[dxbc] Implemented some very basic load/store operations

This commit is contained in:
Philip Rebohle 2017-11-13 02:07:13 +01:00
parent 43dfba2287
commit 901abe4356
8 changed files with 215 additions and 19 deletions

View File

@ -25,12 +25,10 @@ namespace dxvk {
case DxbcOpcode::DclInputPs:
case DxbcOpcode::DclInputPsSiv:
case DxbcOpcode::DclInputPsSgv:
return this->dclInput(ins);
case DxbcOpcode::DclOutput:
case DxbcOpcode::DclOutputSiv:
case DxbcOpcode::DclOutputSgv:
return this->dclOutput(ins);
return this->dclInterfaceVar(ins);
case DxbcOpcode::DclTemps:
return this->dclTemps(ins);
@ -53,12 +51,7 @@ namespace dxvk {
}
void DxbcCompiler::dclInput(const DxbcInstruction& ins) {
}
void DxbcCompiler::dclOutput(const DxbcInstruction& ins) {
void DxbcCompiler::dclInterfaceVar(const DxbcInstruction& ins) {
}

View File

@ -30,10 +30,7 @@ namespace dxvk {
void dclGlobalFlags(
const DxbcInstruction& ins);
void dclInput(
const DxbcInstruction& ins);
void dclOutput(
void dclInterfaceVar(
const DxbcInstruction& ins);
void dclTemps(

View File

@ -41,6 +41,84 @@ namespace dxvk {
}
DxbcPointer DxbcCodeGen::ptrTempReg(uint32_t regId) {
return m_rRegs.at(regId);
}
DxbcValue DxbcCodeGen::vecStore(
const DxbcValue& dst,
const DxbcValue& src,
DxbcComponentMask mask) {
DxbcValue result;
result.type = dst.type;
if (dst.type.componentCount == 1) {
// Both values are scalar, so the first component
// of the write mask decides which one to take.
result.valueId = mask.test(0)
? src.valueId : dst.valueId;
} else if (src.type.componentCount == 1) {
// The source value is scalar. Since OpVectorShuffle
// requires both arguments to be vectors, we have to
// use OpCompositeInsert to modify the vector instead.
const uint32_t componentId = mask.firstComponent();
result.valueId = m_module.opCompositeInsert(
this->defValueType(result.type),
src.valueId, dst.valueId,
1, &componentId);
} else {
// Both arguments are vectors. We can determine which
// components to take from which vector and use the
// OpVectorShuffle instruction.
std::array<uint32_t, 4> components;
uint32_t srcComponentId = dst.type.componentCount;
for (uint32_t i = 0; i < dst.type.componentCount; i++)
components[i] = mask.test(i) ? srcComponentId++ : i;
result.valueId = m_module.opVectorShuffle(
this->defValueType(result.type),
dst.valueId, src.valueId,
dst.type.componentCount,
components.data());
}
return result;
}
DxbcValue DxbcCodeGen::regLoad(const DxbcPointer& ptr) {
DxbcValue result;
result.type = ptr.type.valueType;
result.valueId = m_module.opLoad(
this->defValueType(result.type),
ptr.valueId);
return result;
}
void DxbcCodeGen::regStore(
const DxbcPointer& ptr,
const DxbcValue& val,
DxbcComponentMask mask) {
if (ptr.type.valueType.componentCount != val.type.componentCount) {
// In case we write to only a part of the destination
// register, we need to load the previous value first
// and then update the given components.
DxbcValue tmp = this->regLoad(ptr);
tmp = this->vecStore(tmp, val, mask);
m_module.opStore(ptr.valueId, tmp.valueId);
} else {
// All destination components get written, so we don't
// need to load and modify the target register first.
m_module.opStore(ptr.valueId, val.valueId);
}
}
Rc<DxbcCodeGen> DxbcCodeGen::create(
const DxbcProgramVersion& version) {
switch (version.type()) {

View File

@ -37,12 +37,6 @@ namespace dxvk {
virtual ~DxbcCodeGen();
/**
* \brief Declares temporary registers
* \param [in] n Number of temp registers
*/
void dclTemps(uint32_t n);
/**
* \brief Declares an interface variable
*
@ -59,6 +53,86 @@ namespace dxvk {
DxbcComponentMask regMask,
DxbcSystemValue sv) = 0;
/**
* \brief Declares temporary registers
* \param [in] n Number of temp registers
*/
void dclTemps(uint32_t n);
/**
* \brief Retrieves temporary register pointer
*
* Provides access to a temporary register.
* \param [in] regId Register index
* \returns Register pointer
*/
DxbcPointer ptrTempReg(
uint32_t regId);
/**
* \brief Writes to parts of a vector register
*
* Note that the source value must not have the
* same number of components as the write mask.
* \param [in] dst Destination value ID
* \param [in] src Source value ID
* \param [in] mask Write mask
* \returns New destination value ID
*/
DxbcValue vecStore(
const DxbcValue& dst,
const DxbcValue& src,
DxbcComponentMask mask);
/**
* \brief Loads register
*
* \param [in] ptr Register pointer
* \returns The register value ID
*/
DxbcValue regLoad(
const DxbcPointer& ptr);
/**
* \brief Stores register
*
* \param [in] ptr Register pointer
* \param [in] val Value ID to store
* \param [in] mask Write mask
*/
void regStore(
const DxbcPointer& ptr,
const DxbcValue& val,
DxbcComponentMask mask);
/**
* \brief Pointer to an interface variable
*
* Provides access to an interface variable.
* \param [in] regType Register type
* \param [in] regId Register index
* \returns Register pointer
*/
virtual void ptrInterfaceVar(
DxbcOperandType regType,
uint32_t regId) = 0;
/**
* \brief Pointer to an interface variable
*
* Provides access to an indexed interface variable.
* Some shader types may have indexed input or output
* variables that can be accesswed via an array index.
* \param [in] regType Register type
* \param [in] regId Register index
* \param [in] index Array index
* \returns Register pointer
*/
virtual void ptrInterfaceVarIndexed(
DxbcOperandType regType,
uint32_t regId,
const DxbcValue& index) = 0;
/**
* \brief Finalizes shader
*

View File

@ -6,6 +6,7 @@ namespace dxvk {
m_outPerVertex = m_module.newVar(
m_module.defPointerType(this->defPerVertexBlock(), spv::StorageClassOutput),
spv::StorageClassOutput);
m_module.setDebugName(m_outPerVertex, "vs_out");
}
@ -24,6 +25,23 @@ namespace dxvk {
}
void DxbcVsCodeGen::ptrInterfaceVar(
DxbcOperandType regType,
uint32_t regId) {
}
void DxbcVsCodeGen::ptrInterfaceVarIndexed(
DxbcOperandType regType,
uint32_t regId,
const DxbcValue& index) {
throw DxvkError(str::format(
"DxbcVsCodeGen::ptrInterfaceVarIndexed:\n",
"Vertex shaders do not support indexed interface variables"));
}
Rc<DxvkShader> DxbcVsCodeGen::finalize() {
m_module.addEntryPoint(m_entryPointId,
spv::ExecutionModelVertex, "main",

View File

@ -21,6 +21,15 @@ namespace dxvk {
DxbcComponentMask regMask,
DxbcSystemValue sv);
void ptrInterfaceVar(
DxbcOperandType regType,
uint32_t regId);
void ptrInterfaceVarIndexed(
DxbcOperandType regType,
uint32_t regId,
const DxbcValue& index);
Rc<DxvkShader> finalize() final;
private:

View File

@ -444,6 +444,26 @@ namespace dxvk {
}
uint32_t SpirvModule::opCompositeInsert(
uint32_t resultType,
uint32_t object,
uint32_t composite,
uint32_t indexCount,
const uint32_t* indexArray) {
uint32_t resultId = this->allocateId();
m_code.putIns (spv::OpCompositeInsert, 5 + indexCount);
m_code.putWord(resultType);
m_code.putWord(resultId);
m_code.putWord(object);
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,

View File

@ -165,6 +165,13 @@ namespace dxvk {
uint32_t indexCount,
const uint32_t* indexArray);
uint32_t opCompositeInsert(
uint32_t resultType,
uint32_t object,
uint32_t composite,
uint32_t indexCount,
const uint32_t* indexArray);
uint32_t opVectorShuffle(
uint32_t resultType,
uint32_t vectorLeft,