From: Rajnesh Kanwal Date: Mon, 4 Apr 2022 11:17:47 +0000 (+0100) Subject: pvr: Add support to create transfer context and setup required shaders. X-Git-Tag: upstream/22.3.5~9007 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e8ed0e49842de3e5c95837dffe0ef3a3984904e5;p=platform%2Fupstream%2Fmesa.git pvr: Add support to create transfer context and setup required shaders. Signed-off-by: Rajnesh Kanwal Reviewed-by: Frank Binns Part-of: --- diff --git a/src/imagination/vulkan/pvr_job_context.c b/src/imagination/vulkan/pvr_job_context.c index efb7084..cabbfb4 100644 --- a/src/imagination/vulkan/pvr_job_context.c +++ b/src/imagination/vulkan/pvr_job_context.c @@ -29,11 +29,12 @@ #include "hwdef/rogue_hw_utils.h" #include "pvr_bo.h" +#include "pvr_cdm_load_sr.h" #include "pvr_csb.h" #include "pvr_job_context.h" #include "pvr_pds.h" #include "pvr_private.h" -#include "pvr_cdm_load_sr.h" +#include "pvr_transfer_eot.h" #include "pvr_vdm_load_sr.h" #include "pvr_vdm_store_sr.h" #include "pvr_winsys.h" @@ -1176,3 +1177,142 @@ void pvr_compute_ctx_destroy(struct pvr_compute_ctx *const ctx) vk_free(&device->vk.alloc, ctx); } + +static void pvr_transfer_ctx_ws_create_info_init( + enum pvr_winsys_ctx_priority priority, + struct pvr_winsys_transfer_ctx_create_info *const create_info) +{ + create_info->priority = priority; +} + +static VkResult pvr_transfer_ctx_setup_shaders(struct pvr_device *device, + struct pvr_transfer_ctx *ctx) +{ + const uint32_t cache_line_size = + rogue_get_slc_cache_line_size(&device->pdevice->dev_info); + VkResult result; + + /* TODO: Setup USC fragments. */ + + /* Setup EOT program. */ + result = pvr_gpu_upload_usc(device, + pvr_transfer_eot_usc_code, + sizeof(pvr_transfer_eot_usc_code), + cache_line_size, + &ctx->usc_eot_bo); + if (result != VK_SUCCESS) + return result; + + STATIC_ASSERT(ARRAY_SIZE(pvr_transfer_eot_usc_offsets) == + ARRAY_SIZE(ctx->transfer_mrts)); + for (uint32_t i = 0U; i < ARRAY_SIZE(pvr_transfer_eot_usc_offsets); i++) { + ctx->transfer_mrts[i] = ctx->usc_eot_bo->vma->dev_addr; + ctx->transfer_mrts[i].addr += pvr_transfer_eot_usc_offsets[i]; + } + + return VK_SUCCESS; +} + +static void pvr_transfer_ctx_fini_shaders(struct pvr_device *device, + struct pvr_transfer_ctx *ctx) +{ + pvr_bo_free(device, ctx->usc_eot_bo); +} + +VkResult pvr_transfer_ctx_create(struct pvr_device *const device, + enum pvr_winsys_ctx_priority priority, + struct pvr_transfer_ctx **const ctx_out) +{ + struct pvr_winsys_transfer_ctx_create_info create_info; + struct pvr_transfer_ctx *ctx; + VkResult result; + + ctx = vk_zalloc(&device->vk.alloc, + sizeof(*ctx), + 8U, + VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); + if (!ctx) + return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + + ctx->device = device; + + result = pvr_ctx_reset_cmd_init(device, &ctx->reset_cmd); + if (result != VK_SUCCESS) + goto err_free_ctx; + + pvr_transfer_ctx_ws_create_info_init(priority, &create_info); + + result = device->ws->ops->transfer_ctx_create(device->ws, + &create_info, + &ctx->ws_ctx); + if (result != VK_SUCCESS) + goto err_fini_reset_cmd; + + result = pvr_transfer_ctx_setup_shaders(device, ctx); + if (result != VK_SUCCESS) + goto err_destroy_transfer_ctx; + + /* Create the PDS Uniform/Tex state code segment array. */ + for (uint32_t i = 0U; i < ARRAY_SIZE(ctx->pds_unitex_code); i++) { + for (uint32_t j = 0U; j < ARRAY_SIZE(ctx->pds_unitex_code[0U]); j++) { + if (i == 0U && j == 0U) + continue; + + result = pvr_pds_unitex_state_program_create_and_upload( + device, + NULL, + i, + j, + &ctx->pds_unitex_code[i][j]); + if (result != VK_SUCCESS) { + goto err_free_pds_unitex_bos; + } + } + } + + *ctx_out = ctx; + + return VK_SUCCESS; + +err_free_pds_unitex_bos: + for (uint32_t i = 0U; i < ARRAY_SIZE(ctx->pds_unitex_code); i++) { + for (uint32_t j = 0U; j < ARRAY_SIZE(ctx->pds_unitex_code[0U]); j++) { + if (!ctx->pds_unitex_code[i][j].pvr_bo) + continue; + + pvr_bo_free(device, ctx->pds_unitex_code[i][j].pvr_bo); + } + } + + pvr_transfer_ctx_fini_shaders(device, ctx); + +err_destroy_transfer_ctx: + device->ws->ops->transfer_ctx_destroy(ctx->ws_ctx); + +err_fini_reset_cmd: + pvr_ctx_reset_cmd_fini(device, &ctx->reset_cmd); + +err_free_ctx: + vk_free(&device->vk.alloc, ctx); + + return result; +} + +void pvr_transfer_ctx_destroy(struct pvr_transfer_ctx *const ctx) +{ + struct pvr_device *device = ctx->device; + + for (uint32_t i = 0U; i < ARRAY_SIZE(ctx->pds_unitex_code); i++) { + for (uint32_t j = 0U; j < ARRAY_SIZE(ctx->pds_unitex_code[0U]); j++) { + if (!ctx->pds_unitex_code[i][j].pvr_bo) + continue; + + pvr_bo_free(device, ctx->pds_unitex_code[i][j].pvr_bo); + } + } + + pvr_transfer_ctx_fini_shaders(device, ctx); + device->ws->ops->transfer_ctx_destroy(ctx->ws_ctx); + pvr_ctx_reset_cmd_fini(device, &ctx->reset_cmd); + vk_free(&device->vk.alloc, ctx); +} diff --git a/src/imagination/vulkan/pvr_job_context.h b/src/imagination/vulkan/pvr_job_context.h index 0e3f81b..5cd948a 100644 --- a/src/imagination/vulkan/pvr_job_context.h +++ b/src/imagination/vulkan/pvr_job_context.h @@ -96,6 +96,10 @@ struct pvr_render_ctx { struct pvr_reset_cmd reset_cmd; }; +/****************************************************************************** + Compute context + ******************************************************************************/ + struct pvr_compute_ctx { struct pvr_device *device; @@ -113,6 +117,43 @@ struct pvr_compute_ctx { struct pvr_reset_cmd reset_cmd; }; +/****************************************************************************** + Transfer context + ******************************************************************************/ + +/* TODO: Can we move these to pds code headers? */ +/* Maximum number of DMAs in the PDS TexState/Uniform program. */ +#define PVR_TRANSFER_MAX_UNIFORM_DMA 1U +#define PVR_TRANSFER_MAX_TEXSTATE_DMA 2U + +#if (PVR_TRANSFER_MAX_TEXSTATE_DMA >= PVR_PDS_MAX_NUM_DMA_KICKS) || \ + (PVR_TRANSFER_MAX_UNIFORM_DMA >= PVR_PDS_MAX_NUM_DMA_KICKS) +# error \ + "Transfer queue can not support more DMA kicks than supported by PDS codegen." +#endif + +#define PVR_TRANSFER_MAX_RENDER_TARGETS 3U + +struct pvr_transfer_ctx { + struct pvr_device *device; + + /* Reset framework. */ + struct pvr_reset_cmd reset_cmd; + + struct pvr_winsys_transfer_ctx *ws_ctx; + + /* Multiple on-chip render targets (MRT). */ + pvr_dev_addr_t transfer_mrts[PVR_TRANSFER_MAX_RENDER_TARGETS]; + struct pvr_bo *usc_eot_bo; + + struct pvr_pds_upload pds_unitex_code[PVR_TRANSFER_MAX_TEXSTATE_DMA] + [PVR_TRANSFER_MAX_UNIFORM_DMA]; +}; + +/****************************************************************************** + Function prototypes + ******************************************************************************/ + VkResult pvr_render_ctx_create(struct pvr_device *device, enum pvr_winsys_ctx_priority priority, struct pvr_render_ctx **const ctx_out); @@ -123,4 +164,9 @@ VkResult pvr_compute_ctx_create(struct pvr_device *const device, struct pvr_compute_ctx **const ctx_out); void pvr_compute_ctx_destroy(struct pvr_compute_ctx *ctx); +VkResult pvr_transfer_ctx_create(struct pvr_device *const device, + enum pvr_winsys_ctx_priority priority, + struct pvr_transfer_ctx **const ctx_out); +void pvr_transfer_ctx_destroy(struct pvr_transfer_ctx *const ctx); + #endif /* PVR_JOB_CONTEXT_H */ diff --git a/src/imagination/vulkan/pvr_pass.c b/src/imagination/vulkan/pvr_pass.c index bebc9a4..96e53b7 100644 --- a/src/imagination/vulkan/pvr_pass.c +++ b/src/imagination/vulkan/pvr_pass.c @@ -155,13 +155,16 @@ static inline bool pvr_has_output_register_writes( return false; } -static VkResult pvr_pds_texture_state_program_create_and_upload( +VkResult pvr_pds_unitex_state_program_create_and_upload( struct pvr_device *device, const VkAllocationCallbacks *allocator, + uint32_t texture_kicks, + uint32_t uniform_kicks, struct pvr_pds_upload *const pds_upload_out) { struct pvr_pds_pixel_shader_sa_program program = { - .num_texture_dma_kicks = 1, + .num_texture_dma_kicks = texture_kicks, + .num_uniform_dma_kicks = uniform_kicks, }; uint32_t staging_buffer_size; uint32_t *staging_buffer; @@ -174,7 +177,7 @@ static VkResult pvr_pds_texture_state_program_create_and_upload( staging_buffer = vk_alloc2(&device->vk.alloc, allocator, staging_buffer_size, - 8, + 8U, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); if (!staging_buffer) return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); @@ -184,12 +187,12 @@ static VkResult pvr_pds_texture_state_program_create_and_upload( /* FIXME: Figure out the define for alignment of 16. */ result = pvr_gpu_upload_pds(device, NULL, - 0, - 0, - &staging_buffer[program.data_size], + 0U, + 0U, + staging_buffer, program.code_size, - 16, - 16, + 16U, + 16U, pds_upload_out); if (result != VK_SUCCESS) { vk_free2(&device->vk.alloc, allocator, staging_buffer); @@ -248,9 +251,11 @@ pvr_load_op_create(struct pvr_device *device, if (result != VK_SUCCESS) goto err_free_usc_frag_prog_bo; - result = pvr_pds_texture_state_program_create_and_upload( + result = pvr_pds_unitex_state_program_create_and_upload( device, allocator, + 1U, + 0U, &load_op->pds_tex_state_prog); if (result != VK_SUCCESS) goto err_free_pds_frag_prog; diff --git a/src/imagination/vulkan/pvr_private.h b/src/imagination/vulkan/pvr_private.h index 6cc4844..b32c99e 100644 --- a/src/imagination/vulkan/pvr_private.h +++ b/src/imagination/vulkan/pvr_private.h @@ -230,6 +230,7 @@ struct pvr_queue { struct pvr_render_ctx *gfx_ctx; struct pvr_compute_ctx *compute_ctx; + struct pvr_transfer_ctx *transfer_ctx; struct pvr_winsys_syncobj *completion[PVR_JOB_TYPE_MAX]; }; @@ -1335,6 +1336,13 @@ VkResult pvr_pds_fragment_program_create_and_upload( bool has_phase_rate_change, struct pvr_pds_upload *const pds_upload_out); +VkResult pvr_pds_unitex_state_program_create_and_upload( + struct pvr_device *device, + const VkAllocationCallbacks *allocator, + uint32_t texture_kicks, + uint32_t uniform_kicks, + struct pvr_pds_upload *const pds_upload_out); + #define PVR_FROM_HANDLE(__pvr_type, __name, __handle) \ VK_FROM_HANDLE(__pvr_type, __name, __handle) diff --git a/src/imagination/vulkan/pvr_queue.c b/src/imagination/vulkan/pvr_queue.c index 4c78406..3cbb10f 100644 --- a/src/imagination/vulkan/pvr_queue.c +++ b/src/imagination/vulkan/pvr_queue.c @@ -54,6 +54,7 @@ static VkResult pvr_queue_init(struct pvr_device *device, const VkDeviceQueueCreateInfo *pCreateInfo, uint32_t index_in_family) { + struct pvr_transfer_ctx *transfer_ctx; struct pvr_compute_ctx *compute_ctx; struct pvr_render_ctx *gfx_ctx; VkResult result; @@ -63,11 +64,17 @@ static VkResult pvr_queue_init(struct pvr_device *device, if (result != VK_SUCCESS) return result; + result = pvr_transfer_ctx_create(device, + PVR_WINSYS_CTX_PRIORITY_MEDIUM, + &transfer_ctx); + if (result != VK_SUCCESS) + goto err_vk_queue_finish; + result = pvr_compute_ctx_create(device, PVR_WINSYS_CTX_PRIORITY_MEDIUM, &compute_ctx); if (result != VK_SUCCESS) - goto err_vk_queue_finish; + goto err_transfer_ctx_destroy; result = pvr_render_ctx_create(device, PVR_WINSYS_CTX_PRIORITY_MEDIUM, &gfx_ctx); @@ -77,6 +84,7 @@ static VkResult pvr_queue_init(struct pvr_device *device, queue->device = device; queue->gfx_ctx = gfx_ctx; queue->compute_ctx = compute_ctx; + queue->transfer_ctx = transfer_ctx; for (uint32_t i = 0; i < ARRAY_SIZE(queue->completion); i++) queue->completion[i] = NULL; @@ -86,6 +94,9 @@ static VkResult pvr_queue_init(struct pvr_device *device, err_compute_ctx_destroy: pvr_compute_ctx_destroy(compute_ctx); +err_transfer_ctx_destroy: + pvr_transfer_ctx_destroy(transfer_ctx); + err_vk_queue_finish: vk_queue_finish(&queue->vk); @@ -138,6 +149,7 @@ static void pvr_queue_finish(struct pvr_queue *queue) pvr_render_ctx_destroy(queue->gfx_ctx); pvr_compute_ctx_destroy(queue->compute_ctx); + pvr_transfer_ctx_destroy(queue->transfer_ctx); vk_queue_finish(&queue->vk); } diff --git a/src/imagination/vulkan/usc/programs/pvr_transfer_eot.h b/src/imagination/vulkan/usc/programs/pvr_transfer_eot.h new file mode 100644 index 0000000..427f092 --- /dev/null +++ b/src/imagination/vulkan/usc/programs/pvr_transfer_eot.h @@ -0,0 +1,47 @@ +/* + * Copyright © 2022 Imagination Technologies Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* Auto-generated file - don't edit */ + +#ifndef PVR_TRANSFER_EOT_H +#define PVR_TRANSFER_EOT_H + +#include + +static const uint8_t pvr_transfer_eot_usc_code[] = { + 0x46, 0xa0, 0x80, 0xc2, 0x80, 0x40, 0x80, 0x01, 0x88, 0x00, 0x00, 0xff, + 0x35, 0x20, 0xc0, 0x80, 0x40, 0x80, 0x01, 0x88, 0x00, 0x00, 0x02, 0x80, + 0x68, 0xff, 0x46, 0xa0, 0x80, 0xc2, 0x82, 0x40, 0x80, 0x03, 0x88, 0x00, + 0x00, 0xff, 0xcd, 0xcd, 0x35, 0x20, 0xc0, 0x80, 0x40, 0x80, 0x01, 0x88, + 0x00, 0x00, 0x02, 0x80, 0x68, 0xff, 0x35, 0x20, 0xc0, 0x82, 0x40, 0x80, + 0x03, 0x88, 0x00, 0x00, 0x02, 0x80, 0x68, 0xff, 0x46, 0xa0, 0x80, 0xc2, + 0x84, 0x40, 0x80, 0x05, 0x88, 0x00, 0x00, 0xff, +}; + +static const uint32_t pvr_transfer_eot_usc_offsets[] = { + 0, + 12, + 40, +}; + +#endif /* PVR_TRANSFER_EOT_H */