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 <post@arntzen-software.no>
This commit is contained in:
Hans-Kristian Arntzen 2022-03-08 15:07:24 +01:00
parent 422f6804fb
commit cc08339624
2 changed files with 31 additions and 12 deletions

View File

@ -1740,10 +1740,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_pipeline_state_QueryInterface(ID3D12Pipel
return E_NOINTERFACE; 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) static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_AddRef(ID3D12PipelineState *iface)
{ {
struct d3d12_pipeline_state *state = impl_from_ID3D12PipelineState(iface); struct d3d12_pipeline_state *state = impl_from_ID3D12PipelineState(iface);
ULONG refcount = InterlockedIncrement(&state->refcount); ULONG refcount = InterlockedIncrement(&state->refcount);
if (refcount == 1)
d3d12_pipeline_state_inc_ref(state);
TRACE("%p increasing refcount to %u.\n", state, refcount); 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); struct d3d12_device *device = state->device;
ULONG refcount = InterlockedDecrement(&state->refcount); const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
ULONG refcount = InterlockedDecrement(&state->internal_refcount);
TRACE("%p decreasing refcount to %u.\n", state, refcount);
if (!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); vkd3d_private_store_destroy(&state->private_store);
d3d12_pipeline_state_free_spirv_code(state); d3d12_pipeline_state_free_spirv_code(state);
@ -1874,6 +1877,17 @@ static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_Release(ID3D12PipelineState
d3d12_device_release(device); 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; 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; const struct d3d12_root_signature *root_signature;
HRESULT hr; HRESULT hr;
state->ID3D12PipelineState_iface.lpVtbl = &d3d12_pipeline_state_vtbl;
state->refcount = 1;
state->vk_bind_point = VK_PIPELINE_BIND_POINT_COMPUTE; state->vk_bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
if (desc->root_signature) 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)}, {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; state->vk_bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS;
graphics->stage_count = 0; 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) switch (bind_point)
{ {
case VK_PIPELINE_BIND_POINT_COMPUTE: case VK_PIPELINE_BIND_POINT_COMPUTE:

View File

@ -1524,6 +1524,7 @@ struct d3d12_pipeline_state
{ {
ID3D12PipelineState ID3D12PipelineState_iface; ID3D12PipelineState ID3D12PipelineState_iface;
LONG refcount; LONG refcount;
LONG internal_refcount;
union 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); 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 struct d3d12_cached_pipeline_state
{ {
D3D12_CACHED_PIPELINE_STATE blob; D3D12_CACHED_PIPELINE_STATE blob;