mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 10:54:16 +01:00
[dxbc] Initial xSGN chunk implementation
This commit is contained in:
parent
bc8cc76888
commit
72f353074f
39
src/dxbc/dxbc_chunk_isgn.cpp
Normal file
39
src/dxbc/dxbc_chunk_isgn.cpp
Normal 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() {
|
||||
|
||||
}
|
||||
|
||||
}
|
45
src/dxbc/dxbc_chunk_isgn.h
Normal file
45
src/dxbc/dxbc_chunk_isgn.h
Normal 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;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
104
src/dxbc/dxbc_type.h
Normal 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;
|
||||
};
|
||||
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
dxbc_src = files([
|
||||
'dxbc_chunk_isgn.cpp',
|
||||
'dxbc_chunk_shex.cpp',
|
||||
'dxbc_common.cpp',
|
||||
'dxbc_compiler.cpp',
|
||||
|
Loading…
x
Reference in New Issue
Block a user