Merge execute and present commands for RenderingDeviceDriver.
This commit is contained in:
parent
fb10e67fef
commit
ee2d8f68ba
@ -1955,13 +1955,14 @@ RDD::CommandQueueID RenderingDeviceDriverD3D12::command_queue_create(CommandQueu
|
|||||||
return CommandQueueID(command_queue);
|
return CommandQueueID(command_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
Error RenderingDeviceDriverD3D12::command_queue_execute(CommandQueueID p_cmd_queue, VectorView<CommandBufferID> p_cmd_buffers, VectorView<SemaphoreID> p_wait_semaphores, VectorView<SemaphoreID> p_signal_semaphores, FenceID p_signal_fence) {
|
Error RenderingDeviceDriverD3D12::command_queue_execute_and_present(CommandQueueID p_cmd_queue, VectorView<SemaphoreID> p_wait_semaphores, VectorView<CommandBufferID> p_cmd_buffers, VectorView<SemaphoreID> p_cmd_semaphores, FenceID p_cmd_fence, VectorView<SwapChainID> p_swap_chains) {
|
||||||
CommandQueueInfo *command_queue = (CommandQueueInfo *)(p_cmd_queue.id);
|
CommandQueueInfo *command_queue = (CommandQueueInfo *)(p_cmd_queue.id);
|
||||||
for (uint32_t i = 0; i < p_wait_semaphores.size(); i++) {
|
for (uint32_t i = 0; i < p_wait_semaphores.size(); i++) {
|
||||||
const SemaphoreInfo *semaphore = (const SemaphoreInfo *)(p_wait_semaphores[i].id);
|
const SemaphoreInfo *semaphore = (const SemaphoreInfo *)(p_wait_semaphores[i].id);
|
||||||
command_queue->d3d_queue->Wait(semaphore->d3d_fence.Get(), semaphore->fence_value);
|
command_queue->d3d_queue->Wait(semaphore->d3d_fence.Get(), semaphore->fence_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p_cmd_buffers.size() > 0) {
|
||||||
thread_local LocalVector<ID3D12CommandList *> command_lists;
|
thread_local LocalVector<ID3D12CommandList *> command_lists;
|
||||||
command_lists.resize(p_cmd_buffers.size());
|
command_lists.resize(p_cmd_buffers.size());
|
||||||
for (uint32_t i = 0; i < p_cmd_buffers.size(); i++) {
|
for (uint32_t i = 0; i < p_cmd_buffers.size(); i++) {
|
||||||
@ -1971,32 +1972,27 @@ Error RenderingDeviceDriverD3D12::command_queue_execute(CommandQueueID p_cmd_que
|
|||||||
|
|
||||||
command_queue->d3d_queue->ExecuteCommandLists(command_lists.size(), command_lists.ptr());
|
command_queue->d3d_queue->ExecuteCommandLists(command_lists.size(), command_lists.ptr());
|
||||||
|
|
||||||
for (uint32_t i = 0; i < p_signal_semaphores.size(); i++) {
|
for (uint32_t i = 0; i < p_cmd_semaphores.size(); i++) {
|
||||||
SemaphoreInfo *semaphore = (SemaphoreInfo *)(p_signal_semaphores[i].id);
|
SemaphoreInfo *semaphore = (SemaphoreInfo *)(p_cmd_semaphores[i].id);
|
||||||
semaphore->fence_value++;
|
semaphore->fence_value++;
|
||||||
command_queue->d3d_queue->Signal(semaphore->d3d_fence.Get(), semaphore->fence_value);
|
command_queue->d3d_queue->Signal(semaphore->d3d_fence.Get(), semaphore->fence_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_signal_fence) {
|
if (p_cmd_fence) {
|
||||||
FenceInfo *fence = (FenceInfo *)(p_signal_fence.id);
|
FenceInfo *fence = (FenceInfo *)(p_cmd_fence.id);
|
||||||
fence->fence_value++;
|
fence->fence_value++;
|
||||||
command_queue->d3d_queue->Signal(fence->d3d_fence.Get(), fence->fence_value);
|
command_queue->d3d_queue->Signal(fence->d3d_fence.Get(), fence->fence_value);
|
||||||
fence->d3d_fence->SetEventOnCompletion(fence->fence_value, fence->event_handle);
|
fence->d3d_fence->SetEventOnCompletion(fence->fence_value, fence->event_handle);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error RenderingDeviceDriverD3D12::command_queue_present(CommandQueueID p_cmd_queue, VectorView<SwapChainID> p_swap_chains, VectorView<SemaphoreID> p_wait_semaphores) {
|
|
||||||
// D3D12 does not require waiting for the command queue's semaphores to handle presentation.
|
|
||||||
// We just present the swap chains that were specified and ignore the command queue and the semaphores.
|
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
bool any_present_failed = false;
|
bool any_present_failed = false;
|
||||||
for (uint32_t i = 0; i < p_swap_chains.size(); i++) {
|
for (uint32_t i = 0; i < p_swap_chains.size(); i++) {
|
||||||
SwapChain *swap_chain = (SwapChain *)(p_swap_chains[i].id);
|
SwapChain *swap_chain = (SwapChain *)(p_swap_chains[i].id);
|
||||||
res = swap_chain->d3d_swap_chain->Present(swap_chain->sync_interval, swap_chain->present_flags);
|
res = swap_chain->d3d_swap_chain->Present(swap_chain->sync_interval, swap_chain->present_flags);
|
||||||
if (!SUCCEEDED(res)) {
|
if (!SUCCEEDED(res)) {
|
||||||
print_verbose("D3D12: Presenting swapchain failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
|
print_verbose(vformat("D3D12: Presenting swapchain failed with error 0x%08ux.", (uint64_t)res));
|
||||||
any_present_failed = true;
|
any_present_failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -413,8 +413,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
virtual CommandQueueID command_queue_create(CommandQueueFamilyID p_cmd_queue_family, bool p_identify_as_main_queue = false) override;
|
virtual CommandQueueID command_queue_create(CommandQueueFamilyID p_cmd_queue_family, bool p_identify_as_main_queue = false) override;
|
||||||
virtual Error command_queue_execute(CommandQueueID p_cmd_queue, VectorView<CommandBufferID> p_cmd_buffers, VectorView<SemaphoreID> p_wait_semaphores, VectorView<SemaphoreID> p_signal_semaphores, FenceID p_signal_fence) override;
|
virtual Error command_queue_execute_and_present(CommandQueueID p_cmd_queue, VectorView<SemaphoreID> p_wait_semaphores, VectorView<CommandBufferID> p_cmd_buffers, VectorView<SemaphoreID> p_cmd_semaphores, FenceID p_cmd_fence, VectorView<SwapChainID> p_swap_chains) override;
|
||||||
virtual Error command_queue_present(CommandQueueID p_cmd_queue, VectorView<SwapChainID> p_swap_chains, VectorView<SemaphoreID> p_wait_semaphores) override;
|
|
||||||
virtual void command_queue_free(CommandQueueID p_cmd_queue) override;
|
virtual void command_queue_free(CommandQueueID p_cmd_queue) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1113,12 +1113,12 @@ void RenderingDeviceDriverVulkan::_set_object_name(VkObjectType p_object_type, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
Error RenderingDeviceDriverVulkan::initialize(uint32_t p_device_index, uint32_t p_frame_count) {
|
Error RenderingDeviceDriverVulkan::initialize(uint32_t p_device_index, uint32_t p_frame_count) {
|
||||||
// Frame count is not required for the Vulkan driver, so we just ignore it.
|
|
||||||
|
|
||||||
context_device = context_driver->device_get(p_device_index);
|
context_device = context_driver->device_get(p_device_index);
|
||||||
physical_device = context_driver->physical_device_get(p_device_index);
|
physical_device = context_driver->physical_device_get(p_device_index);
|
||||||
vkGetPhysicalDeviceProperties(physical_device, &physical_device_properties);
|
vkGetPhysicalDeviceProperties(physical_device, &physical_device_properties);
|
||||||
|
|
||||||
|
frame_count = p_frame_count;
|
||||||
|
|
||||||
// Copy the queue family properties the context already retrieved.
|
// Copy the queue family properties the context already retrieved.
|
||||||
uint32_t queue_family_count = context_driver->queue_family_get_count(p_device_index);
|
uint32_t queue_family_count = context_driver->queue_family_get_count(p_device_index);
|
||||||
queue_family_properties.resize(queue_family_count);
|
queue_family_properties.resize(queue_family_count);
|
||||||
@ -2131,21 +2131,18 @@ RDD::CommandQueueID RenderingDeviceDriverVulkan::command_queue_create(CommandQue
|
|||||||
return CommandQueueID(command_queue);
|
return CommandQueueID(command_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
Error RenderingDeviceDriverVulkan::command_queue_execute(CommandQueueID p_cmd_queue, VectorView<CommandBufferID> p_cmd_buffers, VectorView<SemaphoreID> p_wait_semaphores, VectorView<SemaphoreID> p_signal_semaphores, FenceID p_signal_fence) {
|
Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueueID p_cmd_queue, VectorView<SemaphoreID> p_wait_semaphores, VectorView<CommandBufferID> p_cmd_buffers, VectorView<SemaphoreID> p_cmd_semaphores, FenceID p_cmd_fence, VectorView<SwapChainID> p_swap_chains) {
|
||||||
DEV_ASSERT(p_cmd_queue.id != 0);
|
DEV_ASSERT(p_cmd_queue.id != 0);
|
||||||
|
|
||||||
|
VkResult err;
|
||||||
CommandQueue *command_queue = (CommandQueue *)(p_cmd_queue.id);
|
CommandQueue *command_queue = (CommandQueue *)(p_cmd_queue.id);
|
||||||
Queue &device_queue = queue_families[command_queue->queue_family][command_queue->queue_index];
|
Queue &device_queue = queue_families[command_queue->queue_family][command_queue->queue_index];
|
||||||
Fence *fence = (Fence *)(p_signal_fence.id);
|
Fence *fence = (Fence *)(p_cmd_fence.id);
|
||||||
VkFence vk_fence = (fence != nullptr) ? fence->vk_fence : VK_NULL_HANDLE;
|
VkFence vk_fence = (fence != nullptr) ? fence->vk_fence : VK_NULL_HANDLE;
|
||||||
|
|
||||||
thread_local LocalVector<VkCommandBuffer> command_buffers;
|
|
||||||
thread_local LocalVector<VkSemaphore> wait_semaphores;
|
thread_local LocalVector<VkSemaphore> wait_semaphores;
|
||||||
thread_local LocalVector<VkSemaphore> signal_semaphores;
|
|
||||||
thread_local LocalVector<VkPipelineStageFlags> wait_semaphores_stages;
|
thread_local LocalVector<VkPipelineStageFlags> wait_semaphores_stages;
|
||||||
command_buffers.clear();
|
|
||||||
wait_semaphores.clear();
|
wait_semaphores.clear();
|
||||||
signal_semaphores.clear();
|
|
||||||
wait_semaphores_stages.clear();
|
wait_semaphores_stages.clear();
|
||||||
|
|
||||||
if (!command_queue->pending_semaphores_for_execute.is_empty()) {
|
if (!command_queue->pending_semaphores_for_execute.is_empty()) {
|
||||||
@ -2158,18 +2155,47 @@ Error RenderingDeviceDriverVulkan::command_queue_execute(CommandQueueID p_cmd_qu
|
|||||||
command_queue->pending_semaphores_for_execute.clear();
|
command_queue->pending_semaphores_for_execute.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < p_cmd_buffers.size(); i++) {
|
|
||||||
command_buffers.push_back(VkCommandBuffer(p_cmd_buffers[i].id));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < p_wait_semaphores.size(); i++) {
|
for (uint32_t i = 0; i < p_wait_semaphores.size(); i++) {
|
||||||
// FIXME: Allow specifying the stage mask in more detail.
|
// FIXME: Allow specifying the stage mask in more detail.
|
||||||
wait_semaphores.push_back(VkSemaphore(p_wait_semaphores[i].id));
|
wait_semaphores.push_back(VkSemaphore(p_wait_semaphores[i].id));
|
||||||
wait_semaphores_stages.push_back(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
|
wait_semaphores_stages.push_back(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < p_signal_semaphores.size(); i++) {
|
if (p_cmd_buffers.size() > 0) {
|
||||||
signal_semaphores.push_back(VkSemaphore(p_signal_semaphores[i].id));
|
thread_local LocalVector<VkCommandBuffer> command_buffers;
|
||||||
|
thread_local LocalVector<VkSemaphore> signal_semaphores;
|
||||||
|
command_buffers.clear();
|
||||||
|
signal_semaphores.clear();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < p_cmd_buffers.size(); i++) {
|
||||||
|
command_buffers.push_back(VkCommandBuffer(p_cmd_buffers[i].id));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < p_cmd_semaphores.size(); i++) {
|
||||||
|
signal_semaphores.push_back(VkSemaphore(p_cmd_semaphores[i].id));
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSemaphore present_semaphore = VK_NULL_HANDLE;
|
||||||
|
if (p_swap_chains.size() > 0) {
|
||||||
|
if (command_queue->present_semaphores.is_empty()) {
|
||||||
|
// Create the semaphores used for presentation if they haven't been created yet.
|
||||||
|
VkSemaphore semaphore = VK_NULL_HANDLE;
|
||||||
|
VkSemaphoreCreateInfo create_info = {};
|
||||||
|
create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < frame_count; i++) {
|
||||||
|
err = vkCreateSemaphore(vk_device, &create_info, nullptr, &semaphore);
|
||||||
|
ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED);
|
||||||
|
command_queue->present_semaphores.push_back(semaphore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a presentation semaphore is required, cycle across the ones available on the queue. It is technically possible
|
||||||
|
// and valid to reuse the same semaphore for this particular operation, but we create multiple ones anyway in case
|
||||||
|
// some hardware expects multiple semaphores to be used.
|
||||||
|
present_semaphore = command_queue->present_semaphores[command_queue->present_semaphore_index];
|
||||||
|
signal_semaphores.push_back(present_semaphore);
|
||||||
|
command_queue->present_semaphore_index = (command_queue->present_semaphore_index + 1) % command_queue->present_semaphores.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSubmitInfo submit_info = {};
|
VkSubmitInfo submit_info = {};
|
||||||
@ -2183,7 +2209,7 @@ Error RenderingDeviceDriverVulkan::command_queue_execute(CommandQueueID p_cmd_qu
|
|||||||
submit_info.pSignalSemaphores = signal_semaphores.ptr();
|
submit_info.pSignalSemaphores = signal_semaphores.ptr();
|
||||||
|
|
||||||
device_queue.submit_mutex.lock();
|
device_queue.submit_mutex.lock();
|
||||||
VkResult err = vkQueueSubmit(device_queue.queue, 1, &submit_info, vk_fence);
|
err = vkQueueSubmit(device_queue.queue, 1, &submit_info, vk_fence);
|
||||||
device_queue.submit_mutex.unlock();
|
device_queue.submit_mutex.unlock();
|
||||||
ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED);
|
ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED);
|
||||||
|
|
||||||
@ -2198,21 +2224,20 @@ Error RenderingDeviceDriverVulkan::command_queue_execute(CommandQueueID p_cmd_qu
|
|||||||
command_queue->pending_semaphores_for_fence.clear();
|
command_queue->pending_semaphores_for_fence.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
if (present_semaphore != VK_NULL_HANDLE) {
|
||||||
}
|
// If command buffers were executed, swap chains must wait on the present semaphore used by the command queue.
|
||||||
|
wait_semaphores.clear();
|
||||||
Error RenderingDeviceDriverVulkan::command_queue_present(CommandQueueID p_cmd_queue, VectorView<SwapChainID> p_swap_chains, VectorView<SemaphoreID> p_wait_semaphores) {
|
wait_semaphores.push_back(present_semaphore);
|
||||||
DEV_ASSERT(p_cmd_queue.id != 0);
|
}
|
||||||
|
}
|
||||||
CommandQueue *command_queue = (CommandQueue *)(p_cmd_queue.id);
|
|
||||||
Queue &device_queue = queue_families[command_queue->queue_family][command_queue->queue_index];
|
|
||||||
|
|
||||||
|
if (p_swap_chains.size() > 0) {
|
||||||
thread_local LocalVector<VkSwapchainKHR> swapchains;
|
thread_local LocalVector<VkSwapchainKHR> swapchains;
|
||||||
thread_local LocalVector<uint32_t> image_indices;
|
thread_local LocalVector<uint32_t> image_indices;
|
||||||
thread_local LocalVector<VkSemaphore> wait_semaphores;
|
|
||||||
thread_local LocalVector<VkResult> results;
|
thread_local LocalVector<VkResult> results;
|
||||||
swapchains.clear();
|
swapchains.clear();
|
||||||
image_indices.clear();
|
image_indices.clear();
|
||||||
|
|
||||||
for (uint32_t i = 0; i < p_swap_chains.size(); i++) {
|
for (uint32_t i = 0; i < p_swap_chains.size(); i++) {
|
||||||
SwapChain *swap_chain = (SwapChain *)(p_swap_chains[i].id);
|
SwapChain *swap_chain = (SwapChain *)(p_swap_chains[i].id);
|
||||||
swapchains.push_back(swap_chain->vk_swapchain);
|
swapchains.push_back(swap_chain->vk_swapchain);
|
||||||
@ -2220,11 +2245,6 @@ Error RenderingDeviceDriverVulkan::command_queue_present(CommandQueueID p_cmd_qu
|
|||||||
image_indices.push_back(swap_chain->image_index);
|
image_indices.push_back(swap_chain->image_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_semaphores.clear();
|
|
||||||
for (uint32_t i = 0; i < p_wait_semaphores.size(); i++) {
|
|
||||||
wait_semaphores.push_back(VkSemaphore(p_wait_semaphores[i].id));
|
|
||||||
}
|
|
||||||
|
|
||||||
results.resize(swapchains.size());
|
results.resize(swapchains.size());
|
||||||
|
|
||||||
VkPresentInfoKHR present_info = {};
|
VkPresentInfoKHR present_info = {};
|
||||||
@ -2235,8 +2255,9 @@ Error RenderingDeviceDriverVulkan::command_queue_present(CommandQueueID p_cmd_qu
|
|||||||
present_info.pSwapchains = swapchains.ptr();
|
present_info.pSwapchains = swapchains.ptr();
|
||||||
present_info.pImageIndices = image_indices.ptr();
|
present_info.pImageIndices = image_indices.ptr();
|
||||||
present_info.pResults = results.ptr();
|
present_info.pResults = results.ptr();
|
||||||
|
|
||||||
device_queue.submit_mutex.lock();
|
device_queue.submit_mutex.lock();
|
||||||
VkResult err = device_functions.QueuePresentKHR(device_queue.queue, &present_info);
|
err = device_functions.QueuePresentKHR(device_queue.queue, &present_info);
|
||||||
device_queue.submit_mutex.unlock();
|
device_queue.submit_mutex.unlock();
|
||||||
|
|
||||||
// Set the index to an invalid value. If any of the swap chains returned out of date, indicate it should be resized the next time it's acquired.
|
// Set the index to an invalid value. If any of the swap chains returned out of date, indicate it should be resized the next time it's acquired.
|
||||||
@ -2269,6 +2290,7 @@ Error RenderingDeviceDriverVulkan::command_queue_present(CommandQueueID p_cmd_qu
|
|||||||
// every frame.
|
// every frame.
|
||||||
|
|
||||||
ERR_FAIL_COND_V(err != VK_SUCCESS && err != VK_SUBOPTIMAL_KHR, FAILED);
|
ERR_FAIL_COND_V(err != VK_SUCCESS && err != VK_SUBOPTIMAL_KHR, FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -2278,6 +2300,11 @@ void RenderingDeviceDriverVulkan::command_queue_free(CommandQueueID p_cmd_queue)
|
|||||||
|
|
||||||
CommandQueue *command_queue = (CommandQueue *)(p_cmd_queue.id);
|
CommandQueue *command_queue = (CommandQueue *)(p_cmd_queue.id);
|
||||||
|
|
||||||
|
// Erase all the semaphores used for presentation.
|
||||||
|
for (VkSemaphore semaphore : command_queue->present_semaphores) {
|
||||||
|
vkDestroySemaphore(vk_device, semaphore, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
// Erase all the semaphores used for image acquisition.
|
// Erase all the semaphores used for image acquisition.
|
||||||
for (VkSemaphore semaphore : command_queue->image_semaphores) {
|
for (VkSemaphore semaphore : command_queue->image_semaphores) {
|
||||||
vkDestroySemaphore(vk_device, semaphore, nullptr);
|
vkDestroySemaphore(vk_device, semaphore, nullptr);
|
||||||
|
@ -115,6 +115,7 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver {
|
|||||||
VkDevice vk_device = VK_NULL_HANDLE;
|
VkDevice vk_device = VK_NULL_HANDLE;
|
||||||
RenderingContextDriverVulkan *context_driver = nullptr;
|
RenderingContextDriverVulkan *context_driver = nullptr;
|
||||||
RenderingContextDriver::Device context_device = {};
|
RenderingContextDriver::Device context_device = {};
|
||||||
|
uint32_t frame_count = 1;
|
||||||
VkPhysicalDevice physical_device = VK_NULL_HANDLE;
|
VkPhysicalDevice physical_device = VK_NULL_HANDLE;
|
||||||
VkPhysicalDeviceProperties physical_device_properties = {};
|
VkPhysicalDeviceProperties physical_device_properties = {};
|
||||||
VkPhysicalDeviceFeatures physical_device_features = {};
|
VkPhysicalDeviceFeatures physical_device_features = {};
|
||||||
@ -276,6 +277,7 @@ public:
|
|||||||
// ----- QUEUE -----
|
// ----- QUEUE -----
|
||||||
private:
|
private:
|
||||||
struct CommandQueue {
|
struct CommandQueue {
|
||||||
|
LocalVector<VkSemaphore> present_semaphores;
|
||||||
LocalVector<VkSemaphore> image_semaphores;
|
LocalVector<VkSemaphore> image_semaphores;
|
||||||
LocalVector<SwapChain *> image_semaphores_swap_chains;
|
LocalVector<SwapChain *> image_semaphores_swap_chains;
|
||||||
LocalVector<uint32_t> pending_semaphores_for_execute;
|
LocalVector<uint32_t> pending_semaphores_for_execute;
|
||||||
@ -284,12 +286,12 @@ private:
|
|||||||
LocalVector<Pair<Fence *, uint32_t>> image_semaphores_for_fences;
|
LocalVector<Pair<Fence *, uint32_t>> image_semaphores_for_fences;
|
||||||
uint32_t queue_family = 0;
|
uint32_t queue_family = 0;
|
||||||
uint32_t queue_index = 0;
|
uint32_t queue_index = 0;
|
||||||
|
uint32_t present_semaphore_index = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual CommandQueueID command_queue_create(CommandQueueFamilyID p_cmd_queue_family, bool p_identify_as_main_queue = false) override final;
|
virtual CommandQueueID command_queue_create(CommandQueueFamilyID p_cmd_queue_family, bool p_identify_as_main_queue = false) override final;
|
||||||
virtual Error command_queue_execute(CommandQueueID p_cmd_queue, VectorView<CommandBufferID> p_cmd_buffers, VectorView<SemaphoreID> p_wait_semaphores, VectorView<SemaphoreID> p_signal_semaphores, FenceID p_signal_fence) override final;
|
virtual Error command_queue_execute_and_present(CommandQueueID p_cmd_queue, VectorView<SemaphoreID> p_wait_semaphores, VectorView<CommandBufferID> p_cmd_buffers, VectorView<SemaphoreID> p_cmd_semaphores, FenceID p_cmd_fence, VectorView<SwapChainID> p_swap_chains) override final;
|
||||||
virtual Error command_queue_present(CommandQueueID p_cmd_queue, VectorView<SwapChainID> p_swap_chains, VectorView<SemaphoreID> p_wait_semaphores) override final;
|
|
||||||
virtual void command_queue_free(CommandQueueID p_cmd_queue) override final;
|
virtual void command_queue_free(CommandQueueID p_cmd_queue) override final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -3185,7 +3185,7 @@ Error RenderingDevice::screen_prepare_for_drawing(DisplayServer::WindowID p_scre
|
|||||||
uint32_t to_present_index = 0;
|
uint32_t to_present_index = 0;
|
||||||
while (to_present_index < frames[frame].swap_chains_to_present.size()) {
|
while (to_present_index < frames[frame].swap_chains_to_present.size()) {
|
||||||
if (frames[frame].swap_chains_to_present[to_present_index] == it->value) {
|
if (frames[frame].swap_chains_to_present[to_present_index] == it->value) {
|
||||||
driver->command_queue_present(present_queue, it->value, {});
|
driver->command_queue_execute_and_present(present_queue, {}, {}, {}, {}, it->value);
|
||||||
frames[frame].swap_chains_to_present.remove_at(to_present_index);
|
frames[frame].swap_chains_to_present.remove_at(to_present_index);
|
||||||
} else {
|
} else {
|
||||||
to_present_index++;
|
to_present_index++;
|
||||||
@ -4717,7 +4717,6 @@ void RenderingDevice::swap_buffers() {
|
|||||||
|
|
||||||
_end_frame();
|
_end_frame();
|
||||||
_execute_frame(true);
|
_execute_frame(true);
|
||||||
_present_frame();
|
|
||||||
|
|
||||||
// Advance to the next frame and begin recording again.
|
// Advance to the next frame and begin recording again.
|
||||||
frame = (frame + 1) % frames.size();
|
frame = (frame + 1) % frames.size();
|
||||||
@ -4890,17 +4889,21 @@ void RenderingDevice::_end_frame() {
|
|||||||
driver->end_segment();
|
driver->end_segment();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingDevice::_execute_frame(bool p_signal_for_present) {
|
void RenderingDevice::_execute_frame(bool p_present) {
|
||||||
const bool frame_can_present = !frames[frame].swap_chains_to_present.is_empty();
|
const bool frame_can_present = p_present && !frames[frame].swap_chains_to_present.is_empty();
|
||||||
const VectorView<RDD::SemaphoreID> execute_draw_semaphore = p_signal_for_present && frame_can_present ? frames[frame].draw_semaphore : VectorView<RDD::SemaphoreID>();
|
const bool separate_present_queue = main_queue != present_queue;
|
||||||
driver->command_queue_execute(main_queue, frames[frame].setup_command_buffer, {}, frames[frame].setup_semaphore, {});
|
const VectorView<RDD::SemaphoreID> execute_draw_semaphore = frame_can_present && separate_present_queue ? frames[frame].draw_semaphore : VectorView<RDD::SemaphoreID>();
|
||||||
driver->command_queue_execute(main_queue, frames[frame].draw_command_buffer, frames[frame].setup_semaphore, execute_draw_semaphore, frames[frame].draw_fence);
|
const VectorView<RDD::SwapChainID> execute_draw_swap_chains = frame_can_present && !separate_present_queue ? frames[frame].swap_chains_to_present : VectorView<RDD::SwapChainID>();
|
||||||
|
driver->command_queue_execute_and_present(main_queue, {}, frames[frame].setup_command_buffer, frames[frame].setup_semaphore, {}, {});
|
||||||
|
driver->command_queue_execute_and_present(main_queue, frames[frame].setup_semaphore, frames[frame].draw_command_buffer, execute_draw_semaphore, frames[frame].draw_fence, execute_draw_swap_chains);
|
||||||
frames[frame].draw_fence_signaled = true;
|
frames[frame].draw_fence_signaled = true;
|
||||||
}
|
|
||||||
|
|
||||||
void RenderingDevice::_present_frame() {
|
if (frame_can_present) {
|
||||||
if (!frames[frame].swap_chains_to_present.is_empty()) {
|
if (separate_present_queue) {
|
||||||
driver->command_queue_present(present_queue, frames[frame].swap_chains_to_present, frames[frame].draw_semaphore);
|
// Issue the presentation separately if the presentation queue is different from the main queue.
|
||||||
|
driver->command_queue_execute_and_present(present_queue, frames[frame].draw_semaphore, {}, {}, {}, frames[frame].swap_chains_to_present);
|
||||||
|
}
|
||||||
|
|
||||||
frames[frame].swap_chains_to_present.clear();
|
frames[frame].swap_chains_to_present.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1291,8 +1291,7 @@ private:
|
|||||||
void _free_internal(RID p_id);
|
void _free_internal(RID p_id);
|
||||||
void _begin_frame();
|
void _begin_frame();
|
||||||
void _end_frame();
|
void _end_frame();
|
||||||
void _execute_frame(bool p_signal_for_present);
|
void _execute_frame(bool p_present);
|
||||||
void _present_frame();
|
|
||||||
void _stall_for_previous_frames();
|
void _stall_for_previous_frames();
|
||||||
void _flush_and_stall_for_all_frames();
|
void _flush_and_stall_for_all_frames();
|
||||||
|
|
||||||
|
@ -408,8 +408,7 @@ public:
|
|||||||
// ----- QUEUE -----
|
// ----- QUEUE -----
|
||||||
|
|
||||||
virtual CommandQueueID command_queue_create(CommandQueueFamilyID p_cmd_queue_family, bool p_identify_as_main_queue = false) = 0;
|
virtual CommandQueueID command_queue_create(CommandQueueFamilyID p_cmd_queue_family, bool p_identify_as_main_queue = false) = 0;
|
||||||
virtual Error command_queue_execute(CommandQueueID p_cmd_queue, VectorView<CommandBufferID> p_cmd_buffers, VectorView<SemaphoreID> p_wait_semaphores, VectorView<SemaphoreID> p_signal_semaphores, FenceID p_signal_fence) = 0;
|
virtual Error command_queue_execute_and_present(CommandQueueID p_cmd_queue, VectorView<SemaphoreID> p_wait_semaphores, VectorView<CommandBufferID> p_cmd_buffers, VectorView<SemaphoreID> p_cmd_semaphores, FenceID p_cmd_fence, VectorView<SwapChainID> p_swap_chains) = 0;
|
||||||
virtual Error command_queue_present(CommandQueueID p_cmd_queue, VectorView<SwapChainID> p_swap_chains, VectorView<SemaphoreID> p_wait_semaphores) = 0;
|
|
||||||
virtual void command_queue_free(CommandQueueID p_cmd_queue) = 0;
|
virtual void command_queue_free(CommandQueueID p_cmd_queue) = 0;
|
||||||
|
|
||||||
// ----- POOL -----
|
// ----- POOL -----
|
||||||
|
Loading…
Reference in New Issue
Block a user