From d1720c0c52fea183d6eacd3041e80693a688e842 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 19 Dec 2017 20:26:05 +0100 Subject: [PATCH] [dxbc] Implemented derivatives --- src/dxbc/dxbc_compiler.cpp | 47 +++++++++++++++++ src/dxbc/dxbc_compiler.h | 3 ++ src/dxbc/dxbc_defs.cpp | 30 ++++++++--- src/dxbc/dxbc_defs.h | 1 + src/dxvk/dxvk_memory.cpp | 2 + src/spirv/spirv_module.cpp | 104 ++++++++++++++++++++++++++++++++----- src/spirv/spirv_module.h | 32 ++++++++++-- 7 files changed, 196 insertions(+), 23 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index d52fbefbc..99e45e858 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -74,6 +74,9 @@ namespace dxvk { case DxbcInstClass::VectorCmp: return this->emitVectorCmp(ins); + case DxbcInstClass::VectorDeriv: + return this->emitVectorDeriv(ins); + case DxbcInstClass::VectorDot: return this->emitVectorDot(ins); @@ -981,6 +984,50 @@ namespace dxvk { } + void DxbcCompiler::emitVectorDeriv(const DxbcShaderInstruction& ins) { + // Derivative instructions have two operands: + // (dst0) Destination register for the derivative + // (src0) The operand to compute the derivative of + DxbcRegisterValue value = emitRegisterLoad(ins.src[0], ins.dst[0].mask); + const uint32_t typeId = getVectorTypeId(value.type); + + switch (ins.op) { + case DxbcOpcode::DerivRtx: + value.id = m_module.opDpdx(typeId, value.id); + break; + + case DxbcOpcode::DerivRty: + value.id = m_module.opDpdy(typeId, value.id); + break; + + case DxbcOpcode::DerivRtxCoarse: + value.id = m_module.opDpdxCoarse(typeId, value.id); + break; + + case DxbcOpcode::DerivRtyCoarse: + value.id = m_module.opDpdyCoarse(typeId, value.id); + break; + + case DxbcOpcode::DerivRtxFine: + value.id = m_module.opDpdxFine(typeId, value.id); + break; + + case DxbcOpcode::DerivRtyFine: + value.id = m_module.opDpdyFine(typeId, value.id); + break; + + default: + Logger::warn(str::format( + "DxbcCompiler: Unhandled instruction: ", + ins.op)); + return; + } + + value = emitDstOperandModifiers(value, ins.modifiers); + emitRegisterStore(ins.dst[0], value); + } + + void DxbcCompiler::emitVectorDot(const DxbcShaderInstruction& ins) { const DxbcRegMask srcMask(true, ins.op >= DxbcOpcode::Dp2, diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index a7793587b..74878dc19 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -305,6 +305,9 @@ namespace dxvk { void emitVectorCmp( const DxbcShaderInstruction& ins); + void emitVectorDeriv( + const DxbcShaderInstruction& ins); + void emitVectorDot( const DxbcShaderInstruction& ins); diff --git a/src/dxbc/dxbc_defs.cpp b/src/dxbc/dxbc_defs.cpp index 2481af637..0109f7e62 100644 --- a/src/dxbc/dxbc_defs.cpp +++ b/src/dxbc/dxbc_defs.cpp @@ -42,9 +42,15 @@ namespace dxvk { /* Default */ { }, /* DerivRtx */ - { }, + { 2, DxbcInstClass::VectorDeriv, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, /* DerivRty */ - { }, + { 2, DxbcInstClass::VectorDeriv, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, /* Discard */ { 1, DxbcInstClass::ControlFlow, { { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, @@ -457,13 +463,25 @@ namespace dxvk { /* BufInfo */ { }, /* DerivRtxCoarse */ - { }, + { 2, DxbcInstClass::VectorDeriv, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, /* DerivRtxFine */ - { }, + { 2, DxbcInstClass::VectorDeriv, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, /* DerivRtyCoarse */ - { }, + { 2, DxbcInstClass::VectorDeriv, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, /* DerivRtyFine */ - { }, + { 2, DxbcInstClass::VectorDeriv, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, /* Gather4C */ { }, /* Gather4Po */ diff --git a/src/dxbc/dxbc_defs.h b/src/dxbc/dxbc_defs.h index c14064336..a3668e20e 100644 --- a/src/dxbc/dxbc_defs.h +++ b/src/dxbc/dxbc_defs.h @@ -36,6 +36,7 @@ namespace dxvk { 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 diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index 183704ea1..cd98d3831 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -59,12 +59,14 @@ namespace dxvk { m_memory(memory), m_mapPtr(mapPtr), m_size (size) { + TRACE(this, heap, size); // Mark the entire chunk as free m_freeList.push_back(FreeSlice { 0, size }); } DxvkMemoryChunk::~DxvkMemoryChunk() { + TRACE(this); m_heap->freeDeviceMemory(m_memory); } diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index 2bbafe12e..c1fdcbbe2 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -641,6 +641,19 @@ namespace dxvk { } + uint32_t SpirvModule::opNot( + uint32_t resultType, + uint32_t operand) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpNot, 4); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(operand); + return resultId; + } + + uint32_t SpirvModule::opConvertFtoS( uint32_t resultType, uint32_t operand) { @@ -693,19 +706,6 @@ namespace dxvk { } - uint32_t SpirvModule::opNot( - uint32_t resultType, - uint32_t operand) { - uint32_t resultId = this->allocateId(); - - m_code.putIns (spv::OpNot, 4); - m_code.putWord(resultType); - m_code.putWord(resultId); - m_code.putWord(operand); - return resultId; - } - - uint32_t SpirvModule::opCompositeConstruct( uint32_t resultType, uint32_t valueCount, @@ -760,6 +760,84 @@ namespace dxvk { } + uint32_t SpirvModule::opDpdx( + uint32_t resultType, + uint32_t operand) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpDPdx, 4); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(operand); + return resultId; + } + + + uint32_t SpirvModule::opDpdy( + uint32_t resultType, + uint32_t operand) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpDPdy, 4); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(operand); + return resultId; + } + + + uint32_t SpirvModule::opDpdxCoarse( + uint32_t resultType, + uint32_t operand) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpDPdxCoarse, 4); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(operand); + return resultId; + } + + + uint32_t SpirvModule::opDpdyCoarse( + uint32_t resultType, + uint32_t operand) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpDPdyCoarse, 4); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(operand); + return resultId; + } + + + uint32_t SpirvModule::opDpdxFine( + uint32_t resultType, + uint32_t operand) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpDPdxFine, 4); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(operand); + return resultId; + } + + + uint32_t SpirvModule::opDpdyFine( + uint32_t resultType, + uint32_t operand) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpDPdyFine, 4); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(operand); + return resultId; + } + + uint32_t SpirvModule::opVectorShuffle( uint32_t resultType, uint32_t vectorLeft, diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index 55b85bf87..87bbb2c08 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -236,6 +236,10 @@ namespace dxvk { uint32_t operand1, uint32_t operand2); + uint32_t opNot( + uint32_t resultType, + uint32_t operand); + uint32_t opConvertFtoS( uint32_t resultType, uint32_t operand); @@ -252,10 +256,6 @@ namespace dxvk { uint32_t resultType, uint32_t operand); - uint32_t opNot( - uint32_t resultType, - uint32_t operand); - uint32_t opCompositeConstruct( uint32_t resultType, uint32_t valueCount, @@ -274,6 +274,30 @@ namespace dxvk { uint32_t indexCount, const uint32_t* indexArray); + uint32_t opDpdx( + uint32_t resultType, + uint32_t operand); + + uint32_t opDpdy( + uint32_t resultType, + uint32_t operand); + + uint32_t opDpdxCoarse( + uint32_t resultType, + uint32_t operand); + + uint32_t opDpdyCoarse( + uint32_t resultType, + uint32_t operand); + + uint32_t opDpdxFine( + uint32_t resultType, + uint32_t operand); + + uint32_t opDpdyFine( + uint32_t resultType, + uint32_t operand); + uint32_t opVectorShuffle( uint32_t resultType, uint32_t vectorLeft,