mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-14 04:29:15 +01:00
[dxbc] Implemented constant buffers
This commit is contained in:
parent
9f4cc6b77d
commit
a2f66025f8
@ -21,6 +21,9 @@ namespace dxvk {
|
||||
case DxbcOpcode::DclGlobalFlags:
|
||||
return this->dclGlobalFlags(ins);
|
||||
|
||||
case DxbcOpcode::DclConstantBuffer:
|
||||
return this->dclConstantBuffer(ins);
|
||||
|
||||
case DxbcOpcode::DclInput:
|
||||
case DxbcOpcode::DclInputSiv:
|
||||
case DxbcOpcode::DclInputSgv:
|
||||
@ -41,6 +44,15 @@ namespace dxvk {
|
||||
case DxbcOpcode::Mov:
|
||||
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:
|
||||
return this->opRet(ins);
|
||||
|
||||
@ -58,7 +70,20 @@ namespace dxvk {
|
||||
|
||||
|
||||
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) {
|
||||
auto dstOp = ins.operand(0);
|
||||
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) {
|
||||
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) {
|
||||
switch (operand.token().type()) {
|
||||
case DxbcOperandType::Temp:
|
||||
@ -234,6 +307,9 @@ namespace dxvk {
|
||||
case DxbcOperandType::Output:
|
||||
return this->getInterfaceOperandPtr(operand);
|
||||
|
||||
case DxbcOperandType::ConstantBuffer:
|
||||
return this->getConstantBufferPtr(operand);
|
||||
|
||||
default:
|
||||
throw DxvkError(str::format(
|
||||
"DxbcCompiler::getOperandPtr: Unhandled operand type: ",
|
||||
|
@ -32,6 +32,9 @@ namespace dxvk {
|
||||
void dclGlobalFlags(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
void dclConstantBuffer(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
void dclInterfaceVar(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
@ -41,12 +44,19 @@ namespace dxvk {
|
||||
void opAdd(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
void opDpx(
|
||||
const DxbcInstruction& ins,
|
||||
uint32_t n);
|
||||
|
||||
void opMov(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
void opRet(
|
||||
const DxbcInstruction& ins);
|
||||
|
||||
DxbcValue getDynamicIndexValue(
|
||||
const DxbcOperandIndex& index);
|
||||
|
||||
DxbcComponentMask getDstOperandMask(
|
||||
const DxbcOperand& operand);
|
||||
|
||||
@ -56,6 +66,9 @@ namespace dxvk {
|
||||
DxbcPointer getInterfaceOperandPtr(
|
||||
const DxbcOperand& operand);
|
||||
|
||||
DxbcPointer getConstantBufferPtr(
|
||||
const DxbcOperand& operand);
|
||||
|
||||
DxbcPointer getOperandPtr(
|
||||
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 result;
|
||||
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 result;
|
||||
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 result;
|
||||
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
|
||||
*
|
||||
@ -40,6 +52,10 @@ namespace dxvk {
|
||||
|
||||
void dclTemps(uint32_t n);
|
||||
|
||||
void dclConstantBuffer(
|
||||
uint32_t bufferId,
|
||||
uint32_t elementCount);
|
||||
|
||||
DxbcValue defConstScalar(uint32_t v);
|
||||
|
||||
DxbcValue defConstVector(
|
||||
@ -49,7 +65,11 @@ namespace dxvk {
|
||||
void fnReturn();
|
||||
|
||||
DxbcPointer ptrTempReg(
|
||||
uint32_t regId);
|
||||
uint32_t regId);
|
||||
|
||||
DxbcPointer ptrConstantBuffer(
|
||||
uint32_t regId,
|
||||
const DxbcValue& index);
|
||||
|
||||
DxbcValue opAbs(
|
||||
const DxbcValue& src);
|
||||
@ -62,6 +82,10 @@ namespace dxvk {
|
||||
const DxbcValue& a,
|
||||
const DxbcValue& b);
|
||||
|
||||
DxbcValue opDot(
|
||||
const DxbcValue& a,
|
||||
const DxbcValue& b);
|
||||
|
||||
DxbcValue opNeg(
|
||||
const DxbcValue& src);
|
||||
|
||||
@ -132,6 +156,8 @@ namespace dxvk {
|
||||
|
||||
std::vector<DxbcPointer> m_rRegs;
|
||||
|
||||
std::array<DxbcConstantBuffer, 16> m_constantBuffers;
|
||||
|
||||
uint32_t defScalarType(
|
||||
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() {
|
||||
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 resultType,
|
||||
uint32_t functionId,
|
||||
|
@ -116,6 +116,11 @@ namespace dxvk {
|
||||
uint32_t memberId,
|
||||
spv::BuiltIn builtIn);
|
||||
|
||||
void memberDecorateOffset(
|
||||
uint32_t structId,
|
||||
uint32_t memberId,
|
||||
uint32_t offset);
|
||||
|
||||
uint32_t defVoidType();
|
||||
|
||||
uint32_t defBoolType();
|
||||
@ -251,6 +256,11 @@ namespace dxvk {
|
||||
uint32_t minVal,
|
||||
uint32_t maxVal);
|
||||
|
||||
uint32_t opDot(
|
||||
uint32_t resultType,
|
||||
uint32_t vector1,
|
||||
uint32_t vector2);
|
||||
|
||||
uint32_t opFunctionCall(
|
||||
uint32_t resultType,
|
||||
uint32_t functionId,
|
||||
|
Loading…
x
Reference in New Issue
Block a user