From: Stefan Dösinger stefan@codeweavers.com
--- libs/vkd3d/device.c | 42 +++++++++++++++++++++++++++++--------- libs/vkd3d/state.c | 16 ++++++++++++++- libs/vkd3d/vkd3d_private.h | 2 ++ 3 files changed, 49 insertions(+), 11 deletions(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index b0e6deb1d..38d13f5e6 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -4469,7 +4469,6 @@ static bool d3d12_device_load_cache2(struct vkd3d_shader_cache *cache, /* Handled already */ break;
- case SHADER_CACHE_ENTRY_COMPUTE_STATE: /* TODO */ break;
@@ -4495,12 +4494,21 @@ static bool d3d12_device_load_cache2(struct vkd3d_shader_cache *cache, if (ret) ERR("whut?\n");
+ /* Fall through */ + case SHADER_CACHE_ENTRY_COMPUTE_STATE: + if (e->type == SHADER_CACHE_ENTRY_COMPUTE_STATE) + { + s = (void *)value; + k = NULL; /* gcc thinks it may be used uninitialized. */ + } + ret = vkd3d_shader_cache_get(cache, &s->root_signature, sizeof(s->root_signature), NULL, &size); if (ret) { FIXME("Did not find root signature %lx for graphics pipeline\n", s->root_signature); - vkd3d_free(s); + if (s != key) + vkd3d_free(s); break; } rs = vkd3d_malloc(size); @@ -4523,6 +4531,9 @@ static bool d3d12_device_load_cache2(struct vkd3d_shader_cache *cache, memset(&desc, 0, sizeof(desc)); desc.root_signature = &d3d12_root_sig->ID3D12RootSignature_iface;
+ desc.cs.BytecodeLength = s->cs_size; + desc.cs.pShaderBytecode = s->cs_size ? s->data + pos : NULL; + pos += s->cs_size; desc.vs.BytecodeLength = s->vs_size; desc.vs.pShaderBytecode = s->vs_size ? s->data + pos : NULL; pos += s->vs_size; @@ -4602,19 +4613,30 @@ static bool d3d12_device_load_cache2(struct vkd3d_shader_cache *cache, * FIXME: The manipulation of the device refcount in init() and Release() makes it * unsafe to move this function to a separate thread. We might hold and release the * last reference to the device. */ - hr = d3d12_pipeline_state_init_graphics(object, device, &desc); - if (SUCCEEDED(hr)) + if (e->type == SHADER_CACHE_ENTRY_GRAPHICS_PIPELINE) + { + hr = d3d12_pipeline_state_init_graphics(object, device, &desc); + if (SUCCEEDED(hr)) + { + VkRenderPass pass; + VkPipeline p = d3d12_pipeline_state_get_or_create_pipeline(object, + k->topology, k->strides, k->dsv_format, &pass); + TRACE("got render pass %lx\n", p); + ID3D12PipelineState_Release(&object->ID3D12PipelineState_iface); + } + vkd3d_free(s); + } + else if (e->type == SHADER_CACHE_ENTRY_COMPUTE_STATE) { - VkRenderPass pass; - VkPipeline p = d3d12_pipeline_state_get_or_create_pipeline(object, - k->topology, k->strides, k->dsv_format, &pass); - TRACE("got render pass %lx\n", p); - ID3D12PipelineState_Release(&object->ID3D12PipelineState_iface); + hr = d3d12_pipeline_state_init_compute(object, device, &desc); + if (SUCCEEDED(hr)) + ID3D12PipelineState_Release(&object->ID3D12PipelineState_iface); + else + ERR("Cached compute pipeline did not build.\n"); }
vkd3d_free(so_decl); vkd3d_free(il_element); - vkd3d_free(s); break; }
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index c59a97aa1..508b6d659 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -2603,15 +2603,17 @@ static struct vkd3d_shader_cache_pipeline_state *vkd3d_cache_pipeline_from_d3d( return entry; }
-static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *state, +HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *state, struct d3d12_device *device, const struct d3d12_pipeline_state_desc *desc) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; struct vkd3d_shader_interface_info shader_interface; struct vkd3d_shader_descriptor_offset_info offset_info; + struct vkd3d_shader_cache_pipeline_state *cache_entry; const struct d3d12_root_signature *root_signature; struct vkd3d_shader_spirv_target_info target_info; VkPipelineLayout vk_pipeline_layout; + uint32_t cache_entry_size; HRESULT hr;
state->ID3D12PipelineState_iface.lpVtbl = &d3d12_pipeline_state_vtbl; @@ -2682,6 +2684,18 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st return hr; }
+ cache_entry = vkd3d_cache_pipeline_from_d3d(desc, root_signature, &cache_entry_size); + if (cache_entry) + { + uint64_t hash; + cache_entry->super.type = SHADER_CACHE_ENTRY_COMPUTE_STATE; + hash = hash_key(cache_entry, cache_entry_size); + vkd3d_shader_cache_put(device->persistent_cache, &hash, sizeof(hash), + cache_entry, cache_entry_size); + vkd3d_free(cache_entry); + state->state_hash = hash; + } + state->vk_bind_point = VK_PIPELINE_BIND_POINT_COMPUTE; d3d12_device_add_ref(state->device = device);
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 3c28166e9..3535d4389 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -1463,6 +1463,8 @@ HRESULT d3d12_pipeline_state_create_compute(struct d3d12_device *device, const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state); HRESULT d3d12_pipeline_state_create_graphics(struct d3d12_device *device, const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state); +HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *state, + struct d3d12_device *device, const struct d3d12_pipeline_state_desc *desc); HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *state, struct d3d12_device *device, const struct d3d12_pipeline_state_desc *desc); HRESULT d3d12_pipeline_state_create(struct d3d12_device *device,