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