[dxbc] Shader compiler rewrite (2/2)

This commit is contained in:
Philip Rebohle 2017-12-14 12:53:53 +01:00
parent bdce9a69fb
commit 2ad5f49f3e
12 changed files with 211 additions and 375 deletions

View File

@ -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;
};

View File

@ -10,7 +10,7 @@ namespace dxvk {
constexpr uint32_t PerVertex_ClipDist = 3;
DxbcCompiler2::DxbcCompiler2(
DxbcCompiler::DxbcCompiler(
const DxbcProgramVersion& version,
const Rc<DxbcIsgn>& isgn,
const Rc<DxbcIsgn>& 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<DxvkShader> DxbcCompiler2::finalize() {
Rc<DxvkShader> 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<uint32_t, 4> 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<uint32_t, 2> 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<DxbcIsgn>& isgn) {
void DxbcCompiler::beginVertexShader(const Rc<DxbcIsgn>& 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<DxbcIsgn>& osgn) {
void DxbcCompiler::beginPixelShader(const Rc<DxbcIsgn>& 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);

View File

@ -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<DxbcPointer2, DxbcMaxInterfaceRegs> oregs;
std::array<DxbcPointer, DxbcMaxInterfaceRegs> 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<DxbcIsgn>& isgn,
const Rc<DxbcIsgn>& 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<DxbcConstantBuffer2, 16> m_constantBuffers;
std::array<DxbcSampler2, 16> m_samplers;
std::array<DxbcShaderResource2, 128> m_textures;
std::array<DxbcConstantBuffer, 16> m_constantBuffers;
std::array<DxbcSampler, 16> m_samplers;
std::array<DxbcShaderResource, 128> m_textures;
////////////////////////////////////////////////////////
// Input/Output system value mappings. These will need
// to be set up before or after the main function runs.
std::vector<DxbcSvMapping2> m_vSvs;
std::vector<DxbcSvMapping2> m_oSvs;
std::vector<DxbcSvMapping> m_vSvs;
std::vector<DxbcSvMapping> 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);
/////////////////////////////////

View File

@ -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<DxbcComponentSelectionMode>(
DxbcRegMode selectionMode() const {
return static_cast<DxbcRegMode>(
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
*

View File

@ -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);
}

View File

@ -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<DxbcSyncFlag>;
/**
* \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,
};
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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<uint32_t, 4> m_components;
};
}

View File

@ -9,7 +9,6 @@ dxbc_src = files([
'dxbc_module.cpp',
'dxbc_names.cpp',
'dxbc_reader.cpp',
'dxbc_type.cpp',
'dxbc_util.cpp',
])