Commit c6601ec8 by James Dong Committed by Commit Bot

Vulkan: fix texture swizzle

Corrects texture swizzle in Vulkan backend. Previously user-supplied swizzle was applied before internal swizzle; this change applies the internal swizzle first, causing the correct behavior. Also recreates image views when swizzle is dirty. Test: ./angle_deqp_gles3_no_gtest --deqp-egl-display-type=angle-vulkan -n 'dEQP-GLES3.functional.texture.swizzle.*' Test: ./angle_end2end_tests --gtest_filter='SwizzleTest.*/ES3_Vulkan' Bug: angleproject:3212 Change-Id: Ie2c44b479da5c19ba744ace7562a73c944f97a49 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1660909 Commit-Queue: Courtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent f157aba5
...@@ -1186,6 +1186,18 @@ angle::Result TextureVk::syncState(const gl::Context *context, ...@@ -1186,6 +1186,18 @@ angle::Result TextureVk::syncState(const gl::Context *context,
contextVk->releaseObject(contextVk->getCurrentQueueSerial(), &mSampler); contextVk->releaseObject(contextVk->getCurrentQueueSerial(), &mSampler);
} }
if (dirtyBits.test(gl::Texture::DIRTY_BIT_SWIZZLE_RED) ||
dirtyBits.test(gl::Texture::DIRTY_BIT_SWIZZLE_GREEN) ||
dirtyBits.test(gl::Texture::DIRTY_BIT_SWIZZLE_BLUE) ||
dirtyBits.test(gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA))
{
if (mImage && mImage->valid())
{
releaseImageViews(contextVk);
ANGLE_TRY(initImageViews(contextVk, mImage->getFormat(), mImage->getLevelCount()));
}
}
const gl::Extensions &extensions = renderer->getNativeExtensions(); const gl::Extensions &extensions = renderer->getNativeExtensions();
const gl::SamplerState &samplerState = mState.getSamplerState(); const gl::SamplerState &samplerState = mState.getSamplerState();
...@@ -1436,6 +1448,13 @@ void TextureVk::releaseImage(ContextVk *contextVk) ...@@ -1436,6 +1448,13 @@ void TextureVk::releaseImage(ContextVk *contextVk)
} }
} }
releaseImageViews(contextVk);
mCubeMapRenderTargets.clear();
}
void TextureVk::releaseImageViews(ContextVk *contextVk)
{
Serial currentSerial = contextVk->getCurrentQueueSerial(); Serial currentSerial = contextVk->getCurrentQueueSerial();
contextVk->releaseObject(currentSerial, &mDrawBaseLevelImageView); contextVk->releaseObject(currentSerial, &mDrawBaseLevelImageView);
...@@ -1457,7 +1476,6 @@ void TextureVk::releaseImage(ContextVk *contextVk) ...@@ -1457,7 +1476,6 @@ void TextureVk::releaseImage(ContextVk *contextVk)
contextVk->releaseObject(currentSerial, &imageView); contextVk->releaseObject(currentSerial, &imageView);
} }
mLayerFetchImageView.clear(); mLayerFetchImageView.clear();
mCubeMapRenderTargets.clear();
} }
void TextureVk::releaseStagingBuffer(ContextVk *context) void TextureVk::releaseStagingBuffer(ContextVk *context)
......
...@@ -267,6 +267,7 @@ class TextureVk : public TextureImpl ...@@ -267,6 +267,7 @@ class TextureVk : public TextureImpl
const uint32_t levelCount, const uint32_t levelCount,
vk::CommandBuffer *commandBuffer); vk::CommandBuffer *commandBuffer);
void releaseImage(ContextVk *context); void releaseImage(ContextVk *context);
void releaseImageViews(ContextVk *contextVk);
void releaseStagingBuffer(ContextVk *context); void releaseStagingBuffer(ContextVk *context);
uint32_t getLevelCount() const; uint32_t getLevelCount() const;
angle::Result initImageViews(ContextVk *contextVk, angle::Result initImageViews(ContextVk *contextVk,
......
...@@ -269,64 +269,86 @@ size_t GetVertexInputAlignment(const vk::Format &format) ...@@ -269,64 +269,86 @@ size_t GetVertexInputAlignment(const vk::Format &format)
return format.vkBufferFormatIsPacked ? pixelBytes : (pixelBytes / bufferFormat.channelCount()); return format.vkBufferFormatIsPacked ? pixelBytes : (pixelBytes / bufferFormat.channelCount());
} }
GLenum GetSwizzleStateComponent(const gl::SwizzleState &swizzleState, GLenum component)
{
switch (component)
{
case GL_RED:
return swizzleState.swizzleRed;
case GL_GREEN:
return swizzleState.swizzleGreen;
case GL_BLUE:
return swizzleState.swizzleBlue;
case GL_ALPHA:
return swizzleState.swizzleAlpha;
default:
return component;
}
}
// Places the swizzle obtained by applying second after first into out.
void ComposeSwizzleState(const gl::SwizzleState &first,
const gl::SwizzleState &second,
gl::SwizzleState *out)
{
out->swizzleRed = GetSwizzleStateComponent(first, second.swizzleRed);
out->swizzleGreen = GetSwizzleStateComponent(first, second.swizzleGreen);
out->swizzleBlue = GetSwizzleStateComponent(first, second.swizzleBlue);
out->swizzleAlpha = GetSwizzleStateComponent(first, second.swizzleAlpha);
}
void MapSwizzleState(const vk::Format &format, void MapSwizzleState(const vk::Format &format,
const gl::SwizzleState &swizzleState, const gl::SwizzleState &swizzleState,
gl::SwizzleState *swizzleStateOut) gl::SwizzleState *swizzleStateOut)
{ {
const angle::Format &angleFormat = format.angleFormat(); const angle::Format &angleFormat = format.angleFormat();
if (angleFormat.isBlock) gl::SwizzleState internalSwizzle;
{
// No need to override swizzles for compressed images, as they are not emulated.
// Either way, angleFormat.xBits (with x in {red, green, blue, alpha}) is zero for blocked
// formats so the following code would incorrectly turn its swizzle to (0, 0, 0, 1).
return;
}
switch (format.internalFormat) switch (format.internalFormat)
{ {
case GL_LUMINANCE8_OES: case GL_LUMINANCE8_OES:
swizzleStateOut->swizzleRed = swizzleState.swizzleRed; internalSwizzle.swizzleRed = GL_RED;
swizzleStateOut->swizzleGreen = swizzleState.swizzleRed; internalSwizzle.swizzleGreen = GL_RED;
swizzleStateOut->swizzleBlue = swizzleState.swizzleRed; internalSwizzle.swizzleBlue = GL_RED;
swizzleStateOut->swizzleAlpha = GL_ONE; internalSwizzle.swizzleAlpha = GL_ONE;
break; break;
case GL_LUMINANCE8_ALPHA8_OES: case GL_LUMINANCE8_ALPHA8_OES:
swizzleStateOut->swizzleRed = swizzleState.swizzleRed; internalSwizzle.swizzleRed = GL_RED;
swizzleStateOut->swizzleGreen = swizzleState.swizzleRed; internalSwizzle.swizzleGreen = GL_RED;
swizzleStateOut->swizzleBlue = swizzleState.swizzleRed; internalSwizzle.swizzleBlue = GL_RED;
swizzleStateOut->swizzleAlpha = swizzleState.swizzleGreen; internalSwizzle.swizzleAlpha = GL_GREEN;
break; break;
case GL_ALPHA8_OES: case GL_ALPHA8_OES:
swizzleStateOut->swizzleRed = GL_ZERO; internalSwizzle.swizzleRed = GL_ZERO;
swizzleStateOut->swizzleGreen = GL_ZERO; internalSwizzle.swizzleGreen = GL_ZERO;
swizzleStateOut->swizzleBlue = GL_ZERO; internalSwizzle.swizzleBlue = GL_ZERO;
swizzleStateOut->swizzleAlpha = swizzleState.swizzleRed; internalSwizzle.swizzleAlpha = GL_RED;
break; break;
default: default:
if (angleFormat.hasDepthOrStencilBits()) if (angleFormat.hasDepthOrStencilBits())
{ {
swizzleStateOut->swizzleRed = internalSwizzle.swizzleRed = angleFormat.depthBits > 0 ? GL_RED : GL_ZERO;
angleFormat.depthBits > 0 ? swizzleState.swizzleRed : GL_ZERO; internalSwizzle.swizzleGreen = angleFormat.depthBits > 0 ? GL_RED : GL_ZERO;
swizzleStateOut->swizzleGreen = internalSwizzle.swizzleBlue = angleFormat.depthBits > 0 ? GL_RED : GL_ZERO;
angleFormat.depthBits > 0 ? swizzleState.swizzleRed : GL_ZERO; internalSwizzle.swizzleAlpha = GL_ONE;
swizzleStateOut->swizzleBlue =
angleFormat.depthBits > 0 ? swizzleState.swizzleRed : GL_ZERO;
swizzleStateOut->swizzleAlpha = GL_ONE;
} }
else else
{ {
if (angleFormat.isBlock)
{
// Color bits are all zero for blocked formats, so the
// below will erroneously set swizzle to (0, 0, 0, 1).
break;
}
// Set any missing channel to default in case the emulated format has that channel. // Set any missing channel to default in case the emulated format has that channel.
swizzleStateOut->swizzleRed = internalSwizzle.swizzleRed = angleFormat.redBits > 0 ? GL_RED : GL_ZERO;
angleFormat.redBits > 0 ? swizzleState.swizzleRed : GL_ZERO; internalSwizzle.swizzleGreen = angleFormat.greenBits > 0 ? GL_GREEN : GL_ZERO;
swizzleStateOut->swizzleGreen = internalSwizzle.swizzleBlue = angleFormat.blueBits > 0 ? GL_BLUE : GL_ZERO;
angleFormat.greenBits > 0 ? swizzleState.swizzleGreen : GL_ZERO; internalSwizzle.swizzleAlpha = angleFormat.alphaBits > 0 ? GL_ALPHA : GL_ONE;
swizzleStateOut->swizzleBlue =
angleFormat.blueBits > 0 ? swizzleState.swizzleBlue : GL_ZERO;
swizzleStateOut->swizzleAlpha =
angleFormat.alphaBits > 0 ? swizzleState.swizzleAlpha : GL_ONE;
} }
break; break;
} }
ComposeSwizzleState(internalSwizzle, swizzleState, swizzleStateOut);
} }
} // namespace rx } // namespace rx
...@@ -550,7 +550,6 @@ ...@@ -550,7 +550,6 @@
3189 VULKAN : dEQP-GLES3.functional.texture.wrap.* = SKIP 3189 VULKAN : dEQP-GLES3.functional.texture.wrap.* = SKIP
3189 VULKAN : dEQP-GLES3.functional.texture.filtering.* = SKIP 3189 VULKAN : dEQP-GLES3.functional.texture.filtering.* = SKIP
3189 VULKAN : dEQP-GLES3.functional.texture.mipmap.* = SKIP 3189 VULKAN : dEQP-GLES3.functional.texture.mipmap.* = SKIP
3189 VULKAN : dEQP-GLES3.functional.texture.swizzle.* = SKIP
3189 VULKAN : dEQP-GLES3.functional.texture.shadow.2d_array.* = SKIP 3189 VULKAN : dEQP-GLES3.functional.texture.shadow.2d_array.* = SKIP
3189 VULKAN : dEQP-GLES3.functional.texture.specification.* = SKIP 3189 VULKAN : dEQP-GLES3.functional.texture.specification.* = SKIP
3189 VULKAN : dEQP-GLES3.functional.texture.vertex.* = SKIP 3189 VULKAN : dEQP-GLES3.functional.texture.vertex.* = SKIP
......
...@@ -287,6 +287,7 @@ TEST_P(SwizzleTest, RGBA32F_2D) ...@@ -287,6 +287,7 @@ TEST_P(SwizzleTest, RGBA32F_2D)
TEST_P(SwizzleTest, RGB32F_2D) TEST_P(SwizzleTest, RGB32F_2D)
{ {
ANGLE_SKIP_TEST_IF(IsVulkan()); // anglebug.com/2898 - float textures
GLfloat data[] = {0.1f, 0.2f, 0.3f}; GLfloat data[] = {0.1f, 0.2f, 0.3f};
init2DTexture(GL_RGB32F, GL_RGB, GL_FLOAT, data); init2DTexture(GL_RGB32F, GL_RGB, GL_FLOAT, data);
runTest2D(); runTest2D();
...@@ -322,6 +323,7 @@ TEST_P(SwizzleTest, D16_2D) ...@@ -322,6 +323,7 @@ TEST_P(SwizzleTest, D16_2D)
TEST_P(SwizzleTest, D24_2D) TEST_P(SwizzleTest, D24_2D)
{ {
ANGLE_SKIP_TEST_IF(IsVulkan() && IsAMD() && IsWindows()); // anglebug.com/3545
GLuint data[] = {0xFFFF}; GLuint data[] = {0xFFFF};
init2DTexture(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data); init2DTexture(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data);
runTest2D(); runTest2D();
...@@ -393,6 +395,7 @@ TEST_P(SwizzleTest, CompressedDXT_2D) ...@@ -393,6 +395,7 @@ TEST_P(SwizzleTest, CompressedDXT_2D)
TEST_P(SwizzleIntegerTest, RGB8UI_2D) TEST_P(SwizzleIntegerTest, RGB8UI_2D)
{ {
ANGLE_SKIP_TEST_IF(IsVulkan()); // anglebug.com/3196 - integer textures
GLubyte data[] = {77, 66, 55}; GLubyte data[] = {77, 66, 55};
init2DTexture(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, data); init2DTexture(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, data);
runTest2D(); runTest2D();
...@@ -429,7 +432,7 @@ TEST_P(SwizzleTest, SubUpdate) ...@@ -429,7 +432,7 @@ TEST_P(SwizzleTest, SubUpdate)
EXPECT_PIXEL_COLOR_EQ(0, 0, expectedUpdateData); EXPECT_PIXEL_COLOR_EQ(0, 0, expectedUpdateData);
} }
ANGLE_INSTANTIATE_TEST(SwizzleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); ANGLE_INSTANTIATE_TEST(SwizzleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES(), ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(SwizzleIntegerTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); ANGLE_INSTANTIATE_TEST(SwizzleIntegerTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES(), ES3_VULKAN());
} // namespace } // namespace
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