zink: move sparse buffer commit to screen queue
all queue submission must be serialized with the dispatch thread Acked-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11437>
This commit is contained in:
parent
478f129ee7
commit
97f8249336
|
@ -3137,6 +3137,29 @@ out:
|
|||
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT);
|
||||
}
|
||||
|
||||
static inline struct zink_screen **
|
||||
get_screen_ptr_for_commit(uint8_t *mem)
|
||||
{
|
||||
return (struct zink_screen**)(mem + sizeof(VkBindSparseInfo) + sizeof(VkSparseBufferMemoryBindInfo) + sizeof(VkSparseMemoryBind));
|
||||
}
|
||||
|
||||
static bool
|
||||
resource_commit(struct zink_screen *screen, VkBindSparseInfo *sparse)
|
||||
{
|
||||
VkQueue queue = screen->threaded ? screen->thread_queue : screen->queue;
|
||||
|
||||
VkResult ret = vkQueueBindSparse(queue, 1, sparse, VK_NULL_HANDLE);
|
||||
return zink_screen_handle_vkresult(screen, ret);
|
||||
}
|
||||
|
||||
static void
|
||||
submit_resource_commit(void *data, void *gdata, int thread_index)
|
||||
{
|
||||
struct zink_screen **screen = get_screen_ptr_for_commit(data);
|
||||
resource_commit(*screen, data);
|
||||
free(data);
|
||||
}
|
||||
|
||||
static bool
|
||||
zink_resource_commit(struct pipe_context *pctx, struct pipe_resource *pres, unsigned level, struct pipe_box *box, bool commit)
|
||||
{
|
||||
|
@ -3149,37 +3172,48 @@ zink_resource_commit(struct pipe_context *pctx, struct pipe_resource *pres, unsi
|
|||
zink_batch_usage_is_unflushed(res->obj->writes))
|
||||
zink_flush_queue(ctx);
|
||||
|
||||
VkBindSparseInfo sparse;
|
||||
sparse.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
|
||||
sparse.pNext = NULL;
|
||||
sparse.waitSemaphoreCount = 0;
|
||||
sparse.bufferBindCount = 1;
|
||||
sparse.imageOpaqueBindCount = 0;
|
||||
sparse.imageBindCount = 0;
|
||||
sparse.signalSemaphoreCount = 0;
|
||||
uint8_t *mem = malloc(sizeof(VkBindSparseInfo) + sizeof(VkSparseBufferMemoryBindInfo) + sizeof(VkSparseMemoryBind) + sizeof(void*));
|
||||
if (!mem)
|
||||
return false;
|
||||
VkBindSparseInfo *sparse = (void*)mem;
|
||||
sparse->sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
|
||||
sparse->pNext = NULL;
|
||||
sparse->waitSemaphoreCount = 0;
|
||||
sparse->bufferBindCount = 1;
|
||||
sparse->imageOpaqueBindCount = 0;
|
||||
sparse->imageBindCount = 0;
|
||||
sparse->signalSemaphoreCount = 0;
|
||||
|
||||
VkSparseBufferMemoryBindInfo sparse_bind;
|
||||
sparse_bind.buffer = res->obj->buffer;
|
||||
sparse_bind.bindCount = 1;
|
||||
sparse.pBufferBinds = &sparse_bind;
|
||||
VkSparseBufferMemoryBindInfo *sparse_bind = (void*)(mem + sizeof(VkBindSparseInfo));
|
||||
sparse_bind->buffer = res->obj->buffer;
|
||||
sparse_bind->bindCount = 1;
|
||||
sparse->pBufferBinds = sparse_bind;
|
||||
|
||||
VkSparseMemoryBind mem_bind;
|
||||
mem_bind.resourceOffset = box->x;
|
||||
mem_bind.size = box->width;
|
||||
mem_bind.memory = commit ? res->obj->mem : VK_NULL_HANDLE;
|
||||
VkSparseMemoryBind *mem_bind = (void*)(mem + sizeof(VkBindSparseInfo) + sizeof(VkSparseBufferMemoryBindInfo));
|
||||
mem_bind->resourceOffset = box->x;
|
||||
mem_bind->size = box->width;
|
||||
mem_bind->memory = commit ? res->obj->mem : VK_NULL_HANDLE;
|
||||
/* currently sparse buffers allocate memory 1:1 for the max sparse size,
|
||||
* but probably it should dynamically allocate the committed regions;
|
||||
* if this ever changes, update the below line
|
||||
*/
|
||||
mem_bind.memoryOffset = box->x;
|
||||
mem_bind.flags = 0;
|
||||
sparse_bind.pBinds = &mem_bind;
|
||||
VkQueue queue = screen->threaded ? screen->thread_queue : screen->queue;
|
||||
mem_bind->memoryOffset = box->x;
|
||||
mem_bind->flags = 0;
|
||||
sparse_bind->pBinds = mem_bind;
|
||||
|
||||
VkResult ret = vkQueueBindSparse(queue, 1, &sparse, VK_NULL_HANDLE);
|
||||
if (!zink_screen_handle_vkresult(screen, ret)) {
|
||||
struct zink_screen **ptr = get_screen_ptr_for_commit(mem);
|
||||
*ptr = screen;
|
||||
|
||||
if (screen->threaded) {
|
||||
/* this doesn't need any kind of fencing because any access to this resource
|
||||
* will be automagically synchronized by queue dispatch */
|
||||
util_queue_add_job(&screen->flush_queue, mem, NULL, submit_resource_commit, NULL, 0);
|
||||
} else {
|
||||
bool ret = resource_commit(screen, sparse);
|
||||
if (!ret)
|
||||
check_device_lost(ctx);
|
||||
return false;
|
||||
free(sparse);
|
||||
return ret;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue