mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-15 07:29:17 +01:00
[dxbc] Implemented Hull Shader output variables
This commit is contained in:
parent
13331a463f
commit
988aaa0161
@ -586,6 +586,14 @@ namespace dxvk {
|
|||||||
DxbcRegMask regMask,
|
DxbcRegMask regMask,
|
||||||
DxbcSystemValue sv,
|
DxbcSystemValue sv,
|
||||||
DxbcInterpolationMode im) {
|
DxbcInterpolationMode im) {
|
||||||
|
// Add a new system value mapping if needed
|
||||||
|
if (sv != DxbcSystemValue::None)
|
||||||
|
m_oMappings.push_back({ regIdx, regMask, sv });
|
||||||
|
|
||||||
|
// Hull shaders don't use standard outputs
|
||||||
|
if (m_version.type() == DxbcProgramType::HullShader)
|
||||||
|
return;
|
||||||
|
|
||||||
// Avoid declaring the same variable multiple times.
|
// Avoid declaring the same variable multiple times.
|
||||||
// This may happen when multiple system values are
|
// This may happen when multiple system values are
|
||||||
// mapped to different parts of the same register.
|
// mapped to different parts of the same register.
|
||||||
@ -607,10 +615,6 @@ namespace dxvk {
|
|||||||
// Declare the output slot as defined
|
// Declare the output slot as defined
|
||||||
m_interfaceSlots.outputSlots |= 1u << regIdx;
|
m_interfaceSlots.outputSlots |= 1u << regIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new system value mapping if needed
|
|
||||||
if (sv != DxbcSystemValue::None)
|
|
||||||
m_oMappings.push_back({ regIdx, regMask, sv });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1089,6 +1093,9 @@ namespace dxvk {
|
|||||||
// count embedded within the opcode token.
|
// count embedded within the opcode token.
|
||||||
m_hs.vertexCountOut = ins.controls.controlPointCount;
|
m_hs.vertexCountOut = ins.controls.controlPointCount;
|
||||||
|
|
||||||
|
m_hs.outputPerPatch = emitTessInterfacePerPatch (spv::StorageClassOutput);
|
||||||
|
m_hs.outputPerVertex = emitTessInterfacePerVertex(spv::StorageClassOutput, m_hs.vertexCountOut);
|
||||||
|
|
||||||
m_module.setOutputVertices(m_entryPointId, ins.controls.controlPointCount);
|
m_module.setOutputVertices(m_entryPointId, ins.controls.controlPointCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3889,7 +3896,7 @@ namespace dxvk {
|
|||||||
result.type.ctype = DxbcScalarType::Float32;
|
result.type.ctype = DxbcScalarType::Float32;
|
||||||
result.type.ccount = 4;
|
result.type.ccount = 4;
|
||||||
|
|
||||||
std::array<uint32_t, 2> indices = { 0, 0 };
|
std::array<uint32_t, 2> indices = {{ 0, 0 }};
|
||||||
|
|
||||||
for (uint32_t i = 0; i < operand.idxDim; i++)
|
for (uint32_t i = 0; i < operand.idxDim; i++)
|
||||||
indices.at(i) = emitIndexLoad(operand.idx[i]).id;
|
indices.at(i) = emitIndexLoad(operand.idx[i]).id;
|
||||||
@ -3910,28 +3917,49 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxbcRegisterPointer DxbcCompiler::emitGetOutputPtr(
|
DxbcRegisterPointer DxbcCompiler::emitGetOutputPtr(
|
||||||
const DxbcRegister& operand) {
|
const DxbcRegister& operand) {
|
||||||
// Same index format as input registers, except that
|
DxbcRegisterPointer result;
|
||||||
// outputs cannot be accessed with a relative index.
|
result.type.ctype = DxbcScalarType::Float32;
|
||||||
if (operand.idxDim != 1)
|
result.type.ccount = 4;
|
||||||
throw DxvkError("DxbcCompiler: 2D index for o# not yet supported");
|
|
||||||
|
|
||||||
// We don't support two-dimensional indices yet
|
switch (m_version.type()) {
|
||||||
const uint32_t registerId = operand.idx[0].offset;
|
// Pixel shaders have typed output registers, whereas they
|
||||||
|
// are simple float4 vectors in all other shader stages.
|
||||||
|
case DxbcProgramType::PixelShader: {
|
||||||
|
const uint32_t registerId = operand.idx[0].offset;
|
||||||
|
result.type = m_ps.oTypes.at(registerId);
|
||||||
|
result.id = m_oRegs.at(registerId);
|
||||||
|
} break;
|
||||||
|
|
||||||
// In the pixel shader, output registers are typed,
|
// Hull shaders are special in that they have two sets of
|
||||||
// whereas they are float4 in all other stages.
|
// output registers, one for per-patch values and one for
|
||||||
if (m_version.type() == DxbcProgramType::PixelShader) {
|
// per-vertex values.
|
||||||
DxbcRegisterPointer result;
|
case DxbcProgramType::HullShader: {
|
||||||
result.type = m_ps.oTypes.at(registerId);
|
uint32_t registerId = emitIndexLoad(operand.idx[0]).id;
|
||||||
result.id = m_oRegs.at(registerId);
|
uint32_t ptrTypeId = m_module.defPointerType(
|
||||||
return result;
|
getVectorTypeId(result.type),
|
||||||
} else {
|
spv::StorageClassOutput);
|
||||||
DxbcRegisterPointer result;
|
|
||||||
result.type.ctype = DxbcScalarType::Float32;
|
if (m_hs.currPhaseType == DxbcCompilerHsPhase::ControlPoint) {
|
||||||
result.type.ccount = 4;
|
std::array<uint32_t, 2> indices = {{
|
||||||
result.id = m_oRegs.at(registerId);
|
m_module.opLoad(m_module.defIntType(32, 0), m_hs.builtinInvocationId),
|
||||||
return result;
|
registerId,
|
||||||
|
}};
|
||||||
|
|
||||||
|
result.id = m_module.opAccessChain(
|
||||||
|
ptrTypeId, m_hs.outputPerVertex,
|
||||||
|
indices.size(), indices.data());
|
||||||
|
} else {
|
||||||
|
result.id = m_module.opAccessChain(
|
||||||
|
ptrTypeId, m_hs.outputPerPatch,
|
||||||
|
1, ®isterId);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
result.id = m_oRegs.at(operand.idx[0].offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5161,6 +5189,8 @@ namespace dxvk {
|
|||||||
for (const auto& phase : m_hs.joinPhases)
|
for (const auto& phase : m_hs.joinPhases)
|
||||||
this->emitHsForkJoinPhase(phase);
|
this->emitHsForkJoinPhase(phase);
|
||||||
|
|
||||||
|
this->emitHsPhaseBarrier();
|
||||||
|
|
||||||
// TODO set up output variables
|
// TODO set up output variables
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5311,6 +5341,40 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t DxbcCompiler::emitTessInterfacePerPatch(spv::StorageClass storageClass) {
|
||||||
|
const bool isInput = storageClass == spv::StorageClassInput;
|
||||||
|
|
||||||
|
uint32_t vecType = m_module.defVectorType (m_module.defFloatType(32), 4);
|
||||||
|
uint32_t arrType = m_module.defArrayType (vecType, m_module.constu32(32));
|
||||||
|
uint32_t ptrType = m_module.defPointerType(arrType, storageClass);
|
||||||
|
uint32_t varId = m_module.newVar (ptrType, storageClass);
|
||||||
|
|
||||||
|
m_module.setDebugName (varId, isInput ? "vPatch" : "oPatch");
|
||||||
|
m_module.decorate (varId, spv::DecorationPatch);
|
||||||
|
m_module.decorateLocation (varId, 0);
|
||||||
|
|
||||||
|
m_entryPointInterfaces.push_back(varId);
|
||||||
|
return varId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t DxbcCompiler::emitTessInterfacePerVertex(spv::StorageClass storageClass, uint32_t vertexCount) {
|
||||||
|
const bool isInput = storageClass == spv::StorageClassInput;
|
||||||
|
|
||||||
|
uint32_t vecType = m_module.defVectorType (m_module.defFloatType(32), 4);
|
||||||
|
uint32_t arrTypeInner = m_module.defArrayType (vecType, m_module.constu32(32));
|
||||||
|
uint32_t arrTypeOuter = m_module.defArrayType (arrTypeInner, m_module.constu32(vertexCount));
|
||||||
|
uint32_t ptrType = m_module.defPointerType(arrTypeOuter, storageClass);
|
||||||
|
uint32_t varId = m_module.newVar (ptrType, storageClass);
|
||||||
|
|
||||||
|
m_module.setDebugName (varId, isInput ? "vVertex" : "oVertex");
|
||||||
|
m_module.decorateLocation (varId, 32);
|
||||||
|
|
||||||
|
m_entryPointInterfaces.push_back(varId);
|
||||||
|
return varId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t DxbcCompiler::emitNewVariable(const DxbcRegisterInfo& info) {
|
uint32_t DxbcCompiler::emitNewVariable(const DxbcRegisterInfo& info) {
|
||||||
const uint32_t ptrTypeId = this->getPointerTypeId(info);
|
const uint32_t ptrTypeId = this->getPointerTypeId(info);
|
||||||
return m_module.newVar(ptrTypeId, info.sclass);
|
return m_module.newVar(ptrTypeId, info.sclass);
|
||||||
|
@ -206,6 +206,9 @@ namespace dxvk {
|
|||||||
uint32_t builtinTessLevelOuter = 0;
|
uint32_t builtinTessLevelOuter = 0;
|
||||||
uint32_t builtinTessLevelInner = 0;
|
uint32_t builtinTessLevelInner = 0;
|
||||||
|
|
||||||
|
uint32_t outputPerPatch = 0;
|
||||||
|
uint32_t outputPerVertex = 0;
|
||||||
|
|
||||||
DxbcCompilerHsControlPointPhase cpPhase;
|
DxbcCompilerHsControlPointPhase cpPhase;
|
||||||
std::vector<DxbcCompilerHsForkJoinPhase> forkPhases;
|
std::vector<DxbcCompilerHsForkJoinPhase> forkPhases;
|
||||||
std::vector<DxbcCompilerHsForkJoinPhase> joinPhases;
|
std::vector<DxbcCompilerHsForkJoinPhase> joinPhases;
|
||||||
@ -870,6 +873,13 @@ namespace dxvk {
|
|||||||
|
|
||||||
void emitHsPhaseBarrier();
|
void emitHsPhaseBarrier();
|
||||||
|
|
||||||
|
uint32_t emitTessInterfacePerPatch(
|
||||||
|
spv::StorageClass storageClass);
|
||||||
|
|
||||||
|
uint32_t emitTessInterfacePerVertex(
|
||||||
|
spv::StorageClass storageClass,
|
||||||
|
uint32_t vertexCount);
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
// Misc stuff
|
// Misc stuff
|
||||||
void emitDclInputArray(
|
void emitDclInputArray(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user