Commit 81db1a46 by Mohan Maiya Committed by Angle LUCI CQ

Vulkan: TextureVk inherits a few attributes from ImageHelper

Cache VkImageCreateFlags in ImageHelper. This allows texture target siblings to inherit a few VkImage create attributes thus avoiding image respecification in certain code paths. Bug: angleproject:2514 Bug: angleproject:5281 Test: PbufferTest.ClearAndBindTexImageSrgbSkipDecode*Vulkan Change-Id: Ic7397fabdce185264e06488355ca47f809338519 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2910473 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 fad9053f
...@@ -1305,8 +1305,6 @@ angle::Result TextureVk::setEGLImageTarget(const gl::Context *context, ...@@ -1305,8 +1305,6 @@ angle::Result TextureVk::setEGLImageTarget(const gl::Context *context,
imageVk->getImageLevel().get(), imageVk->getImageLayer(), imageVk->getImageLevel().get(), imageVk->getImageLayer(),
gl::LevelIndex(mState.getEffectiveBaseLevel()), false); gl::LevelIndex(mState.getEffectiveBaseLevel()), false);
initImageUsageFlags(contextVk, format);
ASSERT(type != gl::TextureType::CubeMap); ASSERT(type != gl::TextureType::CubeMap);
ANGLE_TRY(initImageViews(contextVk, format, image->getFormat().info->sized, 1, 1)); ANGLE_TRY(initImageViews(contextVk, format, image->getFormat().info->sized, 1, 1));
...@@ -1480,6 +1478,15 @@ void TextureVk::setImageHelper(ContextVk *contextVk, ...@@ -1480,6 +1478,15 @@ void TextureVk::setImageHelper(ContextVk *contextVk,
renderTargets.clear(); renderTargets.clear();
} }
if (!selfOwned)
{
// (!selfOwned) implies that the texture is a target sibling.
// Inherit a few VkImage's create attributes from ImageHelper.
mImageCreateFlags = mImage->getCreateFlags();
mImageUsageFlags = mImage->getUsage();
mRequiresMutableStorage = (mImageCreateFlags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) != 0;
}
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
getImageViews().init(renderer); getImageViews().init(renderer);
......
...@@ -3731,6 +3731,7 @@ ImageHelper::ImageHelper(ImageHelper &&other) ...@@ -3731,6 +3731,7 @@ ImageHelper::ImageHelper(ImageHelper &&other)
mDeviceMemory(std::move(other.mDeviceMemory)), mDeviceMemory(std::move(other.mDeviceMemory)),
mImageType(other.mImageType), mImageType(other.mImageType),
mTilingMode(other.mTilingMode), mTilingMode(other.mTilingMode),
mCreateFlags(other.mCreateFlags),
mUsage(other.mUsage), mUsage(other.mUsage),
mExtents(other.mExtents), mExtents(other.mExtents),
mRotatedAspectRatio(other.mRotatedAspectRatio), mRotatedAspectRatio(other.mRotatedAspectRatio),
...@@ -3765,6 +3766,7 @@ void ImageHelper::resetCachedProperties() ...@@ -3765,6 +3766,7 @@ void ImageHelper::resetCachedProperties()
{ {
mImageType = VK_IMAGE_TYPE_2D; mImageType = VK_IMAGE_TYPE_2D;
mTilingMode = VK_IMAGE_TILING_OPTIMAL; mTilingMode = VK_IMAGE_TILING_OPTIMAL;
mCreateFlags = kVkImageCreateFlagsNone;
mUsage = 0; mUsage = 0;
mExtents = {}; mExtents = {};
mRotatedAspectRatio = false; mRotatedAspectRatio = false;
...@@ -3938,6 +3940,7 @@ angle::Result ImageHelper::initExternal(Context *context, ...@@ -3938,6 +3940,7 @@ angle::Result ImageHelper::initExternal(Context *context,
mFirstAllocatedLevel = firstLevel; mFirstAllocatedLevel = firstLevel;
mLevelCount = mipLevels; mLevelCount = mipLevels;
mLayerCount = layerCount; mLayerCount = layerCount;
mCreateFlags = GetImageCreateFlags(textureType) | additionalCreateFlags;
mUsage = usage; mUsage = usage;
// Validate that mLayerCount is compatible with the texture type // Validate that mLayerCount is compatible with the texture type
...@@ -3968,7 +3971,7 @@ angle::Result ImageHelper::initExternal(Context *context, ...@@ -3968,7 +3971,7 @@ angle::Result ImageHelper::initExternal(Context *context,
imageFormatListEnabled = true; imageFormatListEnabled = true;
// Add VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT to VkImage create flag // Add VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT to VkImage create flag
additionalCreateFlags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; mCreateFlags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
// There is just 1 additional format we might use to create a VkImageView for this // There is just 1 additional format we might use to create a VkImageView for this
// VkImage // VkImage
...@@ -3986,7 +3989,7 @@ angle::Result ImageHelper::initExternal(Context *context, ...@@ -3986,7 +3989,7 @@ angle::Result ImageHelper::initExternal(Context *context,
VkImageCreateInfo imageInfo = {}; VkImageCreateInfo imageInfo = {};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageInfo.pNext = (imageFormatListEnabled) ? &imageFormatListInfo : externalImageCreateInfo; imageInfo.pNext = (imageFormatListEnabled) ? &imageFormatListInfo : externalImageCreateInfo;
imageInfo.flags = GetImageCreateFlags(textureType) | additionalCreateFlags; imageInfo.flags = mCreateFlags;
imageInfo.imageType = mImageType; imageInfo.imageType = mImageType;
imageInfo.format = format.actualImageVkFormat(); imageInfo.format = format.actualImageVkFormat();
imageInfo.extent = mExtents; imageInfo.extent = mExtents;
......
...@@ -1562,6 +1562,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -1562,6 +1562,7 @@ class ImageHelper final : public Resource, public angle::Subject
void setTilingMode(VkImageTiling tilingMode) { mTilingMode = tilingMode; } void setTilingMode(VkImageTiling tilingMode) { mTilingMode = tilingMode; }
VkImageTiling getTilingMode() const { return mTilingMode; } VkImageTiling getTilingMode() const { return mTilingMode; }
VkImageCreateFlags getCreateFlags() const { return mCreateFlags; }
VkImageUsageFlags getUsage() const { return mUsage; } VkImageUsageFlags getUsage() const { return mUsage; }
VkImageType getType() const { return mImageType; } VkImageType getType() const { return mImageType; }
const VkExtent3D &getExtents() const { return mExtents; } const VkExtent3D &getExtents() const { return mExtents; }
...@@ -2054,6 +2055,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -2054,6 +2055,7 @@ class ImageHelper final : public Resource, public angle::Subject
// Image properties. // Image properties.
VkImageType mImageType; VkImageType mImageType;
VkImageTiling mTilingMode; VkImageTiling mTilingMode;
VkImageCreateFlags mCreateFlags;
VkImageUsageFlags mUsage; VkImageUsageFlags mUsage;
// For Android swapchain images, the Vulkan VkImage must be "rotated". However, most of ANGLE // For Android swapchain images, the Vulkan VkImage must be "rotated". However, most of ANGLE
// uses non-rotated extents (i.e. the way the application views the extents--see "Introduction // uses non-rotated extents (i.e. the way the application views the extents--see "Introduction
......
...@@ -298,6 +298,87 @@ TEST_P(PbufferTest, ClearAndBindTexImageSrgb) ...@@ -298,6 +298,87 @@ TEST_P(PbufferTest, ClearAndBindTexImageSrgb)
glDeleteTextures(1, &texture); glDeleteTextures(1, &texture);
} }
// Test clearing a Pbuffer in sRGB colorspace and checking the color is correct.
// Then bind the Pbuffer to a texture and verify it renders correctly.
// Then change texture state to skip decode and verify it renders correctly.
TEST_P(PbufferTest, ClearAndBindTexImageSrgbSkipDecode)
{
EGLWindow *window = getEGLWindow();
// Test skipped because Pbuffers are not supported or Pbuffer does not support binding to RGBA
// textures.
ANGLE_SKIP_TEST_IF(!mSupportsPbuffers || !mSupportsBindTexImage);
ANGLE_SKIP_TEST_IF(
!IsEGLDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_colorspace"));
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_sRGB_decode"));
// Possible GLES driver bug on Pixel devices: http://anglebug.com/5321
ANGLE_SKIP_TEST_IF((IsPixel2() || IsPixel4()) && IsOpenGLES());
GLubyte kLinearColor[] = {132, 55, 219, 255};
GLubyte kSrgbColor[] = {190, 128, 238, 255};
// Switch to sRGB
recreatePbufferInSrgbColorspace();
EGLint colorspace = 0;
eglQuerySurface(window->getDisplay(), mPbuffer, EGL_GL_COLORSPACE, &colorspace);
EXPECT_EQ(colorspace, EGL_GL_COLORSPACE_SRGB_KHR);
// Clear the Pbuffer surface with `kLinearColor`
eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
ASSERT_EGL_SUCCESS();
glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize));
glClearColor(kLinearColor[0] / 255.0f, kLinearColor[1] / 255.0f, kLinearColor[2] / 255.0f,
kLinearColor[3] / 255.0f);
glClear(GL_COLOR_BUFFER_BIT);
ASSERT_GL_NO_ERROR();
// Expect glReadPixels to be `kSrgbColor` with a tolerance of 1
EXPECT_PIXEL_NEAR(static_cast<GLint>(mPbufferSize) / 2, static_cast<GLint>(mPbufferSize) / 2,
kSrgbColor[0], kSrgbColor[1], kSrgbColor[2], kSrgbColor[3], 1);
window->makeCurrent();
// Create a texture and bind the Pbuffer to it
GLuint texture = 0;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
EXPECT_GL_NO_ERROR();
eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
glViewport(0, 0, getWindowWidth(), getWindowHeight());
ASSERT_EGL_SUCCESS();
// Sample from a texture with `kSrgbColor` data and render into a surface in linear colorspace.
glUseProgram(mTextureProgram);
glUniform1i(mTextureUniformLocation, 0);
drawQuad(mTextureProgram, "position", 0.5f);
EXPECT_GL_NO_ERROR();
// Expect glReadPixels to be `kLinearColor` with a tolerance of 1
EXPECT_PIXEL_NEAR(getWindowWidth() / 2, getWindowHeight() / 2, kLinearColor[0], kLinearColor[1],
kLinearColor[2], kLinearColor[3], 1);
// Set skip decode for the texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
drawQuad(mTextureProgram, "position", 0.5f);
// Texture is in skip decode mode, expect glReadPixels to be `kSrgbColor`
EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, kSrgbColor[0], kSrgbColor[1],
kSrgbColor[2], kSrgbColor[3]);
// Unbind the texture
eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
ASSERT_EGL_SUCCESS();
glDeleteTextures(1, &texture);
}
// Verify that when eglBind/ReleaseTexImage are called, the texture images are freed and their // Verify that when eglBind/ReleaseTexImage are called, the texture images are freed and their
// size information is correctly updated. // size information is correctly updated.
TEST_P(PbufferTest, TextureSizeReset) TEST_P(PbufferTest, TextureSizeReset)
......
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