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

Signed-off-by: Rajnesh Kanwal <rajnesh.kanwal@imgtec.com>
Reviewed-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16451>
This commit is contained in:
Rajnesh Kanwal 2022-04-04 12:17:47 +01:00
parent f88d1fbdbd
commit e8ed0e4984
6 changed files with 269 additions and 11 deletions

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;

View File

@ -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)

View File

@ -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);
}

View File

@ -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 */