diff --git a/source/d3d12/d3d12_device.cpp b/source/d3d12/d3d12_device.cpp index 6f6aa1031..55244c0bd 100644 --- a/source/d3d12/d3d12_device.cpp +++ b/source/d3d12/d3d12_device.cpp @@ -2672,6 +2672,7 @@ bool D3D12Device::invoke_create_and_init_pipeline_layout_event(UINT node_mask, c std::vector> ranges; std::vector ranges_with_static_samplers; std::vector static_samplers; + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; if (const auto part = static_cast(const_cast( find_dxbc_part( @@ -2682,6 +2683,7 @@ bool D3D12Device::invoke_create_and_init_pipeline_layout_event(UINT node_mask, c const bool has_pipeline_layout_event = reshade::has_addon_event() || reshade::has_addon_event(); const uint32_t version = part[0]; + flags = static_cast(part[5]); if (has_pipeline_layout_event && (version == D3D_ROOT_SIGNATURE_VERSION_1_0 || version == D3D_ROOT_SIGNATURE_VERSION_1_1 || version == D3D_ROOT_SIGNATURE_VERSION_1_2)) @@ -2864,7 +2866,7 @@ bool D3D12Device::invoke_create_and_init_pipeline_layout_event(UINT node_mask, c reshade::invoke_addon_event(this, param_count, param_data) || modified)) { reshade::api::pipeline_layout layout; - hr = device_impl::create_pipeline_layout(param_count, param_data, &layout) ? S_OK : E_FAIL; + hr = device_impl::create_pipeline_layout(param_count, param_data, &layout, flags) ? S_OK : E_FAIL; root_signature = reinterpret_cast(layout.handle); } else diff --git a/source/d3d12/d3d12_impl_device.cpp b/source/d3d12/d3d12_impl_device.cpp index 49243f14f..64268c03c 100644 --- a/source/d3d12/d3d12_impl_device.cpp +++ b/source/d3d12/d3d12_impl_device.cpp @@ -851,6 +851,7 @@ bool reshade::d3d12::device_impl::create_pipeline(api::pipeline_layout layout, u uint32_t max_attribute_size = 2 * sizeof(float); // Default triangle attributes uint32_t max_recursion_depth = 1; api::pipeline_flags flags = api::pipeline_flags::none; + bool ray_tracing = false; for (uint32_t i = 0; i < subobject_count; ++i) { @@ -986,14 +987,17 @@ bool reshade::d3d12::device_impl::create_pipeline(api::pipeline_layout layout, u case api::pipeline_subobject_type::max_payload_size: assert(subobjects[i].count == 1); max_payload_size = *static_cast(subobjects[i].data); + ray_tracing = true; break; case api::pipeline_subobject_type::max_attribute_size: assert(subobjects[i].count == 1); max_attribute_size = *static_cast(subobjects[i].data); + ray_tracing = true; break; case api::pipeline_subobject_type::max_recursion_depth: assert(subobjects[i].count == 1); max_recursion_depth = *static_cast(subobjects[i].data); + ray_tracing = true; break; case api::pipeline_subobject_type::flags: assert(subobjects[i].count == 1); @@ -1005,7 +1009,7 @@ bool reshade::d3d12::device_impl::create_pipeline(api::pipeline_layout layout, u } } - if (!raygen_desc.empty() || !shader_groups.empty()) + if (ray_tracing || !raygen_desc.empty() || !shader_groups.empty()) { com_ptr device5; if (SUCCEEDED(_orig->QueryInterface(&device5))) @@ -1316,7 +1320,7 @@ void reshade::d3d12::device_impl::destroy_pipeline(api::pipeline pipeline) reinterpret_cast(pipeline.handle)->Release(); } -bool reshade::d3d12::device_impl::create_pipeline_layout(uint32_t param_count, const api::pipeline_layout_param *params, api::pipeline_layout *out_layout) +bool reshade::d3d12::device_impl::create_pipeline_layout(uint32_t param_count, const api::pipeline_layout_param *params, api::pipeline_layout *out_layout, D3D12_ROOT_SIGNATURE_FLAGS flags) { *out_layout = { 0 }; @@ -1470,29 +1474,34 @@ bool reshade::d3d12::device_impl::create_pipeline_layout(uint32_t param_count, c internal_desc.pParameters = internal_params.data(); internal_desc.NumStaticSamplers = static_cast(internal_static_samplers.size()); internal_desc.pStaticSamplers = internal_static_samplers.data(); - internal_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; - - if ((global_visibility_mask & api::shader_stage::vertex) == 0) - internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS; - if ((global_visibility_mask & api::shader_stage::hull) == 0) - internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS; - if ((global_visibility_mask & api::shader_stage::domain) == 0) - internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS; - if ((global_visibility_mask & api::shader_stage::geometry) == 0) - internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS; - if ((global_visibility_mask & api::shader_stage::pixel) == 0) - internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS; - if ((global_visibility_mask & api::shader_stage::amplification) == 0) - internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_DENY_AMPLIFICATION_SHADER_ROOT_ACCESS; - if ((global_visibility_mask & api::shader_stage::mesh) == 0) - internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_DENY_MESH_SHADER_ROOT_ACCESS; - - if (std::pair options = { { D3D_SHADER_MODEL_6_6 }, {} }; - SUCCEEDED(_orig->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &options.first, sizeof(options.first))) && - SUCCEEDED(_orig->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options.second, sizeof(options.second))) && - options.first.HighestShaderModel >= D3D_SHADER_MODEL_6_6 && - options.second.ResourceBindingTier >= D3D12_RESOURCE_BINDING_TIER_3) - internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED | D3D12_ROOT_SIGNATURE_FLAG_SAMPLER_HEAP_DIRECTLY_INDEXED; + internal_desc.Flags = flags; + + if (flags == D3D12_ROOT_SIGNATURE_FLAG_NONE) + { + internal_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + + if ((global_visibility_mask & api::shader_stage::vertex) == 0) + internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS; + if ((global_visibility_mask & api::shader_stage::hull) == 0) + internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS; + if ((global_visibility_mask & api::shader_stage::domain) == 0) + internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS; + if ((global_visibility_mask & api::shader_stage::geometry) == 0) + internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS; + if ((global_visibility_mask & api::shader_stage::pixel) == 0) + internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS; + if ((global_visibility_mask & api::shader_stage::amplification) == 0) + internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_DENY_AMPLIFICATION_SHADER_ROOT_ACCESS; + if ((global_visibility_mask & api::shader_stage::mesh) == 0) + internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_DENY_MESH_SHADER_ROOT_ACCESS; + + if (std::pair options = { { D3D_SHADER_MODEL_6_6 }, {} }; + SUCCEEDED(_orig->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &options.first, sizeof(options.first))) && + SUCCEEDED(_orig->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options.second, sizeof(options.second))) && + options.first.HighestShaderModel >= D3D_SHADER_MODEL_6_6 && + options.second.ResourceBindingTier >= D3D12_RESOURCE_BINDING_TIER_3) + internal_desc.Flags |= D3D12_ROOT_SIGNATURE_FLAG_CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED | D3D12_ROOT_SIGNATURE_FLAG_SAMPLER_HEAP_DIRECTLY_INDEXED; + } com_ptr signature_blob, error_blob; com_ptr signature; @@ -1532,6 +1541,10 @@ bool reshade::d3d12::device_impl::create_pipeline_layout(uint32_t param_count, c return false; } } +bool reshade::d3d12::device_impl::create_pipeline_layout(uint32_t param_count, const api::pipeline_layout_param *params, api::pipeline_layout *out_layout) +{ + return create_pipeline_layout(param_count, params, out_layout, D3D12_ROOT_SIGNATURE_FLAG_NONE); +} void reshade::d3d12::device_impl::destroy_pipeline_layout(api::pipeline_layout layout) { if (layout == 0) diff --git a/source/d3d12/d3d12_impl_device.hpp b/source/d3d12/d3d12_impl_device.hpp index 184b7eca6..ae52dabb1 100644 --- a/source/d3d12/d3d12_impl_device.hpp +++ b/source/d3d12/d3d12_impl_device.hpp @@ -58,6 +58,7 @@ namespace reshade::d3d12 bool create_pipeline(api::pipeline_layout layout, uint32_t subobject_count, const api::pipeline_subobject *subobjects, api::pipeline *out_pipeline) final; void destroy_pipeline(api::pipeline pipeline) final; + bool create_pipeline_layout(uint32_t param_count, const api::pipeline_layout_param *params, api::pipeline_layout *out_layout, D3D12_ROOT_SIGNATURE_FLAGS flags); bool create_pipeline_layout(uint32_t param_count, const api::pipeline_layout_param *params, api::pipeline_layout *out_layout) final; void destroy_pipeline_layout(api::pipeline_layout layout) final;