diff options
author | Jason Ekstrand <jason.ekstrand@intel.com> | 2016-03-10 18:35:00 -0800 |
---|---|---|
committer | Jason Ekstrand <jason.ekstrand@intel.com> | 2016-03-11 11:31:13 -0800 |
commit | 41a147904a95ba699358e8209e91d535f853ba61 (patch) | |
tree | 7ebccaa3233a0ae2c615d74e4cc85c7b5ac5d9f6 /src/intel/vulkan | |
parent | 132f079a8cbaeab442a7ea8b0f02b9f07dfdd310 (diff) | |
download | external_mesa3d-41a147904a95ba699358e8209e91d535f853ba61.zip external_mesa3d-41a147904a95ba699358e8209e91d535f853ba61.tar.gz external_mesa3d-41a147904a95ba699358e8209e91d535f853ba61.tar.bz2 |
anv/wsi: Throttle rendering to no more than 2 frames ahead
Right now, Vulkan apps can pretty easily DOS the GPU by simply submitting a
lot of batches. This commit makes us wait until the rendering for earlier
frames is comlete before continuing. By waiting 2 frames out, we can still
keep the pipe reasonably full but without taking the entire system down.
This is similar to what the GL driver does today.
Diffstat (limited to 'src/intel/vulkan')
-rw-r--r-- | src/intel/vulkan/anv_wsi.c | 38 | ||||
-rw-r--r-- | src/intel/vulkan/anv_wsi.h | 4 |
2 files changed, 42 insertions, 0 deletions
diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c index c5911a3..c2938f3 100644 --- a/src/intel/vulkan/anv_wsi.c +++ b/src/intel/vulkan/anv_wsi.c @@ -132,6 +132,14 @@ VkResult anv_CreateSwapchainKHR( if (result != VK_SUCCESS) return result; + if (pAllocator) + swapchain->alloc = *pAllocator; + else + swapchain->alloc = device->alloc; + + for (unsigned i = 0; i < ARRAY_SIZE(swapchain->fences); i++) + swapchain->fences[i] = VK_NULL_HANDLE; + *pSwapchain = anv_swapchain_to_handle(swapchain); return VK_SUCCESS; @@ -144,6 +152,11 @@ void anv_DestroySwapchainKHR( { ANV_FROM_HANDLE(anv_swapchain, swapchain, _swapchain); + for (unsigned i = 0; i < ARRAY_SIZE(swapchain->fences); i++) { + if (swapchain->fences[i] != VK_NULL_HANDLE) + anv_DestroyFence(device, swapchain->fences[i], pAllocator); + } + swapchain->destroy(swapchain, pAllocator); } @@ -185,11 +198,36 @@ VkResult anv_QueuePresentKHR( assert(swapchain->device == queue->device); + if (swapchain->fences[0] == VK_NULL_HANDLE) { + result = anv_CreateFence(anv_device_to_handle(queue->device), + &(VkFenceCreateInfo) { + .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + .flags = 0, + }, &swapchain->alloc, &swapchain->fences[0]); + if (result != VK_SUCCESS) + return result; + } else { + anv_ResetFences(anv_device_to_handle(queue->device), + 1, &swapchain->fences[0]); + } + + anv_QueueSubmit(_queue, 0, NULL, swapchain->fences[0]); + result = swapchain->queue_present(swapchain, queue, pPresentInfo->pImageIndices[i]); /* TODO: What if one of them returns OUT_OF_DATE? */ if (result != VK_SUCCESS) return result; + + VkFence last = swapchain->fences[2]; + swapchain->fences[2] = swapchain->fences[1]; + swapchain->fences[1] = swapchain->fences[0]; + swapchain->fences[0] = last; + + if (last != VK_NULL_HANDLE) { + anv_WaitForFences(anv_device_to_handle(queue->device), + 1, &last, true, 1); + } } return VK_SUCCESS; diff --git a/src/intel/vulkan/anv_wsi.h b/src/intel/vulkan/anv_wsi.h index 6e9ff9b..bf17f03 100644 --- a/src/intel/vulkan/anv_wsi.h +++ b/src/intel/vulkan/anv_wsi.h @@ -53,6 +53,10 @@ struct anv_wsi_interface { struct anv_swapchain { struct anv_device *device; + VkAllocationCallbacks alloc; + + VkFence fences[3]; + VkResult (*destroy)(struct anv_swapchain *swapchain, const VkAllocationCallbacks *pAllocator); VkResult (*get_images)(struct anv_swapchain *swapchain, |