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 }); } }