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,
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::SamplerState &samplerState = mState.getSamplerState();
......@@ -1436,6 +1448,13 @@ void TextureVk::releaseImage(ContextVk *contextVk)
}
}
releaseImageViews(contextVk);
mCubeMapRenderTargets.clear();
}
void TextureVk::releaseImageViews(ContextVk *contextVk)
{
Serial currentSerial = contextVk->getCurrentQueueSerial();
contextVk->releaseObject(currentSerial, &mDrawBaseLevelImageView);
......@@ -1457,7 +1476,6 @@ void TextureVk::releaseImage(ContextVk *contextVk)
contextVk->releaseObject(currentSerial, &imageView);
}
mLayerFetchImageView.clear();
mCubeMapRenderTargets.clear();
}
void TextureVk::releaseStagingBuffer(ContextVk *context)
......
......@@ -267,6 +267,7 @@ class TextureVk : public TextureImpl
const uint32_t levelCount,
vk::CommandBuffer *commandBuffer);
void releaseImage(ContextVk *context);
void releaseImageViews(ContextVk *contextVk);
void releaseStagingBuffer(ContextVk *context);
uint32_t getLevelCount() const;
angle::Result initImageViews(ContextVk *contextVk,
......
......@@ -269,64 +269,86 @@ size_t GetVertexInputAlignment(const vk::Format &format)
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,
const gl::SwizzleState &swizzleState,
gl::SwizzleState *swizzleStateOut)
{
const angle::Format &angleFormat = format.angleFormat();
if (angleFormat.isBlock)
{
// 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;
}
gl::SwizzleState internalSwizzle;
switch (format.internalFormat)
{
case GL_LUMINANCE8_OES:
swizzleStateOut->swizzleRed = swizzleState.swizzleRed;
swizzleStateOut->swizzleGreen = swizzleState.swizzleRed;
swizzleStateOut->swizzleBlue = swizzleState.swizzleRed;
swizzleStateOut->swizzleAlpha = GL_ONE;
internalSwizzle.swizzleRed = GL_RED;
internalSwizzle.swizzleGreen = GL_RED;
internalSwizzle.swizzleBlue = GL_RED;
internalSwizzle.swizzleAlpha = GL_ONE;
break;
case GL_LUMINANCE8_ALPHA8_OES:
swizzleStateOut->swizzleRed = swizzleState.swizzleRed;
swizzleStateOut->swizzleGreen = swizzleState.swizzleRed;
swizzleStateOut->swizzleBlue = swizzleState.swizzleRed;
swizzleStateOut->swizzleAlpha = swizzleState.swizzleGreen;
internalSwizzle.swizzleRed = GL_RED;
internalSwizzle.swizzleGreen = GL_RED;
internalSwizzle.swizzleBlue = GL_RED;
internalSwizzle.swizzleAlpha = GL_GREEN;
break;
case GL_ALPHA8_OES:
swizzleStateOut->swizzleRed = GL_ZERO;
swizzleStateOut->swizzleGreen = GL_ZERO;
swizzleStateOut->swizzleBlue = GL_ZERO;
swizzleStateOut->swizzleAlpha = swizzleState.swizzleRed;
internalSwizzle.swizzleRed = GL_ZERO;
internalSwizzle.swizzleGreen = GL_ZERO;
internalSwizzle.swizzleBlue = GL_ZERO;
internalSwizzle.swizzleAlpha = GL_RED;
break;
default:
if (angleFormat.hasDepthOrStencilBits())
{
swizzleStateOut->swizzleRed =
angleFormat.depthBits > 0 ? swizzleState.swizzleRed : GL_ZERO;
swizzleStateOut->swizzleGreen =
angleFormat.depthBits > 0 ? swizzleState.swizzleRed : GL_ZERO;
swizzleStateOut->swizzleBlue =
angleFormat.depthBits > 0 ? swizzleState.swizzleRed : GL_ZERO;
swizzleStateOut->swizzleAlpha = GL_ONE;
internalSwizzle.swizzleRed = angleFormat.depthBits > 0 ? GL_RED : GL_ZERO;
internalSwizzle.swizzleGreen = angleFormat.depthBits > 0 ? GL_RED : GL_ZERO;
internalSwizzle.swizzleBlue = angleFormat.depthBits > 0 ? GL_RED : GL_ZERO;
internalSwizzle.swizzleAlpha = GL_ONE;
}
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.
swizzleStateOut->swizzleRed =
angleFormat.redBits > 0 ? swizzleState.swizzleRed : GL_ZERO;
swizzleStateOut->swizzleGreen =
angleFormat.greenBits > 0 ? swizzleState.swizzleGreen : GL_ZERO;
swizzleStateOut->swizzleBlue =
angleFormat.blueBits > 0 ? swizzleState.swizzleBlue : GL_ZERO;
swizzleStateOut->swizzleAlpha =
angleFormat.alphaBits > 0 ? swizzleState.swizzleAlpha : GL_ONE;
internalSwizzle.swizzleRed = angleFormat.redBits > 0 ? GL_RED : GL_ZERO;
internalSwizzle.swizzleGreen = angleFormat.greenBits > 0 ? GL_GREEN : GL_ZERO;
internalSwizzle.swizzleBlue = angleFormat.blueBits > 0 ? GL_BLUE : GL_ZERO;
internalSwizzle.swizzleAlpha = angleFormat.alphaBits > 0 ? GL_ALPHA : GL_ONE;
}
break;
}
ComposeSwizzleState(internalSwizzle, swizzleState, swizzleStateOut);
}
} // namespace rx
......@@ -550,7 +550,6 @@
3189 VULKAN : dEQP-GLES3.functional.texture.wrap.* = SKIP
3189 VULKAN : dEQP-GLES3.functional.texture.filtering.* = 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.specification.* = SKIP
3189 VULKAN : dEQP-GLES3.functional.texture.vertex.* = SKIP
......
......@@ -287,6 +287,7 @@ TEST_P(SwizzleTest, RGBA32F_2D)
TEST_P(SwizzleTest, RGB32F_2D)
{
ANGLE_SKIP_TEST_IF(IsVulkan()); // anglebug.com/2898 - float textures
GLfloat data[] = {0.1f, 0.2f, 0.3f};
init2DTexture(GL_RGB32F, GL_RGB, GL_FLOAT, data);
runTest2D();
......@@ -322,6 +323,7 @@ TEST_P(SwizzleTest, D16_2D)
TEST_P(SwizzleTest, D24_2D)
{
ANGLE_SKIP_TEST_IF(IsVulkan() && IsAMD() && IsWindows()); // anglebug.com/3545
GLuint data[] = {0xFFFF};
init2DTexture(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data);
runTest2D();
......@@ -393,6 +395,7 @@ TEST_P(SwizzleTest, CompressedDXT_2D)
TEST_P(SwizzleIntegerTest, RGB8UI_2D)
{
ANGLE_SKIP_TEST_IF(IsVulkan()); // anglebug.com/3196 - integer textures
GLubyte data[] = {77, 66, 55};
init2DTexture(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, data);
runTest2D();
......@@ -429,7 +432,7 @@ TEST_P(SwizzleTest, SubUpdate)
EXPECT_PIXEL_COLOR_EQ(0, 0, expectedUpdateData);
}
ANGLE_INSTANTIATE_TEST(SwizzleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
ANGLE_INSTANTIATE_TEST(SwizzleIntegerTest, 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(), ES3_VULKAN());
} // 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