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
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;
}
......@@ -4134,6 +4180,11 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
blitDepth = true;
readDSBuffer = readFramebuffer->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
blitStencil = true;
readDSBuffer = readFramebuffer->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
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);
}
if(samples > es2::IMPLEMENTATION_MAX_SAMPLES ||
(sw::Surface::isNonNormalizedInteger(es2sw::ConvertRenderbufferFormat(internalformat)) && samples > 0))
{
return error(GL_INVALID_OPERATION);
}
es2::Context *context = es2::getContext();
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();
if(handle == 0)
{
......
......@@ -1498,7 +1498,12 @@ GL_APICALL void GL_APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint sr
switch(filter)
{
case GL_NEAREST:
break;
case GL_LINEAR:
if((mask & GL_DEPTH_BUFFER_BIT) || (mask & GL_STENCIL_BUFFER_BIT))
{
return error(GL_INVALID_OPERATION);
}
break;
default:
return error(GL_INVALID_ENUM);
......@@ -1547,7 +1552,7 @@ GL_APICALL void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum atta
{
if(!textureObject)
{
return error(GL_INVALID_VALUE);
return error(GL_INVALID_OPERATION);
}
textarget = textureObject->getTarget();
......@@ -1575,9 +1580,17 @@ GL_APICALL void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum atta
{
case GL_DRAW_FRAMEBUFFER:
case GL_FRAMEBUFFER:
if(context->getDrawFramebufferName() == 0)
{
return error(GL_INVALID_OPERATION);
}
framebuffer = context->getDrawFramebuffer();
break;
case GL_READ_FRAMEBUFFER:
if(context->getReadFramebufferName() == 0)
{
return error(GL_INVALID_OPERATION);
}
framebuffer = context->getReadFramebuffer();
break;
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