mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 19: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
|
// Make sure our interface registers are clear
|
||||||
for (uint32_t i = 0; i < DxbcMaxInterfaceRegs; i++) {
|
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_vRegs.at(i) = 0;
|
||||||
m_oRegs.at(i) = 0;
|
m_oRegs.at(i) = 0;
|
||||||
}
|
}
|
||||||
@ -635,9 +632,11 @@ namespace dxvk {
|
|||||||
// 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.
|
||||||
if (m_oRegs.at(regIdx) == 0) {
|
if (m_oRegs.at(regIdx) == 0) {
|
||||||
|
const DxbcVectorType regType = getOutputRegType(regIdx);
|
||||||
|
|
||||||
DxbcRegisterInfo info;
|
DxbcRegisterInfo info;
|
||||||
info.type.ctype = DxbcScalarType::Float32;
|
info.type.ctype = regType.ctype;
|
||||||
info.type.ccount = 4;
|
info.type.ccount = regType.ccount;
|
||||||
info.type.alength = regDim;
|
info.type.alength = regDim;
|
||||||
info.sclass = spv::StorageClassOutput;
|
info.sclass = spv::StorageClassOutput;
|
||||||
|
|
||||||
@ -4093,7 +4092,7 @@ namespace dxvk {
|
|||||||
// are simple float4 vectors in all other shader stages.
|
// are simple float4 vectors in all other shader stages.
|
||||||
case DxbcProgramType::PixelShader: {
|
case DxbcProgramType::PixelShader: {
|
||||||
const uint32_t registerId = operand.idx[0].offset;
|
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);
|
result.id = m_oRegs.at(registerId);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -4858,7 +4857,7 @@ namespace dxvk {
|
|||||||
case DxbcProgramType::GeometryShader: emitGsSystemValueStore(sv, mask, value); break;
|
case DxbcProgramType::GeometryShader: emitGsSystemValueStore(sv, mask, value); break;
|
||||||
case DxbcProgramType::HullShader: emitHsSystemValueStore(sv, mask, value); break;
|
case DxbcProgramType::HullShader: emitHsSystemValueStore(sv, mask, value); break;
|
||||||
case DxbcProgramType::DomainShader: emitDsSystemValueStore(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;
|
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(
|
void DxbcCompiler::emitDsSystemValueStore(
|
||||||
DxbcSystemValue sv,
|
DxbcSystemValue sv,
|
||||||
DxbcRegMask mask,
|
DxbcRegMask mask,
|
||||||
@ -5563,30 +5571,6 @@ namespace dxvk {
|
|||||||
m_module.setExecutionMode(m_entryPointId,
|
m_module.setExecutionMode(m_entryPointId,
|
||||||
spv::ExecutionModeOriginUpperLeft);
|
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
|
// Standard input array
|
||||||
emitDclInputArray(0);
|
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 {
|
VkImageViewType DxbcCompiler::getViewType(DxbcResourceDim dim) const {
|
||||||
switch (dim) {
|
switch (dim) {
|
||||||
default:
|
default:
|
||||||
|
@ -136,8 +136,6 @@ namespace dxvk {
|
|||||||
uint32_t builtinSampleMaskIn = 0;
|
uint32_t builtinSampleMaskIn = 0;
|
||||||
uint32_t builtinSampleMaskOut = 0;
|
uint32_t builtinSampleMaskOut = 0;
|
||||||
uint32_t builtinLayer = 0;
|
uint32_t builtinLayer = 0;
|
||||||
|
|
||||||
std::array<DxbcVectorType, DxbcMaxInterfaceRegs> oTypes;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -882,6 +880,11 @@ namespace dxvk {
|
|||||||
DxbcRegMask mask,
|
DxbcRegMask mask,
|
||||||
const DxbcRegisterValue& value);
|
const DxbcRegisterValue& value);
|
||||||
|
|
||||||
|
void emitPsSystemValueStore(
|
||||||
|
DxbcSystemValue sv,
|
||||||
|
DxbcRegMask mask,
|
||||||
|
const DxbcRegisterValue& value);
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
// Special system value stores
|
// Special system value stores
|
||||||
void emitClipCullStore(
|
void emitClipCullStore(
|
||||||
@ -1001,6 +1004,9 @@ namespace dxvk {
|
|||||||
DxbcVectorType getInputRegType(
|
DxbcVectorType getInputRegType(
|
||||||
uint32_t regIdx) const;
|
uint32_t regIdx) const;
|
||||||
|
|
||||||
|
DxbcVectorType getOutputRegType(
|
||||||
|
uint32_t regIdx) const;
|
||||||
|
|
||||||
VkImageViewType getViewType(
|
VkImageViewType getViewType(
|
||||||
DxbcResourceDim dim) const;
|
DxbcResourceDim dim) const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user