Commit 4d65934f by Chris Forbes

Fix FP blending path to not make clamping assumptions

We had assumed in Context in various places that negative pixel values would be clamped to zero, which is incorrect for floating-point color attachments. TODO: on the assumption that there is value in these blend optimizations themselves, we should split the context blend state to be per-attachment. This would give us the `independentBlend` optional feature, and also allow us to keep the optimization for those attachments which do have clamping in a mixed MRT scenario. Bug: b/132433217 Test: dEQP-VK.pipeline.blend.format.r16* Change-Id: I5434475aba5d21a8c8342b42cccc575b517f0900 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31050Tested-by: 's avatarChris Forbes <chrisforbes@google.com> Presubmit-Ready: Chris Forbes <chrisforbes@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent b1665554
......@@ -324,6 +324,20 @@ namespace sw
return destBlendFactorState;
}
bool Context::allTargetsColorClamp() const
{
// TODO: remove all of this and support VkPhysicalDeviceFeatures::independentBlend instead
for (int i = 0; i < RENDERTARGETS; i++)
{
if (renderTarget[i] && renderTarget[i]->getFormat().isFloatFormat())
{
return false;
}
}
return true;
}
VkBlendOp Context::blendOperation() const
{
if(!alphaBlendEnable) return VK_BLEND_OP_SRC_EXT;
......@@ -365,7 +379,7 @@ namespace sw
}
}
case VK_BLEND_OP_SUBTRACT:
if(sourceBlendFactor() == VK_BLEND_FACTOR_ZERO)
if(sourceBlendFactor() == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
{
return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero
}
......@@ -405,7 +419,7 @@ namespace sw
}
else if(sourceBlendFactor() == VK_BLEND_FACTOR_ONE)
{
if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
if(destBlendFactor() == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
{
return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero
}
......@@ -416,7 +430,7 @@ namespace sw
}
else
{
if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
if(destBlendFactor() == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
{
return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero
}
......@@ -533,7 +547,7 @@ namespace sw
}
}
case VK_BLEND_OP_SUBTRACT:
if(sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
if(sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
{
return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero
}
......@@ -573,7 +587,7 @@ namespace sw
}
else if(sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ONE)
{
if(destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
if(destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
{
return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero
}
......@@ -584,7 +598,7 @@ namespace sw
}
else
{
if(destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
if(destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
{
return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero
}
......
......@@ -123,6 +123,7 @@ namespace sw
bool perspectiveActive() const;
bool allTargetsColorClamp() const;
bool alphaBlendActive() const;
VkBlendFactor sourceBlendFactor() const;
VkBlendFactor destBlendFactor() const;
......
......@@ -1672,10 +1672,14 @@ namespace sw
switch(blendFactorActive)
{
case VK_BLEND_FACTOR_ZERO:
// Optimized
blendFactor.x = Float4(0);
blendFactor.y = Float4(0);
blendFactor.z = Float4(0);
break;
case VK_BLEND_FACTOR_ONE:
// Optimized
blendFactor.x = Float4(1);
blendFactor.y = Float4(1);
blendFactor.z = Float4(1);
break;
case VK_BLEND_FACTOR_SRC_COLOR:
blendFactor.x = oC.x;
......@@ -1754,10 +1758,10 @@ namespace sw
switch(blendFactorAlphaActive)
{
case VK_BLEND_FACTOR_ZERO:
// Optimized
blendFactor.w = Float4(0);
break;
case VK_BLEND_FACTOR_ONE:
// Optimized
blendFactor.w = Float4(1);
break;
case VK_BLEND_FACTOR_SRC_COLOR:
blendFactor.w = oC.w;
......@@ -1928,19 +1932,13 @@ namespace sw
blendFactor(sourceFactor, oC, pixel, state.sourceBlendFactor);
blendFactor(destFactor, oC, pixel, state.destBlendFactor);
if(state.sourceBlendFactor != VK_BLEND_FACTOR_ONE && state.sourceBlendFactor != VK_BLEND_FACTOR_ZERO)
{
oC.x *= sourceFactor.x;
oC.y *= sourceFactor.y;
oC.z *= sourceFactor.z;
}
oC.x *= sourceFactor.x;
oC.y *= sourceFactor.y;
oC.z *= sourceFactor.z;
if(state.destBlendFactor != VK_BLEND_FACTOR_ONE && state.destBlendFactor != VK_BLEND_FACTOR_ZERO)
{
pixel.x *= destFactor.x;
pixel.y *= destFactor.y;
pixel.z *= destFactor.z;
}
pixel.x *= destFactor.x;
pixel.y *= destFactor.y;
pixel.z *= destFactor.z;
switch(state.blendOperation)
{
......@@ -1989,15 +1987,8 @@ namespace sw
blendFactorAlpha(sourceFactor, oC, pixel, state.sourceBlendFactorAlpha);
blendFactorAlpha(destFactor, oC, pixel, state.destBlendFactorAlpha);
if(state.sourceBlendFactorAlpha != VK_BLEND_FACTOR_ONE && state.sourceBlendFactorAlpha != VK_BLEND_FACTOR_ZERO)
{
oC.w *= sourceFactor.w;
}
if(state.destBlendFactorAlpha != VK_BLEND_FACTOR_ONE && state.destBlendFactorAlpha != VK_BLEND_FACTOR_ZERO)
{
pixel.w *= destFactor.w;
}
oC.w *= sourceFactor.w;
pixel.w *= destFactor.w;
switch(state.blendOperationAlpha)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment