Commit f8be756e by Luc Ferron

Vulkan: Implement blend states and add a simple test for it

Bug: angleproject:2346 Change-Id: I462a2cb29ceda5563f48b4a3cc1d0aa20f4a49fc Reviewed-on: https://chromium-review.googlesource.com/907169Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 3e520b6f
...@@ -174,8 +174,8 @@ gl::Error ContextVk::setupDraw(const gl::Context *context, ...@@ -174,8 +174,8 @@ gl::Error ContextVk::setupDraw(const gl::Context *context,
VertexArrayVk *vkVAO = vk::GetImpl(vao); VertexArrayVk *vkVAO = vk::GetImpl(vao);
const auto *drawFBO = state.getDrawFramebuffer(); const auto *drawFBO = state.getDrawFramebuffer();
FramebufferVk *vkFBO = vk::GetImpl(drawFBO); FramebufferVk *vkFBO = vk::GetImpl(drawFBO);
Serial queueSerial = mRenderer->getCurrentQueueSerial(); Serial queueSerial = mRenderer->getCurrentQueueSerial();
uint32_t maxAttrib = programGL->getState().getMaxActiveAttribLocation(); uint32_t maxAttrib = programGL->getState().getMaxActiveAttribLocation();
// Process vertex attributes. Assume zero offsets for now. // Process vertex attributes. Assume zero offsets for now.
// TODO(jmadill): Offset handling. // TODO(jmadill): Offset handling.
...@@ -449,16 +449,16 @@ void ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits ...@@ -449,16 +449,16 @@ void ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits
WARN() << "DIRTY_BIT_DEPTH_RANGE unimplemented"; WARN() << "DIRTY_BIT_DEPTH_RANGE unimplemented";
break; break;
case gl::State::DIRTY_BIT_BLEND_ENABLED: case gl::State::DIRTY_BIT_BLEND_ENABLED:
WARN() << "DIRTY_BIT_BLEND_ENABLED unimplemented"; mPipelineDesc->updateBlendEnabled(glState.isBlendEnabled());
break; break;
case gl::State::DIRTY_BIT_BLEND_COLOR: case gl::State::DIRTY_BIT_BLEND_COLOR:
WARN() << "DIRTY_BIT_BLEND_COLOR unimplemented"; mPipelineDesc->updateBlendColor(glState.getBlendColor());
break; break;
case gl::State::DIRTY_BIT_BLEND_FUNCS: case gl::State::DIRTY_BIT_BLEND_FUNCS:
WARN() << "DIRTY_BIT_BLEND_FUNCS unimplemented"; mPipelineDesc->updateBlendFuncs(glState.getBlendState());
break; break;
case gl::State::DIRTY_BIT_BLEND_EQUATIONS: case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
WARN() << "DIRTY_BIT_BLEND_EQUATIONS unimplemented"; mPipelineDesc->updateBlendEquations(glState.getBlendState());
break; break;
case gl::State::DIRTY_BIT_COLOR_MASK: case gl::State::DIRTY_BIT_COLOR_MASK:
WARN() << "DIRTY_BIT_COLOR_MASK unimplemented"; WARN() << "DIRTY_BIT_COLOR_MASK unimplemented";
......
...@@ -24,6 +24,23 @@ namespace vk ...@@ -24,6 +24,23 @@ namespace vk
namespace namespace
{ {
uint8_t PackGLBlendOp(GLenum blendOp)
{
switch (blendOp)
{
case GL_FUNC_ADD:
return static_cast<uint8_t>(VK_BLEND_OP_ADD);
case GL_FUNC_SUBTRACT:
return static_cast<uint8_t>(VK_BLEND_OP_SUBTRACT);
case GL_FUNC_REVERSE_SUBTRACT:
return static_cast<uint8_t>(VK_BLEND_OP_REVERSE_SUBTRACT);
default:
UNREACHABLE();
return 0;
}
}
VkSampleCountFlagBits ConvertSamples(GLint sampleCount) VkSampleCountFlagBits ConvertSamples(GLint sampleCount)
{ {
switch (sampleCount) switch (sampleCount)
...@@ -602,6 +619,43 @@ const RenderPassDesc &PipelineDesc::getRenderPassDesc() const ...@@ -602,6 +619,43 @@ const RenderPassDesc &PipelineDesc::getRenderPassDesc() const
return mRenderPassDesc; return mRenderPassDesc;
} }
void PipelineDesc::updateBlendColor(const gl::ColorF &color)
{
mColorBlendStateInfo.blendConstants[0] = color.red;
mColorBlendStateInfo.blendConstants[1] = color.green;
mColorBlendStateInfo.blendConstants[2] = color.blue;
mColorBlendStateInfo.blendConstants[3] = color.alpha;
}
void PipelineDesc::updateBlendEnabled(bool isBlendEnabled)
{
for (auto &blendAttachmentState : mColorBlendStateInfo.attachments)
{
blendAttachmentState.blendEnable = isBlendEnabled;
}
}
void PipelineDesc::updateBlendEquations(const gl::BlendState &blendState)
{
for (auto &blendAttachmentState : mColorBlendStateInfo.attachments)
{
blendAttachmentState.colorBlendOp = PackGLBlendOp(blendState.blendEquationRGB);
blendAttachmentState.alphaBlendOp = PackGLBlendOp(blendState.blendEquationAlpha);
}
}
void PipelineDesc::updateBlendFuncs(const gl::BlendState &blendState)
{
for (auto &blendAttachmentState : mColorBlendStateInfo.attachments)
{
blendAttachmentState.srcColorBlendFactor = static_cast<uint8_t>(blendState.sourceBlendRGB);
blendAttachmentState.dstColorBlendFactor = static_cast<uint8_t>(blendState.destBlendRGB);
blendAttachmentState.srcAlphaBlendFactor =
static_cast<uint8_t>(blendState.sourceBlendAlpha);
blendAttachmentState.dstAlphaBlendFactor = static_cast<uint8_t>(blendState.destBlendAlpha);
}
}
void PipelineDesc::updateRenderPassDesc(const RenderPassDesc &renderPassDesc) void PipelineDesc::updateRenderPassDesc(const RenderPassDesc &renderPassDesc)
{ {
mRenderPassDesc = renderPassDesc; mRenderPassDesc = renderPassDesc;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#ifndef LIBANGLE_RENDERER_VULKAN_VK_CACHE_UTILS_H_ #ifndef LIBANGLE_RENDERER_VULKAN_VK_CACHE_UTILS_H_
#define LIBANGLE_RENDERER_VULKAN_VK_CACHE_UTILS_H_ #define LIBANGLE_RENDERER_VULKAN_VK_CACHE_UTILS_H_
#include "common/Color.h"
#include "libANGLE/renderer/vulkan/vk_utils.h" #include "libANGLE/renderer/vulkan/vk_utils.h"
namespace rx namespace rx
...@@ -290,7 +291,15 @@ class PipelineDesc final ...@@ -290,7 +291,15 @@ class PipelineDesc final
// Scissor support // Scissor support
void updateScissor(const gl::Rectangle &rect); void updateScissor(const gl::Rectangle &rect);
// Blend states
void updateBlendEnabled(bool isBlendEnabled);
void updateBlendColor(const gl::ColorF &color);
void updateBlendFuncs(const gl::BlendState &blend_state);
void updateBlendEquations(const gl::BlendState &blend_state);
private: private:
void fillAllColorAttachments(PackedColorBlendAttachmentState blendAttachmentState);
// TODO(jmadill): Handle Geometry/Compute shaders when necessary. // TODO(jmadill): Handle Geometry/Compute shaders when necessary.
ShaderStageInfo mShaderStageInfo; ShaderStageInfo mShaderStageInfo;
VertexInputBindings mVertexInputBindings; VertexInputBindings mVertexInputBindings;
......
...@@ -64,6 +64,50 @@ void SimpleOperationTest::verifyBuffer(const std::vector<uint8_t> &data, GLenum ...@@ -64,6 +64,50 @@ void SimpleOperationTest::verifyBuffer(const std::vector<uint8_t> &data, GLenum
EXPECT_EQ(data, readbackData); EXPECT_EQ(data, readbackData);
} }
// Validates if blending render states work. Simply draws twice and verify the color have been
// added in the final output.
TEST_P(SimpleOperationTest, BlendingRenderState)
{
// The precision when blending isn't perfect and some tests fail with a color of 254 instead
// of 255 on the green component. This is why we need 0.51 green instead of .5
constexpr char halfGreenFragmentShader[] =
R"(void main()
{
gl_FragColor = vec4(0, 0.51, 0, 1);
})";
ANGLE_GL_PROGRAM(program, kBasicVertexShader, halfGreenFragmentShader);
glUseProgram(program);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
auto vertices = GetQuadVertices();
const GLint positionLocation = glGetAttribLocation(program, "position");
ASSERT_NE(-1, positionLocation);
GLBuffer vertexBuffer;
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.get());
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
GL_STATIC_DRAW);
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(positionLocation);
// Drawing a quad once will give 0.51 green, but if we enable blending
// with additive function we should end up with full green of 1.0 with
// a clamping func of 1.0.
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(vertices.size()));
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(vertices.size()));
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
TEST_P(SimpleOperationTest, CompileVertexShader) TEST_P(SimpleOperationTest, CompileVertexShader)
{ {
GLuint shader = CompileShader(GL_VERTEX_SHADER, kBasicVertexShader); GLuint shader = CompileShader(GL_VERTEX_SHADER, kBasicVertexShader);
......
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