Commit 3fcf17e6 by Mohan Maiya Committed by Commit Bot

Vulkan: Bug fix in sRGBDecode logic

When a sampler's GL_TEXTURE_SRGB_DECODE_EXT state was toggled between GL_DECODE_EXT and GL_SKIP_DECODE_EXT VkImageViews of the TextureVk object were not being updated. Add sRGB_decode state as part of ImageViewSubresourceSerial so we retrieve the correct VkImageView from the texture cache. Bug: angleproject:3609 Tests: angle_end2end_tests --gtest_filter=SRGBTextureTestES3.SRGBDecodeSamplerParameterToggle*Vulkan Change-Id: I897e461957d408b5a5b4f03fefc05f2e9684c7b7 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2514900 Commit-Queue: Mohan Maiya <m.maiya@samsung.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 59fbb989
......@@ -4265,7 +4265,8 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context)
ANGLE_TRY(textureVk->ensureMutable(this));
}
vk::ImageViewSubresourceSerial imageViewSerial = textureVk->getImageViewSubresourceSerial();
vk::ImageViewSubresourceSerial imageViewSerial =
textureVk->getImageViewSubresourceSerial(samplerState);
mActiveTexturesDesc.update(textureUnit, imageViewSerial, samplerHelper.getSamplerSerial());
if (textureVk->getImage().hasImmutableSampler())
......
......@@ -71,8 +71,8 @@ vk::ImageViewSubresourceSerial RenderTargetVk::getSubresourceSerialImpl(
ASSERT(mLayerIndex < std::numeric_limits<uint16_t>::max());
ASSERT(mLevelIndexGL.get() < std::numeric_limits<uint16_t>::max());
vk::ImageViewSubresourceSerial imageViewSerial =
imageViews->getSubresourceSerial(mLevelIndexGL, 1, mLayerIndex, vk::LayerMode::Single);
vk::ImageViewSubresourceSerial imageViewSerial = imageViews->getSubresourceSerial(
mLevelIndexGL, 1, mLayerIndex, vk::LayerMode::Single, vk::SrgbDecodeMode::SkipDecode);
return imageViewSerial;
}
......
......@@ -2631,12 +2631,18 @@ void TextureVk::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMe
onStateChange(angle::SubjectMessage::SubjectChanged);
}
vk::ImageViewSubresourceSerial TextureVk::getImageViewSubresourceSerial() const
vk::ImageViewSubresourceSerial TextureVk::getImageViewSubresourceSerial(
const gl::SamplerState &samplerState) const
{
gl::LevelIndex baseLevel(mState.getEffectiveBaseLevel());
// getMipmapMaxLevel will clamp to the max level if it is smaller than the number of mips.
uint32_t levelCount = gl::LevelIndex(mState.getMipmapMaxLevel()) - baseLevel + 1;
return getImageViews().getSubresourceSerial(baseLevel, levelCount, 0, vk::LayerMode::All);
uint32_t levelCount = gl::LevelIndex(mState.getMipmapMaxLevel()) - baseLevel + 1;
vk::SrgbDecodeMode srgbDecodeMode = (samplerState.getSRGBDecode() == GL_DECODE_EXT)
? vk::SrgbDecodeMode::SrgbDecode
: vk::SrgbDecodeMode::SkipDecode;
return getImageViews().getSubresourceSerial(baseLevel, levelCount, 0, vk::LayerMode::All,
srgbDecodeMode);
}
angle::Result TextureVk::refreshImageViews(ContextVk *contextVk)
......
......@@ -199,7 +199,8 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
// Normally, initialize the image with enabled mipmap level counts.
angle::Result ensureImageInitialized(ContextVk *contextVk, ImageMipLevels mipLevels);
vk::ImageViewSubresourceSerial getImageViewSubresourceSerial() const;
vk::ImageViewSubresourceSerial getImageViewSubresourceSerial(
const gl::SamplerState &samplerState) const;
void overrideStagingBufferSizeForTesting(size_t initialSizeForTesting)
{
......
......@@ -988,15 +988,16 @@ ANGLE_INLINE PipelineHelper::PipelineHelper(Pipeline &&pipeline) : mPipeline(std
struct ImageSubresourceRange
{
uint16_t level : 10; // GL max is 1000 (fits in 10 bits).
uint16_t levelCount : 6; // Max 63 levels (2 ** 6 - 1). If we need more, take from layer.
uint16_t layer : 15; // Implementation max is 2048 (11 bits).
uint16_t singleLayer : 1; // true/false only. Not possible to use sub-slices of levels.
uint16_t level : 10; // GL max is 1000 (fits in 10 bits).
uint16_t levelCount : 6; // Max 63 levels (2 ** 6 - 1). If we need more, take from layer.
uint16_t layer : 14; // Implementation max is 2048 (11 bits).
uint16_t singleLayer : 1; // true/false only. Not possible to use sub-slices of levels.
uint16_t srgbDecodeMode : 1; // Values from vk::SrgbDecodeMode.
};
static_assert(sizeof(ImageSubresourceRange) == sizeof(uint32_t), "Size mismatch");
constexpr ImageSubresourceRange kInvalidImageSubresourceRange = {0, 0, 0, 0};
constexpr ImageSubresourceRange kInvalidImageSubresourceRange = {0, 0, 0, 0, 0};
struct ImageViewSubresourceSerial
{
......
......@@ -6171,10 +6171,12 @@ angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk,
imageView, levelVk, 1, layer, 1);
}
ImageViewSubresourceSerial ImageViewHelper::getSubresourceSerial(gl::LevelIndex levelGL,
uint32_t levelCount,
uint32_t layer,
LayerMode layerMode) const
ImageViewSubresourceSerial ImageViewHelper::getSubresourceSerial(
gl::LevelIndex levelGL,
uint32_t levelCount,
uint32_t layer,
LayerMode layerMode,
SrgbDecodeMode srgbDecodeMode) const
{
ASSERT(mImageViewSerial.valid());
......@@ -6184,6 +6186,7 @@ ImageViewSubresourceSerial ImageViewHelper::getSubresourceSerial(gl::LevelIndex
SetBitField(serial.subresource.levelCount, levelCount);
SetBitField(serial.subresource.layer, layer);
SetBitField(serial.subresource.singleLayer, layerMode == LayerMode::Single ? 1 : 0);
SetBitField(serial.subresource.srgbDecodeMode, srgbDecodeMode);
return serial;
}
......
......@@ -1867,6 +1867,13 @@ enum LayerMode
All
};
// Sampler decode mode indicating if an attachment needs to be decoded in linear colorspace or sRGB
enum class SrgbDecodeMode
{
SkipDecode,
SrgbDecode
};
class ImageViewHelper : angle::NonCopyable
{
public:
......@@ -1999,7 +2006,8 @@ class ImageViewHelper : angle::NonCopyable
ImageViewSubresourceSerial getSubresourceSerial(gl::LevelIndex levelGL,
uint32_t levelCount,
uint32_t layer,
LayerMode layerMode) const;
LayerMode layerMode,
SrgbDecodeMode srgbDecodeMode) const;
private:
ImageView &getReadImageView()
......
......@@ -470,6 +470,40 @@ TEST_P(SRGBTextureTestES3, SRGBDecodeSamplerParameter)
EXPECT_PIXEL_COLOR_NEAR(0, 0, linearColor, 1.0);
}
// Toggle between GL_DECODE_EXT and GL_SKIP_DECODE_EXT of sampler parameter
// GL_TEXTURE_SRGB_DECODE_EXT
TEST_P(SRGBTextureTestES3, SRGBDecodeSamplerParameterToggle)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_sRGB_decode"));
GLColor linearColor = kLinearColor;
GLColor srgbColor = kNonlinearColor;
GLTexture tex;
glBindTexture(GL_TEXTURE_2D, tex.get());
glTexImage2D(GL_TEXTURE_2D, 0, getSRGBA8TextureInternalFormat(), 1, 1, 0,
getSRGBA8TextureFormat(), GL_UNSIGNED_BYTE, &linearColor);
ASSERT_GL_NO_ERROR();
GLSampler sampler;
glBindSampler(0, sampler.get());
glUseProgram(mProgram);
glUniform1i(mTextureLocation, 0);
glDisable(GL_DEPTH_TEST);
for (int i = 0; i < 4; i++)
{
// Toggle betwee decode and skip decode and verify pixel value
GLint decode = ((i & 1) == 0) ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT;
angle::GLColor &expectedColor = ((i & 1) == 0) ? srgbColor : linearColor;
glSamplerParameteri(sampler.get(), GL_TEXTURE_SRGB_DECODE_EXT, decode);
drawQuad(mProgram, "position", 0.5f);
EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, 1.0);
}
}
// Test that sampler state overrides texture state for srgb decode
TEST_P(SRGBTextureTestES3, SRGBDecodeTextureAndSamplerParameter)
{
......
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