pvr: Add services winsys transfer cmd submit interface.

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/16897>
This commit is contained in:
Rajnesh Kanwal 2022-04-19 16:36:43 +01:00
parent df671f6a8f
commit 16d4ca6e14
8 changed files with 365 additions and 9 deletions

View file

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

View file

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

View file

@ -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];
};
/**

View file

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

View file

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

View file

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

View file

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

View file

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