Browse Source

Merge pull request #87570 from RandomShaper/d3d12_defensive

Direct3D 12: Make format feature check more defensive
Rémi Verschelde 1 year ago
parent
commit
b8b0eea1f8
1 changed files with 8 additions and 4 deletions
  1. 8 4
      drivers/d3d12/rendering_device_driver_d3d12.cpp

+ 8 - 4
drivers/d3d12/rendering_device_driver_d3d12.cpp

@@ -1579,15 +1579,19 @@ void RenderingDeviceDriverD3D12::texture_unmap(TextureID p_texture) {
 BitField<RDD::TextureUsageBits> RenderingDeviceDriverD3D12::texture_get_usages_supported_by_format(DataFormat p_format, bool p_cpu_readable) {
 BitField<RDD::TextureUsageBits> RenderingDeviceDriverD3D12::texture_get_usages_supported_by_format(DataFormat p_format, bool p_cpu_readable) {
 	D3D12_FEATURE_DATA_FORMAT_SUPPORT srv_rtv_support = {};
 	D3D12_FEATURE_DATA_FORMAT_SUPPORT srv_rtv_support = {};
 	srv_rtv_support.Format = RD_TO_D3D12_FORMAT[p_format].general_format;
 	srv_rtv_support.Format = RD_TO_D3D12_FORMAT[p_format].general_format;
-	HRESULT res = device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &srv_rtv_support, sizeof(srv_rtv_support));
-	ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), false, "CheckFeatureSupport failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
+	if (srv_rtv_support.Format != DXGI_FORMAT_UNKNOWN) { // Some implementations (i.e., vkd3d-proton) error out instead of returning empty.
+		HRESULT res = device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &srv_rtv_support, sizeof(srv_rtv_support));
+		ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), false, "CheckFeatureSupport failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
+	}
 
 
 	D3D12_FEATURE_DATA_FORMAT_SUPPORT &uav_support = srv_rtv_support; // Fine for now.
 	D3D12_FEATURE_DATA_FORMAT_SUPPORT &uav_support = srv_rtv_support; // Fine for now.
 
 
 	D3D12_FEATURE_DATA_FORMAT_SUPPORT dsv_support = {};
 	D3D12_FEATURE_DATA_FORMAT_SUPPORT dsv_support = {};
 	dsv_support.Format = RD_TO_D3D12_FORMAT[p_format].dsv_format;
 	dsv_support.Format = RD_TO_D3D12_FORMAT[p_format].dsv_format;
-	res = device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &dsv_support, sizeof(dsv_support));
-	ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), false, "CheckFeatureSupport failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
+	if (dsv_support.Format != DXGI_FORMAT_UNKNOWN) { // See above.
+		HRESULT res = device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &dsv_support, sizeof(dsv_support));
+		ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), false, "CheckFeatureSupport failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
+	}
 
 
 	// Everything supported by default makes an all-or-nothing check easier for the caller.
 	// Everything supported by default makes an all-or-nothing check easier for the caller.
 	BitField<RDD::TextureUsageBits> supported = INT64_MAX;
 	BitField<RDD::TextureUsageBits> supported = INT64_MAX;