|
|
|
@ -375,6 +375,10 @@ struct d3d12_state_object_pipeline_data |
|
|
|
|
size_t subobjects_size; |
|
|
|
|
size_t subobjects_count; |
|
|
|
|
|
|
|
|
|
struct d3d12_root_signature **subobject_root_signatures; |
|
|
|
|
size_t subobject_root_signatures_size; |
|
|
|
|
size_t subobject_root_signatures_count; |
|
|
|
|
|
|
|
|
|
/* Resolve these to group + export name later. */ |
|
|
|
|
const struct D3D12_HIT_GROUP_DESC **hit_groups; |
|
|
|
|
size_t hit_groups_size; |
|
|
|
@ -423,6 +427,10 @@ static void d3d12_state_object_pipeline_data_cleanup(struct d3d12_state_object_p |
|
|
|
|
vkd3d_free((void*)data->hit_groups); |
|
|
|
|
vkd3d_free((void*)data->dxil_libraries); |
|
|
|
|
|
|
|
|
|
for (i = 0; i < data->subobject_root_signatures_count; i++) |
|
|
|
|
d3d12_root_signature_dec_ref(data->subobject_root_signatures[i]); |
|
|
|
|
vkd3d_free(data->subobject_root_signatures); |
|
|
|
|
|
|
|
|
|
for (i = 0; i < data->exports_count; i++) |
|
|
|
|
{ |
|
|
|
|
vkd3d_free(data->exports[i].mangled_export); |
|
|
|
@ -442,9 +450,10 @@ static void d3d12_state_object_pipeline_data_cleanup(struct d3d12_state_object_p |
|
|
|
|
|
|
|
|
|
#define VKD3D_ASSOCIATION_PRIORITY_INHERITED_COLLECTION 0 |
|
|
|
|
#define VKD3D_ASSOCIATION_PRIORITY_DXIL_SUBOBJECT 1 |
|
|
|
|
#define VKD3D_ASSOCIATION_PRIORITY_DECLARED_STATE_OBJECT 2 |
|
|
|
|
#define VKD3D_ASSOCIATION_PRIORITY_EXPLICIT_DEFAULT 3 |
|
|
|
|
#define VKD3D_ASSOCIATION_PRIORITY_EXPLICIT 4 |
|
|
|
|
#define VKD3D_ASSOCIATION_PRIORITY_DXIL_SUBOBJECT_ASSIGNMENT 2 |
|
|
|
|
#define VKD3D_ASSOCIATION_PRIORITY_DECLARED_STATE_OBJECT 3 |
|
|
|
|
#define VKD3D_ASSOCIATION_PRIORITY_EXPLICIT_DEFAULT 4 |
|
|
|
|
#define VKD3D_ASSOCIATION_PRIORITY_EXPLICIT 5 |
|
|
|
|
|
|
|
|
|
static HRESULT d3d12_state_object_add_collection( |
|
|
|
|
struct d3d12_state_object *collection, |
|
|
|
@ -546,214 +555,290 @@ static void d3d12_state_object_set_association_data(struct d3d12_state_object_as |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static HRESULT d3d12_state_object_parse_subobjects(struct d3d12_state_object *object, |
|
|
|
|
const D3D12_STATE_OBJECT_DESC *desc, |
|
|
|
|
struct d3d12_state_object *parent, |
|
|
|
|
struct d3d12_state_object_pipeline_data *data) |
|
|
|
|
static HRESULT d3d12_state_object_parse_subobject(struct d3d12_state_object *object, |
|
|
|
|
const D3D12_STATE_SUBOBJECT *obj, |
|
|
|
|
struct d3d12_state_object_pipeline_data *data, |
|
|
|
|
unsigned int association_priority) |
|
|
|
|
{ |
|
|
|
|
unsigned int i, j; |
|
|
|
|
unsigned int i; |
|
|
|
|
HRESULT hr; |
|
|
|
|
|
|
|
|
|
if (parent && FAILED(hr = d3d12_state_object_add_collection(parent, data, NULL, 0))) |
|
|
|
|
return hr; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < desc->NumSubobjects; i++) |
|
|
|
|
switch (obj->Type) |
|
|
|
|
{ |
|
|
|
|
const D3D12_STATE_SUBOBJECT *obj = &desc->pSubobjects[i]; |
|
|
|
|
switch (obj->Type) |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_STATE_OBJECT_CONFIG: |
|
|
|
|
{ |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_STATE_OBJECT_CONFIG: |
|
|
|
|
/* TODO: We might have to do global object assignment similar to SHADER_CONFIG / PIPELINE_CONFIG,
|
|
|
|
|
* but STATE_OBJECT_CONFIG doesn't change any functionality or compatibility rules really, |
|
|
|
|
* so just append flags. */ |
|
|
|
|
const uint32_t supported_flags = |
|
|
|
|
D3D12_STATE_OBJECT_FLAG_ALLOW_EXTERNAL_DEPENDENCIES_ON_LOCAL_DEFINITIONS | |
|
|
|
|
D3D12_STATE_OBJECT_FLAG_ALLOW_STATE_OBJECT_ADDITIONS; |
|
|
|
|
const D3D12_STATE_OBJECT_CONFIG *object_config = obj->pDesc; |
|
|
|
|
object->flags |= object_config->Flags; |
|
|
|
|
if (object->flags & ~supported_flags) |
|
|
|
|
{ |
|
|
|
|
const uint32_t supported_flags = |
|
|
|
|
D3D12_STATE_OBJECT_FLAG_ALLOW_EXTERNAL_DEPENDENCIES_ON_LOCAL_DEFINITIONS | |
|
|
|
|
D3D12_STATE_OBJECT_FLAG_ALLOW_STATE_OBJECT_ADDITIONS; |
|
|
|
|
const D3D12_STATE_OBJECT_CONFIG *object_config = obj->pDesc; |
|
|
|
|
object->flags = object_config->Flags; |
|
|
|
|
if (object->flags & ~supported_flags) |
|
|
|
|
{ |
|
|
|
|
FIXME("Object config flag #%x is not supported.\n", object->flags); |
|
|
|
|
return E_INVALIDARG; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
FIXME("Object config flag #%x is not supported.\n", object->flags); |
|
|
|
|
return E_INVALIDARG; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE: |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE: |
|
|
|
|
{ |
|
|
|
|
/* LOCAL_ROOT_SIGNATURE and GLOBAL_ROOT_SIGNATURE alias. */ |
|
|
|
|
const D3D12_LOCAL_ROOT_SIGNATURE *rs = obj->pDesc; |
|
|
|
|
|
|
|
|
|
/* This is only chosen as default if there is nothing else.
|
|
|
|
|
* Conflicting definitions seem to cause runtime to choose something |
|
|
|
|
* arbitrary. Just override the low priority default. |
|
|
|
|
* A high priority default association takes precedence if it exists. */ |
|
|
|
|
vkd3d_array_reserve((void **)&data->associations, &data->associations_size, |
|
|
|
|
data->associations_count + 1, |
|
|
|
|
sizeof(*data->associations)); |
|
|
|
|
|
|
|
|
|
/* Root signatures being exported to NULL takes priority as the default local RS.
|
|
|
|
|
* They do however, take precedence over DXIL exported subobjects ... */ |
|
|
|
|
data->associations[data->associations_count].export = NULL; |
|
|
|
|
data->associations[data->associations_count].kind = |
|
|
|
|
obj->Type == D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE ? |
|
|
|
|
VKD3D_SHADER_SUBOBJECT_KIND_GLOBAL_ROOT_SIGNATURE : |
|
|
|
|
VKD3D_SHADER_SUBOBJECT_KIND_LOCAL_ROOT_SIGNATURE; |
|
|
|
|
data->associations[data->associations_count].root_signature = |
|
|
|
|
impl_from_ID3D12RootSignature(rs->pLocalRootSignature); |
|
|
|
|
data->associations[data->associations_count].priority = |
|
|
|
|
VKD3D_ASSOCIATION_PRIORITY_DECLARED_STATE_OBJECT; |
|
|
|
|
data->associations_count++; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE: |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE: |
|
|
|
|
{ |
|
|
|
|
/* LOCAL_ROOT_SIGNATURE and GLOBAL_ROOT_SIGNATURE alias. */ |
|
|
|
|
const D3D12_LOCAL_ROOT_SIGNATURE *rs = obj->pDesc; |
|
|
|
|
|
|
|
|
|
/* This is only chosen as default if there is nothing else.
|
|
|
|
|
* Conflicting definitions seem to cause runtime to choose something |
|
|
|
|
* arbitrary. Just override the low priority default. |
|
|
|
|
* A high priority default association takes precedence if it exists. */ |
|
|
|
|
vkd3d_array_reserve((void **)&data->associations, &data->associations_size, |
|
|
|
|
data->associations_count + 1, |
|
|
|
|
sizeof(*data->associations)); |
|
|
|
|
|
|
|
|
|
/* Root signatures being exported to NULL takes priority as the default local RS.
|
|
|
|
|
* They do however, take precedence over DXIL exported subobjects ... */ |
|
|
|
|
data->associations[data->associations_count].export = NULL; |
|
|
|
|
data->associations[data->associations_count].kind = |
|
|
|
|
obj->Type == D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE ? |
|
|
|
|
VKD3D_SHADER_SUBOBJECT_KIND_GLOBAL_ROOT_SIGNATURE : |
|
|
|
|
VKD3D_SHADER_SUBOBJECT_KIND_LOCAL_ROOT_SIGNATURE; |
|
|
|
|
data->associations[data->associations_count].root_signature = |
|
|
|
|
impl_from_ID3D12RootSignature(rs->pLocalRootSignature); |
|
|
|
|
data->associations[data->associations_count].priority = association_priority; |
|
|
|
|
data->associations_count++; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY: |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY: |
|
|
|
|
{ |
|
|
|
|
const D3D12_DXIL_LIBRARY_DESC *lib = obj->pDesc; |
|
|
|
|
if (vkd3d_shader_dxil_append_library_entry_points_and_subobjects(lib, data->dxil_libraries_count, |
|
|
|
|
&data->entry_points, &data->entry_points_size, |
|
|
|
|
&data->entry_points_count, |
|
|
|
|
&data->subobjects, &data->subobjects_size, |
|
|
|
|
&data->subobjects_count) != VKD3D_OK) |
|
|
|
|
{ |
|
|
|
|
const D3D12_DXIL_LIBRARY_DESC *lib = obj->pDesc; |
|
|
|
|
if (vkd3d_shader_dxil_append_library_entry_points_and_subobjects(lib, data->dxil_libraries_count, |
|
|
|
|
&data->entry_points, &data->entry_points_size, |
|
|
|
|
&data->entry_points_count, |
|
|
|
|
&data->subobjects, &data->subobjects_size, |
|
|
|
|
&data->subobjects_count) != VKD3D_OK) |
|
|
|
|
{ |
|
|
|
|
ERR("Failed to parse DXIL library.\n"); |
|
|
|
|
return E_OUTOFMEMORY; |
|
|
|
|
} |
|
|
|
|
vkd3d_array_reserve((void**)&data->dxil_libraries, &data->dxil_libraries_size, |
|
|
|
|
data->dxil_libraries_count + 1, sizeof(*data->dxil_libraries)); |
|
|
|
|
data->dxil_libraries[data->dxil_libraries_count++] = lib; |
|
|
|
|
break; |
|
|
|
|
ERR("Failed to parse DXIL library.\n"); |
|
|
|
|
return E_OUTOFMEMORY; |
|
|
|
|
} |
|
|
|
|
vkd3d_array_reserve((void**)&data->dxil_libraries, &data->dxil_libraries_size, |
|
|
|
|
data->dxil_libraries_count + 1, sizeof(*data->dxil_libraries)); |
|
|
|
|
data->dxil_libraries[data->dxil_libraries_count++] = lib; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP: |
|
|
|
|
{ |
|
|
|
|
const D3D12_HIT_GROUP_DESC *group = obj->pDesc; |
|
|
|
|
vkd3d_array_reserve((void**)&data->hit_groups, &data->hit_groups_size, |
|
|
|
|
data->hit_groups_count + 1, sizeof(*data->hit_groups)); |
|
|
|
|
data->hit_groups[data->hit_groups_count++] = group; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP: |
|
|
|
|
{ |
|
|
|
|
const D3D12_HIT_GROUP_DESC *group = obj->pDesc; |
|
|
|
|
vkd3d_array_reserve((void**)&data->hit_groups, &data->hit_groups_size, |
|
|
|
|
data->hit_groups_count + 1, sizeof(*data->hit_groups)); |
|
|
|
|
data->hit_groups[data->hit_groups_count++] = group; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG: |
|
|
|
|
{ |
|
|
|
|
const D3D12_RAYTRACING_SHADER_CONFIG *config = obj->pDesc; |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG: |
|
|
|
|
{ |
|
|
|
|
const D3D12_RAYTRACING_SHADER_CONFIG *config = obj->pDesc; |
|
|
|
|
|
|
|
|
|
vkd3d_array_reserve((void **)&data->associations, &data->associations_size, |
|
|
|
|
data->associations_count + 1, |
|
|
|
|
sizeof(*data->associations)); |
|
|
|
|
vkd3d_array_reserve((void **)&data->associations, &data->associations_size, |
|
|
|
|
data->associations_count + 1, |
|
|
|
|
sizeof(*data->associations)); |
|
|
|
|
|
|
|
|
|
data->associations[data->associations_count].kind = VKD3D_SHADER_SUBOBJECT_KIND_RAYTRACING_SHADER_CONFIG; |
|
|
|
|
data->associations[data->associations_count].priority = VKD3D_ASSOCIATION_PRIORITY_DECLARED_STATE_OBJECT; |
|
|
|
|
data->associations[data->associations_count].shader_config = *config; |
|
|
|
|
data->associations[data->associations_count].export = NULL; |
|
|
|
|
data->associations_count++; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
data->associations[data->associations_count].kind = VKD3D_SHADER_SUBOBJECT_KIND_RAYTRACING_SHADER_CONFIG; |
|
|
|
|
data->associations[data->associations_count].priority = association_priority; |
|
|
|
|
data->associations[data->associations_count].shader_config = *config; |
|
|
|
|
data->associations[data->associations_count].export = NULL; |
|
|
|
|
data->associations_count++; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG: |
|
|
|
|
{ |
|
|
|
|
const D3D12_RAYTRACING_PIPELINE_CONFIG *pipeline_config = obj->pDesc; |
|
|
|
|
|
|
|
|
|
vkd3d_array_reserve((void **)&data->associations, &data->associations_size, |
|
|
|
|
data->associations_count + 1, |
|
|
|
|
sizeof(*data->associations)); |
|
|
|
|
|
|
|
|
|
data->associations[data->associations_count].kind = VKD3D_SHADER_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG1; |
|
|
|
|
data->associations[data->associations_count].priority = VKD3D_ASSOCIATION_PRIORITY_DECLARED_STATE_OBJECT; |
|
|
|
|
data->associations[data->associations_count].pipeline_config.MaxTraceRecursionDepth = |
|
|
|
|
pipeline_config->MaxTraceRecursionDepth; |
|
|
|
|
data->associations[data->associations_count].pipeline_config.Flags = 0; |
|
|
|
|
data->associations[data->associations_count].export = NULL; |
|
|
|
|
data->associations_count++; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG: |
|
|
|
|
{ |
|
|
|
|
const D3D12_RAYTRACING_PIPELINE_CONFIG *pipeline_config = obj->pDesc; |
|
|
|
|
|
|
|
|
|
vkd3d_array_reserve((void **)&data->associations, &data->associations_size, |
|
|
|
|
data->associations_count + 1, |
|
|
|
|
sizeof(*data->associations)); |
|
|
|
|
|
|
|
|
|
data->associations[data->associations_count].kind = VKD3D_SHADER_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG1; |
|
|
|
|
data->associations[data->associations_count].priority = association_priority; |
|
|
|
|
data->associations[data->associations_count].pipeline_config.MaxTraceRecursionDepth = |
|
|
|
|
pipeline_config->MaxTraceRecursionDepth; |
|
|
|
|
data->associations[data->associations_count].pipeline_config.Flags = 0; |
|
|
|
|
data->associations[data->associations_count].export = NULL; |
|
|
|
|
data->associations_count++; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG1: |
|
|
|
|
{ |
|
|
|
|
const D3D12_RAYTRACING_PIPELINE_CONFIG1 *pipeline_config = obj->pDesc; |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG1: |
|
|
|
|
{ |
|
|
|
|
const D3D12_RAYTRACING_PIPELINE_CONFIG1 *pipeline_config = obj->pDesc; |
|
|
|
|
|
|
|
|
|
vkd3d_array_reserve((void **)&data->associations, &data->associations_size, |
|
|
|
|
data->associations_count + 1, |
|
|
|
|
sizeof(*data->associations)); |
|
|
|
|
vkd3d_array_reserve((void **)&data->associations, &data->associations_size, |
|
|
|
|
data->associations_count + 1, |
|
|
|
|
sizeof(*data->associations)); |
|
|
|
|
|
|
|
|
|
data->associations[data->associations_count].kind = VKD3D_SHADER_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG1; |
|
|
|
|
data->associations[data->associations_count].priority = VKD3D_ASSOCIATION_PRIORITY_DECLARED_STATE_OBJECT; |
|
|
|
|
data->associations[data->associations_count].pipeline_config = *pipeline_config; |
|
|
|
|
data->associations[data->associations_count].export = NULL; |
|
|
|
|
data->associations_count++; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
data->associations[data->associations_count].kind = VKD3D_SHADER_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG1; |
|
|
|
|
data->associations[data->associations_count].priority = association_priority; |
|
|
|
|
data->associations[data->associations_count].pipeline_config = *pipeline_config; |
|
|
|
|
data->associations[data->associations_count].export = NULL; |
|
|
|
|
data->associations_count++; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION: |
|
|
|
|
{ |
|
|
|
|
const D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION *association = obj->pDesc; |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION: |
|
|
|
|
{ |
|
|
|
|
const D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION *association = obj->pDesc; |
|
|
|
|
|
|
|
|
|
switch (association->pSubobjectToAssociate->Type) |
|
|
|
|
switch (association->pSubobjectToAssociate->Type) |
|
|
|
|
{ |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG: |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG: |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG1: |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE: |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE: |
|
|
|
|
{ |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG: |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG: |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG1: |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE: |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE: |
|
|
|
|
if (association->NumExports) |
|
|
|
|
{ |
|
|
|
|
if (association->NumExports) |
|
|
|
|
{ |
|
|
|
|
vkd3d_array_reserve((void **)&data->associations, &data->associations_size, |
|
|
|
|
data->associations_count + association->NumExports, |
|
|
|
|
sizeof(*data->associations)); |
|
|
|
|
|
|
|
|
|
for (j = 0; j < association->NumExports; j++) |
|
|
|
|
{ |
|
|
|
|
data->associations[data->associations_count].export = association->pExports[j]; |
|
|
|
|
d3d12_state_object_set_association_data(&data->associations[data->associations_count], |
|
|
|
|
association->pSubobjectToAssociate); |
|
|
|
|
data->associations[data->associations_count].priority = VKD3D_ASSOCIATION_PRIORITY_EXPLICIT; |
|
|
|
|
data->associations_count++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
vkd3d_array_reserve((void **)&data->associations, &data->associations_size, |
|
|
|
|
data->associations_count + 1, |
|
|
|
|
sizeof(*data->associations)); |
|
|
|
|
vkd3d_array_reserve((void **)&data->associations, &data->associations_size, |
|
|
|
|
data->associations_count + association->NumExports, |
|
|
|
|
sizeof(*data->associations)); |
|
|
|
|
|
|
|
|
|
/* Local root signatures being exported to NULL takes priority as the default local RS. */ |
|
|
|
|
data->associations[data->associations_count].export = NULL; |
|
|
|
|
for (i = 0; i < association->NumExports; i++) |
|
|
|
|
{ |
|
|
|
|
data->associations[data->associations_count].export = association->pExports[i]; |
|
|
|
|
d3d12_state_object_set_association_data(&data->associations[data->associations_count], |
|
|
|
|
association->pSubobjectToAssociate); |
|
|
|
|
data->associations[data->associations_count].priority = VKD3D_ASSOCIATION_PRIORITY_EXPLICIT_DEFAULT; |
|
|
|
|
data->associations[data->associations_count].priority = VKD3D_ASSOCIATION_PRIORITY_EXPLICIT; |
|
|
|
|
data->associations_count++; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
FIXME("Got unsupported subobject association type %u.\n", association->pSubobjectToAssociate->Type); |
|
|
|
|
return E_INVALIDARG; |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
vkd3d_array_reserve((void **)&data->associations, &data->associations_size, |
|
|
|
|
data->associations_count + 1, |
|
|
|
|
sizeof(*data->associations)); |
|
|
|
|
|
|
|
|
|
/* Local root signatures being exported to NULL takes priority as the default local RS. */ |
|
|
|
|
data->associations[data->associations_count].export = NULL; |
|
|
|
|
d3d12_state_object_set_association_data(&data->associations[data->associations_count], |
|
|
|
|
association->pSubobjectToAssociate); |
|
|
|
|
data->associations[data->associations_count].priority = VKD3D_ASSOCIATION_PRIORITY_EXPLICIT_DEFAULT; |
|
|
|
|
data->associations_count++; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
FIXME("Got unsupported subobject association type %u.\n", association->pSubobjectToAssociate->Type); |
|
|
|
|
return E_INVALIDARG; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION: |
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION: |
|
|
|
|
{ |
|
|
|
|
const D3D12_EXISTING_COLLECTION_DESC *collection = obj->pDesc; |
|
|
|
|
struct d3d12_state_object *library_state; |
|
|
|
|
library_state = impl_from_ID3D12StateObject(collection->pExistingCollection); |
|
|
|
|
if (FAILED(hr = d3d12_state_object_add_collection(library_state, data, |
|
|
|
|
collection->pExports, collection->NumExports))) |
|
|
|
|
{ |
|
|
|
|
const D3D12_EXISTING_COLLECTION_DESC *collection = obj->pDesc; |
|
|
|
|
struct d3d12_state_object *library_state; |
|
|
|
|
library_state = impl_from_ID3D12StateObject(collection->pExistingCollection); |
|
|
|
|
if (FAILED(hr = d3d12_state_object_add_collection(library_state, data, |
|
|
|
|
collection->pExports, collection->NumExports))) |
|
|
|
|
{ |
|
|
|
|
return hr; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
return hr; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_NODE_MASK: |
|
|
|
|
/* Just ignore this. It's irrelevant for us. */ |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
FIXME("Unrecognized subobject type: %u.\n", obj->Type); |
|
|
|
|
return E_INVALIDARG; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return S_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static HRESULT d3d12_state_object_parse_subobjects(struct d3d12_state_object *object, |
|
|
|
|
const D3D12_STATE_OBJECT_DESC *desc, |
|
|
|
|
struct d3d12_state_object *parent, |
|
|
|
|
struct d3d12_state_object_pipeline_data *data) |
|
|
|
|
{ |
|
|
|
|
struct d3d12_root_signature *root_signature; |
|
|
|
|
unsigned int i; |
|
|
|
|
HRESULT hr; |
|
|
|
|
|
|
|
|
|
case D3D12_STATE_SUBOBJECT_TYPE_NODE_MASK: |
|
|
|
|
/* Just ignore this. It's irrelevant for us. */ |
|
|
|
|
if (parent && FAILED(hr = d3d12_state_object_add_collection(parent, data, NULL, 0))) |
|
|
|
|
return hr; |
|
|
|
|
|
|
|
|
|
/* First, parse the DXIL libraries so every subobject is parsed. */ |
|
|
|
|
for (i = 0; i < desc->NumSubobjects; i++) |
|
|
|
|
{ |
|
|
|
|
const D3D12_STATE_SUBOBJECT *obj = &desc->pSubobjects[i]; |
|
|
|
|
if (obj->Type == D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY) |
|
|
|
|
if (FAILED(hr = d3d12_state_object_parse_subobject(object, obj, data, VKD3D_ASSOCIATION_PRIORITY_DECLARED_STATE_OBJECT))) |
|
|
|
|
return hr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Make sure all child state has been parsed. */ |
|
|
|
|
for (i = 0; i < data->subobjects_count; i++) |
|
|
|
|
{ |
|
|
|
|
D3D12_GLOBAL_ROOT_SIGNATURE obj_root_signature; |
|
|
|
|
D3D12_STATE_SUBOBJECT obj; |
|
|
|
|
obj.pDesc = NULL; |
|
|
|
|
|
|
|
|
|
switch (data->subobjects[i].kind) |
|
|
|
|
{ |
|
|
|
|
case VKD3D_SHADER_SUBOBJECT_KIND_STATE_OBJECT_CONFIG: |
|
|
|
|
obj.Type = D3D12_STATE_SUBOBJECT_TYPE_STATE_OBJECT_CONFIG; |
|
|
|
|
obj.pDesc = &data->subobjects[i].data.object_config; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case VKD3D_SHADER_SUBOBJECT_KIND_RAYTRACING_SHADER_CONFIG: |
|
|
|
|
obj.Type = D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG; |
|
|
|
|
obj.pDesc = &data->subobjects[i].data.shader_config; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case VKD3D_SHADER_SUBOBJECT_KIND_RAYTRACING_PIPELINE_CONFIG1: |
|
|
|
|
obj.Type = D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG1; |
|
|
|
|
obj.pDesc = &data->subobjects[i].data.pipeline_config; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case VKD3D_SHADER_SUBOBJECT_KIND_HIT_GROUP: |
|
|
|
|
obj.Type = D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP; |
|
|
|
|
obj.pDesc = &data->subobjects[i].data.hit_group; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case VKD3D_SHADER_SUBOBJECT_KIND_GLOBAL_ROOT_SIGNATURE: |
|
|
|
|
case VKD3D_SHADER_SUBOBJECT_KIND_LOCAL_ROOT_SIGNATURE: |
|
|
|
|
if (FAILED(hr = d3d12_root_signature_create(object->device, data->subobjects[i].data.payload.data, |
|
|
|
|
data->subobjects[i].data.payload.size, &root_signature))) |
|
|
|
|
return hr; |
|
|
|
|
|
|
|
|
|
d3d12_root_signature_inc_ref(root_signature); |
|
|
|
|
ID3D12RootSignature_Release(&root_signature->ID3D12RootSignature_iface); |
|
|
|
|
|
|
|
|
|
obj_root_signature.pGlobalRootSignature = &root_signature->ID3D12RootSignature_iface; |
|
|
|
|
obj.Type = data->subobjects[i].kind == VKD3D_SHADER_SUBOBJECT_KIND_GLOBAL_ROOT_SIGNATURE ? |
|
|
|
|
D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE : D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE; |
|
|
|
|
obj.pDesc = &obj_root_signature; |
|
|
|
|
|
|
|
|
|
vkd3d_array_reserve((void**)&data->subobject_root_signatures, &data->subobject_root_signatures_size, |
|
|
|
|
data->subobject_root_signatures_count + 1, sizeof(*data->subobject_root_signatures)); |
|
|
|
|
data->subobject_root_signatures[data->subobject_root_signatures_count++] = root_signature; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
FIXME("Unrecognized subobject type: %u.\n", obj->Type); |
|
|
|
|
return E_INVALIDARG; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (obj.pDesc && FAILED(hr = d3d12_state_object_parse_subobject( |
|
|
|
|
object, &obj, data, VKD3D_ASSOCIATION_PRIORITY_DXIL_SUBOBJECT))) |
|
|
|
|
return hr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return S_OK; |
|
|
|
|