vkd3d: Append UpdateTileMappings() commands to the command queue op array.

This commit is contained in:
Conor McCarthy 2023-05-30 15:57:18 +10:00 committed by Alexandre Julliard
parent e98e6c9b53
commit 3935e8647f
Notes: Alexandre Julliard 2023-06-27 23:33:57 +02:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/216
3 changed files with 158 additions and 2 deletions

View File

@ -26,6 +26,7 @@ static HRESULT d3d12_fence_signal(struct d3d12_fence *fence, uint64_t value, VkF
static void d3d12_fence_signal_timeline_semaphore(struct d3d12_fence *fence, uint64_t timeline_value);
static HRESULT d3d12_command_queue_signal(struct d3d12_command_queue *command_queue,
struct d3d12_fence *fence, uint64_t value);
static void d3d12_command_queue_submit_locked(struct d3d12_command_queue *queue);
static HRESULT d3d12_command_queue_flush_ops(struct d3d12_command_queue *queue, bool *flushed_any);
static HRESULT d3d12_command_queue_flush_ops_locked(struct d3d12_command_queue *queue, bool *flushed_any);
@ -6162,17 +6163,131 @@ static struct vkd3d_cs_op_data *d3d12_command_queue_op_array_require_space(struc
return &array->ops[array->count++];
}
static bool clone_array_parameter(void **dst, const void *src, size_t elem_size, unsigned int count)
{
void *buffer;
*dst = NULL;
if (src)
{
if (!(buffer = vkd3d_calloc(count, elem_size)))
return false;
memcpy(buffer, src, count * elem_size);
*dst = buffer;
}
return true;
}
static void update_mappings_cleanup(struct vkd3d_cs_update_mappings *update_mappings)
{
vkd3d_free(update_mappings->region_start_coordinates);
vkd3d_free(update_mappings->region_sizes);
vkd3d_free(update_mappings->range_flags);
vkd3d_free(update_mappings->heap_range_offsets);
vkd3d_free(update_mappings->range_tile_counts);
}
static void STDMETHODCALLTYPE d3d12_command_queue_UpdateTileMappings(ID3D12CommandQueue *iface,
ID3D12Resource *resource, UINT region_count,
const D3D12_TILED_RESOURCE_COORDINATE *region_start_coordinates, const D3D12_TILE_REGION_SIZE *region_sizes,
ID3D12Heap *heap, UINT range_count, const D3D12_TILE_RANGE_FLAGS *range_flags,
const UINT *heap_range_offsets, const UINT *range_tile_counts, D3D12_TILE_MAPPING_FLAGS flags)
{
FIXME("iface %p, resource %p, region_count %u, region_start_coordinates %p, "
struct d3d12_resource *resource_impl = unsafe_impl_from_ID3D12Resource(resource);
struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface);
struct d3d12_heap *heap_impl = unsafe_impl_from_ID3D12Heap(heap);
struct vkd3d_cs_update_mappings update_mappings = {0};
struct vkd3d_cs_op_data *op;
TRACE("iface %p, resource %p, region_count %u, region_start_coordinates %p, "
"region_sizes %p, heap %p, range_count %u, range_flags %p, heap_range_offsets %p, "
"range_tile_counts %p, flags %#x stub!\n",
"range_tile_counts %p, flags %#x.\n",
iface, resource, region_count, region_start_coordinates, region_sizes, heap, range_count,
range_flags, heap_range_offsets, range_tile_counts, flags);
if (!region_count || !range_count)
return;
if (!command_queue->supports_sparse_binding)
{
FIXME("Command queue %p does not support sparse binding.\n", command_queue);
return;
}
if (!resource_impl->tiles.subresource_count)
{
WARN("Resource %p is not a tiled resource.\n", resource_impl);
return;
}
if (region_count > 1 && !region_start_coordinates)
{
WARN("Region start coordinates must not be NULL when region count is > 1.\n");
return;
}
if (range_count > 1 && !range_tile_counts)
{
WARN("Range tile counts must not be NULL when range count is > 1.\n");
return;
}
update_mappings.resource = resource_impl;
update_mappings.heap = heap_impl;
if (!clone_array_parameter((void **)&update_mappings.region_start_coordinates,
region_start_coordinates, sizeof(*region_start_coordinates), region_count))
{
ERR("Failed to allocate region start coordinates.\n");
return;
}
if (!clone_array_parameter((void **)&update_mappings.region_sizes,
region_sizes, sizeof(*region_sizes), region_count))
{
ERR("Failed to allocate region sizes.\n");
goto free_clones;
}
if (!clone_array_parameter((void **)&update_mappings.range_flags,
range_flags, sizeof(*range_flags), range_count))
{
ERR("Failed to allocate range flags.\n");
goto free_clones;
}
if (!clone_array_parameter((void **)&update_mappings.heap_range_offsets,
heap_range_offsets, sizeof(*heap_range_offsets), range_count))
{
ERR("Failed to allocate heap range offsets.\n");
goto free_clones;
}
if (!clone_array_parameter((void **)&update_mappings.range_tile_counts,
range_tile_counts, sizeof(*range_tile_counts), range_count))
{
ERR("Failed to allocate range tile counts.\n");
goto free_clones;
}
update_mappings.region_count = region_count;
update_mappings.range_count = range_count;
update_mappings.flags = flags;
vkd3d_mutex_lock(&command_queue->op_mutex);
if (!(op = d3d12_command_queue_op_array_require_space(&command_queue->op_queue)))
{
ERR("Failed to add op.\n");
goto unlock_mutex;
}
op->opcode = VKD3D_CS_OP_UPDATE_MAPPINGS;
op->u.update_mappings = update_mappings;
d3d12_command_queue_submit_locked(command_queue);
vkd3d_mutex_unlock(&command_queue->op_mutex);
return;
unlock_mutex:
vkd3d_mutex_unlock(&command_queue->op_mutex);
free_clones:
update_mappings_cleanup(&update_mappings);
}
static void STDMETHODCALLTYPE d3d12_command_queue_CopyTileMappings(ID3D12CommandQueue *iface,
@ -6934,6 +7049,11 @@ static HRESULT d3d12_command_queue_flush_ops_locked(struct d3d12_command_queue *
d3d12_command_queue_execute(queue, op->u.execute.buffers, op->u.execute.buffer_count);
break;
case VKD3D_CS_OP_UPDATE_MAPPINGS:
FIXME("Tiled resource binding is not supported yet.\n");
update_mappings_cleanup(&op->u.update_mappings);
break;
default:
vkd3d_unreachable();
}
@ -7000,6 +7120,8 @@ static HRESULT d3d12_command_queue_init(struct d3d12_command_queue *queue,
if (FAILED(hr = vkd3d_fence_worker_start(&queue->fence_worker, queue->vkd3d_queue, device)))
goto fail_destroy_op_mutex;
queue->supports_sparse_binding = !!(queue->vkd3d_queue->vk_queue_flags & VK_QUEUE_SPARSE_BINDING_BIT);
d3d12_device_add_ref(queue->device = device);
return S_OK;

View File

@ -1057,6 +1057,11 @@ static void d3d12_resource_get_level_box(const struct d3d12_resource *resource,
box->back = d3d12_resource_desc_get_depth(&resource->desc, level);
}
static void d3d12_resource_init_tiles(struct d3d12_resource *resource)
{
resource->tiles.subresource_count = d3d12_resource_desc_get_sub_resource_count(&resource->desc);
}
/* ID3D12Resource */
static inline struct d3d12_resource *impl_from_ID3D12Resource(ID3D12Resource *iface)
{
@ -1826,6 +1831,8 @@ static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12
resource->heap = NULL;
resource->heap_offset = 0;
memset(&resource->tiles, 0, sizeof(resource->tiles));
if (FAILED(hr = vkd3d_private_store_init(&resource->private_store)))
{
d3d12_resource_destroy(resource, device);
@ -2011,6 +2018,8 @@ HRESULT d3d12_reserved_resource_create(struct d3d12_device *device,
desc, initial_state, optimized_clear_value, &object)))
return hr;
d3d12_resource_init_tiles(object);
TRACE("Created reserved resource %p.\n", object);
*resource = object;

View File

@ -673,6 +673,11 @@ struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface);
#define VKD3D_RESOURCE_DEDICATED_HEAP 0x00000008
#define VKD3D_RESOURCE_LINEAR_TILING 0x00000010
struct d3d12_resource_tile_info
{
unsigned int subresource_count;
};
/* ID3D12Resource */
struct d3d12_resource
{
@ -701,6 +706,8 @@ struct d3d12_resource
struct d3d12_device *device;
struct d3d12_resource_tile_info tiles;
struct vkd3d_private_store private_store;
};
@ -1457,6 +1464,7 @@ enum vkd3d_cs_op
VKD3D_CS_OP_WAIT,
VKD3D_CS_OP_SIGNAL,
VKD3D_CS_OP_EXECUTE,
VKD3D_CS_OP_UPDATE_MAPPINGS,
};
struct vkd3d_cs_wait
@ -1477,6 +1485,20 @@ struct vkd3d_cs_execute
unsigned int buffer_count;
};
struct vkd3d_cs_update_mappings
{
struct d3d12_resource *resource;
struct d3d12_heap *heap;
D3D12_TILED_RESOURCE_COORDINATE *region_start_coordinates;
D3D12_TILE_REGION_SIZE *region_sizes;
D3D12_TILE_RANGE_FLAGS *range_flags;
UINT *heap_range_offsets;
UINT *range_tile_counts;
UINT region_count;
UINT range_count;
D3D12_TILE_MAPPING_FLAGS flags;
};
struct vkd3d_cs_op_data
{
enum vkd3d_cs_op opcode;
@ -1485,6 +1507,7 @@ struct vkd3d_cs_op_data
struct vkd3d_cs_wait wait;
struct vkd3d_cs_signal signal;
struct vkd3d_cs_execute execute;
struct vkd3d_cs_update_mappings update_mappings;
} u;
};
@ -1522,6 +1545,8 @@ struct d3d12_command_queue
* set, aux_op_queue.count must be zero. */
struct d3d12_command_queue_op_array aux_op_queue;
bool supports_sparse_binding;
struct vkd3d_private_store private_store;
};