Commit ed01473e by Alexey Knyazev Committed by Commit Bot

Vulkan: Fix blendEnable-02023 VU

Enable BlendIntegerTest Add DrawBuffersTest.BlendWithGaps test Add BlendPackedTest Bug: angleproject:4548 Bug: angleproject:4571 Bug: angleproject:4583 Change-Id: I139183099b26f0fe1ac9e43f96d18b8ccb134a2f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2407772 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 3018d5e5
...@@ -131,8 +131,6 @@ constexpr const char *kSkippedMessages[] = { ...@@ -131,8 +131,6 @@ constexpr const char *kSkippedMessages[] = {
"VUID-VkDeviceCreateInfo-pNext-pNext", "VUID-VkDeviceCreateInfo-pNext-pNext",
"VUID-VkPipelineRasterizationStateCreateInfo-pNext-pNext", "VUID-VkPipelineRasterizationStateCreateInfo-pNext-pNext",
"VUID_Undefined", "VUID_Undefined",
// http://anglebug.com/4583
"VUID-VkGraphicsPipelineCreateInfo-blendEnable-02023",
// https://issuetracker.google.com/issues/159493191 // https://issuetracker.google.com/issues/159493191
"VUID-vkCmdDraw-None-02690", "VUID-vkCmdDraw-None-02690",
"VUID-vkCmdDrawIndexed-None-02690", "VUID-vkCmdDrawIndexed-None-02690",
......
...@@ -1015,14 +1015,30 @@ angle::Result GraphicsPipelineDesc::initializePipeline( ...@@ -1015,14 +1015,30 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
const gl::DrawBufferMask blendEnableMask(inputAndBlend.blendEnableMask); const gl::DrawBufferMask blendEnableMask(inputAndBlend.blendEnableMask);
// Zero-init all states.
blendAttachmentState = {};
for (uint32_t colorIndexGL = 0; colorIndexGL < blendState.attachmentCount; ++colorIndexGL) for (uint32_t colorIndexGL = 0; colorIndexGL < blendState.attachmentCount; ++colorIndexGL)
{ {
VkPipelineColorBlendAttachmentState &state = blendAttachmentState[colorIndexGL]; VkPipelineColorBlendAttachmentState &state = blendAttachmentState[colorIndexGL];
state.blendEnable = blendEnableMask[colorIndexGL] ? VK_TRUE : VK_FALSE; if (blendEnableMask[colorIndexGL])
{
// To avoid triggering valid usage error, blending must be disabled for formats that do
// not have VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT feature bit set.
// From OpenGL ES clients, this means disabling blending for integer formats.
if (!angle::Format::Get(mRenderPassDesc[colorIndexGL]).isInt())
{
ASSERT(!contextVk->getRenderer()
->getFormat(mRenderPassDesc[colorIndexGL])
.actualImageFormat()
.isInt());
state.blendEnable = VK_TRUE;
UnpackBlendAttachmentState(inputAndBlend.attachments[colorIndexGL], &state);
}
}
state.colorWriteMask = state.colorWriteMask =
Int4Array_Get<VkColorComponentFlags>(inputAndBlend.colorWriteMaskBits, colorIndexGL); Int4Array_Get<VkColorComponentFlags>(inputAndBlend.colorWriteMaskBits, colorIndexGL);
UnpackBlendAttachmentState(inputAndBlend.attachments[colorIndexGL], &state);
} }
// We would define dynamic state here if it were to be used. // We would define dynamic state here if it were to be used.
......
...@@ -291,9 +291,24 @@ bool HasFullTextureFormatSupport(RendererVk *renderer, VkFormat vkFormat) ...@@ -291,9 +291,24 @@ bool HasFullTextureFormatSupport(RendererVk *renderer, VkFormat vkFormat)
constexpr uint32_t kBitsColor = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | constexpr uint32_t kBitsColor = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
// In OpenGL ES, all renderable formats except 32-bit floating-point support blending.
// 32-bit floating-point case validation is handled by ANGLE's frontend.
uint32_t kBitsColorFull = kBitsColor;
switch (vkFormat)
{
case VK_FORMAT_R32_SFLOAT:
case VK_FORMAT_R32G32_SFLOAT:
case VK_FORMAT_R32G32B32A32_SFLOAT:
break;
default:
kBitsColorFull |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
break;
}
constexpr uint32_t kBitsDepth = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; constexpr uint32_t kBitsDepth = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
return renderer->hasImageFormatFeatureBits(vkFormat, kBitsColor) || return renderer->hasImageFormatFeatureBits(vkFormat, kBitsColorFull) ||
renderer->hasImageFormatFeatureBits(vkFormat, kBitsDepth); renderer->hasImageFormatFeatureBits(vkFormat, kBitsDepth);
} }
......
...@@ -32,6 +32,7 @@ angle_end2end_tests_sources = [ ...@@ -32,6 +32,7 @@ angle_end2end_tests_sources = [
"gl_tests/BlendFuncExtendedTest.cpp", "gl_tests/BlendFuncExtendedTest.cpp",
"gl_tests/BlendIntegerTest.cpp", "gl_tests/BlendIntegerTest.cpp",
"gl_tests/BlendMinMaxTest.cpp", "gl_tests/BlendMinMaxTest.cpp",
"gl_tests/BlendPackedTest.cpp",
"gl_tests/BlitFramebufferANGLETest.cpp", "gl_tests/BlitFramebufferANGLETest.cpp",
"gl_tests/BufferDataTest.cpp", "gl_tests/BufferDataTest.cpp",
"gl_tests/BuiltinVariableTest.cpp", "gl_tests/BuiltinVariableTest.cpp",
......
...@@ -43,9 +43,6 @@ class BlendIntegerTest : public ANGLETest ...@@ -43,9 +43,6 @@ class BlendIntegerTest : public ANGLETest
template <GLenum internalformat, GLuint components, bool isSigned> template <GLenum internalformat, GLuint components, bool isSigned>
void runTest() void runTest()
{ {
// https://crbug.com/angleproject/4548
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsIntel() && !isVulkanSwiftshaderRenderer());
constexpr char kFsui[] = constexpr char kFsui[] =
"#version 300 es\n" "#version 300 es\n"
"out highp uvec4 o_drawBuffer0;\n" "out highp uvec4 o_drawBuffer0;\n"
...@@ -114,135 +111,97 @@ class BlendIntegerTest : public ANGLETest ...@@ -114,135 +111,97 @@ class BlendIntegerTest : public ANGLETest
// Test that blending is not applied to signed integer attachments. // Test that blending is not applied to signed integer attachments.
TEST_P(BlendIntegerTest, R8I) TEST_P(BlendIntegerTest, R8I)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_R8I, 1, true>(); runTest<GL_R8I, 1, true>();
} }
TEST_P(BlendIntegerTest, R16I) TEST_P(BlendIntegerTest, R16I)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_R16I, 1, true>(); runTest<GL_R16I, 1, true>();
} }
TEST_P(BlendIntegerTest, R32I) TEST_P(BlendIntegerTest, R32I)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_R32I, 1, true>(); runTest<GL_R32I, 1, true>();
} }
TEST_P(BlendIntegerTest, RG8I) TEST_P(BlendIntegerTest, RG8I)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_RG8I, 2, true>(); runTest<GL_RG8I, 2, true>();
} }
TEST_P(BlendIntegerTest, RG16I) TEST_P(BlendIntegerTest, RG16I)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_RG16I, 2, true>(); runTest<GL_RG16I, 2, true>();
} }
TEST_P(BlendIntegerTest, RG32I) TEST_P(BlendIntegerTest, RG32I)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_RG32I, 2, true>(); runTest<GL_RG32I, 2, true>();
} }
TEST_P(BlendIntegerTest, RGBA8I) TEST_P(BlendIntegerTest, RGBA8I)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_RGBA8I, 4, true>(); runTest<GL_RGBA8I, 4, true>();
} }
TEST_P(BlendIntegerTest, RGBA16I) TEST_P(BlendIntegerTest, RGBA16I)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_RGBA16I, 4, true>(); runTest<GL_RGBA16I, 4, true>();
} }
TEST_P(BlendIntegerTest, RGBA32I) TEST_P(BlendIntegerTest, RGBA32I)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_RGBA32I, 4, true>(); runTest<GL_RGBA32I, 4, true>();
} }
// Test that blending is not applied to unsigned integer attachments. // Test that blending is not applied to unsigned integer attachments.
TEST_P(BlendIntegerTest, R8UI) TEST_P(BlendIntegerTest, R8UI)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_R8UI, 1, false>(); runTest<GL_R8UI, 1, false>();
} }
TEST_P(BlendIntegerTest, R16UI) TEST_P(BlendIntegerTest, R16UI)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_R16UI, 1, false>(); runTest<GL_R16UI, 1, false>();
} }
TEST_P(BlendIntegerTest, R32UI) TEST_P(BlendIntegerTest, R32UI)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_R32UI, 1, false>(); runTest<GL_R32UI, 1, false>();
} }
TEST_P(BlendIntegerTest, RG8UI) TEST_P(BlendIntegerTest, RG8UI)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_RG8UI, 2, false>(); runTest<GL_RG8UI, 2, false>();
} }
TEST_P(BlendIntegerTest, RG16UI) TEST_P(BlendIntegerTest, RG16UI)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_RG16UI, 2, false>(); runTest<GL_RG16UI, 2, false>();
} }
TEST_P(BlendIntegerTest, RG32UI) TEST_P(BlendIntegerTest, RG32UI)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_RG32UI, 2, false>(); runTest<GL_RG32UI, 2, false>();
} }
TEST_P(BlendIntegerTest, RGBA8UI) TEST_P(BlendIntegerTest, RGBA8UI)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_RGBA8UI, 4, false>(); runTest<GL_RGBA8UI, 4, false>();
} }
TEST_P(BlendIntegerTest, RGBA16UI) TEST_P(BlendIntegerTest, RGBA16UI)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_RGBA16UI, 4, false>(); runTest<GL_RGBA16UI, 4, false>();
} }
TEST_P(BlendIntegerTest, RGBA32UI) TEST_P(BlendIntegerTest, RGBA32UI)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_RGBA32UI, 4, false>(); runTest<GL_RGBA32UI, 4, false>();
} }
TEST_P(BlendIntegerTest, RGB10_A2UI) TEST_P(BlendIntegerTest, RGB10_A2UI)
{ {
// TODO(http://anglebug.com/4571)
ANGLE_SKIP_TEST_IF(isVulkanRenderer());
runTest<GL_RGB10_A2UI, 4, false>(); runTest<GL_RGB10_A2UI, 4, false>();
} }
......
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
using namespace angle;
class BlendPackedTest : public ANGLETest
{
protected:
BlendPackedTest()
{
setWindowWidth(128);
setWindowHeight(128);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
template <GLenum internalformat, GLuint components>
void runTest()
{
constexpr char kFs[] =
"#version 100\n"
"void main(void)\n"
"{\n"
" gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);\n"
"}\n";
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), kFs);
glUseProgram(program);
GLFramebuffer framebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
GLRenderbuffer colorRenderbuffer;
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, internalformat, getWindowWidth(), getWindowHeight());
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
colorRenderbuffer);
glClearColor(1.0, 1.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
ASSERT_GL_NO_ERROR();
if (components == 3)
{
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
}
else
{
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(255u, 255u, 0, 0));
}
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
}
};
// Test that blending is applied to attachments with packed formats.
TEST_P(BlendPackedTest, RGB565)
{
runTest<GL_RGB565, 3>();
}
TEST_P(BlendPackedTest, RGBA4)
{
runTest<GL_RGBA4, 4>();
}
TEST_P(BlendPackedTest, RGB5_A1)
{
// RGB5_A1 is not color-renderable on NVIDIA Mac, see https://crbug.com/676209.
ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsOSX() && IsOpenGL());
runTest<GL_RGB5_A1, 4>();
}
TEST_P(BlendPackedTest, RGB10_A2)
{
ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
runTest<GL_RGB10_A2, 4>();
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(BlendPackedTest);
...@@ -289,6 +289,51 @@ TEST_P(DrawBuffersTest, Gaps) ...@@ -289,6 +289,51 @@ TEST_P(DrawBuffersTest, Gaps)
glDeleteProgram(program); glDeleteProgram(program);
} }
// Test that blend works with gaps
TEST_P(DrawBuffersTest, BlendWithGaps)
{
ANGLE_SKIP_TEST_IF(!setupTest());
// Qualcomm driver crashes in the presence of VK_ATTACHMENT_UNUSED.
// http://anglebug.com/3423
ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
// Fails on Intel Ubuntu 19.04 Mesa 19.0.2 Vulkan. http://anglebug.com/3616
ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsVulkan());
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mTextures[0], 0);
ASSERT_GL_NO_ERROR();
bool flags[8] = {false, true};
GLuint program;
setupMRTProgram(flags, &program);
const GLenum bufs[] = {GL_NONE, GL_COLOR_ATTACHMENT1};
setDrawBuffers(2, bufs);
// Draws green into attachment 1
drawQuad(program, positionAttrib(), 0.5);
verifyAttachment2D(1, mTextures[0], GL_TEXTURE_2D, 0);
ASSERT_GL_NO_ERROR();
// Clear with red
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
verifyAttachment2DColor(1, mTextures[0], GL_TEXTURE_2D, 0, GLColor(255u, 0, 0, 255u));
// Draw green into attachment 1 again but with blending, expecting yellow
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
drawQuad(program, positionAttrib(), 0.5);
verifyAttachment2DColor(1, mTextures[0], GL_TEXTURE_2D, 0, GLColor(255u, 255u, 0, 255u));
ASSERT_GL_NO_ERROR();
glDeleteProgram(program);
}
// Test that clear works with gaps // Test that clear works with gaps
TEST_P(DrawBuffersTest, ClearWithGaps) TEST_P(DrawBuffersTest, ClearWithGaps)
{ {
......
...@@ -471,6 +471,12 @@ void RunTextureFormatCompatChromiumTest(bool useMemoryObjectFlags, ...@@ -471,6 +471,12 @@ void RunTextureFormatCompatChromiumTest(bool useMemoryObjectFlags,
helper.initialize(isSwiftshader, enableDebugLayers); helper.initialize(isSwiftshader, enableDebugLayers);
for (const ImageFormatPair &format : kChromeFormats) for (const ImageFormatPair &format : kChromeFormats)
{ {
// https://crbug.com/angleproject/5046
if (format.vkFormat == VK_FORMAT_R4G4B4A4_UNORM_PACK16 && IsIntel())
{
continue;
}
if (!Traits::CanCreateImage(helper, format.vkFormat, VK_IMAGE_TYPE_2D, if (!Traits::CanCreateImage(helper, format.vkFormat, VK_IMAGE_TYPE_2D,
VK_IMAGE_TILING_OPTIMAL, createFlags, usageFlags)) VK_IMAGE_TILING_OPTIMAL, createFlags, usageFlags))
{ {
......
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