[dxbc] Initial xSGN chunk implementation

This commit is contained in:
Philip Rebohle 2017-11-01 00:01:40 +01:00
parent bc8cc76888
commit 72f353074f
13 changed files with 587 additions and 108 deletions

View File

@ -0,0 +1,39 @@
#include "dxbc_chunk_isgn.h"
namespace dxvk {
DxbcIsgn::DxbcIsgn(DxbcReader reader) {
uint32_t elementCount = reader.readu32();
reader.skip(sizeof(uint32_t));
std::array<DxbcScalarType, 4> componentTypes = {
DxbcScalarType::Uint32, DxbcScalarType::Uint32,
DxbcScalarType::Sint32, DxbcScalarType::Float32,
};
for (uint32_t i = 0; i < elementCount; i++) {
DxbcSgnEntry entry;
entry.semanticName = reader.clone(reader.readu32()).readString();
entry.semanticIndex = reader.readu32();
entry.systemValue = static_cast<DxbcSystemValue>(reader.readu32());
entry.componentType = componentTypes.at(reader.readu32());
entry.registerId = reader.readu32();
entry.componentMask = bit::extract(reader.readu32(), 0, 3);
Logger::info(str::format(
entry.semanticName, ",",
entry.semanticIndex, ",",
entry.systemValue, ",",
// entry.componentType, ",",
entry.registerId));
m_entries.push_back(entry);
}
}
DxbcIsgn::~DxbcIsgn() {
}
}

View File

@ -0,0 +1,45 @@
#pragma once
#include "dxbc_common.h"
#include "dxbc_decoder.h"
#include "dxbc_enums.h"
#include "dxbc_reader.h"
#include "dxbc_type.h"
namespace dxvk {
/**
* \brief Signature entry
*
* Stores the semantic name of an input or
* output and the corresponding register.
*/
struct DxbcSgnEntry {
std::string semanticName;
uint32_t semanticIndex;
uint32_t registerId;
DxbcComponentMask componentMask;
DxbcScalarType componentType;
DxbcSystemValue systemValue;
};
/**
* \brief Input/Output signature chunk
*
* Stores information about the input and
* output registers used by the shader stage.
*/
class DxbcIsgn : public RcObject {
public:
DxbcIsgn(DxbcReader reader);
~DxbcIsgn();
private:
std::vector<DxbcSgnEntry> m_entries;
};
}

View File

@ -2,8 +2,13 @@
namespace dxvk {
DxbcCompiler::DxbcCompiler(DxbcProgramVersion version)
: m_version(version) {
DxbcCompiler::DxbcCompiler(
DxbcProgramVersion version,
const Rc<DxbcIsgn>& inputSig,
const Rc<DxbcIsgn>& outputSig)
: m_version (version),
m_inputSig (inputSig),
m_outputSig (outputSig) {
m_entryPointId = m_module.allocateId();
this->declareCapabilities();
@ -15,6 +20,9 @@ namespace dxvk {
m_module.functionBegin(m_typeVoid,
m_entryPointId, m_typeFunction,
spv::FunctionControlMaskNone);
// TODO implement proper control flow
m_module.opLabel(m_module.allocateId());
}
@ -23,31 +31,33 @@ namespace dxvk {
}
bool DxbcCompiler::processInstruction(const DxbcInstruction& ins) {
void DxbcCompiler::processInstruction(const DxbcInstruction& ins) {
const DxbcOpcodeToken token = ins.token();
switch (token.opcode()) {
case DxbcOpcode::DclGlobalFlags:
return this->dclGlobalFlags(token.control());
return this->dclGlobalFlags(ins);
case DxbcOpcode::DclInput:
return this->dclInput(ins);
case DxbcOpcode::DclTemps:
return this->dclTemps(ins.arg(0));
case DxbcOpcode::DclOutputSiv:
return this->dclOutputSiv(ins);
case DxbcOpcode::DclThreadGroup: {
m_module.setLocalSize(
m_entryPointId,
ins.arg(0),
ins.arg(1),
ins.arg(2));
} return true;
case DxbcOpcode::DclTemps:
return this->dclTemps(ins);
case DxbcOpcode::DclThreadGroup:
return this->dclThreadGroup(ins);
case DxbcOpcode::Mov:
return this->opMov(ins);
case DxbcOpcode::Ret:
return this->opRet(ins);
default:
Logger::err(str::format("DXBC: unhandled instruction: ",
static_cast<uint32_t>(token.opcode())));
return false;
throw DxvkError(str::format("DXBC: Unhandled instruction: ", ins.token().opcode()));
}
}
@ -91,7 +101,9 @@ namespace dxvk {
}
bool DxbcCompiler::dclGlobalFlags(DxbcGlobalFlags flags) {
void DxbcCompiler::dclGlobalFlags(const DxbcInstruction& ins) {
const DxbcGlobalFlags flags(ins.token().control());
if (!flags.test(DxbcGlobalFlag::RefactoringAllowed))
m_useRestrictedMath = true;
@ -103,37 +115,167 @@ namespace dxvk {
// Raw and structured buffers are supported regardless
// of whether the corresponding flag is set or not.
return true;
}
bool DxbcCompiler::dclInput(const DxbcInstruction& ins) {
// const DxbcOperand operand = ins.operand(0);
// const DxbcOperandToken token = operand.token();
void DxbcCompiler::dclInput(const DxbcInstruction& ins) {
const DxbcOperand operand = ins.operand(0);
const DxbcOperandToken token = operand.token();
Logger::err("DXBC: dcl_input: Not implemented yet");
return false;
}
bool DxbcCompiler::dclTemps(uint32_t n) {
void DxbcCompiler::dclOutputSiv(const DxbcInstruction& ins) {
Logger::err("DXBC: dclOutputSiv: Not implemented yet");
}
void DxbcCompiler::dclTemps(const DxbcInstruction& ins) {
// Temporaries are treated as untyped 4x32-bit vectors.
uint32_t u32Type = m_module.defIntType(32, 0);
uint32_t regType = m_module.defVectorType(u32Type, 4);
uint32_t ptrType = m_module.defPointerType(regType, spv::StorageClassPrivate);
const DxbcValueType regType(DxbcScalarType::Uint32, 4);
const DxbcPointerType ptrType(regType, spv::StorageClassPrivate);
const uint32_t ptrTypeId = this->getPointerTypeId(ptrType);
for (uint32_t i = 0; i < n; i++) {
DxbcRegTypeR reg;
reg.varType = regType;
reg.ptrType = ptrType;
reg.varId = m_module.newVar(ptrType, spv::StorageClassPrivate);
for (uint32_t i = 0; i < ins.arg(0); i++) {
DxbcPointer reg;
reg.type = ptrType;
reg.typeId = ptrTypeId;
reg.valueId = m_module.newVar(ptrTypeId, spv::StorageClassPrivate);
m_rRegs.push_back(reg);
m_module.setDebugName(reg.varId,
m_module.setDebugName(reg.valueId,
str::format("r", i).c_str());
}
}
void DxbcCompiler::dclThreadGroup(const DxbcInstruction& ins) {
m_module.setLocalSize(m_entryPointId,
ins.arg(0), ins.arg(1), ins.arg(2));
}
void DxbcCompiler::opMov(const DxbcInstruction& ins) {
const DxbcOperand dstOp = ins.operand(0);
const DxbcOperand srcOp = ins.operand(dstOp.length());
DxbcValueType dstType(DxbcScalarType::Uint32, 1);
this->loadOperand(srcOp, dstType);
Logger::err("DXBC: mov: Not implemented yet");
}
void DxbcCompiler::opRet(const DxbcInstruction& ins) {
// TODO implement proper control flow
m_module.opReturn();
}
uint32_t DxbcCompiler::getScalarTypeId(const 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);
}
throw DxvkError("DXBC: Invalid scalar type");
}
uint32_t DxbcCompiler::getValueTypeId(const DxbcValueType& type) {
const uint32_t scalarTypeId = this->getScalarTypeId(type.componentType);
return type.componentCount > 1
? m_module.defVectorType(scalarTypeId, type.componentCount)
: scalarTypeId;
}
uint32_t DxbcCompiler::getPointerTypeId(const DxbcPointerType& type) {
return m_module.defPointerType(
this->getValueTypeId(type.valueType),
type.storageClass);
}
DxbcValue DxbcCompiler::loadPointer(const DxbcPointer& pointer) {
DxbcValue result;
result.type = pointer.type.valueType;
result.typeId = this->getValueTypeId(result.type);
result.valueId = m_module.opLoad(result.typeId, pointer.valueId);
return result;
}
DxbcValue DxbcCompiler::loadOperand(
const DxbcOperand& operand,
const DxbcValueType& type) {
const DxbcOperandToken token = operand.token();
DxbcValue result;
switch (token.type()) {
case DxbcOperandType::Imm32: {
const uint32_t componentCount = token.numComponents();
result.type = DxbcValueType(DxbcScalarType::Uint32, componentCount);
result.typeId = this->getValueTypeId(result.type);
if (componentCount == 1) {
result.valueId = m_module.constu32(operand.imm32(0));
} else {
std::array<uint32_t, 4> constIds;
for (uint32_t i = 0; i < componentCount; i++)
constIds.at(i) = m_module.constu32(operand.imm32(i));
result.valueId = m_module.constComposite(
result.typeId, componentCount, constIds.data());
}
} break;
case DxbcOperandType::Temp: {
const DxbcOperandIndex index = operand.index(0);
result = this->loadPointer(m_rRegs.at(index.immPart()));
} break;
case DxbcOperandType::Input: {
const DxbcOperandIndex index = operand.index(0);
result = this->loadPointer(m_vRegs.at(index.immPart()));
} break;
case DxbcOperandType::Output: {
const DxbcOperandIndex index = operand.index(0);
result = this->loadPointer(m_oRegs.at(index.immPart()));
} break;
default:
throw DxvkError(str::format(
"DxbcCompiler::loadOperandRegister: Unhandled operand type: ",
token.type()));
}
return result;
}
void DxbcCompiler::storePointer(
const DxbcPointer& pointer,
const DxbcValue& value) {
m_module.opStore(pointer.valueId, value.valueId);
}
void DxbcCompiler::storeOperand(
const DxbcOperand& operand,
const DxbcValueType& srcType,
uint32_t srcValue) {
return true;
}
}

View File

@ -1,44 +1,25 @@
#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"
namespace dxvk {
struct DxbcRegTypeR {
uint32_t varType;
uint32_t ptrType;
uint32_t varId;
};
struct DxbcValueType {
spv::Op componentType = spv::OpTypeVoid;
uint32_t componentWidth = 0;
uint32_t componentSigned = 0;
uint32_t componentCount = 0;
};
struct DxbcValue {
DxbcValueType type;
uint32_t typeId;
uint32_t valueId;
};
/**
* \brief DXBC to SPIR-V compiler
*
*
*/
class DxbcCompiler {
public:
DxbcCompiler(DxbcProgramVersion version);
DxbcCompiler(
DxbcProgramVersion version,
const Rc<DxbcIsgn>& inputSig,
const Rc<DxbcIsgn>& outputSig);
~DxbcCompiler();
DxbcCompiler (DxbcCompiler&&) = delete;
@ -50,7 +31,7 @@ namespace dxvk {
* \param [in] ins The instruction
* \returns \c true on success
*/
bool processInstruction(
void processInstruction(
const DxbcInstruction& ins);
/**
@ -66,8 +47,13 @@ namespace dxvk {
DxbcProgramVersion m_version;
SpirvModule m_module;
Rc<DxbcIsgn> m_inputSig;
Rc<DxbcIsgn> m_outputSig;
std::vector<uint32_t> m_interfaces;
std::vector<DxbcRegTypeR> m_rRegs;
std::vector<DxbcPointer> m_rRegs; // Temps
std::vector<DxbcPointer> m_vRegs; // Input registers
std::vector<DxbcPointer> m_oRegs; // Output registers
uint32_t m_entryPointId = 0;
@ -76,13 +62,37 @@ namespace dxvk {
bool m_useRestrictedMath = false;
void declareCapabilities();
void declareMemoryModel();
bool dclGlobalFlags(DxbcGlobalFlags flags);
bool dclInput(const DxbcInstruction& ins);
bool dclTemps(uint32_t n);
void dclGlobalFlags(const DxbcInstruction& ins);
void dclInput(const DxbcInstruction& ins);
void dclOutputSiv(const DxbcInstruction& ins);
void dclTemps(const DxbcInstruction& ins);
void dclThreadGroup(const DxbcInstruction& ins);
void opMov(const DxbcInstruction& ins);
void opRet(const DxbcInstruction& ins);
uint32_t getScalarTypeId(const DxbcScalarType& type);
uint32_t getValueTypeId(const DxbcValueType& type);
uint32_t getPointerTypeId(const DxbcPointerType& type);
DxbcValue loadPointer(
const DxbcPointer& pointer);
DxbcValue loadOperand(
const DxbcOperand& operand,
const DxbcValueType& type);
void storePointer(
const DxbcPointer& pointer,
const DxbcValue& value);
void storeOperand(
const DxbcOperand& operand,
const DxbcValueType& srcType,
uint32_t srcValue);
};

View File

@ -114,16 +114,10 @@ namespace dxvk {
// Immediate operands
uint32_t length = 0;
uint32_t componentCount = 0;
switch (token.numComponents()) {
case DxbcOperandNumComponents::Component0: componentCount = 0; break;
case DxbcOperandNumComponents::Component1: componentCount = 1; break;
case DxbcOperandNumComponents::Component4: componentCount = 4; break;
}
if (token.type() == DxbcOperandType::Imm32) length += 1 * componentCount;
if (token.type() == DxbcOperandType::Imm64) length += 2 * componentCount;
if (token.type() == DxbcOperandType::Imm32
|| token.type() == DxbcOperandType::Imm64)
length += token.numComponents();
// Indices into the register file, may contain additional operands
for (uint32_t i = 0; i < token.indexDimension(); i++) {

View File

@ -10,6 +10,21 @@ namespace dxvk {
class DxbcOperand;
/**
* \brief Component swizzle
*/
struct DxbcComponentSwizzle {
DxbcComponentName x;
DxbcComponentName y;
DxbcComponentName z;
DxbcComponentName w;
};
/**
* \brief Component mask
*/
using DxbcComponentMask = Flags<DxbcComponentName>;
/**
* \brief DXBC instruction token
*
@ -161,9 +176,9 @@ namespace dxvk {
* has. Can be zero, one, or four.
* \returns Number of components
*/
DxbcOperandNumComponents numComponents() const {
return static_cast<DxbcOperandNumComponents>(
bit::extract(m_token, 0, 1));
uint32_t numComponents() const {
std::array<uint32_t, 3> count = { 0, 1, 4 };
return count.at(bit::extract(m_token, 0, 1));
}
/**
@ -174,11 +189,48 @@ namespace dxvk {
* a given set of components is used.
* \returns Component selection mode
*/
DxbcOperandComponentSelectionMode selectionMode() const {
return static_cast<DxbcOperandComponentSelectionMode>(
DxbcComponentSelectionMode selectionMode() const {
return static_cast<DxbcComponentSelectionMode>(
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 swizzle
*
* Used when the component selection mode is
* \c DxbcComponentSelectionMode::Swizzle.
* \returns The component swizzle
*/
DxbcComponentSwizzle componentSwizzle() const {
return DxbcComponentSwizzle {
static_cast<DxbcComponentName>(bit::extract(m_token, 4, 5)),
static_cast<DxbcComponentName>(bit::extract(m_token, 6, 7)),
static_cast<DxbcComponentName>(bit::extract(m_token, 8, 9)),
static_cast<DxbcComponentName>(bit::extract(m_token, 10, 11)) };
}
/**
* \brief Component selection
*
* Used when the component selection mode is
* \c DxbcComponentSelectionMode::Select1.
*/
DxbcComponentName componentSelection() const {
return static_cast<DxbcComponentName>(
bit::extract(m_token, 4, 5));
}
/**
* \brief Operand type
*
@ -404,6 +456,28 @@ namespace dxvk {
std::optional<DxbcOperandTokenExt> queryOperandExt(
DxbcOperandExt ext) const;
/**
* \brief Reads 32-bit immediate integer
*
* \param [in] idx Component index
* \returns The immediate operand
*/
uint32_t imm32(uint32_t idx) const {
return m_data.getWord(idx);
}
/**
* \brief Reads 64-bit immediate integer
*
* \param [in] idx Component index
* \returns The immediate operand
*/
uint64_t imm64(uint32_t idx) const {
uint64_t hi = m_data.getWord(2 * idx + 0);
uint64_t lo = m_data.getWord(2 * idx + 1);
return (hi << 32) | (lo);
}
private:
DxbcCodeReader m_info;

View File

@ -164,9 +164,9 @@ namespace dxvk {
DclHsForkPhaseInstanceCount = 153,
DclHsJoinPhaseInstanceCount = 154,
DclThreadGroup = 155,
DclUnorderedAccessViewTyped = 156,
DclUnorderedAccessViewRaw = 157,
DclUnorderedAccessViewStructured = 158,
DclUavTyped = 156,
DclUavRaw = 157,
DclUavStructured = 158,
DclThreadGroupSharedMemoryRaw = 159,
DclThreadGroupSharedMemoryStructured = 160,
DclResourceRaw = 161,
@ -286,7 +286,7 @@ namespace dxvk {
* Used by operands to determine whether the
* operand has one, four or zero components.
*/
enum class DxbcOperandNumComponents : uint32_t {
enum class DxbcComponentCount : uint32_t {
Component0 = 0,
Component1 = 1,
Component4 = 2,
@ -300,7 +300,7 @@ namespace dxvk {
* component selection mode deterines which
* components are used for the operation.
*/
enum class DxbcOperandComponentSelectionMode : uint32_t {
enum class DxbcComponentSelectionMode : uint32_t {
Mask = 0,
Swizzle = 1,
Select1 = 2,
@ -311,7 +311,7 @@ namespace dxvk {
* \brief Component name
* Used for component selection.
*/
enum class DxbcOperandComponentName : uint32_t {
enum class DxbcComponentName : uint32_t {
X = 0, Y = 1, Z = 2, W = 3,
};
@ -398,6 +398,32 @@ namespace dxvk {
};
enum class DxbcSystemValue : uint32_t {
None = 0,
Position = 1,
ClipDistance = 2,
CullDistance = 3,
RenderTargetId = 4,
ViewportId = 5,
VertexId = 6,
PrimitiveId = 7,
InstanceId = 8,
IsFrontFace = 9,
SampleIndex = 10,
FinalQuadEdgeTessFactor = 11,
FinalQuadInsideTessFactor = 12,
FinalTriEdgeTessFactor = 13,
FinalTriInsideTessFactor = 14,
FinalLineDetailTessFactor = 15,
FinalLineDensityTessFactor = 16,
Target = 64,
Depth = 65,
Coverage = 66,
DepthGe = 67,
DepthLe = 68
};
enum class DxbcGlobalFlag : uint32_t {
RefactoringAllowed = 0,
DoublePrecision = 1,

View File

@ -14,12 +14,23 @@ namespace dxvk {
// The chunk size follows right after the four-character
// code. This does not include the eight bytes that are
// consumed by the FourCC and chunk length entry.
auto chunkLength = chunkReader.readu32() + 8;
chunkReader = chunkReader.resize(chunkLength);
auto chunkLength = chunkReader.readu32();
chunkReader = chunkReader.clone(8);
chunkReader = chunkReader.resize(chunkLength);
if ((tag == "SHDR") || (tag == "SHEX"))
m_shexChunk = new DxbcShex(chunkReader);
if ((tag == "ISGN"))
m_isgnChunk = new DxbcIsgn(chunkReader);
if ((tag == "OSGN"))
m_osgnChunk = new DxbcIsgn(chunkReader);
// if ((tag == "OSG5"))
// m_osgnChunk = new DxbcIsgn(chunkReader);
}
}
@ -33,7 +44,7 @@ namespace dxvk {
if (m_shexChunk == nullptr)
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
DxbcCompiler compiler(m_shexChunk->version());
DxbcCompiler compiler(m_shexChunk->version(), m_isgnChunk, m_osgnChunk);
for (auto ins : *m_shexChunk)
compiler.processInstruction(ins);

View File

@ -2,6 +2,7 @@
#include "../dxvk/dxvk_shader.h"
#include "dxbc_chunk_isgn.h"
#include "dxbc_chunk_shex.h"
#include "dxbc_header.h"
#include "dxbc_reader.h"
@ -36,6 +37,8 @@ namespace dxvk {
DxbcHeader m_header;
Rc<DxbcIsgn> m_isgnChunk;
Rc<DxbcIsgn> m_osgnChunk;
Rc<DxbcShex> m_shexChunk;
};

View File

@ -160,9 +160,9 @@ std::ostream& operator << (std::ostream& os, DxbcOpcode e) {
ENUM_NAME(DxbcOpcode::DclHsForkPhaseInstanceCount);
ENUM_NAME(DxbcOpcode::DclHsJoinPhaseInstanceCount);
ENUM_NAME(DxbcOpcode::DclThreadGroup);
ENUM_NAME(DxbcOpcode::DclUnorderedAccessViewTyped);
ENUM_NAME(DxbcOpcode::DclUnorderedAccessViewRaw);
ENUM_NAME(DxbcOpcode::DclUnorderedAccessViewStructured);
ENUM_NAME(DxbcOpcode::DclUavTyped);
ENUM_NAME(DxbcOpcode::DclUavRaw);
ENUM_NAME(DxbcOpcode::DclUavStructured);
ENUM_NAME(DxbcOpcode::DclThreadGroupSharedMemoryRaw);
ENUM_NAME(DxbcOpcode::DclThreadGroupSharedMemoryStructured);
ENUM_NAME(DxbcOpcode::DclResourceRaw);
@ -275,32 +275,32 @@ std::ostream& operator << (std::ostream& os, DxbcOperandType e) {
}
std::ostream& operator << (std::ostream& os, DxbcOperandNumComponents e) {
std::ostream& operator << (std::ostream& os, DxbcComponentCount e) {
switch (e) {
ENUM_NAME(DxbcOperandNumComponents::Component0);
ENUM_NAME(DxbcOperandNumComponents::Component1);
ENUM_NAME(DxbcOperandNumComponents::Component4);
ENUM_NAME(DxbcComponentCount::Component0);
ENUM_NAME(DxbcComponentCount::Component1);
ENUM_NAME(DxbcComponentCount::Component4);
ENUM_DEFAULT(e);
}
}
std::ostream& operator << (std::ostream& os, DxbcOperandComponentSelectionMode e) {
std::ostream& operator << (std::ostream& os, DxbcComponentSelectionMode e) {
switch (e) {
ENUM_NAME(DxbcOperandComponentSelectionMode::Mask);
ENUM_NAME(DxbcOperandComponentSelectionMode::Swizzle);
ENUM_NAME(DxbcOperandComponentSelectionMode::Select1);
ENUM_NAME(DxbcComponentSelectionMode::Mask);
ENUM_NAME(DxbcComponentSelectionMode::Swizzle);
ENUM_NAME(DxbcComponentSelectionMode::Select1);
ENUM_DEFAULT(e);
}
}
std::ostream& operator << (std::ostream& os, DxbcOperandComponentName e) {
std::ostream& operator << (std::ostream& os, DxbcComponentName e) {
switch (e) {
ENUM_NAME(DxbcOperandComponentName::X);
ENUM_NAME(DxbcOperandComponentName::Y);
ENUM_NAME(DxbcOperandComponentName::Z);
ENUM_NAME(DxbcOperandComponentName::W);
ENUM_NAME(DxbcComponentName::X);
ENUM_NAME(DxbcComponentName::Y);
ENUM_NAME(DxbcComponentName::Z);
ENUM_NAME(DxbcComponentName::W);
ENUM_DEFAULT(e);
}
}
@ -372,3 +372,32 @@ std::ostream& operator << (std::ostream& os, DxbcInstructionReturnType e) {
ENUM_DEFAULT(e);
}
}
std::ostream& operator << (std::ostream& os, DxbcSystemValue e) {
switch (e) {
ENUM_NAME(DxbcSystemValue::None);
ENUM_NAME(DxbcSystemValue::Position);
ENUM_NAME(DxbcSystemValue::ClipDistance);
ENUM_NAME(DxbcSystemValue::CullDistance);
ENUM_NAME(DxbcSystemValue::RenderTargetId);
ENUM_NAME(DxbcSystemValue::ViewportId);
ENUM_NAME(DxbcSystemValue::VertexId);
ENUM_NAME(DxbcSystemValue::PrimitiveId);
ENUM_NAME(DxbcSystemValue::InstanceId);
ENUM_NAME(DxbcSystemValue::IsFrontFace);
ENUM_NAME(DxbcSystemValue::SampleIndex);
ENUM_NAME(DxbcSystemValue::FinalQuadEdgeTessFactor);
ENUM_NAME(DxbcSystemValue::FinalQuadInsideTessFactor);
ENUM_NAME(DxbcSystemValue::FinalTriEdgeTessFactor);
ENUM_NAME(DxbcSystemValue::FinalTriInsideTessFactor);
ENUM_NAME(DxbcSystemValue::FinalLineDetailTessFactor);
ENUM_NAME(DxbcSystemValue::FinalLineDensityTessFactor);
ENUM_NAME(DxbcSystemValue::Target);
ENUM_NAME(DxbcSystemValue::Depth);
ENUM_NAME(DxbcSystemValue::Coverage);
ENUM_NAME(DxbcSystemValue::DepthGe);
ENUM_NAME(DxbcSystemValue::DepthLe);
ENUM_DEFAULT(e);
}
}

View File

@ -7,11 +7,12 @@
std::ostream& operator << (std::ostream& os, dxvk::DxbcOpcode e);
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::DxbcOperandNumComponents e);
std::ostream& operator << (std::ostream& os, dxvk::DxbcOperandComponentSelectionMode e);
std::ostream& operator << (std::ostream& os, dxvk::DxbcOperandComponentName 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::DxbcComponentName 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);
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);

104
src/dxbc/dxbc_type.h Normal file
View File

@ -0,0 +1,104 @@
#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)
: componentType(s), componentCount(c) { }
DxbcScalarType componentType = DxbcScalarType::Uint32;
uint32_t componentCount = 0;
};
/**
* \brief Value
*
* Stores the type and SPIR-V ID of an expression
* 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;
};
/**
* \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 {
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;
};
}

View File

@ -1,4 +1,5 @@
dxbc_src = files([
'dxbc_chunk_isgn.cpp',
'dxbc_chunk_shex.cpp',
'dxbc_common.cpp',
'dxbc_compiler.cpp',