pvr: prepare winsys files for multi-arch

Acked-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38922>
This commit is contained in:
Erik Faye-Lund 2025-11-25 16:29:38 +01:00
parent f473c5fa97
commit edca79bc41
17 changed files with 1167 additions and 914 deletions

View file

@ -16,6 +16,8 @@ pvr_entrypoints = custom_target(
)
pvr_files = files(
'winsys/powervr/pvr_arch_drm_job_compute.c',
'winsys/powervr/pvr_arch_drm_job_render.c',
'winsys/powervr/pvr_drm.c',
'winsys/powervr/pvr_drm_bo.c',
'winsys/powervr/pvr_drm_job_compute.c',
@ -92,6 +94,9 @@ pvr_flags = [
if with_imagination_srv
pvr_files += files(
'winsys/pvrsrvkm/pvr_arch_srv_job_compute.c',
'winsys/pvrsrvkm/pvr_arch_srv_job_render.c',
'winsys/pvrsrvkm/pvr_arch_srv_job_transfer.c',
'winsys/pvrsrvkm/pvr_srv.c',
'winsys/pvrsrvkm/pvr_srv_bo.c',
'winsys/pvrsrvkm/pvr_srv_bridge.c',

View file

@ -0,0 +1,36 @@
/*
* Copyright © 2022 Imagination Technologies Ltd.
*
* SPDX-License-Identifier: MIT
*/
#include "pvr_drm_job_compute.h"
#include "pvr_csb.h"
void pvr_drm_compute_ctx_static_state_init(
const struct pvr_winsys_compute_ctx_create_info *create_info,
uint8_t *stream_ptr_start,
uint32_t *stream_len_ptr)
{
const struct pvr_winsys_compute_ctx_static_state *ws_static_state =
&create_info->static_state;
uint64_t *stream_ptr = (uint64_t *)stream_ptr_start;
/* Leave space for stream header. */
stream_ptr += pvr_cmd_length(KMD_STREAM_HDR) / 2;
*stream_ptr++ = ws_static_state->cdm_ctx_store_pds0;
*stream_ptr++ = ws_static_state->cdm_ctx_store_pds1;
*stream_ptr++ = ws_static_state->cdm_ctx_terminate_pds;
*stream_ptr++ = ws_static_state->cdm_ctx_terminate_pds1;
*stream_ptr++ = ws_static_state->cdm_ctx_resume_pds0;
*stream_ptr++ = ws_static_state->cdm_ctx_store_pds0_b;
*stream_ptr++ = ws_static_state->cdm_ctx_resume_pds0_b;
*stream_len_ptr = ((uint8_t *)stream_ptr - stream_ptr_start);
pvr_csb_pack ((uint64_t *)stream_ptr_start, KMD_STREAM_HDR, value) {
value.length = *stream_len_ptr;
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright © 2022 Imagination Technologies Ltd.
*
* SPDX-License-Identifier: MIT
*/
#include "pvr_drm_job_render.h"
#include "pvr_csb.h"
void pvr_drm_render_ctx_static_state_init(
struct pvr_winsys_render_ctx_create_info *create_info,
uint8_t *stream_ptr_start,
uint32_t *stream_len_ptr)
{
struct pvr_winsys_render_ctx_static_state *ws_static_state =
&create_info->static_state;
uint64_t *stream_ptr = (uint64_t *)stream_ptr_start;
/* Leave space for stream header. */
stream_ptr += pvr_cmd_length(KMD_STREAM_HDR) / 2;
*stream_ptr++ = ws_static_state->vdm_ctx_state_base_addr;
/* geom_reg_vdm_context_state_resume_addr is unused and zeroed. */
*stream_ptr++ = 0;
*stream_ptr++ = ws_static_state->geom_ctx_state_base_addr;
for (uint32_t i = 0; i < ARRAY_SIZE(ws_static_state->geom_state); i++) {
*stream_ptr++ = ws_static_state->geom_state[i].vdm_ctx_store_task0;
*stream_ptr++ = ws_static_state->geom_state[i].vdm_ctx_store_task1;
*stream_ptr++ = ws_static_state->geom_state[i].vdm_ctx_store_task2;
/* {store, resume}_task{3, 4} are unused and zeroed. */
*stream_ptr++ = 0;
*stream_ptr++ = 0;
*stream_ptr++ = ws_static_state->geom_state[i].vdm_ctx_resume_task0;
*stream_ptr++ = ws_static_state->geom_state[i].vdm_ctx_resume_task1;
*stream_ptr++ = ws_static_state->geom_state[i].vdm_ctx_resume_task2;
/* {store, resume}_task{3, 4} are unused and zeroed. */
*stream_ptr++ = 0;
*stream_ptr++ = 0;
}
*stream_len_ptr = ((uint8_t *)stream_ptr - stream_ptr_start);
pvr_csb_pack ((uint64_t *)stream_ptr_start, KMD_STREAM_HDR, value) {
value.length = *stream_len_ptr;
}
}

View file

@ -21,26 +21,19 @@
* SOFTWARE.
*/
#include <errno.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <vulkan/vulkan.h>
#include <xf86drm.h>
#include "drm-uapi/pvr_drm.h"
#include "pvr_csb.h"
#include "pvr_drm.h"
#include "pvr_drm_job_common.h"
#include "pvr_drm_job_compute.h"
#include "pvr_winsys.h"
#include "pvr_winsys_helper.h"
#include "util/macros.h"
#include "vk_alloc.h"
#include "vk_drm_syncobj.h"
#include "vk_log.h"
#include "drm-uapi/pvr_drm.h"
#include "pvr_drm_job_common.h"
#include "pvr_drm.h"
#include "pvr_macros.h"
#include "pvr_winsys_helper.h"
struct pvr_drm_winsys_compute_ctx {
struct pvr_winsys_compute_ctx base;
@ -51,33 +44,6 @@ struct pvr_drm_winsys_compute_ctx {
#define to_pvr_drm_winsys_compute_ctx(ctx) \
container_of(ctx, struct pvr_drm_winsys_compute_ctx, base)
static void pvr_drm_compute_ctx_static_state_init(
const struct pvr_winsys_compute_ctx_create_info *create_info,
uint8_t *stream_ptr_start,
uint32_t *stream_len_ptr)
{
const struct pvr_winsys_compute_ctx_static_state *ws_static_state =
&create_info->static_state;
uint64_t *stream_ptr = (uint64_t *)stream_ptr_start;
/* Leave space for stream header. */
stream_ptr += pvr_cmd_length(KMD_STREAM_HDR) / 2;
*stream_ptr++ = ws_static_state->cdm_ctx_store_pds0;
*stream_ptr++ = ws_static_state->cdm_ctx_store_pds1;
*stream_ptr++ = ws_static_state->cdm_ctx_terminate_pds;
*stream_ptr++ = ws_static_state->cdm_ctx_terminate_pds1;
*stream_ptr++ = ws_static_state->cdm_ctx_resume_pds0;
*stream_ptr++ = ws_static_state->cdm_ctx_store_pds0_b;
*stream_ptr++ = ws_static_state->cdm_ctx_resume_pds0_b;
*stream_len_ptr = ((uint8_t *)stream_ptr - stream_ptr_start);
pvr_csb_pack ((uint64_t *)stream_ptr_start, KMD_STREAM_HDR, value) {
value.length = *stream_len_ptr;
}
}
VkResult pvr_drm_winsys_compute_ctx_create(
struct pvr_winsys *ws,
const struct pvr_winsys_compute_ctx_create_info *create_info,

View file

@ -49,4 +49,9 @@ VkResult pvr_drm_winsys_compute_submit(
const struct pvr_device_info *dev_info,
struct vk_sync *signal_sync);
void pvr_drm_compute_ctx_static_state_init(
const struct pvr_winsys_compute_ctx_create_info *create_info,
uint8_t *stream_ptr_start,
uint32_t *stream_len_ptr);
#endif /* PVR_DRM_JOB_COMPUTE_H */

View file

@ -143,46 +143,6 @@ void pvr_drm_winsys_free_list_destroy(struct pvr_winsys_free_list *free_list)
vk_free(drm_ws->base.alloc, free_list);
}
static void pvr_drm_render_ctx_static_state_init(
struct pvr_winsys_render_ctx_create_info *create_info,
uint8_t *stream_ptr_start,
uint32_t *stream_len_ptr)
{
struct pvr_winsys_render_ctx_static_state *ws_static_state =
&create_info->static_state;
uint64_t *stream_ptr = (uint64_t *)stream_ptr_start;
/* Leave space for stream header. */
stream_ptr += pvr_cmd_length(KMD_STREAM_HDR) / 2;
*stream_ptr++ = ws_static_state->vdm_ctx_state_base_addr;
/* geom_reg_vdm_context_state_resume_addr is unused and zeroed. */
*stream_ptr++ = 0;
*stream_ptr++ = ws_static_state->geom_ctx_state_base_addr;
for (uint32_t i = 0; i < ARRAY_SIZE(ws_static_state->geom_state); i++) {
*stream_ptr++ = ws_static_state->geom_state[i].vdm_ctx_store_task0;
*stream_ptr++ = ws_static_state->geom_state[i].vdm_ctx_store_task1;
*stream_ptr++ = ws_static_state->geom_state[i].vdm_ctx_store_task2;
/* {store, resume}_task{3, 4} are unused and zeroed. */
*stream_ptr++ = 0;
*stream_ptr++ = 0;
*stream_ptr++ = ws_static_state->geom_state[i].vdm_ctx_resume_task0;
*stream_ptr++ = ws_static_state->geom_state[i].vdm_ctx_resume_task1;
*stream_ptr++ = ws_static_state->geom_state[i].vdm_ctx_resume_task2;
/* {store, resume}_task{3, 4} are unused and zeroed. */
*stream_ptr++ = 0;
*stream_ptr++ = 0;
}
*stream_len_ptr = ((uint8_t *)stream_ptr - stream_ptr_start);
pvr_csb_pack ((uint64_t *)stream_ptr_start, KMD_STREAM_HDR, value) {
value.length = *stream_len_ptr;
}
}
struct pvr_drm_winsys_render_ctx {
struct pvr_winsys_render_ctx base;

View file

@ -27,6 +27,8 @@
#include <stdint.h>
#include <vulkan/vulkan.h>
#include "pvr_macros.h"
struct pvr_device_info;
struct pvr_winsys;
struct pvr_winsys_free_list;
@ -74,4 +76,9 @@ VkResult pvr_drm_winsys_render_submit(
struct vk_sync *signal_sync_geom,
struct vk_sync *signal_sync_frag);
void pvr_drm_render_ctx_static_state_init(
struct pvr_winsys_render_ctx_create_info *create_info,
uint8_t *stream_ptr_start,
uint32_t *stream_len_ptr);
#endif /* PVR_DRM_JOB_RENDER_H */

View file

@ -29,7 +29,6 @@
#include "pco/pco_data.h"
#include "pco_uscgen_programs.h"
#include "pvr_csb.h"
#include "pvr_pass.h"
#include "pvr_pds.h"
#include "pvr_types.h"
@ -276,6 +275,8 @@ void pvr_winsys_helper_free_static_memory(
pvr_buffer_destroy_and_unmap(general_vma);
}
static uint32_t get_doutu_sample_rate(void);
static void pvr_setup_static_vdm_sync(uint8_t *const pds_ptr,
uint64_t pds_sync_offset_in_bytes,
uint8_t *const usc_ptr,
@ -292,7 +293,7 @@ static void pvr_setup_static_vdm_sync(uint8_t *const pds_ptr,
pvr_pds_setup_doutu(&ppp_state_update_program.usc_task_control,
usc_sync_offset_in_bytes,
precomp_data->temps,
ROGUE_PDSINST_DOUTU_SAMPLE_RATE_INSTANCE,
get_doutu_sample_rate(),
false);
pvr_pds_kick_usc(&ppp_state_update_program,
@ -357,3 +358,12 @@ err_pvr_srv_winsys_buffer_unmap_general:
err_out:
return result;
}
/* Leave this at the very end, to avoid leakage of HW-defs here */
#define PVR_BUILD_ARCH_ROGUE
#include "pvr_csb.h"
static uint32_t get_doutu_sample_rate(void)
{
return ROGUE_PDSINST_DOUTU_SAMPLE_RATE_INSTANCE;
}

View file

@ -0,0 +1,137 @@
/*
* 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.
*/
#include "pvr_srv_job_compute.h"
#include "fw-api/pvr_rogue_fwif.h"
#include "pvr_csb.h"
#include "pvr_device_info.h"
static uint32_t
pvr_srv_compute_cmd_stream_load(struct rogue_fwif_cmd_compute *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const struct pvr_device_info *const dev_info)
{
const uint32_t *stream_ptr = (const uint32_t *)stream;
struct rogue_fwif_cdm_regs *const regs = &cmd->regs;
uint32_t main_stream_len =
pvr_csb_unpack((uint64_t *)stream_ptr, KMD_STREAM_HDR).length;
stream_ptr += pvr_cmd_length(KMD_STREAM_HDR);
regs->tpu_border_colour_table = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_TPU_BORDER_COLOUR_TABLE_CDM);
regs->cdm_ctrl_stream_base = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_CDM_CTRL_STREAM_BASE);
regs->cdm_context_state_base_addr = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_CDM_CONTEXT_STATE_BASE);
regs->cdm_resume_pds1 = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_CDM_CONTEXT_PDS1);
if (PVR_HAS_FEATURE(dev_info, compute_morton_capable)) {
regs->cdm_item = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_CDM_ITEM);
}
if (PVR_HAS_FEATURE(dev_info, cluster_grouping)) {
regs->compute_cluster = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_COMPUTE_CLUSTER);
}
if (PVR_HAS_FEATURE(dev_info, tpu_dm_global_registers)) {
regs->tpu_tag_cdm_ctrl = *stream_ptr;
stream_ptr++;
}
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support)) {
cmd->execute_count = *stream_ptr;
stream_ptr++;
}
assert((const uint8_t *)stream_ptr - stream <= stream_len);
assert((const uint8_t *)stream_ptr - stream == main_stream_len);
return main_stream_len;
}
static void pvr_srv_compute_cmd_ext_stream_load(
struct rogue_fwif_cmd_compute *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const uint32_t ext_stream_offset,
const struct pvr_device_info *const dev_info)
{
const uint32_t *ext_stream_ptr =
(const uint32_t *)((uint8_t *)stream + ext_stream_offset);
struct rogue_fwif_cdm_regs *const regs = &cmd->regs;
struct ROGUE_KMD_STREAM_EXTHDR_COMPUTE0 header0;
header0 = pvr_csb_unpack(ext_stream_ptr, KMD_STREAM_EXTHDR_COMPUTE0);
ext_stream_ptr += pvr_cmd_length(KMD_STREAM_EXTHDR_COMPUTE0);
assert(PVR_HAS_QUIRK(dev_info, 49927) == header0.has_brn49927);
if (header0.has_brn49927) {
regs->tpu = *ext_stream_ptr;
ext_stream_ptr += pvr_cmd_length(CR_TPU);
}
assert((const uint8_t *)ext_stream_ptr - stream == stream_len);
}
void pvr_srv_compute_cmd_init(
const struct pvr_winsys_compute_submit_info *submit_info,
struct rogue_fwif_cmd_compute *cmd,
const struct pvr_device_info *const dev_info)
{
uint32_t ext_stream_offset;
memset(cmd, 0, sizeof(*cmd));
cmd->cmn.frame_num = submit_info->frame_num;
ext_stream_offset =
pvr_srv_compute_cmd_stream_load(cmd,
submit_info->fw_stream,
submit_info->fw_stream_len,
dev_info);
if (ext_stream_offset < submit_info->fw_stream_len) {
pvr_srv_compute_cmd_ext_stream_load(cmd,
submit_info->fw_stream,
submit_info->fw_stream_len,
ext_stream_offset,
dev_info);
}
if (submit_info->flags.prevent_all_overlap)
cmd->flags |= ROGUE_FWIF_COMPUTE_FLAG_PREVENT_ALL_OVERLAP;
if (submit_info->flags.use_single_core)
cmd->flags |= ROGUE_FWIF_COMPUTE_FLAG_SINGLE_CORE;
}

View file

@ -0,0 +1,753 @@
/*
* 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.
*/
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <vulkan/vulkan.h>
#include "fw-api/pvr_rogue_fwif.h"
#include "fw-api/pvr_rogue_fwif_rf.h"
#include "pvr_csb.h"
#include "pvr_job_render.h"
#include "pvr_srv.h"
#include "pvr_srv_bo.h"
#include "pvr_srv_bridge.h"
#include "pvr_srv_job_common.h"
#include "pvr_srv_job_render.h"
#include "pvr_srv_sync.h"
#include "pvr_srv_sync_prim.h"
#include "pvr_types.h"
#include "pvr_winsys.h"
#include "util/compiler.h"
#include "util/log.h"
#include "util/macros.h"
#include "util/os_file.h"
#include "util/u_math.h"
#include "vk_alloc.h"
#include "vk_log.h"
#include "vk_util.h"
struct pvr_srv_winsys_free_list {
struct pvr_winsys_free_list base;
void *handle;
struct pvr_srv_winsys_free_list *parent;
};
#define to_pvr_srv_winsys_free_list(free_list) \
container_of(free_list, struct pvr_srv_winsys_free_list, base)
struct pvr_srv_winsys_rt_dataset {
struct pvr_winsys_rt_dataset base;
struct {
void *handle;
struct pvr_srv_sync_prim *sync_prim;
} rt_datas[ROGUE_FWIF_NUM_RTDATAS];
};
#define to_pvr_srv_winsys_rt_dataset(rt_dataset) \
container_of(rt_dataset, struct pvr_srv_winsys_rt_dataset, base)
struct pvr_srv_winsys_render_ctx {
struct pvr_winsys_render_ctx base;
/* Handle to kernel context. */
void *handle;
int timeline_geom;
int timeline_frag;
};
#define to_pvr_srv_winsys_render_ctx(ctx) \
container_of(ctx, struct pvr_srv_winsys_render_ctx, base)
static uint64_t pvr_rogue_get_cr_multisamplectl_val(uint32_t samples,
bool y_flip)
{
static const struct {
uint8_t x[8];
uint8_t y[8];
} sample_positions[4] = {
/* 1 sample */
{
.x = { 8 },
.y = { 8 },
},
/* 2 samples */
{
.x = { 12, 4 },
.y = { 12, 4 },
},
/* 4 samples */
{
.x = { 6, 14, 2, 10 },
.y = { 2, 6, 10, 14 },
},
/* 8 samples */
{
.x = { 9, 7, 13, 5, 3, 1, 11, 15 },
.y = { 5, 11, 9, 3, 13, 7, 15, 1 },
},
};
uint64_t multisamplectl;
uint8_t idx;
idx = util_fast_log2(samples);
assert(idx < ARRAY_SIZE(sample_positions));
pvr_csb_pack (&multisamplectl, CR_PPP_MULTISAMPLECTL, value) {
switch (samples) {
case 8:
value.msaa_x7 = sample_positions[idx].x[7];
value.msaa_x6 = sample_positions[idx].x[6];
value.msaa_x5 = sample_positions[idx].x[5];
value.msaa_x4 = sample_positions[idx].x[4];
if (y_flip) {
value.msaa_y7 = 16U - sample_positions[idx].y[7];
value.msaa_y6 = 16U - sample_positions[idx].y[6];
value.msaa_y5 = 16U - sample_positions[idx].y[5];
value.msaa_y4 = 16U - sample_positions[idx].y[4];
} else {
value.msaa_y7 = sample_positions[idx].y[7];
value.msaa_y6 = sample_positions[idx].y[6];
value.msaa_y5 = sample_positions[idx].y[5];
value.msaa_y4 = sample_positions[idx].y[4];
}
FALLTHROUGH;
case 4:
value.msaa_x3 = sample_positions[idx].x[3];
value.msaa_x2 = sample_positions[idx].x[2];
if (y_flip) {
value.msaa_y3 = 16U - sample_positions[idx].y[3];
value.msaa_y2 = 16U - sample_positions[idx].y[2];
} else {
value.msaa_y3 = sample_positions[idx].y[3];
value.msaa_y2 = sample_positions[idx].y[2];
}
FALLTHROUGH;
case 2:
value.msaa_x1 = sample_positions[idx].x[1];
if (y_flip) {
value.msaa_y1 = 16U - sample_positions[idx].y[1];
} else {
value.msaa_y1 = sample_positions[idx].y[1];
}
FALLTHROUGH;
case 1:
value.msaa_x0 = sample_positions[idx].x[0];
if (y_flip) {
value.msaa_y0 = 16U - sample_positions[idx].y[0];
} else {
value.msaa_y0 = sample_positions[idx].y[0];
}
break;
default:
UNREACHABLE("Unsupported number of samples");
}
}
return multisamplectl;
}
static uint32_t
pvr_rogue_get_cr_isp_mtile_size_val(const struct pvr_device_info *dev_info,
const struct pvr_rt_mtile_info *mtile_info,
uint32_t samples)
{
uint32_t samples_per_pixel =
PVR_GET_FEATURE_VALUE(dev_info, isp_samples_per_pixel, 0);
uint32_t isp_mtile_size;
pvr_csb_pack (&isp_mtile_size, CR_ISP_MTILE_SIZE, value) {
value.x = mtile_info->mtile_x1;
value.y = mtile_info->mtile_y1;
if (samples_per_pixel == 1) {
if (samples >= 4)
value.x <<= 1;
if (samples >= 2)
value.y <<= 1;
} else if (samples_per_pixel == 2) {
if (samples >= 8)
value.x <<= 1;
if (samples >= 4)
value.y <<= 1;
} else if (samples_per_pixel == 4) {
if (samples >= 8)
value.y <<= 1;
} else {
assert(!"Unsupported ISP samples per pixel value");
}
}
return isp_mtile_size;
}
static uint32_t pvr_rogue_get_ppp_screen_val(uint32_t width, uint32_t height)
{
uint32_t val;
pvr_csb_pack (&val, CR_PPP_SCREEN, state) {
state.pixxmax = width - 1;
state.pixymax = height - 1;
}
return val;
}
struct pvr_rogue_cr_te {
uint32_t aa;
uint32_t mtile1;
uint32_t mtile2;
uint32_t screen;
uint32_t mtile_stride;
};
static void pvr_rogue_ct_te_init(const struct pvr_device_info *dev_info,
const struct pvr_rt_mtile_info *mtile_info,
uint32_t samples,
struct pvr_rogue_cr_te *const te_regs)
{
uint32_t samples_per_pixel =
PVR_GET_FEATURE_VALUE(dev_info, isp_samples_per_pixel, 0);
pvr_csb_pack (&te_regs->aa, CR_TE_AA, value) {
if (samples_per_pixel == 1) {
if (samples >= 2)
value.y = true;
if (samples >= 4)
value.x = true;
} else if (samples_per_pixel == 2) {
if (samples >= 2)
value.x2 = true;
if (samples >= 4)
value.y = true;
if (samples >= 8)
value.x = true;
} else if (samples_per_pixel == 4) {
if (samples >= 2)
value.x2 = true;
if (samples >= 4)
value.y2 = true;
if (samples >= 8)
value.y = true;
} else {
assert(!"Unsupported ISP samples per pixel value");
}
}
pvr_csb_pack (&te_regs->mtile1, CR_TE_MTILE1, value) {
value.x1 = mtile_info->mtile_x1;
if (!PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format)) {
value.x2 = mtile_info->mtile_x2;
value.x3 = mtile_info->mtile_x3;
}
}
pvr_csb_pack (&te_regs->mtile2, CR_TE_MTILE2, value) {
value.y1 = mtile_info->mtile_y1;
if (!PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format)) {
value.y2 = mtile_info->mtile_y2;
value.y3 = mtile_info->mtile_y3;
}
}
pvr_csb_pack (&te_regs->screen, CR_TE_SCREEN, value) {
value.xmax = mtile_info->x_tile_max;
value.ymax = mtile_info->y_tile_max;
}
te_regs->mtile_stride = mtile_info->mtile_x1 * mtile_info->mtile_y1;
}
VkResult pvr_srv_render_target_dataset_create(
struct pvr_winsys *ws,
const struct pvr_winsys_rt_dataset_create_info *create_info,
const struct pvr_device_info *dev_info,
struct pvr_winsys_rt_dataset **const rt_dataset_out)
{
const pvr_dev_addr_t macrotile_addrs[ROGUE_FWIF_NUM_RTDATAS] = {
[0] = create_info->rt_datas[0].macrotile_array_dev_addr,
[1] = create_info->rt_datas[1].macrotile_array_dev_addr,
};
const pvr_dev_addr_t pm_mlist_addrs[ROGUE_FWIF_NUM_RTDATAS] = {
[0] = create_info->rt_datas[0].pm_mlist_dev_addr,
[1] = create_info->rt_datas[1].pm_mlist_dev_addr,
};
const pvr_dev_addr_t rgn_header_addrs[ROGUE_FWIF_NUM_RTDATAS] = {
[0] = create_info->rt_datas[0].rgn_header_dev_addr,
[1] = create_info->rt_datas[1].rgn_header_dev_addr,
};
struct pvr_srv_winsys *srv_ws = to_pvr_srv_winsys(ws);
struct pvr_srv_winsys_free_list *srv_local_free_list =
to_pvr_srv_winsys_free_list(create_info->local_free_list);
void *free_lists[ROGUE_FW_MAX_FREELISTS] = { NULL };
struct pvr_srv_winsys_rt_dataset *srv_rt_dataset;
void *handles[ROGUE_FWIF_NUM_RTDATAS];
struct pvr_rogue_cr_te rogue_te_regs;
struct pvr_rt_mtile_info mtile_info;
uint32_t isp_mtile_size;
VkResult result;
free_lists[ROGUE_FW_LOCAL_FREELIST] = srv_local_free_list->handle;
if (srv_local_free_list->parent) {
free_lists[ROGUE_FW_GLOBAL_FREELIST] =
srv_local_free_list->parent->handle;
}
srv_rt_dataset = vk_zalloc(ws->alloc,
sizeof(*srv_rt_dataset),
8,
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
if (!srv_rt_dataset)
return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
/* If greater than 1 we'll have to pass in an array. For now just passing in
* the reference.
*/
STATIC_ASSERT(ROGUE_FWIF_NUM_GEOMDATAS == 1);
/* If not 2 the arrays used in the bridge call will require updating. */
STATIC_ASSERT(ROGUE_FWIF_NUM_RTDATAS == 2);
pvr_rt_mtile_info_init(dev_info,
&mtile_info,
create_info->width,
create_info->height,
create_info->samples);
isp_mtile_size = pvr_rogue_get_cr_isp_mtile_size_val(dev_info,
&mtile_info,
create_info->samples);
pvr_rogue_ct_te_init(dev_info,
&mtile_info,
create_info->samples,
&rogue_te_regs);
result = pvr_srv_rgx_create_hwrt_dataset(
ws->render_fd,
pvr_rogue_get_cr_multisamplectl_val(create_info->samples, true),
pvr_rogue_get_cr_multisamplectl_val(create_info->samples, false),
macrotile_addrs,
pm_mlist_addrs,
&create_info->rtc_dev_addr,
rgn_header_addrs,
&create_info->tpc_dev_addr,
&create_info->vheap_table_dev_addr,
free_lists,
create_info->isp_merge_lower_x,
create_info->isp_merge_lower_y,
create_info->isp_merge_scale_x,
create_info->isp_merge_scale_y,
create_info->isp_merge_upper_x,
create_info->isp_merge_upper_y,
isp_mtile_size,
rogue_te_regs.mtile_stride,
pvr_rogue_get_ppp_screen_val(create_info->width, create_info->height),
create_info->rgn_header_size,
rogue_te_regs.aa,
rogue_te_regs.mtile1,
rogue_te_regs.mtile2,
rogue_te_regs.screen,
create_info->tpc_size,
create_info->tpc_stride,
create_info->layers,
handles);
if (result != VK_SUCCESS)
goto err_vk_free_srv_rt_dataset;
srv_rt_dataset->rt_datas[0].handle = handles[0];
srv_rt_dataset->rt_datas[1].handle = handles[1];
for (uint32_t i = 0; i < ARRAY_SIZE(srv_rt_dataset->rt_datas); i++) {
srv_rt_dataset->rt_datas[i].sync_prim = pvr_srv_sync_prim_alloc(srv_ws);
if (!srv_rt_dataset->rt_datas[i].sync_prim)
goto err_srv_sync_prim_free;
}
srv_rt_dataset->base.ws = ws;
*rt_dataset_out = &srv_rt_dataset->base;
return VK_SUCCESS;
err_srv_sync_prim_free:
for (uint32_t i = 0; i < ARRAY_SIZE(srv_rt_dataset->rt_datas); i++) {
pvr_srv_sync_prim_free(srv_ws, srv_rt_dataset->rt_datas[i].sync_prim);
if (srv_rt_dataset->rt_datas[i].handle) {
pvr_srv_rgx_destroy_hwrt_dataset(ws->render_fd,
srv_rt_dataset->rt_datas[i].handle);
}
}
err_vk_free_srv_rt_dataset:
vk_free(ws->alloc, srv_rt_dataset);
return result;
}
static void pvr_srv_render_ctx_fw_static_state_init(
struct pvr_winsys_render_ctx_create_info *create_info,
struct rogue_fwif_static_rendercontext_state *static_state)
{
struct pvr_winsys_render_ctx_static_state *ws_static_state =
&create_info->static_state;
struct rogue_fwif_ta_regs_cswitch *regs =
&static_state->ctx_switch_geom_regs[0];
memset(static_state, 0, sizeof(*static_state));
regs->vdm_context_state_base_addr = ws_static_state->vdm_ctx_state_base_addr;
regs->ta_context_state_base_addr = ws_static_state->geom_ctx_state_base_addr;
STATIC_ASSERT(ARRAY_SIZE(regs->ta_state) ==
ARRAY_SIZE(ws_static_state->geom_state));
for (uint32_t i = 0; i < ARRAY_SIZE(ws_static_state->geom_state); i++) {
regs->ta_state[i].vdm_context_store_task0 =
ws_static_state->geom_state[i].vdm_ctx_store_task0;
regs->ta_state[i].vdm_context_store_task1 =
ws_static_state->geom_state[i].vdm_ctx_store_task1;
regs->ta_state[i].vdm_context_store_task2 =
ws_static_state->geom_state[i].vdm_ctx_store_task2;
regs->ta_state[i].vdm_context_resume_task0 =
ws_static_state->geom_state[i].vdm_ctx_resume_task0;
regs->ta_state[i].vdm_context_resume_task1 =
ws_static_state->geom_state[i].vdm_ctx_resume_task1;
regs->ta_state[i].vdm_context_resume_task2 =
ws_static_state->geom_state[i].vdm_ctx_resume_task2;
}
}
static uint32_t
pvr_srv_geometry_cmd_stream_load(struct rogue_fwif_cmd_ta *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const struct pvr_device_info *const dev_info)
{
const uint32_t *stream_ptr = (const uint32_t *)stream;
struct rogue_fwif_ta_regs *const regs = &cmd->regs;
uint32_t main_stream_len =
pvr_csb_unpack((const uint64_t *)stream_ptr, KMD_STREAM_HDR).length;
stream_ptr += pvr_cmd_length(KMD_STREAM_HDR);
regs->vdm_ctrl_stream_base = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_VDM_CTRL_STREAM_BASE);
regs->tpu_border_colour_table = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_TPU_BORDER_COLOUR_TABLE_VDM);
regs->ppp_ctrl = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_PPP_CTRL);
regs->te_psg = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_TE_PSG);
regs->vdm_context_resume_task0_size = *stream_ptr;
stream_ptr += pvr_cmd_length(VDMCTRL_PDS_STATE0);
regs->view_idx = *stream_ptr;
stream_ptr++;
assert((const uint8_t *)stream_ptr - stream <= stream_len);
assert((const uint8_t *)stream_ptr - stream == main_stream_len);
return main_stream_len;
}
static void pvr_srv_geometry_cmd_ext_stream_load(
struct rogue_fwif_cmd_ta *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const uint32_t ext_stream_offset,
const struct pvr_device_info *const dev_info)
{
const uint32_t *ext_stream_ptr =
(const uint32_t *)((uint8_t *)stream + ext_stream_offset);
struct rogue_fwif_ta_regs *const regs = &cmd->regs;
struct ROGUE_KMD_STREAM_EXTHDR_GEOM0 header0;
header0 = pvr_csb_unpack(ext_stream_ptr, KMD_STREAM_EXTHDR_GEOM0);
ext_stream_ptr += pvr_cmd_length(KMD_STREAM_EXTHDR_GEOM0);
assert(PVR_HAS_QUIRK(dev_info, 49927) == header0.has_brn49927);
if (header0.has_brn49927) {
regs->tpu = *ext_stream_ptr;
ext_stream_ptr += pvr_cmd_length(CR_TPU);
}
assert((const uint8_t *)ext_stream_ptr - stream == stream_len);
}
void pvr_srv_geometry_cmd_init(
const struct pvr_winsys_render_submit_info *submit_info,
const struct pvr_srv_sync_prim *sync_prim,
struct rogue_fwif_cmd_ta *cmd,
const struct pvr_device_info *const dev_info)
{
const struct pvr_winsys_geometry_state *state = &submit_info->geometry;
uint32_t ext_stream_offset;
memset(cmd, 0, sizeof(*cmd));
cmd->cmd_shared.cmn.frame_num = submit_info->frame_num;
ext_stream_offset = pvr_srv_geometry_cmd_stream_load(cmd,
state->fw_stream,
state->fw_stream_len,
dev_info);
if (ext_stream_offset < state->fw_stream_len) {
pvr_srv_geometry_cmd_ext_stream_load(cmd,
state->fw_stream,
state->fw_stream_len,
ext_stream_offset,
dev_info);
}
if (state->flags.is_first_geometry)
cmd->flags |= ROGUE_FWIF_TAFLAGS_FIRSTKICK;
if (state->flags.is_last_geometry)
cmd->flags |= ROGUE_FWIF_TAFLAGS_LASTKICK;
if (state->flags.use_single_core)
cmd->flags |= ROGUE_FWIF_TAFLAGS_SINGLE_CORE;
cmd->partial_render_ta_3d_fence.ufo_addr.addr =
pvr_srv_sync_prim_get_fw_addr(sync_prim);
cmd->partial_render_ta_3d_fence.value = sync_prim->value;
}
static uint32_t
pvr_srv_fragment_cmd_stream_load(struct rogue_fwif_cmd_3d *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const struct pvr_device_info *const dev_info)
{
const uint32_t *stream_ptr = (const uint32_t *)stream;
struct rogue_fwif_3d_regs *const regs = &cmd->regs;
uint32_t main_stream_len =
pvr_csb_unpack((const uint64_t *)stream_ptr, KMD_STREAM_HDR).length;
stream_ptr += pvr_cmd_length(KMD_STREAM_HDR);
regs->isp_scissor_base = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_SCISSOR_BASE);
regs->isp_dbias_base = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_DBIAS_BASE);
regs->isp_oclqry_base = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_OCLQRY_BASE);
regs->isp_zlsctl = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_ZLSCTL);
regs->isp_zload_store_base = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_ZLOAD_BASE);
regs->isp_stencil_load_store_base = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_STENCIL_LOAD_BASE);
if (PVR_HAS_FEATURE(dev_info, requires_fb_cdc_zls_setup)) {
regs->fb_cdc_zls = *(const uint64_t *)stream_ptr;
stream_ptr += 2U;
}
STATIC_ASSERT(ARRAY_SIZE(regs->pbe_word) == 8U);
STATIC_ASSERT(ARRAY_SIZE(regs->pbe_word[0]) == 3U);
STATIC_ASSERT(sizeof(regs->pbe_word[0][0]) == sizeof(uint64_t));
memcpy(regs->pbe_word, stream_ptr, sizeof(regs->pbe_word));
stream_ptr += 8U * 3U * 2U;
regs->tpu_border_colour_table = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_TPU_BORDER_COLOUR_TABLE_PDM);
STATIC_ASSERT(ARRAY_SIZE(regs->pds_bgnd) == 3U);
STATIC_ASSERT(sizeof(regs->pds_bgnd[0]) == sizeof(uint64_t));
memcpy(regs->pds_bgnd, stream_ptr, sizeof(regs->pds_bgnd));
stream_ptr += 3U * 2U;
STATIC_ASSERT(ARRAY_SIZE(regs->pds_pr_bgnd) == 3U);
STATIC_ASSERT(sizeof(regs->pds_pr_bgnd[0]) == sizeof(uint64_t));
memcpy(regs->pds_pr_bgnd, stream_ptr, sizeof(regs->pds_pr_bgnd));
stream_ptr += 3U * 2U;
STATIC_ASSERT(ARRAY_SIZE(regs->usc_clear_register) == 8U);
STATIC_ASSERT(sizeof(regs->usc_clear_register[0]) == sizeof(uint32_t));
memcpy(regs->usc_clear_register,
stream_ptr,
sizeof(regs->usc_clear_register));
stream_ptr += 8U;
regs->usc_pixel_output_ctrl = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_USC_PIXEL_OUTPUT_CTRL);
regs->isp_bgobjdepth = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_BGOBJDEPTH);
regs->isp_bgobjvals = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_BGOBJVALS);
regs->isp_aa = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_AA);
regs->isp_ctl = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_CTL);
regs->event_pixel_pds_info = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_EVENT_PIXEL_PDS_INFO);
if (PVR_HAS_FEATURE(dev_info, cluster_grouping)) {
regs->pixel_phantom = *stream_ptr;
stream_ptr++;
}
regs->view_idx = *stream_ptr;
stream_ptr++;
regs->event_pixel_pds_data = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_EVENT_PIXEL_PDS_DATA);
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support)) {
regs->isp_oclqry_stride = *stream_ptr;
stream_ptr++;
}
if (PVR_HAS_FEATURE(dev_info, zls_subtile)) {
regs->isp_zls_pixels = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_ZLS_PIXELS);
}
cmd->zls_stride = *stream_ptr;
stream_ptr++;
cmd->sls_stride = *stream_ptr;
stream_ptr++;
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support)) {
cmd->execute_count = *stream_ptr;
stream_ptr++;
}
assert((const uint8_t *)stream_ptr - stream <= stream_len);
assert((const uint8_t *)stream_ptr - stream == main_stream_len);
return main_stream_len;
}
static void pvr_srv_fragment_cmd_ext_stream_load(
struct rogue_fwif_cmd_3d *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const uint32_t ext_stream_offset,
const struct pvr_device_info *const dev_info)
{
const uint32_t *ext_stream_ptr =
(const uint32_t *)((uint8_t *)stream + ext_stream_offset);
struct rogue_fwif_3d_regs *const regs = &cmd->regs;
struct ROGUE_KMD_STREAM_EXTHDR_FRAG0 header0;
header0 = pvr_csb_unpack(ext_stream_ptr, KMD_STREAM_EXTHDR_FRAG0);
ext_stream_ptr += pvr_cmd_length(KMD_STREAM_EXTHDR_FRAG0);
assert(PVR_HAS_QUIRK(dev_info, 49927) == header0.has_brn49927);
if (header0.has_brn49927) {
regs->tpu = *ext_stream_ptr;
ext_stream_ptr += pvr_cmd_length(CR_TPU);
}
assert((const uint8_t *)ext_stream_ptr - stream == stream_len);
}
void pvr_srv_fragment_cmd_init(struct rogue_fwif_cmd_3d *cmd,
const struct pvr_winsys_fragment_state *state,
const struct pvr_device_info *dev_info,
uint32_t frame_num)
{
uint32_t ext_stream_offset;
memset(cmd, 0, sizeof(*cmd));
cmd->cmd_shared.cmn.frame_num = frame_num;
ext_stream_offset = pvr_srv_fragment_cmd_stream_load(cmd,
state->fw_stream,
state->fw_stream_len,
dev_info);
if (ext_stream_offset < state->fw_stream_len) {
pvr_srv_fragment_cmd_ext_stream_load(cmd,
state->fw_stream,
state->fw_stream_len,
ext_stream_offset,
dev_info);
}
if (state->flags.has_depth_buffer)
cmd->flags |= ROGUE_FWIF_RENDERFLAGS_DEPTHBUFFER;
if (state->flags.has_stencil_buffer)
cmd->flags |= ROGUE_FWIF_RENDERFLAGS_STENCILBUFFER;
if (state->flags.prevent_cdm_overlap)
cmd->flags |= ROGUE_FWIF_RENDERFLAGS_PREVENT_CDM_OVERLAP;
if (state->flags.use_single_core)
cmd->flags |= ROGUE_FWIF_RENDERFLAGS_SINGLE_CORE;
if (state->flags.get_vis_results)
cmd->flags |= ROGUE_FWIF_RENDERFLAGS_GETVISRESULTS;
if (state->flags.has_spm_scratch_buffer)
cmd->flags |= ROGUE_FWIF_RENDERFLAGS_SPMSCRATCHBUFFER;
if (state->flags.disable_pixel_merging)
cmd->flags |= ROGUE_FWIF_RENDERFLAGS_DISABLE_PIXELMERGE;
}

View file

@ -0,0 +1,114 @@
/*
* 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.
*/
#include "pvr_srv_job_transfer.h"
#include "fw-api/pvr_rogue_fwif.h"
#include "pvr_csb.h"
#include "pvr_device_info.h"
void pvr_srv_transfer_cmd_stream_load(
struct rogue_fwif_cmd_transfer *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const struct pvr_device_info *const dev_info)
{
const uint32_t *stream_ptr = (const uint32_t *)stream;
struct rogue_fwif_transfer_regs *const regs = &cmd->regs;
uint32_t main_stream_len =
pvr_csb_unpack((uint64_t *)stream_ptr, KMD_STREAM_HDR).length;
stream_ptr += pvr_cmd_length(KMD_STREAM_HDR);
memcpy(&regs->pds_bgnd0_base, stream_ptr, sizeof(regs->pds_bgnd0_base));
stream_ptr += pvr_cmd_length(CR_PDS_BGRND0_BASE);
memcpy(&regs->pds_bgnd1_base, stream_ptr, sizeof(regs->pds_bgnd1_base));
stream_ptr += pvr_cmd_length(CR_PDS_BGRND1_BASE);
memcpy(&regs->pds_bgnd3_sizeinfo,
stream_ptr,
sizeof(regs->pds_bgnd3_sizeinfo));
stream_ptr += pvr_cmd_length(CR_PDS_BGRND3_SIZEINFO);
memcpy(&regs->isp_mtile_base, stream_ptr, sizeof(regs->isp_mtile_base));
stream_ptr += pvr_cmd_length(CR_ISP_MTILE_BASE);
STATIC_ASSERT(ARRAY_SIZE(regs->pbe_wordx_mrty) == 9U);
STATIC_ASSERT(sizeof(regs->pbe_wordx_mrty[0]) == sizeof(uint64_t));
memcpy(regs->pbe_wordx_mrty, stream_ptr, sizeof(regs->pbe_wordx_mrty));
stream_ptr += 9U * 2U;
regs->isp_bgobjvals = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_BGOBJVALS);
regs->usc_pixel_output_ctrl = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_USC_PIXEL_OUTPUT_CTRL);
regs->usc_clear_register0 = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_USC_CLEAR_REGISTER);
regs->usc_clear_register1 = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_USC_CLEAR_REGISTER);
regs->usc_clear_register2 = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_USC_CLEAR_REGISTER);
regs->usc_clear_register3 = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_USC_CLEAR_REGISTER);
regs->isp_mtile_size = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_MTILE_SIZE);
regs->isp_render_origin = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_RENDER_ORIGIN);
regs->isp_ctl = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_CTL);
regs->isp_aa = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_AA);
regs->event_pixel_pds_info = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_EVENT_PIXEL_PDS_INFO);
regs->event_pixel_pds_code = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_EVENT_PIXEL_PDS_CODE);
regs->event_pixel_pds_data = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_EVENT_PIXEL_PDS_DATA);
regs->isp_render = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_RENDER);
regs->isp_rgn = *stream_ptr;
stream_ptr++;
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support)) {
regs->frag_screen = *stream_ptr;
stream_ptr++;
}
assert((const uint8_t *)stream_ptr - stream == stream_len);
assert((const uint8_t *)stream_ptr - stream == main_stream_len);
}

View file

@ -32,7 +32,6 @@
#include "fw-api/pvr_rogue_fwif.h"
#include "fw-api/pvr_rogue_fwif_rf.h"
#include "pvr_csb.h"
#include "pvr_device_info.h"
#include "pvr_srv.h"
#include "pvr_srv_bridge.h"
@ -139,114 +138,6 @@ void pvr_srv_winsys_compute_ctx_destroy(struct pvr_winsys_compute_ctx *ctx)
vk_free(srv_ws->base.alloc, srv_ctx);
}
static uint32_t
pvr_srv_compute_cmd_stream_load(struct rogue_fwif_cmd_compute *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const struct pvr_device_info *const dev_info)
{
const uint32_t *stream_ptr = (const uint32_t *)stream;
struct rogue_fwif_cdm_regs *const regs = &cmd->regs;
uint32_t main_stream_len =
pvr_csb_unpack((uint64_t *)stream_ptr, KMD_STREAM_HDR).length;
stream_ptr += pvr_cmd_length(KMD_STREAM_HDR);
regs->tpu_border_colour_table = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_TPU_BORDER_COLOUR_TABLE_CDM);
regs->cdm_ctrl_stream_base = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_CDM_CTRL_STREAM_BASE);
regs->cdm_context_state_base_addr = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_CDM_CONTEXT_STATE_BASE);
regs->cdm_resume_pds1 = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_CDM_CONTEXT_PDS1);
if (PVR_HAS_FEATURE(dev_info, compute_morton_capable)) {
regs->cdm_item = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_CDM_ITEM);
}
if (PVR_HAS_FEATURE(dev_info, cluster_grouping)) {
regs->compute_cluster = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_COMPUTE_CLUSTER);
}
if (PVR_HAS_FEATURE(dev_info, tpu_dm_global_registers)) {
regs->tpu_tag_cdm_ctrl = *stream_ptr;
stream_ptr++;
}
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support)) {
cmd->execute_count = *stream_ptr;
stream_ptr++;
}
assert((const uint8_t *)stream_ptr - stream <= stream_len);
assert((const uint8_t *)stream_ptr - stream == main_stream_len);
return main_stream_len;
}
static void pvr_srv_compute_cmd_ext_stream_load(
struct rogue_fwif_cmd_compute *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const uint32_t ext_stream_offset,
const struct pvr_device_info *const dev_info)
{
const uint32_t *ext_stream_ptr =
(const uint32_t *)((uint8_t *)stream + ext_stream_offset);
struct rogue_fwif_cdm_regs *const regs = &cmd->regs;
struct ROGUE_KMD_STREAM_EXTHDR_COMPUTE0 header0;
header0 = pvr_csb_unpack(ext_stream_ptr, KMD_STREAM_EXTHDR_COMPUTE0);
ext_stream_ptr += pvr_cmd_length(KMD_STREAM_EXTHDR_COMPUTE0);
assert(PVR_HAS_QUIRK(dev_info, 49927) == header0.has_brn49927);
if (header0.has_brn49927) {
regs->tpu = *ext_stream_ptr;
ext_stream_ptr += pvr_cmd_length(CR_TPU);
}
assert((const uint8_t *)ext_stream_ptr - stream == stream_len);
}
static void pvr_srv_compute_cmd_init(
const struct pvr_winsys_compute_submit_info *submit_info,
struct rogue_fwif_cmd_compute *cmd,
const struct pvr_device_info *const dev_info)
{
uint32_t ext_stream_offset;
memset(cmd, 0, sizeof(*cmd));
cmd->cmn.frame_num = submit_info->frame_num;
ext_stream_offset =
pvr_srv_compute_cmd_stream_load(cmd,
submit_info->fw_stream,
submit_info->fw_stream_len,
dev_info);
if (ext_stream_offset < submit_info->fw_stream_len) {
pvr_srv_compute_cmd_ext_stream_load(cmd,
submit_info->fw_stream,
submit_info->fw_stream_len,
ext_stream_offset,
dev_info);
}
if (submit_info->flags.prevent_all_overlap)
cmd->flags |= ROGUE_FWIF_COMPUTE_FLAG_PREVENT_ALL_OVERLAP;
if (submit_info->flags.use_single_core)
cmd->flags |= ROGUE_FWIF_COMPUTE_FLAG_SINGLE_CORE;
}
VkResult pvr_srv_winsys_compute_submit(
const struct pvr_winsys_compute_ctx *ctx,
const struct pvr_winsys_compute_submit_info *submit_info,

View file

@ -26,6 +26,7 @@
#include <vulkan/vulkan.h>
struct rogue_fwif_cmd_compute;
struct pvr_device_info;
struct pvr_winsys;
struct pvr_winsys_compute_ctx;
@ -49,4 +50,9 @@ VkResult pvr_srv_winsys_compute_submit(
const struct pvr_device_info *dev_info,
struct vk_sync *signal_sync);
void pvr_srv_compute_cmd_init(
const struct pvr_winsys_compute_submit_info *submit_info,
struct rogue_fwif_cmd_compute *cmd,
const struct pvr_device_info *const dev_info);
#endif /* PVR_SRV_JOB_COMPUTE_H */

View file

@ -21,6 +21,8 @@
* SOFTWARE.
*/
#include "pvr_srv_job_render.h"
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
@ -34,17 +36,18 @@
#include "fw-api/pvr_rogue_fwif.h"
#include "fw-api/pvr_rogue_fwif_rf.h"
#include "pvr_csb.h"
#include "pvr_job_render.h"
#include "pvr_srv.h"
#include "pvr_macros.h"
#include "pvr_srv_bo.h"
#include "pvr_srv_bridge.h"
#include "pvr_srv_job_common.h"
#include "pvr_srv_job_render.h"
#include "pvr_srv_sync.h"
#include "pvr_srv_sync_prim.h"
#include "pvr_srv_sync.h"
#include "pvr_srv.h"
#include "pvr_types.h"
#include "pvr_winsys.h"
#include "util/compiler.h"
#include "util/log.h"
#include "util/macros.h"
@ -163,344 +166,6 @@ void pvr_srv_winsys_free_list_destroy(struct pvr_winsys_free_list *free_list)
vk_free(srv_ws->base.alloc, srv_free_list);
}
static uint64_t pvr_rogue_get_cr_multisamplectl_val(uint32_t samples,
bool y_flip)
{
static const struct {
uint8_t x[8];
uint8_t y[8];
} sample_positions[4] = {
/* 1 sample */
{
.x = { 8 },
.y = { 8 },
},
/* 2 samples */
{
.x = { 12, 4 },
.y = { 12, 4 },
},
/* 4 samples */
{
.x = { 6, 14, 2, 10 },
.y = { 2, 6, 10, 14 },
},
/* 8 samples */
{
.x = { 9, 7, 13, 5, 3, 1, 11, 15 },
.y = { 5, 11, 9, 3, 13, 7, 15, 1 },
},
};
uint64_t multisamplectl;
uint8_t idx;
idx = util_fast_log2(samples);
assert(idx < ARRAY_SIZE(sample_positions));
pvr_csb_pack (&multisamplectl, CR_PPP_MULTISAMPLECTL, value) {
switch (samples) {
case 8:
value.msaa_x7 = sample_positions[idx].x[7];
value.msaa_x6 = sample_positions[idx].x[6];
value.msaa_x5 = sample_positions[idx].x[5];
value.msaa_x4 = sample_positions[idx].x[4];
if (y_flip) {
value.msaa_y7 = 16U - sample_positions[idx].y[7];
value.msaa_y6 = 16U - sample_positions[idx].y[6];
value.msaa_y5 = 16U - sample_positions[idx].y[5];
value.msaa_y4 = 16U - sample_positions[idx].y[4];
} else {
value.msaa_y7 = sample_positions[idx].y[7];
value.msaa_y6 = sample_positions[idx].y[6];
value.msaa_y5 = sample_positions[idx].y[5];
value.msaa_y4 = sample_positions[idx].y[4];
}
FALLTHROUGH;
case 4:
value.msaa_x3 = sample_positions[idx].x[3];
value.msaa_x2 = sample_positions[idx].x[2];
if (y_flip) {
value.msaa_y3 = 16U - sample_positions[idx].y[3];
value.msaa_y2 = 16U - sample_positions[idx].y[2];
} else {
value.msaa_y3 = sample_positions[idx].y[3];
value.msaa_y2 = sample_positions[idx].y[2];
}
FALLTHROUGH;
case 2:
value.msaa_x1 = sample_positions[idx].x[1];
if (y_flip) {
value.msaa_y1 = 16U - sample_positions[idx].y[1];
} else {
value.msaa_y1 = sample_positions[idx].y[1];
}
FALLTHROUGH;
case 1:
value.msaa_x0 = sample_positions[idx].x[0];
if (y_flip) {
value.msaa_y0 = 16U - sample_positions[idx].y[0];
} else {
value.msaa_y0 = sample_positions[idx].y[0];
}
break;
default:
UNREACHABLE("Unsupported number of samples");
}
}
return multisamplectl;
}
static uint32_t
pvr_rogue_get_cr_isp_mtile_size_val(const struct pvr_device_info *dev_info,
const struct pvr_rt_mtile_info *mtile_info,
uint32_t samples)
{
uint32_t samples_per_pixel =
PVR_GET_FEATURE_VALUE(dev_info, isp_samples_per_pixel, 0);
uint32_t isp_mtile_size;
pvr_csb_pack (&isp_mtile_size, CR_ISP_MTILE_SIZE, value) {
value.x = mtile_info->mtile_x1;
value.y = mtile_info->mtile_y1;
if (samples_per_pixel == 1) {
if (samples >= 4)
value.x <<= 1;
if (samples >= 2)
value.y <<= 1;
} else if (samples_per_pixel == 2) {
if (samples >= 8)
value.x <<= 1;
if (samples >= 4)
value.y <<= 1;
} else if (samples_per_pixel == 4) {
if (samples >= 8)
value.y <<= 1;
} else {
assert(!"Unsupported ISP samples per pixel value");
}
}
return isp_mtile_size;
}
static uint32_t pvr_rogue_get_ppp_screen_val(uint32_t width, uint32_t height)
{
uint32_t val;
pvr_csb_pack (&val, CR_PPP_SCREEN, state) {
state.pixxmax = width - 1;
state.pixymax = height - 1;
}
return val;
}
struct pvr_rogue_cr_te {
uint32_t aa;
uint32_t mtile1;
uint32_t mtile2;
uint32_t screen;
uint32_t mtile_stride;
};
static void pvr_rogue_ct_te_init(const struct pvr_device_info *dev_info,
const struct pvr_rt_mtile_info *mtile_info,
uint32_t samples,
struct pvr_rogue_cr_te *const te_regs)
{
uint32_t samples_per_pixel =
PVR_GET_FEATURE_VALUE(dev_info, isp_samples_per_pixel, 0);
pvr_csb_pack (&te_regs->aa, CR_TE_AA, value) {
if (samples_per_pixel == 1) {
if (samples >= 2)
value.y = true;
if (samples >= 4)
value.x = true;
} else if (samples_per_pixel == 2) {
if (samples >= 2)
value.x2 = true;
if (samples >= 4)
value.y = true;
if (samples >= 8)
value.x = true;
} else if (samples_per_pixel == 4) {
if (samples >= 2)
value.x2 = true;
if (samples >= 4)
value.y2 = true;
if (samples >= 8)
value.y = true;
} else {
assert(!"Unsupported ISP samples per pixel value");
}
}
pvr_csb_pack (&te_regs->mtile1, CR_TE_MTILE1, value) {
value.x1 = mtile_info->mtile_x1;
if (!PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format)) {
value.x2 = mtile_info->mtile_x2;
value.x3 = mtile_info->mtile_x3;
}
}
pvr_csb_pack (&te_regs->mtile2, CR_TE_MTILE2, value) {
value.y1 = mtile_info->mtile_y1;
if (!PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format)) {
value.y2 = mtile_info->mtile_y2;
value.y3 = mtile_info->mtile_y3;
}
}
pvr_csb_pack (&te_regs->screen, CR_TE_SCREEN, value) {
value.xmax = mtile_info->x_tile_max;
value.ymax = mtile_info->y_tile_max;
}
te_regs->mtile_stride = mtile_info->mtile_x1 * mtile_info->mtile_y1;
}
VkResult pvr_srv_render_target_dataset_create(
struct pvr_winsys *ws,
const struct pvr_winsys_rt_dataset_create_info *create_info,
const struct pvr_device_info *dev_info,
struct pvr_winsys_rt_dataset **const rt_dataset_out)
{
const pvr_dev_addr_t macrotile_addrs[ROGUE_FWIF_NUM_RTDATAS] = {
[0] = create_info->rt_datas[0].macrotile_array_dev_addr,
[1] = create_info->rt_datas[1].macrotile_array_dev_addr,
};
const pvr_dev_addr_t pm_mlist_addrs[ROGUE_FWIF_NUM_RTDATAS] = {
[0] = create_info->rt_datas[0].pm_mlist_dev_addr,
[1] = create_info->rt_datas[1].pm_mlist_dev_addr,
};
const pvr_dev_addr_t rgn_header_addrs[ROGUE_FWIF_NUM_RTDATAS] = {
[0] = create_info->rt_datas[0].rgn_header_dev_addr,
[1] = create_info->rt_datas[1].rgn_header_dev_addr,
};
struct pvr_srv_winsys *srv_ws = to_pvr_srv_winsys(ws);
struct pvr_srv_winsys_free_list *srv_local_free_list =
to_pvr_srv_winsys_free_list(create_info->local_free_list);
void *free_lists[ROGUE_FW_MAX_FREELISTS] = { NULL };
struct pvr_srv_winsys_rt_dataset *srv_rt_dataset;
void *handles[ROGUE_FWIF_NUM_RTDATAS];
struct pvr_rogue_cr_te rogue_te_regs;
struct pvr_rt_mtile_info mtile_info;
uint32_t isp_mtile_size;
VkResult result;
free_lists[ROGUE_FW_LOCAL_FREELIST] = srv_local_free_list->handle;
if (srv_local_free_list->parent) {
free_lists[ROGUE_FW_GLOBAL_FREELIST] =
srv_local_free_list->parent->handle;
}
srv_rt_dataset = vk_zalloc(ws->alloc,
sizeof(*srv_rt_dataset),
8,
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
if (!srv_rt_dataset)
return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
/* If greater than 1 we'll have to pass in an array. For now just passing in
* the reference.
*/
STATIC_ASSERT(ROGUE_FWIF_NUM_GEOMDATAS == 1);
/* If not 2 the arrays used in the bridge call will require updating. */
STATIC_ASSERT(ROGUE_FWIF_NUM_RTDATAS == 2);
pvr_rt_mtile_info_init(dev_info,
&mtile_info,
create_info->width,
create_info->height,
create_info->samples);
isp_mtile_size = pvr_rogue_get_cr_isp_mtile_size_val(dev_info,
&mtile_info,
create_info->samples);
pvr_rogue_ct_te_init(dev_info,
&mtile_info,
create_info->samples,
&rogue_te_regs);
result = pvr_srv_rgx_create_hwrt_dataset(
ws->render_fd,
pvr_rogue_get_cr_multisamplectl_val(create_info->samples, true),
pvr_rogue_get_cr_multisamplectl_val(create_info->samples, false),
macrotile_addrs,
pm_mlist_addrs,
&create_info->rtc_dev_addr,
rgn_header_addrs,
&create_info->tpc_dev_addr,
&create_info->vheap_table_dev_addr,
free_lists,
create_info->isp_merge_lower_x,
create_info->isp_merge_lower_y,
create_info->isp_merge_scale_x,
create_info->isp_merge_scale_y,
create_info->isp_merge_upper_x,
create_info->isp_merge_upper_y,
isp_mtile_size,
rogue_te_regs.mtile_stride,
pvr_rogue_get_ppp_screen_val(create_info->width, create_info->height),
create_info->rgn_header_size,
rogue_te_regs.aa,
rogue_te_regs.mtile1,
rogue_te_regs.mtile2,
rogue_te_regs.screen,
create_info->tpc_size,
create_info->tpc_stride,
create_info->layers,
handles);
if (result != VK_SUCCESS)
goto err_vk_free_srv_rt_dataset;
srv_rt_dataset->rt_datas[0].handle = handles[0];
srv_rt_dataset->rt_datas[1].handle = handles[1];
for (uint32_t i = 0; i < ARRAY_SIZE(srv_rt_dataset->rt_datas); i++) {
srv_rt_dataset->rt_datas[i].sync_prim = pvr_srv_sync_prim_alloc(srv_ws);
if (!srv_rt_dataset->rt_datas[i].sync_prim)
goto err_srv_sync_prim_free;
}
srv_rt_dataset->base.ws = ws;
*rt_dataset_out = &srv_rt_dataset->base;
return VK_SUCCESS;
err_srv_sync_prim_free:
for (uint32_t i = 0; i < ARRAY_SIZE(srv_rt_dataset->rt_datas); i++) {
pvr_srv_sync_prim_free(srv_ws, srv_rt_dataset->rt_datas[i].sync_prim);
if (srv_rt_dataset->rt_datas[i].handle) {
pvr_srv_rgx_destroy_hwrt_dataset(ws->render_fd,
srv_rt_dataset->rt_datas[i].handle);
}
}
err_vk_free_srv_rt_dataset:
vk_free(ws->alloc, srv_rt_dataset);
return result;
}
void pvr_srv_render_target_dataset_destroy(
struct pvr_winsys_rt_dataset *rt_dataset)
{
@ -635,298 +300,6 @@ void pvr_srv_winsys_render_ctx_destroy(struct pvr_winsys_render_ctx *ctx)
vk_free(srv_ws->base.alloc, srv_ctx);
}
static uint32_t
pvr_srv_geometry_cmd_stream_load(struct rogue_fwif_cmd_ta *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const struct pvr_device_info *const dev_info)
{
const uint32_t *stream_ptr = (const uint32_t *)stream;
struct rogue_fwif_ta_regs *const regs = &cmd->regs;
uint32_t main_stream_len =
pvr_csb_unpack((const uint64_t *)stream_ptr, KMD_STREAM_HDR).length;
stream_ptr += pvr_cmd_length(KMD_STREAM_HDR);
regs->vdm_ctrl_stream_base = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_VDM_CTRL_STREAM_BASE);
regs->tpu_border_colour_table = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_TPU_BORDER_COLOUR_TABLE_VDM);
regs->ppp_ctrl = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_PPP_CTRL);
regs->te_psg = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_TE_PSG);
regs->vdm_context_resume_task0_size = *stream_ptr;
stream_ptr += pvr_cmd_length(VDMCTRL_PDS_STATE0);
regs->view_idx = *stream_ptr;
stream_ptr++;
assert((const uint8_t *)stream_ptr - stream <= stream_len);
assert((const uint8_t *)stream_ptr - stream == main_stream_len);
return main_stream_len;
}
static void pvr_srv_geometry_cmd_ext_stream_load(
struct rogue_fwif_cmd_ta *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const uint32_t ext_stream_offset,
const struct pvr_device_info *const dev_info)
{
const uint32_t *ext_stream_ptr =
(const uint32_t *)((uint8_t *)stream + ext_stream_offset);
struct rogue_fwif_ta_regs *const regs = &cmd->regs;
struct ROGUE_KMD_STREAM_EXTHDR_GEOM0 header0;
header0 = pvr_csb_unpack(ext_stream_ptr, KMD_STREAM_EXTHDR_GEOM0);
ext_stream_ptr += pvr_cmd_length(KMD_STREAM_EXTHDR_GEOM0);
assert(PVR_HAS_QUIRK(dev_info, 49927) == header0.has_brn49927);
if (header0.has_brn49927) {
regs->tpu = *ext_stream_ptr;
ext_stream_ptr += pvr_cmd_length(CR_TPU);
}
assert((const uint8_t *)ext_stream_ptr - stream == stream_len);
}
static void pvr_srv_geometry_cmd_init(
const struct pvr_winsys_render_submit_info *submit_info,
const struct pvr_srv_sync_prim *sync_prim,
struct rogue_fwif_cmd_ta *cmd,
const struct pvr_device_info *const dev_info)
{
const struct pvr_winsys_geometry_state *state = &submit_info->geometry;
uint32_t ext_stream_offset;
memset(cmd, 0, sizeof(*cmd));
cmd->cmd_shared.cmn.frame_num = submit_info->frame_num;
ext_stream_offset = pvr_srv_geometry_cmd_stream_load(cmd,
state->fw_stream,
state->fw_stream_len,
dev_info);
if (ext_stream_offset < state->fw_stream_len) {
pvr_srv_geometry_cmd_ext_stream_load(cmd,
state->fw_stream,
state->fw_stream_len,
ext_stream_offset,
dev_info);
}
if (state->flags.is_first_geometry)
cmd->flags |= ROGUE_FWIF_TAFLAGS_FIRSTKICK;
if (state->flags.is_last_geometry)
cmd->flags |= ROGUE_FWIF_TAFLAGS_LASTKICK;
if (state->flags.use_single_core)
cmd->flags |= ROGUE_FWIF_TAFLAGS_SINGLE_CORE;
cmd->partial_render_ta_3d_fence.ufo_addr.addr =
pvr_srv_sync_prim_get_fw_addr(sync_prim);
cmd->partial_render_ta_3d_fence.value = sync_prim->value;
}
static uint32_t
pvr_srv_fragment_cmd_stream_load(struct rogue_fwif_cmd_3d *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const struct pvr_device_info *const dev_info)
{
const uint32_t *stream_ptr = (const uint32_t *)stream;
struct rogue_fwif_3d_regs *const regs = &cmd->regs;
uint32_t main_stream_len =
pvr_csb_unpack((const uint64_t *)stream_ptr, KMD_STREAM_HDR).length;
stream_ptr += pvr_cmd_length(KMD_STREAM_HDR);
regs->isp_scissor_base = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_SCISSOR_BASE);
regs->isp_dbias_base = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_DBIAS_BASE);
regs->isp_oclqry_base = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_OCLQRY_BASE);
regs->isp_zlsctl = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_ZLSCTL);
regs->isp_zload_store_base = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_ZLOAD_BASE);
regs->isp_stencil_load_store_base = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_STENCIL_LOAD_BASE);
if (PVR_HAS_FEATURE(dev_info, requires_fb_cdc_zls_setup)) {
regs->fb_cdc_zls = *(const uint64_t *)stream_ptr;
stream_ptr += 2U;
}
STATIC_ASSERT(ARRAY_SIZE(regs->pbe_word) == 8U);
STATIC_ASSERT(ARRAY_SIZE(regs->pbe_word[0]) == 3U);
STATIC_ASSERT(sizeof(regs->pbe_word[0][0]) == sizeof(uint64_t));
memcpy(regs->pbe_word, stream_ptr, sizeof(regs->pbe_word));
stream_ptr += 8U * 3U * 2U;
regs->tpu_border_colour_table = *(const uint64_t *)stream_ptr;
stream_ptr += pvr_cmd_length(CR_TPU_BORDER_COLOUR_TABLE_PDM);
STATIC_ASSERT(ARRAY_SIZE(regs->pds_bgnd) == 3U);
STATIC_ASSERT(sizeof(regs->pds_bgnd[0]) == sizeof(uint64_t));
memcpy(regs->pds_bgnd, stream_ptr, sizeof(regs->pds_bgnd));
stream_ptr += 3U * 2U;
STATIC_ASSERT(ARRAY_SIZE(regs->pds_pr_bgnd) == 3U);
STATIC_ASSERT(sizeof(regs->pds_pr_bgnd[0]) == sizeof(uint64_t));
memcpy(regs->pds_pr_bgnd, stream_ptr, sizeof(regs->pds_pr_bgnd));
stream_ptr += 3U * 2U;
STATIC_ASSERT(ARRAY_SIZE(regs->usc_clear_register) == 8U);
STATIC_ASSERT(sizeof(regs->usc_clear_register[0]) == sizeof(uint32_t));
memcpy(regs->usc_clear_register,
stream_ptr,
sizeof(regs->usc_clear_register));
stream_ptr += 8U;
regs->usc_pixel_output_ctrl = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_USC_PIXEL_OUTPUT_CTRL);
regs->isp_bgobjdepth = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_BGOBJDEPTH);
regs->isp_bgobjvals = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_BGOBJVALS);
regs->isp_aa = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_AA);
regs->isp_ctl = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_CTL);
regs->event_pixel_pds_info = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_EVENT_PIXEL_PDS_INFO);
if (PVR_HAS_FEATURE(dev_info, cluster_grouping)) {
regs->pixel_phantom = *stream_ptr;
stream_ptr++;
}
regs->view_idx = *stream_ptr;
stream_ptr++;
regs->event_pixel_pds_data = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_EVENT_PIXEL_PDS_DATA);
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support)) {
regs->isp_oclqry_stride = *stream_ptr;
stream_ptr++;
}
if (PVR_HAS_FEATURE(dev_info, zls_subtile)) {
regs->isp_zls_pixels = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_ZLS_PIXELS);
}
cmd->zls_stride = *stream_ptr;
stream_ptr++;
cmd->sls_stride = *stream_ptr;
stream_ptr++;
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support)) {
cmd->execute_count = *stream_ptr;
stream_ptr++;
}
assert((const uint8_t *)stream_ptr - stream <= stream_len);
assert((const uint8_t *)stream_ptr - stream == main_stream_len);
return main_stream_len;
}
static void pvr_srv_fragment_cmd_ext_stream_load(
struct rogue_fwif_cmd_3d *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const uint32_t ext_stream_offset,
const struct pvr_device_info *const dev_info)
{
const uint32_t *ext_stream_ptr =
(const uint32_t *)((uint8_t *)stream + ext_stream_offset);
struct rogue_fwif_3d_regs *const regs = &cmd->regs;
struct ROGUE_KMD_STREAM_EXTHDR_FRAG0 header0;
header0 = pvr_csb_unpack(ext_stream_ptr, KMD_STREAM_EXTHDR_FRAG0);
ext_stream_ptr += pvr_cmd_length(KMD_STREAM_EXTHDR_FRAG0);
assert(PVR_HAS_QUIRK(dev_info, 49927) == header0.has_brn49927);
if (header0.has_brn49927) {
regs->tpu = *ext_stream_ptr;
ext_stream_ptr += pvr_cmd_length(CR_TPU);
}
assert((const uint8_t *)ext_stream_ptr - stream == stream_len);
}
static void
pvr_srv_fragment_cmd_init(struct rogue_fwif_cmd_3d *cmd,
const struct pvr_winsys_fragment_state *state,
const struct pvr_device_info *dev_info,
uint32_t frame_num)
{
uint32_t ext_stream_offset;
memset(cmd, 0, sizeof(*cmd));
cmd->cmd_shared.cmn.frame_num = frame_num;
ext_stream_offset = pvr_srv_fragment_cmd_stream_load(cmd,
state->fw_stream,
state->fw_stream_len,
dev_info);
if (ext_stream_offset < state->fw_stream_len) {
pvr_srv_fragment_cmd_ext_stream_load(cmd,
state->fw_stream,
state->fw_stream_len,
ext_stream_offset,
dev_info);
}
if (state->flags.has_depth_buffer)
cmd->flags |= ROGUE_FWIF_RENDERFLAGS_DEPTHBUFFER;
if (state->flags.has_stencil_buffer)
cmd->flags |= ROGUE_FWIF_RENDERFLAGS_STENCILBUFFER;
if (state->flags.prevent_cdm_overlap)
cmd->flags |= ROGUE_FWIF_RENDERFLAGS_PREVENT_CDM_OVERLAP;
if (state->flags.use_single_core)
cmd->flags |= ROGUE_FWIF_RENDERFLAGS_SINGLE_CORE;
if (state->flags.get_vis_results)
cmd->flags |= ROGUE_FWIF_RENDERFLAGS_GETVISRESULTS;
if (state->flags.has_spm_scratch_buffer)
cmd->flags |= ROGUE_FWIF_RENDERFLAGS_SPMSCRATCHBUFFER;
if (state->flags.disable_pixel_merging)
cmd->flags |= ROGUE_FWIF_RENDERFLAGS_DISABLE_PIXELMERGE;
}
VkResult pvr_srv_winsys_render_submit(
const struct pvr_winsys_render_ctx *ctx,
const struct pvr_winsys_render_submit_info *submit_info,

View file

@ -27,8 +27,12 @@
#include <stdint.h>
#include <vulkan/vulkan.h>
struct rogue_fwif_cmd_3d;
struct rogue_fwif_cmd_ta;
struct pvr_device_info;
struct pvr_srv_sync_prim;
struct pvr_winsys;
struct pvr_winsys_fragment_state;
struct pvr_winsys_free_list;
struct pvr_winsys_render_ctx;
struct pvr_winsys_render_ctx_create_info;
@ -74,4 +78,21 @@ VkResult pvr_srv_winsys_render_submit(
struct vk_sync *signal_sync_geom,
struct vk_sync *signal_sync_frag);
VkResult pvr_srv_render_target_dataset_create(
struct pvr_winsys *ws,
const struct pvr_winsys_rt_dataset_create_info *create_info,
const struct pvr_device_info *dev_info,
struct pvr_winsys_rt_dataset **const rt_dataset_out);
void pvr_srv_fragment_cmd_init(struct rogue_fwif_cmd_3d *cmd,
const struct pvr_winsys_fragment_state *state,
const struct pvr_device_info *dev_info,
uint32_t frame_num);
void pvr_srv_geometry_cmd_init(
const struct pvr_winsys_render_submit_info *submit_info,
const struct pvr_srv_sync_prim *sync_prim,
struct rogue_fwif_cmd_ta *cmd,
const struct pvr_device_info *const dev_info);
#endif /* PVR_SRV_JOB_RENDER_H */

View file

@ -31,7 +31,6 @@
#include "fw-api/pvr_rogue_fwif.h"
#include "fw-api/pvr_rogue_fwif_rf.h"
#include "pvr_csb.h"
#include "pvr_device_info.h"
#include "pvr_srv.h"
#include "pvr_srv_bridge.h"
@ -133,92 +132,6 @@ void pvr_srv_winsys_transfer_ctx_destroy(struct pvr_winsys_transfer_ctx *ctx)
vk_free(srv_ws->base.alloc, srv_ctx);
}
static void
pvr_srv_transfer_cmd_stream_load(struct rogue_fwif_cmd_transfer *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const struct pvr_device_info *const dev_info)
{
const uint32_t *stream_ptr = (const uint32_t *)stream;
struct rogue_fwif_transfer_regs *const regs = &cmd->regs;
uint32_t main_stream_len =
pvr_csb_unpack((uint64_t *)stream_ptr, KMD_STREAM_HDR).length;
stream_ptr += pvr_cmd_length(KMD_STREAM_HDR);
memcpy(&regs->pds_bgnd0_base, stream_ptr, sizeof(regs->pds_bgnd0_base));
stream_ptr += pvr_cmd_length(CR_PDS_BGRND0_BASE);
memcpy(&regs->pds_bgnd1_base, stream_ptr, sizeof(regs->pds_bgnd1_base));
stream_ptr += pvr_cmd_length(CR_PDS_BGRND1_BASE);
memcpy(&regs->pds_bgnd3_sizeinfo,
stream_ptr,
sizeof(regs->pds_bgnd3_sizeinfo));
stream_ptr += pvr_cmd_length(CR_PDS_BGRND3_SIZEINFO);
memcpy(&regs->isp_mtile_base, stream_ptr, sizeof(regs->isp_mtile_base));
stream_ptr += pvr_cmd_length(CR_ISP_MTILE_BASE);
STATIC_ASSERT(ARRAY_SIZE(regs->pbe_wordx_mrty) == 9U);
STATIC_ASSERT(sizeof(regs->pbe_wordx_mrty[0]) == sizeof(uint64_t));
memcpy(regs->pbe_wordx_mrty, stream_ptr, sizeof(regs->pbe_wordx_mrty));
stream_ptr += 9U * 2U;
regs->isp_bgobjvals = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_BGOBJVALS);
regs->usc_pixel_output_ctrl = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_USC_PIXEL_OUTPUT_CTRL);
regs->usc_clear_register0 = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_USC_CLEAR_REGISTER);
regs->usc_clear_register1 = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_USC_CLEAR_REGISTER);
regs->usc_clear_register2 = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_USC_CLEAR_REGISTER);
regs->usc_clear_register3 = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_USC_CLEAR_REGISTER);
regs->isp_mtile_size = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_MTILE_SIZE);
regs->isp_render_origin = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_RENDER_ORIGIN);
regs->isp_ctl = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_CTL);
regs->isp_aa = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_AA);
regs->event_pixel_pds_info = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_EVENT_PIXEL_PDS_INFO);
regs->event_pixel_pds_code = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_EVENT_PIXEL_PDS_CODE);
regs->event_pixel_pds_data = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_EVENT_PIXEL_PDS_DATA);
regs->isp_render = *stream_ptr;
stream_ptr += pvr_cmd_length(CR_ISP_RENDER);
regs->isp_rgn = *stream_ptr;
stream_ptr++;
if (PVR_HAS_FEATURE(dev_info, gpu_multicore_support)) {
regs->frag_screen = *stream_ptr;
stream_ptr++;
}
assert((const uint8_t *)stream_ptr - stream == stream_len);
assert((const uint8_t *)stream_ptr - stream == main_stream_len);
}
static void pvr_srv_transfer_cmds_init(
const struct pvr_winsys_transfer_submit_info *submit_info,
struct rogue_fwif_cmd_transfer *cmds,

View file

@ -26,6 +26,7 @@
#include <vulkan/vulkan.h>
struct rogue_fwif_cmd_transfer;
struct pvr_device_info;
struct pvr_winsys;
struct pvr_winsys_transfer_ctx;
@ -49,4 +50,10 @@ VkResult pvr_srv_winsys_transfer_submit(
const struct pvr_device_info *dev_info,
struct vk_sync *signal_sync);
void pvr_srv_transfer_cmd_stream_load(
struct rogue_fwif_cmd_transfer *const cmd,
const uint8_t *const stream,
const uint32_t stream_len,
const struct pvr_device_info *const dev_info);
#endif /* PVR_SRV_JOB_TRANSFER_H */