mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
libs/vkd3d: Delay destroying render passes until the command list is destroyed.
Render passes should only be destroyed after all submitted commands referring to them have completed execution.
This commit is contained in:
parent
ee3c147f82
commit
fb6071d108
@ -656,6 +656,17 @@ static inline struct d3d12_command_list *impl_from_ID3D12GraphicsCommandList(ID3
|
||||
return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList_iface);
|
||||
}
|
||||
|
||||
static bool d3d12_command_list_add_render_pass(struct d3d12_command_list *list, VkRenderPass pass)
|
||||
{
|
||||
if (!vkd3d_array_reserve((void **)&list->passes, &list->passes_size,
|
||||
list->pass_count + 1, sizeof(*list->passes)))
|
||||
return false;
|
||||
|
||||
list->passes[list->pass_count++] = pass;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12GraphicsCommandList *iface,
|
||||
REFIID riid, void **object)
|
||||
{
|
||||
@ -698,11 +709,20 @@ static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandL
|
||||
if (!refcount)
|
||||
{
|
||||
struct d3d12_device *device = list->device;
|
||||
struct vkd3d_vk_device_procs *vk_procs;
|
||||
unsigned int i;
|
||||
|
||||
vk_procs = &device->vk_procs;
|
||||
|
||||
/* When command pool is destroyed, all command buffers are implicitly freed. */
|
||||
if (list->allocator)
|
||||
vkd3d_command_allocator_free_command_list(list->allocator, list);
|
||||
|
||||
for (i = 0; i < list->pass_count; ++i)
|
||||
{
|
||||
VK_CALL(vkDestroyRenderPass(device->vk_device, list->passes[i], NULL));
|
||||
}
|
||||
|
||||
vkd3d_free(list);
|
||||
|
||||
ID3D12Device_Release(&device->ID3D12Device_iface);
|
||||
@ -1211,6 +1231,13 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra
|
||||
return;
|
||||
}
|
||||
|
||||
if (!d3d12_command_list_add_render_pass(list, vk_render_pass))
|
||||
{
|
||||
WARN("Failed to add render pass,\n");
|
||||
VK_CALL(vkDestroyRenderPass(list->device->vk_device, vk_render_pass, NULL));
|
||||
return;
|
||||
}
|
||||
|
||||
fb_desc.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
fb_desc.pNext = NULL;
|
||||
fb_desc.flags = 0;
|
||||
@ -1223,7 +1250,6 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra
|
||||
if ((vr = VK_CALL(vkCreateFramebuffer(list->device->vk_device, &fb_desc, NULL, &vk_framebuffer))) < 0)
|
||||
{
|
||||
WARN("Failed to create Vulkan framebuffer, vr %d.\n", vr);
|
||||
VK_CALL(vkDestroyRenderPass(list->device->vk_device, vk_render_pass, NULL));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1245,8 +1271,6 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra
|
||||
}
|
||||
|
||||
VK_CALL(vkDestroyFramebuffer(list->device->vk_device, vk_framebuffer, NULL));
|
||||
|
||||
VK_CALL(vkDestroyRenderPass(list->device->vk_device, vk_render_pass, NULL));
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList *iface,
|
||||
@ -1407,16 +1431,19 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d
|
||||
|
||||
list->type = type;
|
||||
list->device = device;
|
||||
ID3D12Device_AddRef(&device->ID3D12Device_iface);
|
||||
|
||||
list->allocator = allocator;
|
||||
if (FAILED(hr = vkd3d_command_allocator_allocate_command_list(allocator, list)))
|
||||
return hr;
|
||||
|
||||
list->passes = NULL;
|
||||
list->passes_size = 0;
|
||||
list->pass_count = 0;
|
||||
|
||||
if (initial_pipeline_state)
|
||||
FIXME("Ignoring initial pipeline state %p.\n", initial_pipeline_state);
|
||||
|
||||
ID3D12Device_AddRef(&device->ID3D12Device_iface);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,34 @@
|
||||
|
||||
#include "vkd3d_private.h"
|
||||
|
||||
bool vkd3d_array_reserve(void **elements, size_t *capacity, size_t element_count, size_t element_size)
|
||||
{
|
||||
size_t new_capacity, max_capacity;
|
||||
void *new_elements;
|
||||
|
||||
if (element_count <= *capacity)
|
||||
return true;
|
||||
|
||||
max_capacity = ~(size_t)0 / element_size;
|
||||
if (max_capacity < element_count)
|
||||
return false;
|
||||
|
||||
new_capacity = max(*capacity, 4);
|
||||
while (new_capacity < element_count && new_capacity <= max_capacity / 2)
|
||||
new_capacity *= 2;
|
||||
|
||||
if (new_capacity < element_count)
|
||||
new_capacity = element_count;
|
||||
|
||||
if (!(new_elements = vkd3d_realloc(*elements, new_capacity * element_size)))
|
||||
return false;
|
||||
|
||||
*elements = new_elements;
|
||||
*capacity = new_capacity;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL is_valid_feature_level(D3D_FEATURE_LEVEL feature_level)
|
||||
{
|
||||
static const D3D_FEATURE_LEVEL valid_feature_levels[] =
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define VKD3D_DESCRIPTOR_MAGIC_FREE 0x00000000u
|
||||
#define VKD3D_DESCRIPTOR_MAGIC_RTV 0x00565452u
|
||||
@ -205,6 +206,10 @@ struct d3d12_command_list
|
||||
VkCommandBuffer vk_command_buffer;
|
||||
BOOL is_recording;
|
||||
|
||||
VkRenderPass *passes;
|
||||
size_t passes_size;
|
||||
size_t pass_count;
|
||||
|
||||
struct d3d12_command_allocator *allocator;
|
||||
struct d3d12_device *device;
|
||||
};
|
||||
@ -261,6 +266,9 @@ const char *debug_vk_queue_flags(VkQueueFlags flags) DECLSPEC_HIDDEN;
|
||||
|
||||
VkFormat vk_format_from_dxgi_format(DXGI_FORMAT format) DECLSPEC_HIDDEN;
|
||||
|
||||
bool vkd3d_array_reserve(void **elements, size_t *capacity,
|
||||
size_t element_count, size_t element_size) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline void *vkd3d_malloc(size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
Loading…
Reference in New Issue
Block a user