Selaa lähdekoodia

Merge pull request #89038 from RandomShaper/d3d12_sm

Direct3D 12: Fix shader model support check for devices not aware of the highest ones
Rémi Verschelde 1 vuosi sitten
vanhempi
commit
a47e38b175
1 muutettua tiedostoa jossa 33 lisäystä ja 9 poistoa
  1. 33 9
      drivers/d3d12/rendering_device_driver_d3d12.cpp

+ 33 - 9
drivers/d3d12/rendering_device_driver_d3d12.cpp

@@ -6142,20 +6142,44 @@ Error RenderingDeviceDriverD3D12::_check_capabilities() {
 	multiview_capabilities.is_supported = false;
 	multiview_capabilities.is_supported = false;
 	subgroup_capabilities.size = 0;
 	subgroup_capabilities.size = 0;
 	subgroup_capabilities.wave_ops_supported = false;
 	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;
 	shader_capabilities.native_16bit_ops = false;
 	storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported = false;
 	storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported = false;
 	format_capabilities.relaxed_casting_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).
+		};
+
+		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))
 
 
-	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));
+		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 = {};
 	D3D12_FEATURE_DATA_D3D12_OPTIONS options = {};
 	res = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options));
 	res = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options));