diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 5a3ab325..19010dec 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -753,9 +753,11 @@ int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc, void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *code); int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc, - struct vkd3d_versioned_root_signature_desc *root_signature); + struct vkd3d_versioned_root_signature_desc *root_signature, + vkd3d_shader_hash_t *compatibility_hash); int vkd3d_shader_parse_root_signature_raw(const char *data, unsigned int data_size, - struct vkd3d_versioned_root_signature_desc *desc); + struct vkd3d_versioned_root_signature_desc *desc, + vkd3d_shader_hash_t *compatibility_hash); void vkd3d_shader_free_root_signature(struct vkd3d_versioned_root_signature_desc *root_signature); /* FIXME: Add support for returning error messages (ID3DBlob). */ @@ -865,7 +867,8 @@ typedef int (*PFN_vkd3d_shader_compile_dxbc)(const struct vkd3d_shader_code *dxb typedef void (*PFN_vkd3d_shader_free_shader_code)(struct vkd3d_shader_code *code); typedef int (*PFN_vkd3d_shader_parse_root_signature)(const struct vkd3d_shader_code *dxbc, - struct vkd3d_versioned_root_signature_desc *root_signature); + struct vkd3d_versioned_root_signature_desc *root_signature, + vkd3d_shader_hash_t *compatibility_hash); typedef void (*PFN_vkd3d_shader_free_root_signature)(struct vkd3d_versioned_root_signature_desc *root_signature); typedef int (*PFN_vkd3d_shader_serialize_root_signature)( diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index a48ff3a3..c449e49c 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -2756,7 +2756,8 @@ static int shader_parse_static_samplers(struct root_signature_parser_context *co } int vkd3d_shader_parse_root_signature_raw(const char *data, unsigned int data_size, - struct vkd3d_versioned_root_signature_desc *desc) + struct vkd3d_versioned_root_signature_desc *desc, + vkd3d_shader_hash_t *compatibility_hash) { struct vkd3d_root_signature_desc *v_1_0 = &desc->v_1_0; struct root_signature_parser_context context; @@ -2837,27 +2838,46 @@ int vkd3d_shader_parse_root_signature_raw(const char *data, unsigned int data_si read_uint32(&ptr, &v_1_0->flags); TRACE("Flags %#x.\n", v_1_0->flags); + if (compatibility_hash) + { + struct vkd3d_shader_code code = { data, data_size }; + *compatibility_hash = vkd3d_shader_hash(&code); + } + return VKD3D_OK; } static int rts0_handler(const char *data, DWORD data_size, DWORD tag, void *context) { - struct vkd3d_versioned_root_signature_desc *desc = context; + struct vkd3d_shader_code *payload = context; if (tag != TAG_RTS0) return VKD3D_OK; - return vkd3d_shader_parse_root_signature_raw(data, data_size, desc); + payload->code = data; + payload->size = data_size; + return VKD3D_OK; } int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc, - struct vkd3d_versioned_root_signature_desc *root_signature) + struct vkd3d_versioned_root_signature_desc *root_signature, + vkd3d_shader_hash_t *compatibility_hash) { + struct vkd3d_shader_code raw_payload; int ret; TRACE("dxbc {%p, %zu}, root_signature %p.\n", dxbc->code, dxbc->size, root_signature); - if ((ret = parse_dxbc(dxbc->code, dxbc->size, rts0_handler, root_signature)) < 0) + memset(&raw_payload, 0, sizeof(raw_payload)); + + if ((ret = parse_dxbc(dxbc->code, dxbc->size, rts0_handler, &raw_payload)) < 0) + return ret; + + if (!raw_payload.code) + return VKD3D_OK; + + if ((ret = vkd3d_shader_parse_root_signature_raw(raw_payload.code, raw_payload.size, + root_signature, compatibility_hash)) < 0) { vkd3d_shader_free_root_signature(root_signature); return ret; diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 4f5000da..93fbaf4a 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -1510,13 +1510,14 @@ static HRESULT d3d12_root_signature_create_from_blob(struct d3d12_device *device D3D12_VERSIONED_ROOT_SIGNATURE_DESC d3d12; struct vkd3d_versioned_root_signature_desc vkd3d; } root_signature_desc; + vkd3d_shader_hash_t compatibility_hash; struct d3d12_root_signature *object; HRESULT hr; int ret; if (raw_payload) { - if ((ret = vkd3d_parse_root_signature_v_1_1_from_raw_payload(&dxbc, &root_signature_desc.vkd3d))) + if ((ret = vkd3d_parse_root_signature_v_1_1_from_raw_payload(&dxbc, &root_signature_desc.vkd3d, &compatibility_hash))) { WARN("Failed to parse root signature, vkd3d result %d.\n", ret); return hresult_from_vkd3d_result(ret); @@ -1524,7 +1525,7 @@ static HRESULT d3d12_root_signature_create_from_blob(struct d3d12_device *device } else { - if ((ret = vkd3d_parse_root_signature_v_1_1(&dxbc, &root_signature_desc.vkd3d)) < 0) + if ((ret = vkd3d_parse_root_signature_v_1_1(&dxbc, &root_signature_desc.vkd3d, &compatibility_hash)) < 0) { WARN("Failed to parse root signature, vkd3d result %d.\n", ret); return hresult_from_vkd3d_result(ret); @@ -1541,7 +1542,7 @@ static HRESULT d3d12_root_signature_create_from_blob(struct d3d12_device *device /* For pipeline libraries, (and later DXR to some degree), we need a way to * compare root signature objects. */ - object->compatibility_hash = vkd3d_shader_hash(&dxbc); + object->compatibility_hash = compatibility_hash; vkd3d_shader_free_root_signature(&root_signature_desc.vkd3d); if (FAILED(hr)) diff --git a/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/vkd3d_main.c index 9052a06b..090df4d1 100644 --- a/libs/vkd3d/vkd3d_main.c +++ b/libs/vkd3d/vkd3d_main.c @@ -166,14 +166,15 @@ static CONST_VTBL struct ID3D12RootSignatureDeserializerVtbl d3d12_root_signatur static int vkd3d_parse_root_signature_for_version(const struct vkd3d_shader_code *dxbc, struct vkd3d_versioned_root_signature_desc *out_desc, enum vkd3d_root_signature_version target_version, - bool raw_payload) + bool raw_payload, + vkd3d_shader_hash_t *compatibility_hash) { struct vkd3d_versioned_root_signature_desc desc, converted_desc; int ret; if (raw_payload) { - if ((ret = vkd3d_shader_parse_root_signature_raw(dxbc->code, dxbc->size, &desc)) < 0) + if ((ret = vkd3d_shader_parse_root_signature_raw(dxbc->code, dxbc->size, &desc, compatibility_hash)) < 0) { WARN("Failed to parse root signature, vkd3d result %d.\n", ret); return ret; @@ -181,7 +182,7 @@ static int vkd3d_parse_root_signature_for_version(const struct vkd3d_shader_code } else { - if ((ret = vkd3d_shader_parse_root_signature(dxbc, &desc)) < 0) + if ((ret = vkd3d_shader_parse_root_signature(dxbc, &desc, compatibility_hash)) < 0) { WARN("Failed to parse root signature, vkd3d result %d.\n", ret); return ret; @@ -209,21 +210,27 @@ static int vkd3d_parse_root_signature_for_version(const struct vkd3d_shader_code } int vkd3d_parse_root_signature_v_1_0(const struct vkd3d_shader_code *dxbc, - struct vkd3d_versioned_root_signature_desc *out_desc) + struct vkd3d_versioned_root_signature_desc *out_desc, + vkd3d_shader_hash_t *compatibility_hash) { - return vkd3d_parse_root_signature_for_version(dxbc, out_desc, VKD3D_ROOT_SIGNATURE_VERSION_1_0, false); + return vkd3d_parse_root_signature_for_version(dxbc, out_desc, VKD3D_ROOT_SIGNATURE_VERSION_1_0, false, + compatibility_hash); } int vkd3d_parse_root_signature_v_1_1(const struct vkd3d_shader_code *dxbc, - struct vkd3d_versioned_root_signature_desc *out_desc) + struct vkd3d_versioned_root_signature_desc *out_desc, + vkd3d_shader_hash_t *compatibility_hash) { - return vkd3d_parse_root_signature_for_version(dxbc, out_desc, VKD3D_ROOT_SIGNATURE_VERSION_1_1, false); + return vkd3d_parse_root_signature_for_version(dxbc, out_desc, VKD3D_ROOT_SIGNATURE_VERSION_1_1, false, + compatibility_hash); } int vkd3d_parse_root_signature_v_1_1_from_raw_payload(const struct vkd3d_shader_code *dxbc, - struct vkd3d_versioned_root_signature_desc *out_desc) + struct vkd3d_versioned_root_signature_desc *out_desc, + vkd3d_shader_hash_t *compatibility_hash) { - return vkd3d_parse_root_signature_for_version(dxbc, out_desc, VKD3D_ROOT_SIGNATURE_VERSION_1_1, true); + return vkd3d_parse_root_signature_for_version(dxbc, out_desc, VKD3D_ROOT_SIGNATURE_VERSION_1_1, true, + compatibility_hash); } static HRESULT d3d12_root_signature_deserializer_init(struct d3d12_root_signature_deserializer *deserializer, @@ -234,7 +241,7 @@ static HRESULT d3d12_root_signature_deserializer_init(struct d3d12_root_signatur deserializer->ID3D12RootSignatureDeserializer_iface.lpVtbl = &d3d12_root_signature_deserializer_vtbl; deserializer->refcount = 1; - if ((ret = vkd3d_parse_root_signature_v_1_0(dxbc, &deserializer->desc.vkd3d)) < 0) + if ((ret = vkd3d_parse_root_signature_v_1_0(dxbc, &deserializer->desc.vkd3d, NULL)) < 0) return hresult_from_vkd3d_result(ret); return S_OK; @@ -412,7 +419,7 @@ static HRESULT d3d12_versioned_root_signature_deserializer_init(struct d3d12_ver deserializer->ID3D12VersionedRootSignatureDeserializer_iface.lpVtbl = &d3d12_versioned_root_signature_deserializer_vtbl; deserializer->refcount = 1; - if ((ret = vkd3d_shader_parse_root_signature(dxbc, &deserializer->desc.vkd3d)) < 0) + if ((ret = vkd3d_shader_parse_root_signature(dxbc, &deserializer->desc.vkd3d, NULL)) < 0) { WARN("Failed to parse root signature, vkd3d result %d.\n", ret); return hresult_from_vkd3d_result(ret); diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index a7d7fcfe..f98ebdbb 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -1429,11 +1429,14 @@ HRESULT vkd3d_create_pipeline_layout(struct d3d12_device *device, VkPipelineLayout *pipeline_layout); int vkd3d_parse_root_signature_v_1_0(const struct vkd3d_shader_code *dxbc, - struct vkd3d_versioned_root_signature_desc *desc); + struct vkd3d_versioned_root_signature_desc *desc, + vkd3d_shader_hash_t *compatibility_hash); int vkd3d_parse_root_signature_v_1_1(const struct vkd3d_shader_code *dxbc, - struct vkd3d_versioned_root_signature_desc *desc); + struct vkd3d_versioned_root_signature_desc *desc, + vkd3d_shader_hash_t *compatibility_hash); int vkd3d_parse_root_signature_v_1_1_from_raw_payload(const struct vkd3d_shader_code *dxbc, - struct vkd3d_versioned_root_signature_desc *desc); + struct vkd3d_versioned_root_signature_desc *desc, + vkd3d_shader_hash_t *compatibility_hash); VkShaderStageFlags vkd3d_vk_stage_flags_from_visibility(D3D12_SHADER_VISIBILITY visibility); enum vkd3d_shader_visibility vkd3d_shader_visibility_from_d3d12(D3D12_SHADER_VISIBILITY visibility);