mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
parent
1fa8887c47
commit
94ce76da6b
@ -4174,6 +4174,63 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxbcCompiler::emitControlFlowLabel(const DxbcShaderInstruction& ins) {
|
||||||
|
uint32_t functionNr = ins.dst[0].idx[0].offset;
|
||||||
|
uint32_t functionId = getFunctionId(functionNr);
|
||||||
|
|
||||||
|
this->emitFunctionBegin(
|
||||||
|
functionId,
|
||||||
|
m_module.defVoidType(),
|
||||||
|
m_module.defFunctionType(
|
||||||
|
m_module.defVoidType(), 0, nullptr));
|
||||||
|
|
||||||
|
m_module.opLabel(m_module.allocateId());
|
||||||
|
m_module.setDebugName(functionId, str::format("label", functionNr).c_str());
|
||||||
|
|
||||||
|
m_insideFunction = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxbcCompiler::emitControlFlowCall(const DxbcShaderInstruction& ins) {
|
||||||
|
uint32_t functionNr = ins.src[0].idx[0].offset;
|
||||||
|
uint32_t functionId = getFunctionId(functionNr);
|
||||||
|
|
||||||
|
m_module.opFunctionCall(
|
||||||
|
m_module.defVoidType(),
|
||||||
|
functionId, 0, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxbcCompiler::emitControlFlowCallc(const DxbcShaderInstruction& ins) {
|
||||||
|
uint32_t functionNr = ins.src[1].idx[0].offset;
|
||||||
|
uint32_t functionId = getFunctionId(functionNr);
|
||||||
|
|
||||||
|
// Perform zero test on the first component of the condition
|
||||||
|
const DxbcRegisterValue condition = emitRegisterLoad(
|
||||||
|
ins.src[0], DxbcRegMask(true, false, false, false));
|
||||||
|
|
||||||
|
const DxbcRegisterValue zeroTest = emitRegisterZeroTest(
|
||||||
|
condition, ins.controls.zeroTest());
|
||||||
|
|
||||||
|
// We basically have to wrap this into an 'if' block
|
||||||
|
const uint32_t callLabel = m_module.allocateId();
|
||||||
|
const uint32_t continueLabel = m_module.allocateId();
|
||||||
|
|
||||||
|
m_module.opSelectionMerge(continueLabel,
|
||||||
|
spv::SelectionControlMaskNone);
|
||||||
|
|
||||||
|
m_module.opBranchConditional(
|
||||||
|
zeroTest.id, callLabel, continueLabel);
|
||||||
|
|
||||||
|
m_module.opLabel(callLabel);
|
||||||
|
m_module.opFunctionCall(
|
||||||
|
m_module.defVoidType(),
|
||||||
|
functionId, 0, nullptr);
|
||||||
|
|
||||||
|
m_module.opLabel(continueLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxbcCompiler::emitControlFlow(const DxbcShaderInstruction& ins) {
|
void DxbcCompiler::emitControlFlow(const DxbcShaderInstruction& ins) {
|
||||||
switch (ins.op) {
|
switch (ins.op) {
|
||||||
case DxbcOpcode::If:
|
case DxbcOpcode::If:
|
||||||
@ -4210,7 +4267,7 @@ namespace dxvk {
|
|||||||
case DxbcOpcode::Breakc:
|
case DxbcOpcode::Breakc:
|
||||||
case DxbcOpcode::Continuec:
|
case DxbcOpcode::Continuec:
|
||||||
return this->emitControlFlowBreakc(ins);
|
return this->emitControlFlowBreakc(ins);
|
||||||
|
|
||||||
case DxbcOpcode::Ret:
|
case DxbcOpcode::Ret:
|
||||||
return this->emitControlFlowRet(ins);
|
return this->emitControlFlowRet(ins);
|
||||||
|
|
||||||
@ -4220,6 +4277,15 @@ namespace dxvk {
|
|||||||
case DxbcOpcode::Discard:
|
case DxbcOpcode::Discard:
|
||||||
return this->emitControlFlowDiscard(ins);
|
return this->emitControlFlowDiscard(ins);
|
||||||
|
|
||||||
|
case DxbcOpcode::Label:
|
||||||
|
return this->emitControlFlowLabel(ins);
|
||||||
|
|
||||||
|
case DxbcOpcode::Call:
|
||||||
|
return this->emitControlFlowCall(ins);
|
||||||
|
|
||||||
|
case DxbcOpcode::Callc:
|
||||||
|
return this->emitControlFlowCallc(ins);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Logger::warn(str::format(
|
Logger::warn(str::format(
|
||||||
"DxbcCompiler: Unhandled instruction: ",
|
"DxbcCompiler: Unhandled instruction: ",
|
||||||
@ -7659,6 +7725,18 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t DxbcCompiler::getFunctionId(
|
||||||
|
uint32_t functionNr) {
|
||||||
|
auto entry = m_subroutines.find(functionNr);
|
||||||
|
if (entry != m_subroutines.end())
|
||||||
|
return entry->second;
|
||||||
|
|
||||||
|
uint32_t functionId = m_module.allocateId();
|
||||||
|
m_subroutines.insert({ functionNr, functionId });
|
||||||
|
return functionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxbcCompilerHsForkJoinPhase* DxbcCompiler::getCurrentHsForkJoinPhase() {
|
DxbcCompilerHsForkJoinPhase* DxbcCompiler::getCurrentHsForkJoinPhase() {
|
||||||
switch (m_hs.currPhaseType) {
|
switch (m_hs.currPhaseType) {
|
||||||
case DxbcCompilerHsPhase::Fork: return &m_hs.forkPhases.at(m_hs.currPhaseId);
|
case DxbcCompilerHsPhase::Fork: return &m_hs.forkPhases.at(m_hs.currPhaseId);
|
||||||
|
@ -472,7 +472,7 @@ namespace dxvk {
|
|||||||
// Function state tracking. Required in order
|
// Function state tracking. Required in order
|
||||||
// to properly end functions in some cases.
|
// to properly end functions in some cases.
|
||||||
bool m_insideFunction = false;
|
bool m_insideFunction = false;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// Array of input values. Since v# registers are indexable
|
// Array of input values. Since v# registers are indexable
|
||||||
// in DXBC, we need to copy them into an array first.
|
// in DXBC, we need to copy them into an array first.
|
||||||
@ -506,6 +506,10 @@ namespace dxvk {
|
|||||||
uint32_t m_uavCtrStructType = 0;
|
uint32_t m_uavCtrStructType = 0;
|
||||||
uint32_t m_uavCtrPointerType = 0;
|
uint32_t m_uavCtrPointerType = 0;
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
// Function IDs for subroutines
|
||||||
|
std::unordered_map<uint32_t, uint32_t> m_subroutines;
|
||||||
|
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
// Entry point description - we'll need to declare
|
// Entry point description - we'll need to declare
|
||||||
// the function ID and all input/output variables.
|
// the function ID and all input/output variables.
|
||||||
@ -784,6 +788,15 @@ namespace dxvk {
|
|||||||
void emitControlFlowDiscard(
|
void emitControlFlowDiscard(
|
||||||
const DxbcShaderInstruction& ins);
|
const DxbcShaderInstruction& ins);
|
||||||
|
|
||||||
|
void emitControlFlowLabel(
|
||||||
|
const DxbcShaderInstruction& ins);
|
||||||
|
|
||||||
|
void emitControlFlowCall(
|
||||||
|
const DxbcShaderInstruction& ins);
|
||||||
|
|
||||||
|
void emitControlFlowCallc(
|
||||||
|
const DxbcShaderInstruction& ins);
|
||||||
|
|
||||||
void emitControlFlow(
|
void emitControlFlow(
|
||||||
const DxbcShaderInstruction& ins);
|
const DxbcShaderInstruction& ins);
|
||||||
|
|
||||||
@ -1218,6 +1231,9 @@ namespace dxvk {
|
|||||||
const DxbcRegisterInfo& type);
|
const DxbcRegisterInfo& type);
|
||||||
|
|
||||||
uint32_t getPerVertexBlockId();
|
uint32_t getPerVertexBlockId();
|
||||||
|
|
||||||
|
uint32_t getFunctionId(
|
||||||
|
uint32_t functionNr);
|
||||||
|
|
||||||
DxbcCompilerHsForkJoinPhase* getCurrentHsForkJoinPhase();
|
DxbcCompilerHsForkJoinPhase* getCurrentHsForkJoinPhase();
|
||||||
|
|
||||||
|
@ -209,7 +209,9 @@ namespace dxvk {
|
|||||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 },
|
{ DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 },
|
||||||
} },
|
} },
|
||||||
/* Label */
|
/* Label */
|
||||||
{ },
|
{ 1, DxbcInstClass::ControlFlow, {
|
||||||
|
{ DxbcOperandKind::DstReg, DxbcScalarType::Uint32 },
|
||||||
|
} },
|
||||||
/* Ld */
|
/* Ld */
|
||||||
{ 3, DxbcInstClass::TextureFetch, {
|
{ 3, DxbcInstClass::TextureFetch, {
|
||||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user