Module: Mesa Branch: main Commit: f88d1fbdbd2ba8f41ed73ec274d3dc2b160c1f92 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=f88d1fbdbd2ba8f41ed73ec274d3dc2b160c1f92
Author: Rajnesh Kanwal <[email protected]> Date: Mon Apr 4 12:16:45 2022 +0100 pvr: Add services winsys transfer context support. Signed-off-by: Rajnesh Kanwal <[email protected]> Reviewed-by: Frank Binns <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16451> --- src/imagination/vulkan/meson.build | 1 + src/imagination/vulkan/winsys/pvr_winsys.h | 14 +++ src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c | 3 + .../vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c | 78 +++++++++++++ .../vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h | 57 ++++++++++ .../vulkan/winsys/pvrsrvkm/pvr_srv_job_compute.c | 3 + .../vulkan/winsys/pvrsrvkm/pvr_srv_job_render.c | 3 + .../vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.c | 126 +++++++++++++++++++++ .../vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.h | 43 +++++++ 9 files changed, 328 insertions(+) diff --git a/src/imagination/vulkan/meson.build b/src/imagination/vulkan/meson.build index c350b2d2268..d212a12f7cd 100644 --- a/src/imagination/vulkan/meson.build +++ b/src/imagination/vulkan/meson.build @@ -86,6 +86,7 @@ if with_imagination_srv 'winsys/pvrsrvkm/pvr_srv_job_common.c', 'winsys/pvrsrvkm/pvr_srv_job_compute.c', 'winsys/pvrsrvkm/pvr_srv_job_render.c', + 'winsys/pvrsrvkm/pvr_srv_job_transfer.c', 'winsys/pvrsrvkm/pvr_srv_syncobj.c', ) pvr_flags += '-DPVR_SUPPORT_SERVICES_DRIVER' diff --git a/src/imagination/vulkan/winsys/pvr_winsys.h b/src/imagination/vulkan/winsys/pvr_winsys.h index faa9e06240f..a4b035b31c3 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys.h +++ b/src/imagination/vulkan/winsys/pvr_winsys.h @@ -247,6 +247,14 @@ struct pvr_winsys_compute_ctx { struct pvr_winsys *ws; }; +struct pvr_winsys_transfer_ctx_create_info { + enum pvr_winsys_ctx_priority priority; +}; + +struct pvr_winsys_transfer_ctx { + struct pvr_winsys *ws; +}; + #define PVR_WINSYS_COMPUTE_FLAG_PREVENT_ALL_OVERLAP BITFIELD_BIT(0U) #define PVR_WINSYS_COMPUTE_FLAG_SINGLE_CORE BITFIELD_BIT(1U) @@ -447,6 +455,12 @@ struct pvr_winsys_ops { const struct pvr_winsys_compute_ctx *ctx, const struct pvr_winsys_compute_submit_info *submit_info, struct pvr_winsys_syncobj **const syncobj_out); + + VkResult (*transfer_ctx_create)( + struct pvr_winsys *ws, + const struct pvr_winsys_transfer_ctx_create_info *create_info, + struct pvr_winsys_transfer_ctx **const ctx_out); + void (*transfer_ctx_destroy)(struct pvr_winsys_transfer_ctx *ctx); }; struct pvr_winsys { diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c index 2d3dbb92deb..1cc5f020dfe 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c @@ -34,6 +34,7 @@ #include "pvr_srv_bridge.h" #include "pvr_srv_job_compute.h" #include "pvr_srv_job_render.h" +#include "pvr_srv_job_transfer.h" #include "pvr_srv_public.h" #include "pvr_srv_syncobj.h" #include "pvr_winsys.h" @@ -429,6 +430,8 @@ static const struct pvr_winsys_ops srv_winsys_ops = { .compute_ctx_create = pvr_srv_winsys_compute_ctx_create, .compute_ctx_destroy = pvr_srv_winsys_compute_ctx_destroy, .compute_submit = pvr_srv_winsys_compute_submit, + .transfer_ctx_create = pvr_srv_winsys_transfer_ctx_create, + .transfer_ctx_destroy = pvr_srv_winsys_transfer_ctx_destroy, }; static bool pvr_is_driver_compatible(int render_fd) diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c index cb0eb5a7dfb..9a6da62d8db 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c @@ -793,6 +793,84 @@ VkResult pvr_srv_physmem_export_dmabuf(int fd, void *pmr, int *const fd_out) return VK_SUCCESS; } +VkResult pvr_srv_rgx_create_transfer_context(int fd, + uint32_t priority, + uint32_t reset_framework_cmd_size, + uint8_t *reset_framework_cmd, + void *priv_data, + uint32_t packed_ccb_size_u8888, + uint32_t context_flags, + uint64_t robustness_address, + void **const cli_pmr_out, + void **const usc_pmr_out, + void **const transfer_context_out) +{ + struct pvr_srv_rgx_create_transfer_context_cmd cmd = { + .robustness_address = robustness_address, + .priority = priority, + .reset_framework_cmd_size = reset_framework_cmd_size, + .reset_framework_cmd = reset_framework_cmd, + .priv_data = priv_data, + .packed_ccb_size_u8888 = packed_ccb_size_u8888, + .context_flags = context_flags, + }; + + struct pvr_srv_rgx_create_transfer_context_ret ret = { + .error = PVR_SRV_ERROR_BRIDGE_CALL_FAILED, + }; + + int result; + + result = pvr_srv_bridge_call(fd, + PVR_SRV_BRIDGE_RGXTQ, + PVR_SRV_BRIDGE_RGXTQ_RGXCREATETRANSFERCONTEXT, + &cmd, + sizeof(cmd), + &ret, + sizeof(ret)); + if (result || ret.error != PVR_SRV_OK) { + return vk_bridge_err(VK_ERROR_INITIALIZATION_FAILED, + "PVR_SRV_BRIDGE_RGXTQ_RGXCREATETRANSFERCONTEXT", + ret); + } + + if (cli_pmr_out) + *cli_pmr_out = ret.cli_pmr_mem; + + if (usc_pmr_out) + *usc_pmr_out = ret.usc_pmr_mem; + + *transfer_context_out = ret.transfer_context; + + return VK_SUCCESS; +} + +void pvr_srv_rgx_destroy_transfer_context(int fd, void *transfer_context) +{ + struct pvr_srv_rgx_destroy_transfer_context_cmd cmd = { + .transfer_context = transfer_context, + }; + + struct pvr_srv_rgx_destroy_transfer_context_ret ret = { + .error = PVR_SRV_ERROR_BRIDGE_CALL_FAILED, + }; + + int result; + + result = pvr_srv_bridge_call(fd, + PVR_SRV_BRIDGE_RGXTQ, + PVR_SRV_BRIDGE_RGXTQ_RGXDESTROYTRANSFERCONTEXT, + &cmd, + sizeof(cmd), + &ret, + sizeof(ret)); + if (result || ret.error != PVR_SRV_OK) { + vk_bridge_err(VK_ERROR_UNKNOWN, + "PVR_SRV_BRIDGE_RGXTQ_RGXDESTROYTRANSFERCONTEXT", + ret); + } +} + VkResult pvr_srv_rgx_create_compute_context(int fd, uint32_t priority, diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h index 59b5f57b879..978e4fa3fe5 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h @@ -69,6 +69,11 @@ #define PVR_SRV_BRIDGE_DMABUF_PHYSMEMIMPORTDMABUF 0UL #define PVR_SRV_BRIDGE_DMABUF_PHYSMEMEXPORTDMABUF 2UL +#define PVR_SRV_BRIDGE_RGXTQ 128UL + +#define PVR_SRV_BRIDGE_RGXTQ_RGXCREATETRANSFERCONTEXT 0UL +#define PVR_SRV_BRIDGE_RGXTQ_RGXDESTROYTRANSFERCONTEXT 1UL + #define PVR_SRV_BRIDGE_RGXCMP 129UL #define PVR_SRV_BRIDGE_RGXCMP_RGXCREATECOMPUTECONTEXT 0UL @@ -132,6 +137,12 @@ #define PVR_BUFFER_FLAG_READ BITFIELD_BIT(0U) #define PVR_BUFFER_FLAG_WRITE BITFIELD_BIT(1U) +/* clang-format off */ +#define PVR_U8888_TO_U32(v1, v2, v3, v4) \ + (((v1) & 0xFFU) | (((v2) & 0xFFU) << 8U) | (((v3) & 0xFFU) << 16U) | \ + (((v4) & 0xFFU) << 24U)) +/* clang-format on */ + /****************************************************************************** Services Boolean ******************************************************************************/ @@ -460,6 +471,39 @@ struct pvr_srv_phys_mem_export_dmabuf_ret { int fd; } PACKED; +/****************************************************************************** + PVR_SRV_BRIDGE_RGXTQ_RGXCREATETRANSFERCONTEXT structs + ******************************************************************************/ + +struct pvr_srv_rgx_create_transfer_context_cmd { + uint64_t robustness_address; + void *priv_data; + uint8_t *reset_framework_cmd; + uint32_t context_flags; + uint32_t reset_framework_cmd_size; + uint32_t packed_ccb_size_u8888; + uint32_t priority; +} PACKED; + +struct pvr_srv_rgx_create_transfer_context_ret { + void *cli_pmr_mem; + void *transfer_context; + void *usc_pmr_mem; + enum pvr_srv_error error; +} PACKED; + +/****************************************************************************** + PVR_SRV_BRIDGE_RGXTQ_RGXDESTROYTRANSFERCONTEXT structs + ******************************************************************************/ + +struct pvr_srv_rgx_destroy_transfer_context_cmd { + void *transfer_context; +} PACKED; + +struct pvr_srv_rgx_destroy_transfer_context_ret { + enum pvr_srv_error error; +} PACKED; + /****************************************************************************** PVR_SRV_BRIDGE_RGXCMP_RGXCREATECOMPUTECONTEXT structs ******************************************************************************/ @@ -879,6 +923,19 @@ VkResult pvr_srv_rgx_kick_compute2(int fd, char *update_fence_name, int32_t *const update_fence_out); +VkResult pvr_srv_rgx_create_transfer_context(int fd, + uint32_t priority, + uint32_t reset_framework_cmd_size, + uint8_t *reset_framework_cmd, + void *priv_data, + uint32_t packed_ccb_size_u8888, + uint32_t context_flags, + uint64_t robustness_address, + void **const cli_pmr_out, + void **const usc_pmr_out, + void **const transfer_context_out); +void pvr_srv_rgx_destroy_transfer_context(int fd, void *transfer_context); + VkResult pvr_srv_rgx_create_hwrt_dataset(int fd, uint64_t flipped_multi_sample_ctl, diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_compute.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_compute.c index 74a3a0d84ae..339f283bc1c 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_compute.c +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_compute.c @@ -90,6 +90,9 @@ VkResult pvr_srv_winsys_compute_ctx_create( if (result != VK_SUCCESS) goto err_free_srv_ctx; + /* TODO: Add support for reset framework. Currently we subtract + * reset_cmd.regs size from reset_cmd size to only pass empty flags field. + */ result = pvr_srv_rgx_create_compute_context( srv_ws->render_fd, pvr_srv_from_winsys_priority(create_info->priority), diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_render.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_render.c index 5493b8babb4..2bc179f5e05 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_render.c +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_render.c @@ -350,6 +350,9 @@ VkResult pvr_srv_winsys_render_ctx_create( pvr_srv_render_ctx_fw_static_state_init(create_info, &static_state); + /* TODO: Add support for reset framework. Currently we subtract + * reset_cmd.regs size from reset_cmd size to only pass empty flags field. + */ result = pvr_srv_rgx_create_render_context( srv_ws->render_fd, pvr_srv_from_winsys_priority(create_info->priority), diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.c new file mode 100644 index 00000000000..44b43da1953 --- /dev/null +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.c @@ -0,0 +1,126 @@ +/* + * 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. + */ + +#include <fcntl.h> +#include <stddef.h> +#include <stdint.h> +#include <unistd.h> +#include <vulkan/vulkan.h> + +#include "fw-api/pvr_rogue_fwif_rf.h" +#include "pvr_private.h" +#include "pvr_srv.h" +#include "pvr_srv_bridge.h" +#include "pvr_srv_job_common.h" +#include "pvr_srv_job_transfer.h" +#include "pvr_winsys.h" +#include "util/macros.h" +#include "vk_alloc.h" +#include "vk_log.h" + +#define PVR_SRV_TRANSFER_CONTEXT_INITIAL_CCB_SIZE_LOG2 16U +#define PVR_SRV_TRANSFER_CONTEXT_MAX_CCB_SIZE_LOG2 0U + +struct pvr_srv_winsys_transfer_ctx { + struct pvr_winsys_transfer_ctx base; + + void *handle; + + int timeline; +}; + +#define to_pvr_srv_winsys_transfer_ctx(ctx) \ + container_of(ctx, struct pvr_srv_winsys_transfer_ctx, base) + +VkResult pvr_srv_winsys_transfer_ctx_create( + struct pvr_winsys *ws, + const struct pvr_winsys_transfer_ctx_create_info *create_info, + struct pvr_winsys_transfer_ctx **const ctx_out) +{ + struct pvr_srv_winsys *srv_ws = to_pvr_srv_winsys(ws); + struct pvr_srv_winsys_transfer_ctx *srv_ctx; + struct rogue_fwif_rf_cmd reset_cmd = { 0 }; + VkResult result; + + /* First 2 U8s are 2d work load related, and the last 2 are 3d workload + * related. + */ + const uint32_t packed_ccb_size = + PVR_U8888_TO_U32(PVR_SRV_TRANSFER_CONTEXT_INITIAL_CCB_SIZE_LOG2, + PVR_SRV_TRANSFER_CONTEXT_MAX_CCB_SIZE_LOG2, + PVR_SRV_TRANSFER_CONTEXT_INITIAL_CCB_SIZE_LOG2, + PVR_SRV_TRANSFER_CONTEXT_MAX_CCB_SIZE_LOG2); + + srv_ctx = vk_alloc(srv_ws->alloc, + sizeof(*srv_ctx), + 8U, + VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); + if (!srv_ctx) + return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY); + + result = pvr_srv_create_timeline(srv_ws->render_fd, &srv_ctx->timeline); + if (result != VK_SUCCESS) + goto err_free_srv_ctx; + + /* TODO: Add support for reset framework. Currently we subtract + * reset_cmd.regs size from reset_cmd size to only pass empty flags field. + */ + result = pvr_srv_rgx_create_transfer_context( + srv_ws->render_fd, + pvr_srv_from_winsys_priority(create_info->priority), + sizeof(reset_cmd) - sizeof(reset_cmd.regs), + (uint8_t *)&reset_cmd, + srv_ws->server_memctx_data, + packed_ccb_size, + RGX_CONTEXT_FLAG_DISABLESLR, + 0U, + NULL, + NULL, + &srv_ctx->handle); + if (result != VK_SUCCESS) + goto err_close_timeline; + + srv_ctx->base.ws = ws; + *ctx_out = &srv_ctx->base; + + return VK_SUCCESS; + +err_close_timeline: + close(srv_ctx->timeline); + +err_free_srv_ctx: + vk_free(srv_ws->alloc, srv_ctx); + + return result; +} + +void pvr_srv_winsys_transfer_ctx_destroy(struct pvr_winsys_transfer_ctx *ctx) +{ + struct pvr_srv_winsys *srv_ws = to_pvr_srv_winsys(ctx->ws); + struct pvr_srv_winsys_transfer_ctx *srv_ctx = + to_pvr_srv_winsys_transfer_ctx(ctx); + + pvr_srv_rgx_destroy_transfer_context(srv_ws->render_fd, srv_ctx->handle); + close(srv_ctx->timeline); + vk_free(srv_ws->alloc, srv_ctx); +} diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.h b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.h new file mode 100644 index 00000000000..dc3af2e29f0 --- /dev/null +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.h @@ -0,0 +1,43 @@ +/* + * 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. + */ + +#ifndef PVR_SRV_JOB_TRANSFER_H +#define PVR_SRV_JOB_TRANSFER_H + +#include <vulkan/vulkan.h> + +struct pvr_winsys; +struct pvr_winsys_transfer_ctx; +struct pvr_winsys_transfer_ctx_create_info; + +/******************************************* + Function prototypes + *******************************************/ + +VkResult pvr_srv_winsys_transfer_ctx_create( + struct pvr_winsys *ws, + const struct pvr_winsys_transfer_ctx_create_info *create_info, + struct pvr_winsys_transfer_ctx **const ctx_out); +void pvr_srv_winsys_transfer_ctx_destroy(struct pvr_winsys_transfer_ctx *ctx); + +#endif /* PVR_SRV_JOB_TRANSFER_H */
