Commit 648b582e by Nicolas Capens Committed by Nicolas Capens

Fix texture upload format.

We were using the effective sized internal format as the upload format of glTexImage*() calls. This caused issues when using e.g. GL_RGBA16F with GL_RGBA / GL_FLOAT. Change-Id: I2dbd7142447c5330eec1895b1a9652ac20f8414a Reviewed-on: https://swiftshader-review.googlesource.com/16448Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarLingfeng Yang <lfy@google.com> Reviewed-by: 's avatarLingfeng Yang <lfy@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent b1d452ea
...@@ -612,14 +612,14 @@ int Texture2D::getTopLevel() const ...@@ -612,14 +612,14 @@ int Texture2D::getTopLevel() const
return level - 1; return level - 1;
} }
void Texture2D::setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels) void Texture2D::setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
{ {
if(image[level]) if(image[level])
{ {
image[level]->release(); image[level]->release();
} }
image[level] = egl::Image::create(this, width, height, format, type); image[level] = egl::Image::create(this, width, height, internalformat, type);
if(!image[level]) if(!image[level])
{ {
...@@ -1315,7 +1315,7 @@ void TextureCubeMap::releaseTexImage() ...@@ -1315,7 +1315,7 @@ void TextureCubeMap::releaseTexImage()
UNREACHABLE(0); // Cube maps cannot have an EGL surface bound as an image UNREACHABLE(0); // Cube maps cannot have an EGL surface bound as an image
} }
void TextureCubeMap::setImage(egl::Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels) void TextureCubeMap::setImage(egl::Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
{ {
int face = CubeFaceIndex(target); int face = CubeFaceIndex(target);
...@@ -1325,7 +1325,7 @@ void TextureCubeMap::setImage(egl::Context *context, GLenum target, GLint level, ...@@ -1325,7 +1325,7 @@ void TextureCubeMap::setImage(egl::Context *context, GLenum target, GLint level,
} }
int border = (egl::getClientVersion() >= 3) ? 1 : 0; int border = (egl::getClientVersion() >= 3) ? 1 : 0;
image[face][level] = egl::Image::create(this, width, height, 1, border, format, type); image[face][level] = egl::Image::create(this, width, height, 1, border, internalformat, type);
if(!image[face][level]) if(!image[face][level])
{ {
...@@ -1640,14 +1640,14 @@ int Texture3D::getTopLevel() const ...@@ -1640,14 +1640,14 @@ int Texture3D::getTopLevel() const
return level - 1; return level - 1;
} }
void Texture3D::setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels) void Texture3D::setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLint internalformat, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
{ {
if(image[level]) if(image[level])
{ {
image[level]->release(); image[level]->release();
} }
image[level] = egl::Image::create(this, width, height, depth, 0, format, type); image[level] = egl::Image::create(this, width, height, depth, 0, internalformat, type);
if(!image[level]) if(!image[level])
{ {
......
...@@ -162,7 +162,7 @@ public: ...@@ -162,7 +162,7 @@ public:
GLenum getType(GLenum target, GLint level) const override; GLenum getType(GLenum target, GLint level) const override;
int getTopLevel() const override; int getTopLevel() const override;
void setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels); void setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
void subImage(egl::Context *context, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels); void subImage(egl::Context *context, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
...@@ -220,7 +220,7 @@ public: ...@@ -220,7 +220,7 @@ public:
GLenum getType(GLenum target, GLint level) const override; GLenum getType(GLenum target, GLint level) const override;
int getTopLevel() const override; int getTopLevel() const override;
void setImage(egl::Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels); void setImage(egl::Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
void subImage(egl::Context *context, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels); void subImage(egl::Context *context, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
...@@ -282,7 +282,7 @@ public: ...@@ -282,7 +282,7 @@ public:
GLenum getType(GLenum target, GLint level) const override; GLenum getType(GLenum target, GLint level) const override;
int getTopLevel() const override; int getTopLevel() const override;
void setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels); void setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLint internalformat, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
void subImage(egl::Context *context, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels); void subImage(egl::Context *context, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
......
...@@ -5086,7 +5086,7 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, ...@@ -5086,7 +5086,7 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
texture->setImage(context, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data); texture->setImage(context, level, width, height, sizedInternalFormat, format, type, context->getUnpackInfo(), data);
} }
else else
{ {
...@@ -5097,7 +5097,7 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, ...@@ -5097,7 +5097,7 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
texture->setImage(context, target, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data); texture->setImage(context, target, level, width, height, sizedInternalFormat, format, type, context->getUnpackInfo(), data);
} }
} }
} }
...@@ -6309,7 +6309,7 @@ void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei wi ...@@ -6309,7 +6309,7 @@ void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei wi
return error(validationError); return error(validationError);
} }
texture->setImage(context, level, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data); texture->setImage(context, level, width, height, depth, sizedInternalFormat, format, type, context->getUnpackInfo(), data);
} }
} }
......
...@@ -686,7 +686,7 @@ GL_APICALL void GL_APIENTRY glTexImage3D(GLenum target, GLint level, GLint inter ...@@ -686,7 +686,7 @@ GL_APICALL void GL_APIENTRY glTexImage3D(GLenum target, GLint level, GLint inter
return error(validationError); return error(validationError);
} }
texture->setImage(context, level, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data); texture->setImage(context, level, width, height, depth, sizedInternalFormat, format, type, context->getUnpackInfo(), data);
} }
} }
...@@ -3927,6 +3927,7 @@ GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum ...@@ -3927,6 +3927,7 @@ GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum
{ {
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
GLenum sizedInternalFormat = GetSizedInternalFormat(internalformat, type);
es2::Context *context = es2::getContext(); es2::Context *context = es2::getContext();
...@@ -3935,41 +3936,41 @@ GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum ...@@ -3935,41 +3936,41 @@ GL_APICALL void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum
switch(target) switch(target)
{ {
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
{
es2::Texture2D *texture = context->getTexture2D();
if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
{ {
return error(GL_INVALID_OPERATION); es2::Texture2D *texture = context->getTexture2D();
} if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
{
return error(GL_INVALID_OPERATION);
}
for(int level = 0; level < levels; ++level) for(int level = 0; level < levels; level++)
{ {
texture->setImage(context, level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr); texture->setImage(context, level, width, height, sizedInternalFormat, sizedInternalFormat, type, context->getUnpackInfo(), nullptr);
width = std::max(1, (width / 2)); width = std::max(1, (width / 2));
height = std::max(1, (height / 2)); height = std::max(1, (height / 2));
}
texture->makeImmutable(levels);
} }
texture->makeImmutable(levels);
}
break; break;
case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP:
{
es2::TextureCubeMap *texture = context->getTextureCubeMap();
if(!texture || texture->name == 0 || texture->getImmutableFormat())
{ {
return error(GL_INVALID_OPERATION); es2::TextureCubeMap *texture = context->getTextureCubeMap();
} if(!texture || texture->name == 0 || texture->getImmutableFormat())
{
return error(GL_INVALID_OPERATION);
}
for(int level = 0; level < levels; ++level) for(int level = 0; level < levels; level++)
{
for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)
{ {
texture->setImage(context, face, level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr); for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; face++)
{
texture->setImage(context, face, level, width, height, sizedInternalFormat, sizedInternalFormat, type, context->getUnpackInfo(), nullptr);
}
width = std::max(1, (width / 2));
height = std::max(1, (height / 2));
} }
width = std::max(1, (width / 2)); texture->makeImmutable(levels);
height = std::max(1, (height / 2));
} }
texture->makeImmutable(levels);
}
break; break;
default: default:
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
...@@ -3992,6 +3993,7 @@ GL_APICALL void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum ...@@ -3992,6 +3993,7 @@ GL_APICALL void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum
{ {
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
GLenum sizedInternalFormat = GetSizedInternalFormat(internalformat, type);
es2::Context *context = es2::getContext(); es2::Context *context = es2::getContext();
...@@ -4000,52 +4002,52 @@ GL_APICALL void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum ...@@ -4000,52 +4002,52 @@ GL_APICALL void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum
switch(target) switch(target)
{ {
case GL_TEXTURE_3D: case GL_TEXTURE_3D:
{
if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(std::max(width, height), depth)) + 1))
{ {
return error(GL_INVALID_OPERATION); if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(std::max(width, height), depth)) + 1))
} {
return error(GL_INVALID_OPERATION);
}
es2::Texture3D *texture = context->getTexture3D(); es2::Texture3D *texture = context->getTexture3D();
if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE) if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
for(int level = 0; level < levels; ++level) for(int level = 0; level < levels; level++)
{ {
texture->setImage(context, level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr); texture->setImage(context, level, width, height, depth, sizedInternalFormat, sizedInternalFormat, type, context->getUnpackInfo(), nullptr);
width = std::max(1, (width / 2)); width = std::max(1, (width / 2));
height = std::max(1, (height / 2)); height = std::max(1, (height / 2));
depth = std::max(1, (depth / 2)); depth = std::max(1, (depth / 2));
}
texture->makeImmutable(levels);
} }
texture->makeImmutable(levels);
}
break; break;
case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_2D_ARRAY:
{
if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(width, height)) + 1))
{ {
return error(GL_INVALID_OPERATION); if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(width, height)) + 1))
} {
return error(GL_INVALID_OPERATION);
}
es2::Texture3D *texture = context->getTexture2DArray(); es2::Texture3D *texture = context->getTexture2DArray();
if(!texture || texture->name == 0 || texture->getImmutableFormat()) if(!texture || texture->name == 0 || texture->getImmutableFormat())
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
for(int level = 0; level < levels; ++level) for(int level = 0; level < levels; level++)
{
for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)
{ {
texture->setImage(context, level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr); for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; face++)
{
texture->setImage(context, level, width, height, depth, sizedInternalFormat, sizedInternalFormat, type, context->getUnpackInfo(), nullptr);
}
width = std::max(1, (width / 2));
height = std::max(1, (height / 2));
} }
width = std::max(1, (width / 2)); texture->makeImmutable(levels);
height = std::max(1, (height / 2));
} }
texture->makeImmutable(levels);
}
break; break;
default: default:
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
......
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