Commit d95dbb8f by Nicolas Capens Committed by Nicolas Capens

Fix framebuffer attachment validation.

GL_BACK, GL_DEPTH, and GL_STENCIL are only valid for the default framebuffer, while GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL_ATTACHMENT, and GL_COLOR_ATTACHMENTi are only valid for non-default framebuffer objects. Also implement the color encoding query. Change-Id: I153ae9407850a30ed14d9ae145ee3504ba71029a Reviewed-on: https://swiftshader-review.googlesource.com/14569Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 23f54d74
...@@ -2756,121 +2756,86 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu ...@@ -2756,121 +2756,86 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
GLint clientVersion = context->getClientVersion(); GLuint framebufferName = 0;
es2::Framebuffer *framebuffer = nullptr;
if(target == GL_READ_FRAMEBUFFER) if(target == GL_READ_FRAMEBUFFER)
{ {
if(context->getReadFramebufferName() == 0) framebufferName = context->getReadFramebufferName();
}
else
{
framebufferName = context->getDrawFramebufferName();
}
GLint clientVersion = context->getClientVersion();
if(framebufferName == 0) // Default framebuffer.
{ {
if(clientVersion < 3) if(clientVersion < 3)
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
else }
{
switch(attachment) switch(attachment)
{ {
case GL_BACK: case GL_BACK:
case GL_DEPTH: case GL_DEPTH:
case GL_STENCIL: case GL_STENCIL:
break; if(clientVersion < 3)
default: {
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
}
}
framebuffer = context->getReadFramebuffer(); if(framebufferName != 0)
}
else
{
if(context->getDrawFramebufferName() == 0)
{ {
if(clientVersion < 3) return error(GL_INVALID_OPERATION);
}
break;
case GL_DEPTH_ATTACHMENT:
case GL_STENCIL_ATTACHMENT:
if(framebufferName == 0)
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
else break;
case GL_DEPTH_STENCIL_ATTACHMENT:
if(clientVersion < 3)
{ {
switch(attachment) return error(GL_INVALID_ENUM);
}
if(framebufferName == 0)
{ {
case GL_BACK: return error(GL_INVALID_OPERATION);
case GL_DEPTH: }
case GL_STENCIL:
break; break;
default: default:
return error(GL_INVALID_ENUM); if((unsigned int)(attachment - GL_COLOR_ATTACHMENT0) < MAX_COLOR_ATTACHMENTS)
{
if(framebufferName == 0)
{
return error(GL_INVALID_OPERATION);
} }
} }
else return error(GL_INVALID_ENUM);
} }
framebuffer = context->getDrawFramebuffer(); es2::Framebuffer *framebuffer = context->getFramebuffer(framebufferName);
}
GLenum attachmentType; GLenum attachmentType;
GLuint attachmentHandle; GLuint attachmentHandle;
GLint attachmentLayer; GLint attachmentLayer;
Renderbuffer* renderbuffer = nullptr; Renderbuffer *renderbuffer = nullptr;
switch(attachment) switch(attachment)
{ {
case GL_BACK: case GL_BACK:
if(clientVersion >= 3)
{
attachmentType = framebuffer->getColorbufferType(0); attachmentType = framebuffer->getColorbufferType(0);
attachmentHandle = framebuffer->getColorbufferName(0); attachmentHandle = framebuffer->getColorbufferName(0);
attachmentLayer = framebuffer->getColorbufferLayer(0); attachmentLayer = framebuffer->getColorbufferLayer(0);
renderbuffer = framebuffer->getColorbuffer(0); renderbuffer = framebuffer->getColorbuffer(0);
}
else return error(GL_INVALID_ENUM);
break;
case GL_COLOR_ATTACHMENT0:
case GL_COLOR_ATTACHMENT1:
case GL_COLOR_ATTACHMENT2:
case GL_COLOR_ATTACHMENT3:
case GL_COLOR_ATTACHMENT4:
case GL_COLOR_ATTACHMENT5:
case GL_COLOR_ATTACHMENT6:
case GL_COLOR_ATTACHMENT7:
case GL_COLOR_ATTACHMENT8:
case GL_COLOR_ATTACHMENT9:
case GL_COLOR_ATTACHMENT10:
case GL_COLOR_ATTACHMENT11:
case GL_COLOR_ATTACHMENT12:
case GL_COLOR_ATTACHMENT13:
case GL_COLOR_ATTACHMENT14:
case GL_COLOR_ATTACHMENT15:
case GL_COLOR_ATTACHMENT16:
case GL_COLOR_ATTACHMENT17:
case GL_COLOR_ATTACHMENT18:
case GL_COLOR_ATTACHMENT19:
case GL_COLOR_ATTACHMENT20:
case GL_COLOR_ATTACHMENT21:
case GL_COLOR_ATTACHMENT22:
case GL_COLOR_ATTACHMENT23:
case GL_COLOR_ATTACHMENT24:
case GL_COLOR_ATTACHMENT25:
case GL_COLOR_ATTACHMENT26:
case GL_COLOR_ATTACHMENT27:
case GL_COLOR_ATTACHMENT28:
case GL_COLOR_ATTACHMENT29:
case GL_COLOR_ATTACHMENT30:
case GL_COLOR_ATTACHMENT31:
if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
{
return error(GL_INVALID_ENUM);
}
attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);
attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);
attachmentLayer = framebuffer->getColorbufferLayer(attachment - GL_COLOR_ATTACHMENT0);
renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
break; break;
case GL_DEPTH: case GL_DEPTH:
if(clientVersion < 3)
{
return error(GL_INVALID_ENUM);
}
// fall through
case GL_DEPTH_ATTACHMENT: case GL_DEPTH_ATTACHMENT:
attachmentType = framebuffer->getDepthbufferType(); attachmentType = framebuffer->getDepthbufferType();
attachmentHandle = framebuffer->getDepthbufferName(); attachmentHandle = framebuffer->getDepthbufferName();
...@@ -2878,11 +2843,6 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu ...@@ -2878,11 +2843,6 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu
renderbuffer = framebuffer->getDepthbuffer(); renderbuffer = framebuffer->getDepthbuffer();
break; break;
case GL_STENCIL: case GL_STENCIL:
if(clientVersion < 3)
{
return error(GL_INVALID_ENUM);
}
// fall through
case GL_STENCIL_ATTACHMENT: case GL_STENCIL_ATTACHMENT:
attachmentType = framebuffer->getStencilbufferType(); attachmentType = framebuffer->getStencilbufferType();
attachmentHandle = framebuffer->getStencilbufferName(); attachmentHandle = framebuffer->getStencilbufferName();
...@@ -2890,26 +2850,32 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu ...@@ -2890,26 +2850,32 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu
renderbuffer = framebuffer->getStencilbuffer(); renderbuffer = framebuffer->getStencilbuffer();
break; break;
case GL_DEPTH_STENCIL_ATTACHMENT: case GL_DEPTH_STENCIL_ATTACHMENT:
if(clientVersion >= 3)
{
attachmentType = framebuffer->getDepthbufferType(); attachmentType = framebuffer->getDepthbufferType();
attachmentHandle = framebuffer->getDepthbufferName(); attachmentHandle = framebuffer->getDepthbufferName();
attachmentLayer = framebuffer->getDepthbufferLayer(); attachmentLayer = framebuffer->getDepthbufferLayer();
renderbuffer = framebuffer->getDepthbuffer();
if(attachmentHandle != framebuffer->getStencilbufferName()) if(attachmentHandle != framebuffer->getStencilbufferName())
{ {
// Different attachments to DEPTH and STENCIL, query fails // Different attachments to DEPTH and STENCIL, query fails
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
renderbuffer = framebuffer->getDepthbuffer();
}
else return error(GL_INVALID_ENUM);
break; break;
default: default:
return error(GL_INVALID_ENUM); ASSERT((unsigned int)(attachment - GL_COLOR_ATTACHMENT0) < MAX_COLOR_ATTACHMENTS);
attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);
attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);
attachmentLayer = framebuffer->getColorbufferLayer(attachment - GL_COLOR_ATTACHMENT0);
renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
break;
} }
GLenum attachmentObjectType = GL_NONE; // Type category GLenum attachmentObjectType = GL_NONE; // Type category
if(attachmentType == GL_NONE || Framebuffer::IsRenderbuffer(attachmentType)) if(framebufferName == 0)
{
attachmentObjectType = GL_FRAMEBUFFER_DEFAULT;
}
else if(attachmentType == GL_NONE || Framebuffer::IsRenderbuffer(attachmentType))
{ {
attachmentObjectType = attachmentType; attachmentObjectType = attachmentType;
} }
...@@ -2927,7 +2893,7 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu ...@@ -2927,7 +2893,7 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu
*params = attachmentObjectType; *params = attachmentObjectType;
break; break;
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
if(Framebuffer::IsRenderbuffer(attachmentObjectType) || attachmentObjectType == GL_TEXTURE) if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
{ {
*params = attachmentHandle; *params = attachmentHandle;
} }
...@@ -2939,7 +2905,7 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu ...@@ -2939,7 +2905,7 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
if(attachmentObjectType == GL_TEXTURE) if(attachmentObjectType == GL_TEXTURE)
{ {
*params = clientVersion < 3 ? 0 : renderbuffer->getLevel(); // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0 *params = clientVersion < 3 ? 0 : renderbuffer->getLevel(); // glFramebufferTexture2D does not allow level to be set to anything else in GL ES 2.0
} }
else else
{ {
...@@ -3024,7 +2990,7 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu ...@@ -3024,7 +2990,7 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu
case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
if(clientVersion >= 3) if(clientVersion >= 3)
{ {
*params = GL_LINEAR; // FIXME: GL_SRGB will also be possible, when sRGB is added *params = GetColorEncoding(renderbuffer->getFormat());
} }
else return error(GL_INVALID_ENUM); else return error(GL_INVALID_ENUM);
break; break;
...@@ -3046,7 +3012,6 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu ...@@ -3046,7 +3012,6 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
*params = GL_NONE; *params = GL_NONE;
break; break;
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
if(clientVersion < 3) if(clientVersion < 3)
{ {
...@@ -3054,7 +3019,6 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu ...@@ -3054,7 +3019,6 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu
} }
*params = 0; *params = 0;
break; break;
default: default:
if(clientVersion < 3) if(clientVersion < 3)
{ {
......
...@@ -1719,6 +1719,21 @@ namespace es2 ...@@ -1719,6 +1719,21 @@ namespace es2
return GetColorComponentType(internalformat) == GL_UNSIGNED_INT; return GetColorComponentType(internalformat) == GL_UNSIGNED_INT;
} }
GLenum GetColorEncoding(GLint internalformat)
{
switch(internalformat)
{
case GL_SRGB8:
case GL_SRGB8_ALPHA8:
return GL_SRGB;
default:
// [OpenGL ES 3.0.5] section 6.1.13 page 242:
// If attachment is not a color attachment, or no data storage or texture image
// has been specified for the attachment, params will contain the value LINEAR.
return GL_LINEAR;
}
}
std::string ParseUniformName(const std::string &name, unsigned int *outSubscript) std::string ParseUniformName(const std::string &name, unsigned int *outSubscript)
{ {
// Strip any trailing array operator and retrieve the subscript // Strip any trailing array operator and retrieve the subscript
......
...@@ -77,6 +77,7 @@ namespace es2 ...@@ -77,6 +77,7 @@ namespace es2
bool IsFloatFormat(GLint internalformat); bool IsFloatFormat(GLint internalformat);
bool IsSignedNonNormalizedInteger(GLint internalformat); bool IsSignedNonNormalizedInteger(GLint internalformat);
bool IsUnsignedNonNormalizedInteger(GLint internalformat); bool IsUnsignedNonNormalizedInteger(GLint internalformat);
GLenum GetColorEncoding(GLint internalformat);
// Parse the base uniform name and array index. Returns the base name of the uniform. outSubscript is // Parse the base uniform name and array index. Returns the base name of the uniform. outSubscript is
// set to GL_INVALID_INDEX if the provided name is not an array or the array index is invalid. // set to GL_INVALID_INDEX if the provided name is not an array or the array index is invalid.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment