diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 3cdc0bf79..8d7f38b21 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1681,10 +1681,9 @@ namespace dxvk { return E_INVALIDARG; const auto& extensions = m_dxvkDevice->extensions(); - const auto& features = m_dxvkDevice->features(); info->PSSpecifiedStencilRefSupported = extensions.extShaderStencilExport; - info->TypedUAVLoadAdditionalFormats = features.core.features.shaderStorageImageReadWithoutFormat; + info->TypedUAVLoadAdditionalFormats = m_dxbcOptions.supportsTypedUavLoadExtended; info->ROVsSupported = FALSE; info->ConservativeRasterizationTier = D3D11_CONSERVATIVE_RASTERIZATION_NOT_SUPPORTED; info->MapOnDefaultTextures = TRUE; @@ -1977,7 +1976,6 @@ namespace dxvk { enabled.core.features.multiDrawIndirect = VK_TRUE; enabled.core.features.shaderFloat64 = supported.core.features.shaderFloat64; enabled.core.features.shaderInt64 = supported.core.features.shaderInt64; - enabled.core.features.shaderStorageImageReadWithoutFormat = supported.core.features.shaderStorageImageReadWithoutFormat; enabled.core.features.tessellationShader = VK_TRUE; } diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 9317eac06..da0e481b1 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -454,7 +454,7 @@ namespace dxvk { D3D11StateObjectSet m_rsStateObjects; D3D11StateObjectSet m_samplerObjects; D3D11ShaderModuleSet m_shaderModules; - + HRESULT CreateShaderModule( D3D11CommonShader* pShaderModule, DxvkShaderKey ShaderKey, diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 70aaa2e3f..c3028fbe4 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -876,7 +876,7 @@ namespace dxvk { const bool isUav = ins.op == DxbcOpcode::DclUavTyped; if (isUav) { - if (m_moduleInfo.options.useStorageImageReadWithoutFormat) + if (m_moduleInfo.options.supportsTypedUavLoadR32) m_module.enableCapability(spv::CapabilityStorageImageReadWithoutFormat); m_module.enableCapability(spv::CapabilityStorageImageWriteWithoutFormat); } @@ -951,7 +951,7 @@ namespace dxvk { if (isUav) { if ((m_analysis->uavInfos[registerId].accessAtomicOp) || (m_analysis->uavInfos[registerId].accessTypedLoad - && !m_moduleInfo.options.useStorageImageReadWithoutFormat)) + && !m_moduleInfo.options.supportsTypedUavLoadR32)) imageFormat = getScalarImageFormat(sampledType); } diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index f4f8b1726..f6b111a12 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -17,8 +17,6 @@ namespace dxvk { useDepthClipWorkaround = !devFeatures.extDepthClipEnable.depthClipEnable; - useStorageImageReadWithoutFormat - = devFeatures.core.features.shaderStorageImageReadWithoutFormat; useSubgroupOpsForAtomicCounters = (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_COMPUTE_BIT) && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); @@ -28,7 +26,41 @@ namespace dxvk { = (devInfo.vk11.subgroupSize >= 4) && (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); - + + supportsTypedUavLoadR32 = true; + supportsTypedUavLoadExtended = true; + + static const std::array, 18> s_typedUavFormats = { + std::make_pair(VK_FORMAT_R32_SFLOAT, false), + std::make_pair(VK_FORMAT_R32_UINT, false), + std::make_pair(VK_FORMAT_R32_SINT, false), + std::make_pair(VK_FORMAT_R32G32B32A32_SFLOAT, true), + std::make_pair(VK_FORMAT_R32G32B32A32_UINT, true), + std::make_pair(VK_FORMAT_R32G32B32A32_SINT, true), + std::make_pair(VK_FORMAT_R16G16B16A16_SFLOAT, true), + std::make_pair(VK_FORMAT_R16G16B16A16_UINT, true), + std::make_pair(VK_FORMAT_R16G16B16A16_SINT, true), + std::make_pair(VK_FORMAT_R8G8B8A8_UNORM, true), + std::make_pair(VK_FORMAT_R8G8B8A8_UINT, true), + std::make_pair(VK_FORMAT_R8G8B8A8_SINT, true), + std::make_pair(VK_FORMAT_R16_SFLOAT, true), + std::make_pair(VK_FORMAT_R16_UINT, true), + std::make_pair(VK_FORMAT_R16_SINT, true), + std::make_pair(VK_FORMAT_R8_UNORM, true), + std::make_pair(VK_FORMAT_R8_UINT, true), + std::make_pair(VK_FORMAT_R8_SINT, true), + }; + + for (const auto& f : s_typedUavFormats) { + DxvkFormatFeatures features = device->getFormatFeatures(f.first); + VkFormatFeatureFlags2 imgFeatures = features.optimal | features.linear; + + if (!(imgFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT)) { + supportsTypedUavLoadR32 &= f.second; + supportsTypedUavLoadExtended = false; + } + } + switch (device->config().useRawSsbo) { case Tristate::Auto: minSsboAlignment = devInfo.core.properties.limits.minStorageBufferOffsetAlignment; break; case Tristate::True: minSsboAlignment = 4u; break; diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index 1edec4c7b..3d13ad6a8 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -23,8 +23,10 @@ namespace dxvk { // clip device feature is not supported bool useDepthClipWorkaround = false; - /// Use the ShaderImageReadWithoutFormat capability. - bool useStorageImageReadWithoutFormat = false; + /// Determines whether format qualifiers + /// on typed UAV loads are required + bool supportsTypedUavLoadR32 = false; + bool supportsTypedUavLoadExtended = false; /// Use subgroup operations to reduce the number of /// atomic operations for append/consume buffers.