From bb57f646f4ac300adbc0ffc2b6c5ab4a79fbcaa5 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 7 Nov 2014 14:30:34 +0800 Subject: demos: add a fence for presentation After xglWsiX11QueuePresent(), the image is scheduled for copying. We should not render to it until the copying is done. Otherwise, depending on how the DDX works, flickering or GPU hangs may be expected. Add and wait on the fence before submitting the command buffer. This ensures the DDX is done with the image. Set async to true to run as fast as possible. --- demos/cube.c | 20 ++++++++++++++++++-- demos/tri.c | 17 ++++++++++++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/demos/cube.c b/demos/cube.c index 8c50858c..e3f3c45d 100644 --- a/demos/cube.c +++ b/demos/cube.c @@ -205,6 +205,7 @@ struct demo { XGL_GPU_MEMORY mem; XGL_COLOR_ATTACHMENT_VIEW view; + XGL_FENCE fence; } buffers[DEMO_BUFFER_COUNT]; struct { @@ -348,17 +349,22 @@ static void demo_draw(struct demo *demo) const XGL_WSI_X11_PRESENT_INFO present = { .destWindow = demo->window, .srcImage = demo->buffers[demo->current_buffer].image, - .async = false + .async = true, + .flip = false, }; + XGL_FENCE fence = demo->buffers[demo->current_buffer].fence; XGL_RESULT err; demo_draw_build_cmd(demo); + err = xglWaitForFences(demo->device, 1, &fence, XGL_TRUE, ~((XGL_UINT64) 0)); + assert(err == XGL_SUCCESS || err == XGL_ERROR_UNAVAILABLE); + err = xglQueueSubmit(demo->queue, 1, &demo->cmd, 0, NULL, XGL_NULL_HANDLE); assert(!err); - err = xglWsiX11QueuePresent(demo->queue, &present, XGL_NULL_HANDLE); + err = xglWsiX11QueuePresent(demo->queue, &present, fence); assert(!err); demo->current_buffer = (demo->current_buffer + 1) % DEMO_BUFFER_COUNT; @@ -375,6 +381,11 @@ static void demo_prepare_buffers(struct demo *demo) }, .flags = 0, }; + const XGL_FENCE_CREATE_INFO fence = { + .sType = XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO, + .pNext = NULL, + .flags = 0, + }; XGL_RESULT err; XGL_UINT i; @@ -397,6 +408,10 @@ static void demo_prepare_buffers(struct demo *demo) err = xglCreateColorAttachmentView(demo->device, &color_attachment_view, &demo->buffers[i].view); assert(!err); + + err = xglCreateFence(demo->device, + &fence, &demo->buffers[i].fence); + assert(!err); } } @@ -1324,6 +1339,7 @@ static void demo_cleanup(struct demo *demo) xglFreeMemory(demo->depth.mem); for (i = 0; i < DEMO_BUFFER_COUNT; i++) { + xglDestroyObject(demo->buffers[i].fence); xglDestroyObject(demo->buffers[i].view); xglDestroyObject(demo->buffers[i].image); } diff --git a/demos/tri.c b/demos/tri.c index 9aae4292..3d9be2d9 100644 --- a/demos/tri.c +++ b/demos/tri.c @@ -36,6 +36,7 @@ struct demo { XGL_GPU_MEMORY mem; XGL_COLOR_ATTACHMENT_VIEW view; + XGL_FENCE fence; } buffers[DEMO_BUFFER_COUNT]; struct { @@ -142,15 +143,19 @@ static void demo_draw(struct demo *demo) .destWindow = demo->window, .srcImage = demo->buffers[demo->current_buffer].image, }; + XGL_FENCE fence = demo->buffers[demo->current_buffer].fence; XGL_RESULT err; demo_draw_build_cmd(demo); + err = xglWaitForFences(demo->device, 1, &fence, XGL_TRUE, ~((XGL_UINT64) 0)); + assert(err == XGL_SUCCESS || err == XGL_ERROR_UNAVAILABLE); + err = xglQueueSubmit(demo->queue, 1, &demo->cmd, 0, NULL, XGL_NULL_HANDLE); assert(!err); - err = xglWsiX11QueuePresent(demo->queue, &present, XGL_NULL_HANDLE); + err = xglWsiX11QueuePresent(demo->queue, &present, fence); assert(!err); demo->current_buffer = (demo->current_buffer + 1) % DEMO_BUFFER_COUNT; @@ -167,6 +172,11 @@ static void demo_prepare_buffers(struct demo *demo) }, .flags = 0, }; + const XGL_FENCE_CREATE_INFO fence = { + .sType = XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO, + .pNext = NULL, + .flags = 0, + }; XGL_RESULT err; XGL_UINT i; @@ -189,6 +199,10 @@ static void demo_prepare_buffers(struct demo *demo) err = xglCreateColorAttachmentView(demo->device, &color_attachment_view, &demo->buffers[i].view); assert(!err); + + err = xglCreateFence(demo->device, + &fence, &demo->buffers[i].fence); + assert(!err); } } @@ -894,6 +908,7 @@ static void demo_cleanup(struct demo *demo) xglFreeMemory(demo->depth.mem); for (i = 0; i < DEMO_BUFFER_COUNT; i++) { + xglDestroyObject(demo->buffers[i].fence); xglDestroyObject(demo->buffers[i].view); xglDestroyObject(demo->buffers[i].image); } -- cgit v1.2.3