Support for independentBlend feature
A few blend related context members were changed from scalars to
arrays in order to support independent blend.
Bug b/140193782
Change-Id: I5ca1153e952fe0d3899f68dc6cd7cc5d8a244b72
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/34113
Tested-by: Alexis Hétu <sugoi@google.com>
Presubmit-Ready: Alexis Hétu <sugoi@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/Device/Context.cpp b/src/Device/Context.cpp
index c0f8ec1..af55417 100644
--- a/src/Device/Context.cpp
+++ b/src/Device/Context.cpp
@@ -24,6 +24,19 @@
namespace sw
{
+ void BlendState::init()
+ {
+ alphaBlendEnable = false;
+
+ sourceBlendFactor = VK_BLEND_FACTOR_ONE;
+ destBlendFactor = VK_BLEND_FACTOR_ZERO;
+ blendOperation = VK_BLEND_OP_ADD;
+
+ sourceBlendFactorAlpha = VK_BLEND_FACTOR_ONE;
+ destBlendFactorAlpha = VK_BLEND_FACTOR_ZERO;
+ blendOperationAlpha = VK_BLEND_OP_ADD;
+ }
+
Context::Context()
{
init();
@@ -88,6 +101,8 @@
for(int i = 0; i < RENDERTARGETS; ++i)
{
renderTarget[i] = nullptr;
+
+ blendState[i].init();
}
depthBuffer = nullptr;
stencilBuffer = nullptr;
@@ -103,15 +118,6 @@
depthBufferEnable = false;
depthWriteEnable = false;
- alphaBlendEnable = false;
- sourceBlendFactorState = VK_BLEND_FACTOR_ONE;
- destBlendFactorState = VK_BLEND_FACTOR_ZERO;
- blendOperationState = VK_BLEND_OP_ADD;
-
- sourceBlendFactorStateAlpha = VK_BLEND_FACTOR_ONE;
- destBlendFactorStateAlpha = VK_BLEND_FACTOR_ZERO;
- blendOperationStateAlpha = VK_BLEND_OP_ADD;
-
cullMode = VK_CULL_MODE_FRONT_BIT;
frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
@@ -153,9 +159,33 @@
return stencilBuffer && stencilEnable;
}
- bool Context::alphaBlendActive() const
+ void Context::setBlendState(int index, BlendState state)
{
- if(!alphaBlendEnable)
+ ASSERT((index >= 0) && (index < RENDERTARGETS));
+
+ blendState[index] = state;
+ }
+
+ BlendState Context::getBlendState(int index) const
+ {
+ ASSERT((index >= 0) && (index < RENDERTARGETS));
+
+ BlendState activeBlendState;
+ activeBlendState.alphaBlendEnable = alphaBlendActive(index);
+ activeBlendState.sourceBlendFactor = sourceBlendFactor(index);
+ activeBlendState.destBlendFactor = destBlendFactor(index);
+ activeBlendState.blendOperation = blendOperation(index);
+ activeBlendState.sourceBlendFactorAlpha = sourceBlendFactorAlpha(index);
+ activeBlendState.destBlendFactorAlpha = destBlendFactorAlpha(index);
+ activeBlendState.blendOperationAlpha = blendOperationAlpha(index);
+ return activeBlendState;
+ }
+
+ bool Context::alphaBlendActive(int index) const
+ {
+ ASSERT((index >= 0) && (index < RENDERTARGETS));
+
+ if(!blendState[index].alphaBlendEnable)
{
return false;
}
@@ -165,22 +195,24 @@
return false;
}
- bool colorBlend = !(blendOperation() == VK_BLEND_OP_SRC_EXT && sourceBlendFactor() == VK_BLEND_FACTOR_ONE);
- bool alphaBlend = !(blendOperationAlpha() == VK_BLEND_OP_SRC_EXT && sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ONE);
+ bool colorBlend = !(blendOperation(index) == VK_BLEND_OP_SRC_EXT && sourceBlendFactor(index) == VK_BLEND_FACTOR_ONE);
+ bool alphaBlend = !(blendOperationAlpha(index) == VK_BLEND_OP_SRC_EXT && sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ONE);
return colorBlend || alphaBlend;
}
- VkBlendFactor Context::sourceBlendFactor() const
+ VkBlendFactor Context::sourceBlendFactor(int index) const
{
- if(!alphaBlendEnable) return VK_BLEND_FACTOR_ONE;
+ ASSERT((index >= 0) && (index < RENDERTARGETS));
- switch(blendOperationState)
+ if(!blendState[index].alphaBlendEnable) return VK_BLEND_FACTOR_ONE;
+
+ switch(blendState[index].blendOperation)
{
case VK_BLEND_OP_ADD:
case VK_BLEND_OP_SUBTRACT:
case VK_BLEND_OP_REVERSE_SUBTRACT:
- return sourceBlendFactorState;
+ return blendState[index].sourceBlendFactor;
case VK_BLEND_OP_MIN:
return VK_BLEND_FACTOR_ONE;
case VK_BLEND_OP_MAX:
@@ -189,19 +221,21 @@
ASSERT(false);
}
- return sourceBlendFactorState;
+ return blendState[index].sourceBlendFactor;
}
- VkBlendFactor Context::destBlendFactor() const
+ VkBlendFactor Context::destBlendFactor(int index) const
{
- if(!alphaBlendEnable) return VK_BLEND_FACTOR_ONE;
+ ASSERT((index >= 0) && (index < RENDERTARGETS));
- switch(blendOperationState)
+ if(!blendState[index].alphaBlendEnable) return VK_BLEND_FACTOR_ONE;
+
+ switch(blendState[index].blendOperation)
{
case VK_BLEND_OP_ADD:
case VK_BLEND_OP_SUBTRACT:
case VK_BLEND_OP_REVERSE_SUBTRACT:
- return destBlendFactorState;
+ return blendState[index].destBlendFactor;
case VK_BLEND_OP_MIN:
return VK_BLEND_FACTOR_ONE;
case VK_BLEND_OP_MAX:
@@ -210,7 +244,7 @@
ASSERT(false);
}
- return destBlendFactorState;
+ return blendState[index].destBlendFactor;
}
bool Context::allTargetsColorClamp() const
@@ -227,16 +261,18 @@
return true;
}
- VkBlendOp Context::blendOperation() const
+ VkBlendOp Context::blendOperation(int index) const
{
- if(!alphaBlendEnable) return VK_BLEND_OP_SRC_EXT;
+ ASSERT((index >= 0) && (index < RENDERTARGETS));
- switch(blendOperationState)
+ if(!blendState[index].alphaBlendEnable) return VK_BLEND_OP_SRC_EXT;
+
+ switch(blendState[index].blendOperation)
{
case VK_BLEND_OP_ADD:
- if(sourceBlendFactor() == VK_BLEND_FACTOR_ZERO)
+ if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
{
- if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
+ if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
{
return VK_BLEND_OP_ZERO_EXT;
}
@@ -245,9 +281,9 @@
return VK_BLEND_OP_DST_EXT;
}
}
- else if(sourceBlendFactor() == VK_BLEND_FACTOR_ONE)
+ else if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ONE)
{
- if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
+ if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
{
return VK_BLEND_OP_SRC_EXT;
}
@@ -258,7 +294,7 @@
}
else
{
- if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
+ if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
{
return VK_BLEND_OP_SRC_EXT;
}
@@ -268,13 +304,13 @@
}
}
case VK_BLEND_OP_SUBTRACT:
- if(sourceBlendFactor() == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
+ if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
{
return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero
}
- else if(sourceBlendFactor() == VK_BLEND_FACTOR_ONE)
+ else if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ONE)
{
- if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
+ if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
{
return VK_BLEND_OP_SRC_EXT;
}
@@ -285,7 +321,7 @@
}
else
{
- if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
+ if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
{
return VK_BLEND_OP_SRC_EXT;
}
@@ -295,9 +331,9 @@
}
}
case VK_BLEND_OP_REVERSE_SUBTRACT:
- if(sourceBlendFactor() == VK_BLEND_FACTOR_ZERO)
+ if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
{
- if(destBlendFactor() == VK_BLEND_FACTOR_ZERO)
+ if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO)
{
return VK_BLEND_OP_ZERO_EXT;
}
@@ -306,9 +342,9 @@
return VK_BLEND_OP_DST_EXT;
}
}
- else if(sourceBlendFactor() == VK_BLEND_FACTOR_ONE)
+ else if(sourceBlendFactor(index) == VK_BLEND_FACTOR_ONE)
{
- if(destBlendFactor() == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
+ if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
{
return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero
}
@@ -319,7 +355,7 @@
}
else
{
- if(destBlendFactor() == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
+ if(destBlendFactor(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
{
return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero
}
@@ -336,17 +372,19 @@
ASSERT(false);
}
- return blendOperationState;
+ return blendState[index].blendOperation;
}
- VkBlendFactor Context::sourceBlendFactorAlpha() const
+ VkBlendFactor Context::sourceBlendFactorAlpha(int index) const
{
- switch (blendOperationStateAlpha)
+ ASSERT((index >= 0) && (index < RENDERTARGETS));
+
+ switch (blendState[index].blendOperationAlpha)
{
case VK_BLEND_OP_ADD:
case VK_BLEND_OP_SUBTRACT:
case VK_BLEND_OP_REVERSE_SUBTRACT:
- return sourceBlendFactorStateAlpha;
+ return blendState[index].sourceBlendFactorAlpha;
case VK_BLEND_OP_MIN:
return VK_BLEND_FACTOR_ONE;
case VK_BLEND_OP_MAX:
@@ -355,17 +393,19 @@
ASSERT(false);
}
- return sourceBlendFactorStateAlpha;
+ return blendState[index].sourceBlendFactorAlpha;
}
- VkBlendFactor Context::destBlendFactorAlpha() const
+ VkBlendFactor Context::destBlendFactorAlpha(int index) const
{
- switch (blendOperationStateAlpha)
+ ASSERT((index >= 0) && (index < RENDERTARGETS));
+
+ switch (blendState[index].blendOperationAlpha)
{
case VK_BLEND_OP_ADD:
case VK_BLEND_OP_SUBTRACT:
case VK_BLEND_OP_REVERSE_SUBTRACT:
- return destBlendFactorStateAlpha;
+ return blendState[index].destBlendFactorAlpha;
case VK_BLEND_OP_MIN:
return VK_BLEND_FACTOR_ONE;
case VK_BLEND_OP_MAX:
@@ -374,17 +414,19 @@
ASSERT(false);
}
- return destBlendFactorStateAlpha;
+ return blendState[index].destBlendFactorAlpha;
}
- VkBlendOp Context::blendOperationAlpha() const
+ VkBlendOp Context::blendOperationAlpha(int index) const
{
- switch (blendOperationStateAlpha)
+ ASSERT((index >= 0) && (index < RENDERTARGETS));
+
+ switch (blendState[index].blendOperationAlpha)
{
case VK_BLEND_OP_ADD:
- if (sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
+ if (sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
{
- if (destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
+ if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
{
return VK_BLEND_OP_ZERO_EXT;
}
@@ -393,9 +435,9 @@
return VK_BLEND_OP_DST_EXT;
}
}
- else if (sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ONE)
+ else if (sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ONE)
{
- if (destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
+ if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
{
return VK_BLEND_OP_SRC_EXT;
}
@@ -406,7 +448,7 @@
}
else
{
- if (destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
+ if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
{
return VK_BLEND_OP_SRC_EXT;
}
@@ -416,13 +458,13 @@
}
}
case VK_BLEND_OP_SUBTRACT:
- if (sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
+ if (sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
{
return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero
}
- else if (sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ONE)
+ else if (sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ONE)
{
- if (destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
+ if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
{
return VK_BLEND_OP_SRC_EXT;
}
@@ -433,7 +475,7 @@
}
else
{
- if (destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
+ if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
{
return VK_BLEND_OP_SRC_EXT;
}
@@ -443,9 +485,9 @@
}
}
case VK_BLEND_OP_REVERSE_SUBTRACT:
- if (sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
+ if (sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
{
- if (destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO)
+ if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO)
{
return VK_BLEND_OP_ZERO_EXT;
}
@@ -454,9 +496,9 @@
return VK_BLEND_OP_DST_EXT;
}
}
- else if (sourceBlendFactorAlpha() == VK_BLEND_FACTOR_ONE)
+ else if (sourceBlendFactorAlpha(index) == VK_BLEND_FACTOR_ONE)
{
- if (destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
+ if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
{
return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero
}
@@ -467,7 +509,7 @@
}
else
{
- if (destBlendFactorAlpha() == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
+ if (destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ZERO && allTargetsColorClamp())
{
return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero
}
@@ -484,11 +526,13 @@
ASSERT(false);
}
- return blendOperationStateAlpha;
+ return blendState[index].blendOperationAlpha;
}
VkFormat Context::renderTargetInternalFormat(int index) const
{
+ ASSERT((index >= 0) && (index < RENDERTARGETS));
+
if(renderTarget[index])
{
return renderTarget[index]->getFormat();
@@ -514,13 +558,15 @@
int Context::colorWriteActive(int index) const
{
+ ASSERT((index >= 0) && (index < RENDERTARGETS));
+
if(!renderTarget[index] || renderTarget[index]->getFormat() == VK_FORMAT_UNDEFINED)
{
return 0;
}
- if(blendOperation() == VK_BLEND_OP_DST_EXT && destBlendFactor() == VK_BLEND_FACTOR_ONE &&
- (blendOperationAlpha() == VK_BLEND_OP_DST_EXT && destBlendFactorAlpha() == VK_BLEND_FACTOR_ONE))
+ if(blendOperation(index) == VK_BLEND_OP_DST_EXT && destBlendFactor(index) == VK_BLEND_FACTOR_ONE &&
+ (blendOperationAlpha(index) == VK_BLEND_OP_DST_EXT && destBlendFactorAlpha(index) == VK_BLEND_FACTOR_ONE))
{
return 0;
}
diff --git a/src/Device/Context.hpp b/src/Device/Context.hpp
index fa79416..502eacf 100644
--- a/src/Device/Context.hpp
+++ b/src/Device/Context.hpp
@@ -36,6 +36,19 @@
unsigned char data[vk::MAX_PUSH_CONSTANT_SIZE];
};
+ struct BlendState
+ {
+ void init();
+
+ bool alphaBlendEnable;
+ VkBlendFactor sourceBlendFactor;
+ VkBlendFactor destBlendFactor;
+ VkBlendOp blendOperation;
+ VkBlendFactor sourceBlendFactorAlpha;
+ VkBlendFactor destBlendFactorAlpha;
+ VkBlendOp blendOperationAlpha;
+ };
+
class Context
{
public:
@@ -52,14 +65,9 @@
bool stencilActive() const;
bool allTargetsColorClamp() const;
- bool alphaBlendActive() const;
- VkBlendFactor sourceBlendFactor() const;
- VkBlendFactor destBlendFactor() const;
- VkBlendOp blendOperation() const;
- VkBlendFactor sourceBlendFactorAlpha() const;
- VkBlendFactor destBlendFactorAlpha() const;
- VkBlendOp blendOperationAlpha() const;
+ void setBlendState(int index, BlendState state);
+ BlendState getBlendState(int index) const;
VkPrimitiveTopology topology;
@@ -75,9 +83,7 @@
float slopeDepthBias;
VkFormat renderTargetInternalFormat(int index) const;
- bool colorWriteActive() const;
int colorWriteActive(int index) const;
- bool colorUsed() const;
vk::DescriptorSet::Bindings descriptorSets = {};
vk::DescriptorSet::DynamicOffsets descriptorDynamicOffsets = {};
@@ -102,15 +108,6 @@
VkCompareOp depthCompareMode;
bool depthWriteEnable;
- bool alphaBlendEnable;
- VkBlendFactor sourceBlendFactorState;
- VkBlendFactor destBlendFactorState;
- VkBlendOp blendOperationState;
-
- VkBlendFactor sourceBlendFactorStateAlpha;
- VkBlendFactor destBlendFactorStateAlpha;
- VkBlendOp blendOperationStateAlpha;
-
float lineWidth;
int colorWriteMask[RENDERTARGETS]; // RGBA
@@ -118,6 +115,21 @@
unsigned int multiSampleMask;
int sampleCount;
bool alphaToCoverage;
+
+ private:
+ bool colorWriteActive() const;
+ bool colorUsed() const;
+
+ bool alphaBlendActive(int index) const;
+ VkBlendFactor sourceBlendFactor(int index) const;
+ VkBlendFactor destBlendFactor(int index) const;
+ VkBlendOp blendOperation(int index) const;
+
+ VkBlendFactor sourceBlendFactorAlpha(int index) const;
+ VkBlendFactor destBlendFactorAlpha(int index) const;
+ VkBlendOp blendOperationAlpha(int index) const;
+
+ BlendState blendState[RENDERTARGETS];
};
}
diff --git a/src/Device/PixelProcessor.cpp b/src/Device/PixelProcessor.cpp
index d6593b2..6976cce 100644
--- a/src/Device/PixelProcessor.cpp
+++ b/src/Device/PixelProcessor.cpp
@@ -195,21 +195,11 @@
state.occlusionEnabled = context->occlusionEnabled;
state.depthClamp = (context->depthBias != 0.0f) || (context->slopeDepthBias != 0.0f);
- if(context->alphaBlendActive())
- {
- state.alphaBlendActive = true;
- state.sourceBlendFactor = context->sourceBlendFactor();
- state.destBlendFactor = context->destBlendFactor();
- state.blendOperation = context->blendOperation();
- state.sourceBlendFactorAlpha = context->sourceBlendFactorAlpha();
- state.destBlendFactorAlpha = context->destBlendFactorAlpha();
- state.blendOperationAlpha = context->blendOperationAlpha();
- }
-
for(int i = 0; i < RENDERTARGETS; i++)
{
state.colorWriteMask |= context->colorWriteActive(i) << (4 * i);
state.targetFormat[i] = context->renderTargetInternalFormat(i);
+ state.blendState[i] = context->getBlendState(i);
}
state.multiSample = static_cast<unsigned int>(context->sampleCount);
diff --git a/src/Device/PixelProcessor.hpp b/src/Device/PixelProcessor.hpp
index c076a54..2b7ddca 100644
--- a/src/Device/PixelProcessor.hpp
+++ b/src/Device/PixelProcessor.hpp
@@ -52,13 +52,7 @@
bool perspective;
bool depthClamp;
- bool alphaBlendActive;
- VkBlendFactor sourceBlendFactor;
- VkBlendFactor destBlendFactor;
- VkBlendOp blendOperation;
- VkBlendFactor sourceBlendFactorAlpha;
- VkBlendFactor destBlendFactorAlpha;
- VkBlendOp blendOperationAlpha;
+ BlendState blendState[RENDERTARGETS];
unsigned int colorWriteMask;
VkFormat targetFormat[RENDERTARGETS];
diff --git a/src/Pipeline/PixelRoutine.cpp b/src/Pipeline/PixelRoutine.cpp
index a231b62..188ac73 100644
--- a/src/Pipeline/PixelRoutine.cpp
+++ b/src/Pipeline/PixelRoutine.cpp
@@ -1064,7 +1064,7 @@
void PixelRoutine::alphaBlend(int index, Pointer<Byte> &cBuffer, Vector4s ¤t, Int &x)
{
- if(!state.alphaBlendActive)
+ if(!state.blendState[index].alphaBlendEnable)
{
return;
}
@@ -1076,24 +1076,24 @@
Vector4s sourceFactor;
Vector4s destFactor;
- blendFactor(sourceFactor, current, pixel, state.sourceBlendFactor);
- blendFactor(destFactor, current, pixel, state.destBlendFactor);
+ blendFactor(sourceFactor, current, pixel, state.blendState[index].sourceBlendFactor);
+ blendFactor(destFactor, current, pixel, state.blendState[index].destBlendFactor);
- if(state.sourceBlendFactor != VK_BLEND_FACTOR_ONE && state.sourceBlendFactor != VK_BLEND_FACTOR_ZERO)
+ if(state.blendState[index].sourceBlendFactor != VK_BLEND_FACTOR_ONE && state.blendState[index].sourceBlendFactor != VK_BLEND_FACTOR_ZERO)
{
current.x = MulHigh(As<UShort4>(current.x), As<UShort4>(sourceFactor.x));
current.y = MulHigh(As<UShort4>(current.y), As<UShort4>(sourceFactor.y));
current.z = MulHigh(As<UShort4>(current.z), As<UShort4>(sourceFactor.z));
}
- if(state.destBlendFactor != VK_BLEND_FACTOR_ONE && state.destBlendFactor != VK_BLEND_FACTOR_ZERO)
+ if(state.blendState[index].destBlendFactor != VK_BLEND_FACTOR_ONE && state.blendState[index].destBlendFactor != VK_BLEND_FACTOR_ZERO)
{
pixel.x = MulHigh(As<UShort4>(pixel.x), As<UShort4>(destFactor.x));
pixel.y = MulHigh(As<UShort4>(pixel.y), As<UShort4>(destFactor.y));
pixel.z = MulHigh(As<UShort4>(pixel.z), As<UShort4>(destFactor.z));
}
- switch(state.blendOperation)
+ switch(state.blendState[index].blendOperation)
{
case VK_BLEND_OP_ADD:
current.x = AddSat(As<UShort4>(current.x), As<UShort4>(pixel.x));
@@ -1134,23 +1134,23 @@
current.z = Short4(0x0000);
break;
default:
- UNIMPLEMENTED("VkBlendOp: %d", int(state.blendOperation));
+ UNIMPLEMENTED("VkBlendOp: %d", int(state.blendState[index].blendOperation));
}
- blendFactorAlpha(sourceFactor, current, pixel, state.sourceBlendFactorAlpha);
- blendFactorAlpha(destFactor, current, pixel, state.destBlendFactorAlpha);
+ blendFactorAlpha(sourceFactor, current, pixel, state.blendState[index].sourceBlendFactorAlpha);
+ blendFactorAlpha(destFactor, current, pixel, state.blendState[index].destBlendFactorAlpha);
- if(state.sourceBlendFactorAlpha != VK_BLEND_FACTOR_ONE && state.sourceBlendFactorAlpha != VK_BLEND_FACTOR_ZERO)
+ if(state.blendState[index].sourceBlendFactorAlpha != VK_BLEND_FACTOR_ONE && state.blendState[index].sourceBlendFactorAlpha != VK_BLEND_FACTOR_ZERO)
{
current.w = MulHigh(As<UShort4>(current.w), As<UShort4>(sourceFactor.w));
}
- if(state.destBlendFactorAlpha != VK_BLEND_FACTOR_ONE && state.destBlendFactorAlpha != VK_BLEND_FACTOR_ZERO)
+ if(state.blendState[index].destBlendFactorAlpha != VK_BLEND_FACTOR_ONE && state.blendState[index].destBlendFactorAlpha != VK_BLEND_FACTOR_ZERO)
{
pixel.w = MulHigh(As<UShort4>(pixel.w), As<UShort4>(destFactor.w));
}
- switch(state.blendOperationAlpha)
+ switch(state.blendState[index].blendOperationAlpha)
{
case VK_BLEND_OP_ADD:
current.w = AddSat(As<UShort4>(current.w), As<UShort4>(pixel.w));
@@ -1177,7 +1177,7 @@
current.w = Short4(0x0000);
break;
default:
- UNIMPLEMENTED("VkBlendOp: %d", int(state.blendOperationAlpha));
+ UNIMPLEMENTED("VkBlendOp: %d", int(state.blendState[index].blendOperationAlpha));
}
}
@@ -1794,7 +1794,7 @@
void PixelRoutine::alphaBlend(int index, Pointer<Byte> &cBuffer, Vector4f &oC, Int &x)
{
- if(!state.alphaBlendActive)
+ if(!state.blendState[index].alphaBlendEnable)
{
return;
}
@@ -1911,8 +1911,8 @@
Vector4f sourceFactor;
Vector4f destFactor;
- blendFactor(sourceFactor, oC, pixel, state.sourceBlendFactor);
- blendFactor(destFactor, oC, pixel, state.destBlendFactor);
+ blendFactor(sourceFactor, oC, pixel, state.blendState[index].sourceBlendFactor);
+ blendFactor(destFactor, oC, pixel, state.blendState[index].destBlendFactor);
oC.x *= sourceFactor.x;
oC.y *= sourceFactor.y;
@@ -1922,7 +1922,7 @@
pixel.y *= destFactor.y;
pixel.z *= destFactor.z;
- switch(state.blendOperation)
+ switch(state.blendState[index].blendOperation)
{
case VK_BLEND_OP_ADD:
oC.x += pixel.x;
@@ -1963,16 +1963,16 @@
oC.z = Float4(0.0f);
break;
default:
- UNIMPLEMENTED("VkBlendOp: %d", int(state.blendOperation));
+ UNIMPLEMENTED("VkBlendOp: %d", int(state.blendState[index].blendOperation));
}
- blendFactorAlpha(sourceFactor, oC, pixel, state.sourceBlendFactorAlpha);
- blendFactorAlpha(destFactor, oC, pixel, state.destBlendFactorAlpha);
+ blendFactorAlpha(sourceFactor, oC, pixel, state.blendState[index].sourceBlendFactorAlpha);
+ blendFactorAlpha(destFactor, oC, pixel, state.blendState[index].destBlendFactorAlpha);
oC.w *= sourceFactor.w;
pixel.w *= destFactor.w;
- switch(state.blendOperationAlpha)
+ switch(state.blendState[index].blendOperationAlpha)
{
case VK_BLEND_OP_ADD:
oC.w += pixel.w;
@@ -2000,7 +2000,7 @@
oC.w = Float4(0.0f);
break;
default:
- UNIMPLEMENTED("VkBlendOp: %d", int(state.blendOperationAlpha));
+ UNIMPLEMENTED("VkBlendOp: %d", int(state.blendState[index].blendOperationAlpha));
}
}
diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp
index 5e5b74c..c86221c 100644
--- a/src/Vulkan/VkPhysicalDevice.cpp
+++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -34,7 +34,7 @@
VK_TRUE, // robustBufferAccess
VK_FALSE, // fullDrawIndexUint32
VK_FALSE, // imageCubeArray
- VK_FALSE, // independentBlend
+ VK_TRUE, // independentBlend
VK_FALSE, // geometryShader
VK_FALSE, // tessellationShader
VK_FALSE, // sampleRateShading
diff --git a/src/Vulkan/VkPipeline.cpp b/src/Vulkan/VkPipeline.cpp
index 0efde4c..89e835d 100644
--- a/src/Vulkan/VkPipeline.cpp
+++ b/src/Vulkan/VkPipeline.cpp
@@ -468,18 +468,10 @@
{
const VkPipelineColorBlendAttachmentState& attachment = colorBlendState->pAttachments[i];
context.colorWriteMask[i] = attachment.colorWriteMask;
- }
- if(colorBlendState->attachmentCount > 0)
- {
- const VkPipelineColorBlendAttachmentState& attachment = colorBlendState->pAttachments[0];
- context.alphaBlendEnable = (attachment.blendEnable == VK_TRUE);
- context.blendOperationStateAlpha = attachment.alphaBlendOp;
- context.blendOperationState = attachment.colorBlendOp;
- context.destBlendFactorStateAlpha = attachment.dstAlphaBlendFactor;
- context.destBlendFactorState = attachment.dstColorBlendFactor;
- context.sourceBlendFactorStateAlpha = attachment.srcAlphaBlendFactor;
- context.sourceBlendFactorState = attachment.srcColorBlendFactor;
+ context.setBlendState(i, { (attachment.blendEnable == VK_TRUE),
+ attachment.srcColorBlendFactor, attachment.dstColorBlendFactor, attachment.colorBlendOp,
+ attachment.srcAlphaBlendFactor, attachment.dstAlphaBlendFactor, attachment.alphaBlendOp });
}
}