[dxbc] Do not emit depth compare for unsupported image types

Fixes invalid SPIR-V.
This commit is contained in:
Philip Rebohle 2024-03-07 16:10:50 +01:00
parent 707ad6f328
commit 69a52b3da0
1 changed files with 113 additions and 98 deletions

View File

@ -3881,33 +3881,38 @@ namespace dxvk {
if (imageOperands.sparse) if (imageOperands.sparse)
resultTypeId = getSparseResultTypeId(texelTypeId); resultTypeId = getSparseResultTypeId(texelTypeId);
switch (ins.op) { if (sampledImageId) {
// Simple image gather operation switch (ins.op) {
case DxbcOpcode::Gather4: // Simple image gather operation
case DxbcOpcode::Gather4S: case DxbcOpcode::Gather4:
case DxbcOpcode::Gather4Po: case DxbcOpcode::Gather4S:
case DxbcOpcode::Gather4PoS: { case DxbcOpcode::Gather4Po:
resultId = m_module.opImageGather( case DxbcOpcode::Gather4PoS: {
resultTypeId, sampledImageId, coord.id, resultId = m_module.opImageGather(
m_module.consti32(samplerReg.swizzle[0]), resultTypeId, sampledImageId, coord.id,
imageOperands); m_module.consti32(samplerReg.swizzle[0]),
} break; imageOperands);
} break;
// Depth-compare operation
case DxbcOpcode::Gather4C: // Depth-compare operation
case DxbcOpcode::Gather4CS: case DxbcOpcode::Gather4C:
case DxbcOpcode::Gather4PoC: case DxbcOpcode::Gather4CS:
case DxbcOpcode::Gather4PoCS: { case DxbcOpcode::Gather4PoC:
resultId = m_module.opImageDrefGather( case DxbcOpcode::Gather4PoCS: {
resultTypeId, sampledImageId, coord.id, resultId = m_module.opImageDrefGather(
referenceValue.id, imageOperands); resultTypeId, sampledImageId, coord.id,
} break; referenceValue.id, imageOperands);
} break;
default:
Logger::warn(str::format( default:
"DxbcCompiler: Unhandled instruction: ", Logger::warn(str::format(
ins.op)); "DxbcCompiler: Unhandled instruction: ",
return; ins.op));
return;
}
} else {
Logger::warn(str::format("DxbcCompiler: ", ins.op, ": Unsupported image type"));
resultId = m_module.constNull(resultTypeId);
} }
// If necessary, deal with the sparse result // If necessary, deal with the sparse result
@ -4035,73 +4040,78 @@ namespace dxvk {
if (imageOperands.sparse) if (imageOperands.sparse)
resultTypeId = getSparseResultTypeId(texelTypeId); resultTypeId = getSparseResultTypeId(texelTypeId);
switch (ins.op) { if (sampledImageId) {
// Simple image sample operation switch (ins.op) {
case DxbcOpcode::Sample: // Simple image sample operation
case DxbcOpcode::SampleClampS: { case DxbcOpcode::Sample:
resultId = m_module.opImageSampleImplicitLod( case DxbcOpcode::SampleClampS: {
resultTypeId, sampledImageId, coord.id, resultId = m_module.opImageSampleImplicitLod(
imageOperands); resultTypeId, sampledImageId, coord.id,
} break; imageOperands);
} break;
// Depth-compare operation
case DxbcOpcode::SampleC: // Depth-compare operation
case DxbcOpcode::SampleCClampS: { case DxbcOpcode::SampleC:
resultId = m_module.opImageSampleDrefImplicitLod( case DxbcOpcode::SampleCClampS: {
resultTypeId, sampledImageId, coord.id, resultId = m_module.opImageSampleDrefImplicitLod(
referenceValue.id, imageOperands); resultTypeId, sampledImageId, coord.id,
} break; referenceValue.id, imageOperands);
} break;
// Depth-compare operation on mip level zero
case DxbcOpcode::SampleClz: // Depth-compare operation on mip level zero
case DxbcOpcode::SampleClzS: { case DxbcOpcode::SampleClz:
imageOperands.flags |= spv::ImageOperandsLodMask; case DxbcOpcode::SampleClzS: {
imageOperands.sLod = m_module.constf32(0.0f); imageOperands.flags |= spv::ImageOperandsLodMask;
imageOperands.sLod = m_module.constf32(0.0f);
resultId = m_module.opImageSampleDrefExplicitLod(
resultTypeId, sampledImageId, coord.id, resultId = m_module.opImageSampleDrefExplicitLod(
referenceValue.id, imageOperands); resultTypeId, sampledImageId, coord.id,
} break; referenceValue.id, imageOperands);
} break;
// Sample operation with explicit gradients
case DxbcOpcode::SampleD: // Sample operation with explicit gradients
case DxbcOpcode::SampleDClampS: { case DxbcOpcode::SampleD:
imageOperands.flags |= spv::ImageOperandsGradMask; case DxbcOpcode::SampleDClampS: {
imageOperands.sGradX = explicitGradientX.id; imageOperands.flags |= spv::ImageOperandsGradMask;
imageOperands.sGradY = explicitGradientY.id; imageOperands.sGradX = explicitGradientX.id;
imageOperands.sGradY = explicitGradientY.id;
resultId = m_module.opImageSampleExplicitLod(
resultTypeId, sampledImageId, coord.id, resultId = m_module.opImageSampleExplicitLod(
imageOperands); resultTypeId, sampledImageId, coord.id,
} break; imageOperands);
} break;
// Sample operation with explicit LOD
case DxbcOpcode::SampleL: // Sample operation with explicit LOD
case DxbcOpcode::SampleLS: { case DxbcOpcode::SampleL:
imageOperands.flags |= spv::ImageOperandsLodMask; case DxbcOpcode::SampleLS: {
imageOperands.sLod = lod.id; imageOperands.flags |= spv::ImageOperandsLodMask;
imageOperands.sLod = lod.id;
resultId = m_module.opImageSampleExplicitLod(
resultTypeId, sampledImageId, coord.id, resultId = m_module.opImageSampleExplicitLod(
imageOperands); resultTypeId, sampledImageId, coord.id,
} break; imageOperands);
} break;
// Sample operation with LOD bias
case DxbcOpcode::SampleB: // Sample operation with LOD bias
case DxbcOpcode::SampleBClampS: { case DxbcOpcode::SampleB:
imageOperands.flags |= spv::ImageOperandsBiasMask; case DxbcOpcode::SampleBClampS: {
imageOperands.sLodBias = lod.id; imageOperands.flags |= spv::ImageOperandsBiasMask;
imageOperands.sLodBias = lod.id;
resultId = m_module.opImageSampleImplicitLod(
resultTypeId, sampledImageId, coord.id, resultId = m_module.opImageSampleImplicitLod(
imageOperands); resultTypeId, sampledImageId, coord.id,
} break; imageOperands);
} break;
default:
Logger::warn(str::format( default:
"DxbcCompiler: Unhandled instruction: ", Logger::warn(str::format(
ins.op)); "DxbcCompiler: Unhandled instruction: ",
return; ins.op));
return;
}
} else {
Logger::warn(str::format("DxbcCompiler: ", ins.op, ": Unsupported image type"));
resultId = m_module.constNull(resultTypeId);
} }
DxbcRegisterValue result; DxbcRegisterValue result;
@ -5147,10 +5157,15 @@ namespace dxvk {
const DxbcShaderResource& textureResource, const DxbcShaderResource& textureResource,
const DxbcSampler& samplerResource, const DxbcSampler& samplerResource,
bool isDepthCompare) { bool isDepthCompare) {
const uint32_t sampledImageType = isDepthCompare uint32_t baseId = isDepthCompare
? m_module.defSampledImageType(textureResource.depthTypeId) ? textureResource.depthTypeId
: m_module.defSampledImageType(textureResource.colorTypeId); : textureResource.colorTypeId;
if (!baseId)
return 0;
uint32_t sampledImageType = m_module.defSampledImageType(baseId);
return m_module.opSampledImage(sampledImageType, return m_module.opSampledImage(sampledImageType,
m_module.opLoad(textureResource.imageTypeId, textureResource.varId), m_module.opLoad(textureResource.imageTypeId, textureResource.varId),
m_module.opLoad(samplerResource.typeId, samplerResource.varId)); m_module.opLoad(samplerResource.typeId, samplerResource.varId));