diff --git a/src/gpu/GrBlend.h b/src/gpu/GrBlend.h index 42790fe445..8d1af859f2 100644 --- a/src/gpu/GrBlend.h +++ b/src/gpu/GrBlend.h @@ -112,6 +112,12 @@ static constexpr bool GrBlendCoeffRefsConstant(const GrBlendCoeff coeff) { return coeff == kConstC_GrBlendCoeff || coeff == kIConstC_GrBlendCoeff; } +static constexpr bool GrBlendShouldDisable(GrBlendEquation equation, GrBlendCoeff srcCoeff, + GrBlendCoeff dstCoeff) { + return (kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) && + kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff; +} + /** * Advanced blend equations can always tweak alpha for coverage. (See GrCustomXfermode.cpp) * diff --git a/src/gpu/d3d/GrD3DPipelineState.cpp b/src/gpu/d3d/GrD3DPipelineState.cpp index e4700576bd..f0682055ad 100644 --- a/src/gpu/d3d/GrD3DPipelineState.cpp +++ b/src/gpu/d3d/GrD3DPipelineState.cpp @@ -9,6 +9,7 @@ #include "include/private/SkTemplates.h" #include "src/gpu/GrProgramInfo.h" +#include "src/gpu/d3d/GrD3DGpu.h" static DXGI_FORMAT attrib_type_to_format(GrVertexAttribType type) { switch (type) { @@ -107,7 +108,106 @@ static void setup_vertex_input_layout(const GrPrimitiveProcessor& primProc, SkASSERT(instanceAttributeOffset == primProc.vertexStride()); } -std::unique_ptr GrD3DPipelineState::Make(const GrProgramInfo& programInfo) { +static D3D12_BLEND blend_coeff_to_d3d_blend(GrBlendCoeff coeff) { + switch (coeff) { + case kZero_GrBlendCoeff: + return D3D12_BLEND_ZERO; + case kOne_GrBlendCoeff: + return D3D12_BLEND_ONE; + case kSC_GrBlendCoeff: + return D3D12_BLEND_SRC_COLOR; + case kISC_GrBlendCoeff: + return D3D12_BLEND_INV_SRC_COLOR; + case kDC_GrBlendCoeff: + return D3D12_BLEND_DEST_COLOR; + case kIDC_GrBlendCoeff: + return D3D12_BLEND_INV_DEST_COLOR; + case kSA_GrBlendCoeff: + return D3D12_BLEND_SRC_ALPHA; + case kISA_GrBlendCoeff: + return D3D12_BLEND_INV_SRC_ALPHA; + case kDA_GrBlendCoeff: + return D3D12_BLEND_DEST_ALPHA; + case kIDA_GrBlendCoeff: + return D3D12_BLEND_INV_DEST_ALPHA; + case kConstC_GrBlendCoeff: + return D3D12_BLEND_BLEND_FACTOR; + case kIConstC_GrBlendCoeff: + return D3D12_BLEND_INV_BLEND_FACTOR; + case kS2C_GrBlendCoeff: + return D3D12_BLEND_SRC1_COLOR; + case kIS2C_GrBlendCoeff: + return D3D12_BLEND_INV_SRC1_COLOR; + case kS2A_GrBlendCoeff: + return D3D12_BLEND_SRC1_ALPHA; + case kIS2A_GrBlendCoeff: + return D3D12_BLEND_INV_SRC1_ALPHA; + case kIllegal_GrBlendCoeff: + return D3D12_BLEND_ZERO; + } + SkUNREACHABLE; +} + +static D3D12_BLEND_OP blend_equation_to_d3d_op(GrBlendEquation equation) { + switch (equation) { + case kAdd_GrBlendEquation: + return D3D12_BLEND_OP_ADD; + case kSubtract_GrBlendEquation: + return D3D12_BLEND_OP_SUBTRACT; + case kReverseSubtract_GrBlendEquation: + return D3D12_BLEND_OP_REV_SUBTRACT; + default: + SkUNREACHABLE; + } +} + +static void fill_in_blend_state(const GrPipeline& pipeline, D3D12_BLEND_DESC* blendDesc) { + blendDesc->AlphaToCoverageEnable = false; + blendDesc->IndependentBlendEnable = false; + + const GrXferProcessor::BlendInfo& blendInfo = pipeline.getXferProcessor().getBlendInfo(); + + GrBlendEquation equation = blendInfo.fEquation; + GrBlendCoeff srcCoeff = blendInfo.fSrcBlend; + GrBlendCoeff dstCoeff = blendInfo.fDstBlend; + bool blendOff = GrBlendShouldDisable(equation, srcCoeff, dstCoeff); + + auto& rtBlend = blendDesc->RenderTarget[0]; + rtBlend.BlendEnable = !blendOff; + if (!blendOff) { + rtBlend.SrcBlend = blend_coeff_to_d3d_blend(srcCoeff); + rtBlend.DestBlend = blend_coeff_to_d3d_blend(dstCoeff); + rtBlend.BlendOp = blend_equation_to_d3d_op(equation); + rtBlend.SrcBlendAlpha = blend_coeff_to_d3d_blend(srcCoeff); + rtBlend.DestBlendAlpha = blend_coeff_to_d3d_blend(dstCoeff); + rtBlend.BlendOpAlpha = blend_equation_to_d3d_op(equation); + } + + if (!blendInfo.fWriteColor) { + rtBlend.RenderTargetWriteMask = 0; + } else { + rtBlend.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + } +} + +static void fill_in_rasterizer_state(const GrPipeline& pipeline, const GrCaps* caps, + D3D12_RASTERIZER_DESC* rasterizer) { + rasterizer->FillMode = (caps->wireframeMode() || pipeline.isWireframe()) ? + D3D12_FILL_MODE_WIREFRAME : D3D12_FILL_MODE_SOLID; + rasterizer->CullMode = D3D12_CULL_MODE_NONE; + rasterizer->FrontCounterClockwise = true; + rasterizer->DepthBias = 0; + rasterizer->DepthBiasClamp = 0.0f; + rasterizer->SlopeScaledDepthBias = 0.0f; + rasterizer->DepthClipEnable = false; + rasterizer->MultisampleEnable = pipeline.isHWAntialiasState(); + rasterizer->AntialiasedLineEnable = false; + rasterizer->ForcedSampleCount = 0; + rasterizer->ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; +} + +std::unique_ptr GrD3DPipelineState::Make(GrD3DGpu* gpu, + const GrProgramInfo& programInfo) { D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; unsigned int totalAttributeCnt = programInfo.primProc().numVertexAttributes() + @@ -116,13 +216,16 @@ std::unique_ptr GrD3DPipelineState::Make(const GrProgramInfo setup_vertex_input_layout(programInfo.primProc(), inputElements.get()); psoDesc.InputLayout = { inputElements.get(), totalAttributeCnt }; + + fill_in_blend_state(programInfo.pipeline(), &psoDesc.BlendState); + + fill_in_rasterizer_state(programInfo.pipeline(), gpu->caps(), &psoDesc.RasterizerState); + // TODO: fill in the rest of the descriptor. #if 0 psoDesc.pRootSignature = m_rootSignature.Get(); psoDesc.VS = { reinterpret_cast(vertexShader->GetBufferPointer()), vertexShader->GetBufferSize() }; psoDesc.PS = { reinterpret_cast(pixelShader->GetBufferPointer()), pixelShader->GetBufferSize() }; - psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); - psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); psoDesc.DepthStencilState.DepthEnable = FALSE; psoDesc.DepthStencilState.StencilEnable = FALSE; psoDesc.SampleMask = UINT_MAX; diff --git a/src/gpu/d3d/GrD3DPipelineState.h b/src/gpu/d3d/GrD3DPipelineState.h index 19b345fd74..674493076c 100644 --- a/src/gpu/d3d/GrD3DPipelineState.h +++ b/src/gpu/d3d/GrD3DPipelineState.h @@ -12,11 +12,12 @@ #include "src/gpu/d3d/GrD3D12.h" #include +class GrD3DGpu; class GrProgramInfo; class GrD3DPipelineState { public: - static std::unique_ptr Make(const GrProgramInfo&); + static std::unique_ptr Make(GrD3DGpu* gpu, const GrProgramInfo&); private: GrD3DPipelineState(gr_cp pipelineState); diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 94b18ff620..3e3648f4bf 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -2493,10 +2493,8 @@ void GrGLGpu::flushBlendAndColorWrite( // Any optimization to disable blending should have already been applied and // tweaked the equation to "add" or "subtract", and the coeffs to (1, 0). - bool blendOff = - ((kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) && - kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff) || - !blendInfo.fWriteColor; + bool blendOff = GrBlendShouldDisable(equation, srcCoeff, dstCoeff) || + !blendInfo.fWriteColor; if (blendOff) { if (kNo_TriState != fHWBlendState.fEnabled) { diff --git a/src/gpu/mtl/GrMtlPipelineStateBuilder.mm b/src/gpu/mtl/GrMtlPipelineStateBuilder.mm index e98cccb1e1..4cfb225619 100644 --- a/src/gpu/mtl/GrMtlPipelineStateBuilder.mm +++ b/src/gpu/mtl/GrMtlPipelineStateBuilder.mm @@ -346,8 +346,7 @@ static MTLRenderPipelineColorAttachmentDescriptor* create_color_attachment( GrBlendEquation equation = blendInfo.fEquation; GrBlendCoeff srcCoeff = blendInfo.fSrcBlend; GrBlendCoeff dstCoeff = blendInfo.fDstBlend; - bool blendOff = (kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) && - kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff; + bool blendOff = GrBlendShouldDisable(equation, srcCoeff, dstCoeff); mtlColorAttachment.blendingEnabled = !blendOff; if (!blendOff) { diff --git a/src/gpu/vk/GrVkPipeline.cpp b/src/gpu/vk/GrVkPipeline.cpp index 52dd2b4bd9..660bf3a77c 100644 --- a/src/gpu/vk/GrVkPipeline.cpp +++ b/src/gpu/vk/GrVkPipeline.cpp @@ -427,8 +427,7 @@ static void setup_color_blend_state(const GrPipeline& pipeline, GrBlendEquation equation = blendInfo.fEquation; GrBlendCoeff srcCoeff = blendInfo.fSrcBlend; GrBlendCoeff dstCoeff = blendInfo.fDstBlend; - bool blendOff = (kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) && - kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff; + bool blendOff = GrBlendShouldDisable(equation, srcCoeff, dstCoeff); memset(attachmentState, 0, sizeof(VkPipelineColorBlendAttachmentState)); attachmentState->blendEnable = !blendOff;