Compare commits

...

4 Commits

Author SHA1 Message Date
Hans-Kristian Arntzen fc51054680 vkd3d: Add env-var entry for ALLOW_SBT_COLLECTION. 2 months ago
Hans-Kristian Arntzen abba84d6e8 tests: Test that we can deal with local samplers in COLLECTIONS. 2 months ago
Hans-Kristian Arntzen bc5fcfda22 tests: Add test for querying identifiers from COLLECTION objects. 2 months ago
Hans-Kristian Arntzen 81f0a71502 vkd3d: Do a best effort in handling COLLECTION local static samplers. 2 months ago
  1. 1
      libs/vkd3d/device.c
  2. 58
      libs/vkd3d/raytracing_pipeline.c
  3. 2
      libs/vkd3d/vkd3d_private.h
  4. 162
      tests/d3d12_raytracing.c
  5. 2
      tests/d3d12_tests.h

@ -655,6 +655,7 @@ static const struct vkd3d_debug_option vkd3d_config_options[] =
{"breadcrumbs", VKD3D_CONFIG_FLAG_BREADCRUMBS},
{"pipeline_library_app_cache", VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_APP_CACHE_ONLY},
{"shader_cache_sync", VKD3D_CONFIG_FLAG_SHADER_CACHE_SYNC},
{"allow_sbt_collection", VKD3D_CONFIG_FLAG_ALLOW_SBT_COLLECTION},
};
static void vkd3d_config_flags_init_once(void)

@ -130,14 +130,17 @@ static void d3d12_state_object_cleanup(struct d3d12_state_object *object)
VK_CALL(vkDestroyPipeline(object->device->vk_device, object->pipeline, NULL));
VK_CALL(vkDestroyPipeline(object->device->vk_device, object->pipeline_library, NULL));
VK_CALL(vkDestroyPipelineLayout(object->device->vk_device,
object->local_static_sampler.pipeline_layout, NULL));
VK_CALL(vkDestroyDescriptorSetLayout(object->device->vk_device,
object->local_static_sampler.set_layout, NULL));
if (object->local_static_sampler.desc_set)
if (object->local_static_sampler.owned_handles)
{
vkd3d_sampler_state_free_descriptor_set(&object->device->sampler_state, object->device,
object->local_static_sampler.desc_set, object->local_static_sampler.desc_pool);
VK_CALL(vkDestroyPipelineLayout(object->device->vk_device,
object->local_static_sampler.pipeline_layout, NULL));
VK_CALL(vkDestroyDescriptorSetLayout(object->device->vk_device,
object->local_static_sampler.set_layout, NULL));
if (object->local_static_sampler.desc_set)
{
vkd3d_sampler_state_free_descriptor_set(&object->device->sampler_state, object->device,
object->local_static_sampler.desc_set, object->local_static_sampler.desc_pool);
}
}
#ifdef VKD3D_ENABLE_BREADCRUMBS
@ -1957,6 +1960,19 @@ static HRESULT d3d12_state_object_compile_pipeline(struct d3d12_state_object *ob
if (local_static_sampler_bindings_count)
{
uint64_t hash = hash_fnv1_init();
hash = hash_fnv1_iterate_u32(hash, local_static_sampler_bindings_count);
for (i = 0; i < local_static_sampler_bindings_count; i++)
{
/* Immutable samplers are deduplicated, so this is fine. */
hash = hash_fnv1_iterate_u64(hash, (uint64_t)local_static_sampler_bindings[i].pImmutableSamplers[0]);
hash = hash_fnv1_iterate_u32(hash, local_static_sampler_bindings[i].binding);
hash = hash_fnv1_iterate_u32(hash, local_static_sampler_bindings[i].stageFlags);
}
object->local_static_sampler.compatibility_hash = hash;
object->local_static_sampler.owned_handles = true;
if (FAILED(hr = vkd3d_create_descriptor_set_layout(object->device, 0, local_static_sampler_bindings_count,
local_static_sampler_bindings, &object->local_static_sampler.set_layout)))
{
@ -1985,6 +2001,33 @@ static HRESULT d3d12_state_object_compile_pipeline(struct d3d12_state_object *ob
return hr;
}
/* If we have collections, we need to make sure that every pipeline layout is compatible.
* We validate that global root signature is compatible, so we only need to ensure the
* local root signature is either unused (compatible with appended local sampler sets)
* or the same compat hash. */
for (i = 0; i < data->collections_count; i++)
{
struct d3d12_state_object *child = data->collections[i].object;
if (child->local_static_sampler.pipeline_layout && !object->local_static_sampler.pipeline_layout)
{
/* Borrow these handles. */
object->local_static_sampler.pipeline_layout = child->local_static_sampler.pipeline_layout;
object->local_static_sampler.desc_set = child->local_static_sampler.desc_set;
object->local_static_sampler.compatibility_hash = child->local_static_sampler.compatibility_hash;
}
if (child->local_static_sampler.pipeline_layout)
{
if (child->local_static_sampler.compatibility_hash != object->local_static_sampler.compatibility_hash)
{
FIXME("COLLECTION and RTPSO declares local static sampler set layouts with different definitions. "
"This is unsupported.\n");
return E_NOTIMPL;
}
}
}
pipeline_create_info.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR;
pipeline_create_info.pNext = NULL;
@ -1995,7 +2038,6 @@ static HRESULT d3d12_state_object_compile_pipeline(struct d3d12_state_object *ob
(object->flags & D3D12_STATE_OBJECT_FLAG_ALLOW_STATE_OBJECT_ADDITIONS)) ?
VK_PIPELINE_CREATE_LIBRARY_BIT_KHR : 0;
/* TODO: What happens here if we have local static samplers with COLLECTIONS? :| */
if (object->local_static_sampler.pipeline_layout)
pipeline_create_info.layout = object->local_static_sampler.pipeline_layout;
else

@ -3454,6 +3454,8 @@ struct d3d12_state_object
VkDescriptorSet desc_set;
VkDescriptorPool desc_pool;
uint32_t set_index;
uint64_t compatibility_hash;
bool owned_handles;
} local_static_sampler;
UINT64 pipeline_stack_size;

@ -2979,7 +2979,7 @@ void test_rayquery(void)
vkd3d_test_set_context(NULL);
}
void test_raytracing_local_rs_static_sampler(void)
static void test_raytracing_local_rs_static_sampler_inner(bool use_libraries)
{
ID3D12GraphicsCommandList4 *command_list4;
ID3D12GraphicsCommandList *command_list;
@ -3070,6 +3070,86 @@ void test_raytracing_local_rs_static_sampler(void)
}
/* Create PSO. */
if (use_libraries)
{
/* Test that we can deal with local samplers in collections.
* We can only deal with this as long as the collections are compatible,
* but at least do what we can. */
D3D12_EXPORT_DESC collection_export_descs[2] = { { u"RayClosest1" }, { u"RayClosest2" } };
D3D12_EXPORT_DESC export_descs[2] = { { u"RayGen" }, { u"RayMiss" } };
ID3D12StateObject *collections[2];
D3D12_HIT_GROUP_DESC hit_group[2];
struct rt_pso_factory factory;
unsigned local_index[2];
unsigned int i;
memset(hit_group, 0, sizeof(hit_group));
hit_group[0].Type = D3D12_HIT_GROUP_TYPE_TRIANGLES;
hit_group[0].HitGroupExport = u"RayHit1";
hit_group[0].ClosestHitShaderImport = u"RayClosest1";
hit_group[1].Type = D3D12_HIT_GROUP_TYPE_TRIANGLES;
hit_group[1].HitGroupExport = u"RayHit2";
hit_group[1].ClosestHitShaderImport = u"RayClosest2";
for (i = 0; i < 2; i++)
{
rt_pso_factory_init(&factory);
rt_pso_factory_add_dxil_library(&factory, get_static_sampler_rt_lib(), 1, &collection_export_descs[i]);
rt_pso_factory_add_state_object_config(&factory, D3D12_STATE_OBJECT_FLAG_NONE);
rt_pso_factory_add_pipeline_config(&factory, 1);
rt_pso_factory_add_shader_config(&factory, 8, 4);
rt_pso_factory_add_global_root_signature(&factory, global_rs);
rt_pso_factory_add_local_root_signature(&factory, local_rs[i]);
rt_pso_factory_add_hit_group(&factory, &hit_group[i]);
collections[i] = rt_pso_factory_compile(&context, &factory, D3D12_STATE_OBJECT_TYPE_COLLECTION);
}
rt_pso_factory_init(&factory);
for (i = 0; i < 2; i++)
rt_pso_factory_add_existing_collection(&factory, collections[i], 0, NULL);
rt_pso_factory_add_state_object_config(&factory, D3D12_STATE_OBJECT_FLAG_NONE);
rt_pso_factory_add_pipeline_config(&factory, 1);
rt_pso_factory_add_shader_config(&factory, 8, 4);
rt_pso_factory_add_global_root_signature(&factory, global_rs);
rt_pso_factory_add_dxil_library(&factory, get_static_sampler_rt_lib(), ARRAY_SIZE(export_descs), export_descs);
rt_pso = rt_pso_factory_compile(&context, &factory, D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE);
/* Currently, we expect this to fail on vkd3d-proton since the local sampler sets definitions diverge
* in the different collections. */
todo ok(!!rt_pso, "Failed to compile RTPSO.\n");
for (i = 0; i < 2; i++)
ID3D12StateObject_Release(collections[i]);
if (!rt_pso)
{
/* Try again, but now with both local sets in one collection, which we can make work. */
rt_pso_factory_init(&factory);
rt_pso_factory_add_dxil_library(&factory, get_static_sampler_rt_lib(),
ARRAY_SIZE(collection_export_descs), collection_export_descs);
rt_pso_factory_add_state_object_config(&factory, D3D12_STATE_OBJECT_FLAG_NONE);
rt_pso_factory_add_pipeline_config(&factory, 1);
rt_pso_factory_add_shader_config(&factory, 8, 4);
rt_pso_factory_add_global_root_signature(&factory, global_rs);
for (i = 0; i < 2; i++)
{
rt_pso_factory_add_hit_group(&factory, &hit_group[i]);
local_index[i] = rt_pso_factory_add_local_root_signature(&factory, local_rs[i]);
rt_pso_factory_add_subobject_to_exports_association(&factory, local_index[i], 1, &hit_group[i].HitGroupExport);
}
collections[0] = rt_pso_factory_compile(&context, &factory, D3D12_STATE_OBJECT_TYPE_COLLECTION);
rt_pso_factory_init(&factory);
rt_pso_factory_add_existing_collection(&factory, collections[0], 0, NULL);
rt_pso_factory_add_state_object_config(&factory, D3D12_STATE_OBJECT_FLAG_NONE);
rt_pso_factory_add_pipeline_config(&factory, 1);
rt_pso_factory_add_shader_config(&factory, 8, 4);
rt_pso_factory_add_global_root_signature(&factory, global_rs);
rt_pso_factory_add_dxil_library(&factory, get_static_sampler_rt_lib(), ARRAY_SIZE(export_descs), export_descs);
rt_pso = rt_pso_factory_compile(&context, &factory, D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE);
ok(!!rt_pso, "Failed to compile RTPSO.\n");
ID3D12StateObject_Release(collections[0]);
}
}
else
{
D3D12_HIT_GROUP_DESC hit_group[2];
struct rt_pso_factory factory;
@ -3253,6 +3333,16 @@ void test_raytracing_local_rs_static_sampler(void)
destroy_raytracing_test_context(&context);
}
void test_raytracing_local_rs_static_sampler(void)
{
test_raytracing_local_rs_static_sampler_inner(false);
}
void test_raytracing_local_rs_static_sampler_collection(void)
{
test_raytracing_local_rs_static_sampler_inner(true);
}
void test_raytracing_no_global_root_signature(void)
{
struct raytracing_test_context context;
@ -3673,3 +3763,73 @@ void test_raytracing_embedded_subobjects(void)
ID3D12Device_Release(device);
destroy_raytracing_test_context(&context);
}
void test_raytracing_collection_identifiers(void)
{
uint8_t collection_identifier[D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES] = { 0 };
uint8_t rtpso_identifier[D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES] = { 0 };
struct raytracing_test_context context;
ID3D12RootSignature *root_signature;
ID3D12StateObjectProperties *props;
D3D12_ROOT_SIGNATURE_DESC rs_desc;
ID3D12StateObject *full_object;
struct rt_pso_factory factory;
D3D12_ROOT_PARAMETER param;
ID3D12StateObject *object;
ID3D12Device *device;
const void *ident;
HRESULT hr;
if (!init_raytracing_test_context(&context, D3D12_RAYTRACING_TIER_1_0))
return;
ID3D12Device5_QueryInterface(context.device5, &IID_ID3D12Device, (void **)&device);
memset(&rs_desc, 0, sizeof(rs_desc));
rs_desc.pParameters = &param;
rs_desc.NumParameters = 1;
memset(&param, 0, sizeof(param));
param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
param.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
create_root_signature(device, &rs_desc, &root_signature);
rt_pso_factory_init(&factory);
rt_pso_factory_add_dxil_library(&factory, get_dummy_raygen_rt_lib(), 0, NULL);
rt_pso_factory_add_pipeline_config(&factory, 1);
rt_pso_factory_add_shader_config(&factory, 8, 4);
rt_pso_factory_add_global_root_signature(&factory, root_signature);
object = rt_pso_factory_compile(&context, &factory, D3D12_STATE_OBJECT_TYPE_COLLECTION);
ok(!!object, "Failed to create collection.\n");
hr = ID3D12StateObject_QueryInterface(object, &IID_ID3D12StateObjectProperties, (void **)&props);
ok(SUCCEEDED(hr), "Failed to query props interface, hr #%x.\n", hr);
ident = ID3D12StateObjectProperties_GetShaderIdentifier(props, u"main");
todo ok(!!ident, "Failed to query identifier for COLLECTION.\n");
if (ident)
memcpy(collection_identifier, ident, sizeof(collection_identifier));
ID3D12StateObjectProperties_Release(props);
rt_pso_factory_init(&factory);
rt_pso_factory_add_existing_collection(&factory, object, 0, NULL);
rt_pso_factory_add_pipeline_config(&factory, 1);
rt_pso_factory_add_shader_config(&factory, 8, 4);
full_object = rt_pso_factory_compile(&context, &factory, D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE);
ok(!!full_object, "Failed to create RTPSO.\n");
hr = ID3D12StateObject_QueryInterface(full_object, &IID_ID3D12StateObjectProperties, (void **)&props);
ident = ID3D12StateObjectProperties_GetShaderIdentifier(props, u"main");
ok(!!ident, "Failed to query identifier for COLLECTION.\n");
if (ident)
memcpy(rtpso_identifier, ident, sizeof(collection_identifier));
ID3D12StateObjectProperties_Release(props);
todo ok(memcmp(collection_identifier, rtpso_identifier, D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES) == 0, "COLLECTION identifier does not match RTPSO identifier.\n");
if (object)
ID3D12StateObject_Release(object);
if (full_object)
ID3D12StateObject_Release(full_object);
ID3D12RootSignature_Release(root_signature);
ID3D12Device_Release(device);
destroy_raytracing_test_context(&context);
}

@ -294,6 +294,7 @@ decl_test(test_integer_blending_pipeline_state);
decl_test(test_discard_resource_uav);
decl_test(test_unbound_rtv_rendering);
decl_test(test_raytracing_local_rs_static_sampler);
decl_test(test_raytracing_local_rs_static_sampler_collection);
decl_test(test_rayquery);
decl_test(test_typed_srv_uav_cast);
decl_test(test_typed_srv_cast_clear);
@ -309,3 +310,4 @@ decl_test(test_raytracing_missing_required_objects);
decl_test(test_raytracing_reject_duplicate_objects);
decl_test(test_raytracing_embedded_subobjects);
decl_test(test_raytracing_default_association_tiebreak);
decl_test(test_raytracing_collection_identifiers);

Loading…
Cancel
Save