1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00

[dxbc] Implemented workaround for hull shader output synchronization

This commit is contained in:
Philip Rebohle 2018-03-06 18:29:20 +01:00
parent 4fed7521f7
commit 88c4e363e5
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 44 additions and 15 deletions

View File

@ -493,11 +493,25 @@ namespace dxvk {
"vDomain"); "vDomain");
} break; } break;
case DxbcOperandType::OutputControlPointId:
case DxbcOperandType::InputForkInstanceId: case DxbcOperandType::InputForkInstanceId:
case DxbcOperandType::InputJoinInstanceId: { case DxbcOperandType::InputJoinInstanceId: {
// All of these system values map to the hull shader's auto phase = this->getCurrentHsForkJoinPhase();
// invocation ID, which has been declared already.
phase->instanceIdPtr = m_module.newVar(
m_module.defPointerType(
m_module.defIntType(32, 0),
spv::StorageClassFunction),
spv::StorageClassFunction);
m_module.opStore(phase->instanceIdPtr, phase->instanceId);
m_module.setDebugName(phase->instanceIdPtr,
ins.dst[0].type == DxbcOperandType::InputForkInstanceId
? "vForkInstanceId" : "vJoinInstanceId");
} break;
case DxbcOperandType::OutputControlPointId: {
// This system value map to the invocation
// ID, which has been declared already.
} break; } break;
case DxbcOperandType::InputControlPoint: case DxbcOperandType::InputControlPoint:
@ -4117,11 +4131,15 @@ namespace dxvk {
m_ds.builtinTessCoord }; m_ds.builtinTessCoord };
case DxbcOperandType::OutputControlPointId: case DxbcOperandType::OutputControlPointId:
return DxbcRegisterPointer {
{ DxbcScalarType::Uint32, 1 },
m_hs.builtinInvocationId };
case DxbcOperandType::InputForkInstanceId: case DxbcOperandType::InputForkInstanceId:
case DxbcOperandType::InputJoinInstanceId: case DxbcOperandType::InputJoinInstanceId:
return DxbcRegisterPointer { return DxbcRegisterPointer {
{ DxbcScalarType::Uint32, 1 }, { DxbcScalarType::Uint32, 1 },
m_hs.builtinInvocationId }; getCurrentHsForkJoinPhase()->instanceIdPtr };
default: default:
throw DxvkError(str::format( throw DxvkError(str::format(
@ -5310,13 +5328,16 @@ namespace dxvk {
if (m_hs.cpPhase.functionId == 0) if (m_hs.cpPhase.functionId == 0)
m_hs.cpPhase = this->emitNewHullShaderPassthroughPhase(); m_hs.cpPhase = this->emitNewHullShaderPassthroughPhase();
// Control point phase
this->emitMainFunctionBegin(); this->emitMainFunctionBegin();
this->emitInputSetup(m_hs.vertexCountIn); this->emitInputSetup(m_hs.vertexCountIn);
this->emitHsControlPointPhase(m_hs.cpPhase); this->emitHsControlPointPhase(m_hs.cpPhase);
this->emitHsPhaseBarrier();
if (m_hs.forkPhases.size() != 0 // Fork/join phases. We cannot run this in parallel
|| m_hs.joinPhases.size() != 0) // because synchronizing per-patch outputs does not
this->emitHsPhaseBarrier(); // work. We don't need to synchronize after this.
this->emitHsInvocationBlockBegin(1);
for (const auto& phase : m_hs.forkPhases) for (const auto& phase : m_hs.forkPhases)
this->emitHsForkJoinPhase(phase); this->emitHsForkJoinPhase(phase);
@ -5324,8 +5345,7 @@ namespace dxvk {
for (const auto& phase : m_hs.joinPhases) for (const auto& phase : m_hs.joinPhases)
this->emitHsForkJoinPhase(phase); this->emitHsForkJoinPhase(phase);
this->emitHsPhaseBarrier(); // Output setup phase
this->emitHsInvocationBlockBegin(1);
this->emitOutputSetup(); this->emitOutputSetup();
this->emitHsInvocationBlockEnd(); this->emitHsInvocationBlockEnd();
this->emitMainFunctionEnd(); this->emitMainFunctionEnd();
@ -5385,11 +5405,13 @@ namespace dxvk {
void DxbcCompiler::emitHsForkJoinPhase( void DxbcCompiler::emitHsForkJoinPhase(
const DxbcCompilerHsForkJoinPhase& phase) { const DxbcCompilerHsForkJoinPhase& phase) {
this->emitHsInvocationBlockBegin(phase.instanceCount); for (uint32_t i = 0; i < phase.instanceCount; i++) {
m_module.opFunctionCall( const uint32_t instanceId = m_module.constu32(i);
m_module.defVoidType(),
phase.functionId, 0, nullptr); m_module.opFunctionCall(
this->emitHsInvocationBlockEnd(); m_module.defVoidType(),
phase.functionId, 1, &instanceId);
}
} }
@ -5515,17 +5537,21 @@ namespace dxvk {
DxbcCompilerHsForkJoinPhase DxbcCompiler::emitNewHullShaderForkJoinPhase() { DxbcCompilerHsForkJoinPhase DxbcCompiler::emitNewHullShaderForkJoinPhase() {
uint32_t argTypeId = m_module.defIntType(32, 0);
uint32_t funTypeId = m_module.defFunctionType( uint32_t funTypeId = m_module.defFunctionType(
m_module.defVoidType(), 0, nullptr); m_module.defVoidType(), 1, &argTypeId);
uint32_t funId = m_module.allocateId(); uint32_t funId = m_module.allocateId();
m_module.functionBegin(m_module.defVoidType(), m_module.functionBegin(m_module.defVoidType(),
funId, funTypeId, spv::FunctionControlMaskNone); funId, funTypeId, spv::FunctionControlMaskNone);
uint32_t argId = m_module.functionParameter(argTypeId);
m_module.opLabel(m_module.allocateId()); m_module.opLabel(m_module.allocateId());
DxbcCompilerHsForkJoinPhase result; DxbcCompilerHsForkJoinPhase result;
result.functionId = funId; result.functionId = funId;
result.instanceId = argId;
return result; return result;
} }

View File

@ -161,6 +161,9 @@ namespace dxvk {
struct DxbcCompilerHsForkJoinPhase { struct DxbcCompilerHsForkJoinPhase {
uint32_t functionId = 0; uint32_t functionId = 0;
uint32_t instanceCount = 1; uint32_t instanceCount = 1;
uint32_t instanceId = 0;
uint32_t instanceIdPtr = 0;
}; };