Mesa (main): pvr: Add services winsys transfer context support.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu May 12 11:52:22 UTC 2022


Module: Mesa
Branch: main
Commit: f88d1fbdbd2ba8f41ed73ec274d3dc2b160c1f92
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f88d1fbdbd2ba8f41ed73ec274d3dc2b160c1f92

Author: Rajnesh Kanwal <rajnesh.kanwal at imgtec.com>
Date:   Mon Apr  4 12:16:45 2022 +0100

pvr: Add services winsys transfer context support.

Signed-off-by: Rajnesh Kanwal <rajnesh.kanwal at imgtec.com>
Reviewed-by: Frank Binns <frank.binns at imgtec.com>
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 */



More information about the mesa-commit mailing list