diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 435703a0..93df5d9d 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -741,7 +741,8 @@ namespace dxvk { const bool isUav = ins.op == DxbcOpcode::DclUavTyped; if (isUav) { - m_module.enableCapability(spv::CapabilityStorageImageReadWithoutFormat); + if (m_options.useStorageImageReadWithoutFormat) + m_module.enableCapability(spv::CapabilityStorageImageReadWithoutFormat); m_module.enableCapability(spv::CapabilityStorageImageWriteWithoutFormat); } @@ -3136,6 +3137,13 @@ namespace dxvk { const DxbcRegisterValue texCoord = emitRegisterLoad( ins.src[0], getTexCoordMask(uavInfo.imageInfo)); + // If the read-without-format capability is not + // set. we must define the image format explicitly. + if (!m_options.useStorageImageReadWithoutFormat) { + m_module.setImageTypeFormat(uavInfo.imageTypeId, + getScalarImageFormat(uavInfo.sampledType)); + } + // Load source value from the UAV DxbcRegisterValue uavValue; uavValue.type.ctype = uavInfo.sampledType; diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index 35d32346..a5ea3f8a 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -3,27 +3,23 @@ namespace dxvk { DxbcOptions::DxbcOptions(const Rc& device) { - const VkPhysicalDeviceProperties deviceProps - = device->adapter()->deviceProperties(); + const VkPhysicalDeviceProperties devProps = device->adapter()->deviceProperties(); + const VkPhysicalDeviceFeatures devFeatures = device->features(); - const DxvkGpuVendor vendor - = static_cast(deviceProps.vendorID); + // Apply driver-specific workarounds + const DxvkGpuVendor vendor = static_cast(devProps.vendorID); if (vendor == DxvkGpuVendor::Nvidia) { - // The driver expects the coordinate - // vector to have an extra component + // Older versions of the driver expect the + // coordinate vector to have an extra component this->addExtraDrefCoordComponent = true; - // From vkd3d: NMin/NMax/NClamp crash the driver. + // From vkd3d: NMin/NMax/NClamp may crash the driver. this->useSimpleMinMaxClamp = true; } - // Inform the user about which workarounds are enabled - if (this->addExtraDrefCoordComponent) - Logger::warn("DxbcOptions: Growing coordinate vector for Dref operations"); - - if (this->useSimpleMinMaxClamp) - Logger::warn("DxbcOptions: Using FMin/FMax/FClamp instead of NMin/NMax/NClamp"); + // Enable certain features if they are supported by the device + this->useStorageImageReadWithoutFormat = devFeatures.shaderStorageImageReadWithoutFormat; } } \ No newline at end of file diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index 44ae84c5..74b8db2f 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -20,6 +20,10 @@ namespace dxvk { /// Use Fmin/Fmax instead of Nmin/Nmax. bool useSimpleMinMaxClamp = false; + + /// If \c false, image read operations can only be performed + /// on storage images with a scalar 32-bit image formats. + bool useStorageImageReadWithoutFormat = false; }; } \ No newline at end of file diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index ed1533ac..f8f3e13e 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -624,12 +624,9 @@ namespace dxvk { uint32_t imageType, spv::ImageFormat format) { for (auto ins : m_typeConstDefs) { - bool match = ins.arg(1) == imageType; - - if (match) { + if (ins.arg(1) == imageType + && ins.arg(8) == spv::ImageFormatUnknown) ins.setArg(8, format); - return; - } } }