mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
[d3d9,dxso] Factor out common alpha test code
This commit is contained in:
parent
3806bd44d8
commit
2c713a34c9
@ -189,6 +189,86 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DoFixedFunctionAlphaTest(SpirvModule& spvModule, const D3D9AlphaTestContext& ctx) {
|
||||||
|
// Labels for the alpha test
|
||||||
|
std::array<SpirvSwitchCaseLabel, 8> atestCaseLabels = {{
|
||||||
|
{ uint32_t(VK_COMPARE_OP_NEVER), spvModule.allocateId() },
|
||||||
|
{ uint32_t(VK_COMPARE_OP_LESS), spvModule.allocateId() },
|
||||||
|
{ uint32_t(VK_COMPARE_OP_EQUAL), spvModule.allocateId() },
|
||||||
|
{ uint32_t(VK_COMPARE_OP_LESS_OR_EQUAL), spvModule.allocateId() },
|
||||||
|
{ uint32_t(VK_COMPARE_OP_GREATER), spvModule.allocateId() },
|
||||||
|
{ uint32_t(VK_COMPARE_OP_NOT_EQUAL), spvModule.allocateId() },
|
||||||
|
{ uint32_t(VK_COMPARE_OP_GREATER_OR_EQUAL), spvModule.allocateId() },
|
||||||
|
{ uint32_t(VK_COMPARE_OP_ALWAYS), spvModule.allocateId() },
|
||||||
|
}};
|
||||||
|
|
||||||
|
uint32_t atestBeginLabel = spvModule.allocateId();
|
||||||
|
uint32_t atestTestLabel = spvModule.allocateId();
|
||||||
|
uint32_t atestDiscardLabel = spvModule.allocateId();
|
||||||
|
uint32_t atestKeepLabel = spvModule.allocateId();
|
||||||
|
uint32_t atestSkipLabel = spvModule.allocateId();
|
||||||
|
|
||||||
|
// if (alpha_func != ALWAYS) { ... }
|
||||||
|
uint32_t boolType = spvModule.defBoolType();
|
||||||
|
uint32_t isNotAlways = spvModule.opINotEqual(boolType, ctx.alphaFuncId, spvModule.constu32(VK_COMPARE_OP_ALWAYS));
|
||||||
|
spvModule.opSelectionMerge(atestSkipLabel, spv::SelectionControlMaskNone);
|
||||||
|
spvModule.opBranchConditional(isNotAlways, atestBeginLabel, atestSkipLabel);
|
||||||
|
spvModule.opLabel(atestBeginLabel);
|
||||||
|
|
||||||
|
// switch (alpha_func) { ... }
|
||||||
|
spvModule.opSelectionMerge(atestTestLabel, spv::SelectionControlMaskNone);
|
||||||
|
spvModule.opSwitch(ctx.alphaFuncId,
|
||||||
|
atestCaseLabels[uint32_t(VK_COMPARE_OP_ALWAYS)].labelId,
|
||||||
|
atestCaseLabels.size(),
|
||||||
|
atestCaseLabels.data());
|
||||||
|
|
||||||
|
std::array<SpirvPhiLabel, 8> atestVariables;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < atestCaseLabels.size(); i++) {
|
||||||
|
spvModule.opLabel(atestCaseLabels[i].labelId);
|
||||||
|
|
||||||
|
atestVariables[i].labelId = atestCaseLabels[i].labelId;
|
||||||
|
atestVariables[i].varId = [&] {
|
||||||
|
switch (VkCompareOp(atestCaseLabels[i].literal)) {
|
||||||
|
case VK_COMPARE_OP_NEVER: return spvModule.constBool(false);
|
||||||
|
case VK_COMPARE_OP_LESS: return spvModule.opFOrdLessThan (boolType, ctx.alphaId, ctx.alphaRefId);
|
||||||
|
case VK_COMPARE_OP_EQUAL: return spvModule.opFOrdEqual (boolType, ctx.alphaId, ctx.alphaRefId);
|
||||||
|
case VK_COMPARE_OP_LESS_OR_EQUAL: return spvModule.opFOrdLessThanEqual (boolType, ctx.alphaId, ctx.alphaRefId);
|
||||||
|
case VK_COMPARE_OP_GREATER: return spvModule.opFOrdGreaterThan (boolType, ctx.alphaId, ctx.alphaRefId);
|
||||||
|
case VK_COMPARE_OP_NOT_EQUAL: return spvModule.opFOrdNotEqual (boolType, ctx.alphaId, ctx.alphaRefId);
|
||||||
|
case VK_COMPARE_OP_GREATER_OR_EQUAL: return spvModule.opFOrdGreaterThanEqual(boolType, ctx.alphaId, ctx.alphaRefId);
|
||||||
|
default:
|
||||||
|
case VK_COMPARE_OP_ALWAYS: return spvModule.constBool(true);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
spvModule.opBranch(atestTestLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// end switch
|
||||||
|
spvModule.opLabel(atestTestLabel);
|
||||||
|
|
||||||
|
uint32_t atestResult = spvModule.opPhi(boolType,
|
||||||
|
atestVariables.size(),
|
||||||
|
atestVariables.data());
|
||||||
|
uint32_t atestDiscard = spvModule.opLogicalNot(boolType, atestResult);
|
||||||
|
|
||||||
|
// if (do_discard) { ... }
|
||||||
|
spvModule.opSelectionMerge(atestKeepLabel, spv::SelectionControlMaskNone);
|
||||||
|
spvModule.opBranchConditional(atestDiscard, atestDiscardLabel, atestKeepLabel);
|
||||||
|
|
||||||
|
spvModule.opLabel(atestDiscardLabel);
|
||||||
|
spvModule.opKill();
|
||||||
|
|
||||||
|
// end if (do_discard)
|
||||||
|
spvModule.opLabel(atestKeepLabel);
|
||||||
|
spvModule.opBranch(atestSkipLabel);
|
||||||
|
|
||||||
|
// end if (alpha_test)
|
||||||
|
spvModule.opLabel(atestSkipLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t SetupRenderStateBlock(SpirvModule& spvModule, uint32_t count) {
|
uint32_t SetupRenderStateBlock(SpirvModule& spvModule, uint32_t count) {
|
||||||
uint32_t floatType = spvModule.defFloatType(32);
|
uint32_t floatType = spvModule.defFloatType(32);
|
||||||
uint32_t vec3Type = spvModule.defVectorType(floatType, 3);
|
uint32_t vec3Type = spvModule.defVectorType(floatType, 3);
|
||||||
@ -2220,101 +2300,22 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void D3D9FFShaderCompiler::alphaTestPS() {
|
void D3D9FFShaderCompiler::alphaTestPS() {
|
||||||
// Alpha testing
|
|
||||||
uint32_t boolType = m_module.defBoolType();
|
|
||||||
uint32_t floatPtr = m_module.defPointerType(m_floatType, spv::StorageClassPushConstant);
|
uint32_t floatPtr = m_module.defPointerType(m_floatType, spv::StorageClassPushConstant);
|
||||||
|
|
||||||
// Declare spec constants for render states
|
|
||||||
uint32_t alphaFuncId = m_spec.get(m_module, m_specUbo, SpecAlphaCompareOp);
|
|
||||||
|
|
||||||
// Implement alpha test
|
|
||||||
auto oC0 = m_ps.out.COLOR;
|
auto oC0 = m_ps.out.COLOR;
|
||||||
// Labels for the alpha test
|
|
||||||
std::array<SpirvSwitchCaseLabel, 8> atestCaseLabels = { {
|
|
||||||
{ uint32_t(VK_COMPARE_OP_NEVER), m_module.allocateId() },
|
|
||||||
{ uint32_t(VK_COMPARE_OP_LESS), m_module.allocateId() },
|
|
||||||
{ uint32_t(VK_COMPARE_OP_EQUAL), m_module.allocateId() },
|
|
||||||
{ uint32_t(VK_COMPARE_OP_LESS_OR_EQUAL), m_module.allocateId() },
|
|
||||||
{ uint32_t(VK_COMPARE_OP_GREATER), m_module.allocateId() },
|
|
||||||
{ uint32_t(VK_COMPARE_OP_NOT_EQUAL), m_module.allocateId() },
|
|
||||||
{ uint32_t(VK_COMPARE_OP_GREATER_OR_EQUAL), m_module.allocateId() },
|
|
||||||
{ uint32_t(VK_COMPARE_OP_ALWAYS), m_module.allocateId() },
|
|
||||||
} };
|
|
||||||
|
|
||||||
uint32_t atestBeginLabel = m_module.allocateId();
|
|
||||||
uint32_t atestTestLabel = m_module.allocateId();
|
|
||||||
uint32_t atestDiscardLabel = m_module.allocateId();
|
|
||||||
uint32_t atestKeepLabel = m_module.allocateId();
|
|
||||||
uint32_t atestSkipLabel = m_module.allocateId();
|
|
||||||
|
|
||||||
// if (alpha_test) { ... }
|
|
||||||
uint32_t isNotAlways = m_module.opINotEqual(boolType, alphaFuncId, m_module.constu32(VK_COMPARE_OP_ALWAYS));
|
|
||||||
m_module.opSelectionMerge(atestSkipLabel, spv::SelectionControlMaskNone);
|
|
||||||
m_module.opBranchConditional(isNotAlways, atestBeginLabel, atestSkipLabel);
|
|
||||||
m_module.opLabel(atestBeginLabel);
|
|
||||||
|
|
||||||
// Load alpha component
|
|
||||||
uint32_t alphaComponentId = 3;
|
uint32_t alphaComponentId = 3;
|
||||||
uint32_t alphaId = m_module.opCompositeExtract(m_floatType,
|
uint32_t alphaRefMember = m_module.constu32(uint32_t(D3D9RenderStateItem::AlphaRef));
|
||||||
|
|
||||||
|
D3D9AlphaTestContext alphaTestContext;
|
||||||
|
alphaTestContext.alphaFuncId = m_spec.get(m_module, m_specUbo, SpecAlphaCompareOp);
|
||||||
|
alphaTestContext.alphaRefId = m_module.opLoad(m_floatType,
|
||||||
|
m_module.opAccessChain(floatPtr, m_rsBlock, 1, &alphaRefMember));
|
||||||
|
alphaTestContext.alphaId = m_module.opCompositeExtract(m_floatType,
|
||||||
m_module.opLoad(m_vec4Type, oC0),
|
m_module.opLoad(m_vec4Type, oC0),
|
||||||
1, &alphaComponentId);
|
1, &alphaComponentId);
|
||||||
|
|
||||||
// Load alpha reference
|
DoFixedFunctionAlphaTest(m_module, alphaTestContext);
|
||||||
uint32_t alphaRefMember = m_module.constu32(uint32_t(D3D9RenderStateItem::AlphaRef));
|
|
||||||
uint32_t alphaRefId = m_module.opLoad(m_floatType,
|
|
||||||
m_module.opAccessChain(floatPtr, m_rsBlock, 1, &alphaRefMember));
|
|
||||||
|
|
||||||
// switch (alpha_func) { ... }
|
|
||||||
m_module.opSelectionMerge(atestTestLabel, spv::SelectionControlMaskNone);
|
|
||||||
m_module.opSwitch(alphaFuncId,
|
|
||||||
atestCaseLabels[uint32_t(VK_COMPARE_OP_ALWAYS)].labelId,
|
|
||||||
atestCaseLabels.size(),
|
|
||||||
atestCaseLabels.data());
|
|
||||||
|
|
||||||
std::array<SpirvPhiLabel, 8> atestVariables;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < atestCaseLabels.size(); i++) {
|
|
||||||
m_module.opLabel(atestCaseLabels[i].labelId);
|
|
||||||
|
|
||||||
atestVariables[i].labelId = atestCaseLabels[i].labelId;
|
|
||||||
atestVariables[i].varId = [&] {
|
|
||||||
switch (VkCompareOp(atestCaseLabels[i].literal)) {
|
|
||||||
case VK_COMPARE_OP_NEVER: return m_module.constBool(false);
|
|
||||||
case VK_COMPARE_OP_LESS: return m_module.opFOrdLessThan(boolType, alphaId, alphaRefId);
|
|
||||||
case VK_COMPARE_OP_EQUAL: return m_module.opFOrdEqual(boolType, alphaId, alphaRefId);
|
|
||||||
case VK_COMPARE_OP_LESS_OR_EQUAL: return m_module.opFOrdLessThanEqual(boolType, alphaId, alphaRefId);
|
|
||||||
case VK_COMPARE_OP_GREATER: return m_module.opFOrdGreaterThan(boolType, alphaId, alphaRefId);
|
|
||||||
case VK_COMPARE_OP_NOT_EQUAL: return m_module.opFOrdNotEqual(boolType, alphaId, alphaRefId);
|
|
||||||
case VK_COMPARE_OP_GREATER_OR_EQUAL: return m_module.opFOrdGreaterThanEqual(boolType, alphaId, alphaRefId);
|
|
||||||
default:
|
|
||||||
case VK_COMPARE_OP_ALWAYS: return m_module.constBool(true);
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
|
|
||||||
m_module.opBranch(atestTestLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// end switch
|
|
||||||
m_module.opLabel(atestTestLabel);
|
|
||||||
|
|
||||||
uint32_t atestResult = m_module.opPhi(boolType,
|
|
||||||
atestVariables.size(),
|
|
||||||
atestVariables.data());
|
|
||||||
uint32_t atestDiscard = m_module.opLogicalNot(boolType, atestResult);
|
|
||||||
|
|
||||||
// if (do_discard) { ... }
|
|
||||||
m_module.opSelectionMerge(atestKeepLabel, spv::SelectionControlMaskNone);
|
|
||||||
m_module.opBranchConditional(atestDiscard, atestDiscardLabel, atestKeepLabel);
|
|
||||||
|
|
||||||
m_module.opLabel(atestDiscardLabel);
|
|
||||||
m_module.opKill();
|
|
||||||
|
|
||||||
// end if (do_discard)
|
|
||||||
m_module.opLabel(atestKeepLabel);
|
|
||||||
m_module.opBranch(atestSkipLabel);
|
|
||||||
|
|
||||||
// end if (alpha_test)
|
|
||||||
m_module.opLabel(atestSkipLabel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,6 +38,12 @@ namespace dxvk {
|
|||||||
uint32_t SpecUBO;
|
uint32_t SpecUBO;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct D3D9AlphaTestContext {
|
||||||
|
uint32_t alphaId;
|
||||||
|
uint32_t alphaFuncId;
|
||||||
|
uint32_t alphaRefId;
|
||||||
|
};
|
||||||
|
|
||||||
struct D3D9FixedFunctionOptions {
|
struct D3D9FixedFunctionOptions {
|
||||||
D3D9FixedFunctionOptions(const D3D9Options* options);
|
D3D9FixedFunctionOptions(const D3D9Options* options);
|
||||||
|
|
||||||
@ -48,6 +54,8 @@ namespace dxvk {
|
|||||||
// Returns new oColor if PS
|
// Returns new oColor if PS
|
||||||
uint32_t DoFixedFunctionFog(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, const D3D9FogContext& fogCtx);
|
uint32_t DoFixedFunctionFog(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, const D3D9FogContext& fogCtx);
|
||||||
|
|
||||||
|
void DoFixedFunctionAlphaTest(SpirvModule& spvModule, const D3D9AlphaTestContext& ctx);
|
||||||
|
|
||||||
// Returns a render state block
|
// Returns a render state block
|
||||||
uint32_t SetupRenderStateBlock(SpirvModule& spvModule, uint32_t count);
|
uint32_t SetupRenderStateBlock(SpirvModule& spvModule, uint32_t count);
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ namespace dxvk {
|
|||||||
float fogEnd = 1.0f;
|
float fogEnd = 1.0f;
|
||||||
float fogDensity = 1.0f;
|
float fogDensity = 1.0f;
|
||||||
|
|
||||||
float alphaRef = 0.0f;
|
uint32_t alphaRef = 0u;
|
||||||
|
|
||||||
float pointSize = 1.0f;
|
float pointSize = 1.0f;
|
||||||
float pointSizeMin = 1.0f;
|
float pointSizeMin = 1.0f;
|
||||||
|
@ -3698,8 +3698,6 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
|||||||
uint32_t floatType = m_module.defFloatType(32);
|
uint32_t floatType = m_module.defFloatType(32);
|
||||||
uint32_t floatPtr = m_module.defPointerType(floatType, spv::StorageClassPushConstant);
|
uint32_t floatPtr = m_module.defPointerType(floatType, spv::StorageClassPushConstant);
|
||||||
|
|
||||||
uint32_t alphaFuncId = m_spec.get(m_module, m_specUbo, SpecAlphaCompareOp);
|
|
||||||
|
|
||||||
// Implement alpha test and fog
|
// Implement alpha test and fog
|
||||||
DxsoRegister color0;
|
DxsoRegister color0;
|
||||||
color0.id = DxsoRegisterId{ DxsoRegisterType::ColorOut, 0 };
|
color0.id = DxsoRegisterId{ DxsoRegisterType::ColorOut, 0 };
|
||||||
@ -3709,107 +3707,18 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
|||||||
if (m_programInfo.majorVersion() < 3)
|
if (m_programInfo.majorVersion() < 3)
|
||||||
emitFog();
|
emitFog();
|
||||||
|
|
||||||
// Labels for the alpha test
|
uint32_t alphaRefMember = m_module.constu32(uint32_t(D3D9RenderStateItem::AlphaRef));
|
||||||
std::array<SpirvSwitchCaseLabel, 8> atestCaseLabels = {{
|
|
||||||
{ uint32_t(VK_COMPARE_OP_NEVER), m_module.allocateId() },
|
|
||||||
{ uint32_t(VK_COMPARE_OP_LESS), m_module.allocateId() },
|
|
||||||
{ uint32_t(VK_COMPARE_OP_EQUAL), m_module.allocateId() },
|
|
||||||
{ uint32_t(VK_COMPARE_OP_LESS_OR_EQUAL), m_module.allocateId() },
|
|
||||||
{ uint32_t(VK_COMPARE_OP_GREATER), m_module.allocateId() },
|
|
||||||
{ uint32_t(VK_COMPARE_OP_NOT_EQUAL), m_module.allocateId() },
|
|
||||||
{ uint32_t(VK_COMPARE_OP_GREATER_OR_EQUAL), m_module.allocateId() },
|
|
||||||
{ uint32_t(VK_COMPARE_OP_ALWAYS), m_module.allocateId() },
|
|
||||||
}};
|
|
||||||
|
|
||||||
uint32_t atestBeginLabel = m_module.allocateId();
|
|
||||||
uint32_t atestTestLabel = m_module.allocateId();
|
|
||||||
uint32_t atestDiscardLabel = m_module.allocateId();
|
|
||||||
uint32_t atestKeepLabel = m_module.allocateId();
|
|
||||||
uint32_t atestSkipLabel = m_module.allocateId();
|
|
||||||
|
|
||||||
// if (alpha_func != ALWAYS) { ... }
|
|
||||||
uint32_t isNotAlways = m_module.opINotEqual(boolType, alphaFuncId, m_module.constu32(VK_COMPARE_OP_ALWAYS));
|
|
||||||
m_module.opSelectionMerge(atestSkipLabel, spv::SelectionControlMaskNone);
|
|
||||||
m_module.opBranchConditional(isNotAlways, atestBeginLabel, atestSkipLabel);
|
|
||||||
m_module.opLabel(atestBeginLabel);
|
|
||||||
|
|
||||||
// Load alpha component
|
|
||||||
uint32_t alphaComponentId = 3;
|
uint32_t alphaComponentId = 3;
|
||||||
uint32_t alphaId = m_module.opCompositeExtract(floatType,
|
|
||||||
|
D3D9AlphaTestContext alphaTestContext;
|
||||||
|
alphaTestContext.alphaFuncId = m_spec.get(m_module, m_specUbo, SpecAlphaCompareOp);
|
||||||
|
alphaTestContext.alphaRefId = m_module.opLoad(floatType,
|
||||||
|
m_module.opAccessChain(floatPtr, m_rsBlock, 1, &alphaRefMember));
|
||||||
|
alphaTestContext.alphaId = m_module.opCompositeExtract(floatType,
|
||||||
m_module.opLoad(m_module.defVectorType(floatType, 4), oC0.id),
|
m_module.opLoad(m_module.defVectorType(floatType, 4), oC0.id),
|
||||||
1, &alphaComponentId);
|
1, &alphaComponentId);
|
||||||
|
|
||||||
if (m_moduleInfo.options.alphaTestWiggleRoom) {
|
DoFixedFunctionAlphaTest(m_module, alphaTestContext);
|
||||||
// NV has wonky interpolation of all 1's in a VS -> PS going to 0.999999...
|
|
||||||
// This causes garbage-looking graphics on people's clothing in EverQuest 2 as it does alpha == 1.0.
|
|
||||||
|
|
||||||
// My testing shows the alpha test has a precision of 1/256 for all A8 and below formats,
|
|
||||||
// and around 1 / 2048 for A32F formats and 1 / 4096 for A16F formats (It makes no sense to me too)
|
|
||||||
// so anyway, we're just going to round this to a precision of 1 / 4096 and hopefully this should make things happy
|
|
||||||
// everywhere.
|
|
||||||
const uint32_t alphaSizeId = m_module.constf32(4096.0f);
|
|
||||||
|
|
||||||
alphaId = m_module.opFMul(floatType, alphaId, alphaSizeId);
|
|
||||||
alphaId = m_module.opRound(floatType, alphaId);
|
|
||||||
alphaId = m_module.opFDiv(floatType, alphaId, alphaSizeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load alpha reference
|
|
||||||
uint32_t alphaRefMember = m_module.constu32(uint32_t(D3D9RenderStateItem::AlphaRef));
|
|
||||||
uint32_t alphaRefId = m_module.opLoad(floatType,
|
|
||||||
m_module.opAccessChain(floatPtr, m_rsBlock, 1, &alphaRefMember));
|
|
||||||
|
|
||||||
// switch (alpha_func) { ... }
|
|
||||||
m_module.opSelectionMerge(atestTestLabel, spv::SelectionControlMaskNone);
|
|
||||||
m_module.opSwitch(alphaFuncId,
|
|
||||||
atestCaseLabels[uint32_t(VK_COMPARE_OP_ALWAYS)].labelId,
|
|
||||||
atestCaseLabels.size(),
|
|
||||||
atestCaseLabels.data());
|
|
||||||
|
|
||||||
std::array<SpirvPhiLabel, 8> atestVariables;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < atestCaseLabels.size(); i++) {
|
|
||||||
m_module.opLabel(atestCaseLabels[i].labelId);
|
|
||||||
|
|
||||||
atestVariables[i].labelId = atestCaseLabels[i].labelId;
|
|
||||||
atestVariables[i].varId = [&] {
|
|
||||||
switch (VkCompareOp(atestCaseLabels[i].literal)) {
|
|
||||||
case VK_COMPARE_OP_NEVER: return m_module.constBool(false);
|
|
||||||
case VK_COMPARE_OP_LESS: return m_module.opFOrdLessThan (boolType, alphaId, alphaRefId);
|
|
||||||
case VK_COMPARE_OP_EQUAL: return m_module.opFOrdEqual (boolType, alphaId, alphaRefId);
|
|
||||||
case VK_COMPARE_OP_LESS_OR_EQUAL: return m_module.opFOrdLessThanEqual (boolType, alphaId, alphaRefId);
|
|
||||||
case VK_COMPARE_OP_GREATER: return m_module.opFOrdGreaterThan (boolType, alphaId, alphaRefId);
|
|
||||||
case VK_COMPARE_OP_NOT_EQUAL: return m_module.opFOrdNotEqual (boolType, alphaId, alphaRefId);
|
|
||||||
case VK_COMPARE_OP_GREATER_OR_EQUAL: return m_module.opFOrdGreaterThanEqual(boolType, alphaId, alphaRefId);
|
|
||||||
default:
|
|
||||||
case VK_COMPARE_OP_ALWAYS: return m_module.constBool(true);
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
|
|
||||||
m_module.opBranch(atestTestLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// end switch
|
|
||||||
m_module.opLabel(atestTestLabel);
|
|
||||||
|
|
||||||
uint32_t atestResult = m_module.opPhi(boolType,
|
|
||||||
atestVariables.size(),
|
|
||||||
atestVariables.data());
|
|
||||||
uint32_t atestDiscard = m_module.opLogicalNot(boolType, atestResult);
|
|
||||||
|
|
||||||
// if (do_discard) { ... }
|
|
||||||
m_module.opSelectionMerge(atestKeepLabel, spv::SelectionControlMaskNone);
|
|
||||||
m_module.opBranchConditional(atestDiscard, atestDiscardLabel, atestKeepLabel);
|
|
||||||
|
|
||||||
m_module.opLabel(atestDiscardLabel);
|
|
||||||
m_module.opKill();
|
|
||||||
|
|
||||||
// end if (do_discard)
|
|
||||||
m_module.opLabel(atestKeepLabel);
|
|
||||||
m_module.opBranch(atestSkipLabel);
|
|
||||||
|
|
||||||
// end if (alpha_test)
|
|
||||||
m_module.opLabel(atestSkipLabel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user