From d185977918086762c0eb294b8e4c4df2a50b88ea Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 1 Mar 2018 09:26:17 +0100 Subject: [PATCH] [dxbc] Implemented Hull shader function declarations --- src/dxbc/dxbc_compiler.cpp | 80 ++++++++++++++++++++++++++++++++++++++ src/dxbc/dxbc_compiler.h | 5 +++ src/dxbc/dxbc_defs.cpp | 8 ++-- src/dxbc/dxbc_defs.h | 1 + src/spirv/spirv_module.cpp | 3 +- 5 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 89752602..1a07e494 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -85,6 +85,9 @@ namespace dxvk { case DxbcInstClass::GeometryEmit: return this->emitGeometryEmit(ins); + case DxbcInstClass::HullShaderPhase: + return this->emitHullShaderPhase(ins); + case DxbcInstClass::Interpolate: return this->emitInterpolate(ins); @@ -477,6 +480,12 @@ namespace dxvk { "oDepthLe"); } break; + case DxbcOperandType::InputForkInstanceId: + case DxbcOperandType::InputJoinInstanceId: { + // Nothing to do here, as these are part of the + // function signature for the fork and join phases. + } break; + default: Logger::err(str::format( "DxbcCompiler: Unsupported operand type declaration: ", @@ -2258,6 +2267,45 @@ namespace dxvk { } + void DxbcCompiler::emitHullShaderPhase(const DxbcShaderInstruction& ins) { + switch (ins.op) { + case DxbcOpcode::HsDecls: { + if (m_hs.currPhaseType != DxbcCompilerHsPhase::None) + Logger::err("DXBC: HsDecls not the first phase in hull shader"); + + m_hs.currPhaseType = DxbcCompilerHsPhase::Decl; + } break; + + case DxbcOpcode::HsForkPhase: { + auto phase = this->emitNewHullShaderForkJoinPhase(); + m_hs.forkPhases.push_back(phase); + + m_hs.currPhaseType = DxbcCompilerHsPhase::Fork; + m_hs.currPhaseId = m_hs.forkPhases.size() - 1; + + m_module.setDebugName(phase.functionId, + str::format("hs_fork_", m_hs.currPhaseId).c_str()); + } break; + + case DxbcOpcode::HsJoinPhase: { + auto phase = this->emitNewHullShaderForkJoinPhase(); + m_hs.joinPhases.push_back(phase); + + m_hs.currPhaseType = DxbcCompilerHsPhase::Join; + m_hs.currPhaseId = m_hs.joinPhases.size() - 1; + + m_module.setDebugName(phase.functionId, + str::format("hs_join_", m_hs.currPhaseId).c_str()); + } break; + + default: + Logger::warn(str::format( + "DxbcCompiler: Unhandled instruction: ", + ins.op)); + } + } + + void DxbcCompiler::emitInterpolate(const DxbcShaderInstruction& ins) { // The SPIR-V instructions operate on input variable pointers, // which are all declared as four-component float vectors. @@ -3880,6 +3928,16 @@ namespace dxvk { return DxbcRegisterPointer { { DxbcScalarType::Float32, 1 }, m_ps.builtinDepth }; + + case DxbcOperandType::InputForkInstanceId: + return DxbcRegisterPointer { + { DxbcScalarType::Uint32, 1 }, + m_hs.forkPhases.at(m_hs.currPhaseId).builtinInstanceId }; + + case DxbcOperandType::InputJoinInstanceId: + return DxbcRegisterPointer { + { DxbcScalarType::Uint32, 1 }, + m_hs.joinPhases.at(m_hs.currPhaseId).builtinInstanceId }; default: throw DxvkError(str::format( @@ -5021,6 +5079,28 @@ namespace dxvk { } + DxbcCompilerHsForkJoinPhase DxbcCompiler::emitNewHullShaderForkJoinPhase() { + uint32_t argTypeId = m_module.defPointerType( + m_module.defIntType(32, 0), + spv::StorageClassFunction); + uint32_t funTypeId = m_module.defFunctionType( + m_module.defVoidType(), 1, &argTypeId); + + uint32_t funId = m_module.allocateId(); + + m_module.functionBegin(m_module.defVoidType(), + funId, funTypeId, spv::FunctionControlMaskNone); + + uint32_t argId = m_module.functionParameter(argTypeId); + m_module.opLabel(m_module.allocateId()); + + DxbcCompilerHsForkJoinPhase result; + result.functionId = funId; + result.builtinInstanceId = argId; + return result; + } + + uint32_t DxbcCompiler::emitNewVariable(const DxbcRegisterInfo& info) { const uint32_t ptrTypeId = this->getPointerTypeId(info); return m_module.newVar(ptrTypeId, info.sclass); diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 9b801b49..fab86726 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -527,6 +527,9 @@ namespace dxvk { void emitConvertFloat16( const DxbcShaderInstruction& ins); + void emitHullShaderPhase( + const DxbcShaderInstruction& ins); + void emitInterpolate( const DxbcShaderInstruction& ins); @@ -833,6 +836,8 @@ namespace dxvk { uint32_t vertexCount, const char* varName); + DxbcCompilerHsForkJoinPhase emitNewHullShaderForkJoinPhase(); + /////////////////////////////// // Variable definition methods uint32_t emitNewVariable( diff --git a/src/dxbc/dxbc_defs.cpp b/src/dxbc/dxbc_defs.cpp index cae45c65..781369bc 100644 --- a/src/dxbc/dxbc_defs.cpp +++ b/src/dxbc/dxbc_defs.cpp @@ -562,13 +562,13 @@ namespace dxvk { /* Reserved1 */ { }, /* HsDecls */ - { }, + { 0, DxbcInstClass::HullShaderPhase }, /* HsControlPointPhase */ - { }, + { 0, DxbcInstClass::HullShaderPhase }, /* HsForkPhase */ - { }, + { 0, DxbcInstClass::HullShaderPhase }, /* HsJoinPhase */ - { }, + { 0, DxbcInstClass::HullShaderPhase }, /* EmitStream */ { 1, DxbcInstClass::GeometryEmit, { { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, diff --git a/src/dxbc/dxbc_defs.h b/src/dxbc/dxbc_defs.h index ae048780..4f9006a8 100644 --- a/src/dxbc/dxbc_defs.h +++ b/src/dxbc/dxbc_defs.h @@ -41,6 +41,7 @@ namespace dxvk { BufferLoad, ///< Structured or raw buffer load BufferStore, ///< Structured or raw buffer store ConvertFloat16, ///< 16-bit float packing/unpacking + HullShaderPhase, ///< Hull shader phase declaration Interpolate, ///< Input attribute interpolation TextureQuery, ///< Texture query instruction TextureQueryLod, ///< Texture LOD query instruction diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index 756a0441..3f177523 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -2752,7 +2752,8 @@ namespace dxvk { // we can use the code buffer to look up type IDs as // well. Result IDs are always stored as argument 1. for (auto ins : m_typeConstDefs) { - bool match = ins.opCode() == op; + bool match = ins.opCode() == op + && ins.length() == 2 + argCount; for (uint32_t i = 0; i < argCount && match; i++) match &= ins.arg(2 + i) == argIds[i];