From 584ee6b6f062fc27acf4a48f2145060b4a6ef7f0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 21 Mar 2018 12:47:53 +0100 Subject: [PATCH] [dxbc] Lift ShaderStorageImageReadWithoutFormat requirement --- src/dxbc/dxbc_compiler.cpp | 10 +++++++++- src/dxbc/dxbc_options.cpp | 22 +++++++++------------- src/dxbc/dxbc_options.h | 4 ++++ src/spirv/spirv_module.cpp | 7 ++----- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 435703a0f..93df5d9de 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 35d32346e..a5ea3f8a9 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 44ae84c5e..74b8db2f5 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 ed1533acb..f8f3e13e0 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; - } } }