Skip to content

Commit

Permalink
Vulkan: Cleanup sRGB related code
Browse files Browse the repository at this point in the history
Image and image view code is littered with sRGB related enums, even
in places that don't deal with sRGB. Remove sRGB related parameters
from initLayerImageView and getLevelLayerDrawImageView methods, which
now assume default values. Add dedicated methods that allow overriding
sRGB state values.

Also introduce ColorspaceState struct that consolidates all sRGB
related  states, this will be used in follow up changes to track
and infer colorspace of image views

Bug: angleproject:40644776
Change-Id: Ifb366db48043e376f9ff6c30c852c44dd96562a1
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5860808
Reviewed-by: Shahbaz Youssefi <[email protected]>
Reviewed-by: Charlie Lao <[email protected]>
Commit-Queue: mohan maiya <[email protected]>
  • Loading branch information
Mohan Maiya authored and Angle LUCI CQ committed Sep 17, 2024
1 parent 44bbfbd commit 1b4d618
Show file tree
Hide file tree
Showing 11 changed files with 251 additions and 136 deletions.
75 changes: 62 additions & 13 deletions src/common/utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,26 +239,36 @@ const char *GetDebugMessageSourceString(GLenum source);
const char *GetDebugMessageTypeString(GLenum type);
const char *GetDebugMessageSeverityString(GLenum severity);

// For use with EXT_texture_format_sRGB_override and EXT_texture_sRGB_decode
// A texture may be forced to decode to a nonlinear colorspace, to a linear colorspace, or to the
// default colorspace of its current format.
// For use with EXT_texture_sRGB_decode
// A texture may be forced to skip decoding to a linear colorspace even if its format
// is in sRGB colorspace.
//
// Default corresponds to "the texture should use the imageview that corresponds to its format"
// Linear corresponds to "the texture has sRGB decoding disabled by extension, and should use a
// linear imageview even if it is in a nonlinear format" NonLinear corresponds to "the texture has
// sRGB override enabled by extension, and should use a nonlinear imageview even if it is in a
// linear format"
// Default - decode data according to the image's format's colorspace
// Skip - data is not decoded during sampling
enum class SrgbDecode
{
Default = 0,
Skip
};

// For use with EXT_texture_format_sRGB_override
// A texture may be forced to decode data to linear colorspace even if its format
// is in linear colorspace.
//
// Default - decode data according to the image's format's colorspace
// SRGB - data will be decoded to linear colorspace irrespective of texture's format
enum class SrgbOverride
{
Default = 0,
SRGB,
Linear
SRGB
};

// For use with EXT_sRGB_write_control
// A render target may be forced to convert to a linear colorspace, or may be allowed to do whatever
// colorspace conversion is appropriate for its format. There is no option to force linear->sRGB, it
// can only convert from sRGB->linear
// A framebuffer may be forced to not encode data to sRGB colorspace even if its format
// is in sRGB colorspace.
//
// Default - encode data according to the image's format's colorspace
// Linear - data will not be encoded into sRGB colorspace
enum class SrgbWriteControlMode
{
Default = 0,
Expand All @@ -285,6 +295,19 @@ ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes);

namespace egl
{
// For use with EGL_EXT_image_gl_colorspace
// An EGLImage can be created with attributes that override the color space of underlying image data
// when rendering to the image, or sampling from the image. The possible values are -
// Default - EGLImage source's colorspace should be preserved
// sRGB - EGLImage targets will assume sRGB colorspace
// Linear - EGLImage targets will assume linear colorspace
enum class ImageColorspace
{
Default = 0,
SRGB,
Linear
};

static const EGLenum FirstCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR;
static const EGLenum LastCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR;
bool IsCubeMapTextureTarget(EGLenum target);
Expand All @@ -311,6 +334,32 @@ EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle);
namespace angle
{

// All state that modify attachment's colorspace
struct ColorspaceState
{
public:
ColorspaceState() { reset(); }
void reset()
{
hasStaticTexelFetchAccess = false;
srgbDecode = gl::SrgbDecode::Default;
srgbOverride = gl::SrgbOverride::Default;
srgbWriteControl = gl::SrgbWriteControlMode::Default;
eglImageColorspace = egl::ImageColorspace::Default;
}

// States that affect read operations
bool hasStaticTexelFetchAccess;
gl::SrgbDecode srgbDecode;
gl::SrgbOverride srgbOverride;

// States that affect write operations
gl::SrgbWriteControlMode srgbWriteControl;

// States that affect both read and write operations
egl::ImageColorspace eglImageColorspace;
};

template <typename T>
constexpr size_t ConstStrLen(T s)
{
Expand Down
1 change: 0 additions & 1 deletion src/libANGLE/capture/serialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ const char *SrgbOverrideToString(gl::SrgbOverride value)
{
ENUM_TO_STRING(gl::SrgbOverride, Default);
ENUM_TO_STRING(gl::SrgbOverride, SRGB);
ENUM_TO_STRING(gl::SrgbOverride, Linear);
default:
return "invalid";
}
Expand Down
3 changes: 1 addition & 2 deletions src/libANGLE/renderer/vulkan/ContextVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4578,8 +4578,7 @@ angle::Result ContextVk::optimizeRenderPassForPresent(vk::ImageViewHelper *color
// Add the resolve attachment to the render pass
const vk::ImageView *resolveImageView = nullptr;
ANGLE_TRY(colorImageView->getLevelLayerDrawImageView(this, *colorImage, vk::LevelIndex(0),
0, gl::SrgbWriteControlMode::Default,
&resolveImageView));
0, &resolveImageView));

mRenderPassCommands->addColorResolveAttachment(0, colorImage, resolveImageView->getHandle(),
gl::LevelIndex(0), 0, 1, {});
Expand Down
13 changes: 4 additions & 9 deletions src/libANGLE/renderer/vulkan/FramebufferVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1586,18 +1586,14 @@ angle::Result FramebufferVk::blit(const gl::Context *context,
{
ANGLE_TRY(depthStencilImage->initLayerImageView(
contextVk, textureType, VK_IMAGE_ASPECT_DEPTH_BIT, gl::SwizzleState(),
&depthView.get(), levelIndex, 1, layerIndex, 1,
gl::SrgbWriteControlMode::Default, gl::YuvSamplingMode::Default,
vk::ImageHelper::kDefaultImageViewUsageFlags));
&depthView.get(), levelIndex, 1, layerIndex, 1));
}

if (blitStencilBuffer)
{
ANGLE_TRY(depthStencilImage->initLayerImageView(
contextVk, textureType, VK_IMAGE_ASPECT_STENCIL_BIT, gl::SwizzleState(),
&stencilView.get(), levelIndex, 1, layerIndex, 1,
gl::SrgbWriteControlMode::Default, gl::YuvSamplingMode::Default,
vk::ImageHelper::kDefaultImageViewUsageFlags));
&stencilView.get(), levelIndex, 1, layerIndex, 1));
}

// If shader stencil export is not possible, defer stencil blit/resolve to another
Expand Down Expand Up @@ -1944,9 +1940,8 @@ angle::Result FramebufferVk::updateFoveationState(ContextVk *contextVk,
foveatedAttachmentSize));
ASSERT(mFragmentShadingRateImage.valid());

serial = mFragmentShadingRateImageView.getSubresourceSerial(
gl::LevelIndex(0), 1, 0, vk::LayerMode::All, vk::SrgbDecodeMode::SkipDecode,
gl::SrgbOverride::Default);
serial = mFragmentShadingRateImageView.getSubresourceSerial(gl::LevelIndex(0), 1, 0,
vk::LayerMode::All);
}

// Update state after the possible failure point.
Expand Down
6 changes: 3 additions & 3 deletions src/libANGLE/renderer/vulkan/OverlayVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ angle::Result OverlayVk::createFont(ContextVk *contextVk)
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
vk::MemoryAllocationType::FontImage));

ANGLE_TRY(mFontImage.initImageView(
ANGLE_TRY(mFontImage.initLayerImageView(
contextVk, gl::TextureType::_2DArray, VK_IMAGE_ASPECT_COLOR_BIT, gl::SwizzleState(),
&mFontImageView, vk::LevelIndex(0), gl::overlay::kFontMipCount,
vk::ImageHelper::kDefaultImageViewUsageFlags));
&mFontImageView, vk::LevelIndex(0), gl::overlay::kFontMipCount, 0,
mFontImage.getLayerCount()));

// Copy font data from staging buffer.
vk::CommandBufferAccess access;
Expand Down
7 changes: 3 additions & 4 deletions src/libANGLE/renderer/vulkan/RenderTargetVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ vk::ImageOrBufferViewSubresourceSerial RenderTargetVk::getSubresourceSerialImpl(

vk::LayerMode layerMode = vk::GetLayerMode(*mImage, mLayerCount);
vk::ImageOrBufferViewSubresourceSerial imageViewSerial =
imageViews->getSubresourceSerial(mLevelIndexGL, 1, mLayerIndex, layerMode,
vk::SrgbDecodeMode::SkipDecode, gl::SrgbOverride::Default);
imageViews->getSubresourceSerial(mLevelIndexGL, 1, mLayerIndex, layerMode);
return imageViewSerial;
}

Expand Down Expand Up @@ -192,8 +191,8 @@ angle::Result RenderTargetVk::getImageViewImpl(vk::Context *context,
vk::LevelIndex levelVk = image.toVkLevel(getLevelIndexForImage(image));
if (mLayerCount == 1)
{
return imageViews->getLevelLayerDrawImageView(context, image, levelVk, mLayerIndex, mode,
imageViewOut);
return imageViews->getLevelLayerDrawImageViewWithSrgbWriteControlMode(
context, image, levelVk, mLayerIndex, mode, imageViewOut);
}

// Layered render targets view the whole level or a handful of layers in case of multiview.
Expand Down
8 changes: 3 additions & 5 deletions src/libANGLE/renderer/vulkan/SurfaceVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3041,8 +3041,7 @@ angle::Result WindowSurfaceVk::getCurrentFramebuffer(ContextVk *contextVk,
{
const vk::ImageView *imageView = nullptr;
ANGLE_TRY(swapchainImage.imageViews.getLevelLayerDrawImageView(
contextVk, *swapchainImage.image, vk::LevelIndex(0), 0,
gl::SrgbWriteControlMode::Default, &imageView));
contextVk, *swapchainImage.image, vk::LevelIndex(0), 0, &imageView));
imageViews[0] = imageView->getHandle();
}

Expand Down Expand Up @@ -3145,9 +3144,8 @@ angle::Result WindowSurfaceVk::drawOverlay(ContextVk *contextVk, SwapchainImage

// Draw overlay
const vk::ImageView *imageView = nullptr;
ANGLE_TRY(image->imageViews.getLevelLayerDrawImageView(
contextVk, *image->image, vk::LevelIndex(0), 0, gl::SrgbWriteControlMode::Default,
&imageView));
ANGLE_TRY(image->imageViews.getLevelLayerDrawImageView(contextVk, *image->image,
vk::LevelIndex(0), 0, &imageView));
ANGLE_TRY(overlayVk->onPresent(contextVk, image->image.get(), imageView,
Is90DegreeRotation(getPreTransform())));

Expand Down
24 changes: 9 additions & 15 deletions src/libANGLE/renderer/vulkan/TextureVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1666,9 +1666,7 @@ angle::Result TextureVk::copySubImageImplWithDraw(ContextVk *contextVk,
vk::ImageView stagingView;
ANGLE_TRY(stagingImage->get().initLayerImageView(
contextVk, stagingTextureType, VK_IMAGE_ASPECT_COLOR_BIT, gl::SwizzleState(),
&stagingView, vk::LevelIndex(0), 1, layerIndex, 1,
gl::SrgbWriteControlMode::Default, gl::YuvSamplingMode::Default,
vk::ImageHelper::kDefaultImageViewUsageFlags));
&stagingView, vk::LevelIndex(0), 1, layerIndex, 1));

ANGLE_TRY(utilsVk.copyImage(contextVk, &stagingImage->get(), &stagingView, srcImage,
srcView, params));
Expand Down Expand Up @@ -2271,9 +2269,8 @@ angle::Result TextureVk::generateMipmapsWithCompute(ContextVk *contextVk)
const vk::ImageView *srcView = nullptr;
UtilsVk::GenerateMipmapDestLevelViews destLevelViews = {};

ANGLE_TRY(getImageViews().getLevelLayerDrawImageView(
contextVk, *mImage, srcLevelVk, layer, gl::SrgbWriteControlMode::Default,
&srcView));
ANGLE_TRY(getImageViews().getLevelLayerDrawImageView(contextVk, *mImage, srcLevelVk,
layer, &srcView));

vk::LevelIndex dstLevelCount = maxGenerateLevels;
for (vk::LevelIndex levelVk(0); levelVk < maxGenerateLevels; ++levelVk)
Expand All @@ -2288,8 +2285,7 @@ angle::Result TextureVk::generateMipmapsWithCompute(ContextVk *contextVk)
}

ANGLE_TRY(getImageViews().getLevelLayerDrawImageView(
contextVk, *mImage, dstLevelVk, layer, gl::SrgbWriteControlMode::Default,
&destLevelViews[levelVk.get()]));
contextVk, *mImage, dstLevelVk, layer, &destLevelViews[levelVk.get()]));
}

// If the image has fewer than maximum levels, fill the last views with a unused view.
Expand Down Expand Up @@ -3492,8 +3488,8 @@ angle::Result TextureVk::getLevelLayerImageView(vk::Context *context,
vk::LevelIndex levelVk = mImage->toVkLevel(levelGL);
uint32_t nativeLayer = getNativeImageLayer(static_cast<uint32_t>(layer));

return getImageViews().getLevelLayerDrawImageView(
context, *mImage, levelVk, nativeLayer, gl::SrgbWriteControlMode::Default, imageViewOut);
return getImageViews().getLevelLayerDrawImageView(context, *mImage, levelVk, nativeLayer,
imageViewOut);
}

angle::Result TextureVk::getStorageImageView(vk::Context *context,
Expand Down Expand Up @@ -4134,8 +4130,8 @@ vk::ImageOrBufferViewSubresourceSerial TextureVk::getImageViewSubresourceSerialI
? gl::SrgbOverride::SRGB
: gl::SrgbOverride::Default;

return getImageViews().getSubresourceSerial(baseLevel, levelCount, 0, vk::LayerMode::All,
srgbDecodeMode, srgbOverrideMode);
return getImageViews().getSubresourceSerialWithSrgbModeOverrides(
baseLevel, levelCount, 0, vk::LayerMode::All, srgbDecodeMode, srgbOverrideMode);
}

vk::ImageOrBufferViewSubresourceSerial TextureVk::getBufferViewSerial() const
Expand All @@ -4153,9 +4149,7 @@ vk::ImageOrBufferViewSubresourceSerial TextureVk::getStorageImageViewSerial(
gl::LevelIndex baseLevel(
getNativeImageLevel(gl::LevelIndex(static_cast<uint32_t>(binding.level))));

return getImageViews().getSubresourceSerial(baseLevel, 1, nativeLayer, layerMode,
vk::SrgbDecodeMode::SkipDecode,
gl::SrgbOverride::Default);
return getImageViews().getSubresourceSerial(baseLevel, 1, nativeLayer, layerMode);
}

uint32_t TextureVk::getImageViewLayerCount() const
Expand Down
22 changes: 9 additions & 13 deletions src/libANGLE/renderer/vulkan/UtilsVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2709,10 +2709,9 @@ angle::Result UtilsVk::clearImage(ContextVk *contextVk,
vk::DeviceScoped<vk::ImageView> destView(contextVk->getDevice());
const gl::TextureType destViewType = vk::Get2DTextureType(1, dst->getSamples());

ANGLE_TRY(dst->initLayerImageView(
contextVk, destViewType, VK_IMAGE_ASPECT_COLOR_BIT, gl::SwizzleState(), &destView.get(),
params.dstMip, 1, params.dstLayer, 1, gl::SrgbWriteControlMode::Default,
gl::YuvSamplingMode::Default, vk::ImageHelper::kDefaultImageViewUsageFlags));
ANGLE_TRY(dst->initLayerImageView(contextVk, destViewType, VK_IMAGE_ASPECT_COLOR_BIT,
gl::SwizzleState(), &destView.get(), params.dstMip, 1,
params.dstLayer, 1));

const gl::Rectangle &renderArea = params.clearArea;

Expand Down Expand Up @@ -3785,11 +3784,10 @@ angle::Result UtilsVk::copyImageToBuffer(ContextVk *contextVk,
}

vk::DeviceScoped<vk::ImageView> srcView(contextVk->getDevice());
ANGLE_TRY(src->initLayerImageView(contextVk, textureType, src->getAspectFlags(), swizzle,
&srcView.get(), params.srcMip, 1,
textureType == gl::TextureType::_2D ? params.srcLayer : 0, 1,
gl::SrgbWriteControlMode::Linear,
gl::YuvSamplingMode::Default, VK_IMAGE_USAGE_SAMPLED_BIT));
ANGLE_TRY(src->initLayerImageViewWithSrgbWriteControlMode(
contextVk, textureType, src->getAspectFlags(), swizzle, &srcView.get(), params.srcMip, 1,
textureType == gl::TextureType::_2D ? params.srcLayer : 0, 1,
gl::SrgbWriteControlMode::Linear, VK_IMAGE_USAGE_SAMPLED_BIT));

vk::CommandBufferAccess access;
access.onImageComputeShaderRead(src->getAspectFlags(), src);
Expand Down Expand Up @@ -4186,17 +4184,15 @@ angle::Result UtilsVk::unresolve(ContextVk *contextVk,
{
ANGLE_TRY(depthStencilSrc->initLayerImageView(
contextVk, textureType, VK_IMAGE_ASPECT_DEPTH_BIT, gl::SwizzleState(),
&depthView.get(), levelIndex, 1, layerIndex, 1, gl::SrgbWriteControlMode::Default,
gl::YuvSamplingMode::Default, vk::ImageHelper::kDefaultImageViewUsageFlags));
&depthView.get(), levelIndex, 1, layerIndex, 1));
depthSrcView = &depthView.get();
}

if (params.unresolveStencil)
{
ANGLE_TRY(depthStencilSrc->initLayerImageView(
contextVk, textureType, VK_IMAGE_ASPECT_STENCIL_BIT, gl::SwizzleState(),
&stencilView.get(), levelIndex, 1, layerIndex, 1, gl::SrgbWriteControlMode::Default,
gl::YuvSamplingMode::Default, vk::ImageHelper::kDefaultImageViewUsageFlags));
&stencilView.get(), levelIndex, 1, layerIndex, 1));
stencilSrcView = &stencilView.get();
}
}
Expand Down
Loading

0 comments on commit 1b4d618

Please sign in to comment.