Add support for the remaining ES3 framebuffer attachment parameter queries.
TRAC #23474
Author: Geoff Lang
Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index dc91ce5..518cf5b 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -2861,85 +2861,159 @@
if (context)
{
- if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
+ META_ASSERT(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER && GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER);
+ if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
{
return gl::error(GL_INVALID_ENUM);
}
- gl::Framebuffer *framebuffer = NULL;
- if (target == GL_READ_FRAMEBUFFER_ANGLE)
+ switch (pname)
{
- if(context->getReadFramebufferHandle() == 0)
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ break;
+ case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
+ case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
+ if (context->getClientVersion() >= 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ break;
}
-
- framebuffer = context->getReadFramebuffer();
+ default:
+ return gl::error(GL_INVALID_ENUM);
}
- else
+
+ // Determine if the attachment is a valid enum
+ switch (attachment)
{
- if (context->getDrawFramebufferHandle() == 0)
+ case GL_BACK:
+ case GL_FRONT:
+ case GL_STENCIL:
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ if (context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_ENUM);
}
+ break;
- framebuffer = context->getDrawFramebuffer();
+ case GL_DEPTH_ATTACHMENT:
+ case GL_STENCIL_ATTACHMENT:
+ break;
+
+ default:
+ if (attachment < GL_COLOR_ATTACHMENT0_EXT ||
+ (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getMaximumRenderTargets())
+ {
+ return gl::error(GL_INVALID_ENUM);
+ }
+ break;
}
+ GLuint framebufferHandle = (target == GL_READ_FRAMEBUFFER) ? context->getReadFramebufferHandle()
+ : context->getDrawFramebufferHandle();
+
+ gl::Framebuffer *framebuffer = context->getFramebuffer(framebufferHandle);
+
GLenum attachmentType;
GLuint attachmentHandle;
GLuint attachmentLevel;
GLuint attachmentLayer;
+ gl::Renderbuffer *renderbuffer;
- if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+ if(framebufferHandle == 0)
{
- const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
-
- if (colorAttachment >= context->getMaximumRenderTargets())
+ if(context->getClientVersion() < 3)
{
- return gl::error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_OPERATION);
}
- attachmentType = framebuffer->getColorbufferType(colorAttachment);
- attachmentHandle = framebuffer->getColorbufferHandle(colorAttachment);
- attachmentLevel = framebuffer->getColorbufferMipLevel(colorAttachment);
- attachmentLayer = framebuffer->getColorbufferLayer(colorAttachment);
- }
- else
- {
switch (attachment)
{
- case GL_DEPTH_ATTACHMENT:
+ case GL_BACK:
+ attachmentType = framebuffer->getColorbufferType(0);
+ attachmentHandle = framebuffer->getColorbufferHandle(0);
+ attachmentLevel = framebuffer->getColorbufferMipLevel(0);
+ attachmentLayer = framebuffer->getColorbufferLayer(0);
+ renderbuffer = framebuffer->getColorbuffer(0);
+ break;
+ case GL_DEPTH:
attachmentType = framebuffer->getDepthbufferType();
attachmentHandle = framebuffer->getDepthbufferHandle();
attachmentLevel = framebuffer->getDepthbufferMipLevel();
attachmentLayer = framebuffer->getDepthbufferLayer();
+ renderbuffer = framebuffer->getDepthbuffer();
break;
- case GL_STENCIL_ATTACHMENT:
+ case GL_STENCIL:
attachmentType = framebuffer->getStencilbufferType();
attachmentHandle = framebuffer->getStencilbufferHandle();
attachmentLevel = framebuffer->getStencilbufferMipLevel();
attachmentLayer = framebuffer->getStencilbufferLayer();
+ renderbuffer = framebuffer->getStencilbuffer();
break;
- case GL_DEPTH_STENCIL_ATTACHMENT:
- if (context->getClientVersion() < 3)
+ default:
+ return gl::error(GL_INVALID_OPERATION);
+ }
+ }
+ else
+ {
+ if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+ {
+ const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
+ attachmentType = framebuffer->getColorbufferType(colorAttachment);
+ attachmentHandle = framebuffer->getColorbufferHandle(colorAttachment);
+ attachmentLevel = framebuffer->getColorbufferMipLevel(colorAttachment);
+ attachmentLayer = framebuffer->getColorbufferLayer(colorAttachment);
+ renderbuffer = framebuffer->getColorbuffer(colorAttachment);
+ }
+ else
+ {
+ switch (attachment)
{
- return gl::error(GL_INVALID_ENUM);
- }
- if (framebuffer->getDepthbufferHandle() != framebuffer->getStencilbufferHandle())
- {
+ case GL_DEPTH_ATTACHMENT:
+ attachmentType = framebuffer->getDepthbufferType();
+ attachmentHandle = framebuffer->getDepthbufferHandle();
+ attachmentLevel = framebuffer->getDepthbufferMipLevel();
+ attachmentLayer = framebuffer->getDepthbufferLayer();
+ renderbuffer = framebuffer->getDepthbuffer();
+ break;
+ case GL_STENCIL_ATTACHMENT:
+ attachmentType = framebuffer->getStencilbufferType();
+ attachmentHandle = framebuffer->getStencilbufferHandle();
+ attachmentLevel = framebuffer->getStencilbufferMipLevel();
+ attachmentLayer = framebuffer->getStencilbufferLayer();
+ renderbuffer = framebuffer->getStencilbuffer();
+ break;
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ if (framebuffer->getDepthbufferHandle() != framebuffer->getStencilbufferHandle())
+ {
+ return gl::error(GL_INVALID_OPERATION);
+ }
+ attachmentType = framebuffer->getDepthStencilbufferType();
+ attachmentHandle = framebuffer->getDepthStencilbufferHandle();
+ attachmentLevel = framebuffer->getDepthStencilbufferMipLevel();
+ attachmentLayer = framebuffer->getDepthStencilbufferLayer();
+ renderbuffer = framebuffer->getDepthStencilBuffer();
+ break;
+ default:
return gl::error(GL_INVALID_OPERATION);
}
- attachmentType = framebuffer->getDepthStencilbufferType();
- attachmentHandle = framebuffer->getDepthStencilbufferHandle();
- attachmentLevel = framebuffer->getDepthStencilbufferMipLevel();
- attachmentLayer = framebuffer->getDepthStencilbufferLayer();
- default: return gl::error(GL_INVALID_ENUM);
}
}
GLenum attachmentObjectType; // Type category
- if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
+ if (framebufferHandle == 0)
+ {
+ attachmentObjectType = GL_FRAMEBUFFER_DEFAULT;
+ }
+ else if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
{
attachmentObjectType = attachmentType;
}
@@ -2953,64 +3027,124 @@
return;
}
- switch (pname)
+ if (attachmentObjectType == GL_NONE)
{
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- *params = attachmentObjectType;
- break;
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
+ // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
+ // is NONE, then querying any other pname will generate INVALID_ENUM.
+
+ // ES 3.0.2 spec pg 235 states that if the attachment type is none,
+ // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
+ // INVALID_OPERATION for all other pnames
+
+ switch (pname)
{
- *params = attachmentHandle;
- }
- else
- {
- return gl::error(GL_INVALID_ENUM);
- }
- break;
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
- if (attachmentObjectType == GL_TEXTURE)
- {
- *params = attachmentLevel;
- }
- else
- {
- return gl::error(GL_INVALID_ENUM);
- }
- break;
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
- if (attachmentObjectType == GL_TEXTURE)
- {
- if (gl::IsCubemapTextureTarget(attachmentType))
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ *params = attachmentObjectType;
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ if (context->getClientVersion() < 3)
{
- *params = attachmentType;
+ return gl::error(GL_INVALID_ENUM);
+ }
+ *params = 0;
+ break;
+
+ default:
+ if (context->getClientVersion() < 3)
+ {
+ return gl::error(GL_INVALID_ENUM);
}
else
{
- *params = 0;
+ gl::error(GL_INVALID_OPERATION);
}
}
- else
+ }
+ else
+ {
+ ASSERT(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE ||
+ attachmentObjectType == GL_FRAMEBUFFER_DEFAULT);
+ ASSERT(renderbuffer != NULL);
+
+ switch (pname)
{
- return gl::error(GL_INVALID_ENUM);
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ *params = attachmentObjectType;
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ if (attachmentObjectType != GL_RENDERBUFFER && attachmentObjectType != GL_TEXTURE)
+ {
+ return gl::error(GL_INVALID_ENUM);
+ }
+ *params = attachmentHandle;
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+ if (attachmentObjectType != GL_TEXTURE)
+ {
+ return gl::error(GL_INVALID_ENUM);
+ }
+ *params = attachmentLevel;
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ if (attachmentObjectType != GL_TEXTURE)
+ {
+ return gl::error(GL_INVALID_ENUM);
+ }
+ *params = gl::IsCubemapTextureTarget(attachmentType) ? attachmentType : 0;
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
+ *params = renderbuffer->getRedSize();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
+ *params = renderbuffer->getGreenSize();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
+ *params = renderbuffer->getBlueSize();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
+ *params = renderbuffer->getAlphaSize();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
+ *params = renderbuffer->getDepthSize();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
+ *params = renderbuffer->getStencilSize();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
+ if (attachment == GL_DEPTH_STENCIL)
+ {
+ gl::error(GL_INVALID_OPERATION);
+ }
+ *params = renderbuffer->getComponentType();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
+ *params = renderbuffer->getColorEncoding();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
+ if (attachmentObjectType != GL_TEXTURE)
+ {
+ return gl::error(GL_INVALID_ENUM);
+ }
+ *params = attachmentLayer;
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
}
- break;
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
- if (context->getClientVersion() < 3)
- {
- return gl::error(GL_INVALID_ENUM);
- }
- if (attachmentObjectType == GL_TEXTURE)
- {
- *params = attachmentLayer;
- }
- else
- {
- return gl::error(GL_INVALID_ENUM);
- }
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
}
}
}