vkd3d: Implement virtual query allocation.
Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
This commit is contained in:
parent
634d8fd0fa
commit
16f5cff061
|
@ -1549,7 +1549,11 @@ static ULONG STDMETHODCALLTYPE d3d12_command_allocator_Release(ID3D12CommandAllo
|
|||
for (i = 0; i < allocator->scratch_buffer_count; i++)
|
||||
d3d12_device_return_scratch_buffer(device, &allocator->scratch_buffers[i]);
|
||||
|
||||
for (i = 0; i < allocator->query_pool_count; i++)
|
||||
d3d12_device_return_query_pool(device, &allocator->query_pools[i]);
|
||||
|
||||
vkd3d_free(allocator->scratch_buffers);
|
||||
vkd3d_free(allocator->query_pools);
|
||||
vkd3d_free(allocator);
|
||||
|
||||
d3d12_device_release(device);
|
||||
|
@ -1670,6 +1674,13 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_allocator_Reset(ID3D12CommandAllo
|
|||
d3d12_device_return_scratch_buffer(device, &allocator->scratch_buffers[i]);
|
||||
|
||||
allocator->scratch_buffer_count = 0;
|
||||
|
||||
/* Return query pools to the device */
|
||||
for (i = 0; i < allocator->query_pool_count; i++)
|
||||
d3d12_device_return_query_pool(device, &allocator->query_pools[i]);
|
||||
|
||||
allocator->query_pool_count = 0;
|
||||
memset(&allocator->active_query_pools, 0, sizeof(allocator->active_query_pools));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1779,6 +1790,11 @@ static HRESULT d3d12_command_allocator_init(struct d3d12_command_allocator *allo
|
|||
allocator->scratch_buffers_size = 0;
|
||||
allocator->scratch_buffer_count = 0;
|
||||
|
||||
allocator->query_pools = NULL;
|
||||
allocator->query_pools_size = 0;
|
||||
allocator->query_pool_count = 0;
|
||||
memset(&allocator->active_query_pools, 0, sizeof(allocator->active_query_pools));
|
||||
|
||||
allocator->current_command_list = NULL;
|
||||
|
||||
d3d12_device_add_ref(allocator->device = device);
|
||||
|
@ -1870,6 +1886,58 @@ static bool d3d12_command_allocator_allocate_scratch_memory(struct d3d12_command
|
|||
return true;
|
||||
}
|
||||
|
||||
static struct vkd3d_query_pool *d3d12_command_allocator_find_active_query_pool(struct d3d12_command_allocator *allocator,
|
||||
D3D12_QUERY_HEAP_TYPE heap_type)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
static const struct
|
||||
{
|
||||
D3D12_QUERY_HEAP_TYPE heap_type;
|
||||
uint32_t index;
|
||||
}
|
||||
map[] =
|
||||
{
|
||||
{ D3D12_QUERY_HEAP_TYPE_OCCLUSION, VKD3D_QUERY_TYPE_INDEX_OCCLUSION },
|
||||
{ D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS, VKD3D_QUERY_TYPE_INDEX_PIPELINE_STATISTICS },
|
||||
{ D3D12_QUERY_HEAP_TYPE_SO_STATISTICS, VKD3D_QUERY_TYPE_INDEX_TRANSFORM_FEEDBACK },
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(map); i++)
|
||||
{
|
||||
if (map[i].heap_type == heap_type)
|
||||
return &allocator->active_query_pools[map[i].index];
|
||||
}
|
||||
|
||||
ERR("Unhandled query heap type %u.\n", heap_type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool d3d12_command_allocator_allocate_query(struct d3d12_command_allocator *allocator,
|
||||
D3D12_QUERY_HEAP_TYPE heap_type, VkQueryPool *query_pool, uint32_t *query_index)
|
||||
{
|
||||
struct vkd3d_query_pool *pool = d3d12_command_allocator_find_active_query_pool(allocator, heap_type);
|
||||
|
||||
if (!pool)
|
||||
return false;
|
||||
|
||||
if (pool->next_index >= pool->query_count)
|
||||
{
|
||||
if (FAILED(d3d12_device_get_query_pool(allocator->device, heap_type, pool)))
|
||||
return false;
|
||||
|
||||
if (vkd3d_array_reserve((void**)&allocator->query_pools, &allocator->query_pools_size,
|
||||
allocator->query_pool_count + 1, sizeof(*allocator->query_pools)))
|
||||
allocator->query_pools[allocator->query_pool_count++] = *pool;
|
||||
else
|
||||
ERR("Failed to add query pool.\n");
|
||||
}
|
||||
|
||||
*query_pool = pool->vk_query_pool;
|
||||
*query_index = pool->next_index++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ID3D12CommandList */
|
||||
static inline struct d3d12_command_list *impl_from_ID3D12GraphicsCommandList(d3d12_command_list_iface *iface)
|
||||
{
|
||||
|
|
|
@ -2364,6 +2364,115 @@ void d3d12_device_return_scratch_buffer(struct d3d12_device *device, const struc
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT d3d12_device_create_query_pool(struct d3d12_device *device, D3D12_QUERY_HEAP_TYPE heap_type, struct vkd3d_query_pool *pool)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
VkQueryPoolCreateInfo pool_info;
|
||||
VkResult vr;
|
||||
|
||||
TRACE("device %p, heap_type %u, pool %p.\n", device, heap_type, pool);
|
||||
|
||||
pool_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
|
||||
pool_info.pNext = NULL;
|
||||
pool_info.flags = 0;
|
||||
pool_info.pipelineStatistics = 0;
|
||||
|
||||
switch (heap_type)
|
||||
{
|
||||
case D3D12_QUERY_HEAP_TYPE_OCCLUSION:
|
||||
/* Expect a large number of occlusion queries
|
||||
* to be used within a single command list */
|
||||
pool_info.queryType = VK_QUERY_TYPE_OCCLUSION;
|
||||
pool_info.queryCount = 4096;
|
||||
break;
|
||||
|
||||
case D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS:
|
||||
pool_info.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS;
|
||||
pool_info.queryCount = 128;
|
||||
pool_info.pipelineStatistics =
|
||||
VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT |
|
||||
VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT;
|
||||
break;
|
||||
|
||||
case D3D12_QUERY_HEAP_TYPE_SO_STATISTICS:
|
||||
pool_info.queryType = VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT;
|
||||
pool_info.queryCount = 128;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR("Unhandled query type %u.\n", heap_type);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if ((vr = VK_CALL(vkCreateQueryPool(device->vk_device, &pool_info, NULL, &pool->vk_query_pool))) < 0)
|
||||
{
|
||||
ERR("Failed to create query pool, vr %u.\n", vr);
|
||||
return hresult_from_vk_result(vr);
|
||||
}
|
||||
|
||||
pool->heap_type = heap_type;
|
||||
pool->query_count = pool_info.queryCount;
|
||||
pool->next_index = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void d3d12_device_destroy_query_pool(struct d3d12_device *device, const struct vkd3d_query_pool *pool)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
|
||||
TRACE("device %p, pool %p.\n", device, pool);
|
||||
|
||||
VK_CALL(vkDestroyQueryPool(device->vk_device, pool->vk_query_pool, NULL));
|
||||
}
|
||||
|
||||
HRESULT d3d12_device_get_query_pool(struct d3d12_device *device, D3D12_QUERY_HEAP_TYPE heap_type, struct vkd3d_query_pool *pool)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
pthread_mutex_lock(&device->mutex);
|
||||
|
||||
for (i = 0; i < device->query_pool_count; i++)
|
||||
{
|
||||
if (device->query_pools[i].heap_type == heap_type)
|
||||
{
|
||||
*pool = device->query_pools[i];
|
||||
pool->next_index = 0;
|
||||
if (--device->query_pool_count != i)
|
||||
device->query_pools[i] = device->query_pools[device->query_pool_count];
|
||||
pthread_mutex_unlock(&device->mutex);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&device->mutex);
|
||||
return d3d12_device_create_query_pool(device, heap_type, pool);
|
||||
}
|
||||
|
||||
void d3d12_device_return_query_pool(struct d3d12_device *device, const struct vkd3d_query_pool *pool)
|
||||
{
|
||||
pthread_mutex_lock(&device->mutex);
|
||||
|
||||
if (device->query_pool_count < VKD3D_VIRTUAL_QUERY_POOL_COUNT)
|
||||
{
|
||||
device->query_pools[device->query_pool_count++] = *pool;
|
||||
pthread_mutex_unlock(&device->mutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_mutex_unlock(&device->mutex);
|
||||
d3d12_device_destroy_query_pool(device, pool);
|
||||
}
|
||||
}
|
||||
|
||||
/* ID3D12Device */
|
||||
static inline struct d3d12_device *impl_from_ID3D12Device(d3d12_device_iface *iface)
|
||||
{
|
||||
|
@ -2414,6 +2523,9 @@ static void d3d12_device_destroy(struct d3d12_device *device)
|
|||
for (i = 0; i < device->scratch_buffer_count; i++)
|
||||
d3d12_device_destroy_scratch_buffer(device, &device->scratch_buffers[i]);
|
||||
|
||||
for (i = 0; i < device->query_pool_count; i++)
|
||||
d3d12_device_destroy_query_pool(device, &device->query_pools[i]);
|
||||
|
||||
vkd3d_private_store_destroy(&device->private_store);
|
||||
|
||||
vkd3d_cleanup_format_info(device);
|
||||
|
|
|
@ -1127,6 +1127,20 @@ struct vkd3d_scratch_buffer
|
|||
VkDeviceAddress va;
|
||||
};
|
||||
|
||||
#define VKD3D_QUERY_TYPE_INDEX_OCCLUSION (0u)
|
||||
#define VKD3D_QUERY_TYPE_INDEX_PIPELINE_STATISTICS (1u)
|
||||
#define VKD3D_QUERY_TYPE_INDEX_TRANSFORM_FEEDBACK (2u)
|
||||
#define VKD3D_VIRTUAL_QUERY_TYPE_COUNT (3u)
|
||||
#define VKD3D_VIRTUAL_QUERY_POOL_COUNT (128u)
|
||||
|
||||
struct vkd3d_query_pool
|
||||
{
|
||||
D3D12_QUERY_HEAP_TYPE heap_type;
|
||||
VkQueryPool vk_query_pool;
|
||||
uint32_t query_count;
|
||||
uint32_t next_index;
|
||||
};
|
||||
|
||||
/* ID3D12CommandAllocator */
|
||||
struct d3d12_command_allocator
|
||||
{
|
||||
|
@ -1164,6 +1178,12 @@ struct d3d12_command_allocator
|
|||
size_t scratch_buffers_size;
|
||||
size_t scratch_buffer_count;
|
||||
|
||||
struct vkd3d_query_pool *query_pools;
|
||||
size_t query_pools_size;
|
||||
size_t query_pool_count;
|
||||
|
||||
struct vkd3d_query_pool active_query_pools[VKD3D_VIRTUAL_QUERY_TYPE_COUNT];
|
||||
|
||||
LONG outstanding_submissions_count;
|
||||
|
||||
struct d3d12_command_list *current_command_list;
|
||||
|
@ -2087,6 +2107,9 @@ struct d3d12_device
|
|||
struct vkd3d_scratch_buffer scratch_buffers[VKD3D_SCRATCH_BUFFER_COUNT];
|
||||
size_t scratch_buffer_count;
|
||||
|
||||
struct vkd3d_query_pool query_pools[VKD3D_VIRTUAL_QUERY_POOL_COUNT];
|
||||
size_t query_pool_count;
|
||||
|
||||
HRESULT removed_reason;
|
||||
|
||||
const struct vkd3d_format *depth_stencil_formats;
|
||||
|
@ -2113,6 +2136,9 @@ struct d3d12_device *unsafe_impl_from_ID3D12Device(d3d12_device_iface *iface);
|
|||
HRESULT d3d12_device_get_scratch_buffer(struct d3d12_device *device, VkDeviceSize min_size, struct vkd3d_scratch_buffer *scratch);
|
||||
void d3d12_device_return_scratch_buffer(struct d3d12_device *device, const struct vkd3d_scratch_buffer *scratch);
|
||||
|
||||
HRESULT d3d12_device_get_query_pool(struct d3d12_device *device, D3D12_QUERY_HEAP_TYPE heap_type, struct vkd3d_query_pool *pool);
|
||||
void d3d12_device_return_query_pool(struct d3d12_device *device, const struct vkd3d_query_pool *pool);
|
||||
|
||||
static inline HRESULT d3d12_device_query_interface(struct d3d12_device *device, REFIID iid, void **object)
|
||||
{
|
||||
return ID3D12Device6_QueryInterface(&device->ID3D12Device_iface, iid, object);
|
||||
|
|
Loading…
Reference in New Issue