Add shader mode for constant alpha overwrite

This commit is contained in:
Jack Andersen 2018-02-04 20:52:54 -10:00
parent 25dfeb64aa
commit edd26fc65b
9 changed files with 127 additions and 31 deletions

View File

@ -35,7 +35,7 @@ public:
const boo::ObjToken<IVertexFormat>& vtxFmt, const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite, ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling)=0; bool alphaWrite, CullMode culling, bool overwriteAlpha=true)=0;
}; };
}; };

View File

@ -52,7 +52,7 @@ public:
size_t uniformBlockCount, const char** uniformBlockNames, size_t uniformBlockCount, const char** uniformBlockNames,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite, ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling); bool alphaWrite, CullMode culling, bool overwriteAlpha = true);
ObjToken<IShaderDataBinding> ObjToken<IShaderDataBinding>
newShaderDataBinding(const ObjToken<IShaderPipeline>& pipeline, newShaderDataBinding(const ObjToken<IShaderPipeline>& pipeline,

View File

@ -48,7 +48,9 @@ public:
const ObjToken<IVertexFormat>& vtxFmt, const ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite, ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling, bool depthAttachment = true); bool alphaWrite, CullMode culling,
bool overwriteAlpha = true,
bool depthAttachment = true);
ObjToken<IShaderDataBinding> ObjToken<IShaderDataBinding>
newShaderDataBinding(const ObjToken<IShaderPipeline>& pipeline, newShaderDataBinding(const ObjToken<IShaderPipeline>& pipeline,

View File

@ -160,7 +160,7 @@ public:
const boo::ObjToken<IVertexFormat>& vtxFmt, const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite, ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling); bool alphaWrite, CullMode culling, bool overwriteAlpha = true);
boo::ObjToken<IShaderPipeline> newShaderPipeline(const char* vertSource, const char* fragSource, boo::ObjToken<IShaderPipeline> newShaderPipeline(const char* vertSource, const char* fragSource,
const boo::ObjToken<IVertexFormat>& vtxFmt, const boo::ObjToken<IVertexFormat>& vtxFmt,

View File

@ -560,7 +560,7 @@ class D3D11ShaderPipeline : public GraphicsDataNode<IShaderPipeline>
const boo::ObjToken<IVertexFormat>& vtxFmt, const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite, ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling) bool alphaWrite, bool overwriteAlpha, CullMode culling)
: GraphicsDataNode<IShaderPipeline>(parent), m_vtxFmt(vtxFmt), : GraphicsDataNode<IShaderPipeline>(parent), m_vtxFmt(vtxFmt),
m_vert(std::move(vert)), m_pixel(std::move(pixel)), m_vert(std::move(vert)), m_pixel(std::move(pixel)),
m_topology(PRIMITIVE_TABLE[int(prim)]) m_topology(PRIMITIVE_TABLE[int(prim)])
@ -619,15 +619,36 @@ class D3D11ShaderPipeline : public GraphicsDataNode<IShaderPipeline>
blDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; blDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; blDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
blDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_REV_SUBTRACT; blDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_REV_SUBTRACT;
if (overwriteAlpha)
{
blDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
blDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
}
else
{
blDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
blDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
blDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_REV_SUBTRACT;
}
} }
else else
{ {
blDesc.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(srcFac)]; blDesc.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(srcFac)];
blDesc.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)]; blDesc.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)];
blDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
if (m_overwriteAlpha)
{
blDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
}
else
{
blDesc.RenderTarget[0].SrcBlendAlpha = BLEND_FACTOR_TABLE[int(srcFac)];
blDesc.RenderTarget[0].DestBlendAlpha = BLEND_FACTOR_TABLE[int(dstFac)];
}
blDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
} }
blDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
blDesc.RenderTarget[0].RenderTargetWriteMask = blDesc.RenderTarget[0].RenderTargetWriteMask =
(colorWrite ? (D3D11_COLOR_WRITE_ENABLE_RED | (colorWrite ? (D3D11_COLOR_WRITE_ENABLE_RED |
D3D11_COLOR_WRITE_ENABLE_GREEN | D3D11_COLOR_WRITE_ENABLE_GREEN |
@ -1381,7 +1402,7 @@ public:
ComPtr<ID3DBlob>* pipelineBlob, const boo::ObjToken<IVertexFormat>& vtxFmt, ComPtr<ID3DBlob>* pipelineBlob, const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite, ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling) bool alphaWrite, CullMode culling, bool overwriteAlpha)
{ {
XXH64_state_t hashState; XXH64_state_t hashState;
uint64_t srcHashes[2] = {}; uint64_t srcHashes[2] = {};
@ -1482,7 +1503,8 @@ public:
return {new D3D11ShaderPipeline(m_data, ctx, return {new D3D11ShaderPipeline(m_data, ctx,
std::move(vertShader), std::move(fragShader), std::move(vertShader), std::move(fragShader),
vtxFmt, srcFac, dstFac, prim, depthTest, depthWrite, colorWrite, alphaWrite, culling)}; vtxFmt, srcFac, dstFac, prim, depthTest, depthWrite, colorWrite,
alphaWrite, overwriteAlpha, culling)};
} }
boo::ObjToken<IShaderDataBinding> newShaderDataBinding( boo::ObjToken<IShaderDataBinding> newShaderDataBinding(

View File

@ -751,15 +751,36 @@ class D3D12ShaderPipeline : public GraphicsDataNode<IShaderPipeline>
desc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA; desc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA;
desc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_ONE; desc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_ONE;
desc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_REV_SUBTRACT; desc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_REV_SUBTRACT;
if (overwriteAlpha)
{
desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO;
desc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
}
else
{
desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA;
desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ONE;
desc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_REV_SUBTRACT;
}
} }
else else
{ {
desc.BlendState.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(srcFac)]; desc.BlendState.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(srcFac)];
desc.BlendState.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)]; desc.BlendState.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)];
desc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; desc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
if (m_overwriteAlpha)
{
desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO;
}
else
{
desc.BlendState.RenderTarget[0].SrcBlendAlpha = BLEND_FACTOR_TABLE[int(srcFac)];
desc.BlendState.RenderTarget[0].DestBlendAlpha = BLEND_FACTOR_TABLE[int(dstFac)];
}
desc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
} }
desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO;
} }
desc.BlendState.RenderTarget[0].RenderTargetWriteMask = desc.BlendState.RenderTarget[0].RenderTargetWriteMask =
(colorWrite ? (D3D12_COLOR_WRITE_ENABLE_RED | (colorWrite ? (D3D12_COLOR_WRITE_ENABLE_RED |
@ -1846,7 +1867,7 @@ public:
ComPtr<ID3DBlob>* pipelineBlob, const boo::ObjToken<IVertexFormat>& vtxFmt, ComPtr<ID3DBlob>* pipelineBlob, const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite, ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling) bool alphaWrite, CullMode culling, bool overwriteAlpha)
{ {
XXH64_state_t hashState; XXH64_state_t hashState;
uint64_t srcHashes[2] = {}; uint64_t srcHashes[2] = {};
@ -1930,9 +1951,10 @@ public:
} }
ID3DBlob* pipeline = pipelineBlob ? pipelineBlob->Get() : nullptr; ID3DBlob* pipeline = pipelineBlob ? pipelineBlob->Get() : nullptr;
D3D12ShaderPipeline* retval = new D3D12ShaderPipeline(m_data, m_parent.m_ctx, std::move(vertShader), std::move(fragShader), D3D12ShaderPipeline* retval = new D3D12ShaderPipeline(
pipeline, vtxFmt, srcFac, dstFac, prim, depthTest, depthWrite, colorWrite, m_data, m_parent.m_ctx, std::move(vertShader), std::move(fragShader),
alphaWrite, culling); pipeline, vtxFmt, srcFac, dstFac, prim, depthTest, depthWrite, colorWrite,
alphaWrite, overwriteAlpha, culling);
if (pipelineBlob && !*pipelineBlob) if (pipelineBlob && !*pipelineBlob)
retval->m_state->GetCachedBlob(&*pipelineBlob); retval->m_state->GetCachedBlob(&*pipelineBlob);
return retval; return retval;

View File

@ -669,6 +669,7 @@ class GLShaderPipeline : public GraphicsDataNode<IShaderPipeline>
bool m_colorWrite = true; bool m_colorWrite = true;
bool m_alphaWrite = true; bool m_alphaWrite = true;
bool m_subtractBlend = false; bool m_subtractBlend = false;
bool m_overwriteAlpha = false;
CullMode m_culling; CullMode m_culling;
mutable std::vector<GLint> m_uniLocs; mutable std::vector<GLint> m_uniLocs;
mutable std::vector<std::string> m_texNames; mutable std::vector<std::string> m_texNames;
@ -748,9 +749,13 @@ public:
if (m_dfactor != GL_ZERO) if (m_dfactor != GL_ZERO)
{ {
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFuncSeparate(m_sfactor, m_dfactor, GL_ONE, GL_ZERO); if (m_overwriteAlpha)
glBlendFuncSeparate(m_sfactor, m_dfactor, GL_ONE, GL_ZERO);
else
glBlendFuncSeparate(m_sfactor, m_dfactor, m_sfactor, m_dfactor);
if (m_subtractBlend) if (m_subtractBlend)
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); glBlendEquationSeparate(GL_FUNC_REVERSE_SUBTRACT,
m_overwriteAlpha ? GL_FUNC_ADD : GL_FUNC_REVERSE_SUBTRACT);
else else
glBlendEquation(GL_FUNC_ADD); glBlendEquation(GL_FUNC_ADD);
} }
@ -822,7 +827,7 @@ ObjToken<IShaderPipeline> GLDataFactory::Context::newShaderPipeline
size_t uniformBlockCount, const char** uniformBlockNames, size_t uniformBlockCount, const char** uniformBlockNames,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite, ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling) bool alphaWrite, CullMode culling, bool overwriteAlpha)
{ {
GLDataFactoryImpl& factory = static_cast<GLDataFactoryImpl&>(m_parent); GLDataFactoryImpl& factory = static_cast<GLDataFactoryImpl&>(m_parent);
ObjToken<IShaderPipeline> retval(new GLShaderPipeline(m_data)); ObjToken<IShaderPipeline> retval(new GLShaderPipeline(m_data));
@ -928,6 +933,7 @@ ObjToken<IShaderPipeline> GLDataFactory::Context::newShaderPipeline
shader.m_depthWrite = depthWrite; shader.m_depthWrite = depthWrite;
shader.m_colorWrite = colorWrite; shader.m_colorWrite = colorWrite;
shader.m_alphaWrite = alphaWrite; shader.m_alphaWrite = alphaWrite;
shader.m_overwriteAlpha = overwriteAlpha;
shader.m_culling = culling; shader.m_culling = culling;
shader.m_drawPrim = PRIMITIVE_TABLE[int(prim)]; shader.m_drawPrim = PRIMITIVE_TABLE[int(prim)];

View File

@ -99,7 +99,7 @@ class MetalDataFactoryImpl : public MetalDataFactory, public GraphicsDataFactory
m_gammaVFMT = ctx.newVertexFormat(2, vfmt); m_gammaVFMT = ctx.newVertexFormat(2, vfmt);
m_gammaShader = static_cast<Context&>(ctx).newShaderPipeline(GammaVS, GammaFS, m_gammaShader = static_cast<Context&>(ctx).newShaderPipeline(GammaVS, GammaFS,
nullptr, nullptr, m_gammaVFMT, BlendFactor::One, BlendFactor::Zero, nullptr, nullptr, m_gammaVFMT, BlendFactor::One, BlendFactor::Zero,
Primitive::TriStrips, ZTest::None, false, true, false, CullMode::None, false); Primitive::TriStrips, ZTest::None, false, true, false, CullMode::None, true, false);
m_gammaLUT = ctx.newDynamicTexture(256, 256, TextureFormat::I16, TextureClampMode::ClampToEdge); m_gammaLUT = ctx.newDynamicTexture(256, 256, TextureFormat::I16, TextureClampMode::ClampToEdge);
setDisplayGamma(1.f); setDisplayGamma(1.f);
const struct Vert { const struct Vert {
@ -879,7 +879,8 @@ class MetalShaderPipeline : public GraphicsDataNode<IShaderPipeline>
const ObjToken<IVertexFormat>& vtxFmt, NSUInteger targetSamples, const ObjToken<IVertexFormat>& vtxFmt, NSUInteger targetSamples,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite, ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling, bool depthAttachment = true) bool alphaWrite, bool overwriteAlpha, CullMode culling,
bool depthAttachment = true)
: GraphicsDataNode<IShaderPipeline>(parent), : GraphicsDataNode<IShaderPipeline>(parent),
m_drawPrim(PRIMITIVE_TABLE[int(prim)]), m_drawPrim(PRIMITIVE_TABLE[int(prim)]),
m_vert(std::move(vert)), m_frag(std::move(frag)) m_vert(std::move(vert)), m_frag(std::move(frag))
@ -912,15 +913,36 @@ class MetalShaderPipeline : public GraphicsDataNode<IShaderPipeline>
desc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha; desc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
desc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOne; desc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOne;
desc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationReverseSubtract; desc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationReverseSubtract;
if (overwriteAlpha)
{
desc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
desc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorZero;
desc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
}
else
{
desc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha;
desc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOne;
desc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationReverseSubtract;
}
} }
else else
{ {
desc.colorAttachments[0].sourceRGBBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)]; desc.colorAttachments[0].sourceRGBBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)];
desc.colorAttachments[0].destinationRGBBlendFactor = BLEND_FACTOR_TABLE[int(dstFac)]; desc.colorAttachments[0].destinationRGBBlendFactor = BLEND_FACTOR_TABLE[int(dstFac)];
desc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; desc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
if (overwriteAlpha)
{
desc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
desc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorZero;
}
else
{
desc.colorAttachments[0].sourceAlphaBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)];
desc.colorAttachments[0].destinationAlphaBlendFactor = BLEND_FACTOR_TABLE[int(dstFac)];
}
desc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
} }
desc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
desc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorZero;
desc.depthAttachmentPixelFormat = depthAttachment ? MTLPixelFormatDepth32Float : MTLPixelFormatInvalid; desc.depthAttachmentPixelFormat = depthAttachment ? MTLPixelFormatDepth32Float : MTLPixelFormatInvalid;
desc.inputPrimitiveTopology = MTLPrimitiveTopologyClassTriangle; desc.inputPrimitiveTopology = MTLPrimitiveTopologyClassTriangle;
NSError* err = nullptr; NSError* err = nullptr;
@ -1640,7 +1662,8 @@ MetalDataFactory::Context::newShaderPipeline(const char* vertSource, const char*
const ObjToken<IVertexFormat>& vtxFmt, const ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite, ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling, bool depthAttachment) bool alphaWrite, CullMode culling, bool overwriteAlpha,
bool depthAttachment)
{ {
@autoreleasepool @autoreleasepool
{ {
@ -1769,7 +1792,7 @@ MetalDataFactory::Context::newShaderPipeline(const char* vertSource, const char*
return {new MetalShaderPipeline(m_data, factory.m_ctx, std::move(vertShader), std::move(fragShader), return {new MetalShaderPipeline(m_data, factory.m_ctx, std::move(vertShader), std::move(fragShader),
vtxFmt, depthAttachment ? factory.m_ctx->m_sampleCount : 1, vtxFmt, depthAttachment ? factory.m_ctx->m_sampleCount : 1,
srcFac, dstFac, prim, depthTest, depthWrite, srcFac, dstFac, prim, depthTest, depthWrite,
colorWrite, alphaWrite, culling, depthAttachment)}; colorWrite, alphaWrite, overwriteAlpha, culling, depthAttachment)};
} }
} }

View File

@ -2164,6 +2164,7 @@ class VulkanShaderPipeline : public GraphicsDataNode<IShaderPipeline>
bool m_depthWrite; bool m_depthWrite;
bool m_colorWrite; bool m_colorWrite;
bool m_alphaWrite; bool m_alphaWrite;
bool m_overwriteAlpha;
CullMode m_culling; CullMode m_culling;
mutable VkPipeline m_pipeline = VK_NULL_HANDLE; mutable VkPipeline m_pipeline = VK_NULL_HANDLE;
@ -2175,12 +2176,12 @@ class VulkanShaderPipeline : public GraphicsDataNode<IShaderPipeline>
const boo::ObjToken<IVertexFormat>& vtxFmt, const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite, ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling) bool alphaWrite, bool overwriteAlpha, CullMode culling)
: GraphicsDataNode<IShaderPipeline>(parent), : GraphicsDataNode<IShaderPipeline>(parent),
m_ctx(ctx), m_pipelineCache(pipelineCache), m_vtxFmt(vtxFmt), m_ctx(ctx), m_pipelineCache(pipelineCache), m_vtxFmt(vtxFmt),
m_vert(std::move(vert)), m_frag(std::move(frag)), m_srcFac(srcFac), m_dstFac(dstFac), m_vert(std::move(vert)), m_frag(std::move(frag)), m_srcFac(srcFac), m_dstFac(dstFac),
m_prim(prim), m_depthTest(depthTest), m_depthWrite(depthWrite), m_colorWrite(colorWrite), m_prim(prim), m_depthTest(depthTest), m_depthWrite(depthWrite), m_colorWrite(colorWrite),
m_alphaWrite(alphaWrite), m_culling(culling) m_alphaWrite(alphaWrite), m_overwriteAlpha(overwriteAlpha), m_culling(culling)
{} {}
public: public:
~VulkanShaderPipeline() ~VulkanShaderPipeline()
@ -2308,16 +2309,36 @@ public:
colorAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; colorAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
colorAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE; colorAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
colorAttachment.colorBlendOp = VK_BLEND_OP_REVERSE_SUBTRACT; colorAttachment.colorBlendOp = VK_BLEND_OP_REVERSE_SUBTRACT;
if (m_overwriteAlpha)
{
colorAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
colorAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
colorAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
}
else
{
colorAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
colorAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
colorAttachment.alphaBlendOp = VK_BLEND_OP_REVERSE_SUBTRACT;
}
} }
else else
{ {
colorAttachment.srcColorBlendFactor = BLEND_FACTOR_TABLE[int(m_srcFac)]; colorAttachment.srcColorBlendFactor = BLEND_FACTOR_TABLE[int(m_srcFac)];
colorAttachment.dstColorBlendFactor = BLEND_FACTOR_TABLE[int(m_dstFac)]; colorAttachment.dstColorBlendFactor = BLEND_FACTOR_TABLE[int(m_dstFac)];
colorAttachment.colorBlendOp = VK_BLEND_OP_ADD; colorAttachment.colorBlendOp = VK_BLEND_OP_ADD;
if (m_overwriteAlpha)
{
colorAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
colorAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
}
else
{
colorAttachment.srcAlphaBlendFactor = BLEND_FACTOR_TABLE[int(m_srcFac)];
colorAttachment.dstAlphaBlendFactor = BLEND_FACTOR_TABLE[int(m_dstFac)];
}
colorAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
} }
colorAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
colorAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
colorAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
colorAttachment.colorWriteMask = colorAttachment.colorWriteMask =
(m_colorWrite ? (VK_COLOR_COMPONENT_R_BIT | (m_colorWrite ? (VK_COLOR_COMPONENT_R_BIT |
VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_G_BIT |
@ -3561,7 +3582,7 @@ boo::ObjToken<IShaderPipeline> VulkanDataFactory::Context::newShaderPipeline
std::vector<unsigned char>* pipelineBlob, const boo::ObjToken<IVertexFormat>& vtxFmt, std::vector<unsigned char>* pipelineBlob, const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim, BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite, ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling) bool alphaWrite, CullMode culling, bool overwriteAlpha)
{ {
VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent); VulkanDataFactoryImpl& factory = static_cast<VulkanDataFactoryImpl&>(m_parent);
@ -3688,7 +3709,7 @@ boo::ObjToken<IShaderPipeline> VulkanDataFactory::Context::newShaderPipeline
VulkanShaderPipeline* retval = new VulkanShaderPipeline(m_data, factory.m_ctx, std::move(vertShader), VulkanShaderPipeline* retval = new VulkanShaderPipeline(m_data, factory.m_ctx, std::move(vertShader),
std::move(fragShader), pipelineCache, vtxFmt, srcFac, std::move(fragShader), pipelineCache, vtxFmt, srcFac,
dstFac, prim, depthTest, depthWrite, colorWrite, dstFac, prim, depthTest, depthWrite, colorWrite,
alphaWrite, culling); alphaWrite, overwriteAlpha, culling);
if (pipelineBlob && pipelineBlob->empty()) if (pipelineBlob && pipelineBlob->empty())
{ {