[PATCH v2] vkd3d: Batch up wait operations until work is submitted.

Derek Lesho dlesho at codeweavers.com
Wed Sep 11 14:29:57 CDT 2019


On 9/11/19 2:28 PM, Derek Lesho wrote:

> Signed-off-by: Derek Lesho <dlesho at codeweavers.com>
> ---
> v3: Stores the size of the vulkan semaphore array and sequence number array separately.
> ---
>   libs/vkd3d/command.c       | 85 ++++++++++++++++++++------------------
>   libs/vkd3d/vkd3d_private.h | 10 +++--
>   2 files changed, 51 insertions(+), 44 deletions(-)
>
> diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
> index ae88910..844d0ba 100644
> --- a/libs/vkd3d/command.c
> +++ b/libs/vkd3d/command.c
> @@ -45,9 +45,12 @@ HRESULT vkd3d_queue_create(struct d3d12_device *device,
>       object->vk_queue_flags = properties->queueFlags;
>       object->timestamp_bits = properties->timestampValidBits;
>   
> -    object->semaphores = NULL;
> -    object->semaphores_size = 0;
> +    object->semaphores.vk_semaphores = NULL;
> +    object->semaphores.sequence_numbers = NULL;
> +    object->vk_semaphores_size = 0;
> +    object->seq_numbers_size = 0;
>       object->semaphore_count = 0;
> +    object->pending_semaphore_index = -1;
>   
>       memset(object->old_vk_semaphores, 0, sizeof(object->old_vk_semaphores));
>   
> @@ -70,9 +73,10 @@ void vkd3d_queue_destroy(struct vkd3d_queue *queue, struct d3d12_device *device)
>           ERR("Failed to lock mutex, error %d.\n", rc);
>   
>       for (i = 0; i < queue->semaphore_count; ++i)
> -        VK_CALL(vkDestroySemaphore(device->vk_device, queue->semaphores[i].vk_semaphore, NULL));
> +        VK_CALL(vkDestroySemaphore(device->vk_device, queue->semaphores.vk_semaphores[i], NULL));
>   
> -    vkd3d_free(queue->semaphores);
> +    vkd3d_free(queue->semaphores.vk_semaphores);
> +    vkd3d_free(queue->semaphores.sequence_numbers);
>   
>       for (i = 0; i < ARRAY_SIZE(queue->old_vk_semaphores); ++i)
>       {
> @@ -157,10 +161,10 @@ static void vkd3d_queue_update_sequence_number(struct vkd3d_queue *queue,
>   
>       for (i = 0; i < queue->semaphore_count; ++i)
>       {
> -        if (queue->semaphores[i].sequence_number > queue->completed_sequence_number)
> +        if (queue->semaphores.sequence_numbers[i] > queue->completed_sequence_number)
>               break;
>   
> -        vk_semaphore = queue->semaphores[i].vk_semaphore;
> +        vk_semaphore = queue->semaphores.vk_semaphores[i];
>   
>           /* Try to store the Vulkan semaphore for reuse. */
>           for (j = 0; j < ARRAY_SIZE(queue->old_vk_semaphores); ++j)
> @@ -182,7 +186,8 @@ static void vkd3d_queue_update_sequence_number(struct vkd3d_queue *queue,
>       if (i > 0)
>       {
>           queue->semaphore_count -= i;
> -        memmove(queue->semaphores, &queue->semaphores[i], queue->semaphore_count * sizeof(*queue->semaphores));
> +        memmove(queue->semaphores.vk_semaphores, &queue->semaphores.vk_semaphores[i], queue->semaphore_count * sizeof(*queue->semaphores.vk_semaphores));
> +        memmove(queue->semaphores.sequence_numbers, &queue->semaphores.sequence_numbers[i], queue->semaphore_count * sizeof(*queue->semaphores.sequence_numbers));
>       }
>   
>       if (destroyed_semaphore_count)
> @@ -201,7 +206,7 @@ static uint64_t vkd3d_queue_reset_sequence_number_locked(struct vkd3d_queue *que
>       queue->submitted_sequence_number = 1;
>   
>       for (i = 0; i < queue->semaphore_count; ++i)
> -        queue->semaphores[i].sequence_number = queue->submitted_sequence_number;
> +        queue->semaphores.sequence_numbers[i] = queue->submitted_sequence_number;
>   
>       return queue->submitted_sequence_number;
>   }
> @@ -5511,6 +5516,7 @@ static void STDMETHODCALLTYPE d3d12_command_queue_CopyTileMappings(ID3D12Command
>   static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12CommandQueue *iface,
>           UINT command_list_count, ID3D12CommandList * const *command_lists)
>   {
> +    static const VkPipelineStageFlagBits wait_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
>       struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface);
>       const struct vkd3d_vk_device_procs *vk_procs;
>       struct d3d12_command_list *cmd_list;
> @@ -5556,6 +5562,15 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm
>       submit_desc.signalSemaphoreCount = 0;
>       submit_desc.pSignalSemaphores = NULL;
>   
> +    if (command_queue->vkd3d_queue->pending_semaphore_index != -1)
> +    {
> +        submit_desc.waitSemaphoreCount = command_queue->vkd3d_queue->semaphore_count - command_queue->vkd3d_queue->pending_semaphore_index;
> +        submit_desc.pWaitSemaphores = &command_queue->vkd3d_queue->semaphores.vk_semaphores[command_queue->vkd3d_queue->pending_semaphore_index];
> +        submit_desc.pWaitDstStageMask = &wait_stage_mask;
> +
> +        command_queue->vkd3d_queue->pending_semaphore_index = -1;
> +    }
> +
>       if (!(vk_queue = vkd3d_queue_acquire(command_queue->vkd3d_queue)))
>       {
>           ERR("Failed to acquire queue %p.\n", command_queue->vkd3d_queue);
> @@ -5593,6 +5608,7 @@ static void STDMETHODCALLTYPE d3d12_command_queue_EndEvent(ID3D12CommandQueue *i
>   static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Signal(ID3D12CommandQueue *iface,
>           ID3D12Fence *fence_iface, UINT64 value)
>   {
> +    static const VkPipelineStageFlagBits wait_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
>       struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface);
>       const struct vkd3d_vk_device_procs *vk_procs;
>       VkSemaphore vk_semaphore = VK_NULL_HANDLE;
> @@ -5643,6 +5659,15 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Signal(ID3D12CommandQueue *
>       submit_info.signalSemaphoreCount = vk_semaphore ? 1 : 0;
>       submit_info.pSignalSemaphores = &vk_semaphore;
>   
> +    if (command_queue->vkd3d_queue->pending_semaphore_index != -1)
> +    {
> +        submit_info.waitSemaphoreCount = command_queue->vkd3d_queue->semaphore_count - command_queue->vkd3d_queue->pending_semaphore_index;
> +        submit_info.pWaitSemaphores = &command_queue->vkd3d_queue->semaphores.vk_semaphores[command_queue->vkd3d_queue->pending_semaphore_index];
> +        submit_info.pWaitDstStageMask = &wait_stage_mask;
> +
> +        command_queue->vkd3d_queue->pending_semaphore_index = -1;
> +    }
> +
>       if ((vr = VK_CALL(vkQueueSubmit(vk_queue, 1, &submit_info, vk_fence))) >= 0)
>       {
>           sequence_number = ++vkd3d_queue->submitted_sequence_number;
> @@ -5702,21 +5727,16 @@ fail:
>   static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *iface,
>           ID3D12Fence *fence_iface, UINT64 value)
>   {
> -    static const VkPipelineStageFlagBits wait_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
>       struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface);
> -    const struct vkd3d_vk_device_procs *vk_procs;
>       struct vkd3d_signaled_semaphore *semaphore;
>       uint64_t completed_value = 0;
>       struct vkd3d_queue *queue;
>       struct d3d12_fence *fence;
> -    VkSubmitInfo submit_info;
>       VkQueue vk_queue;
> -    VkResult vr;
>       HRESULT hr;
>   
>       TRACE("iface %p, fence %p, value %#"PRIx64".\n", iface, fence_iface, value);
>   
> -    vk_procs = &command_queue->device->vk_procs;
>       queue = command_queue->vkd3d_queue;
>   
>       fence = unsafe_impl_from_ID3D12Fence(fence_iface);
> @@ -5752,18 +5772,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if
>           return S_OK;
>       }
>   
> -    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
> -    submit_info.pNext = NULL;
> -    submit_info.waitSemaphoreCount = 1;
> -    submit_info.pWaitSemaphores = &semaphore->vk_semaphore;
> -    submit_info.pWaitDstStageMask = &wait_stage_mask;
> -    submit_info.commandBufferCount = 0;
> -    submit_info.pCommandBuffers = NULL;
> -    submit_info.signalSemaphoreCount = 0;
> -    submit_info.pSignalSemaphores = NULL;
> -
> -    if (!vkd3d_array_reserve((void **)&queue->semaphores, &queue->semaphores_size,
> -            queue->semaphore_count + 1, sizeof(*queue->semaphores)))
> +    if (!vkd3d_array_reserve((void **)&queue->semaphores.vk_semaphores, &queue->vk_semaphores_size,
> +            queue->semaphore_count + 1, sizeof(*queue->semaphores.vk_semaphores))
> +     || !vkd3d_array_reserve((void **)&queue->semaphores.sequence_numbers, &queue->seq_numbers_size,
> +            queue->semaphore_count + 1, sizeof(*queue->semaphores.sequence_numbers)))
>       {
>           ERR("Failed to allocate memory for semaphore.\n");
>           vkd3d_queue_release(queue);
> @@ -5771,24 +5783,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if
>           goto fail;
>       }
>   
> -    if ((vr = VK_CALL(vkQueueSubmit(vk_queue, 1, &submit_info, VK_NULL_HANDLE))) >= 0)
> -    {
> -        queue->semaphores[queue->semaphore_count].vk_semaphore = semaphore->vk_semaphore;
> -        queue->semaphores[queue->semaphore_count].sequence_number = queue->submitted_sequence_number + 1;
> -        ++queue->semaphore_count;
> +    queue->semaphores.vk_semaphores[queue->semaphore_count] = semaphore->vk_semaphore;
> +    queue->semaphores.sequence_numbers[queue->semaphore_count] = queue->submitted_sequence_number + 1;
>   
> -        command_queue->last_waited_fence = fence;
> -        command_queue->last_waited_fence_value = value;
> -    }
> +    if (queue->pending_semaphore_index == -1) queue->pending_semaphore_index = queue->semaphore_count;
>   
> -    vkd3d_queue_release(queue);
> +    ++queue->semaphore_count;
>   
> -    if (vr < 0)
> -    {
> -        WARN("Failed to submit wait operation, vr %d.\n", vr);
> -        hr = hresult_from_vk_result(vr);
> -        goto fail;
> -    }
> +    command_queue->last_waited_fence = fence;
> +    command_queue->last_waited_fence_value = value;
> +
> +    vkd3d_queue_release(queue);
>   
>       d3d12_fence_remove_vk_semaphore(fence, semaphore);
>       return S_OK;
> diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
> index 294e677..bd9670e 100644
> --- a/libs/vkd3d/vkd3d_private.h
> +++ b/libs/vkd3d/vkd3d_private.h
> @@ -954,11 +954,13 @@ struct vkd3d_queue
>   
>       struct
>       {
> -        VkSemaphore vk_semaphore;
> -        uint64_t sequence_number;
> -    } *semaphores;
> -    size_t semaphores_size;
> +        VkSemaphore *vk_semaphores;
> +        uint64_t *sequence_numbers;
> +    } semaphores;
> +    size_t vk_semaphores_size;
> +    size_t seq_numbers_size;
>       size_t semaphore_count;
> +    uint64_t pending_semaphore_index;
>   
>       VkSemaphore old_vk_semaphores[VKD3D_MAX_VK_SYNC_OBJECTS];
>   };
*[PATCH v3], not v2, sorry about the typo!



More information about the wine-devel mailing list