From cc08339624f4ec09fda2ce8b70b586298beb0a0d Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Tue, 8 Mar 2022 15:07:24 +0100 Subject: [PATCH] vkd3d: Use internal_refcounts for pipeline state. When we store pipeline state in libraries we have to manage lifetime a bit differently, which requires internal refcounts of some sort. Signed-off-by: Hans-Kristian Arntzen --- libs/vkd3d/state.c | 38 ++++++++++++++++++++++++++------------ libs/vkd3d/vkd3d_private.h | 5 +++++ 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 7a3e8f80..2f9b82f6 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -1740,10 +1740,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_pipeline_state_QueryInterface(ID3D12Pipel return E_NOINTERFACE; } +void d3d12_pipeline_state_inc_ref(struct d3d12_pipeline_state *state) +{ + InterlockedIncrement(&state->internal_refcount); +} + static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_AddRef(ID3D12PipelineState *iface) { struct d3d12_pipeline_state *state = impl_from_ID3D12PipelineState(iface); ULONG refcount = InterlockedIncrement(&state->refcount); + if (refcount == 1) + d3d12_pipeline_state_inc_ref(state); TRACE("%p increasing refcount to %u.\n", state, refcount); @@ -1845,18 +1852,14 @@ static void d3d12_pipeline_state_set_name(struct d3d12_pipeline_state *state, co } } -static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_Release(ID3D12PipelineState *iface) +void d3d12_pipeline_state_dec_ref(struct d3d12_pipeline_state *state) { - struct d3d12_pipeline_state *state = impl_from_ID3D12PipelineState(iface); - ULONG refcount = InterlockedDecrement(&state->refcount); - - TRACE("%p decreasing refcount to %u.\n", state, refcount); + struct d3d12_device *device = state->device; + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + ULONG refcount = InterlockedDecrement(&state->internal_refcount); if (!refcount) { - struct d3d12_device *device = state->device; - const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - vkd3d_private_store_destroy(&state->private_store); d3d12_pipeline_state_free_spirv_code(state); @@ -1874,6 +1877,17 @@ static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_Release(ID3D12PipelineState d3d12_device_release(device); } +} + +static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_Release(ID3D12PipelineState *iface) +{ + struct d3d12_pipeline_state *state = impl_from_ID3D12PipelineState(iface); + ULONG refcount = InterlockedDecrement(&state->refcount); + + TRACE("%p decreasing refcount to %u.\n", state, refcount); + + if (!refcount) + d3d12_pipeline_state_dec_ref(state); return refcount; } @@ -2230,8 +2244,6 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st const struct d3d12_root_signature *root_signature; HRESULT hr; - state->ID3D12PipelineState_iface.lpVtbl = &d3d12_pipeline_state_vtbl; - state->refcount = 1; state->vk_bind_point = VK_PIPELINE_BIND_POINT_COMPUTE; if (desc->root_signature) @@ -2949,8 +2961,6 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s {VK_SHADER_STAGE_FRAGMENT_BIT, offsetof(struct d3d12_pipeline_state_desc, ps)}, }; - state->ID3D12PipelineState_iface.lpVtbl = &d3d12_pipeline_state_vtbl; - state->refcount = 1; state->vk_bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS; graphics->stage_count = 0; @@ -3625,6 +3635,10 @@ HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindP } } + object->ID3D12PipelineState_iface.lpVtbl = &d3d12_pipeline_state_vtbl; + object->refcount = 1; + object->internal_refcount = 1; + switch (bind_point) { case VK_PIPELINE_BIND_POINT_COMPUTE: diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 273ee1c3..2b66bcde 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -1524,6 +1524,7 @@ struct d3d12_pipeline_state { ID3D12PipelineState ID3D12PipelineState_iface; LONG refcount; + LONG internal_refcount; union { @@ -1557,6 +1558,10 @@ static inline bool d3d12_graphics_pipeline_state_has_unknown_dsv_format( return graphics->null_attachment_mask & dsv_attachment_mask(graphics); } +/* Private ref counts, for pipeline library. */ +void d3d12_pipeline_state_inc_ref(struct d3d12_pipeline_state *state); +void d3d12_pipeline_state_dec_ref(struct d3d12_pipeline_state *state); + struct d3d12_cached_pipeline_state { D3D12_CACHED_PIPELINE_STATE blob;