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,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
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,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling);
bool alphaWrite, CullMode culling, bool overwriteAlpha = true);
ObjToken<IShaderDataBinding>
newShaderDataBinding(const ObjToken<IShaderPipeline>& pipeline,

View File

@ -48,7 +48,9 @@ public:
const ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
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>
newShaderDataBinding(const ObjToken<IShaderPipeline>& pipeline,

View File

@ -160,7 +160,7 @@ public:
const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
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,
const boo::ObjToken<IVertexFormat>& vtxFmt,

View File

@ -560,7 +560,7 @@ class D3D11ShaderPipeline : public GraphicsDataNode<IShaderPipeline>
const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling)
bool alphaWrite, bool overwriteAlpha, CullMode culling)
: GraphicsDataNode<IShaderPipeline>(parent), m_vtxFmt(vtxFmt),
m_vert(std::move(vert)), m_pixel(std::move(pixel)),
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].DestBlend = D3D11_BLEND_ONE;
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
{
blDesc.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(srcFac)];
blDesc.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)];
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 =
(colorWrite ? (D3D11_COLOR_WRITE_ENABLE_RED |
D3D11_COLOR_WRITE_ENABLE_GREEN |
@ -1381,7 +1402,7 @@ public:
ComPtr<ID3DBlob>* pipelineBlob, const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling)
bool alphaWrite, CullMode culling, bool overwriteAlpha)
{
XXH64_state_t hashState;
uint64_t srcHashes[2] = {};
@ -1482,7 +1503,8 @@ public:
return {new D3D11ShaderPipeline(m_data, ctx,
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(

View File

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

View File

@ -669,6 +669,7 @@ class GLShaderPipeline : public GraphicsDataNode<IShaderPipeline>
bool m_colorWrite = true;
bool m_alphaWrite = true;
bool m_subtractBlend = false;
bool m_overwriteAlpha = false;
CullMode m_culling;
mutable std::vector<GLint> m_uniLocs;
mutable std::vector<std::string> m_texNames;
@ -748,9 +749,13 @@ public:
if (m_dfactor != GL_ZERO)
{
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)
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
glBlendEquationSeparate(GL_FUNC_REVERSE_SUBTRACT,
m_overwriteAlpha ? GL_FUNC_ADD : GL_FUNC_REVERSE_SUBTRACT);
else
glBlendEquation(GL_FUNC_ADD);
}
@ -822,7 +827,7 @@ ObjToken<IShaderPipeline> GLDataFactory::Context::newShaderPipeline
size_t uniformBlockCount, const char** uniformBlockNames,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling)
bool alphaWrite, CullMode culling, bool overwriteAlpha)
{
GLDataFactoryImpl& factory = static_cast<GLDataFactoryImpl&>(m_parent);
ObjToken<IShaderPipeline> retval(new GLShaderPipeline(m_data));
@ -928,6 +933,7 @@ ObjToken<IShaderPipeline> GLDataFactory::Context::newShaderPipeline
shader.m_depthWrite = depthWrite;
shader.m_colorWrite = colorWrite;
shader.m_alphaWrite = alphaWrite;
shader.m_overwriteAlpha = overwriteAlpha;
shader.m_culling = culling;
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_gammaShader = static_cast<Context&>(ctx).newShaderPipeline(GammaVS, GammaFS,
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);
setDisplayGamma(1.f);
const struct Vert {
@ -879,7 +879,8 @@ class MetalShaderPipeline : public GraphicsDataNode<IShaderPipeline>
const ObjToken<IVertexFormat>& vtxFmt, NSUInteger targetSamples,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
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),
m_drawPrim(PRIMITIVE_TABLE[int(prim)]),
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].destinationRGBBlendFactor = MTLBlendFactorOne;
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
{
desc.colorAttachments[0].sourceRGBBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)];
desc.colorAttachments[0].destinationRGBBlendFactor = BLEND_FACTOR_TABLE[int(dstFac)];
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.inputPrimitiveTopology = MTLPrimitiveTopologyClassTriangle;
NSError* err = nullptr;
@ -1640,7 +1662,8 @@ MetalDataFactory::Context::newShaderPipeline(const char* vertSource, const char*
const ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling, bool depthAttachment)
bool alphaWrite, CullMode culling, bool overwriteAlpha,
bool depthAttachment)
{
@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),
vtxFmt, depthAttachment ? factory.m_ctx->m_sampleCount : 1,
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_colorWrite;
bool m_alphaWrite;
bool m_overwriteAlpha;
CullMode m_culling;
mutable VkPipeline m_pipeline = VK_NULL_HANDLE;
@ -2175,12 +2176,12 @@ class VulkanShaderPipeline : public GraphicsDataNode<IShaderPipeline>
const boo::ObjToken<IVertexFormat>& vtxFmt,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling)
bool alphaWrite, bool overwriteAlpha, CullMode culling)
: GraphicsDataNode<IShaderPipeline>(parent),
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_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:
~VulkanShaderPipeline()
@ -2308,16 +2309,36 @@ public:
colorAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
colorAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
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
{
colorAttachment.srcColorBlendFactor = BLEND_FACTOR_TABLE[int(m_srcFac)];
colorAttachment.dstColorBlendFactor = BLEND_FACTOR_TABLE[int(m_dstFac)];
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 =
(m_colorWrite ? (VK_COLOR_COMPONENT_R_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,
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
ZTest depthTest, bool depthWrite, bool colorWrite,
bool alphaWrite, CullMode culling)
bool alphaWrite, CullMode culling, bool overwriteAlpha)
{
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),
std::move(fragShader), pipelineCache, vtxFmt, srcFac,
dstFac, prim, depthTest, depthWrite, colorWrite,
alphaWrite, culling);
alphaWrite, overwriteAlpha, culling);
if (pipelineBlob && pipelineBlob->empty())
{