opengl: Implement blend state
diff --git a/src/backend/opengl/BlendStateGL.cpp b/src/backend/opengl/BlendStateGL.cpp
index a595ee1..bf90267 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 aca960c..e286cd5 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 b3f91eb..5894266 100644
--- a/src/backend/opengl/CommandBufferGL.cpp
+++ b/src/backend/opengl/CommandBufferGL.cpp
@@ -338,7 +338,8 @@
case Command::SetBlendColor:
{
- commands.NextCommand<SetBlendColorCmd>();
+ SetBlendColorCmd* cmd = commands.NextCommand<SetBlendColorCmd>();
+ 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 cc83ed6..a5c2104 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 @@
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);
+ }
}
}