diff --git a/Source/Engine/Graphics/GPUContext.h b/Source/Engine/Graphics/GPUContext.h index 593282555..99a226193 100644 --- a/Source/Engine/Graphics/GPUContext.h +++ b/Source/Engine/Graphics/GPUContext.h @@ -315,6 +315,12 @@ public: /// The array with render targets to bind. API_FUNCTION() virtual void SetRenderTarget(GPUTextureView* depthBuffer, const Span& rts) = 0; + /// + /// Sets the blend factor that modulate values for a pixel shader, render target, or both. + /// + /// Blend factors, one for each RGBA component. + API_FUNCTION() virtual void SetBlendFactor(const Float4& value) = 0; + public: /// /// Unbinds all shader resource slots and flushes the change with the driver (used to prevent driver detection of resource hazards, eg. when down-scaling the texture). diff --git a/Source/Engine/Graphics/RenderTools.cpp b/Source/Engine/Graphics/RenderTools.cpp index 67cbce85b..8389e5d3c 100644 --- a/Source/Engine/Graphics/RenderTools.cpp +++ b/Source/Engine/Graphics/RenderTools.cpp @@ -181,116 +181,75 @@ uint32 GetHash(const BlendingMode& key) return hash; } +// @formatter:off + BlendingMode BlendingMode::Opaque = { - false, - // AlphaToCoverageEnable - false, - // BlendEnable - Blend::One, - // SrcBlend - Blend::Zero, - // DestBlend - Operation::Add, - // BlendOp - Blend::One, - // SrcBlendAlpha - Blend::Zero, - // DestBlendAlpha - Operation::Add, - // BlendOpAlpha - ColorWrite::All, - // RenderTargetWriteMask + false, // AlphaToCoverageEnable + false, // BlendEnable + Blend::One, // SrcBlend + Blend::Zero, // DestBlend + Operation::Add, // BlendOp + Blend::One, // SrcBlendAlpha + Blend::Zero, // DestBlendAlpha + Operation::Add, // BlendOpAlpha + ColorWrite::All, // RenderTargetWriteMask }; BlendingMode BlendingMode::Additive = { - false, - // AlphaToCoverageEnable - true, - // BlendEnable - Blend::SrcAlpha, - // SrcBlend - Blend::One, - // DestBlend - Operation::Add, - // BlendOp - Blend::SrcAlpha, - // SrcBlendAlpha - Blend::One, - // DestBlendAlpha - Operation::Add, - // BlendOpAlpha - ColorWrite::All, - // RenderTargetWriteMask + false, // AlphaToCoverageEnable + true, // BlendEnable + Blend::SrcAlpha, // SrcBlend + Blend::One, // DestBlend + Operation::Add, // BlendOp + Blend::SrcAlpha, // SrcBlendAlpha + Blend::One, // DestBlendAlpha + Operation::Add, // BlendOpAlpha + ColorWrite::All, // RenderTargetWriteMask }; BlendingMode BlendingMode::AlphaBlend = { - false, - // AlphaToCoverageEnable - true, - // BlendEnable - Blend::SrcAlpha, - // SrcBlend - Blend::InvSrcAlpha, - // DestBlend - Operation::Add, - // BlendOp - Blend::One, - // SrcBlendAlpha - Blend::InvSrcAlpha, - // DestBlendAlpha - Operation::Add, - // BlendOpAlpha - ColorWrite::All, - // RenderTargetWriteMask + false, // AlphaToCoverageEnable + true, // BlendEnable + Blend::SrcAlpha, // SrcBlend + Blend::InvSrcAlpha, // DestBlend + Operation::Add, // BlendOp + Blend::One, // SrcBlendAlpha + Blend::InvSrcAlpha, // DestBlendAlpha + Operation::Add, // BlendOpAlpha + ColorWrite::All, // RenderTargetWriteMask }; BlendingMode BlendingMode::Add = { - false, - // AlphaToCoverageEnable - true, - // BlendEnable - Blend::One, - // SrcBlend - Blend::One, - // DestBlend - Operation::Add, - // BlendOp - Blend::One, - // SrcBlendAlpha - Blend::One, - // DestBlendAlpha - Operation::Add, - // BlendOpAlpha - ColorWrite::All, - // RenderTargetWriteMask + false, // AlphaToCoverageEnable + true, // BlendEnable + Blend::One, // SrcBlend + Blend::One, // DestBlend + Operation::Add, // BlendOp + Blend::One, // SrcBlendAlpha + Blend::One, // DestBlendAlpha + Operation::Add, // BlendOpAlpha + ColorWrite::All, // RenderTargetWriteMask }; BlendingMode BlendingMode::Multiply = { - false, - // AlphaToCoverageEnable - true, - // BlendEnable - Blend::Zero, - // SrcBlend - Blend::SrcColor, - // DestBlend - Operation::Add, - // BlendOp - Blend::Zero, - // SrcBlendAlpha - Blend::SrcAlpha, - // DestBlendAlpha - Operation::Add, - // BlendOpAlpha - ColorWrite::All, - // RenderTargetWriteMask + false, // AlphaToCoverageEnable + true, // BlendEnable + Blend::Zero, // SrcBlend + Blend::SrcColor, // DestBlend + Operation::Add, // BlendOp + Blend::Zero, // SrcBlendAlpha + Blend::SrcAlpha, // DestBlendAlpha + Operation::Add, // BlendOpAlpha + ColorWrite::All, // RenderTargetWriteMask }; +// @formatter:on + FeatureLevel RenderTools::GetFeatureLevel(ShaderProfile profile) { switch (profile) diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.cpp index 06f666e12..2ac639e30 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.cpp @@ -103,6 +103,7 @@ void GPUContextDX11::FrameBegin() CurrentPS = nullptr; CurrentCS = nullptr; CurrentPrimitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; + CurrentBlendFactor = Float4::One; // Bind static samplers ID3D11SamplerState* samplers[] = @@ -267,6 +268,13 @@ void GPUContextDX11::SetRenderTarget(GPUTextureView* depthBuffer, const SpanOMSetBlendState(CurrentBlendState, CurrentBlendFactor.Raw, D3D11_DEFAULT_SAMPLE_MASK); +} + void GPUContextDX11::ResetSR() { _srDirtyFlag = false; @@ -560,8 +568,7 @@ void GPUContextDX11::SetState(GPUPipelineState* state) if (CurrentBlendState != blendState) { CurrentBlendState = blendState; - FLOAT blendFactor[4] = { 1, 1, 1, 1 }; - _context->OMSetBlendState(blendState, blendFactor, D3D11_DEFAULT_SAMPLE_MASK); + _context->OMSetBlendState(blendState, CurrentBlendFactor.Raw, D3D11_DEFAULT_SAMPLE_MASK); } if (CurrentVS != vs) { diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.h b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.h index 209968fda..b623cba3b 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUContextDX11.h @@ -61,6 +61,7 @@ private: GPUShaderProgramPSDX11* CurrentPS; GPUShaderProgramCSDX11* CurrentCS; D3D11_PRIMITIVE_TOPOLOGY CurrentPrimitiveTopology; + Float4 CurrentBlendFactor; public: @@ -115,6 +116,7 @@ public: void SetRenderTarget(GPUTextureView* rt) override; void SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureView* rt) override; void SetRenderTarget(GPUTextureView* depthBuffer, const Span& rts) override; + void SetBlendFactor(const Float4& value) override; void ResetSR() override; void ResetUA() override; void ResetCB() override; diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp index b8af1178b..54f1a4290 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp @@ -845,6 +845,11 @@ void GPUContextDX12::SetRenderTarget(GPUTextureView* depthBuffer, const SpanOMSetBlendFactor(value.Raw); +} + void GPUContextDX12::ResetSR() { for (int32 slot = 0; slot < GPU_MAX_SR_BINDED; slot++) diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h index 4ab6c9155..c870cf71e 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h @@ -166,6 +166,7 @@ public: void SetRenderTarget(GPUTextureView* rt) override; void SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureView* rt) override; void SetRenderTarget(GPUTextureView* depthBuffer, const Span& rts) override; + void SetBlendFactor(const Float4& value) override; void ResetSR() override; void ResetUA() override; void ResetCB() override; diff --git a/Source/Engine/GraphicsDevice/Null/GPUContextNull.h b/Source/Engine/GraphicsDevice/Null/GPUContextNull.h index a1ffc290a..7568bb60c 100644 --- a/Source/Engine/GraphicsDevice/Null/GPUContextNull.h +++ b/Source/Engine/GraphicsDevice/Null/GPUContextNull.h @@ -84,6 +84,10 @@ public: { } + void SetBlendFactor(const Float4& value) override + { + } + void ResetSR() override { } diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp index 5c13dd896..d52b446e3 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp @@ -966,6 +966,12 @@ void GPUContextVulkan::SetRenderTarget(GPUTextureView* depthBuffer, const SpanGetCmdBuffer(); + vkCmdSetBlendConstants(cmdBuffer->GetHandle(), value.Raw); +} + void GPUContextVulkan::ResetSR() { Platform::MemoryClear(_srHandles, sizeof(_srHandles)); diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h index 2b8d9f122..63224b2d0 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h @@ -184,6 +184,7 @@ public: void SetRenderTarget(GPUTextureView* rt) override; void SetRenderTarget(GPUTextureView* depthBuffer, GPUTextureView* rt) override; void SetRenderTarget(GPUTextureView* depthBuffer, const Span& rts) override; + void SetBlendFactor(const Float4& value) override; void ResetSR() override; void ResetUA() override; void ResetCB() override;