Commit 33e30205 by Jamie Madill Committed by Commit Bot

Vulkan: sRGB cleanups.

A few fixes to how we check for the sRGB override in the TextureVk class. In at least one instance there was a potential edge case where in syncState we might not create the Texture with the mutable bit the second time through the function. Bug: angleproject:5176 Change-Id: I4f1ca6e469b10514c3a0de3120be9ade62568084 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2482292Reviewed-by: 's avatarMohan Maiya <m.maiya@samsung.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent a7c16c2d
...@@ -4167,23 +4167,20 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context) ...@@ -4167,23 +4167,20 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context)
const SamplerVk *samplerVk = sampler ? vk::GetImpl(sampler) : nullptr; const SamplerVk *samplerVk = sampler ? vk::GetImpl(sampler) : nullptr;
if (samplerVk != nullptr && samplerVk->skipSamplerSRGBDecode())
{
// TODO (http://anglebug.com/5176) Refactor to use ensureImageInitialized instead of
// syncState
// A sampler may force a texture to reallocate in order to support sRGB_decode
// state
gl::Texture::DirtyBits decodeBit;
decodeBit.set(gl::Texture::DIRTY_BIT_SRGB_DECODE);
ANGLE_TRY(textureVk->syncState(context, decodeBit, gl::Command::Other));
}
const vk::SamplerHelper &samplerHelper = const vk::SamplerHelper &samplerHelper =
samplerVk ? samplerVk->getSampler() : textureVk->getSampler(); samplerVk ? samplerVk->getSampler() : textureVk->getSampler();
activeTexture.texture = textureVk; const gl::SamplerState &samplerState =
activeTexture.sampler = &samplerHelper; sampler ? sampler->getSamplerState() : texture->getSamplerState();
activeTexture.useLinearImageView = activeTexture.texture = textureVk;
textureVk->shouldUseLinearColorspaceWithSampler(samplerVk); activeTexture.sampler = &samplerHelper;
activeTexture.srgbDecode = samplerState.getSRGBDecode();
if (activeTexture.srgbDecode == GL_SKIP_DECODE_EXT)
{
// Make sure we use the MUTABLE bit for the storage. Because the "skip decode" is a
// Sampler state we might not have caught this setting in TextureVk::syncState.
ANGLE_TRY(textureVk->ensureMutable(this));
}
vk::ImageViewSubresourceSerial imageViewSerial = textureVk->getImageViewSubresourceSerial(); vk::ImageViewSubresourceSerial imageViewSerial = textureVk->getImageViewSubresourceSerial();
mActiveTexturesDesc.update(textureUnit, imageViewSerial, samplerHelper.getSamplerSerial()); mActiveTexturesDesc.update(textureUnit, imageViewSerial, samplerHelper.getSamplerSerial());
......
...@@ -1455,16 +1455,13 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex ...@@ -1455,16 +1455,13 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex
VkWriteDescriptorSet *writeInfos = contextVk->allocWriteDescriptorSets(arraySize); VkWriteDescriptorSet *writeInfos = contextVk->allocWriteDescriptorSets(arraySize);
for (uint32_t arrayElement = 0; arrayElement < arraySize; ++arrayElement) for (uint32_t arrayElement = 0; arrayElement < arraySize; ++arrayElement)
{ {
GLuint textureUnit = samplerBinding.boundTextureUnits[arrayElement]; GLuint textureUnit = samplerBinding.boundTextureUnits[arrayElement];
TextureVk *textureVk = activeTextures[textureUnit].texture; const vk::TextureUnit &unit = activeTextures[textureUnit];
const vk::SamplerHelper &samplerHelper = *activeTextures[textureUnit].sampler; TextureVk *textureVk = unit.texture;
bool linearColorspaceWithSampler = activeTextures[textureUnit].useLinearImageView; const vk::SamplerHelper &samplerHelper = *unit.sampler;
vk::ImageHelper &image = textureVk->getImage(); vk::ImageHelper &image = textureVk->getImage();
bool shouldUseLinearColorspace = textureVk->shouldUseLinearColorspaceWithTexelFetch(
linearColorspaceWithSampler, samplerUniform.texelFetchStaticUse);
imageInfos[arrayElement].sampler = samplerHelper.get().getHandle(); imageInfos[arrayElement].sampler = samplerHelper.get().getHandle();
imageInfos[arrayElement].imageLayout = image.getCurrentLayout(); imageInfos[arrayElement].imageLayout = image.getCurrentLayout();
...@@ -1474,13 +1471,13 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex ...@@ -1474,13 +1471,13 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex
// basically the same image view as read, except it's a 2DArray view for // basically the same image view as read, except it's a 2DArray view for
// cube maps. // cube maps.
const vk::ImageView &imageView = textureVk->getFetchImageViewAndRecordUse( const vk::ImageView &imageView = textureVk->getFetchImageViewAndRecordUse(
contextVk, shouldUseLinearColorspace); contextVk, unit.srgbDecode, samplerUniform.texelFetchStaticUse);
imageInfos[arrayElement].imageView = imageView.getHandle(); imageInfos[arrayElement].imageView = imageView.getHandle();
} }
else else
{ {
const vk::ImageView &imageView = textureVk->getReadImageViewAndRecordUse( const vk::ImageView &imageView = textureVk->getReadImageViewAndRecordUse(
contextVk, shouldUseLinearColorspace); contextVk, unit.srgbDecode, samplerUniform.texelFetchStaticUse);
imageInfos[arrayElement].imageView = imageView.getHandle(); imageInfos[arrayElement].imageView = imageView.getHandle();
} }
......
...@@ -32,8 +32,6 @@ class SamplerVk : public SamplerImpl ...@@ -32,8 +32,6 @@ class SamplerVk : public SamplerImpl
return mSampler.get(); return mSampler.get();
} }
bool skipSamplerSRGBDecode() const { return mState.getSRGBDecode() == GL_SKIP_DECODE_EXT; }
private: private:
vk::SamplerBinding mSampler; vk::SamplerBinding mSampler;
}; };
......
...@@ -175,12 +175,14 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface ...@@ -175,12 +175,14 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
void releaseOwnershipOfImage(const gl::Context *context); void releaseOwnershipOfImage(const gl::Context *context);
const vk::ImageView &getReadImageViewAndRecordUse(ContextVk *contextVk, const vk::ImageView &getReadImageViewAndRecordUse(ContextVk *contextVk,
bool useLinearColorspace) const; GLenum srgbDecode,
bool texelFetchStaticUse) const;
// A special view for cube maps as a 2D array, used with shaders that do texelFetch() and for // A special view for cube maps as a 2D array, used with shaders that do texelFetch() and for
// seamful cube map emulation. // seamful cube map emulation.
const vk::ImageView &getFetchImageViewAndRecordUse(ContextVk *contextVk, const vk::ImageView &getFetchImageViewAndRecordUse(ContextVk *contextVk,
bool useLinearColorspace) const; GLenum srgbDecode,
bool texelFetchStaticUse) const;
// A special view used for texture copies that shouldn't perform swizzle. // A special view used for texture copies that shouldn't perform swizzle.
const vk::ImageView &getCopyImageViewAndRecordUse(ContextVk *contextVk) const; const vk::ImageView &getCopyImageViewAndRecordUse(ContextVk *contextVk) const;
...@@ -218,11 +220,12 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface ...@@ -218,11 +220,12 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
ANGLE_INLINE bool hasBeenBoundAsImage() const { return mState.hasBeenBoundAsImage(); } ANGLE_INLINE bool hasBeenBoundAsImage() const { return mState.hasBeenBoundAsImage(); }
ANGLE_INLINE bool hasSRGBViews() const { return mRequiresSRGBViews; } bool isSRGBOverrideEnabled() const
{
return mState.getSRGBOverride() != gl::SrgbOverride::Default;
}
bool shouldUseLinearColorspaceWithSampler(const SamplerVk *samplerVk) const; angle::Result ensureMutable(ContextVk *contextVk);
bool shouldUseLinearColorspaceWithTexelFetch(bool colorspaceWithSampler,
bool texelFetchForcesDecodeOn) const;
private: private:
// Transform an image index from the frontend into one that can be used on the backing // Transform an image index from the frontend into one that can be used on the backing
...@@ -395,11 +398,11 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface ...@@ -395,11 +398,11 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
const vk::Format &getBaseLevelFormat(RendererVk *renderer) const; const vk::Format &getBaseLevelFormat(RendererVk *renderer) const;
// Queues a flush of any modified image attributes. The image will be reallocated with its new // Queues a flush of any modified image attributes. The image will be reallocated with its new
// attributes at the next opportunity. // attributes at the next opportunity.
angle::Result respecifyImageAttributes(ContextVk *contextVk); angle::Result respecifyImageStorage(ContextVk *contextVk);
angle::Result respecifyImageAttributesAndLevels(ContextVk *contextVk, angle::Result respecifyImageStorageAndLevels(ContextVk *contextVk,
gl::LevelIndex previousBaseLevelGL, gl::LevelIndex previousBaseLevelGL,
gl::LevelIndex baseLevelGL, gl::LevelIndex baseLevelGL,
gl::LevelIndex maxLevelGL); gl::LevelIndex maxLevelGL);
// Update base and max levels, and re-create image if needed. // Update base and max levels, and re-create image if needed.
angle::Result updateBaseMaxLevels(ContextVk *contextVk, angle::Result updateBaseMaxLevels(ContextVk *contextVk,
...@@ -419,8 +422,12 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface ...@@ -419,8 +422,12 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
return (mImage->valid()) ? mImage->getTilingMode() : VK_IMAGE_TILING_OPTIMAL; return (mImage->valid()) ? mImage->getTilingMode() : VK_IMAGE_TILING_OPTIMAL;
} }
angle::Result refreshImageViews(ContextVk *contextVk);
bool shouldDecodeSRGB(ContextVk *contextVk, GLenum srgbDecode, bool texelFetchStaticUse) const;
void initImageUsageFlags(ContextVk *contextVk, const vk::Format &format);
bool mOwnsImage; bool mOwnsImage;
bool mRequiresSRGBViews; bool mRequiresMutableStorage;
gl::TextureType mImageNativeType; gl::TextureType mImageNativeType;
......
...@@ -325,19 +325,10 @@ ANGLE_INLINE VkFormat ConvertToLinear(VkFormat format) ...@@ -325,19 +325,10 @@ ANGLE_INLINE VkFormat ConvertToLinear(VkFormat format)
} }
} }
ANGLE_INLINE bool IsSRGBFormat(VkFormat format)
{
return ConvertToLinear(format) != VK_FORMAT_UNDEFINED;
}
ANGLE_INLINE bool IsOverridableLinearFormat(VkFormat format) ANGLE_INLINE bool IsOverridableLinearFormat(VkFormat format)
{ {
return ConvertToSRGB(format) != VK_FORMAT_UNDEFINED; return ConvertToSRGB(format) != VK_FORMAT_UNDEFINED;
} }
ANGLE_INLINE bool IsLinearFormat(VkFormat format)
{
return !IsSRGBFormat(format);
}
} // namespace vk } // namespace vk
} // namespace rx } // namespace rx
......
...@@ -5975,7 +5975,7 @@ angle::Result ImageViewHelper::initReadViewsImpl(ContextVk *contextVk, ...@@ -5975,7 +5975,7 @@ angle::Result ImageViewHelper::initReadViewsImpl(ContextVk *contextVk,
ASSERT(mImageViewSerial.valid()); ASSERT(mImageViewSerial.valid());
const VkImageAspectFlags aspectFlags = GetFormatAspectFlags(format.intendedFormat()); const VkImageAspectFlags aspectFlags = GetFormatAspectFlags(format.intendedFormat());
mLinearColorspace = IsLinearFormat(format.vkImageFormat); mLinearColorspace = !format.actualImageFormat().isSRGB;
if (HasBothDepthAndStencilAspects(aspectFlags)) if (HasBothDepthAndStencilAspects(aspectFlags))
{ {
......
...@@ -44,7 +44,7 @@ struct TextureUnit final ...@@ -44,7 +44,7 @@ struct TextureUnit final
{ {
TextureVk *texture; TextureVk *texture;
const SamplerHelper *sampler; const SamplerHelper *sampler;
bool useLinearImageView; GLenum srgbDecode;
}; };
// A dynamic buffer is conceptually an infinitely long buffer. Each time you write to the buffer, // A dynamic buffer is conceptually an infinitely long buffer. Each time you write to the buffer,
......
...@@ -719,6 +719,10 @@ class ImageTest : public ANGLETest ...@@ -719,6 +719,10 @@ class ImageTest : public ANGLETest
bool hasImageGLColorspaceExt() const bool hasImageGLColorspaceExt() const
{ {
// Vulkan back-end bug: http://anglebug.com/5209
if (IsVulkan())
return false;
return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), kImageGLColorspaceExt); return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), kImageGLColorspaceExt);
} }
......
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