From bed48f37aa7d18dbab81d3bf844e09f8eb00e305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Fri, 1 Mar 2024 12:58:25 +0100 Subject: [PATCH] Direct3D 12: Fix shader model support check for devices not aware of the highest ones --- .../d3d12/rendering_device_driver_d3d12.cpp | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index 381d022a55a..b4bbc44d937 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -6142,20 +6142,44 @@ Error RenderingDeviceDriverD3D12::_check_capabilities() { multiview_capabilities.is_supported = false; subgroup_capabilities.size = 0; subgroup_capabilities.wave_ops_supported = false; - shader_capabilities.shader_model = D3D_SHADER_MODEL_6_0; + shader_capabilities.shader_model = (D3D_SHADER_MODEL)0; shader_capabilities.native_16bit_ops = false; storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported = false; format_capabilities.relaxed_casting_supported = false; - // Check shader model. - D3D12_FEATURE_DATA_SHADER_MODEL shader_model = {}; - shader_model.HighestShaderModel = MIN(D3D_HIGHEST_SHADER_MODEL, D3D_SHADER_MODEL_6_6); - res = device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shader_model, sizeof(shader_model)); - ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ERR_CANT_CREATE, "CheckFeatureSupport failed with error " + vformat("0x%08ux", (uint64_t)res) + "."); + { + static const D3D_SHADER_MODEL SMS_TO_CHECK[] = { + D3D_SHADER_MODEL_6_6, + D3D_SHADER_MODEL_6_5, + D3D_SHADER_MODEL_6_4, + D3D_SHADER_MODEL_6_3, + D3D_SHADER_MODEL_6_2, + D3D_SHADER_MODEL_6_1, + D3D_SHADER_MODEL_6_0, // Determined by NIR (dxil_min_shader_model). + }; - shader_capabilities.shader_model = shader_model.HighestShaderModel; - print_verbose("- Shader:"); - print_verbose(" model: " + itos(shader_capabilities.shader_model >> 4) + "." + itos(shader_capabilities.shader_model & 0xf)); + D3D12_FEATURE_DATA_SHADER_MODEL shader_model = {}; + for (uint32_t i = 0; i < ARRAY_SIZE(SMS_TO_CHECK); i++) { + shader_model.HighestShaderModel = SMS_TO_CHECK[i]; + res = device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shader_model, sizeof(shader_model)); + if (SUCCEEDED(res)) { + shader_capabilities.shader_model = shader_model.HighestShaderModel; + break; + } + if (res == E_INVALIDARG) { + continue; // Must assume the device doesn't know about the SM just checked. + } + ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ERR_CANT_CREATE, "CheckFeatureSupport failed with error " + vformat("0x%08ux", (uint64_t)res) + "."); + } + +#define D3D_SHADER_MODEL_TO_STRING(m_sm) vformat("%d.%d", (m_sm >> 4), (m_sm & 0xf)) + + ERR_FAIL_COND_V_MSG(!shader_capabilities.shader_model, ERR_UNAVAILABLE, + vformat("No support for any of the suitable shader models (%s-%s) has been found.", D3D_SHADER_MODEL_TO_STRING(SMS_TO_CHECK[ARRAY_SIZE(SMS_TO_CHECK) - 1]), D3D_SHADER_MODEL_TO_STRING(SMS_TO_CHECK[0]))); + + print_verbose("- Shader:"); + print_verbose(" model: " + D3D_SHADER_MODEL_TO_STRING(shader_capabilities.shader_model)); + } D3D12_FEATURE_DATA_D3D12_OPTIONS options = {}; res = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options));