mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-01 16:24:12 +01:00
[dxbc] Removed most of the DXBC compiler again
This commit is contained in:
parent
9cdc341946
commit
4052951542
@ -29,14 +29,4 @@ namespace dxvk {
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint32_t DxbcIsgn::entryCount() const {
|
||||
return m_entries.size();
|
||||
}
|
||||
|
||||
|
||||
const DxbcSgnEntry& DxbcIsgn::entry(uint32_t id) const {
|
||||
return m_entries.at(id);
|
||||
}
|
||||
|
||||
}
|
@ -36,9 +36,8 @@ namespace dxvk {
|
||||
DxbcIsgn(DxbcReader reader);
|
||||
~DxbcIsgn();
|
||||
|
||||
uint32_t entryCount() const;
|
||||
|
||||
const DxbcSgnEntry& entry(uint32_t id) const;
|
||||
auto begin() const { return m_entries.cbegin(); }
|
||||
auto end () const { return m_entries.cend(); }
|
||||
|
||||
private:
|
||||
|
||||
|
@ -1,28 +1,12 @@
|
||||
#include "dxbc_compiler.h"
|
||||
#include "dxbc_names.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
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();
|
||||
DxbcProgramVersion version)
|
||||
: m_version(version) {
|
||||
|
||||
this->declareCapabilities();
|
||||
this->declareMemoryModel();
|
||||
|
||||
m_typeVoid = m_module.defVoidType();
|
||||
m_typeFunction = m_module.defFunctionType(m_typeVoid, 0, nullptr);
|
||||
|
||||
m_module.functionBegin(m_typeVoid,
|
||||
m_entryPointId, m_typeFunction,
|
||||
spv::FunctionControlMaskNone);
|
||||
|
||||
// TODO implement proper control flow
|
||||
m_module.opLabel(m_module.allocateId());
|
||||
}
|
||||
|
||||
|
||||
@ -32,240 +16,13 @@ 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:
|
||||
return this->dclInput(ins);
|
||||
|
||||
case DxbcOpcode::DclOutputSiv:
|
||||
return this->dclOutputSiv(ins);
|
||||
|
||||
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:
|
||||
throw DxvkError(str::format("DXBC: Unhandled instruction: ", ins.token().opcode()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkShader> DxbcCompiler::finalize() {
|
||||
m_module.functionEnd();
|
||||
|
||||
m_module.addEntryPoint(m_entryPointId,
|
||||
m_version.executionModel(), "main",
|
||||
m_interfaces.size(),
|
||||
m_interfaces.data());
|
||||
|
||||
return new DxvkShader(m_version.shaderStage(),
|
||||
m_module.compile(), 0, nullptr);
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::declareCapabilities() {
|
||||
m_module.enableCapability(spv::CapabilityShader);
|
||||
|
||||
switch (m_version.type()) {
|
||||
case DxbcProgramType::GeometryShader:
|
||||
m_module.enableCapability(spv::CapabilityGeometry);
|
||||
break;
|
||||
|
||||
case DxbcProgramType::HullShader:
|
||||
case DxbcProgramType::DomainShader:
|
||||
m_module.enableCapability(spv::CapabilityTessellation);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::declareMemoryModel() {
|
||||
m_module.setMemoryModel(
|
||||
spv::AddressingModelLogical,
|
||||
spv::MemoryModelGLSL450);
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::dclGlobalFlags(const DxbcInstruction& ins) {
|
||||
const DxbcGlobalFlags flags(ins.token().control());
|
||||
|
||||
if (!flags.test(DxbcGlobalFlag::RefactoringAllowed))
|
||||
m_useRestrictedMath = true;
|
||||
|
||||
if (flags.test(DxbcGlobalFlag::DoublePrecision))
|
||||
m_module.enableCapability(spv::CapabilityFloat64);
|
||||
|
||||
if (flags.test(DxbcGlobalFlag::EarlyFragmentTests))
|
||||
m_module.enableEarlyFragmentTests(m_entryPointId);
|
||||
|
||||
// Raw and structured buffers are supported regardless
|
||||
// of whether the corresponding flag is set or not.
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::dclInput(const DxbcInstruction& ins) {
|
||||
const DxbcOperand operand = ins.operand(0);
|
||||
const DxbcOperandToken token = operand.token();
|
||||
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
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 < 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.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;
|
||||
|
||||
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) {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -17,9 +17,7 @@ namespace dxvk {
|
||||
public:
|
||||
|
||||
DxbcCompiler(
|
||||
DxbcProgramVersion version,
|
||||
const Rc<DxbcIsgn>& inputSig,
|
||||
const Rc<DxbcIsgn>& outputSig);
|
||||
DxbcProgramVersion version);
|
||||
~DxbcCompiler();
|
||||
|
||||
DxbcCompiler (DxbcCompiler&&) = delete;
|
||||
@ -32,7 +30,7 @@ namespace dxvk {
|
||||
* \returns \c true on success
|
||||
*/
|
||||
void processInstruction(
|
||||
const DxbcInstruction& ins);
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
/**
|
||||
* \brief Creates actual shader object
|
||||
@ -47,77 +45,6 @@ namespace dxvk {
|
||||
DxbcProgramVersion m_version;
|
||||
SpirvModule m_module;
|
||||
|
||||
Rc<DxbcIsgn> m_inputSig;
|
||||
Rc<DxbcIsgn> m_outputSig;
|
||||
|
||||
std::vector<uint32_t> m_interfaces;
|
||||
std::vector<DxbcPointer> m_rRegs; // Temps
|
||||
|
||||
DxbcPointer m_svPosition;
|
||||
std::vector<DxbcPointer> m_svClipDistance;
|
||||
std::vector<DxbcPointer> m_svCullDistance;
|
||||
|
||||
uint32_t m_entryPointId = 0;
|
||||
|
||||
uint32_t m_typeVoid = 0;
|
||||
uint32_t m_typeFunction = 0;
|
||||
|
||||
bool m_useRestrictedMath = false;
|
||||
|
||||
|
||||
|
||||
void declareCapabilities();
|
||||
void declareMemoryModel();
|
||||
|
||||
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);
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -5,26 +5,12 @@
|
||||
|
||||
#include "dxbc_enums.h"
|
||||
#include "dxbc_names.h"
|
||||
#include "dxbc_type.h"
|
||||
|
||||
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
|
||||
*
|
||||
@ -213,11 +199,11 @@ namespace dxvk {
|
||||
* \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)) };
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -226,9 +212,8 @@ namespace dxvk {
|
||||
* Used when the component selection mode is
|
||||
* \c DxbcComponentSelectionMode::Select1.
|
||||
*/
|
||||
DxbcComponentName componentSelection() const {
|
||||
return static_cast<DxbcComponentName>(
|
||||
bit::extract(m_token, 4, 5));
|
||||
DxbcComponentMask componentSelection() const {
|
||||
return DxbcComponentMask(bit::extract(m_token, 4, 5));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -307,15 +307,6 @@ namespace dxvk {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Component name
|
||||
* Used for component selection.
|
||||
*/
|
||||
enum class DxbcComponentName : uint32_t {
|
||||
X = 0, Y = 1, Z = 2, W = 3,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Index representation
|
||||
*
|
||||
|
@ -44,7 +44,13 @@ namespace dxvk {
|
||||
if (m_shexChunk == nullptr)
|
||||
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
|
||||
|
||||
DxbcCompiler compiler(m_shexChunk->version(), m_isgnChunk, m_osgnChunk);
|
||||
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);
|
||||
|
@ -295,17 +295,6 @@ std::ostream& operator << (std::ostream& os, DxbcComponentSelectionMode e) {
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator << (std::ostream& os, DxbcComponentName e) {
|
||||
switch (e) {
|
||||
ENUM_NAME(DxbcComponentName::X);
|
||||
ENUM_NAME(DxbcComponentName::Y);
|
||||
ENUM_NAME(DxbcComponentName::Z);
|
||||
ENUM_NAME(DxbcComponentName::W);
|
||||
ENUM_DEFAULT(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator << (std::ostream& os, DxbcOperandIndexRepresentation e) {
|
||||
switch (e) {
|
||||
ENUM_NAME(DxbcOperandIndexRepresentation::Imm32);
|
||||
|
@ -9,7 +9,6 @@ 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::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);
|
||||
|
@ -101,4 +101,83 @@ namespace dxvk {
|
||||
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;
|
||||
|
||||
DxbcComponentMask mask(uint32_t n) const;
|
||||
|
||||
private:
|
||||
|
||||
std::array<uint32_t, 4> m_components;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -8,6 +8,7 @@ dxbc_src = files([
|
||||
'dxbc_module.cpp',
|
||||
'dxbc_names.cpp',
|
||||
'dxbc_reader.cpp',
|
||||
'dxbc_type.cpp',
|
||||
])
|
||||
|
||||
dxbc_lib = static_library('dxbc', dxbc_src,
|
||||
|
@ -204,6 +204,36 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void SpirvModule::decorateBuiltIn(
|
||||
uint32_t object,
|
||||
spv::BuiltIn builtIn) {
|
||||
m_annotations.putIns (spv::OpDecorate, 4);
|
||||
m_annotations.putWord (object);
|
||||
m_annotations.putWord (spv::DecorationBuiltIn);
|
||||
m_annotations.putWord (builtIn);
|
||||
}
|
||||
|
||||
|
||||
void SpirvModule::decorateComponent(
|
||||
uint32_t object,
|
||||
uint32_t location) {
|
||||
m_annotations.putIns (spv::OpDecorate, 4);
|
||||
m_annotations.putWord (object);
|
||||
m_annotations.putWord (spv::DecorationComponent);
|
||||
m_annotations.putInt32(location);
|
||||
}
|
||||
|
||||
|
||||
void SpirvModule::decorateLocation(
|
||||
uint32_t object,
|
||||
uint32_t location) {
|
||||
m_annotations.putIns (spv::OpDecorate, 4);
|
||||
m_annotations.putWord (object);
|
||||
m_annotations.putWord (spv::DecorationLocation);
|
||||
m_annotations.putInt32(location);
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::defVoidType() {
|
||||
return this->defType(spv::OpTypeVoid, 0, nullptr);
|
||||
}
|
||||
@ -354,6 +384,57 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opBitcast(
|
||||
uint32_t resultType,
|
||||
uint32_t operand) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpBitcast, 4);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(operand);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opCompositeExtract(
|
||||
uint32_t resultType,
|
||||
uint32_t composite,
|
||||
uint32_t indexCount,
|
||||
const uint32_t* indexArray) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpCompositeExtract, 4 + indexCount);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(composite);
|
||||
|
||||
for (uint32_t i = 0; i < indexCount; i++)
|
||||
m_code.putInt32(indexArray[i]);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opVectorShuffle(
|
||||
uint32_t resultType,
|
||||
uint32_t vectorLeft,
|
||||
uint32_t vectorRight,
|
||||
uint32_t indexCount,
|
||||
const uint32_t* indexArray) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpVectorShuffle, 5 + indexCount);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(vectorLeft);
|
||||
m_code.putWord(vectorRight);
|
||||
|
||||
for (uint32_t i = 0; i < indexCount; i++)
|
||||
m_code.putInt32(indexArray[i]);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opFunctionCall(
|
||||
uint32_t resultType,
|
||||
uint32_t functionId,
|
||||
@ -373,7 +454,7 @@ namespace dxvk {
|
||||
|
||||
|
||||
void SpirvModule::opLabel(uint32_t labelId) {
|
||||
m_code.putIns (spv::OpReturn, 2);
|
||||
m_code.putIns (spv::OpLabel, 2);
|
||||
m_code.putWord(labelId);
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,18 @@ namespace dxvk {
|
||||
uint32_t constCount,
|
||||
const uint32_t* constIds);
|
||||
|
||||
void decorateBuiltIn(
|
||||
uint32_t object,
|
||||
spv::BuiltIn builtIn);
|
||||
|
||||
void decorateComponent(
|
||||
uint32_t object,
|
||||
uint32_t location);
|
||||
|
||||
void decorateLocation(
|
||||
uint32_t object,
|
||||
uint32_t location);
|
||||
|
||||
uint32_t defVoidType();
|
||||
|
||||
uint32_t defBoolType();
|
||||
@ -130,6 +142,23 @@ namespace dxvk {
|
||||
|
||||
void functionEnd();
|
||||
|
||||
uint32_t opBitcast(
|
||||
uint32_t resultType,
|
||||
uint32_t operand);
|
||||
|
||||
uint32_t opCompositeExtract(
|
||||
uint32_t resultType,
|
||||
uint32_t composite,
|
||||
uint32_t indexCount,
|
||||
const uint32_t* indexArray);
|
||||
|
||||
uint32_t opVectorShuffle(
|
||||
uint32_t resultType,
|
||||
uint32_t vectorLeft,
|
||||
uint32_t vectorRight,
|
||||
uint32_t indexCount,
|
||||
const uint32_t* indexArray);
|
||||
|
||||
uint32_t opFunctionCall(
|
||||
uint32_t resultType,
|
||||
uint32_t functionId,
|
||||
|
@ -3,8 +3,24 @@
|
||||
namespace dxvk::bit {
|
||||
|
||||
template<typename T>
|
||||
inline T extract(T value, uint32_t fst, uint32_t lst) {
|
||||
T extract(T value, uint32_t fst, uint32_t lst) {
|
||||
return (value >> fst) & ~(~T(0) << (lst - fst + 1));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T popcnt(T value) {
|
||||
return value != 0
|
||||
? (value & 1) + popcnt(value >> 1)
|
||||
: 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T tzcnt(T value) {
|
||||
uint32_t result = 0;
|
||||
while ((result < sizeof(T) * 8)
|
||||
&& (((value >> result) & 1) == 0))
|
||||
result += 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "util_bit.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
template<typename T>
|
||||
@ -54,6 +56,10 @@ namespace dxvk {
|
||||
m_bits = 0;
|
||||
}
|
||||
|
||||
uint32_t raw() const {
|
||||
return m_bits;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
IntType m_bits = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user