radv: add semaphore support

Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:
Dave Airlie 2016-12-01 01:52:31 +00:00 committed by Bas Nieuwenhuizen
parent d270b5fac3
commit 72aaa83f4b
3 changed files with 72 additions and 11 deletions

View File

@ -857,6 +857,10 @@ VkResult radv_QueueSubmit(
}
ret = queue->device->ws->cs_submit(ctx, queue->queue_idx, cs_array,
pSubmits[i].commandBufferCount,
(struct radeon_winsys_sem **)pSubmits[i].pWaitSemaphores,
pSubmits[i].waitSemaphoreCount,
(struct radeon_winsys_sem **)pSubmits[i].pSignalSemaphores,
pSubmits[i].signalSemaphoreCount,
can_patch, base_fence);
if (ret)
radv_loge("failed to submit CS %d\n", i);
@ -866,7 +870,7 @@ VkResult radv_QueueSubmit(
if (fence) {
if (!submitCount)
ret = queue->device->ws->cs_submit(ctx, queue->queue_idx, &queue->device->empty_cs,
1, false, base_fence);
1, NULL, 0, NULL, 0, false, base_fence);
fence->submitted = true;
}
@ -1270,25 +1274,34 @@ VkResult radv_GetFenceStatus(VkDevice _device, VkFence _fence)
// Queue semaphore functions
VkResult radv_CreateSemaphore(
VkDevice device,
VkDevice _device,
const VkSemaphoreCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSemaphore* pSemaphore)
{
/* The DRM execbuffer ioctl always execute in-oder, even between different
* rings. As such, there's nothing to do for the user space semaphore.
*/
RADV_FROM_HANDLE(radv_device, device, _device);
struct radeon_winsys_sem *sem;
*pSemaphore = (VkSemaphore)1;
sem = device->ws->create_sem(device->ws);
if (!sem)
return VK_ERROR_OUT_OF_HOST_MEMORY;
*pSemaphore = (VkSemaphore)sem;
return VK_SUCCESS;
}
void radv_DestroySemaphore(
VkDevice device,
VkSemaphore semaphore,
VkDevice _device,
VkSemaphore _semaphore,
const VkAllocationCallbacks* pAllocator)
{
RADV_FROM_HANDLE(radv_device, device, _device);
struct radeon_winsys_sem *sem;
if (!_semaphore)
return;
sem = (struct radeon_winsys_sem *)_semaphore;
device->ws->destroy_sem(sem);
}
VkResult radv_CreateEvent(

View File

@ -253,6 +253,7 @@ struct radeon_bo_metadata {
struct radeon_winsys_bo;
struct radeon_winsys_fence;
struct radeon_winsys_sem;
struct radeon_winsys {
void (*destroy)(struct radeon_winsys *ws);
@ -304,6 +305,10 @@ struct radeon_winsys {
int queue_index,
struct radeon_winsys_cs **cs_array,
unsigned cs_count,
struct radeon_winsys_sem **wait_sem,
unsigned wait_sem_count,
struct radeon_winsys_sem **signal_sem,
unsigned signal_sem_count,
bool can_patch,
struct radeon_winsys_fence *fence);
@ -326,6 +331,10 @@ struct radeon_winsys {
struct radeon_winsys_fence *fence,
bool absolute,
uint64_t timeout);
struct radeon_winsys_sem *(*create_sem)(struct radeon_winsys *ws);
void (*destroy_sem)(struct radeon_winsys_sem *sem);
};
static inline void radeon_emit(struct radeon_winsys_cs *cs, uint32_t value)

View File

@ -739,20 +739,40 @@ static int radv_amdgpu_winsys_cs_submit(struct radeon_winsys_ctx *_ctx,
int queue_idx,
struct radeon_winsys_cs **cs_array,
unsigned cs_count,
struct radeon_winsys_sem **wait_sem,
unsigned wait_sem_count,
struct radeon_winsys_sem **signal_sem,
unsigned signal_sem_count,
bool can_patch,
struct radeon_winsys_fence *_fence)
{
struct radv_amdgpu_cs *cs = radv_amdgpu_cs(cs_array[0]);
struct radv_amdgpu_ctx *ctx = radv_amdgpu_ctx(_ctx);
int ret;
int i;
for (i = 0; i < wait_sem_count; i++) {
amdgpu_semaphore_handle sem = (amdgpu_semaphore_handle)wait_sem[i];
amdgpu_cs_wait_semaphore(ctx->ctx, cs->hw_ip, 0, queue_idx,
sem);
}
if (!cs->ws->use_ib_bos) {
return radv_amdgpu_winsys_cs_submit_sysmem(_ctx, queue_idx, cs_array,
ret = radv_amdgpu_winsys_cs_submit_sysmem(_ctx, queue_idx, cs_array,
cs_count, _fence);
} else if (can_patch && cs_count > AMDGPU_CS_MAX_IBS_PER_SUBMIT && false) {
return radv_amdgpu_winsys_cs_submit_chained(_ctx, queue_idx, cs_array,
ret = radv_amdgpu_winsys_cs_submit_chained(_ctx, queue_idx, cs_array,
cs_count, _fence);
} else {
return radv_amdgpu_winsys_cs_submit_fallback(_ctx, queue_idx, cs_array,
ret = radv_amdgpu_winsys_cs_submit_fallback(_ctx, queue_idx, cs_array,
cs_count, _fence);
}
for (i = 0; i < signal_sem_count; i++) {
amdgpu_semaphore_handle sem = (amdgpu_semaphore_handle)signal_sem[i];
amdgpu_cs_signal_semaphore(ctx->ctx, cs->hw_ip, 0, queue_idx,
sem);
}
return ret;
}
static struct radeon_winsys_ctx *radv_amdgpu_ctx_create(struct radeon_winsys *_ws)
@ -800,6 +820,23 @@ static bool radv_amdgpu_ctx_wait_idle(struct radeon_winsys_ctx *rwctx,
return true;
}
static struct radeon_winsys_sem *radv_amdgpu_create_sem(struct radeon_winsys *_ws)
{
int ret;
amdgpu_semaphore_handle sem;
ret = amdgpu_cs_create_semaphore(&sem);
if (ret)
return NULL;
return (struct radeon_winsys_sem *)sem;
}
static void radv_amdgpu_destroy_sem(struct radeon_winsys_sem *_sem)
{
amdgpu_semaphore_handle sem = (amdgpu_semaphore_handle)_sem;
amdgpu_cs_destroy_semaphore(sem);
}
void radv_amdgpu_cs_init_functions(struct radv_amdgpu_winsys *ws)
{
ws->base.ctx_create = radv_amdgpu_ctx_create;
@ -815,5 +852,7 @@ void radv_amdgpu_cs_init_functions(struct radv_amdgpu_winsys *ws)
ws->base.cs_submit = radv_amdgpu_winsys_cs_submit;
ws->base.create_fence = radv_amdgpu_create_fence;
ws->base.destroy_fence = radv_amdgpu_destroy_fence;
ws->base.create_sem = radv_amdgpu_create_sem;
ws->base.destroy_sem = radv_amdgpu_destroy_sem;
ws->base.fence_wait = radv_amdgpu_fence_wait;
}