@@ -1261,6 +1261,7 @@ bool reshade::d3d12::device_impl::create_pipeline_layout(uint32_t param_count, c
12611261
12621262 std::vector<D3D12_ROOT_PARAMETER> internal_params (param_count);
12631263 std::vector<std::vector<D3D12_DESCRIPTOR_RANGE>> internal_ranges (param_count);
1264+ std::vector<D3D12_STATIC_SAMPLER_DESC> internal_static_samplers;
12641265 const auto set_ranges = new std::pair<D3D12_DESCRIPTOR_HEAP_TYPE, UINT>[param_count];
12651266
12661267 for (uint32_t i = 0 ; i < param_count; ++i)
@@ -1272,11 +1273,12 @@ bool reshade::d3d12::device_impl::create_pipeline_layout(uint32_t param_count, c
12721273 if (params[i].type != api::pipeline_layout_param_type::push_constants)
12731274 {
12741275 bool push_descriptors = (params[i].type == api::pipeline_layout_param_type::push_descriptors);
1275- const uint32_t range_count = push_descriptors ? 1 : params[i].descriptor_table .count ;
1276- const api::descriptor_range *const input_ranges = push_descriptors ? ¶ms[i].push_descriptors : params[i].descriptor_table .ranges ;
1277- push_descriptors |= (params[i].type == api::pipeline_layout_param_type::push_descriptors_with_ranges);
1276+ const bool with_static_samplers = (params[i].type == api::pipeline_layout_param_type::descriptor_table_with_static_samplers || params[i].type == api::pipeline_layout_param_type::push_descriptors_with_static_samplers);
1277+ const uint32_t range_count = push_descriptors ? 1 : with_static_samplers ? params[i].descriptor_table_with_static_samplers .count : params[i].descriptor_table .count ;
1278+ const api::descriptor_range_with_static_samplers *range = static_cast <const api::descriptor_range_with_static_samplers *>(push_descriptors ? ¶ms[i].push_descriptors : with_static_samplers ? params[i].descriptor_table_with_static_samplers .ranges : params[i].descriptor_table .ranges );
1279+ push_descriptors |= (params[i].type == api::pipeline_layout_param_type::push_descriptors_with_ranges || params[i].type == api::pipeline_layout_param_type::push_descriptors_with_static_samplers);
12781280
1279- if (range_count == 0 || input_ranges[ 0 ]. count == 0 )
1281+ if (range_count == 0 || range-> count == 0 )
12801282 {
12811283 // Dummy parameter (to prevent root signature creation from failing)
12821284 internal_params[i].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
@@ -1286,15 +1288,15 @@ bool reshade::d3d12::device_impl::create_pipeline_layout(uint32_t param_count, c
12861288 continue ;
12871289 }
12881290
1289- const D3D12_DESCRIPTOR_HEAP_TYPE heap_type = convert_descriptor_type_to_heap_type (input_ranges[ 0 ]. type );
1291+ const D3D12_DESCRIPTOR_HEAP_TYPE heap_type = convert_descriptor_type_to_heap_type (range-> type );
12901292 set_ranges[i].first = heap_type;
12911293
1292- if (push_descriptors && range_count == 1 && input_ranges ->binding == 0 && input_ranges ->count == 1 &&
1294+ if (push_descriptors && range_count == 1 && range ->binding == 0 && range ->count == 1 &&
12931295 heap_type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV &&
1294- input_ranges ->type != api::descriptor_type::texture_shader_resource_view &&
1295- input_ranges ->type != api::descriptor_type::texture_unordered_access_view)
1296+ range ->type != api::descriptor_type::texture_shader_resource_view &&
1297+ range ->type != api::descriptor_type::texture_unordered_access_view)
12961298 {
1297- switch (input_ranges ->type )
1299+ switch (range ->type )
12981300 {
12991301 case api::descriptor_type::constant_buffer:
13001302 internal_params[i].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
@@ -1310,36 +1312,69 @@ bool reshade::d3d12::device_impl::create_pipeline_layout(uint32_t param_count, c
13101312 return false ;
13111313 }
13121314
1313- internal_params[i].Descriptor .ShaderRegister = input_ranges ->dx_register_index ;
1314- internal_params[i].Descriptor .RegisterSpace = input_ranges ->dx_register_space ;
1315+ internal_params[i].Descriptor .ShaderRegister = range ->dx_register_index ;
1316+ internal_params[i].Descriptor .RegisterSpace = range ->dx_register_space ;
13151317
1316- visibility_mask = input_ranges ->visibility ;
1318+ visibility_mask = range ->visibility ;
13171319 }
13181320 else
13191321 {
13201322 internal_ranges[i].reserve (range_count);
13211323
1322- for (uint32_t k = 0 ; k < range_count; ++k)
1324+ for (uint32_t k = 0 ; k < range_count; ++k, range = (with_static_samplers ? range + 1 : reinterpret_cast < const api::descriptor_range_with_static_samplers *>( reinterpret_cast < const api::descriptor_range *>(range) + 1 )) )
13231325 {
1324- const api::descriptor_range & range = input_ranges[k] ;
1326+ assert ( range-> array_size <= 1 ) ;
13251327
1326- assert (range.array_size <= 1 );
1328+ if (with_static_samplers && range->type == api::descriptor_type::sampler && range->static_samplers != nullptr )
1329+ {
1330+ for (uint32_t j = 0 ; j < range->count ; ++j)
1331+ {
1332+ D3D12_STATIC_SAMPLER_DESC &internal_static_sampler = internal_static_samplers.emplace_back ();
1333+ convert_sampler_desc (range->static_samplers [j], internal_static_sampler);
1334+
1335+ internal_static_sampler.ShaderRegister = range->dx_register_index + j;
1336+ internal_static_sampler.RegisterSpace = range->dx_register_space ;
1337+
1338+ switch (range->visibility )
1339+ {
1340+ default :
1341+ internal_static_sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
1342+ break ;
1343+ case api::shader_stage::vertex:
1344+ internal_static_sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
1345+ break ;
1346+ case api::shader_stage::hull:
1347+ internal_static_sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_HULL;
1348+ break ;
1349+ case api::shader_stage::domain:
1350+ internal_static_sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_DOMAIN;
1351+ break ;
1352+ case api::shader_stage::geometry:
1353+ internal_static_sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_GEOMETRY;
1354+ break ;
1355+ case api::shader_stage::pixel:
1356+ internal_static_sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
1357+ break ;
1358+ }
1359+ }
1360+ continue ;
1361+ }
13271362
13281363 D3D12_DESCRIPTOR_RANGE &internal_range = internal_ranges[i].emplace_back ();
1329- internal_range.RangeType = convert_descriptor_type (range. type );
1330- internal_range.NumDescriptors = range. count ;
1331- internal_range.BaseShaderRegister = range. dx_register_index ;
1332- internal_range.RegisterSpace = range. dx_register_space ;
1333- internal_range.OffsetInDescriptorsFromTableStart = range. binding ;
1364+ internal_range.RangeType = convert_descriptor_type (range-> type );
1365+ internal_range.NumDescriptors = range-> count ;
1366+ internal_range.BaseShaderRegister = range-> dx_register_index ;
1367+ internal_range.RegisterSpace = range-> dx_register_space ;
1368+ internal_range.OffsetInDescriptorsFromTableStart = range-> binding ;
13341369
1335- visibility_mask |= range. visibility ;
1370+ visibility_mask |= range-> visibility ;
13361371
13371372 // Cannot mix different descriptor heap types in a single descriptor table
1338- if (convert_descriptor_type_to_heap_type (range. type ) != heap_type)
1373+ if (convert_descriptor_type_to_heap_type (range-> type ) != heap_type)
13391374 return false ;
13401375
1341- if (range. count != UINT32_MAX) // Don't count unbounded ranges
1342- set_ranges[i].second = std::max (set_ranges[i].second , range. binding + range. count );
1376+ if (range-> count != UINT32_MAX) // Don't count unbounded ranges
1377+ set_ranges[i].second = std::max (set_ranges[i].second , range-> binding + range-> count );
13431378 }
13441379
13451380 internal_params[i].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
@@ -1388,6 +1423,8 @@ bool reshade::d3d12::device_impl::create_pipeline_layout(uint32_t param_count, c
13881423 internal_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
13891424 internal_desc.NumParameters = param_count;
13901425 internal_desc.pParameters = internal_params.data ();
1426+ internal_desc.NumStaticSamplers = static_cast <uint32_t >(internal_static_samplers.size ());
1427+ internal_desc.pStaticSamplers = internal_static_samplers.data ();
13911428
13921429 com_ptr<ID3DBlob> signature_blob, error_blob;
13931430 com_ptr<ID3D12RootSignature> signature;
0 commit comments