Mesa (main): pvr: Add support to create transfer context and setup required shaders.

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


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

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

pvr: Add support to create transfer context and setup required shaders.

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/pvr_job_context.c           | 142 ++++++++++++++++++++-
 src/imagination/vulkan/pvr_job_context.h           |  46 +++++++
 src/imagination/vulkan/pvr_pass.c                  |  23 ++--
 src/imagination/vulkan/pvr_private.h               |   8 ++
 src/imagination/vulkan/pvr_queue.c                 |  14 +-
 .../vulkan/usc/programs/pvr_transfer_eot.h         |  47 +++++++
 6 files changed, 269 insertions(+), 11 deletions(-)

diff --git a/src/imagination/vulkan/pvr_job_context.c b/src/imagination/vulkan/pvr_job_context.c
index efb7084cb54..cabbfb4be1f 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 0e3f81b0cd5..5cd948acfad 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 bebc9a46503..96e53b7df23 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 6cc4844fa6f..b32c99e4ddc 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 4c78406e838..3cbb10fa0e0 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 00000000000..427f0927f08
--- /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 <stdint.h>
+
+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 */



More information about the mesa-commit mailing list