mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-29 10:24:10 +01:00
[dxbc] Separate code generator classed for each shader type
This commit is contained in:
parent
403ab75aeb
commit
43dfba2287
@ -1,13 +1,10 @@
|
||||
#include "dxbc_compiler.h"
|
||||
#include "dxbc_names.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
DxbcCompiler::DxbcCompiler(
|
||||
DxbcProgramVersion version)
|
||||
: m_version(version) {
|
||||
|
||||
}
|
||||
const DxbcProgramVersion& version)
|
||||
: m_gen(DxbcCodeGen::create(version)) { }
|
||||
|
||||
|
||||
DxbcCompiler::~DxbcCompiler() {
|
||||
@ -16,13 +13,58 @@ namespace dxvk {
|
||||
|
||||
|
||||
void DxbcCompiler::processInstruction(const DxbcInstruction& ins) {
|
||||
const DxbcOpcodeToken token = ins.token();
|
||||
|
||||
switch (token.opcode()) {
|
||||
case DxbcOpcode::DclGlobalFlags:
|
||||
return this->dclGlobalFlags(ins);
|
||||
|
||||
case DxbcOpcode::DclInput:
|
||||
case DxbcOpcode::DclInputSiv:
|
||||
case DxbcOpcode::DclInputSgv:
|
||||
case DxbcOpcode::DclInputPs:
|
||||
case DxbcOpcode::DclInputPsSiv:
|
||||
case DxbcOpcode::DclInputPsSgv:
|
||||
return this->dclInput(ins);
|
||||
|
||||
case DxbcOpcode::DclOutput:
|
||||
case DxbcOpcode::DclOutputSiv:
|
||||
case DxbcOpcode::DclOutputSgv:
|
||||
return this->dclOutput(ins);
|
||||
|
||||
case DxbcOpcode::DclTemps:
|
||||
return this->dclTemps(ins);
|
||||
|
||||
default:
|
||||
Logger::err(str::format(
|
||||
"DxbcCompiler::processInstruction: Unhandled opcode: ",
|
||||
token.opcode()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkShader> DxbcCompiler::finalize() {
|
||||
return new DxvkShader(m_version.shaderStage(),
|
||||
m_module.compile(), 0, nullptr);
|
||||
return m_gen->finalize();
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::dclGlobalFlags(const DxbcInstruction& ins) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::dclInput(const DxbcInstruction& ins) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::dclOutput(const DxbcInstruction& ins) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::dclTemps(const DxbcInstruction& ins) {
|
||||
m_gen->dclTemps(ins.arg(0));
|
||||
}
|
||||
|
||||
}
|
@ -1,49 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "dxbc_chunk_isgn.h"
|
||||
#include "dxbc_chunk_shex.h"
|
||||
#include "dxbc_names.h"
|
||||
#include "dxbc_type.h"
|
||||
|
||||
#include "../spirv/spirv_module.h"
|
||||
#include "./gen/dxbc_gen_common.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief DXBC to SPIR-V compiler
|
||||
* \brief DXBC compiler
|
||||
*
|
||||
* Interprets DXBC instructions and generates
|
||||
* SPIR-V code for the appropriate shader type.
|
||||
*/
|
||||
class DxbcCompiler {
|
||||
|
||||
public:
|
||||
|
||||
DxbcCompiler(
|
||||
DxbcProgramVersion version);
|
||||
const DxbcProgramVersion& version);
|
||||
~DxbcCompiler();
|
||||
|
||||
DxbcCompiler (DxbcCompiler&&) = delete;
|
||||
DxbcCompiler& operator = (DxbcCompiler&&) = delete;
|
||||
|
||||
/**
|
||||
* \brief Processes a single instruction
|
||||
*
|
||||
* \param [in] ins The instruction
|
||||
* \returns \c true on success
|
||||
*/
|
||||
void processInstruction(
|
||||
const DxbcInstruction& ins);
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
/**
|
||||
* \brief Creates actual shader object
|
||||
*
|
||||
* Combines all information gatherd during the
|
||||
* shader compilation into one shader object.
|
||||
*/
|
||||
Rc<DxvkShader> finalize();
|
||||
|
||||
private:
|
||||
|
||||
DxbcProgramVersion m_version;
|
||||
SpirvModule m_module;
|
||||
Rc<DxbcCodeGen> m_gen;
|
||||
|
||||
void dclGlobalFlags(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
void dclInput(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
void dclOutput(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
void dclTemps(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
};
|
||||
|
||||
|
@ -527,6 +527,19 @@ namespace dxvk {
|
||||
return m_args.getWord(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reads an argument enum
|
||||
*
|
||||
* Casts the word at the given location to an enum.
|
||||
* Some instructions take name tokens as operands.
|
||||
* \param [in] idx Argument word index
|
||||
* \returns The enum value of the given word
|
||||
*/
|
||||
template<typename T>
|
||||
T readEnum(uint32_t idx) const {
|
||||
return static_cast<T>(arg(idx));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves an operand
|
||||
*
|
||||
|
@ -45,13 +45,6 @@ namespace dxvk {
|
||||
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
|
||||
|
||||
DxbcCompiler compiler(m_shexChunk->version());
|
||||
|
||||
// if (m_isgnChunk != nullptr)
|
||||
// compiler.declareInputSignature(*m_isgnChunk);
|
||||
|
||||
// if (m_osgnChunk != nullptr)
|
||||
// compiler.declareOutputSignature(*m_osgnChunk);
|
||||
|
||||
for (auto ins : *m_shexChunk)
|
||||
compiler.processInstruction(ins);
|
||||
return compiler.finalize();
|
||||
|
@ -390,3 +390,16 @@ std::ostream& operator << (std::ostream& os, DxbcSystemValue e) {
|
||||
ENUM_DEFAULT(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator << (std::ostream& os, dxvk::DxbcProgramType e) {
|
||||
switch (e) {
|
||||
ENUM_NAME(DxbcProgramType::PixelShader);
|
||||
ENUM_NAME(DxbcProgramType::VertexShader);
|
||||
ENUM_NAME(DxbcProgramType::GeometryShader);
|
||||
ENUM_NAME(DxbcProgramType::HullShader);
|
||||
ENUM_NAME(DxbcProgramType::DomainShader);
|
||||
ENUM_NAME(DxbcProgramType::ComputeShader);
|
||||
ENUM_DEFAULT(e);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "dxbc_common.h"
|
||||
#include "dxbc_enums.h"
|
||||
|
||||
std::ostream& operator << (std::ostream& os, dxvk::DxbcOpcode e);
|
||||
@ -15,3 +16,4 @@ std::ostream& operator << (std::ostream& os, dxvk::DxbcResourceReturnType e);
|
||||
std::ostream& operator << (std::ostream& os, dxvk::DxbcRegisterComponentType e);
|
||||
std::ostream& operator << (std::ostream& os, dxvk::DxbcInstructionReturnType e);
|
||||
std::ostream& operator << (std::ostream& os, dxvk::DxbcSystemValue e);
|
||||
std::ostream& operator << (std::ostream& os, dxvk::DxbcProgramType e);
|
||||
|
@ -14,12 +14,4 @@ namespace dxvk {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
DxbcComponentMask DxbcComponentSwizzle::mask(uint32_t n) const {
|
||||
DxbcComponentMask mask;
|
||||
for (uint32_t i = 0; i < n; i++)
|
||||
mask.set(m_components.at(i));
|
||||
return mask;
|
||||
}
|
||||
|
||||
}
|
@ -30,10 +30,13 @@ namespace dxvk {
|
||||
struct DxbcValueType {
|
||||
DxbcValueType() { }
|
||||
DxbcValueType(DxbcScalarType s, uint32_t c)
|
||||
: componentType(s), componentCount(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;
|
||||
};
|
||||
|
||||
|
||||
@ -44,17 +47,7 @@ namespace dxvk {
|
||||
* result that can be used as an operand value.
|
||||
*/
|
||||
struct DxbcValue {
|
||||
DxbcValue() { }
|
||||
DxbcValue(
|
||||
DxbcValueType p_type,
|
||||
uint32_t p_typeId,
|
||||
uint32_t p_valueId)
|
||||
: type (p_type),
|
||||
typeId (p_typeId),
|
||||
valueId (p_valueId) { }
|
||||
|
||||
DxbcValueType type;
|
||||
uint32_t typeId = 0;
|
||||
uint32_t valueId = 0;
|
||||
};
|
||||
|
||||
@ -87,20 +80,11 @@ namespace dxvk {
|
||||
* class. Can be used as a memory operand.
|
||||
*/
|
||||
struct DxbcPointer {
|
||||
DxbcPointer() { }
|
||||
DxbcPointer(
|
||||
DxbcPointerType p_type,
|
||||
uint32_t p_typeId,
|
||||
uint32_t p_valueId)
|
||||
: type (p_type),
|
||||
typeId (p_typeId),
|
||||
valueId (p_valueId) { }
|
||||
|
||||
DxbcPointerType type;
|
||||
uint32_t typeId = 0;
|
||||
uint32_t valueId = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Component mask
|
||||
*/
|
||||
@ -172,8 +156,6 @@ namespace dxvk {
|
||||
|
||||
DxbcComponentSwizzle extract(DxbcComponentMask mask) const;
|
||||
|
||||
DxbcComponentMask mask(uint32_t n) const;
|
||||
|
||||
private:
|
||||
|
||||
std::array<uint32_t, 4> m_components;
|
||||
|
120
src/dxbc/gen/dxbc_gen_common.cpp
Normal file
120
src/dxbc/gen/dxbc_gen_common.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
#include "dxbc_gen_common.h"
|
||||
#include "dxbc_gen_vertex.h"
|
||||
|
||||
#include "../dxbc_names.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
DxbcCodeGen::DxbcCodeGen() {
|
||||
m_module.enableCapability(spv::CapabilityShader);
|
||||
m_module.setMemoryModel(
|
||||
spv::AddressingModelLogical,
|
||||
spv::MemoryModelGLSL450);
|
||||
m_entryPointId = m_module.allocateId();
|
||||
}
|
||||
|
||||
|
||||
DxbcCodeGen::~DxbcCodeGen() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DxbcCodeGen::dclTemps(uint32_t n) {
|
||||
const uint32_t oldSize = m_rRegs.size();
|
||||
|
||||
if (n > oldSize) {
|
||||
m_rRegs.resize(n);
|
||||
|
||||
DxbcPointer reg;
|
||||
reg.type = DxbcPointerType(
|
||||
DxbcValueType(DxbcScalarType::Float32, 4),
|
||||
spv::StorageClassPrivate);
|
||||
|
||||
const uint32_t typeId = this->defPointerType(reg.type);
|
||||
|
||||
for (uint32_t i = oldSize; i < n; i++) {
|
||||
reg.valueId = m_module.newVar(typeId, spv::StorageClassPrivate);
|
||||
m_module.setDebugName(reg.valueId, str::format("r", i).c_str());
|
||||
m_rRegs.at(i) = reg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Rc<DxbcCodeGen> DxbcCodeGen::create(
|
||||
const DxbcProgramVersion& version) {
|
||||
switch (version.type()) {
|
||||
case DxbcProgramType::VertexShader:
|
||||
return new DxbcVsCodeGen();
|
||||
|
||||
default:
|
||||
throw DxvkError(str::format(
|
||||
"DxbcCodeGen::create: Unsupported program type: ",
|
||||
version.type()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t DxbcCodeGen::defScalarType(DxbcScalarType type) {
|
||||
switch (type) {
|
||||
case DxbcScalarType::Uint32 : return m_module.defIntType(32, 0);
|
||||
case DxbcScalarType::Uint64 : return m_module.defIntType(64, 0);
|
||||
case DxbcScalarType::Sint32 : return m_module.defIntType(32, 1);
|
||||
case DxbcScalarType::Sint64 : return m_module.defIntType(64, 1);
|
||||
case DxbcScalarType::Float32: return m_module.defFloatType(32);
|
||||
case DxbcScalarType::Float64: return m_module.defFloatType(64);
|
||||
|
||||
default:
|
||||
throw DxvkError("DxbcCodeGen::defScalarType: Invalid scalar type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t DxbcCodeGen::defValueType(const DxbcValueType& type) {
|
||||
uint32_t typeId = this->defScalarType(type.componentType);
|
||||
|
||||
if (type.componentCount > 1)
|
||||
typeId = m_module.defVectorType(typeId, type.componentCount);
|
||||
|
||||
if (type.elementCount > 0)
|
||||
typeId = m_module.defArrayType(typeId, m_module.constu32(type.elementCount));
|
||||
|
||||
return typeId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t DxbcCodeGen::defPointerType(const DxbcPointerType& type) {
|
||||
uint32_t valueTypeId = this->defValueType(type.valueType);
|
||||
return m_module.defPointerType(valueTypeId, type.storageClass);
|
||||
}
|
||||
|
||||
|
||||
uint32_t DxbcCodeGen::defPerVertexBlock() {
|
||||
uint32_t s1f32 = this->defScalarType(DxbcScalarType::Float32);
|
||||
uint32_t v4f32 = this->defValueType(DxbcValueType(DxbcScalarType::Float32, 4, 0));
|
||||
uint32_t a2f32 = this->defValueType(DxbcValueType(DxbcScalarType::Float32, 1, 2));
|
||||
|
||||
std::array<uint32_t, 4> members;
|
||||
members[PerVertex_Position] = v4f32;
|
||||
members[PerVertex_PointSize] = s1f32;
|
||||
members[PerVertex_CullDist] = a2f32;
|
||||
members[PerVertex_ClipDist] = a2f32;
|
||||
|
||||
uint32_t typeId = m_module.defStructType(
|
||||
members.size(), members.data());
|
||||
|
||||
m_module.memberDecorateBuiltIn(typeId, PerVertex_Position, spv::BuiltInPosition);
|
||||
m_module.memberDecorateBuiltIn(typeId, PerVertex_PointSize, spv::BuiltInPointSize);
|
||||
m_module.memberDecorateBuiltIn(typeId, PerVertex_CullDist, spv::BuiltInCullDistance);
|
||||
m_module.memberDecorateBuiltIn(typeId, PerVertex_ClipDist, spv::BuiltInClipDistance);
|
||||
m_module.decorateBlock(typeId);
|
||||
|
||||
m_module.setDebugName(typeId, "per_vertex");
|
||||
m_module.setDebugMemberName(typeId, PerVertex_Position, "position");
|
||||
m_module.setDebugMemberName(typeId, PerVertex_PointSize, "point_size");
|
||||
m_module.setDebugMemberName(typeId, PerVertex_CullDist, "cull_dist");
|
||||
m_module.setDebugMemberName(typeId, PerVertex_ClipDist, "clip_dist");
|
||||
return typeId;
|
||||
}
|
||||
|
||||
}
|
108
src/dxbc/gen/dxbc_gen_common.h
Normal file
108
src/dxbc/gen/dxbc_gen_common.h
Normal file
@ -0,0 +1,108 @@
|
||||
#pragma once
|
||||
|
||||
#include "../dxbc_common.h"
|
||||
#include "../dxbc_decoder.h"
|
||||
#include "../dxbc_type.h"
|
||||
|
||||
#include "../../spirv/spirv_module.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief System value mapping
|
||||
*
|
||||
* Maps a system value to a given set of
|
||||
* components of an input or output register.
|
||||
*/
|
||||
struct DxbcSvMapping {
|
||||
uint32_t regId;
|
||||
DxbcComponentMask regMask;
|
||||
DxbcSystemValue sv;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief DXBC code generator
|
||||
*
|
||||
* SPIR-V code generator. Implements simple micro ops that are
|
||||
* generated when parsing the DXBC shader code. Some of these
|
||||
* may require different implementations for each shader stage
|
||||
* and are therefore implemented in a sub class.
|
||||
*/
|
||||
class DxbcCodeGen : public RcObject {
|
||||
|
||||
public:
|
||||
|
||||
DxbcCodeGen();
|
||||
|
||||
virtual ~DxbcCodeGen();
|
||||
|
||||
/**
|
||||
* \brief Declares temporary registers
|
||||
* \param [in] n Number of temp registers
|
||||
*/
|
||||
void dclTemps(uint32_t n);
|
||||
|
||||
/**
|
||||
* \brief Declares an interface variable
|
||||
*
|
||||
* \param [in] regType Register type
|
||||
* \param [in] regId Interface register index
|
||||
* \param [in] regDim Array dimension of interface variable
|
||||
* \param [in] regMask Component mask for this declaration
|
||||
* \param [in] sv System value to map to the given components
|
||||
*/
|
||||
virtual void dclInterfaceVar(
|
||||
DxbcOperandType regType,
|
||||
uint32_t regId,
|
||||
uint32_t regDim,
|
||||
DxbcComponentMask regMask,
|
||||
DxbcSystemValue sv) = 0;
|
||||
|
||||
/**
|
||||
* \brief Finalizes shader
|
||||
*
|
||||
* Depending on the shader stage, this may generate
|
||||
* additional code to set up input variables, output
|
||||
* variables, and execute shader phases.
|
||||
* \returns DXVK shader module
|
||||
*/
|
||||
virtual Rc<DxvkShader> finalize() = 0;
|
||||
|
||||
/**
|
||||
* \brief Creates code generator for a given program type
|
||||
*
|
||||
* \param [in] version Program version
|
||||
* \returns The code generator
|
||||
*/
|
||||
static Rc<DxbcCodeGen> create(
|
||||
const DxbcProgramVersion& version);
|
||||
|
||||
protected:
|
||||
|
||||
constexpr static uint32_t PerVertex_Position = 0;
|
||||
constexpr static uint32_t PerVertex_PointSize = 1;
|
||||
constexpr static uint32_t PerVertex_CullDist = 2;
|
||||
constexpr static uint32_t PerVertex_ClipDist = 3;
|
||||
|
||||
SpirvModule m_module;
|
||||
|
||||
std::vector<uint32_t> m_entryPointInterfaces;
|
||||
uint32_t m_entryPointId = 0;
|
||||
|
||||
std::vector<DxbcPointer> m_rRegs;
|
||||
|
||||
uint32_t defScalarType(
|
||||
DxbcScalarType type);
|
||||
|
||||
uint32_t defValueType(
|
||||
const DxbcValueType& type);
|
||||
|
||||
uint32_t defPointerType(
|
||||
const DxbcPointerType& type);
|
||||
|
||||
uint32_t defPerVertexBlock();
|
||||
|
||||
};
|
||||
|
||||
}
|
38
src/dxbc/gen/dxbc_gen_vertex.cpp
Normal file
38
src/dxbc/gen/dxbc_gen_vertex.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include "dxbc_gen_vertex.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
DxbcVsCodeGen::DxbcVsCodeGen() {
|
||||
m_outPerVertex = m_module.newVar(
|
||||
m_module.defPointerType(this->defPerVertexBlock(), spv::StorageClassOutput),
|
||||
spv::StorageClassOutput);
|
||||
}
|
||||
|
||||
|
||||
DxbcVsCodeGen::~DxbcVsCodeGen() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DxbcVsCodeGen::dclInterfaceVar(
|
||||
DxbcOperandType regType,
|
||||
uint32_t regId,
|
||||
uint32_t regDim,
|
||||
DxbcComponentMask regMask,
|
||||
DxbcSystemValue sv) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkShader> DxbcVsCodeGen::finalize() {
|
||||
m_module.addEntryPoint(m_entryPointId,
|
||||
spv::ExecutionModelVertex, "main",
|
||||
m_entryPointInterfaces.size(),
|
||||
m_entryPointInterfaces.data());
|
||||
m_module.setDebugName(m_entryPointId, "main");
|
||||
|
||||
return new DxvkShader(VK_SHADER_STAGE_VERTEX_BIT,
|
||||
m_module.compile(), 0, nullptr);
|
||||
}
|
||||
|
||||
}
|
38
src/dxbc/gen/dxbc_gen_vertex.h
Normal file
38
src/dxbc/gen/dxbc_gen_vertex.h
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "dxbc_gen_common.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief Vertex shader code generator
|
||||
*/
|
||||
class DxbcVsCodeGen : public DxbcCodeGen {
|
||||
|
||||
public:
|
||||
|
||||
DxbcVsCodeGen();
|
||||
~DxbcVsCodeGen();
|
||||
|
||||
void dclInterfaceVar(
|
||||
DxbcOperandType regType,
|
||||
uint32_t regId,
|
||||
uint32_t regDim,
|
||||
DxbcComponentMask regMask,
|
||||
DxbcSystemValue sv);
|
||||
|
||||
Rc<DxvkShader> finalize() final;
|
||||
|
||||
private:
|
||||
|
||||
uint32_t m_outPerVertex = 0;
|
||||
|
||||
std::array<DxbcPointer, 32> m_vRegs;
|
||||
std::array<DxbcPointer, 32> m_oRegs;
|
||||
|
||||
std::vector<DxbcSvMapping> m_svInputs;
|
||||
std::vector<DxbcSvMapping> m_svOutputs;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -9,6 +9,9 @@ dxbc_src = files([
|
||||
'dxbc_names.cpp',
|
||||
'dxbc_reader.cpp',
|
||||
'dxbc_type.cpp',
|
||||
|
||||
'gen/dxbc_gen_common.cpp',
|
||||
'gen/dxbc_gen_vertex.cpp',
|
||||
])
|
||||
|
||||
dxbc_lib = static_library('dxbc', dxbc_src,
|
||||
|
@ -15,8 +15,7 @@ namespace dxvk {
|
||||
result.append(m_execModeInfo);
|
||||
result.append(m_debugNames);
|
||||
result.append(m_annotations);
|
||||
result.append(m_typeDefs);
|
||||
result.append(m_constDefs);
|
||||
result.append(m_typeConstDefs);
|
||||
result.append(m_variables);
|
||||
result.append(m_code);
|
||||
return result;
|
||||
@ -98,14 +97,25 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void SpirvModule::setDebugMemberName(
|
||||
uint32_t structId,
|
||||
uint32_t memberId,
|
||||
const char* debugName) {
|
||||
m_debugNames.putIns (spv::OpMemberName, 3 + m_debugNames.strLen(debugName));
|
||||
m_debugNames.putWord(structId);
|
||||
m_debugNames.putWord(memberId);
|
||||
m_debugNames.putStr (debugName);
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::constBool(
|
||||
bool v) {
|
||||
uint32_t typeId = this->defBoolType();
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_constDefs.putIns (v ? spv::OpConstantTrue : spv::OpConstantFalse, 3);
|
||||
m_constDefs.putWord (typeId);
|
||||
m_constDefs.putWord (resultId);
|
||||
m_typeConstDefs.putIns (v ? spv::OpConstantTrue : spv::OpConstantFalse, 3);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
@ -115,10 +125,10 @@ namespace dxvk {
|
||||
uint32_t typeId = this->defIntType(32, 1);
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_constDefs.putIns (spv::OpConstant, 4);
|
||||
m_constDefs.putWord (typeId);
|
||||
m_constDefs.putWord (resultId);
|
||||
m_constDefs.putInt32(v);
|
||||
m_typeConstDefs.putIns (spv::OpConstant, 4);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putInt32(v);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
@ -128,10 +138,10 @@ namespace dxvk {
|
||||
uint32_t typeId = this->defIntType(64, 1);
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_constDefs.putIns (spv::OpConstant, 5);
|
||||
m_constDefs.putWord (typeId);
|
||||
m_constDefs.putWord (resultId);
|
||||
m_constDefs.putInt64(v);
|
||||
m_typeConstDefs.putIns (spv::OpConstant, 5);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putInt64(v);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
@ -141,10 +151,10 @@ namespace dxvk {
|
||||
uint32_t typeId = this->defIntType(32, 0);
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_constDefs.putIns (spv::OpConstant, 4);
|
||||
m_constDefs.putWord (typeId);
|
||||
m_constDefs.putWord (resultId);
|
||||
m_constDefs.putInt32(v);
|
||||
m_typeConstDefs.putIns (spv::OpConstant, 4);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putInt32(v);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
@ -154,10 +164,10 @@ namespace dxvk {
|
||||
uint32_t typeId = this->defIntType(64, 0);
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_constDefs.putIns (spv::OpConstant, 5);
|
||||
m_constDefs.putWord (typeId);
|
||||
m_constDefs.putWord (resultId);
|
||||
m_constDefs.putInt64(v);
|
||||
m_typeConstDefs.putIns (spv::OpConstant, 5);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putInt64(v);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
@ -167,10 +177,10 @@ namespace dxvk {
|
||||
uint32_t typeId = this->defFloatType(32);
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_constDefs.putIns (spv::OpConstant, 4);
|
||||
m_constDefs.putWord (typeId);
|
||||
m_constDefs.putWord (resultId);
|
||||
m_constDefs.putFloat32(v);
|
||||
m_typeConstDefs.putIns (spv::OpConstant, 4);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putFloat32(v);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
@ -180,10 +190,10 @@ namespace dxvk {
|
||||
uint32_t typeId = this->defFloatType(64);
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_constDefs.putIns (spv::OpConstant, 5);
|
||||
m_constDefs.putWord (typeId);
|
||||
m_constDefs.putWord (resultId);
|
||||
m_constDefs.putFloat64(v);
|
||||
m_typeConstDefs.putIns (spv::OpConstant, 5);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
m_typeConstDefs.putFloat64(v);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
@ -194,16 +204,23 @@ namespace dxvk {
|
||||
const uint32_t* constIds) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_constDefs.putIns (spv::OpConstantComposite, 3 + constCount);
|
||||
m_constDefs.putWord (typeId);
|
||||
m_constDefs.putWord (resultId);
|
||||
m_typeConstDefs.putIns (spv::OpConstantComposite, 3 + constCount);
|
||||
m_typeConstDefs.putWord (typeId);
|
||||
m_typeConstDefs.putWord (resultId);
|
||||
|
||||
for (uint32_t i = 0; i < constCount; i++)
|
||||
m_constDefs.putWord(constIds[i]);
|
||||
m_typeConstDefs.putWord(constIds[i]);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
void SpirvModule::decorateBlock(uint32_t object) {
|
||||
m_annotations.putIns (spv::OpDecorate, 3);
|
||||
m_annotations.putWord (object);
|
||||
m_annotations.putWord (spv::DecorationBlock);
|
||||
}
|
||||
|
||||
|
||||
void SpirvModule::decorateBuiltIn(
|
||||
uint32_t object,
|
||||
spv::BuiltIn builtIn) {
|
||||
@ -234,6 +251,18 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void SpirvModule::memberDecorateBuiltIn(
|
||||
uint32_t structId,
|
||||
uint32_t memberId,
|
||||
spv::BuiltIn builtIn) {
|
||||
m_annotations.putIns (spv::OpMemberDecorate, 5);
|
||||
m_annotations.putWord (structId);
|
||||
m_annotations.putWord (memberId);
|
||||
m_annotations.putWord (spv::DecorationBuiltIn);
|
||||
m_annotations.putWord (builtIn);
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::defVoidType() {
|
||||
return this->defType(spv::OpTypeVoid, 0, nullptr);
|
||||
}
|
||||
@ -493,7 +522,7 @@ namespace dxvk {
|
||||
// Since the type info is stored in the code buffer,
|
||||
// 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_typeDefs) {
|
||||
for (auto ins : m_typeConstDefs) {
|
||||
bool match = ins.opCode() == op;
|
||||
|
||||
for (uint32_t i = 0; i < argCount && match; i++)
|
||||
@ -505,11 +534,11 @@ namespace dxvk {
|
||||
|
||||
// Type not yet declared, create a new one.
|
||||
uint32_t resultId = this->allocateId();
|
||||
m_typeDefs.putIns (op, 2 + argCount);
|
||||
m_typeDefs.putWord(resultId);
|
||||
m_typeConstDefs.putIns (op, 2 + argCount);
|
||||
m_typeConstDefs.putWord(resultId);
|
||||
|
||||
for (uint32_t i = 0; i < argCount; i++)
|
||||
m_typeDefs.putWord(argIds[i]);
|
||||
m_typeConstDefs.putWord(argIds[i]);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,11 @@ namespace dxvk {
|
||||
uint32_t expressionId,
|
||||
const char* debugName);
|
||||
|
||||
void setDebugMemberName(
|
||||
uint32_t structId,
|
||||
uint32_t memberId,
|
||||
const char* debugName);
|
||||
|
||||
uint32_t constBool(
|
||||
bool v);
|
||||
|
||||
@ -76,6 +81,9 @@ namespace dxvk {
|
||||
uint32_t constCount,
|
||||
const uint32_t* constIds);
|
||||
|
||||
void decorateBlock(
|
||||
uint32_t object);
|
||||
|
||||
void decorateBuiltIn(
|
||||
uint32_t object,
|
||||
spv::BuiltIn builtIn);
|
||||
@ -88,6 +96,11 @@ namespace dxvk {
|
||||
uint32_t object,
|
||||
uint32_t location);
|
||||
|
||||
void memberDecorateBuiltIn(
|
||||
uint32_t structId,
|
||||
uint32_t memberId,
|
||||
spv::BuiltIn builtIn);
|
||||
|
||||
uint32_t defVoidType();
|
||||
|
||||
uint32_t defBoolType();
|
||||
@ -188,8 +201,7 @@ namespace dxvk {
|
||||
SpirvCodeBuffer m_execModeInfo;
|
||||
SpirvCodeBuffer m_debugNames;
|
||||
SpirvCodeBuffer m_annotations;
|
||||
SpirvCodeBuffer m_typeDefs;
|
||||
SpirvCodeBuffer m_constDefs;
|
||||
SpirvCodeBuffer m_typeConstDefs;
|
||||
SpirvCodeBuffer m_variables;
|
||||
SpirvCodeBuffer m_code;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user