Skip to content

Commit

Permalink
Add workaround for local root signature override and handle empty D3D…
Browse files Browse the repository at this point in the history
…12 ray tracing pipeline creation (#342)
  • Loading branch information
clshortfuse authored and crosire committed Jan 26, 2025
1 parent 6ef240f commit 8b36a4f
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 26 deletions.
4 changes: 3 additions & 1 deletion source/d3d12/d3d12_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2672,6 +2672,7 @@ bool D3D12Device::invoke_create_and_init_pipeline_layout_event(UINT node_mask, c
std::vector<std::vector<reshade::api::descriptor_range>> ranges;
std::vector<reshade::api::descriptor_range_with_static_samplers> ranges_with_static_samplers;
std::vector<reshade::api::sampler_desc> static_samplers;
D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;

if (const auto part = static_cast<uint32_t *>(const_cast<void *>(
find_dxbc_part(
Expand All @@ -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::addon_event::create_pipeline_layout>() || reshade::has_addon_event<reshade::addon_event::init_pipeline_layout>();

const uint32_t version = part[0];
flags = static_cast<D3D12_ROOT_SIGNATURE_FLAGS>(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))
Expand Down Expand Up @@ -2864,7 +2866,7 @@ bool D3D12Device::invoke_create_and_init_pipeline_layout_event(UINT node_mask, c
reshade::invoke_addon_event<reshade::addon_event::create_pipeline_layout>(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<ID3D12RootSignature *>(layout.handle);
}
else
Expand Down
63 changes: 38 additions & 25 deletions source/d3d12/d3d12_impl_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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<const uint32_t *>(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<const uint32_t *>(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<const uint32_t *>(subobjects[i].data);
ray_tracing = true;
break;
case api::pipeline_subobject_type::flags:
assert(subobjects[i].count == 1);
Expand All @@ -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<ID3D12Device5> device5;
if (SUCCEEDED(_orig->QueryInterface(&device5)))
Expand Down Expand Up @@ -1316,7 +1320,7 @@ void reshade::d3d12::device_impl::destroy_pipeline(api::pipeline pipeline)
reinterpret_cast<IUnknown *>(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 };

Expand Down Expand Up @@ -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<uint32_t>(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<D3D12_FEATURE_DATA_SHADER_MODEL, D3D12_FEATURE_DATA_D3D12_OPTIONS> 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<D3D12_FEATURE_DATA_SHADER_MODEL, D3D12_FEATURE_DATA_D3D12_OPTIONS> 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<ID3DBlob> signature_blob, error_blob;
com_ptr<ID3D12RootSignature> signature;
Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions source/d3d12/d3d12_impl_device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit 8b36a4f

Please sign in to comment.