mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 10:24:12 +01:00
[dxbc] Scan pixel shader output register type at declaration time
Fixes invalid shaders being generated in the Blacksmith demo on some GPUs. Works around a possible issue in the output signature reader. Commit #1000, yay.
This commit is contained in:
parent
8125d53e58
commit
8eb78591a0
@ -37,9 +37,6 @@ namespace dxvk {
|
||||
|
||||
// Make sure our interface registers are clear
|
||||
for (uint32_t i = 0; i < DxbcMaxInterfaceRegs; i++) {
|
||||
m_ps.oTypes.at(i).ctype = DxbcScalarType::Float32;
|
||||
m_ps.oTypes.at(i).ccount = 0;
|
||||
|
||||
m_vRegs.at(i) = 0;
|
||||
m_oRegs.at(i) = 0;
|
||||
}
|
||||
@ -635,9 +632,11 @@ namespace dxvk {
|
||||
// This may happen when multiple system values are
|
||||
// mapped to different parts of the same register.
|
||||
if (m_oRegs.at(regIdx) == 0) {
|
||||
const DxbcVectorType regType = getOutputRegType(regIdx);
|
||||
|
||||
DxbcRegisterInfo info;
|
||||
info.type.ctype = DxbcScalarType::Float32;
|
||||
info.type.ccount = 4;
|
||||
info.type.ctype = regType.ctype;
|
||||
info.type.ccount = regType.ccount;
|
||||
info.type.alength = regDim;
|
||||
info.sclass = spv::StorageClassOutput;
|
||||
|
||||
@ -4093,7 +4092,7 @@ namespace dxvk {
|
||||
// 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.type = getOutputRegType(registerId);
|
||||
result.id = m_oRegs.at(registerId);
|
||||
} break;
|
||||
|
||||
@ -4858,7 +4857,7 @@ namespace dxvk {
|
||||
case DxbcProgramType::GeometryShader: emitGsSystemValueStore(sv, mask, value); break;
|
||||
case DxbcProgramType::HullShader: emitHsSystemValueStore(sv, mask, value); break;
|
||||
case DxbcProgramType::DomainShader: emitDsSystemValueStore(sv, mask, value); break;
|
||||
case DxbcProgramType::PixelShader: break;
|
||||
case DxbcProgramType::PixelShader: emitPsSystemValueStore(sv, mask, value); break;
|
||||
case DxbcProgramType::ComputeShader: break;
|
||||
}
|
||||
}
|
||||
@ -5256,6 +5255,15 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::emitPsSystemValueStore(
|
||||
DxbcSystemValue sv,
|
||||
DxbcRegMask mask,
|
||||
const DxbcRegisterValue& value) {
|
||||
Logger::warn(str::format(
|
||||
"DxbcCompiler: Unhandled GS SV output: ", sv));
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::emitDsSystemValueStore(
|
||||
DxbcSystemValue sv,
|
||||
DxbcRegMask mask,
|
||||
@ -5563,30 +5571,6 @@ namespace dxvk {
|
||||
m_module.setExecutionMode(m_entryPointId,
|
||||
spv::ExecutionModeOriginUpperLeft);
|
||||
|
||||
// Declare pixel shader outputs. According to the Vulkan
|
||||
// documentation, they are required to match the type of
|
||||
// the render target.
|
||||
for (auto e = m_osgn->begin(); e != m_osgn->end(); e++) {
|
||||
if (e->systemValue == DxbcSystemValue::None
|
||||
&& e->registerId != 0xFFFFFFFF /* depth */) {
|
||||
DxbcRegisterInfo info;
|
||||
info.type.ctype = e->componentType;
|
||||
info.type.ccount = e->componentMask.popCount();
|
||||
info.type.alength = 0;
|
||||
info.sclass = spv::StorageClassOutput;
|
||||
|
||||
const uint32_t varId = emitNewVariable(info);
|
||||
|
||||
m_module.decorateLocation(varId, e->registerId);
|
||||
m_module.setDebugName(varId, str::format("o", e->registerId).c_str());
|
||||
m_entryPointInterfaces.push_back(varId);
|
||||
|
||||
m_oRegs.at(e->registerId) = varId;
|
||||
m_ps.oTypes.at(e->registerId).ctype = info.type.ctype;
|
||||
m_ps.oTypes.at(e->registerId).ccount = info.type.ccount;
|
||||
}
|
||||
}
|
||||
|
||||
// Standard input array
|
||||
emitDclInputArray(0);
|
||||
|
||||
@ -6197,6 +6181,26 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
DxbcVectorType DxbcCompiler::getOutputRegType(uint32_t regIdx) const {
|
||||
DxbcVectorType result;
|
||||
result.ctype = DxbcScalarType::Float32;
|
||||
result.ccount = 4;
|
||||
|
||||
// Pixel shader outputs are required to match the type of
|
||||
// the render target, so we'll scan the output signature.
|
||||
if (m_version.type() == DxbcProgramType::PixelShader) {
|
||||
const DxbcSgnEntry* entry = m_osgn->findByRegister(regIdx);
|
||||
|
||||
if (entry != nullptr) {
|
||||
result.ctype = entry->componentType;
|
||||
result.ccount = entry->componentMask.popCount();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
VkImageViewType DxbcCompiler::getViewType(DxbcResourceDim dim) const {
|
||||
switch (dim) {
|
||||
default:
|
||||
|
@ -136,8 +136,6 @@ namespace dxvk {
|
||||
uint32_t builtinSampleMaskIn = 0;
|
||||
uint32_t builtinSampleMaskOut = 0;
|
||||
uint32_t builtinLayer = 0;
|
||||
|
||||
std::array<DxbcVectorType, DxbcMaxInterfaceRegs> oTypes;
|
||||
};
|
||||
|
||||
|
||||
@ -882,6 +880,11 @@ namespace dxvk {
|
||||
DxbcRegMask mask,
|
||||
const DxbcRegisterValue& value);
|
||||
|
||||
void emitPsSystemValueStore(
|
||||
DxbcSystemValue sv,
|
||||
DxbcRegMask mask,
|
||||
const DxbcRegisterValue& value);
|
||||
|
||||
///////////////////////////////
|
||||
// Special system value stores
|
||||
void emitClipCullStore(
|
||||
@ -1001,6 +1004,9 @@ namespace dxvk {
|
||||
DxbcVectorType getInputRegType(
|
||||
uint32_t regIdx) const;
|
||||
|
||||
DxbcVectorType getOutputRegType(
|
||||
uint32_t regIdx) const;
|
||||
|
||||
VkImageViewType getViewType(
|
||||
DxbcResourceDim dim) const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user