diff --git a/src/dawn_native/d3d12/AdapterD3D12.cpp b/src/dawn_native/d3d12/AdapterD3D12.cpp index 99e4603f81..d1baba3a3a 100644 --- a/src/dawn_native/d3d12/AdapterD3D12.cpp +++ b/src/dawn_native/d3d12/AdapterD3D12.cpp @@ -66,7 +66,7 @@ namespace dawn_native { namespace d3d12 { // Create the device to populate the adapter properties then reuse it when needed for actual // rendering. const PlatformFunctions* functions = GetBackend()->GetFunctions(); - if (FAILED(functions->d3d12CreateDevice(GetHardwareAdapter(), D3D_FEATURE_LEVEL_11_1, + if (FAILED(functions->d3d12CreateDevice(GetHardwareAdapter(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), &mD3d12Device))) { return DAWN_INTERNAL_ERROR("D3D12CreateDevice failed"); } @@ -143,7 +143,25 @@ namespace dawn_native { namespace d3d12 { DAWN_TRY(CheckHRESULT(mD3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &featureData, sizeof(featureData)), - "CheckFeatureSupport")); + "CheckFeatureSupport D3D12_FEATURE_D3D12_OPTIONS")); + + // Check if the device is at least D3D_FEATURE_LEVEL_11_1 or D3D_FEATURE_LEVEL_11_0 + const D3D_FEATURE_LEVEL levelsToQuery[]{D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0}; + + D3D12_FEATURE_DATA_FEATURE_LEVELS featureLevels; + featureLevels.NumFeatureLevels = sizeof(levelsToQuery) / sizeof(D3D_FEATURE_LEVEL); + featureLevels.pFeatureLevelsRequested = levelsToQuery; + DAWN_TRY( + CheckHRESULT(mD3d12Device->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, + &featureLevels, sizeof(featureLevels)), + "CheckFeatureSupport D3D12_FEATURE_FEATURE_LEVELS")); + + if (featureLevels.MaxSupportedFeatureLevel == D3D_FEATURE_LEVEL_11_0 && + featureData.ResourceBindingTier < D3D12_RESOURCE_BINDING_TIER_2) { + return DAWN_VALIDATION_ERROR( + "At least Resource Binding Tier 2 is required for D3D12 Feature Level 11.0 " + "devices."); + } GetDefaultLimits(&limits->v1); @@ -190,22 +208,22 @@ namespace dawn_native { namespace d3d12 { maxSamplersPerStage = 2048; break; case D3D12_RESOURCE_BINDING_TIER_3: + default: maxCBVsPerStage = 1'100'000; maxSRVsPerStage = 1'100'000; maxUAVsAllStages = 1'100'000; maxSamplersPerStage = 2048; break; - default: - UNREACHABLE(); } - ASSERT(maxUAVsAllStages / 2 > limits->v1.maxStorageTexturesPerShaderStage); - ASSERT(maxUAVsAllStages / 2 > limits->v1.maxStorageBuffersPerShaderStage); + ASSERT(maxUAVsAllStages / 4 > limits->v1.maxStorageTexturesPerShaderStage); + ASSERT(maxUAVsAllStages / 4 > limits->v1.maxStorageBuffersPerShaderStage); + uint32_t maxUAVsPerStage = maxUAVsAllStages / 2; limits->v1.maxUniformBuffersPerShaderStage = maxCBVsPerStage; // Allocate half of the UAVs to storage buffers, and half to storage textures. - limits->v1.maxStorageTexturesPerShaderStage = maxUAVsAllStages / 2; - limits->v1.maxStorageBuffersPerShaderStage = maxUAVsAllStages - maxUAVsAllStages / 2; + limits->v1.maxStorageTexturesPerShaderStage = maxUAVsPerStage / 2; + limits->v1.maxStorageBuffersPerShaderStage = maxUAVsPerStage - maxUAVsPerStage / 2; limits->v1.maxSampledTexturesPerShaderStage = maxSRVsPerStage; limits->v1.maxSamplersPerShaderStage = maxSamplersPerStage;