1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2022 Imagination Technologies Ltd. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 5bf215546Sopenharmony_ci * of this software and associated documentation files (the "Software"), to deal 6bf215546Sopenharmony_ci * in the Software without restriction, including without limitation the rights 7bf215546Sopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8bf215546Sopenharmony_ci * copies of the Software, and to permit persons to whom the Software is 9bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18bf215546Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21bf215546Sopenharmony_ci * SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include <stdbool.h> 25bf215546Sopenharmony_ci#include <stdint.h> 26bf215546Sopenharmony_ci#include <stddef.h> 27bf215546Sopenharmony_ci#include <vulkan/vulkan.h> 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "pvr_job_common.h" 30bf215546Sopenharmony_ci#include "pvr_job_context.h" 31bf215546Sopenharmony_ci#include "pvr_job_transfer.h" 32bf215546Sopenharmony_ci#include "pvr_private.h" 33bf215546Sopenharmony_ci#include "pvr_winsys.h" 34bf215546Sopenharmony_ci#include "util/list.h" 35bf215546Sopenharmony_ci#include "util/macros.h" 36bf215546Sopenharmony_ci#include "vk_sync.h" 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci/* FIXME: Implement gpu based transfer support. */ 39bf215546Sopenharmony_ciVkResult pvr_transfer_job_submit(struct pvr_device *device, 40bf215546Sopenharmony_ci struct pvr_transfer_ctx *ctx, 41bf215546Sopenharmony_ci struct pvr_sub_cmd_transfer *sub_cmd, 42bf215546Sopenharmony_ci struct vk_sync **waits, 43bf215546Sopenharmony_ci uint32_t wait_count, 44bf215546Sopenharmony_ci uint32_t *stage_flags, 45bf215546Sopenharmony_ci struct vk_sync *signal_sync) 46bf215546Sopenharmony_ci{ 47bf215546Sopenharmony_ci /* Wait for transfer semaphores here before doing any transfers. */ 48bf215546Sopenharmony_ci for (uint32_t i = 0U; i < wait_count; i++) { 49bf215546Sopenharmony_ci if (stage_flags[i] & PVR_PIPELINE_STAGE_TRANSFER_BIT) { 50bf215546Sopenharmony_ci VkResult result = vk_sync_wait(&device->vk, 51bf215546Sopenharmony_ci waits[i], 52bf215546Sopenharmony_ci 0U, 53bf215546Sopenharmony_ci VK_SYNC_WAIT_COMPLETE, 54bf215546Sopenharmony_ci UINT64_MAX); 55bf215546Sopenharmony_ci if (result != VK_SUCCESS) 56bf215546Sopenharmony_ci return result; 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci stage_flags[i] &= ~PVR_PIPELINE_STAGE_TRANSFER_BIT; 59bf215546Sopenharmony_ci } 60bf215546Sopenharmony_ci } 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci list_for_each_entry_safe (struct pvr_transfer_cmd, 63bf215546Sopenharmony_ci transfer_cmd, 64bf215546Sopenharmony_ci &sub_cmd->transfer_cmds, 65bf215546Sopenharmony_ci link) { 66bf215546Sopenharmony_ci bool src_mapped = false; 67bf215546Sopenharmony_ci bool dst_mapped = false; 68bf215546Sopenharmony_ci void *src_addr; 69bf215546Sopenharmony_ci void *dst_addr; 70bf215546Sopenharmony_ci void *ret_ptr; 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci /* Map if bo is not mapped. */ 73bf215546Sopenharmony_ci if (!transfer_cmd->src->vma->bo->map) { 74bf215546Sopenharmony_ci src_mapped = true; 75bf215546Sopenharmony_ci ret_ptr = device->ws->ops->buffer_map(transfer_cmd->src->vma->bo); 76bf215546Sopenharmony_ci if (!ret_ptr) 77bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_MEMORY_MAP_FAILED); 78bf215546Sopenharmony_ci } 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci if (!transfer_cmd->dst->vma->bo->map) { 81bf215546Sopenharmony_ci dst_mapped = true; 82bf215546Sopenharmony_ci ret_ptr = device->ws->ops->buffer_map(transfer_cmd->dst->vma->bo); 83bf215546Sopenharmony_ci if (!ret_ptr) 84bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_MEMORY_MAP_FAILED); 85bf215546Sopenharmony_ci } 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci src_addr = 88bf215546Sopenharmony_ci transfer_cmd->src->vma->bo->map + transfer_cmd->src->vma->bo_offset; 89bf215546Sopenharmony_ci dst_addr = 90bf215546Sopenharmony_ci transfer_cmd->dst->vma->bo->map + transfer_cmd->dst->vma->bo_offset; 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci for (uint32_t i = 0; i < transfer_cmd->region_count; i++) { 93bf215546Sopenharmony_ci VkBufferCopy2 *region = &transfer_cmd->regions[i]; 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci memcpy(dst_addr + region->dstOffset, 96bf215546Sopenharmony_ci src_addr + region->srcOffset, 97bf215546Sopenharmony_ci region->size); 98bf215546Sopenharmony_ci } 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci if (src_mapped) 101bf215546Sopenharmony_ci device->ws->ops->buffer_unmap(transfer_cmd->src->vma->bo); 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci if (dst_mapped) 104bf215546Sopenharmony_ci device->ws->ops->buffer_unmap(transfer_cmd->dst->vma->bo); 105bf215546Sopenharmony_ci } 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci /* Given we are doing CPU based copy, completion fence should always be 108bf215546Sopenharmony_ci * signaled. This should be fixed when GPU based copy is implemented. 109bf215546Sopenharmony_ci */ 110bf215546Sopenharmony_ci return vk_sync_signal(&device->vk, signal_sync, 0); 111bf215546Sopenharmony_ci} 112