Merge pull request #1914 from TheAggie/feat/agc-force-dst-alpha-one
feat(agc): blend against an opaque destination for CB_COLOR_ATTRIB FORCE_DST_ALPHA_1
This commit is contained in:
commit
eb283f5c8f
|
|
@ -318,6 +318,23 @@ VkBlendFactor blendFactor(std::uint32_t value) {
|
|||
}
|
||||
}
|
||||
|
||||
VkBlendFactor colorFactorWithOpaqueDestination(VkBlendFactor factor) {
|
||||
switch (factor) {
|
||||
case VK_BLEND_FACTOR_DST_ALPHA: return VK_BLEND_FACTOR_ONE;
|
||||
case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: return VK_BLEND_FACTOR_ZERO;
|
||||
case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE: return VK_BLEND_FACTOR_ZERO;
|
||||
default: return factor;
|
||||
}
|
||||
}
|
||||
|
||||
VkBlendFactor alphaFactorWithOpaqueDestination(VkBlendFactor factor) {
|
||||
switch (factor) {
|
||||
case VK_BLEND_FACTOR_DST_ALPHA: case VK_BLEND_FACTOR_DST_COLOR: return VK_BLEND_FACTOR_ONE;
|
||||
case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: case VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR: return VK_BLEND_FACTOR_ZERO;
|
||||
default: return factor;
|
||||
}
|
||||
}
|
||||
|
||||
VkBlendOp blendOp(std::uint32_t value) {
|
||||
switch (value) {
|
||||
case 0: return VK_BLEND_OP_ADD;
|
||||
|
|
@ -684,6 +701,12 @@ State DecodeState(const QueueState& queue) {
|
|||
state.dstColorBlendFactor = state.dstAlphaBlendFactor;
|
||||
state.colorBlendOp = state.alphaBlendOp;
|
||||
}
|
||||
if ((read(cx, 0x31d + slot * 0xfu) & 0x20000u) != 0) {
|
||||
state.srcColorBlendFactor = colorFactorWithOpaqueDestination(state.srcColorBlendFactor);
|
||||
state.dstColorBlendFactor = colorFactorWithOpaqueDestination(state.dstColorBlendFactor);
|
||||
state.srcAlphaBlendFactor = alphaFactorWithOpaqueDestination(state.srcAlphaBlendFactor);
|
||||
state.dstAlphaBlendFactor = alphaFactorWithOpaqueDestination(state.dstAlphaBlendFactor);
|
||||
}
|
||||
for (std::uint32_t i = 0; i < 4; ++i) result.blendConstants[i] = readFloat(cx, 0x105 + i);
|
||||
}
|
||||
result.blends[color.exportIndex] = state;
|
||||
|
|
@ -738,7 +761,7 @@ ColorTarget DecodeColorBuffer(const Registers& cx, std::uint32_t slot) {
|
|||
const auto slice = view & 0x1fffu;
|
||||
Require(slice == ((view >> 13u) & 0x1fffu), "color views of several array slices are unsupported");
|
||||
const auto viewMip = (view >> 26u) & 0xfu;
|
||||
zero(cx, 0x31d + stride, ~0u, "color samples, fragments or destination alpha override");
|
||||
zero(cx, 0x31d + stride, ~0x20000u, "color samples, fragments or destination alpha override");
|
||||
const auto attrib2 = read(cx, 0x3b0 + slot);
|
||||
const auto maxMip = attrib2 >> 28u;
|
||||
Require(viewMip <= maxMip, "color view mip exceeds the surface");
|
||||
|
|
|
|||
|
|
@ -572,6 +572,25 @@ void PixelInputLayoutTests() {
|
|||
Require(!readsBuiltin(read, spv::BuiltInFragCoord) && !readsBuiltin(read, spv::BuiltInBaryCoordKHR), "an ADDR-only centroid pair was loaded");
|
||||
}
|
||||
|
||||
void OpaqueDestinationAlphaTests() {
|
||||
auto queue = makeState();
|
||||
for (std::uint32_t constant = 0x105; constant < 0x109; ++constant) queue.context[constant] = 0;
|
||||
queue.context[0x1e0] = (1u << 30u) | (1u << 29u) | 6u | (7u << 8u) | (8u << 16u) | (10u << 24u);
|
||||
auto blend = AgcDriver::Graphics::DecodeState(queue).blend;
|
||||
Require(blend.srcColorBlendFactor == VK_BLEND_FACTOR_DST_ALPHA && blend.dstColorBlendFactor == VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, "color blend factors changed");
|
||||
Require(blend.srcAlphaBlendFactor == VK_BLEND_FACTOR_DST_COLOR && blend.dstAlphaBlendFactor == VK_BLEND_FACTOR_SRC_ALPHA_SATURATE, "alpha blend factors changed");
|
||||
queue.context[0x31d] = 0x20000u;
|
||||
blend = AgcDriver::Graphics::DecodeState(queue).blend;
|
||||
Require(blend.srcColorBlendFactor == VK_BLEND_FACTOR_ONE && blend.dstColorBlendFactor == VK_BLEND_FACTOR_ZERO, "an opaque destination left a destination-alpha color factor");
|
||||
Require(blend.srcAlphaBlendFactor == VK_BLEND_FACTOR_ONE && blend.dstAlphaBlendFactor == VK_BLEND_FACTOR_SRC_ALPHA_SATURATE, "an opaque destination left a destination alpha factor");
|
||||
queue.context[0x1e0] = (1u << 30u) | 10u | (9u << 8u);
|
||||
blend = AgcDriver::Graphics::DecodeState(queue).blend;
|
||||
Require(blend.srcColorBlendFactor == VK_BLEND_FACTOR_ZERO && blend.dstColorBlendFactor == VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, "alpha saturation with an opaque destination");
|
||||
Require(blend.dstAlphaBlendFactor == VK_BLEND_FACTOR_ZERO, "an opaque destination left a destination-color alpha factor");
|
||||
queue.context[0x31d] = 0x40000u;
|
||||
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "destination alpha override");
|
||||
}
|
||||
|
||||
void DisabledColorTests() {
|
||||
auto queue = makeState();
|
||||
queue.context[0x8e] = 0;
|
||||
|
|
@ -2982,6 +3001,7 @@ int main() {
|
|||
orderedPixelShaderTests();
|
||||
ConservativeRasterizationTests();
|
||||
DisabledColorTests();
|
||||
OpaqueDestinationAlphaTests();
|
||||
CompactedExportTests();
|
||||
ReversedComponentOrderTests();
|
||||
metadataPassTests();
|
||||
|
|
|
|||
Loading…
Reference in New Issue