From 2ad5f49f3e93443cc1f132e8c413023a66571a45 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Dec 2017 12:53:53 +0100 Subject: [PATCH] [dxbc] Shader compiler rewrite (2/2) --- src/dxbc/dxbc_chunk_isgn.h | 3 +- src/dxbc/dxbc_compiler.cpp | 180 ++++++++++++++++++------------------- src/dxbc/dxbc_compiler.h | 102 +++++++++++---------- src/dxbc/dxbc_decoder.h | 55 ++---------- src/dxbc/dxbc_defs.h | 33 ++++++- src/dxbc/dxbc_enums.h | 18 +++- src/dxbc/dxbc_module.cpp | 2 +- src/dxbc/dxbc_names.cpp | 8 +- src/dxbc/dxbc_names.h | 2 +- src/dxbc/dxbc_type.cpp | 17 ---- src/dxbc/dxbc_type.h | 165 ---------------------------------- src/dxbc/meson.build | 1 - 12 files changed, 211 insertions(+), 375 deletions(-) delete mode 100644 src/dxbc/dxbc_type.cpp delete mode 100644 src/dxbc/dxbc_type.h diff --git a/src/dxbc/dxbc_chunk_isgn.h b/src/dxbc/dxbc_chunk_isgn.h index a65208f3e..13b680f4c 100644 --- a/src/dxbc/dxbc_chunk_isgn.h +++ b/src/dxbc/dxbc_chunk_isgn.h @@ -4,7 +4,6 @@ #include "dxbc_decoder.h" #include "dxbc_enums.h" #include "dxbc_reader.h" -#include "dxbc_type.h" namespace dxvk { @@ -18,7 +17,7 @@ namespace dxvk { std::string semanticName; uint32_t semanticIndex; uint32_t registerId; - DxbcComponentMask componentMask; + DxbcRegMask componentMask; DxbcScalarType componentType; DxbcSystemValue systemValue; }; diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 432ca24ae..84698c4c1 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -10,7 +10,7 @@ namespace dxvk { constexpr uint32_t PerVertex_ClipDist = 3; - DxbcCompiler2::DxbcCompiler2( + DxbcCompiler::DxbcCompiler( const DxbcProgramVersion& version, const Rc& isgn, const Rc& osgn) @@ -43,12 +43,12 @@ namespace dxvk { } - DxbcCompiler2::~DxbcCompiler2() { + DxbcCompiler::~DxbcCompiler() { } - DxbcError DxbcCompiler2::processInstruction(const DxbcInstruction& ins) { + DxbcError DxbcCompiler::processInstruction(const DxbcInstruction& ins) { DxbcInst parsedInst; DxbcError parseError = this->parseInstruction(ins, parsedInst); @@ -67,7 +67,7 @@ namespace dxvk { } - Rc DxbcCompiler2::finalize() { + Rc DxbcCompiler::finalize() { // Define the actual 'main' function of the shader m_module.functionBegin( m_module.defVoidType(), @@ -106,7 +106,7 @@ namespace dxvk { } - DxbcError DxbcCompiler2::handleDeclaration(const DxbcInst& ins) { + DxbcError DxbcCompiler::handleDeclaration(const DxbcInst& ins) { switch (ins.opcode) { case DxbcOpcode::DclGlobalFlags: return this->declareGlobalFlags(ins); @@ -140,14 +140,14 @@ namespace dxvk { } - DxbcError DxbcCompiler2::declareGlobalFlags(const DxbcInst& ins) { + DxbcError DxbcCompiler::declareGlobalFlags(const DxbcInst& ins) { // TODO add support for double-precision floats // TODO add support for early depth-stencil return DxbcError::sOk; } - DxbcError DxbcCompiler2::declareTemps(const DxbcInst& ins) { + DxbcError DxbcCompiler::declareTemps(const DxbcInst& ins) { if (ins.operands[0].type != DxbcOperandType::Imm32) { Logger::err("dxbc: Number of temps not a contant"); return DxbcError::eInvalidOperand; @@ -181,7 +181,7 @@ namespace dxvk { } - DxbcError DxbcCompiler2::declareInterfaceVar(const DxbcInst& ins) { + DxbcError DxbcCompiler::declareInterfaceVar(const DxbcInst& ins) { const DxbcInstOp& op = ins.operands[0]; // In the vertex and fragment shader stage, the @@ -266,7 +266,7 @@ namespace dxvk { } - DxbcError DxbcCompiler2::declareConstantBuffer(const DxbcInst& ins) { + DxbcError DxbcCompiler::declareConstantBuffer(const DxbcInst& ins) { const DxbcInstOp& op = ins.operands[0]; // This instruction has one operand with two indices: @@ -322,7 +322,7 @@ namespace dxvk { } - DxbcError DxbcCompiler2::declareSampler(const DxbcInst& ins) { + DxbcError DxbcCompiler::declareSampler(const DxbcInst& ins) { // dclSampler takes one operand: // (1) The sampler register ID // TODO implement sampler mode (default / comparison / mono) @@ -365,7 +365,7 @@ namespace dxvk { } - DxbcError DxbcCompiler2::declareResource(const DxbcInst& ins) { + DxbcError DxbcCompiler::declareResource(const DxbcInst& ins) { // dclResource takes two operands: // (1) The resource register ID // (2) The resource return type @@ -489,7 +489,7 @@ namespace dxvk { } - DxbcError DxbcCompiler2::declareInputVar( + DxbcError DxbcCompiler::declareInputVar( uint32_t regId, uint32_t regDim, DxbcRegMask regMask, @@ -523,7 +523,7 @@ namespace dxvk { } - DxbcError DxbcCompiler2::declareOutputVar( + DxbcError DxbcCompiler::declareOutputVar( uint32_t regId, uint32_t regDim, DxbcRegMask regMask, @@ -567,7 +567,7 @@ namespace dxvk { } - DxbcError DxbcCompiler2::handleControlFlow(const DxbcInst& ins) { + DxbcError DxbcCompiler::handleControlFlow(const DxbcInst& ins) { switch (ins.opcode) { case DxbcOpcode::Ret: m_module.opReturn(); @@ -580,7 +580,7 @@ namespace dxvk { } - DxbcError DxbcCompiler2::handleTextureSample(const DxbcInst& ins) { + DxbcError DxbcCompiler::handleTextureSample(const DxbcInst& ins) { // TODO support address offset // TODO support more sample ops @@ -605,7 +605,7 @@ namespace dxvk { // Load the texture coordinates. SPIR-V allows these // to be float4 even if not all components are used. - const DxbcValue2 coord = this->loadOp(coordOp, + const DxbcValue coord = this->loadOp(coordOp, DxbcRegMask(true, true, true, true), DxbcScalarType::Float32); @@ -625,7 +625,7 @@ namespace dxvk { // Sampling an image in SPIR-V always returns a four-component // vector, so we need to declare the corresponding type here // TODO infer sampled type properly - DxbcValue2 result; + DxbcValue result; result.componentType = DxbcScalarType::Float32; result.componentCount = 4; result.valueId = m_module.opImageSampleImplicitLod( @@ -641,10 +641,10 @@ namespace dxvk { } - DxbcError DxbcCompiler2::handleVectorAlu(const DxbcInst& ins) { + DxbcError DxbcCompiler::handleVectorAlu(const DxbcInst& ins) { // Load input operands. Operands that are floating // point types will be affected by modifiers. - DxbcValue2 arguments[DxbcMaxOperandCount - 1]; + DxbcValue arguments[DxbcMaxOperandCount - 1]; for (uint32_t i = 1; i < ins.format.operandCount; i++) { arguments[i - 1] = this->loadOp( @@ -654,7 +654,7 @@ namespace dxvk { } // Result that we will write to the destination operand - DxbcValue2 result; + DxbcValue result; result.componentType = arguments[0].componentType; result.componentCount = arguments[0].componentCount; @@ -718,7 +718,7 @@ namespace dxvk { } - DxbcError DxbcCompiler2::handleVectorDot(const DxbcInst& ins) { + DxbcError DxbcCompiler::handleVectorDot(const DxbcInst& ins) { // Determine the component count and the source // operand mask. Since the result is scalar, we // cannot use the destination register mask. @@ -737,7 +737,7 @@ namespace dxvk { numComponents >= 3, numComponents >= 4); // Load input operands as floatig point numbers - DxbcValue2 arguments[2]; + DxbcValue arguments[2]; for (uint32_t i = 1; i <= 2; i++) { arguments[i - 1] = this->loadOp( @@ -745,7 +745,7 @@ namespace dxvk { DxbcScalarType::Float32); } - DxbcValue2 result; + DxbcValue result; result.componentType = DxbcScalarType::Float32; result.componentCount = 1; result.valueId = m_module.opDot( @@ -762,7 +762,7 @@ namespace dxvk { } - DxbcError DxbcCompiler2::handleVectorSinCos(const DxbcInst& ins) { + DxbcError DxbcCompiler::handleVectorSinCos(const DxbcInst& ins) { // sincos has three operands: // (1) Destination register for sin(x) // (2) Destination register for cos(x) @@ -772,17 +772,17 @@ namespace dxvk { const DxbcInstOp srcOp = ins.operands[2]; // Load source operand as 32-bit float vector - const DxbcValue2 srcValue = this->loadOp(srcOp, + const DxbcValue srcValue = this->loadOp(srcOp, DxbcRegMask(true, true, true, true), DxbcScalarType::Float32); // Either output may be DxbcOperandType::Null, in // which case we don't have to generate any code if (dstSinOp.type != DxbcOperandType::Null) { - const DxbcValue2 sinInput = this->extractReg( + const DxbcValue sinInput = this->extractReg( srcValue, dstSinOp.mask); - DxbcValue2 sinValue; + DxbcValue sinValue; sinValue.componentType = srcValue.componentType; sinValue.componentCount = srcValue.componentCount; sinValue.valueId = m_module.opSin( @@ -795,10 +795,10 @@ namespace dxvk { } if (dstCosOp.type != DxbcOperandType::Null) { - const DxbcValue2 cosInput = this->extractReg( + const DxbcValue cosInput = this->extractReg( srcValue, dstCosOp.mask); - DxbcValue2 cosValue; + DxbcValue cosValue; cosValue.componentType = srcValue.componentType; cosValue.componentCount = srcValue.componentCount; cosValue.valueId = m_module.opCos( @@ -814,8 +814,8 @@ namespace dxvk { } - DxbcValue2 DxbcCompiler2::bitcastReg( - const DxbcValue2& src, + DxbcValue DxbcCompiler::bitcastReg( + const DxbcValue& src, DxbcScalarType type) { if (src.componentType == type) return src; @@ -823,7 +823,7 @@ namespace dxvk { // TODO support 64-bit types by adjusting the component count uint32_t typeId = this->defineVectorType(type, src.componentCount); - DxbcValue2 result; + DxbcValue result; result.componentType = type; result.componentCount = src.componentCount; result.valueId = m_module.opBitcast(typeId, src.valueId); @@ -831,11 +831,11 @@ namespace dxvk { } - DxbcValue2 DxbcCompiler2::insertReg( - const DxbcValue2& dst, - const DxbcValue2& src, + DxbcValue DxbcCompiler::insertReg( + const DxbcValue& dst, + const DxbcValue& src, DxbcRegMask mask) { - DxbcValue2 result; + DxbcValue result; result.componentType = dst.componentType; result.componentCount = dst.componentCount; @@ -874,16 +874,16 @@ namespace dxvk { } - DxbcValue2 DxbcCompiler2::extractReg( - const DxbcValue2& src, + DxbcValue DxbcCompiler::extractReg( + const DxbcValue& src, DxbcRegMask mask) { return this->swizzleReg(src, DxbcRegSwizzle(0, 1, 2, 3), mask); } - DxbcValue2 DxbcCompiler2::swizzleReg( - const DxbcValue2& src, + DxbcValue DxbcCompiler::swizzleReg( + const DxbcValue& src, const DxbcRegSwizzle& swizzle, DxbcRegMask mask) { std::array indices; @@ -906,7 +906,7 @@ namespace dxvk { // Use OpCompositeExtract if the resulting vector contains // only one component, and OpVectorShuffle if it is a vector. - DxbcValue2 result; + DxbcValue result; result.componentType = src.componentType; result.componentCount = dstIndex; @@ -926,8 +926,8 @@ namespace dxvk { } - DxbcValue2 DxbcCompiler2::extendReg( - const DxbcValue2& src, + DxbcValue DxbcCompiler::extendReg( + const DxbcValue& src, uint32_t size) { if (size == 1) return src; @@ -940,7 +940,7 @@ namespace dxvk { uint32_t typeId = this->defineVectorType( src.componentType, size); - DxbcValue2 result; + DxbcValue result; result.componentType = src.componentType; result.componentCount = size; result.valueId = m_module.opCompositeConstruct( @@ -949,8 +949,8 @@ namespace dxvk { } - DxbcValue2 DxbcCompiler2::applyOperandModifiers( - DxbcValue2 value, + DxbcValue DxbcCompiler::applyOperandModifiers( + DxbcValue value, DxbcOperandModifiers modifiers) { uint32_t typeId = this->defineVectorType( value.componentType, value.componentCount); @@ -967,8 +967,8 @@ namespace dxvk { } - DxbcValue2 DxbcCompiler2::applyResultModifiers( - DxbcValue2 value, + DxbcValue DxbcCompiler::applyResultModifiers( + DxbcValue value, DxbcOpcodeControl control) { uint32_t typeId = this->defineVectorType( value.componentType, value.componentCount); @@ -984,7 +984,7 @@ namespace dxvk { } - DxbcValue2 DxbcCompiler2::loadOp( + DxbcValue DxbcCompiler::loadOp( const DxbcInstOp& srcOp, DxbcRegMask srcMask, DxbcScalarType dstType) { @@ -992,7 +992,7 @@ namespace dxvk { return this->loadImm32(srcOp, srcMask, dstType); } else { // Load operand value from the operand pointer - DxbcValue2 result = this->loadRegister(srcOp, srcMask, dstType); + DxbcValue result = this->loadRegister(srcOp, srcMask, dstType); // Apply the component swizzle or the selection, // depending on which mode the operand is in. @@ -1022,13 +1022,13 @@ namespace dxvk { } - DxbcValue2 DxbcCompiler2::loadImm32( + DxbcValue DxbcCompiler::loadImm32( const DxbcInstOp& srcOp, DxbcRegMask srcMask, DxbcScalarType dstType) { // We will generate Uint32 constants because at this // point we don't know how they are going to be used. - DxbcValue2 result; + DxbcValue result; result.componentType = DxbcScalarType::Uint32; result.componentCount = srcMask.setCount(); @@ -1070,7 +1070,7 @@ namespace dxvk { } - DxbcValue2 DxbcCompiler2::loadRegister( + DxbcValue DxbcCompiler::loadRegister( const DxbcInstOp& srcOp, DxbcRegMask srcMask, DxbcScalarType dstType) { @@ -1079,20 +1079,20 @@ namespace dxvk { } - void DxbcCompiler2::storeOp( + void DxbcCompiler::storeOp( const DxbcInstOp& dstOp, - const DxbcValue2& srcValue) { + const DxbcValue& srcValue) { this->storePtr( this->getOperandPtr(dstOp), srcValue, dstOp.mask); } - DxbcValue2 DxbcCompiler2::loadPtr(const DxbcPointer2& ptr) { + DxbcValue DxbcCompiler::loadPtr(const DxbcPointer& ptr) { const uint32_t typeId = this->defineVectorType( ptr.componentType, ptr.componentCount); - DxbcValue2 result; + DxbcValue result; result.componentType = ptr.componentType; result.componentCount = ptr.componentCount; result.valueId = m_module.opLoad(typeId, ptr.pointerId); @@ -1100,11 +1100,11 @@ namespace dxvk { } - void DxbcCompiler2::storePtr( - const DxbcPointer2& ptr, - const DxbcValue2& value, + void DxbcCompiler::storePtr( + const DxbcPointer& ptr, + const DxbcValue& value, DxbcRegMask mask) { - DxbcValue2 srcValue = value; + DxbcValue srcValue = value; // If the source value consists of only one component, // it is stored in all destination register components. @@ -1122,7 +1122,7 @@ namespace dxvk { } else { // We only write to part of the destination // register, so we need to load and modify it - DxbcValue2 tmp = this->loadPtr(ptr); + DxbcValue tmp = this->loadPtr(ptr); tmp = this->insertReg(tmp, srcValue, mask); m_module.opStore(ptr.pointerId, tmp.valueId); @@ -1131,9 +1131,9 @@ namespace dxvk { } - DxbcValue2 DxbcCompiler2::loadIndex(const DxbcInstOpIndex& idx) { - DxbcValue2 constantPart; - DxbcValue2 relativePart; + DxbcValue DxbcCompiler::loadIndex(const DxbcInstOpIndex& idx) { + DxbcValue constantPart; + DxbcValue relativePart; if ((idx.type == DxbcIndexType::Immediate) || (idx.immediate != 0)) { constantPart.componentType = DxbcScalarType::Sint32; @@ -1160,7 +1160,7 @@ namespace dxvk { if (relativePart.valueId == 0) return constantPart; if (constantPart.valueId == 0) return relativePart; - DxbcValue2 result; + DxbcValue result; result.componentType = DxbcScalarType::Sint32; result.componentCount = 1; result.valueId = m_module.opIAdd( @@ -1170,8 +1170,8 @@ namespace dxvk { } - DxbcPointer2 DxbcCompiler2::getOperandPtr(const DxbcInstOp& op) { - DxbcPointer2 result; + DxbcPointer DxbcCompiler::getOperandPtr(const DxbcInstOp& op) { + DxbcPointer result; switch (op.type) { case DxbcOperandType::Temp: @@ -1208,24 +1208,24 @@ namespace dxvk { } - DxbcPointer2 DxbcCompiler2::getConstantBufferPtr(const DxbcInstOp& op) { + DxbcPointer DxbcCompiler::getConstantBufferPtr(const DxbcInstOp& op) { if (op.indexDim != 2) { Logger::err("dxbc: Constant buffer reference needs two indices"); - return DxbcPointer2(); + return DxbcPointer(); } // The operand itself has two indices: // (1) The constant buffer ID (immediate) // (2) The constant offset (relative) const uint32_t bufferId = op.index[0].immediate; - const DxbcValue2 offset = this->loadIndex(op.index[1]); + const DxbcValue offset = this->loadIndex(op.index[1]); // The first index selects the struct member, // the second one selects the array element. std::array indices = { m_module.constu32(0), offset.valueId }; - DxbcPointer2 result; + DxbcPointer result; result.componentType = DxbcScalarType::Float32; result.componentCount = 4; result.pointerId = m_module.opAccessChain( @@ -1239,7 +1239,7 @@ namespace dxvk { } - void DxbcCompiler2::beginVertexShader(const Rc& isgn) { + void DxbcCompiler::beginVertexShader(const Rc& isgn) { m_module.enableCapability(spv::CapabilityShader); m_module.enableCapability(spv::CapabilityCullDistance); m_module.enableCapability(spv::CapabilityClipDistance); @@ -1269,7 +1269,7 @@ namespace dxvk { } - void DxbcCompiler2::beginPixelShader(const Rc& osgn) { + void DxbcCompiler::beginPixelShader(const Rc& osgn) { m_module.enableCapability(spv::CapabilityShader); m_module.setOriginUpperLeft(m_entryPointId); @@ -1279,7 +1279,7 @@ namespace dxvk { for (auto e = m_osgn->begin(); e != m_osgn->end(); e++) { if (e->systemValue == DxbcSystemValue::None) { uint32_t regTypeId = this->defineVectorType( - e->componentType, e->componentMask.componentCount()); + e->componentType, e->componentMask.setCount()); uint32_t ptrTypeId = m_module.defPointerType( regTypeId, spv::StorageClassOutput); @@ -1292,7 +1292,7 @@ namespace dxvk { m_entryPointInterfaces.push_back(varId); m_ps.oregs.at(e->registerId).componentType = e->componentType; - m_ps.oregs.at(e->registerId).componentCount = e->componentMask.componentCount(); + m_ps.oregs.at(e->registerId).componentCount = e->componentMask.setCount(); m_ps.oregs.at(e->registerId).pointerId = varId; } } @@ -1311,21 +1311,21 @@ namespace dxvk { } - void DxbcCompiler2::prepareVertexInputs() { + void DxbcCompiler::prepareVertexInputs() { // TODO implement } - void DxbcCompiler2::preparePixelInputs() { + void DxbcCompiler::preparePixelInputs() { // TODO implement } - void DxbcCompiler2::prepareVertexOutputs() { - for (const DxbcSvMapping2& svMapping : m_oSvs) { + void DxbcCompiler::prepareVertexOutputs() { + for (const DxbcSvMapping& svMapping : m_oSvs) { switch (svMapping.sv) { case DxbcSystemValue::Position: { - DxbcPointer2 dstPtr; + DxbcPointer dstPtr; dstPtr.componentType = DxbcScalarType::Float32; dstPtr.componentCount = 4; @@ -1340,7 +1340,7 @@ namespace dxvk { dstPtr.pointerId = m_module.opAccessChain( ptrTypeId, m_perVertexOut, 1, &memberId); - DxbcPointer2 srcPtr; + DxbcPointer srcPtr; srcPtr.componentType = DxbcScalarType::Float32; srcPtr.componentCount = 4; srcPtr.pointerId = m_oRegs.at(svMapping.regId); @@ -1358,12 +1358,12 @@ namespace dxvk { } - void DxbcCompiler2::preparePixelOutputs() { + void DxbcCompiler::preparePixelOutputs() { // TODO implement } - void DxbcCompiler2::endVertexShader() { + void DxbcCompiler::endVertexShader() { this->prepareVertexInputs(); m_module.opFunctionCall( m_module.defVoidType(), @@ -1372,7 +1372,7 @@ namespace dxvk { } - void DxbcCompiler2::endPixelShader() { + void DxbcCompiler::endPixelShader() { this->preparePixelInputs(); m_module.opFunctionCall( m_module.defVoidType(), @@ -1381,7 +1381,7 @@ namespace dxvk { } - uint32_t DxbcCompiler2::definePerVertexBlock() { + uint32_t DxbcCompiler::definePerVertexBlock() { uint32_t t_f32 = m_module.defFloatType(32); uint32_t t_f32_v4 = m_module.defVectorType(t_f32, 4); uint32_t t_f32_a2 = m_module.defArrayType(t_f32, m_module.constu32(2)); @@ -1410,7 +1410,7 @@ namespace dxvk { } - uint32_t DxbcCompiler2::defineScalarType( + uint32_t DxbcCompiler::defineScalarType( DxbcScalarType componentType) { switch (componentType) { case DxbcScalarType::Float32: return m_module.defFloatType(32); @@ -1426,7 +1426,7 @@ namespace dxvk { } - uint32_t DxbcCompiler2::defineVectorType( + uint32_t DxbcCompiler::defineVectorType( DxbcScalarType componentType, uint32_t componentCount) { uint32_t typeId = this->defineScalarType(componentType); @@ -1440,7 +1440,7 @@ namespace dxvk { } - uint32_t DxbcCompiler2::definePointerType( + uint32_t DxbcCompiler::definePointerType( DxbcScalarType componentType, uint32_t componentCount, spv::StorageClass storageClass) { @@ -1451,7 +1451,7 @@ namespace dxvk { } - DxbcError DxbcCompiler2::parseInstruction(const DxbcInstruction& ins, DxbcInst& out) { + DxbcError DxbcCompiler::parseInstruction(const DxbcInstruction& ins, DxbcInst& out) { out.opcode = ins.token().opcode(); out.control = ins.token().control(); out.format = dxbcInstructionFormat(out.opcode); diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index a392d0ce5..137b89adf 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -8,16 +8,26 @@ namespace dxvk { - // TODO deprecate DxbcComponentSelectionMode - using DxbcRegMode = DxbcComponentSelectionMode; - - struct DxbcValue2 { + /** + * \brief Expression value + * + * Tracks the type and the SPIR-V variable + * ID when evaluating DXBC instructions. + */ + struct DxbcValue { DxbcScalarType componentType = DxbcScalarType::Float32; uint32_t componentCount = 0; uint32_t valueId = 0; }; - struct DxbcPointer2 { + /** + * \brief Variable pointer + * + * Stores the SPIR-V pointer ID and the + * type of the referenced variable. Used + * to access variables and resources. + */ + struct DxbcPointer { DxbcScalarType componentType = DxbcScalarType::Float32; uint32_t componentCount = 0; uint32_t pointerId = 0; @@ -29,7 +39,7 @@ namespace dxvk { * Stores information required to * access a constant buffer. */ - struct DxbcConstantBuffer2 { + struct DxbcConstantBuffer { uint32_t varId = 0; uint32_t size = 0; }; @@ -40,7 +50,7 @@ namespace dxvk { * Stores a sampler variable that can be * used together with a texture resource. */ - struct DxbcSampler2 { + struct DxbcSampler { uint32_t varId = 0; uint32_t typeId = 0; }; @@ -52,7 +62,7 @@ namespace dxvk { * Stores a resource variable * and associated type IDs. */ - struct DxbcShaderResource2 { + struct DxbcShaderResource { uint32_t varId = 0; uint32_t sampledTypeId = 0; uint32_t textureTypeId = 0; @@ -64,7 +74,7 @@ namespace dxvk { * Maps a system value to a given set of * components of an input or output register. */ - struct DxbcSvMapping2 { + struct DxbcSvMapping { uint32_t regId; DxbcRegMask regMask; DxbcSystemValue sv; @@ -164,7 +174,7 @@ namespace dxvk { struct DxbcPsSpecifics { uint32_t functionId = 0; - std::array oregs; + std::array oregs; }; @@ -175,15 +185,15 @@ namespace dxvk { * a DXVK shader object, which contains the SPIR-V module * and information about the shader resource bindings. */ - class DxbcCompiler2 { + class DxbcCompiler { public: - DxbcCompiler2( + DxbcCompiler( const DxbcProgramVersion& version, const Rc& isgn, const Rc& osgn); - ~DxbcCompiler2(); + ~DxbcCompiler(); /** * \brief Processes a single instruction @@ -231,15 +241,15 @@ namespace dxvk { ////////////////////////////////////////////////////// // Shader resource variables. These provide access to // constant buffers, samplers, textures, and UAVs. - std::array m_constantBuffers; - std::array m_samplers; - std::array m_textures; + std::array m_constantBuffers; + std::array m_samplers; + std::array m_textures; //////////////////////////////////////////////////////// // Input/Output system value mappings. These will need // to be set up before or after the main function runs. - std::vector m_vSvs; - std::vector m_oSvs; + std::vector m_vSvs; + std::vector m_oSvs; /////////////////////////////////////////////////////////// // Array of input values. Since v# registers are indexable @@ -319,80 +329,80 @@ namespace dxvk { //////////////////////////////////// // Register manipulation operations - DxbcValue2 bitcastReg( - const DxbcValue2& src, + DxbcValue bitcastReg( + const DxbcValue& src, DxbcScalarType type); - DxbcValue2 insertReg( - const DxbcValue2& dst, - const DxbcValue2& src, + DxbcValue insertReg( + const DxbcValue& dst, + const DxbcValue& src, DxbcRegMask mask); - DxbcValue2 extractReg( - const DxbcValue2& src, + DxbcValue extractReg( + const DxbcValue& src, DxbcRegMask mask); - DxbcValue2 swizzleReg( - const DxbcValue2& src, + DxbcValue swizzleReg( + const DxbcValue& src, const DxbcRegSwizzle& swizzle, DxbcRegMask mask); - DxbcValue2 regVector( - const DxbcValue2& src, + DxbcValue regVector( + const DxbcValue& src, uint32_t size); - DxbcValue2 extendReg( - const DxbcValue2& src, + DxbcValue extendReg( + const DxbcValue& src, uint32_t size); //////////////////////////// // Operand modifier methods - DxbcValue2 applyOperandModifiers( - DxbcValue2 value, + DxbcValue applyOperandModifiers( + DxbcValue value, DxbcOperandModifiers modifiers); - DxbcValue2 applyResultModifiers( - DxbcValue2 value, + DxbcValue applyResultModifiers( + DxbcValue value, DxbcOpcodeControl control); ///////////////////////// // Load/Store operations - DxbcValue2 loadOp( + DxbcValue loadOp( const DxbcInstOp& srcOp, DxbcRegMask srcMask, DxbcScalarType dstType); - DxbcValue2 loadImm32( + DxbcValue loadImm32( const DxbcInstOp& srcOp, DxbcRegMask srcMask, DxbcScalarType dstType); - DxbcValue2 loadRegister( + DxbcValue loadRegister( const DxbcInstOp& srcOp, DxbcRegMask srcMask, DxbcScalarType dstType); void storeOp( const DxbcInstOp& dstOp, - const DxbcValue2& srcValue); + const DxbcValue& srcValue); - DxbcValue2 loadPtr( - const DxbcPointer2& ptr); + DxbcValue loadPtr( + const DxbcPointer& ptr); void storePtr( - const DxbcPointer2& ptr, - const DxbcValue2& value, + const DxbcPointer& ptr, + const DxbcValue& value, DxbcRegMask mask); - DxbcValue2 loadIndex( + DxbcValue loadIndex( const DxbcInstOpIndex& idx); /////////////////////////// // Operand pointer methods - DxbcPointer2 getOperandPtr( + DxbcPointer getOperandPtr( const DxbcInstOp& op); - DxbcPointer2 getConstantBufferPtr( + DxbcPointer getConstantBufferPtr( const DxbcInstOp& op); ///////////////////////////////// diff --git a/src/dxbc/dxbc_decoder.h b/src/dxbc/dxbc_decoder.h index 3f580138c..cce5140fc 100644 --- a/src/dxbc/dxbc_decoder.h +++ b/src/dxbc/dxbc_decoder.h @@ -4,7 +4,6 @@ #include "dxbc_enums.h" #include "dxbc_names.h" -#include "dxbc_type.h" namespace dxvk { @@ -15,7 +14,6 @@ namespace dxvk { * * Maps vector components to * other vector components. - * TODO remove old class */ class DxbcRegSwizzle { @@ -41,7 +39,6 @@ namespace dxvk { * * Enables access to certain * subset of vector components. - * TODO remove old class */ class DxbcRegMask { @@ -322,27 +319,16 @@ namespace dxvk { * a given set of components is used. * \returns Component selection mode */ - DxbcComponentSelectionMode selectionMode() const { - return static_cast( + DxbcRegMode selectionMode() const { + return static_cast( bit::extract(m_token, 2, 3)); } /** * \brief Component mask * - * Used when the component selection mode is - * \c DxbcComponentSelectionMode::Mask. - * \returns The component mask - */ - DxbcComponentMask componentMask() const { - return DxbcComponentMask(bit::extract(m_token, 4, 7)); - } - - /** - * \brief Component mask - * - * Used when the component selection mode is - * \c DxbcComponentSelectionMode::Mask. + * Used when the component selection + * mode is \c DxbcRegMode::Mask. * \returns The component mask */ DxbcRegMask mask() const { @@ -352,23 +338,8 @@ namespace dxvk { /** * \brief Component swizzle * - * Used when the component selection mode is - * \c DxbcComponentSelectionMode::Swizzle. - * \returns The component swizzle - */ - DxbcComponentSwizzle componentSwizzle() const { - return DxbcComponentSwizzle( - bit::extract(m_token, 4, 5), - bit::extract(m_token, 6, 7), - bit::extract(m_token, 8, 9), - bit::extract(m_token, 10, 11)); - } - - /** - * \brief Component swizzle - * - * Used when the component selection mode is - * \c DxbcComponentSelectionMode::Swizzle. + * Used when the component selection + * mode is \c DxbcRegMode::Swizzle. * \returns The component swizzle */ DxbcRegSwizzle swizzle() const { @@ -381,23 +352,15 @@ namespace dxvk { /** * \brief Single component selection + * + * Used when the component selection + * mode is \c DxbcRegMode::Select1. * \returns The component index */ uint32_t select1() const { return bit::extract(m_token, 4, 5); } - /** - * \brief Component selection - * - * Used when the component selection mode is - * \c DxbcComponentSelectionMode::Select1. - */ - DxbcComponentMask componentSelection() const { - uint32_t id = bit::extract(m_token, 4, 5); - return DxbcComponentMask(id == 0, id == 1, id == 2, id == 3); - } - /** * \brief Operand type * diff --git a/src/dxbc/dxbc_defs.h b/src/dxbc/dxbc_defs.h index e68f15916..4c66fd4ee 100644 --- a/src/dxbc/dxbc_defs.h +++ b/src/dxbc/dxbc_defs.h @@ -1,19 +1,32 @@ #pragma once #include "dxbc_enums.h" -#include "dxbc_type.h" namespace dxvk { constexpr size_t DxbcMaxInterfaceRegs = 32; constexpr size_t DxbcMaxOperandCount = 8; + /** + * \brief Operand kind + * + * In the instruction format definition, this specified + * whether an operand uses an actual operand token, or + * whether it is stored as an immediate value. + */ enum class DxbcOperandKind { DstReg, ///< Destination register SrcReg, ///< Source register Imm32, ///< Constant number }; + /** + * \brief Instruction class + * + * Instructions with a similar format are grouped into + * instruction classes in order to make implementing + * new instructions easier. + */ enum class DxbcInstClass { Declaration, ///< Interface or resource declaration TextureSample, ///< Texture sampling instruction @@ -25,17 +38,35 @@ namespace dxvk { Undefined, ///< Instruction code not defined }; + /** + * \brief Instruction operand format + * + * Stores the kind and the expected data type + * of an operand. Used when parsing instructions. + */ struct DxbcInstOperandFormat { DxbcOperandKind kind; DxbcScalarType type; }; + /** + * \brief Instruction format + * + * Defines the instruction class as well as + * the format of the insttruction operands. + */ struct DxbcInstFormat { uint32_t operandCount = 0; DxbcInstClass instructionClass = DxbcInstClass::Undefined; DxbcInstOperandFormat operands[DxbcMaxOperandCount]; }; + /** + * \brief Retrieves instruction format info + * + * \param [in] opcode The opcode to retrieve + * \returns Instruction format info + */ DxbcInstFormat dxbcInstructionFormat(DxbcOpcode opcode); } \ No newline at end of file diff --git a/src/dxbc/dxbc_enums.h b/src/dxbc/dxbc_enums.h index 037b13e25..c8f3393e2 100644 --- a/src/dxbc/dxbc_enums.h +++ b/src/dxbc/dxbc_enums.h @@ -300,7 +300,7 @@ namespace dxvk { * component selection mode deterines which * components are used for the operation. */ - enum class DxbcComponentSelectionMode : uint32_t { + enum class DxbcRegMode : uint32_t { Mask = 0, Swizzle = 1, Select1 = 2, @@ -464,4 +464,20 @@ namespace dxvk { using DxbcSyncFlags = Flags; + /** + * \brief Scalar value type + * + * Enumerates possible register component + * types. Scalar types are represented as + * a one-component vector type. + */ + enum class DxbcScalarType { + Uint32 = 0, + Uint64 = 1, + Sint32 = 2, + Sint64 = 3, + Float32 = 4, + Float64 = 5, + }; + } \ No newline at end of file diff --git a/src/dxbc/dxbc_module.cpp b/src/dxbc/dxbc_module.cpp index dd87295d5..6bd9fe0d6 100644 --- a/src/dxbc/dxbc_module.cpp +++ b/src/dxbc/dxbc_module.cpp @@ -44,7 +44,7 @@ namespace dxvk { if (m_shexChunk == nullptr) throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk"); - DxbcCompiler2 compiler( + DxbcCompiler compiler( m_shexChunk->version(), m_isgnChunk, m_osgnChunk); diff --git a/src/dxbc/dxbc_names.cpp b/src/dxbc/dxbc_names.cpp index 61fc44009..457376da0 100644 --- a/src/dxbc/dxbc_names.cpp +++ b/src/dxbc/dxbc_names.cpp @@ -293,11 +293,11 @@ std::ostream& operator << (std::ostream& os, DxbcComponentCount e) { } -std::ostream& operator << (std::ostream& os, DxbcComponentSelectionMode e) { +std::ostream& operator << (std::ostream& os, DxbcRegMode e) { switch (e) { - ENUM_NAME(DxbcComponentSelectionMode::Mask); - ENUM_NAME(DxbcComponentSelectionMode::Swizzle); - ENUM_NAME(DxbcComponentSelectionMode::Select1); + ENUM_NAME(DxbcRegMode::Mask); + ENUM_NAME(DxbcRegMode::Swizzle); + ENUM_NAME(DxbcRegMode::Select1); ENUM_DEFAULT(e); } } diff --git a/src/dxbc/dxbc_names.h b/src/dxbc/dxbc_names.h index f3e568a2e..4c377eaf9 100644 --- a/src/dxbc/dxbc_names.h +++ b/src/dxbc/dxbc_names.h @@ -10,7 +10,7 @@ std::ostream& operator << (std::ostream& os, dxvk::DxbcExtOpcode e); std::ostream& operator << (std::ostream& os, dxvk::DxbcOperandType e); std::ostream& operator << (std::ostream& os, dxvk::DxbcOperandExt e); std::ostream& operator << (std::ostream& os, dxvk::DxbcComponentCount e); -std::ostream& operator << (std::ostream& os, dxvk::DxbcComponentSelectionMode e); +std::ostream& operator << (std::ostream& os, dxvk::DxbcRegMode e); std::ostream& operator << (std::ostream& os, dxvk::DxbcOperandIndexRepresentation e); std::ostream& operator << (std::ostream& os, dxvk::DxbcResourceDim e); std::ostream& operator << (std::ostream& os, dxvk::DxbcResourceReturnType e); diff --git a/src/dxbc/dxbc_type.cpp b/src/dxbc/dxbc_type.cpp deleted file mode 100644 index ad68bfd79..000000000 --- a/src/dxbc/dxbc_type.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "dxbc_type.h" - -namespace dxvk { - - DxbcComponentSwizzle DxbcComponentSwizzle::extract(DxbcComponentMask mask) const { - DxbcComponentSwizzle result; - - uint32_t j = 0; - for (uint32_t i = 0; i < m_components.size(); i++) { - if (mask.test(i)) - result[j++] = m_components.at(i); - } - - return result; - } - -} \ No newline at end of file diff --git a/src/dxbc/dxbc_type.h b/src/dxbc/dxbc_type.h deleted file mode 100644 index a6b652bc3..000000000 --- a/src/dxbc/dxbc_type.h +++ /dev/null @@ -1,165 +0,0 @@ -#pragma once - -#include "dxbc_include.h" - -namespace dxvk { - - /** - * \brief Scalar value type - * - * Enumerates possible register component - * types. Scalar types are represented as - * a one-component vector type. - */ - enum class DxbcScalarType { - Uint32 = 0, - Uint64 = 1, - Sint32 = 2, - Sint64 = 3, - Float32 = 4, - Float64 = 5, - }; - - - /** - * \brief Vector value type - * - * Vector type definition that stores the scalar - * component type and the number of components. - */ - struct DxbcValueType { - DxbcValueType() { } - DxbcValueType(DxbcScalarType s, uint32_t c) - : DxbcValueType(s, c, 0) { } - DxbcValueType(DxbcScalarType s, uint32_t c, uint32_t e) - : componentType(s), componentCount(c), elementCount(e) { } - - DxbcScalarType componentType = DxbcScalarType::Uint32; - uint32_t componentCount = 0; - uint32_t elementCount = 0; - }; - - - /** - * \brief Value - * - * Stores the type and SPIR-V ID of an expression - * result that can be used as an operand value. - */ - struct DxbcValue { - DxbcValueType type; - uint32_t valueId = 0; - }; - - - /** - * \brief Pointer type - * - * Stores the type of data that the pointer will - * point to, as well as the storage class of the - * SPIR-V object. - */ - struct DxbcPointerType { - DxbcPointerType() { } - DxbcPointerType( - DxbcValueType p_valueType, - spv::StorageClass p_storageClass) - : valueType (p_valueType), - storageClass(p_storageClass) { } - - DxbcValueType valueType; - spv::StorageClass storageClass = spv::StorageClassGeneric; - }; - - - /** - * \brief Pointer - * - * Stores the SPIR-V ID of a pointer value and - * the type of the pointer, including its storage - * class. Can be used as a memory operand. - */ - struct DxbcPointer { - DxbcPointerType type; - uint32_t valueId = 0; - }; - - - /** - * \brief Component mask - */ - class DxbcComponentMask { - - public: - - DxbcComponentMask() { } - DxbcComponentMask(uint32_t mask) - : m_mask(mask) { } - DxbcComponentMask(bool x, bool y, bool z, bool w) - : m_mask((x ? 1 : 0) | (y ? 2 : 0) | (z ? 4 : 0) | (w ? 8 : 0)) { } - - void set(uint32_t id) { m_mask |= bit(id); } - void clr(uint32_t id) { m_mask &= ~bit(id); } - - bool test(uint32_t id) const { - return !!(m_mask & bit(id)); - } - - uint32_t componentCount() const { - return bit::popcnt(m_mask); - } - - uint32_t firstComponent() const { - return bit::tzcnt(m_mask); - } - - DxbcComponentMask operator ~ () const { return (~m_mask) & 0xF; } - - DxbcComponentMask operator & (const DxbcComponentMask& other) const { return m_mask & other.m_mask; } - DxbcComponentMask operator | (const DxbcComponentMask& other) const { return m_mask | other.m_mask; } - - bool operator == (const DxbcComponentMask& other) const { return m_mask == other.m_mask; } - bool operator != (const DxbcComponentMask& other) const { return m_mask != other.m_mask; } - - operator bool () const { - return m_mask != 0; - } - - private: - - uint32_t m_mask = 0; - - uint32_t bit(uint32_t id) const { - return 1u << id; - } - - }; - - /** - * \brief Component swizzle - */ - class DxbcComponentSwizzle { - - public: - - DxbcComponentSwizzle() - : DxbcComponentSwizzle(0, 1, 2, 3) { } - DxbcComponentSwizzle(uint32_t x, uint32_t y, uint32_t z, uint32_t w) - : m_components {{ x, y, z, w }} { } - - uint32_t operator [] (uint32_t id) const { return m_components.at(id); } - uint32_t& operator [] (uint32_t id) { return m_components.at(id); } - - const uint32_t* operator & () const { - return m_components.data(); - } - - DxbcComponentSwizzle extract(DxbcComponentMask mask) const; - - private: - - std::array m_components; - - }; - -} \ No newline at end of file diff --git a/src/dxbc/meson.build b/src/dxbc/meson.build index 91f124950..c9948f7bd 100644 --- a/src/dxbc/meson.build +++ b/src/dxbc/meson.build @@ -9,7 +9,6 @@ dxbc_src = files([ 'dxbc_module.cpp', 'dxbc_names.cpp', 'dxbc_reader.cpp', - 'dxbc_type.cpp', 'dxbc_util.cpp', ])