diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index b3d6ec2f..e0e1384e 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -88,6 +88,9 @@ namespace dxvk { case DxbcInstClass::HullShaderPhase: return this->emitHullShaderPhase(ins); + case DxbcInstClass::HullShaderInstCnt: + return this->emitHullShaderInstCnt(ins); + case DxbcInstClass::Interpolate: return this->emitInterpolate(ins); @@ -482,8 +485,18 @@ namespace dxvk { case DxbcOperandType::InputForkInstanceId: case DxbcOperandType::InputJoinInstanceId: { - // Nothing to do here, as these are part of the - // function signature for the fork and join phases. + auto phase = this->getCurrentHsForkJoinPhase(); + + 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; default: @@ -2267,6 +2280,11 @@ namespace dxvk { } + void DxbcCompiler::emitHullShaderInstCnt(const DxbcShaderInstruction& ins) { + this->getCurrentHsForkJoinPhase()->instanceCount = ins.imm[0].u32; + } + + void DxbcCompiler::emitHullShaderPhase(const DxbcShaderInstruction& ins) { switch (ins.op) { case DxbcOpcode::HsDecls: { @@ -3954,12 +3972,12 @@ namespace dxvk { case DxbcOperandType::InputForkInstanceId: return DxbcRegisterPointer { { DxbcScalarType::Uint32, 1 }, - m_hs.forkPhases.at(m_hs.currPhaseId).builtinInstanceId }; + m_hs.forkPhases.at(m_hs.currPhaseId).instanceIdPtr }; case DxbcOperandType::InputJoinInstanceId: return DxbcRegisterPointer { { DxbcScalarType::Uint32, 1 }, - m_hs.joinPhases.at(m_hs.currPhaseId).builtinInstanceId }; + m_hs.joinPhases.at(m_hs.currPhaseId).instanceIdPtr }; default: throw DxvkError(str::format( @@ -5016,7 +5034,13 @@ namespace dxvk { void DxbcCompiler::emitHsFinalize() { - // TODO implement + this->emitHsControlPointPhase(m_hs.cpPhase); + + for (const auto& phase : m_hs.forkPhases) + this->emitHsForkJoinPhase(phase); + + for (const auto& phase : m_hs.joinPhases) + this->emitHsForkJoinPhase(phase); } @@ -5052,6 +5076,22 @@ namespace dxvk { } + void DxbcCompiler::emitHsControlPointPhase( + const DxbcCompilerHsControlPointPhase& phase) { + + } + + + void DxbcCompiler::emitHsForkJoinPhase( + const DxbcCompilerHsForkJoinPhase& phase) { + for (uint32_t i = 0; i < phase.instanceCount; i++) { + const uint32_t counterId = m_module.constu32(i); + m_module.opFunctionCall(m_module.defVoidType(), + phase.functionId, 1, &counterId); + } + } + + void DxbcCompiler::emitDclInputArray(uint32_t vertexCount) { DxbcArrayType info; info.ctype = DxbcScalarType::Float32; @@ -5102,9 +5142,7 @@ namespace dxvk { DxbcCompilerHsForkJoinPhase DxbcCompiler::emitNewHullShaderForkJoinPhase() { - uint32_t argTypeId = m_module.defPointerType( - m_module.defIntType(32, 0), - spv::StorageClassFunction); + uint32_t argTypeId = m_module.defIntType(32, 0); uint32_t funTypeId = m_module.defFunctionType( m_module.defVoidType(), 1, &argTypeId); @@ -5117,8 +5155,8 @@ namespace dxvk { m_module.opLabel(m_module.allocateId()); DxbcCompilerHsForkJoinPhase result; - result.functionId = funId; - result.builtinInstanceId = argId; + result.functionId = funId; + result.instanceId = argId; return result; } @@ -5334,4 +5372,13 @@ namespace dxvk { return typeId; } + + DxbcCompilerHsForkJoinPhase* DxbcCompiler::getCurrentHsForkJoinPhase() { + switch (m_hs.currPhaseType) { + case DxbcCompilerHsPhase::Fork: return &m_hs.forkPhases.at(m_hs.currPhaseId); + case DxbcCompilerHsPhase::Join: return &m_hs.joinPhases.at(m_hs.currPhaseId); + default: return nullptr; + } + } + } \ No newline at end of file diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index a9bb913d..0c652fb2 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -160,8 +160,9 @@ namespace dxvk { */ struct DxbcCompilerHsForkJoinPhase { uint32_t functionId = 0; - uint32_t instanceCount = 0; - uint32_t builtinInstanceId = 0; + uint32_t instanceCount = 1; + uint32_t instanceId = 0; + uint32_t instanceIdPtr = 0; }; @@ -530,6 +531,9 @@ namespace dxvk { void emitHullShaderPhase( const DxbcShaderInstruction& ins); + void emitHullShaderInstCnt( + const DxbcShaderInstruction& ins); + void emitInterpolate( const DxbcShaderInstruction& ins); @@ -831,6 +835,14 @@ namespace dxvk { void emitPsFinalize(); void emitCsFinalize(); + /////////////////////////////// + // Hull shader phase methods + void emitHsControlPointPhase( + const DxbcCompilerHsControlPointPhase& phase); + + void emitHsForkJoinPhase( + const DxbcCompilerHsForkJoinPhase& phase); + ////////////// // Misc stuff void emitDclInputArray( @@ -891,7 +903,7 @@ namespace dxvk { uint32_t getPerVertexBlockId(); - uint32_t getPushConstantBlockId(); + DxbcCompilerHsForkJoinPhase* getCurrentHsForkJoinPhase(); }; diff --git a/src/dxbc/dxbc_defs.cpp b/src/dxbc/dxbc_defs.cpp index 781369bc..6590e082 100644 --- a/src/dxbc/dxbc_defs.cpp +++ b/src/dxbc/dxbc_defs.cpp @@ -728,9 +728,13 @@ namespace dxvk { /* DclHsMaxTessFactor */ { }, /* DclHsForkPhaseInstanceCount */ - { }, + { 1, DxbcInstClass::HullShaderInstCnt, { + { DxbcOperandKind::Imm32, DxbcScalarType::Uint32 }, + } }, /* DclHsJoinPhaseInstanceCount */ - { }, + { 1, DxbcInstClass::HullShaderInstCnt, { + { DxbcOperandKind::Imm32, DxbcScalarType::Uint32 }, + } }, /* DclThreadGroup */ { 3, DxbcInstClass::Declaration, { { DxbcOperandKind::Imm32, DxbcScalarType::Uint32 }, diff --git a/src/dxbc/dxbc_defs.h b/src/dxbc/dxbc_defs.h index 4f9006a8..c1155c9a 100644 --- a/src/dxbc/dxbc_defs.h +++ b/src/dxbc/dxbc_defs.h @@ -28,39 +28,40 @@ namespace dxvk { * new instructions easier. */ enum class DxbcInstClass { - Declaration, ///< Interface or resource declaration - CustomData, ///< Immediate constant buffer - ControlFlow, ///< Control flow instructions - GeometryEmit, ///< Special geometry shader instructions - Atomic, ///< Atomic operations - AtomicCounter, ///< Atomic counter operations - Barrier, ///< Execution or memory barrier - BitExtract, ///< Bit field extract operations - BitInsert, ///< Bit field insert operations - BufferQuery, ///< Buffer query instruction - 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 - TextureQueryMs, ///< Multisample texture query - TextureFetch, ///< Texture fetch instruction - TextureGather, ///< Texture gather instruction - TextureSample, ///< Texture sampling instruction - TypedUavLoad, ///< Typed UAV load - TypedUavStore, ///< Typed UAV store - VectorAlu, ///< Component-wise vector instructions - VectorCmov, ///< Component-wise conditional move - VectorCmp, ///< Component-wise vector comparison - VectorDeriv, ///< Vector derivatives - VectorDot, ///< Dot product instruction - VectorIdiv, ///< Component-wise integer division - VectorImul, ///< Component-wise integer multiplication - VectorShift, ///< Bit shift operations on vectors - VectorSinCos, ///< Sine and Cosine instruction - Undefined, ///< Instruction code not defined + Declaration, ///< Interface or resource declaration + CustomData, ///< Immediate constant buffer + ControlFlow, ///< Control flow instructions + GeometryEmit, ///< Special geometry shader instructions + Atomic, ///< Atomic operations + AtomicCounter, ///< Atomic counter operations + Barrier, ///< Execution or memory barrier + BitExtract, ///< Bit field extract operations + BitInsert, ///< Bit field insert operations + BufferQuery, ///< Buffer query instruction + BufferLoad, ///< Structured or raw buffer load + BufferStore, ///< Structured or raw buffer store + ConvertFloat16, ///< 16-bit float packing/unpacking + HullShaderPhase, ///< Hull shader phase declaration + HullShaderInstCnt, ///< Hull shader phase instance count + Interpolate, ///< Input attribute interpolation + TextureQuery, ///< Texture query instruction + TextureQueryLod, ///< Texture LOD query instruction + TextureQueryMs, ///< Multisample texture query + TextureFetch, ///< Texture fetch instruction + TextureGather, ///< Texture gather instruction + TextureSample, ///< Texture sampling instruction + TypedUavLoad, ///< Typed UAV load + TypedUavStore, ///< Typed UAV store + VectorAlu, ///< Component-wise vector instructions + VectorCmov, ///< Component-wise conditional move + VectorCmp, ///< Component-wise vector comparison + VectorDeriv, ///< Vector derivatives + VectorDot, ///< Dot product instruction + VectorIdiv, ///< Component-wise integer division + VectorImul, ///< Component-wise integer multiplication + VectorShift, ///< Bit shift operations on vectors + VectorSinCos, ///< Sine and Cosine instruction + Undefined, ///< Instruction code not defined }; /** diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index 3f177523..b5ba7ed6 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -547,10 +547,13 @@ namespace dxvk { spv::StorageClass storageClass) { uint32_t resultId = this->allocateId(); - m_variables.putIns (spv::OpVariable, 4); - m_variables.putWord (pointerType); - m_variables.putWord (resultId); - m_variables.putWord (storageClass); + auto& code = storageClass != spv::StorageClassFunction + ? m_variables : m_code; + + code.putIns (spv::OpVariable, 4); + code.putWord (pointerType); + code.putWord (resultId); + code.putWord (storageClass); return resultId; } @@ -561,11 +564,14 @@ namespace dxvk { uint32_t initialValue) { uint32_t resultId = this->allocateId(); - m_variables.putIns (spv::OpVariable, 5); - m_variables.putWord (pointerType); - m_variables.putWord (resultId); - m_variables.putWord (storageClass); - m_variables.putWord (initialValue); + auto& code = storageClass != spv::StorageClassFunction + ? m_variables : m_code; + + code.putIns (spv::OpVariable, 5); + code.putWord (pointerType); + code.putWord (resultId); + code.putWord (storageClass); + code.putWord (initialValue); return resultId; }