Commit 66c2f4af by Luc Ferron Committed by Commit Bot

Vulkan: Add test and fix clear on RGB8 with color masks

Fixes the behavior of clearWithDraw to keep the alpha channel if we should not be clearing it. Bug: angleproject:2667 Change-Id: Id49c1d2ca30ecb5b5bdd8abe00825a6210cfacf6 Reviewed-on: https://chromium-review.googlesource.com/1106052Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Luc Ferron <lucferron@chromium.org>
parent a914f7ff
...@@ -134,7 +134,7 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask) ...@@ -134,7 +134,7 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
VkColorComponentFlags colorMaskFlags = contextVk->getClearColorMask(); VkColorComponentFlags colorMaskFlags = contextVk->getClearColorMask();
if (clearColor && (mActiveColorComponents & colorMaskFlags) != mActiveColorComponents) if (clearColor && (mActiveColorComponents & colorMaskFlags) != mActiveColorComponents)
{ {
ANGLE_TRY(clearWithDraw(contextVk, colorMaskFlags)); ANGLE_TRY(clearWithDraw(context, colorMaskFlags));
// Stencil clears must be handled separately. The only way to write out a stencil value from // Stencil clears must be handled separately. The only way to write out a stencil value from
// a fragment shader in Vulkan is with VK_EXT_shader_stencil_export. Support for this // a fragment shader in Vulkan is with VK_EXT_shader_stencil_export. Support for this
...@@ -587,8 +587,10 @@ gl::Error FramebufferVk::clearWithClearAttachments(ContextVk *contextVk, ...@@ -587,8 +587,10 @@ gl::Error FramebufferVk::clearWithClearAttachments(ContextVk *contextVk,
return gl::NoError(); return gl::NoError();
} }
gl::Error FramebufferVk::clearWithDraw(ContextVk *contextVk, VkColorComponentFlags colorMaskFlags) gl::Error FramebufferVk::clearWithDraw(const gl::Context *context,
VkColorComponentFlags colorMaskFlags)
{ {
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
vk::ShaderLibrary *shaderLibrary = renderer->getShaderLibrary(); vk::ShaderLibrary *shaderLibrary = renderer->getShaderLibrary();
...@@ -654,7 +656,18 @@ gl::Error FramebufferVk::clearWithDraw(ContextVk *contextVk, VkColorComponentFla ...@@ -654,7 +656,18 @@ gl::Error FramebufferVk::clearWithDraw(ContextVk *contextVk, VkColorComponentFla
vk::CommandBuffer *writeCommands = nullptr; vk::CommandBuffer *writeCommands = nullptr;
ANGLE_TRY(appendWriteResource(renderer, &writeCommands)); ANGLE_TRY(appendWriteResource(renderer, &writeCommands));
// If the format of the framebuffer does not have an alpha channel, we need to make sure we does
// not affect the alpha channel of the type we're using to emulate the format.
// TODO(jmadill): Implement EXT_draw_buffers http://anglebug.com/2394
RenderTargetVk *renderTarget = mRenderTargetCache.getColors()[0];
ASSERT(renderTarget);
const vk::Format &imageFormat = renderTarget->getImageFormat();
VkClearColorValue clearColorValue = contextVk->getClearColorValue().color; VkClearColorValue clearColorValue = contextVk->getClearColorValue().color;
bool overrideAlphaWithOne =
imageFormat.textureFormat().alphaBits > 0 && imageFormat.angleFormat().alphaBits == 0;
clearColorValue.float32[3] = overrideAlphaWithOne ? 1.0f : clearColorValue.float32[3];
drawCommands->pushConstants(pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, drawCommands->pushConstants(pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0,
sizeof(VkClearColorValue), clearColorValue.float32); sizeof(VkClearColorValue), clearColorValue.float32);
......
...@@ -110,7 +110,7 @@ class FramebufferVk : public FramebufferImpl, public vk::CommandGraphResource ...@@ -110,7 +110,7 @@ class FramebufferVk : public FramebufferImpl, public vk::CommandGraphResource
bool clearColor, bool clearColor,
bool clearDepth, bool clearDepth,
bool clearStencil); bool clearStencil);
gl::Error clearWithDraw(ContextVk *contextVk, VkColorComponentFlags colorMaskFlags); gl::Error clearWithDraw(const gl::Context *context, VkColorComponentFlags colorMaskFlags);
void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a); void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a);
RenderTargetVk *getColorReadRenderTarget() const; RenderTargetVk *getColorReadRenderTarget() const;
......
...@@ -106,6 +106,31 @@ TEST_P(ClearTest, RGBA8Framebuffer) ...@@ -106,6 +106,31 @@ TEST_P(ClearTest, RGBA8Framebuffer)
EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0); EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0);
} }
// Test clearing a RGB8 Framebuffer with a color mask.
TEST_P(ClearTest, RGB8WithMaskFramebuffer)
{
// TODO(lucferron): Figure out why this test fails on OSX / OpenGL.
// http://anglebug.com/2674
ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,
GL_UNSIGNED_BYTE, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
// alpha shouldn't really be taken into account and we should find 255 as a result since we
// are writing to a RGB8 texture. Also, the
glClearColor(0.5f, 0.5f, 0.5f, 0.2f);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_PIXEL_NEAR(0, 0, 128, 128, 0, 255, 1.0);
}
TEST_P(ClearTest, ClearIssue) TEST_P(ClearTest, ClearIssue)
{ {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
......
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