From 8dc3bd1808fb1ea8d7030ab5622268397d754584 Mon Sep 17 00:00:00 2001 From: Austin Eng Date: Tue, 1 Aug 2017 18:22:57 -0400 Subject: [PATCH] opengl: Implement blend state --- src/backend/opengl/BlendStateGL.cpp | 78 +++++++++++++++++++++++++ src/backend/opengl/BlendStateGL.h | 4 ++ src/backend/opengl/CommandBufferGL.cpp | 3 +- src/backend/opengl/RenderPipelineGL.cpp | 9 +++ 4 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/backend/opengl/BlendStateGL.cpp b/src/backend/opengl/BlendStateGL.cpp index a595ee1c13..bf90267279 100644 --- a/src/backend/opengl/BlendStateGL.cpp +++ b/src/backend/opengl/BlendStateGL.cpp @@ -15,12 +15,90 @@ #include "backend/opengl/BlendStateGL.h" #include "backend/opengl/OpenGLBackend.h" +#include "common/Assert.h" namespace backend { namespace opengl { + namespace { + GLenum GLBlendFactor(nxt::BlendFactor factor, bool alpha) { + switch (factor) { + case nxt::BlendFactor::Zero: + return GL_ZERO; + case nxt::BlendFactor::One: + return GL_ONE; + case nxt::BlendFactor::SrcColor: + return GL_SRC_COLOR; + case nxt::BlendFactor::OneMinusSrcColor: + return GL_ONE_MINUS_SRC_COLOR; + case nxt::BlendFactor::SrcAlpha: + return GL_SRC_ALPHA; + case nxt::BlendFactor::OneMinusSrcAlpha: + return GL_ONE_MINUS_SRC_ALPHA; + case nxt::BlendFactor::DstColor: + return GL_DST_COLOR; + case nxt::BlendFactor::OneMinusDstColor: + return GL_ONE_MINUS_DST_COLOR; + case nxt::BlendFactor::DstAlpha: + return GL_DST_ALPHA; + case nxt::BlendFactor::OneMinusDstAlpha: + return GL_ONE_MINUS_DST_ALPHA; + case nxt::BlendFactor::SrcAlphaSaturated: + return GL_SRC_ALPHA_SATURATE; + case nxt::BlendFactor::BlendColor: + return alpha ? GL_CONSTANT_ALPHA : GL_CONSTANT_COLOR; + case nxt::BlendFactor::OneMinusBlendColor: + return alpha ? GL_ONE_MINUS_CONSTANT_ALPHA : GL_ONE_MINUS_CONSTANT_COLOR; + case nxt::BlendFactor::Src1Color: + return GL_SRC1_COLOR; + case nxt::BlendFactor::OneMinusSrc1Color: + return GL_ONE_MINUS_SRC1_COLOR; + case nxt::BlendFactor::Src1Alpha: + return GL_SRC1_ALPHA; + case nxt::BlendFactor::OneMinusSrc1Alpha: + return GL_ONE_MINUS_SRC1_ALPHA; + default: + UNREACHABLE(); + } + } + + GLenum GLBlendMode(nxt::BlendOperation operation) { + switch (operation) { + case nxt::BlendOperation::Add: + return GL_FUNC_ADD; + case nxt::BlendOperation::Subtract: + return GL_FUNC_SUBTRACT; + case nxt::BlendOperation::ReverseSubtract: + return GL_FUNC_REVERSE_SUBTRACT; + case nxt::BlendOperation::Min: + return GL_MIN; + case nxt::BlendOperation::Max: + return GL_MAX; + default: + UNREACHABLE(); + } + } + } + BlendState::BlendState(BlendStateBuilder* builder) : BlendStateBase(builder) { } + void BlendState::ApplyNow(uint32_t attachment) { + const auto& info = GetBlendInfo(); + + if (info.blendEnabled) { + glEnablei(GL_BLEND, attachment); + glBlendEquationSeparatei(attachment, GLBlendMode(info.colorBlend.operation), GLBlendMode(info.alphaBlend.operation)); + glBlendFuncSeparatei(attachment, GLBlendFactor(info.colorBlend.srcFactor, false), GLBlendFactor(info.colorBlend.dstFactor, false), GLBlendFactor(info.alphaBlend.srcFactor, true), GLBlendFactor(info.alphaBlend.dstFactor, true)); + glColorMaski(attachment, + info.colorWriteMask & nxt::ColorWriteMask::Red, + info.colorWriteMask & nxt::ColorWriteMask::Green, + info.colorWriteMask & nxt::ColorWriteMask::Blue, + info.colorWriteMask & nxt::ColorWriteMask::Alpha); + } else { + glDisablei(GL_BLEND, attachment); + } + } + } } diff --git a/src/backend/opengl/BlendStateGL.h b/src/backend/opengl/BlendStateGL.h index aca960ce62..e286cd592c 100644 --- a/src/backend/opengl/BlendStateGL.h +++ b/src/backend/opengl/BlendStateGL.h @@ -17,12 +17,16 @@ #include "backend/BlendState.h" +#include "glad/glad.h" + namespace backend { namespace opengl { class BlendState : public BlendStateBase { public: BlendState(BlendStateBuilder* builder); + + void ApplyNow(uint32_t attachment); }; } diff --git a/src/backend/opengl/CommandBufferGL.cpp b/src/backend/opengl/CommandBufferGL.cpp index b3f91eb5e0..5894266b22 100644 --- a/src/backend/opengl/CommandBufferGL.cpp +++ b/src/backend/opengl/CommandBufferGL.cpp @@ -338,7 +338,8 @@ namespace opengl { case Command::SetBlendColor: { - commands.NextCommand(); + SetBlendColorCmd* cmd = commands.NextCommand(); + glBlendColor(cmd->r, cmd->g, cmd->b, cmd->a); } break; diff --git a/src/backend/opengl/RenderPipelineGL.cpp b/src/backend/opengl/RenderPipelineGL.cpp index cc83ed618a..a5c2104cbd 100644 --- a/src/backend/opengl/RenderPipelineGL.cpp +++ b/src/backend/opengl/RenderPipelineGL.cpp @@ -14,6 +14,7 @@ #include "backend/opengl/RenderPipelineGL.h" +#include "backend/opengl/BlendStateGL.h" #include "backend/opengl/DepthStencilStateGL.h" #include "backend/opengl/PersistentPipelineStateGL.h" #include "backend/opengl/OpenGLBackend.h" @@ -57,6 +58,14 @@ namespace opengl { auto depthStencilState = ToBackend(GetDepthStencilState()); depthStencilState->ApplyNow(persistentPipelineState); + + + RenderPass* renderPass = ToBackend(GetRenderPass()); + auto& subpassInfo = renderPass->GetSubpassInfo(GetSubPass()); + + for (uint32_t attachmentSlot : IterateBitSet(subpassInfo.colorAttachmentsSet)) { + ToBackend(GetBlendState(attachmentSlot))->ApplyNow(attachmentSlot); + } } }