1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-15 07:29:17 +01:00

[dxbc] Do not emit empty 'else' blocks

This commit is contained in:
Philip Rebohle 2018-05-18 22:26:16 +02:00
parent 3d9f7c70dd
commit a6ace7908f
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 28 additions and 28 deletions

View File

@ -3258,29 +3258,21 @@ namespace dxvk {
const DxbcRegisterValue condition = emitRegisterLoad( const DxbcRegisterValue condition = emitRegisterLoad(
ins.src[0], DxbcRegMask(true, false, false, false)); ins.src[0], DxbcRegMask(true, false, false, false));
const DxbcRegisterValue zeroTest = emitRegisterZeroTest(
condition, ins.controls.zeroTest());
// Declare the 'if' block. We do not know if there // Declare the 'if' block. We do not know if there
// will be an 'else' block or not, so we'll assume // will be an 'else' block or not, so we'll assume
// that there is one and leave it empty otherwise. // that there is one and leave it empty otherwise.
DxbcCfgBlock block; DxbcCfgBlock block;
block.type = DxbcCfgBlockType::If; block.type = DxbcCfgBlockType::If;
block.b_if.ztestId = emitRegisterZeroTest(condition, ins.controls.zeroTest()).id;
block.b_if.labelIf = m_module.allocateId(); block.b_if.labelIf = m_module.allocateId();
block.b_if.labelElse = m_module.allocateId(); block.b_if.labelElse = 0;
block.b_if.labelEnd = m_module.allocateId(); block.b_if.labelEnd = m_module.allocateId();
block.b_if.hadElse = false; block.b_if.headerPtr = m_module.getInsertionPtr();
m_controlFlowBlocks.push_back(block); m_controlFlowBlocks.push_back(block);
m_module.opSelectionMerge( // We'll insert the branch instruction when closing
block.b_if.labelEnd, // the block, since we don't know whether or not an
spv::SelectionControlMaskNone); // else block is needed right now.
m_module.opBranchConditional(
zeroTest.id,
block.b_if.labelIf,
block.b_if.labelElse);
m_module.opLabel(block.b_if.labelIf); m_module.opLabel(block.b_if.labelIf);
} }
@ -3288,13 +3280,13 @@ namespace dxvk {
void DxbcCompiler::emitControlFlowElse(const DxbcShaderInstruction& ins) { void DxbcCompiler::emitControlFlowElse(const DxbcShaderInstruction& ins) {
if (m_controlFlowBlocks.size() == 0 if (m_controlFlowBlocks.size() == 0
|| m_controlFlowBlocks.back().type != DxbcCfgBlockType::If || m_controlFlowBlocks.back().type != DxbcCfgBlockType::If
|| m_controlFlowBlocks.back().b_if.hadElse) || m_controlFlowBlocks.back().b_if.labelElse != 0)
throw DxvkError("DxbcCompiler: 'Else' without 'If' found"); throw DxvkError("DxbcCompiler: 'Else' without 'If' found");
// Set the 'Else' flag so that we do // Set the 'Else' flag so that we do
// not insert a dummy block on 'EndIf' // not insert a dummy block on 'EndIf'
DxbcCfgBlock& block = m_controlFlowBlocks.back(); DxbcCfgBlock& block = m_controlFlowBlocks.back();
block.b_if.hadElse = true; block.b_if.labelElse = m_module.allocateId();
// Close the 'If' block by branching to // Close the 'If' block by branching to
// the merge block we declared earlier // the merge block we declared earlier
@ -3309,21 +3301,28 @@ namespace dxvk {
throw DxvkError("DxbcCompiler: 'EndIf' without 'If' found"); throw DxvkError("DxbcCompiler: 'EndIf' without 'If' found");
// Remove the block from the stack, it's closed // Remove the block from the stack, it's closed
const DxbcCfgBlock block = m_controlFlowBlocks.back(); DxbcCfgBlock block = m_controlFlowBlocks.back();
m_controlFlowBlocks.pop_back(); m_controlFlowBlocks.pop_back();
// Write out the 'if' header
m_module.beginInsertion(block.b_if.headerPtr);
m_module.opSelectionMerge(
block.b_if.labelEnd,
spv::SelectionControlMaskNone);
m_module.opBranchConditional(
block.b_if.ztestId,
block.b_if.labelIf,
block.b_if.labelElse != 0
? block.b_if.labelElse
: block.b_if.labelEnd);
m_module.endInsertion();
// End the active 'if' or 'else' block // End the active 'if' or 'else' block
m_module.opBranch(block.b_if.labelEnd); m_module.opBranch(block.b_if.labelEnd);
m_module.opLabel (block.b_if.labelEnd);
// If there was no 'else' block in this construct, we still
// have to declare it because we used it as a branch target.
if (!block.b_if.hadElse) {
m_module.opLabel (block.b_if.labelElse);
m_module.opBranch(block.b_if.labelEnd);
}
// Declare the merge block
m_module.opLabel(block.b_if.labelEnd);
} }

View File

@ -244,10 +244,11 @@ namespace dxvk {
struct DxbcCfgBlockIf { struct DxbcCfgBlockIf {
uint32_t ztestId;
uint32_t labelIf; uint32_t labelIf;
uint32_t labelElse; uint32_t labelElse;
uint32_t labelEnd; uint32_t labelEnd;
bool hadElse; size_t headerPtr;
}; };