Commit 1c93b6c6 by Alexis Hetu Committed by Alexis Hétu

Framebuffer related validity checks

Added validity checks for RenderbufferStorageMultisample and BlitFramebuffer, mostly missing checks for using integer types or depth/stencil framebuffers with multisampling, which is not allowed. Fixes all failures in: dEQP-GLES3.functional.negative_api.buffer* Change-Id: Ie1db21a3b9f1ca71ed660a2758d43f24846acdf1 Reviewed-on: https://swiftshader-review.googlesource.com/14048Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent f89cd0b8
...@@ -4111,6 +4111,52 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -4111,6 +4111,52 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
// The GL ES 3.0.2 spec (pg 193) states that:
// 1) If the read buffer is fixed point format, the draw buffer must be as well
// 2) If the read buffer is an unsigned integer format, the draw buffer must be
// as well
// 3) If the read buffer is a signed integer format, the draw buffer must be as
// well
es2::Renderbuffer *readRenderbuffer = readFramebuffer->getReadColorbuffer();
es2::Renderbuffer *drawRenderbuffer = drawFramebuffer->getColorbuffer(0);
sw::Format readFormat = readRenderbuffer->getInternalFormat();
sw::Format drawFormat = drawRenderbuffer->getInternalFormat();
GLenum readComponentType = sw2es::GetComponentType(readFormat, GL_COLOR_ATTACHMENT0);
GLenum drawComponentType = sw2es::GetComponentType(drawFormat, GL_COLOR_ATTACHMENT0);
bool readFixedPoint = ((readComponentType == GL_UNSIGNED_NORMALIZED) ||
(readComponentType == GL_SIGNED_NORMALIZED));
bool drawFixedPoint = ((drawComponentType == GL_UNSIGNED_NORMALIZED) ||
(drawComponentType == GL_SIGNED_NORMALIZED));
bool readFixedOrFloat = (readFixedPoint || (readComponentType == GL_FLOAT));
bool drawFixedOrFloat = (drawFixedPoint || (drawComponentType == GL_FLOAT));
if(readFixedOrFloat != drawFixedOrFloat)
{
return error(GL_INVALID_OPERATION);
}
if((readComponentType == GL_UNSIGNED_INT) && (drawComponentType != GL_UNSIGNED_INT))
{
return error(GL_INVALID_OPERATION);
}
if((readComponentType == GL_INT) && (drawComponentType != GL_INT))
{
return error(GL_INVALID_OPERATION);
}
// Cannot filter integer data
if(((readComponentType == GL_UNSIGNED_INT) || (readComponentType == GL_INT)) && filter)
{
return error(GL_INVALID_OPERATION);
}
if((readRenderbuffer->getSamples() > 0) &&
(readRenderbuffer->getFormat() != drawRenderbuffer->getFormat()))
{
return error(GL_INVALID_OPERATION);
}
blitRenderTarget = true; blitRenderTarget = true;
} }
...@@ -4134,6 +4180,11 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -4134,6 +4180,11 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
blitDepth = true; blitDepth = true;
readDSBuffer = readFramebuffer->getDepthbuffer(); readDSBuffer = readFramebuffer->getDepthbuffer();
drawDSBuffer = drawFramebuffer->getDepthbuffer(); drawDSBuffer = drawFramebuffer->getDepthbuffer();
if(readDSBuffer->getInternalFormat() != drawDSBuffer->getInternalFormat())
{
return error(GL_INVALID_OPERATION);
}
} }
} }
...@@ -4152,6 +4203,11 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 ...@@ -4152,6 +4203,11 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
blitStencil = true; blitStencil = true;
readDSBuffer = readFramebuffer->getStencilbuffer(); readDSBuffer = readFramebuffer->getStencilbuffer();
drawDSBuffer = drawFramebuffer->getStencilbuffer(); drawDSBuffer = drawFramebuffer->getStencilbuffer();
if(readDSBuffer->getInternalFormat() != drawDSBuffer->getInternalFormat())
{
return error(GL_INVALID_OPERATION);
}
} }
} }
......
...@@ -4726,22 +4726,23 @@ void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum inter ...@@ -4726,22 +4726,23 @@ void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum inter
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
if(width < 0 || height < 0 || samples < 0) if(width < 0 || height < 0 || samples < 0 ||
width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
{ {
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
if(samples > es2::IMPLEMENTATION_MAX_SAMPLES ||
(sw::Surface::isNonNormalizedInteger(es2sw::ConvertRenderbufferFormat(internalformat)) && samples > 0))
{
return error(GL_INVALID_OPERATION);
}
es2::Context *context = es2::getContext(); es2::Context *context = es2::getContext();
if(context) if(context)
{ {
if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
samples > es2::IMPLEMENTATION_MAX_SAMPLES)
{
return error(GL_INVALID_VALUE);
}
GLuint handle = context->getRenderbufferName(); GLuint handle = context->getRenderbufferName();
if(handle == 0) if(handle == 0)
{ {
......
...@@ -1498,7 +1498,12 @@ GL_APICALL void GL_APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint sr ...@@ -1498,7 +1498,12 @@ GL_APICALL void GL_APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint sr
switch(filter) switch(filter)
{ {
case GL_NEAREST: case GL_NEAREST:
break;
case GL_LINEAR: case GL_LINEAR:
if((mask & GL_DEPTH_BUFFER_BIT) || (mask & GL_STENCIL_BUFFER_BIT))
{
return error(GL_INVALID_OPERATION);
}
break; break;
default: default:
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
...@@ -1547,7 +1552,7 @@ GL_APICALL void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum atta ...@@ -1547,7 +1552,7 @@ GL_APICALL void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum atta
{ {
if(!textureObject) if(!textureObject)
{ {
return error(GL_INVALID_VALUE); return error(GL_INVALID_OPERATION);
} }
textarget = textureObject->getTarget(); textarget = textureObject->getTarget();
...@@ -1575,9 +1580,17 @@ GL_APICALL void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum atta ...@@ -1575,9 +1580,17 @@ GL_APICALL void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum atta
{ {
case GL_DRAW_FRAMEBUFFER: case GL_DRAW_FRAMEBUFFER:
case GL_FRAMEBUFFER: case GL_FRAMEBUFFER:
if(context->getDrawFramebufferName() == 0)
{
return error(GL_INVALID_OPERATION);
}
framebuffer = context->getDrawFramebuffer(); framebuffer = context->getDrawFramebuffer();
break; break;
case GL_READ_FRAMEBUFFER: case GL_READ_FRAMEBUFFER:
if(context->getReadFramebufferName() == 0)
{
return error(GL_INVALID_OPERATION);
}
framebuffer = context->getReadFramebuffer(); framebuffer = context->getReadFramebuffer();
break; break;
default: default:
......
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