Mesa (main): pvr: Add services winsys transfer cmd submit interface.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 7 14:02:37 UTC 2022


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

Author: Rajnesh Kanwal <rajnesh.kanwal at imgtec.com>
Date:   Tue Apr 19 16:36:43 2022 +0100

pvr: Add services winsys transfer cmd submit interface.

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/16897>

---

 src/imagination/vulkan/pvr_job_context.h           |   4 +-
 src/imagination/vulkan/winsys/pvr_winsys.h         |  52 ++++++
 .../vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif.h |   6 +-
 src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c   |   1 +
 .../vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c        |  69 ++++++++
 .../vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h        |  59 +++++++
 .../vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.c  | 176 ++++++++++++++++++++-
 .../vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.h  |   7 +
 8 files changed, 365 insertions(+), 9 deletions(-)

diff --git a/src/imagination/vulkan/pvr_job_context.h b/src/imagination/vulkan/pvr_job_context.h
index 5cd948acfad..a655abf0010 100644
--- a/src/imagination/vulkan/pvr_job_context.h
+++ b/src/imagination/vulkan/pvr_job_context.h
@@ -24,8 +24,8 @@
 #ifndef PVR_JOB_CONTEXT_H
 #define PVR_JOB_CONTEXT_H
 
-#include "pvr_winsys.h"
 #include "pvr_private.h"
+#include "pvr_winsys.h"
 
 /* Support PDS code/data loading/storing to the 'B' shared register state
  * buffers.
@@ -132,8 +132,6 @@ struct pvr_compute_ctx {
       "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;
 
diff --git a/src/imagination/vulkan/winsys/pvr_winsys.h b/src/imagination/vulkan/winsys/pvr_winsys.h
index 9cb5bda4c07..a895f3cf42b 100644
--- a/src/imagination/vulkan/winsys/pvr_winsys.h
+++ b/src/imagination/vulkan/winsys/pvr_winsys.h
@@ -253,6 +253,54 @@ struct pvr_winsys_transfer_ctx {
    struct pvr_winsys *ws;
 };
 
+#define PVR_WINSYS_TRANSFER_FLAG_START BITFIELD_BIT(0U)
+#define PVR_WINSYS_TRANSFER_FLAG_END BITFIELD_BIT(1U)
+
+#define PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT 16U
+#define PVR_TRANSFER_MAX_RENDER_TARGETS 3U
+
+struct pvr_winsys_transfer_regs {
+   uint32_t event_pixel_pds_code;
+   uint32_t event_pixel_pds_data;
+   uint32_t event_pixel_pds_info;
+   uint32_t isp_aa;
+   uint32_t isp_bgobjvals;
+   uint32_t isp_ctl;
+   uint64_t isp_mtile_base;
+   uint32_t isp_mtile_size;
+   uint32_t isp_render;
+   uint32_t isp_render_origin;
+   uint32_t isp_rgn;
+   uint64_t pbe_wordx_mrty[PVR_TRANSFER_MAX_RENDER_TARGETS *
+                           ROGUE_NUM_PBESTATE_REG_WORDS];
+   uint64_t pds_bgnd0_base;
+   uint64_t pds_bgnd1_base;
+   uint64_t pds_bgnd3_sizeinfo;
+   uint32_t usc_clear_register0;
+   uint32_t usc_clear_register1;
+   uint32_t usc_clear_register2;
+   uint32_t usc_clear_register3;
+   uint32_t usc_pixel_output_ctrl;
+};
+
+struct pvr_winsys_transfer_submit_info {
+   uint32_t frame_num;
+   uint32_t job_num;
+
+   /* waits and stage_flags are arrays of length wait_count. */
+   struct vk_sync **waits;
+   uint32_t wait_count;
+   uint32_t *stage_flags;
+
+   uint32_t cmd_count;
+   struct {
+      struct pvr_winsys_transfer_regs regs;
+
+      /* Must be 0 or a combination of PVR_WINSYS_TRANSFER_FLAG_* flags. */
+      uint32_t flags;
+   } cmds[PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT];
+};
+
 #define PVR_WINSYS_COMPUTE_FLAG_PREVENT_ALL_OVERLAP BITFIELD_BIT(0U)
 #define PVR_WINSYS_COMPUTE_FLAG_SINGLE_CORE BITFIELD_BIT(1U)
 
@@ -440,6 +488,10 @@ struct pvr_winsys_ops {
       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);
+   VkResult (*transfer_submit)(
+      const struct pvr_winsys_transfer_ctx *ctx,
+      const struct pvr_winsys_transfer_submit_info *submit_info,
+      struct vk_sync *signal_sync);
 
    VkResult (*null_job_submit)(struct pvr_winsys *ws,
                                struct vk_sync **waits,
diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif.h b/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif.h
index 43f72d06b12..365fd37ffa8 100644
--- a/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif.h
+++ b/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif.h
@@ -28,7 +28,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "hwdef/rogue_hw_defs.h"
 #include "pvr_rogue_fwif_shared.h"
+#include "pvr_winsys.h"
 
 /**
  * \name Frag DM command flags.
@@ -358,9 +360,9 @@ struct rogue_fwif_transfer_regs {
    /* FIXME: HIGH: RGX_PBE_WORDS_REQUIRED_FOR_TQS changes the structure's
     * layout.
     */
-#define ROGUE_PBE_WORDS_REQUIRED_FOR_TRANSFER 3
    /* TQ_MAX_RENDER_TARGETS * PBE_STATE_SIZE */
-   uint64_t pbe_wordx_mrty[3U * ROGUE_PBE_WORDS_REQUIRED_FOR_TRANSFER];
+   uint64_t pbe_wordx_mrty[PVR_TRANSFER_MAX_RENDER_TARGETS *
+                           ROGUE_NUM_PBESTATE_REG_WORDS];
 };
 
 /**
diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c
index 2d298e15bf4..de3393c50fa 100644
--- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c
+++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c
@@ -452,6 +452,7 @@ static const struct pvr_winsys_ops srv_winsys_ops = {
    .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,
+   .transfer_submit = pvr_srv_winsys_transfer_submit,
    .null_job_submit = pvr_srv_winsys_null_job_submit,
 };
 
diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c
index 9a6da62d8db..8aff3014fe5 100644
--- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c
+++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c
@@ -871,6 +871,75 @@ void pvr_srv_rgx_destroy_transfer_context(int fd, void *transfer_context)
    }
 }
 
+VkResult pvr_srv_rgx_submit_transfer2(int fd,
+                                      void *transfer_context,
+                                      uint32_t prepare_count,
+                                      uint32_t *client_update_count,
+                                      void ***update_ufo_sync_prim_block,
+                                      uint32_t **update_sync_offset,
+                                      uint32_t **update_value,
+                                      int32_t check_fence,
+                                      int32_t update_timeline_2d,
+                                      int32_t update_timeline_3d,
+                                      char *update_fence_name,
+                                      uint32_t *cmd_size,
+                                      uint8_t **fw_command,
+                                      uint32_t *tq_prepare_flags,
+                                      uint32_t ext_job_ref,
+                                      uint32_t sync_pmr_count,
+                                      uint32_t *sync_pmr_flags,
+                                      void **sync_pmrs,
+                                      int32_t *const update_fence_2d_out,
+                                      int32_t *const update_fence_3d_out)
+{
+   struct pvr_srv_rgx_submit_transfer2_cmd cmd = {
+      .transfer_context = transfer_context,
+      .client_update_count = client_update_count,
+      .cmd_size = cmd_size,
+      .sync_pmr_flags = sync_pmr_flags,
+      .tq_prepare_flags = tq_prepare_flags,
+      .update_sync_offset = update_sync_offset,
+      .update_value = update_value,
+      .fw_command = fw_command,
+      .update_fence_name = update_fence_name,
+      .sync_pmrs = sync_pmrs,
+      .update_ufo_sync_prim_block = update_ufo_sync_prim_block,
+      .update_timeline_2d = update_timeline_2d,
+      .update_timeline_3d = update_timeline_3d,
+      .check_fence = check_fence,
+      .ext_job_ref = ext_job_ref,
+      .prepare_count = prepare_count,
+      .sync_pmr_count = sync_pmr_count,
+   };
+
+   struct pvr_srv_rgx_submit_transfer2_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_RGXSUBMITTRANSFER2,
+                                &cmd,
+                                sizeof(cmd),
+                                &ret,
+                                sizeof(ret));
+   if (result || ret.error != PVR_SRV_OK) {
+      return vk_bridge_err(VK_ERROR_OUT_OF_DEVICE_MEMORY,
+                           "PVR_SRV_BRIDGE_RGXTQ_RGXSUBMITTRANSFER2",
+                           ret);
+   }
+
+   if (update_fence_2d_out)
+      *update_fence_2d_out = ret.update_fence_2d;
+
+   if (update_fence_3d_out)
+      *update_fence_3d_out = ret.update_fence_3d;
+
+   return VK_SUCCESS;
+}
+
 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 978e4fa3fe5..7c475cd63c3 100644
--- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h
+++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h
@@ -73,6 +73,7 @@
 
 #define PVR_SRV_BRIDGE_RGXTQ_RGXCREATETRANSFERCONTEXT 0UL
 #define PVR_SRV_BRIDGE_RGXTQ_RGXDESTROYTRANSFERCONTEXT 1UL
+#define PVR_SRV_BRIDGE_RGXTQ_RGXSUBMITTRANSFER2 3UL
 
 #define PVR_SRV_BRIDGE_RGXCMP 129UL
 
@@ -105,6 +106,14 @@
 #define DRM_IOCTL_SRVKM_INIT \
    DRM_IOWR(DRM_COMMAND_BASE + DRM_SRVKM_INIT, struct drm_srvkm_init_data)
 
+/******************************************************************************
+   Bridge call specific defines
+ ******************************************************************************/
+
+/* Flags for PVR_SRV_BRIDGE_RGXTQ_RGXSUBMITTRANSFER2 bridge call. */
+#define PVR_TRANSFER_PREP_FLAGS_START BITFIELD_BIT(5U)
+#define PVR_TRANSFER_PREP_FLAGS_END BITFIELD_BIT(6U)
+
 /******************************************************************************
    Misc defines
  ******************************************************************************/
@@ -504,6 +513,36 @@ struct pvr_srv_rgx_destroy_transfer_context_ret {
    enum pvr_srv_error error;
 } PACKED;
 
+/******************************************************************************
+   PVR_SRV_BRIDGE_RGXTQ_RGXSUBMITTRANSFER2 structs
+ ******************************************************************************/
+
+struct pvr_srv_rgx_submit_transfer2_cmd {
+   void *transfer_context;
+   uint32_t *client_update_count;
+   uint32_t *cmd_size;
+   uint32_t *sync_pmr_flags;
+   uint32_t *tq_prepare_flags;
+   uint32_t **update_sync_offset;
+   uint32_t **update_value;
+   uint8_t **fw_command;
+   char *update_fence_name;
+   void **sync_pmrs;
+   void ***update_ufo_sync_prim_block;
+   int32_t update_timeline_2d;
+   int32_t update_timeline_3d;
+   int32_t check_fence;
+   uint32_t ext_job_ref;
+   uint32_t prepare_count;
+   uint32_t sync_pmr_count;
+} PACKED;
+
+struct pvr_srv_rgx_submit_transfer2_ret {
+   enum pvr_srv_error error;
+   int32_t update_fence_2d;
+   int32_t update_fence_3d;
+} PACKED;
+
 /******************************************************************************
    PVR_SRV_BRIDGE_RGXCMP_RGXCREATECOMPUTECONTEXT structs
  ******************************************************************************/
@@ -935,6 +974,26 @@ VkResult pvr_srv_rgx_create_transfer_context(int fd,
                                              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_submit_transfer2(int fd,
+                                      void *transfer_context,
+                                      uint32_t prepare_count,
+                                      uint32_t *client_update_count,
+                                      void ***update_ufo_sync_prim_block,
+                                      uint32_t **update_sync_offset,
+                                      uint32_t **update_value,
+                                      int32_t check_fence,
+                                      int32_t update_timeline_2d,
+                                      int32_t update_timeline_3d,
+                                      char *update_fence_name,
+                                      uint32_t *cmd_size,
+                                      uint8_t **fw_command,
+                                      uint32_t *tq_prepare_flags,
+                                      uint32_t ext_job_ref,
+                                      uint32_t sync_pmr_count,
+                                      uint32_t *sync_pmr_flags,
+                                      void **sync_pmrs,
+                                      int32_t *update_fence_2d_out,
+                                      int32_t *update_fence_3d_out);
 
 VkResult
 pvr_srv_rgx_create_hwrt_dataset(int fd,
diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.c
index 44b43da1953..670a71ea525 100644
--- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.c
+++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.c
@@ -27,16 +27,20 @@
 #include <unistd.h>
 #include <vulkan/vulkan.h>
 
+#include "fw-api/pvr_rogue_fwif.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_srv_sync.h"
 #include "pvr_winsys.h"
+#include "util/libsync.h"
 #include "util/macros.h"
 #include "vk_alloc.h"
 #include "vk_log.h"
+#include "vk_util.h"
 
 #define PVR_SRV_TRANSFER_CONTEXT_INITIAL_CCB_SIZE_LOG2 16U
 #define PVR_SRV_TRANSFER_CONTEXT_MAX_CCB_SIZE_LOG2 0U
@@ -46,7 +50,7 @@ struct pvr_srv_winsys_transfer_ctx {
 
    void *handle;
 
-   int timeline;
+   int timeline_3d;
 };
 
 #define to_pvr_srv_winsys_transfer_ctx(ctx) \
@@ -78,7 +82,7 @@ VkResult pvr_srv_winsys_transfer_ctx_create(
    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);
+   result = pvr_srv_create_timeline(srv_ws->render_fd, &srv_ctx->timeline_3d);
    if (result != VK_SUCCESS)
       goto err_free_srv_ctx;
 
@@ -106,7 +110,7 @@ VkResult pvr_srv_winsys_transfer_ctx_create(
    return VK_SUCCESS;
 
 err_close_timeline:
-   close(srv_ctx->timeline);
+   close(srv_ctx->timeline_3d);
 
 err_free_srv_ctx:
    vk_free(srv_ws->alloc, srv_ctx);
@@ -121,6 +125,170 @@ void pvr_srv_winsys_transfer_ctx_destroy(struct pvr_winsys_transfer_ctx *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);
+   close(srv_ctx->timeline_3d);
    vk_free(srv_ws->alloc, srv_ctx);
 }
+
+static void pvr_srv_transfer_cmds_init(
+   const struct pvr_winsys_transfer_submit_info *submit_info,
+   struct rogue_fwif_cmd_transfer *cmds,
+   uint32_t cmd_count)
+{
+   memset(cmds, 0, sizeof(*cmds) * submit_info->cmd_count);
+
+   for (uint32_t i = 0; i < cmd_count; i++) {
+      struct rogue_fwif_transfer_regs *fw_regs = &cmds[i].regs;
+
+      cmds[i].cmn.frame_num = submit_info->frame_num;
+
+      fw_regs->isp_bgobjvals = submit_info->cmds[i].regs.isp_bgobjvals;
+      fw_regs->usc_pixel_output_ctrl =
+         submit_info->cmds[i].regs.usc_pixel_output_ctrl;
+      fw_regs->usc_clear_register0 =
+         submit_info->cmds[i].regs.usc_clear_register0;
+      fw_regs->usc_clear_register1 =
+         submit_info->cmds[i].regs.usc_clear_register1;
+      fw_regs->usc_clear_register2 =
+         submit_info->cmds[i].regs.usc_clear_register2;
+      fw_regs->usc_clear_register3 =
+         submit_info->cmds[i].regs.usc_clear_register3;
+      fw_regs->isp_mtile_size = submit_info->cmds[i].regs.isp_mtile_size;
+      fw_regs->isp_render_origin = submit_info->cmds[i].regs.isp_render_origin;
+      fw_regs->isp_ctl = submit_info->cmds[i].regs.isp_ctl;
+      fw_regs->isp_aa = submit_info->cmds[i].regs.isp_aa;
+      fw_regs->event_pixel_pds_info =
+         submit_info->cmds[i].regs.event_pixel_pds_info;
+      fw_regs->event_pixel_pds_code =
+         submit_info->cmds[i].regs.event_pixel_pds_code;
+      fw_regs->event_pixel_pds_data =
+         submit_info->cmds[i].regs.event_pixel_pds_data;
+      fw_regs->isp_render = submit_info->cmds[i].regs.isp_render;
+      fw_regs->isp_rgn = submit_info->cmds[i].regs.isp_rgn;
+      fw_regs->pds_bgnd0_base = submit_info->cmds[i].regs.pds_bgnd0_base;
+      fw_regs->pds_bgnd1_base = submit_info->cmds[i].regs.pds_bgnd1_base;
+      fw_regs->pds_bgnd3_sizeinfo =
+         submit_info->cmds[i].regs.pds_bgnd3_sizeinfo;
+      fw_regs->isp_mtile_base = submit_info->cmds[i].regs.isp_mtile_base;
+
+      STATIC_ASSERT(ARRAY_SIZE(fw_regs->pbe_wordx_mrty) ==
+                    ARRAY_SIZE(submit_info->cmds[i].regs.pbe_wordx_mrty));
+      for (uint32_t j = 0; j < ARRAY_SIZE(fw_regs->pbe_wordx_mrty); j++) {
+         fw_regs->pbe_wordx_mrty[j] =
+            submit_info->cmds[i].regs.pbe_wordx_mrty[j];
+      }
+   }
+}
+
+VkResult pvr_srv_winsys_transfer_submit(
+   const struct pvr_winsys_transfer_ctx *ctx,
+   const struct pvr_winsys_transfer_submit_info *submit_info,
+   struct vk_sync *signal_sync)
+{
+   const struct pvr_srv_winsys_transfer_ctx *srv_ctx =
+      to_pvr_srv_winsys_transfer_ctx(ctx);
+   const struct pvr_srv_winsys *srv_ws = to_pvr_srv_winsys(ctx->ws);
+
+   struct rogue_fwif_cmd_transfer
+      *cmds_ptr_arr[PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT];
+   uint32_t *update_sync_offsets[PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT] = { 0 };
+   uint32_t client_update_count[PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT] = { 0 };
+   void **update_ufo_syc_prims[PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT] = { 0 };
+   uint32_t *update_values[PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT] = { 0 };
+   uint32_t cmd_sizes[PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT];
+   uint32_t cmd_flags[PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT];
+
+   struct pvr_srv_sync *srv_signal_sync;
+   uint32_t job_num;
+   VkResult result;
+   int in_fd = -1;
+   int fence;
+
+   STACK_ARRAY(struct rogue_fwif_cmd_transfer,
+               transfer_cmds,
+               submit_info->cmd_count);
+   if (!transfer_cmds)
+      return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   pvr_srv_transfer_cmds_init(submit_info,
+                              transfer_cmds,
+                              submit_info->cmd_count);
+
+   for (uint32_t i = 0U; i < submit_info->cmd_count; i++) {
+      cmd_sizes[i] = sizeof(**cmds_ptr_arr);
+
+      cmd_flags[i] = 0;
+      if (submit_info->cmds[i].flags & PVR_WINSYS_TRANSFER_FLAG_START)
+         cmd_flags[i] |= PVR_TRANSFER_PREP_FLAGS_START;
+
+      if (submit_info->cmds[i].flags & PVR_WINSYS_TRANSFER_FLAG_END)
+         cmd_flags[i] |= PVR_TRANSFER_PREP_FLAGS_END;
+
+      cmds_ptr_arr[i] = &transfer_cmds[i];
+   }
+
+   for (uint32_t i = 0U; i < submit_info->wait_count; i++) {
+      struct pvr_srv_sync *srv_wait_sync = to_srv_sync(submit_info->waits[i]);
+      int ret;
+
+      if (!submit_info->waits[i] || srv_wait_sync->fd < 0)
+         continue;
+
+      if (submit_info->stage_flags[i] & PVR_PIPELINE_STAGE_TRANSFER_BIT) {
+         ret = sync_accumulate("", &in_fd, srv_wait_sync->fd);
+         if (ret) {
+            result = vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
+            goto err_close_in_fd;
+         }
+
+         submit_info->stage_flags[i] &= ~PVR_PIPELINE_STAGE_TRANSFER_BIT;
+      }
+   }
+
+   job_num = submit_info->job_num;
+
+   do {
+      result = pvr_srv_rgx_submit_transfer2(srv_ws->render_fd,
+                                            srv_ctx->handle,
+                                            submit_info->cmd_count,
+                                            client_update_count,
+                                            update_ufo_syc_prims,
+                                            update_sync_offsets,
+                                            update_values,
+                                            in_fd,
+                                            -1,
+                                            srv_ctx->timeline_3d,
+                                            "TRANSFER",
+                                            cmd_sizes,
+                                            (uint8_t **)cmds_ptr_arr,
+                                            cmd_flags,
+                                            job_num,
+                                            /* TODO: Add sync PMR support. */
+                                            0U,
+                                            NULL,
+                                            NULL,
+                                            NULL,
+                                            &fence);
+   } while (result == VK_NOT_READY);
+
+   if (result != VK_SUCCESS)
+      goto err_close_in_fd;
+
+   if (signal_sync) {
+      srv_signal_sync = to_srv_sync(signal_sync);
+      pvr_srv_set_sync_payload(srv_signal_sync, fence);
+   } else if (fence != -1) {
+      close(fence);
+   }
+
+   STACK_ARRAY_FINISH(transfer_cmds);
+
+   return VK_SUCCESS;
+
+err_close_in_fd:
+   if (in_fd >= 0)
+      close(in_fd);
+
+   STACK_ARRAY_FINISH(transfer_cmds);
+
+   return result;
+}
diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.h b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.h
index dc3af2e29f0..acc4a14836a 100644
--- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.h
+++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_transfer.h
@@ -29,6 +29,8 @@
 struct pvr_winsys;
 struct pvr_winsys_transfer_ctx;
 struct pvr_winsys_transfer_ctx_create_info;
+struct pvr_winsys_transfer_submit_info;
+struct vk_sync;
 
 /*******************************************
    Function prototypes
@@ -40,4 +42,9 @@ VkResult pvr_srv_winsys_transfer_ctx_create(
    struct pvr_winsys_transfer_ctx **const ctx_out);
 void pvr_srv_winsys_transfer_ctx_destroy(struct pvr_winsys_transfer_ctx *ctx);
 
+VkResult pvr_srv_winsys_transfer_submit(
+   const struct pvr_winsys_transfer_ctx *ctx,
+   const struct pvr_winsys_transfer_submit_info *submit_info,
+   struct vk_sync *signal_sync);
+
 #endif /* PVR_SRV_JOB_TRANSFER_H */



More information about the mesa-commit mailing list