GL/Vulkan: handle depth texture discrepancy In GLES 3.0, depth textures where changed to behave like RED textures, but in GLES 2.0 with ARB/OES_depth_texture, they were treated as luminance textures. This change produces the expected behavior on GLES 2.0 for the GL backend and on GLES 3.0 for the Vulkan backend. Bug: angleproject:3540 Change-Id: Iad6b4e03cf947b27eb97dbb10419bc8bcdb11024 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1666363 Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: James Dong <dongja@google.com>
diff --git a/src/libANGLE/renderer/gl/TextureGL.cpp b/src/libANGLE/renderer/gl/TextureGL.cpp index e52a267..6d02550 100644 --- a/src/libANGLE/renderer/gl/TextureGL.cpp +++ b/src/libANGLE/renderer/gl/TextureGL.cpp
@@ -1261,22 +1261,22 @@ // Texture state case gl::Texture::DIRTY_BIT_SWIZZLE_RED: - syncTextureStateSwizzle(functions, GL_TEXTURE_SWIZZLE_R, + syncTextureStateSwizzle(context, functions, GL_TEXTURE_SWIZZLE_R, mState.getSwizzleState().swizzleRed, &mAppliedSwizzle.swizzleRed); break; case gl::Texture::DIRTY_BIT_SWIZZLE_GREEN: - syncTextureStateSwizzle(functions, GL_TEXTURE_SWIZZLE_G, + syncTextureStateSwizzle(context, functions, GL_TEXTURE_SWIZZLE_G, mState.getSwizzleState().swizzleGreen, &mAppliedSwizzle.swizzleGreen); break; case gl::Texture::DIRTY_BIT_SWIZZLE_BLUE: - syncTextureStateSwizzle(functions, GL_TEXTURE_SWIZZLE_B, + syncTextureStateSwizzle(context, functions, GL_TEXTURE_SWIZZLE_B, mState.getSwizzleState().swizzleBlue, &mAppliedSwizzle.swizzleBlue); break; case gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA: - syncTextureStateSwizzle(functions, GL_TEXTURE_SWIZZLE_A, + syncTextureStateSwizzle(context, functions, GL_TEXTURE_SWIZZLE_A, mState.getSwizzleState().swizzleAlpha, &mAppliedSwizzle.swizzleAlpha); break; @@ -1404,7 +1404,8 @@ return getLevelInfo(index.getTarget(), index.getLevelIndex()).nativeInternalFormat; } -void TextureGL::syncTextureStateSwizzle(const FunctionsGL *functions, +void TextureGL::syncTextureStateSwizzle(const gl::Context *context, + const FunctionsGL *functions, GLenum name, GLenum value, GLenum *outValue) @@ -1483,8 +1484,18 @@ case GL_GREEN: case GL_BLUE: - // Depth textures should sample 0 from the green and blue channels. - resultSwizzle = GL_ZERO; + if (context->getClientMajorVersion() <= 2) + { + // In OES_depth_texture/ARB_depth_texture, depth + // textures are treated as luminance. + resultSwizzle = GL_RED; + } + else + { + // In GLES 3.0, depth textures are treated as RED + // textures, so green and blue should be 0. + resultSwizzle = GL_ZERO; + } break; case GL_ALPHA:
diff --git a/src/libANGLE/renderer/gl/TextureGL.h b/src/libANGLE/renderer/gl/TextureGL.h index e4a7342..786ac86 100644 --- a/src/libANGLE/renderer/gl/TextureGL.h +++ b/src/libANGLE/renderer/gl/TextureGL.h
@@ -40,6 +40,8 @@ GLenum nativeInternalFormat; // If this mip level requires sampler-state re-writing so that only a red channel is exposed. + // In GLES 2.0, depth textures are treated as luminance, so we check the + // context's major version when applying the depth swizzle. bool depthStencilWorkaround; // Information about luminance alpha texture workarounds in the core profile. @@ -234,7 +236,8 @@ const gl::Buffer *unpackBuffer, const uint8_t *pixels); - void syncTextureStateSwizzle(const FunctionsGL *functions, + void syncTextureStateSwizzle(const gl::Context *context, + const FunctionsGL *functions, GLenum name, GLenum value, GLenum *outValue);
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp index 7ce9fa5..48b7b09 100644 --- a/src/libANGLE/renderer/vulkan/TextureVk.cpp +++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -1153,7 +1153,7 @@ // Users of the render target expect the views to directly view the desired layer, so we // need create a fetch view for each layer as well. gl::SwizzleState mappedSwizzle; - MapSwizzleState(mImage->getFormat(), mState.getSwizzleState(), &mappedSwizzle); + MapSwizzleState(contextVk, mImage->getFormat(), mState.getSwizzleState(), &mappedSwizzle); gl::TextureType arrayType = vk::Get2DTextureType(gl::kCubeFaceCount, mImage->getSamples()); ANGLE_TRY(mImage->initLayerImageView(contextVk, arrayType, mImage->getAspectFlags(), mappedSwizzle, &mLayerFetchImageView[cubeMapFaceIndex], @@ -1394,7 +1394,7 @@ ASSERT(mImage != nullptr); gl::SwizzleState mappedSwizzle; - MapSwizzleState(format, mState.getSwizzleState(), &mappedSwizzle); + MapSwizzleState(contextVk, format, mState.getSwizzleState(), &mappedSwizzle); // TODO: Support non-zero base level for ES 3.0 by passing it to getNativeImageLevel. // http://anglebug.com/3148
diff --git a/src/libANGLE/renderer/vulkan/vk_format_utils.cpp b/src/libANGLE/renderer/vulkan/vk_format_utils.cpp index d0be06c..5628aae 100644 --- a/src/libANGLE/renderer/vulkan/vk_format_utils.cpp +++ b/src/libANGLE/renderer/vulkan/vk_format_utils.cpp
@@ -11,6 +11,7 @@ #include "libANGLE/Texture.h" #include "libANGLE/formatutils.h" #include "libANGLE/renderer/load_functions_table.h" +#include "libANGLE/renderer/vulkan/ContextVk.h" #include "libANGLE/renderer/vulkan/RendererVk.h" #include "libANGLE/renderer/vulkan/vk_caps_utils.h" @@ -297,7 +298,8 @@ out->swizzleAlpha = GetSwizzleStateComponent(first, second.swizzleAlpha); } -void MapSwizzleState(const vk::Format &format, +void MapSwizzleState(const ContextVk *contextVk, + const vk::Format &format, const gl::SwizzleState &swizzleState, gl::SwizzleState *swizzleStateOut) { @@ -328,9 +330,14 @@ default: if (angleFormat.hasDepthOrStencilBits()) { - 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; + bool hasRed = angleFormat.depthBits > 0; + // In OES_depth_texture/ARB_depth_texture, depth + // textures are treated as luminance. + bool hasGB = hasRed && contextVk->getClientMajorVersion() <= 2; + + internalSwizzle.swizzleRed = hasRed ? GL_RED : GL_ZERO; + internalSwizzle.swizzleGreen = hasGB ? GL_RED : GL_ZERO; + internalSwizzle.swizzleBlue = hasGB ? GL_RED : GL_ZERO; internalSwizzle.swizzleAlpha = GL_ONE; } else
diff --git a/src/libANGLE/renderer/vulkan/vk_format_utils.h b/src/libANGLE/renderer/vulkan/vk_format_utils.h index 0050e8a..b0efc48 100644 --- a/src/libANGLE/renderer/vulkan/vk_format_utils.h +++ b/src/libANGLE/renderer/vulkan/vk_format_utils.h
@@ -28,6 +28,7 @@ namespace rx { class RendererVk; +class ContextVk; namespace vk { @@ -148,7 +149,8 @@ // calculation is listed in the Vulkan spec at the end of the section 'Vertex Input Description'. size_t GetVertexInputAlignment(const vk::Format &format); -void MapSwizzleState(const vk::Format &format, +void MapSwizzleState(const ContextVk *contextVk, + const vk::Format &format, const gl::SwizzleState &swizzleState, gl::SwizzleState *swizzleStateOut); } // namespace rx