mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-15 07:29:17 +01:00
[dxbc] Implemented constant buffers
This commit is contained in:
parent
9f4cc6b77d
commit
a2f66025f8
@ -21,6 +21,9 @@ namespace dxvk {
|
|||||||
case DxbcOpcode::DclGlobalFlags:
|
case DxbcOpcode::DclGlobalFlags:
|
||||||
return this->dclGlobalFlags(ins);
|
return this->dclGlobalFlags(ins);
|
||||||
|
|
||||||
|
case DxbcOpcode::DclConstantBuffer:
|
||||||
|
return this->dclConstantBuffer(ins);
|
||||||
|
|
||||||
case DxbcOpcode::DclInput:
|
case DxbcOpcode::DclInput:
|
||||||
case DxbcOpcode::DclInputSiv:
|
case DxbcOpcode::DclInputSiv:
|
||||||
case DxbcOpcode::DclInputSgv:
|
case DxbcOpcode::DclInputSgv:
|
||||||
@ -41,6 +44,15 @@ namespace dxvk {
|
|||||||
case DxbcOpcode::Mov:
|
case DxbcOpcode::Mov:
|
||||||
return this->opMov(ins);
|
return this->opMov(ins);
|
||||||
|
|
||||||
|
case DxbcOpcode::Dp2:
|
||||||
|
return this->opDpx(ins, 2);
|
||||||
|
|
||||||
|
case DxbcOpcode::Dp3:
|
||||||
|
return this->opDpx(ins, 3);
|
||||||
|
|
||||||
|
case DxbcOpcode::Dp4:
|
||||||
|
return this->opDpx(ins, 4);
|
||||||
|
|
||||||
case DxbcOpcode::Ret:
|
case DxbcOpcode::Ret:
|
||||||
return this->opRet(ins);
|
return this->opRet(ins);
|
||||||
|
|
||||||
@ -58,7 +70,20 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void DxbcCompiler::dclGlobalFlags(const DxbcInstruction& ins) {
|
void DxbcCompiler::dclGlobalFlags(const DxbcInstruction& ins) {
|
||||||
|
// TODO fill with life
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxbcCompiler::dclConstantBuffer(const DxbcInstruction& ins) {
|
||||||
|
auto op = ins.operand(0);
|
||||||
|
|
||||||
|
if (op.token().indexDimension() != 2)
|
||||||
|
throw DxvkError("DxbcCompiler::dclConstantBuffer: Invalid index dimension");
|
||||||
|
|
||||||
|
const uint32_t index = op.index(0).immPart();
|
||||||
|
const uint32_t size = op.index(1).immPart();
|
||||||
|
|
||||||
|
m_gen->dclConstantBuffer(index, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -139,6 +164,22 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxbcCompiler::opDpx(const DxbcInstruction& ins, uint32_t n) {
|
||||||
|
auto dstOp = ins.operand(0);
|
||||||
|
auto srcOp1 = ins.operand(dstOp.length());
|
||||||
|
auto srcOp2 = ins.operand(dstOp.length() + srcOp1.length());
|
||||||
|
|
||||||
|
DxbcComponentMask dstMask = this->getDstOperandMask(dstOp);
|
||||||
|
DxbcComponentMask srcMask(n >= 1, n >= 2, n >= 3, n == 4);
|
||||||
|
|
||||||
|
DxbcValue src1 = this->loadOperand(srcOp1, srcMask, DxbcScalarType::Float32);
|
||||||
|
DxbcValue src2 = this->loadOperand(srcOp2, srcMask, DxbcScalarType::Float32);
|
||||||
|
DxbcValue val = m_gen->opDot(src1, src2);
|
||||||
|
val = this->applyResultModifiers(val, ins.token().control());
|
||||||
|
this->storeOperand(dstOp, val, dstMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxbcCompiler::opMov(const DxbcInstruction& ins) {
|
void DxbcCompiler::opMov(const DxbcInstruction& ins) {
|
||||||
auto dstOp = ins.operand(0);
|
auto dstOp = ins.operand(0);
|
||||||
auto srcOp = ins.operand(dstOp.length());
|
auto srcOp = ins.operand(dstOp.length());
|
||||||
@ -155,6 +196,28 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxbcValue DxbcCompiler::getDynamicIndexValue(const DxbcOperandIndex& index) {
|
||||||
|
DxbcValue immPart;
|
||||||
|
DxbcValue relPart;
|
||||||
|
|
||||||
|
if (index.hasImmPart())
|
||||||
|
immPart = m_gen->defConstScalar(index.immPart());
|
||||||
|
|
||||||
|
if (index.hasRelPart()) {
|
||||||
|
relPart = this->loadOperand(index.relPart(),
|
||||||
|
DxbcComponentMask(true, false, false, false),
|
||||||
|
DxbcScalarType::Uint32);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (immPart.valueId == 0)
|
||||||
|
return relPart;
|
||||||
|
else if (relPart.valueId == 0)
|
||||||
|
return immPart;
|
||||||
|
else
|
||||||
|
return m_gen->opAdd(relPart, immPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxbcComponentMask DxbcCompiler::getDstOperandMask(const DxbcOperand& operand) {
|
DxbcComponentMask DxbcCompiler::getDstOperandMask(const DxbcOperand& operand) {
|
||||||
const DxbcOperandToken token = operand.token();
|
const DxbcOperandToken token = operand.token();
|
||||||
|
|
||||||
@ -225,6 +288,16 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxbcPointer DxbcCompiler::getConstantBufferPtr(const DxbcOperand& operand) {
|
||||||
|
if (operand.token().indexDimension() != 2)
|
||||||
|
throw DxvkError("DxbcCompiler::getConstantBufferPtr: Invalid index dimension");
|
||||||
|
|
||||||
|
return m_gen->ptrConstantBuffer(
|
||||||
|
operand.index(0).immPart(),
|
||||||
|
this->getDynamicIndexValue(operand.index(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxbcPointer DxbcCompiler::getOperandPtr(const DxbcOperand& operand) {
|
DxbcPointer DxbcCompiler::getOperandPtr(const DxbcOperand& operand) {
|
||||||
switch (operand.token().type()) {
|
switch (operand.token().type()) {
|
||||||
case DxbcOperandType::Temp:
|
case DxbcOperandType::Temp:
|
||||||
@ -234,6 +307,9 @@ namespace dxvk {
|
|||||||
case DxbcOperandType::Output:
|
case DxbcOperandType::Output:
|
||||||
return this->getInterfaceOperandPtr(operand);
|
return this->getInterfaceOperandPtr(operand);
|
||||||
|
|
||||||
|
case DxbcOperandType::ConstantBuffer:
|
||||||
|
return this->getConstantBufferPtr(operand);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw DxvkError(str::format(
|
throw DxvkError(str::format(
|
||||||
"DxbcCompiler::getOperandPtr: Unhandled operand type: ",
|
"DxbcCompiler::getOperandPtr: Unhandled operand type: ",
|
||||||
|
@ -32,6 +32,9 @@ namespace dxvk {
|
|||||||
void dclGlobalFlags(
|
void dclGlobalFlags(
|
||||||
const DxbcInstruction& ins);
|
const DxbcInstruction& ins);
|
||||||
|
|
||||||
|
void dclConstantBuffer(
|
||||||
|
const DxbcInstruction& ins);
|
||||||
|
|
||||||
void dclInterfaceVar(
|
void dclInterfaceVar(
|
||||||
const DxbcInstruction& ins);
|
const DxbcInstruction& ins);
|
||||||
|
|
||||||
@ -41,12 +44,19 @@ namespace dxvk {
|
|||||||
void opAdd(
|
void opAdd(
|
||||||
const DxbcInstruction& ins);
|
const DxbcInstruction& ins);
|
||||||
|
|
||||||
|
void opDpx(
|
||||||
|
const DxbcInstruction& ins,
|
||||||
|
uint32_t n);
|
||||||
|
|
||||||
void opMov(
|
void opMov(
|
||||||
const DxbcInstruction& ins);
|
const DxbcInstruction& ins);
|
||||||
|
|
||||||
void opRet(
|
void opRet(
|
||||||
const DxbcInstruction& ins);
|
const DxbcInstruction& ins);
|
||||||
|
|
||||||
|
DxbcValue getDynamicIndexValue(
|
||||||
|
const DxbcOperandIndex& index);
|
||||||
|
|
||||||
DxbcComponentMask getDstOperandMask(
|
DxbcComponentMask getDstOperandMask(
|
||||||
const DxbcOperand& operand);
|
const DxbcOperand& operand);
|
||||||
|
|
||||||
@ -56,6 +66,9 @@ namespace dxvk {
|
|||||||
DxbcPointer getInterfaceOperandPtr(
|
DxbcPointer getInterfaceOperandPtr(
|
||||||
const DxbcOperand& operand);
|
const DxbcOperand& operand);
|
||||||
|
|
||||||
|
DxbcPointer getConstantBufferPtr(
|
||||||
|
const DxbcOperand& operand);
|
||||||
|
|
||||||
DxbcPointer getOperandPtr(
|
DxbcPointer getOperandPtr(
|
||||||
const DxbcOperand& operand);
|
const DxbcOperand& operand);
|
||||||
|
|
||||||
|
@ -36,6 +36,25 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxbcCodeGen::dclConstantBuffer(
|
||||||
|
uint32_t bufferId,
|
||||||
|
uint32_t elementCount) {
|
||||||
|
uint32_t arrayType = this->defValueType(
|
||||||
|
DxbcValueType(DxbcScalarType::Float32, 4, elementCount));
|
||||||
|
uint32_t structType = m_module.defStructType(1, &arrayType);
|
||||||
|
|
||||||
|
m_module.memberDecorateOffset(structType, 0, 0);
|
||||||
|
m_module.decorateBlock(structType);
|
||||||
|
|
||||||
|
uint32_t varIndex = m_module.newVar(
|
||||||
|
m_module.defPointerType(structType, spv::StorageClassUniform),
|
||||||
|
spv::StorageClassUniform);
|
||||||
|
|
||||||
|
m_constantBuffers.at(bufferId).varId = varIndex;
|
||||||
|
m_constantBuffers.at(bufferId).size = elementCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxbcValue DxbcCodeGen::defConstScalar(uint32_t v) {
|
DxbcValue DxbcCodeGen::defConstScalar(uint32_t v) {
|
||||||
DxbcValue result;
|
DxbcValue result;
|
||||||
result.type = DxbcValueType(DxbcScalarType::Uint32, 1);
|
result.type = DxbcValueType(DxbcScalarType::Uint32, 1);
|
||||||
@ -74,6 +93,26 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxbcPointer DxbcCodeGen::ptrConstantBuffer(
|
||||||
|
uint32_t regId,
|
||||||
|
const DxbcValue& index) {
|
||||||
|
// The first index selects the struct member,
|
||||||
|
// the second one selects the array element.
|
||||||
|
std::array<uint32_t, 2> indices = {
|
||||||
|
m_module.constu32(0), index.valueId };
|
||||||
|
|
||||||
|
DxbcPointer result;
|
||||||
|
result.type = DxbcPointerType(
|
||||||
|
DxbcValueType(DxbcScalarType::Float32, 4),
|
||||||
|
spv::StorageClassUniform);
|
||||||
|
result.valueId = m_module.opAccessChain(
|
||||||
|
this->defPointerType(result.type),
|
||||||
|
m_constantBuffers.at(regId).varId,
|
||||||
|
2, indices.data());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxbcValue DxbcCodeGen::opAbs(const DxbcValue& src) {
|
DxbcValue DxbcCodeGen::opAbs(const DxbcValue& src) {
|
||||||
DxbcValue result;
|
DxbcValue result;
|
||||||
result.type = src.type;
|
result.type = src.type;
|
||||||
@ -129,6 +168,16 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxbcValue DxbcCodeGen::opDot(const DxbcValue& a, const DxbcValue& b) {
|
||||||
|
DxbcValue result;
|
||||||
|
result.type = DxbcValueType(a.type.componentType, 1);
|
||||||
|
result.valueId = m_module.opDot(
|
||||||
|
this->defValueType(result.type),
|
||||||
|
a.valueId, b.valueId);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxbcValue DxbcCodeGen::opNeg(const DxbcValue& src) {
|
DxbcValue DxbcCodeGen::opNeg(const DxbcValue& src) {
|
||||||
DxbcValue result;
|
DxbcValue result;
|
||||||
result.type = src.type;
|
result.type = src.type;
|
||||||
|
@ -22,6 +22,18 @@ namespace dxvk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Constant buffer binding
|
||||||
|
*
|
||||||
|
* Stores information about
|
||||||
|
* a constant buffer.
|
||||||
|
*/
|
||||||
|
struct DxbcConstantBuffer {
|
||||||
|
uint32_t varId = 0;
|
||||||
|
uint32_t size = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief DXBC code generator
|
* \brief DXBC code generator
|
||||||
*
|
*
|
||||||
@ -40,6 +52,10 @@ namespace dxvk {
|
|||||||
|
|
||||||
void dclTemps(uint32_t n);
|
void dclTemps(uint32_t n);
|
||||||
|
|
||||||
|
void dclConstantBuffer(
|
||||||
|
uint32_t bufferId,
|
||||||
|
uint32_t elementCount);
|
||||||
|
|
||||||
DxbcValue defConstScalar(uint32_t v);
|
DxbcValue defConstScalar(uint32_t v);
|
||||||
|
|
||||||
DxbcValue defConstVector(
|
DxbcValue defConstVector(
|
||||||
@ -51,6 +67,10 @@ namespace dxvk {
|
|||||||
DxbcPointer ptrTempReg(
|
DxbcPointer ptrTempReg(
|
||||||
uint32_t regId);
|
uint32_t regId);
|
||||||
|
|
||||||
|
DxbcPointer ptrConstantBuffer(
|
||||||
|
uint32_t regId,
|
||||||
|
const DxbcValue& index);
|
||||||
|
|
||||||
DxbcValue opAbs(
|
DxbcValue opAbs(
|
||||||
const DxbcValue& src);
|
const DxbcValue& src);
|
||||||
|
|
||||||
@ -62,6 +82,10 @@ namespace dxvk {
|
|||||||
const DxbcValue& a,
|
const DxbcValue& a,
|
||||||
const DxbcValue& b);
|
const DxbcValue& b);
|
||||||
|
|
||||||
|
DxbcValue opDot(
|
||||||
|
const DxbcValue& a,
|
||||||
|
const DxbcValue& b);
|
||||||
|
|
||||||
DxbcValue opNeg(
|
DxbcValue opNeg(
|
||||||
const DxbcValue& src);
|
const DxbcValue& src);
|
||||||
|
|
||||||
@ -132,6 +156,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
std::vector<DxbcPointer> m_rRegs;
|
std::vector<DxbcPointer> m_rRegs;
|
||||||
|
|
||||||
|
std::array<DxbcConstantBuffer, 16> m_constantBuffers;
|
||||||
|
|
||||||
uint32_t defScalarType(
|
uint32_t defScalarType(
|
||||||
DxbcScalarType type);
|
DxbcScalarType type);
|
||||||
|
|
||||||
|
@ -307,6 +307,18 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SpirvModule::memberDecorateOffset(
|
||||||
|
uint32_t structId,
|
||||||
|
uint32_t memberId,
|
||||||
|
uint32_t offset) {
|
||||||
|
m_annotations.putIns (spv::OpMemberDecorate, 5);
|
||||||
|
m_annotations.putWord (structId);
|
||||||
|
m_annotations.putWord (memberId);
|
||||||
|
m_annotations.putWord (spv::DecorationOffset);
|
||||||
|
m_annotations.putWord (offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t SpirvModule::defVoidType() {
|
uint32_t SpirvModule::defVoidType() {
|
||||||
return this->defType(spv::OpTypeVoid, 0, nullptr);
|
return this->defType(spv::OpTypeVoid, 0, nullptr);
|
||||||
}
|
}
|
||||||
@ -696,6 +708,21 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t SpirvModule::opDot(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t vector1,
|
||||||
|
uint32_t vector2) {
|
||||||
|
uint32_t resultId = this->allocateId();
|
||||||
|
|
||||||
|
m_code.putIns (spv::OpDot, 5);
|
||||||
|
m_code.putWord(resultType);
|
||||||
|
m_code.putWord(resultId);
|
||||||
|
m_code.putWord(vector1);
|
||||||
|
m_code.putWord(vector2);
|
||||||
|
return resultId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t SpirvModule::opFunctionCall(
|
uint32_t SpirvModule::opFunctionCall(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t functionId,
|
uint32_t functionId,
|
||||||
|
@ -116,6 +116,11 @@ namespace dxvk {
|
|||||||
uint32_t memberId,
|
uint32_t memberId,
|
||||||
spv::BuiltIn builtIn);
|
spv::BuiltIn builtIn);
|
||||||
|
|
||||||
|
void memberDecorateOffset(
|
||||||
|
uint32_t structId,
|
||||||
|
uint32_t memberId,
|
||||||
|
uint32_t offset);
|
||||||
|
|
||||||
uint32_t defVoidType();
|
uint32_t defVoidType();
|
||||||
|
|
||||||
uint32_t defBoolType();
|
uint32_t defBoolType();
|
||||||
@ -251,6 +256,11 @@ namespace dxvk {
|
|||||||
uint32_t minVal,
|
uint32_t minVal,
|
||||||
uint32_t maxVal);
|
uint32_t maxVal);
|
||||||
|
|
||||||
|
uint32_t opDot(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t vector1,
|
||||||
|
uint32_t vector2);
|
||||||
|
|
||||||
uint32_t opFunctionCall(
|
uint32_t opFunctionCall(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t functionId,
|
uint32_t functionId,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user