Commit d2faaa99 by Nicolas Capens Committed by Nicolas Capens

Fix internalformat handling.

- Use internalformat parameter if valid, instead of deriving from format/type parameters. - Validate format/type/internalformat parameters in CopyTexSubImage(). - Moved early-out optimizations after validation. - Removed duplicate validation. - Use GLint consistently for internalformat parameters. Change-Id: I377c6bb5381602d13d281f19985aa4f11d201099 Reviewed-on: https://swiftshader-review.googlesource.com/14488Tested-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 05bcbe6b
......@@ -328,7 +328,7 @@ GLenum Framebuffer::completeness(int &width, int &height, int &samples)
if(IsRenderbuffer(mColorbufferType[i]))
{
if(!IsColorRenderable(colorbuffer->getFormat(), egl::getClientVersion(), false))
if(!IsColorRenderable(colorbuffer->getFormat(), egl::getClientVersion()))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
......@@ -337,7 +337,7 @@ GLenum Framebuffer::completeness(int &width, int &height, int &samples)
{
GLenum format = colorbuffer->getFormat();
if(!IsColorRenderable(format, egl::getClientVersion(), true))
if(!IsColorRenderable(format, egl::getClientVersion()))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
......
......@@ -431,22 +431,7 @@ void Texture::subImage(egl::Context *context, GLint xoffset, GLint yoffset, GLin
return error(GL_INVALID_OPERATION);
}
if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight() || depth + zoffset > image->getDepth())
{
return error(GL_INVALID_VALUE);
}
if(IsCompressed(image->getFormat(), egl::getClientVersion()))
{
return error(GL_INVALID_OPERATION);
}
if(format != image->getFormat())
{
return error(GL_INVALID_OPERATION);
}
if(pixels)
if(pixels && width > 0 && height > 0 && depth > 0)
{
image->loadImageData(context, xoffset, yoffset, zoffset, width, height, depth, format, type, unpackInfo, pixels);
}
......@@ -459,16 +444,6 @@ void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GL
return error(GL_INVALID_OPERATION);
}
if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight() || depth + zoffset > image->getDepth())
{
return error(GL_INVALID_VALUE);
}
if(format != image->getFormat())
{
return error(GL_INVALID_OPERATION);
}
if(pixels && (imageSize > 0)) // imageSize's correlation to width and height is already validated with egl::ComputeCompressedSize() at the API level
{
image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, imageSize, pixels);
......@@ -773,28 +748,31 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
return error(GL_INVALID_VALUE);
}
egl::Image *renderTarget = source->getRenderTarget(0);
if(!renderTarget)
if(width > 0 && height > 0)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
egl::Image *renderTarget = source->getRenderTarget(0);
Renderbuffer* renderbuffer = source->getReadColorbuffer();
if(!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
if(!renderbuffer)
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
Renderbuffer* renderbuffer = source->getReadColorbuffer();
sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
if(!renderbuffer)
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]);
sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
renderTarget->release();
copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]);
renderTarget->release();
}
}
void Texture2D::setSharedImage(egl::Image *sharedImage)
......@@ -1415,28 +1393,31 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
return error(GL_INVALID_VALUE);
}
egl::Image *renderTarget = source->getRenderTarget(0);
if(!renderTarget)
if(width > 0 && height > 0)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
egl::Image *renderTarget = source->getRenderTarget(0);
Renderbuffer* renderbuffer = source->getReadColorbuffer();
if(!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
if(!renderbuffer)
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
Renderbuffer* renderbuffer = source->getReadColorbuffer();
sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
if(!renderbuffer)
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
copy(renderTarget, sourceRect, image[face][level]->getFormat(), xoffset, yoffset, zoffset, image[face][level]);
sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
renderTarget->release();
copy(renderTarget, sourceRect, image[face][level]->getFormat(), xoffset, yoffset, zoffset, image[face][level]);
renderTarget->release();
}
}
void TextureCubeMap::generateMipmaps()
......@@ -1758,28 +1739,31 @@ void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
return error(GL_INVALID_VALUE);
}
egl::Image *renderTarget = source->getRenderTarget(0);
if(!renderTarget)
if(width > 0 && height > 0)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
egl::Image *renderTarget = source->getRenderTarget(0);
Renderbuffer* renderbuffer = source->getReadColorbuffer();
if(!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
if(!renderbuffer)
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
Renderbuffer* renderbuffer = source->getReadColorbuffer();
sw::SliceRect sourceRect = {x, y, x + width, y + height, 0};
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
if(!renderbuffer)
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]);
sw::SliceRect sourceRect = {x, y, x + width, y + height, 0};
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
renderTarget->release();
copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]);
renderTarget->release();
}
}
void Texture3D::setSharedImage(egl::Image *sharedImage)
......
......@@ -729,21 +729,19 @@ GL_APICALL void GL_APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xo
GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);
if(validationError == GL_NONE)
GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texture, context->getClientVersion());
if(validationError != GL_NONE)
{
GLenum validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type));
if(validationError != GL_NONE)
{
return error(validationError);
}
texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
return error(validationError);
}
else
validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type));
if(validationError != GL_NONE)
{
return error(validationError);
}
texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
}
}
......@@ -793,7 +791,7 @@ GL_APICALL void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLin
GLenum colorbufferFormat = source->getFormat();
es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);
GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, zoffset, width, height, 1, GL_NONE, GL_NONE, texture, context->getClientVersion());
if(validationError != GL_NONE)
{
return error(validationError);
......@@ -935,7 +933,7 @@ GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level
return error(GL_INVALID_OPERATION);
}
if(((width % 4) != 0) || ((height % 4) != 0) ||
if(((width % 4) != 0) || ((height % 4) != 0) ||
((xoffset % 4) != 0) || ((yoffset % 4) != 0))
{
return error(GL_INVALID_OPERATION);
......@@ -967,7 +965,8 @@ GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level
if(is_ETC2_EAC)
{
if(((width + xoffset) != texture->getWidth(target, level)) ||
((height + yoffset) != texture->getHeight(target, level)))
((height + yoffset) != texture->getHeight(target, level)) ||
((depth + zoffset) != texture->getDepth(target, level)))
{
return error(GL_INVALID_OPERATION);
}
......@@ -4085,7 +4084,7 @@ GL_APICALL void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internal
return;
}
if(!IsColorRenderable(internalformat, egl::getClientVersion(), false) &&
if(!IsColorRenderable(internalformat, egl::getClientVersion()) &&
!IsDepthRenderable(internalformat, egl::getClientVersion()) &&
!IsStencilRenderable(internalformat, egl::getClientVersion()))
{
......
......@@ -45,21 +45,23 @@ namespace es2
bool IsCompressed(GLenum format, GLint clientVersion);
GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type);
GLenum ValidateCompressedFormat(GLenum format, GLint clientVersion, bool expectCompressedFormats);
GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture);
GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture);
GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLenum format, GLenum type, Texture *texture, GLint clientVersion);
GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, Texture *texture, GLint clientVersion);
bool IsValidReadPixelsFormatType(const Framebuffer *framebuffer, GLenum format, GLenum type, GLint clientVersion);
bool IsDepthTexture(GLenum format);
bool IsStencilTexture(GLenum format);
bool IsCubemapTextureTarget(GLenum target);
int CubeFaceIndex(GLenum cubeTarget);
bool IsTextureTarget(GLenum target);
bool ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion);
GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion);
GLsizei GetTypeSize(GLenum type);
bool IsColorRenderable(GLenum internalformat, GLint clientVersion, bool isTexture);
bool IsMipmappable(GLenum format, sw::Format internalFormat, GLint clientVersion);
bool IsDepthRenderable(GLenum internalformat, GLint clientVersion);
bool IsStencilRenderable(GLenum internalformat, GLint clientVersion);
bool IsColorRenderable(GLint internalformat, GLint clientVersion);
bool IsDepthRenderable(GLint internalformat, GLint clientVersion);
bool IsStencilRenderable(GLint internalformat, GLint clientVersion);
bool IsMipmappable(GLint internalformat, sw::Format format, GLint clientVersion);
// 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.
......
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