diff --git a/src/imagination/common/pvr_device_info.c b/src/imagination/common/pvr_device_info.c index 1b2dc673919..1734bc3abe6 100644 --- a/src/imagination/common/pvr_device_info.c +++ b/src/imagination/common/pvr_device_info.c @@ -102,6 +102,7 @@ const struct pvr_device_quirks pvr_device_quirks_4_40_2_51 = { .has_brn48492 = true, .has_brn48545 = true, .has_brn49032 = true, + .has_brn49927 = true, .has_brn51025 = true, .has_brn51210 = true, .has_brn51764 = true, diff --git a/src/imagination/common/pvr_device_info.h b/src/imagination/common/pvr_device_info.h index 4416f6787ed..026bfd9fe80 100644 --- a/src/imagination/common/pvr_device_info.h +++ b/src/imagination/common/pvr_device_info.h @@ -331,6 +331,7 @@ struct pvr_device_quirks { bool has_brn48492 : 1; bool has_brn48545 : 1; bool has_brn49032 : 1; + bool has_brn49927 : 1; bool has_brn51025 : 1; bool has_brn51210 : 1; bool has_brn51764 : 1; diff --git a/src/imagination/vulkan/meson.build b/src/imagination/vulkan/meson.build index a85f732afb4..c350b2d2268 100644 --- a/src/imagination/vulkan/meson.build +++ b/src/imagination/vulkan/meson.build @@ -83,6 +83,7 @@ if with_imagination_srv 'winsys/pvrsrvkm/pvr_srv.c', 'winsys/pvrsrvkm/pvr_srv_bo.c', 'winsys/pvrsrvkm/pvr_srv_bridge.c', + 'winsys/pvrsrvkm/pvr_srv_job_common.c', 'winsys/pvrsrvkm/pvr_srv_job_compute.c', 'winsys/pvrsrvkm/pvr_srv_job_render.c', 'winsys/pvrsrvkm/pvr_srv_syncobj.c', diff --git a/src/imagination/vulkan/pvr_job_compute.c b/src/imagination/vulkan/pvr_job_compute.c index 34b55caa61a..3d85993f457 100644 --- a/src/imagination/vulkan/pvr_job_compute.c +++ b/src/imagination/vulkan/pvr_job_compute.c @@ -52,6 +52,12 @@ static void pvr_compute_job_ws_submit_info_init( submit_info->semaphore_count = semaphore_count; submit_info->stage_flags = stage_flags; + pvr_csb_pack (&submit_info->regs.cdm_ctx_state_base_addr, + CR_CDM_CONTEXT_STATE_BASE, + state) { + state.addr = ctx_switch->compute_state_bo->vma->dev_addr; + } + /* Other registers are initialized in pvr_sub_cmd_compute_job_init(). */ pvr_csb_pack (&submit_info->regs.cdm_resume_pds1, CR_CDM_CONTEXT_PDS1, diff --git a/src/imagination/vulkan/pvr_job_context.c b/src/imagination/vulkan/pvr_job_context.c index 9fe128596c3..efb7084cb54 100644 --- a/src/imagination/vulkan/pvr_job_context.c +++ b/src/imagination/vulkan/pvr_job_context.c @@ -973,12 +973,6 @@ static void pvr_compute_ctx_ws_static_state_init( { const struct pvr_compute_ctx_switch *const ctx_switch = &ctx->ctx_switch; - pvr_csb_pack (&static_state->cdm_ctx_state_base_addr, - CR_CDM_CONTEXT_STATE_BASE, - state) { - state.addr = ctx_switch->compute_state_bo->vma->dev_addr; - } - /* CR_CDM_CONTEXT_... use state store program info. */ pvr_csb_pack (&static_state->cdm_ctx_store_pds0, diff --git a/src/imagination/vulkan/winsys/pvr_winsys.h b/src/imagination/vulkan/winsys/pvr_winsys.h index a45fe6064a7..faa9e06240f 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys.h +++ b/src/imagination/vulkan/winsys/pvr_winsys.h @@ -231,8 +231,6 @@ struct pvr_winsys_compute_ctx_create_info { enum pvr_winsys_ctx_priority priority; struct pvr_winsys_compute_ctx_static_state { - uint64_t cdm_ctx_state_base_addr; - uint64_t cdm_ctx_store_pds0; uint64_t cdm_ctx_store_pds0_b; uint32_t cdm_ctx_store_pds1; @@ -266,6 +264,7 @@ struct pvr_winsys_compute_submit_info { uint64_t cdm_item; uint32_t compute_cluster; uint64_t cdm_ctrl_stream_base; + uint64_t cdm_ctx_state_base_addr; uint32_t tpu; uint32_t cdm_resume_pds1; } regs; diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif.h b/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif.h index abcaf181061..0477a5059d2 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif.h +++ b/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif.h @@ -30,9 +30,11 @@ #include "pvr_rogue_fwif_shared.h" -/** Indicates the number of RTDATAs per RTDATASET. */ -#define ROGUE_FWIF_NUM_RTDATAS 2U - +/** + * \name Frag DM command flags. + * Flags supported by the Frag DM command i.e. /ref rogue_fwif_cmd_3d . + */ +/**@{*/ /** Render needs flipped sample positions. */ #define ROGUE_FWIF_RENDERFLAGS_FLIP_SAMPLE_POSITIONS 0x00000001UL /** @@ -76,10 +78,19 @@ /** Disallow compute overlapped with this render. */ #define ROGUE_FWIF_RENDERFLAGS_PREVENT_CDM_OVERLAP 0x04000000UL +/**@}*/ +/* End of \name Frag DM command flags. */ + /** * The host must indicate if this is the first and/or last command to be issued * for the specified task. */ + +/** + * \name Geom DM command flags. + * Flags supported by the Geom DM command i.e. \ref rogue_fwif_cmd_ta . + */ +/**@{*/ #define ROGUE_FWIF_TAFLAGS_FIRSTKICK 0x00000001UL #define ROGUE_FWIF_TAFLAGS_LASTKICK 0x00000002UL #define ROGUE_FWIF_TAFLAGS_FLIP_SAMPLE_POSITIONS 0x00000004UL @@ -89,7 +100,10 @@ /** Enable Tile Region Protection for this TA. */ #define ROGUE_FWIF_TAFLAGS_TRP 0x00000010UL -/** Indicates the particular TA needs to be aborted. */ +/** + * Indicates the particular TA needs to be aborted. + * The scene has been aborted, discard this TA command. + */ #define ROGUE_FWIF_TAFLAGS_TA_ABORT 0x00000100UL #define ROGUE_FWIF_TAFLAGS_SECURE 0x00080000UL @@ -100,11 +114,14 @@ #define ROGUE_FWIF_TAFLAGS_CSRM_MAX_COEFFS 0x00200000UL #define ROGUE_FWIF_TAFLAGS_PHR_TRIGGER 0x02000000UL +/**@}/ + * End of \name Geom DM command flags. */ /* Flags for transfer queue commands. */ #define ROGUE_FWIF_CMDTRANSFER_FLAG_SECURE 0x00000001U /** Use single core in a multi core setup. */ #define ROGUE_FWIF_CMDTRANSFER_SINGLE_CORE 0x00000002U +#define ROGUE_FWIF_CMDTRANSFER_TRP 0x00000004U /* Flags for 2D commands. */ #define ROGUE_FWIF_CMD2D_FLAG_SECURE 0x00000001U @@ -128,8 +145,8 @@ ***********************************************/ /** - * Configuration registers which need to be loaded by the firmware before a TA - * job can be started. + * \brief Configuration registers which need to be loaded by the firmware before + * a TA job can be started. */ struct rogue_fwif_ta_regs { uint64_t vdm_ctrl_stream_base; @@ -137,6 +154,11 @@ struct rogue_fwif_ta_regs { uint32_t ppp_ctrl; uint32_t te_psg; + /* FIXME: HIGH: FIX_HW_BRN_49927 changes the structure's layout, given we + * are supporting Features/ERNs/BRNs at runtime, we need to look into this + * and find a solution to keep layout intact. + */ + /* Available if FIX_HW_BRN_49927 is present. */ uint32_t tpu; uint32_t vdm_context_resume_task0_size; @@ -152,8 +174,12 @@ struct rogue_fwif_ta_regs { }; /** - * Represents a TA command that can be used to tile a whole scene's objects as - * per TA behavior. + * \brief DM command for geometry processing phase of a render/3D operation. + * Represents the command data for a ROGUE_FWIF_CCB_CMD_TYPE_GEOM type client + * CCB command. + * + * The Rogue TA can be used to tile a whole scene's objects as per TA behavior + * on ROGUE. */ struct rogue_fwif_cmd_ta { /** @@ -186,8 +212,8 @@ static_assert( "kernel expects command size be increased to match current TA command size"); /** - * Configuration registers which need to be loaded by the firmware before ISP - * can be started. + * \brief Configuration registers which need to be loaded by the firmware before + * ISP can be started. */ struct rogue_fwif_3d_regs { /** @@ -207,6 +233,11 @@ struct rogue_fwif_3d_regs { uint32_t isp_aa; uint32_t isp_ctl; + /* FIXME: HIGH: FIX_HW_BRN_49927 changes the structure's layout, given we + * are supporting Features/ERNs/BRNs at runtime, we need to look into this + * and find a solution to keep layout intact. + */ + /* Available if FIX_HW_BRN_49927 is present. */ uint32_t tpu; uint32_t event_pixel_pds_info; @@ -249,6 +280,11 @@ struct rogue_fwif_3d_regs { uint64_t pds_pr_bgnd[3U]; }; +/** + * \brief DM command for fragment processing phase of a render/3D operation. + * Represents the command data for a ROGUE_FWIF_CCB_CMD_TYPE_FRAG type client + * CCB command. + */ struct rogue_fwif_cmd_3d { /** * This struct is shared between Client and Firmware. @@ -266,6 +302,12 @@ struct rogue_fwif_cmd_3d { uint32_t zls_stride; /** Stride IN BYTES for S-Buffer in case of RTAs. */ uint32_t sls_stride; + + /* FIXME: HIGH: RGX_FEATURE_GPU_MULTICORE_SUPPORT changes the structure's + * layout. Commenting out for now as it's not supported by 4.V.2.51. + */ + /* Number of tiles to submit to GPU before moving to GPU. */ + /* uint32_t execute_count; */ }; static_assert( @@ -318,9 +360,13 @@ struct rogue_fwif_transfer_regs { */ #define ROGUE_PBE_WORDS_REQUIRED_FOR_TRANSFER 3 /* TQ_MAX_RENDER_TARGETS * PBE_STATE_SIZE */ - uint64_t pbe_wordx_mrty[3 * ROGUE_PBE_WORDS_REQUIRED_FOR_TRANSFER]; + uint64_t pbe_wordx_mrty[3U * ROGUE_PBE_WORDS_REQUIRED_FOR_TRANSFER]; }; +/** + * \brief DM command for TQ/2D operation. Represents the command data for a + * ROGUE_FWIF_CCB_CMD_TYPE_TQ_3D type client CCB command. + */ struct rogue_fwif_cmd_transfer { struct rogue_fwif_cmd_common ALIGN(8) cmn; struct rogue_fwif_transfer_regs ALIGN(8) regs; @@ -362,6 +408,11 @@ static_assert( sizeof(struct rogue_fwif_cmd_2d) <= ROGUE_FWIF_DM_INDEPENDENT_KICK_CMD_SIZE, "kernel expects command size be increased to match current 2D command size"); +/** Command to handle aborts. */ +struct rogue_fwif_cmd_abort { + struct rogue_fwif_cmd_ta_3d_shared ALIGN(8) cmd_shared; +}; + /*********************************************** Host interface structures. ***********************************************/ @@ -386,16 +437,34 @@ struct rogue_fwif_cdm_regs { */ /* uint64_t tpu_tag_cdm_ctrl; */ uint64_t cdm_ctrl_stream_base; + uint64_t cdm_contex_state_base_addr; + /* FIXME: HIGH: FIX_HW_BRN_49927 changes the structure's layout, given we + * are supporting Features/ERNs/BRNs at runtime, we need to look into this + * and find a solution to keep layout intact. + */ + /* Available if FIX_HW_BRN_49927 is present. */ uint32_t tpu; uint32_t cdm_resume_pds1; }; +/** + * \brief DM command for Compute operation. Represents the command data for a + * ROGUE_FWIF_CCB_CMD_TYPE_CDM type client CCB command. + * + * Rouge Compute command. + */ struct rogue_fwif_cmd_compute { struct rogue_fwif_cmd_common ALIGN(8) cmn; struct rogue_fwif_cdm_regs ALIGN(8) regs; uint32_t ALIGN(8) flags; + + /* FIXME: HIGH: RGX_FEATURE_GPU_MULTICORE_SUPPORT changes the structure's + * layout. Commenting out for now as it's not supported by 4.V.2.51. + */ + /* Number of tiles to submit to GPU before moving to GPU. */ + /* uint32_t execute_count; */ }; static_assert( diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif_rf.h b/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif_rf.h index 35da3763eff..e8573e26455 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif_rf.h +++ b/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif_rf.h @@ -29,15 +29,16 @@ #include "pvr_rogue_fwif_shared.h" struct rogue_fwif_rf_regs { - uint64_t cdm_ctrl_stream_base; + union { + uint64_t cdm_cb_base; + uint64_t cdm_ctrl_stream_base; + }; + + uint64_t cdm_cb_queue; + uint64_t cdm_cb; }; -/* Enables the reset framework in the firmware. */ -#define ROGUE_FWIF_RF_FLAG_ENABLE 0x00000001U - struct rogue_fwif_rf_cmd { - uint32_t flags; - /* THIS MUST BE THE LAST MEMBER OF THE CONTAINING STRUCTURE */ struct rogue_fwif_rf_regs ALIGN(8) regs; }; diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif_shared.h b/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif_shared.h index 1a2c771c480..f5d98ca707a 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif_shared.h +++ b/src/imagination/vulkan/winsys/pvrsrvkm/fw-api/pvr_rogue_fwif_shared.h @@ -29,6 +29,12 @@ #define ALIGN(x) __attribute__((aligned(x))) +/** Indicates the number of RTDATAs per RTDATASET. */ +#define ROGUE_FWIF_NUM_RTDATAS 2U +#define ROGUE_FWIF_NUM_GEOMDATAS 1U +#define ROGUE_FWIF_NUM_RTDATA_FREELISTS 2U +#define ROGUE_NUM_GEOM_CORES 1U + /** * Maximum number of UFOs in a CCB command. * The number is based on having 32 sync prims (as originally), plus 32 sync @@ -50,11 +56,6 @@ */ #define ROGUE_FWIF_DM_INDEPENDENT_KICK_CMD_SIZE (1024U) -#define ROGUE_FWIF_PRBUFFER_START (0) -#define ROGUE_FWIF_PRBUFFER_ZSBUFFER (0) -#define ROGUE_FWIF_PRBUFFER_MSAABUFFER (1) -#define ROGUE_FWIF_PRBUFFER_MAXSUPPORTED (2) - struct rogue_fwif_dev_addr { uint32_t addr; }; @@ -64,8 +65,13 @@ struct rogue_fwif_dma_addr { struct rogue_fwif_dev_addr fw_addr; } ALIGN(8); +/** + * \brief Command data for fence & update types Client CCB commands. + */ struct rogue_fwif_ufo { + /** Address to be checked/updated. */ struct rogue_fwif_dev_addr ufo_addr; + /** Value to check-against/update-to. */ uint32_t value; }; @@ -77,6 +83,34 @@ struct rogue_fwif_cleanup_ctl { uint32_t executed_cmds; } ALIGN(8); +#define ROGUE_FWIF_PRBUFFER_START 0U +#define ROGUE_FWIF_PRBUFFER_ZSBUFFER 0U +#define ROGUE_FWIF_PRBUFFER_MSAABUFFER 1U +#define ROGUE_FWIF_PRBUFFER_MAXSUPPORTED 2U + +enum rogue_fwif_prbuffer_state { + ROGUE_FWIF_PRBUFFER_UNBACKED = 0, + ROGUE_FWIF_PRBUFFER_BACKED, + ROGUE_FWIF_PRBUFFER_BACKING_PENDING, + ROGUE_FWIF_PRBUFFER_UNBACKING_PENDING, +}; + +/** + * \brief On-demand Z/S/MSAA buffers. + */ +struct rogue_fwif_prbuffer { + /** Buffer ID. */ + uint32_t buffer_id; + /** Needs on-demand Z/S/MSAA buffer allocation. */ + bool ALIGN(4) on_demand; + /** Z/S/MSAA - Buffer state. */ + enum rogue_fwif_prbuffer_state state; + /** Cleanup state. */ + struct rogue_fwif_cleanup_ctl cleanup_state; + /** Compatibility and other flags. */ + uint32_t pr_buffer_flags; +} ALIGN(8); + /** * Used to share frame numbers across UM-KM-FW, * frame number is set in UM, @@ -150,22 +184,33 @@ struct rogue_fwif_cccb_ctl { #define ROGUE_FW_LOCAL_FREELIST 0U #define ROGUE_FW_GLOBAL_FREELIST 1U -#define ROGUE_FW_FREELIST_TYPE_LAST ROGUE_FW_GLOBAL_FREELIST -#define ROGUE_FW_MAX_FREELISTS (ROGUE_FW_FREELIST_TYPE_LAST + 1U) +#define ROGUE_FW_MAX_FREELISTS (ROGUE_FW_GLOBAL_FREELIST + 1U) +#define ROGUE_FW_MAX_HWFREELISTS 2U +/** + * \brief Geom DM or TA register controls for context switch. + */ struct rogue_fwif_ta_regs_cswitch { + /** The base address of the VDM's context state buffer. */ uint64_t vdm_context_state_base_addr; uint64_t vdm_context_state_resume_addr; + /** The base address of the TA's context state buffer. */ uint64_t ta_context_state_base_addr; struct { + /** VDM context store task 0. */ uint64_t vdm_context_store_task0; + /** VDM context store task 1. */ uint64_t vdm_context_store_task1; + /** VDM context store task 2. */ uint64_t vdm_context_store_task2; /* VDM resume state update controls. */ + /** VDM context resume task 0. */ uint64_t vdm_context_resume_task0; + /** VDM context resume task 1. */ uint64_t vdm_context_resume_task1; + /** VDM context resume task 2. */ uint64_t vdm_context_resume_task2; uint64_t vdm_context_store_task3; @@ -180,7 +225,6 @@ struct rogue_fwif_ta_regs_cswitch { sizeof(struct rogue_fwif_taregisters_cswitch) struct rogue_fwif_cdm_regs_cswitch { - uint64_t cdm_context_state_base_addr; uint64_t cdm_context_pds0; uint64_t cdm_context_pds1; uint64_t cdm_terminate_pds; @@ -192,9 +236,13 @@ struct rogue_fwif_cdm_regs_cswitch { uint64_t cdm_resume_pds0_b; }; +/** + * \brief Render context static register controls for context switch. + */ struct rogue_fwif_static_rendercontext_state { /** Geom registers for ctx switch. */ - struct rogue_fwif_ta_regs_cswitch ALIGN(8) ctx_switch_regs; + struct rogue_fwif_ta_regs_cswitch + ALIGN(8) ctx_switch_geom_regs[ROGUE_NUM_GEOM_CORES]; }; #define ROGUE_FWIF_STATIC_RENDERCONTEXT_SIZE \ @@ -208,27 +256,9 @@ struct rogue_fwif_static_computecontext_state { #define ROGUE_FWIF_STATIC_COMPUTECONTEXT_SIZE \ sizeof(struct rogue_fwif_static_computecontext_state) -enum rogue_fwif_prbuffer_state { - ROGUE_FWIF_PRBUFFER_UNBACKED = 0, - ROGUE_FWIF_PRBUFFER_BACKED, - ROGUE_FWIF_PRBUFFER_BACKING_PENDING, - ROGUE_FWIF_PRBUFFER_UNBACKING_PENDING, -}; - -struct rogue_fwif_prbuffer { - /** Buffer ID. */ - uint32_t buffer_id; - /** Needs On-demand Z/S/MSAA Buffer allocation. */ - bool ALIGN(4) on_demand; - /** Z/S/MSAA -Buffer state. */ - enum rogue_fwif_prbuffer_state state; - /** Cleanup state. */ - struct rogue_fwif_cleanup_ctl cleanup_state; - /** Compatibility and other flags. */ - uint32_t pr_buffer_flags; -} ALIGN(8); - -/* Last reset reason for a context. */ +/** + * /brief Context reset reason. Last reset reason for a reset context. + */ enum rogue_context_reset_reason { /** No reset reason recorded. */ ROGUE_CONTEXT_RESET_REASON_NONE = 0, @@ -242,10 +272,23 @@ enum rogue_context_reset_reason { ROGUE_CONTEXT_RESET_REASON_INNOCENT_OVERRUNING = 4, /** Forced reset to ensure scheduling requirements. */ ROGUE_CONTEXT_RESET_REASON_HARD_CONTEXT_SWITCH = 5, + /** FW page fault (no HWR). */ + ROGUE_CONTEXT_RESET_REASON_FW_PAGEFAULT = 13, + /** FW execution error (GPU reset requested). */ + ROGUE_CONTEXT_RESET_REASON_FW_EXEC_ERR = 14, + /** Host watchdog detected FW error. */ + ROGUE_CONTEXT_RESET_REASON_HOST_WDG_FW_ERR = 15, + /** Geometry DM OOM event is not allowed. */ + ROGUE_CONTEXT_GEOM_OOM_DISABLED = 16, }; +/** + * \brief Context reset data shared with the host. + */ struct rogue_context_reset_reason_data { + /** Reset reason. */ enum rogue_context_reset_reason reset_reason; + /** External Job ID. */ uint32_t reset_ext_job_ref; }; diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c index 8c8ba7c16bc..2d3dbb92deb 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv.c @@ -441,7 +441,7 @@ static bool pvr_is_driver_compatible(int render_fd) assert(strcmp(version->name, "pvr") == 0); - /* Only the 1.14 driver is supported for now. */ + /* Only the 1.17 driver is supported for now. */ if (version->version_major != PVR_SRV_VERSION_MAJ || version->version_minor != PVR_SRV_VERSION_MIN) { vk_errorf(NULL, @@ -470,6 +470,10 @@ struct pvr_winsys *pvr_srv_winsys_create(int master_fd, if (!pvr_is_driver_compatible(render_fd)) return NULL; + result = pvr_srv_init_module(render_fd, PVR_SRVKM_MODULE_TYPE_SERVICES); + if (result != VK_SUCCESS) + return NULL; + result = pvr_srv_connection_create(render_fd, &bvnc); if (result != VK_SUCCESS) return NULL; diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c index 4fe434cee9d..cb0eb5a7dfb 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.c @@ -29,6 +29,7 @@ #include #include +#include "fw-api/pvr_rogue_fwif_shared.h" #include "pvr_private.h" #include "pvr_srv.h" #include "pvr_srv_bridge.h" @@ -70,6 +71,21 @@ static int pvr_srv_bridge_call(int fd, return 0U; } +VkResult pvr_srv_init_module(int fd, enum pvr_srvkm_module_type module) +{ + struct drm_srvkm_init_data init_data = { .init_module = module }; + + int ret = drmIoctl(fd, DRM_IOCTL_SRVKM_INIT, &init_data); + if (unlikely(ret)) { + return vk_errorf(NULL, + VK_ERROR_INITIALIZATION_FAILED, + "DRM_IOCTL_SRVKM_INIT failed, Errno: %s", + strerror(errno)); + } + + return VK_SUCCESS; +} + VkResult pvr_srv_connection_create(int fd, uint64_t *const bvnc_out) { struct pvr_srv_bridge_connect_cmd cmd = { @@ -856,7 +872,6 @@ void pvr_srv_rgx_destroy_compute_context(int fd, void *compute_context) VkResult pvr_srv_rgx_kick_compute2(int fd, void *compute_context, - uint32_t client_cache_op_seq_num, uint32_t client_update_count, void **client_update_ufo_sync_prim_block, uint32_t *client_update_offset, @@ -866,6 +881,9 @@ VkResult pvr_srv_rgx_kick_compute2(int fd, uint32_t cmd_size, uint8_t *cdm_cmd, uint32_t ext_job_ref, + uint32_t sync_pmr_count, + uint32_t *sync_pmr_flags, + void **sync_pmrs, uint32_t num_work_groups, uint32_t num_work_items, uint32_t pdump_flags, @@ -878,18 +896,20 @@ VkResult pvr_srv_rgx_kick_compute2(int fd, .compute_context = compute_context, .client_update_offset = client_update_offset, .client_update_value = client_update_value, + .sync_pmr_flags = sync_pmr_flags, .cdm_cmd = cdm_cmd, .update_fence_name = update_fence_name, .client_update_ufo_sync_prim_block = client_update_ufo_sync_prim_block, + .sync_pmrs = sync_pmrs, .check_fence = check_fence, .update_timeline = update_timeline, - .client_cache_op_seq_num = client_cache_op_seq_num, .client_update_count = client_update_count, .cmd_size = cmd_size, .ext_job_ref = ext_job_ref, .num_work_groups = num_work_groups, .num_work_items = num_work_items, .pdump_flags = pdump_flags, + .sync_pmr_count = sync_pmr_count, }; struct pvr_srv_rgx_kick_cdm2_ret ret = { @@ -918,27 +938,15 @@ VkResult pvr_srv_rgx_kick_compute2(int fd, VkResult pvr_srv_rgx_create_hwrt_dataset(int fd, - pvr_dev_addr_t pm_mlist_dev_addr0, - pvr_dev_addr_t pm_mlist_dev_addr1, - pvr_dev_addr_t tail_ptrs_dev_addr, - pvr_dev_addr_t macrotile_array_dev_addr0, - pvr_dev_addr_t macrotile_array_dev_addr1, - pvr_dev_addr_t rtc_dev_addr, - pvr_dev_addr_t rgn_header_dev_addr0, - pvr_dev_addr_t rgn_header_dev_addr1, - pvr_dev_addr_t vheap_table_dev_add, uint64_t flipped_multi_sample_ctl, uint64_t multi_sample_ctl, - uint64_t rgn_header_size, + const pvr_dev_addr_t *macrotile_array_dev_addrs, + const pvr_dev_addr_t *pm_mlist_dev_addrs, + const pvr_dev_addr_t *rtc_dev_addrs, + const pvr_dev_addr_t *rgn_header_dev_addrs, + const pvr_dev_addr_t *tail_ptrs_dev_addrs, + const pvr_dev_addr_t *vheap_table_dev_adds, void **free_lists, - uint32_t mtile_stride, - uint32_t ppp_screen, - uint32_t te_aa, - uint32_t te_mtile1, - uint32_t te_mtile2, - uint32_t te_screen, - uint32_t tpc_size, - uint32_t tpc_stride, uint32_t isp_merge_lower_x, uint32_t isp_merge_lower_y, uint32_t isp_merge_scale_x, @@ -946,32 +954,33 @@ pvr_srv_rgx_create_hwrt_dataset(int fd, uint32_t isp_merge_upper_x, uint32_t isp_merge_upper_y, uint32_t isp_mtile_size, + uint32_t mtile_stride, + uint32_t ppp_screen, + uint32_t rgn_header_size, + uint32_t te_aa, + uint32_t te_mtile1, + uint32_t te_mtile2, + uint32_t te_screen, + uint32_t tpc_size, + uint32_t tpc_stride, uint16_t max_rts, - void **const hwrt_dataset0_out, - void **const hwrt_dataset1_out) + void **hwrt_dataset_out) { + /* Note that hwrt_dataset_out is passed in the cmd struct which the kernel + * writes to. There's also a hwrt_dataset in the ret struct but we're not + * going to use it since it's the same. + */ struct pvr_srv_rgx_create_hwrt_dataset_cmd cmd = { - .pm_mlist_dev_addr0 = pm_mlist_dev_addr0, - .pm_mlist_dev_addr1 = pm_mlist_dev_addr1, - .tail_ptrs_dev_addr = tail_ptrs_dev_addr, - .macrotile_array_dev_addr0 = macrotile_array_dev_addr0, - .macrotile_array_dev_addr1 = macrotile_array_dev_addr1, - .rtc_dev_addr = rtc_dev_addr, - .rgn_header_dev_addr0 = rgn_header_dev_addr0, - .rgn_header_dev_addr1 = rgn_header_dev_addr1, - .vheap_table_dev_add = vheap_table_dev_add, .flipped_multi_sample_ctl = flipped_multi_sample_ctl, .multi_sample_ctl = multi_sample_ctl, - .rgn_header_size = rgn_header_size, + .macrotile_array_dev_addrs = macrotile_array_dev_addrs, + .pm_mlist_dev_addrs = pm_mlist_dev_addrs, + .rtc_dev_addrs = rtc_dev_addrs, + .rgn_header_dev_addrs = rgn_header_dev_addrs, + .tail_ptrs_dev_addrs = tail_ptrs_dev_addrs, + .vheap_table_dev_adds = vheap_table_dev_adds, + .hwrt_dataset = hwrt_dataset_out, .free_lists = free_lists, - .mtile_stride = mtile_stride, - .ppp_screen = ppp_screen, - .te_aa = te_aa, - .te_mtile1 = te_mtile1, - .te_mtile2 = te_mtile2, - .te_screen = te_screen, - .tpc_size = tpc_size, - .tpc_stride = tpc_stride, .isp_merge_lower_x = isp_merge_lower_x, .isp_merge_lower_y = isp_merge_lower_y, .isp_merge_scale_x = isp_merge_scale_x, @@ -979,6 +988,15 @@ pvr_srv_rgx_create_hwrt_dataset(int fd, .isp_merge_upper_x = isp_merge_upper_x, .isp_merge_upper_y = isp_merge_upper_y, .isp_mtile_size = isp_mtile_size, + .mtile_stride = mtile_stride, + .ppp_screen = ppp_screen, + .rgn_header_size = rgn_header_size, + .te_aa = te_aa, + .te_mtile1 = te_mtile1, + .te_mtile2 = te_mtile2, + .te_screen = te_screen, + .tpc_size = tpc_size, + .tpc_stride = tpc_stride, .max_rts = max_rts, }; @@ -1001,8 +1019,9 @@ pvr_srv_rgx_create_hwrt_dataset(int fd, ret); } - *hwrt_dataset0_out = ret.hwrt_dataset0; - *hwrt_dataset1_out = ret.hwrt_dataset1; + VG(VALGRIND_MAKE_MEM_DEFINED(cmd.hwrt_dataset, + sizeof(*cmd.hwrt_dataset) * + ROGUE_FWIF_NUM_RTDATAS)); return VK_SUCCESS; } @@ -1121,6 +1140,7 @@ VkResult pvr_srv_rgx_create_render_context(int fd, uint32_t priority, pvr_dev_addr_t vdm_callstack_addr, + uint32_t call_stack_depth, uint32_t reset_framework_cmd_size, uint8_t *reset_framework_cmd, void *priv_data, @@ -1136,6 +1156,7 @@ pvr_srv_rgx_create_render_context(int fd, struct pvr_srv_rgx_create_render_context_cmd cmd = { .priority = priority, .vdm_callstack_addr = vdm_callstack_addr, + .call_stack_depth = call_stack_depth, .reset_framework_cmd_size = reset_framework_cmd_size, .reset_framework_cmd = reset_framework_cmd, .priv_data = priv_data, @@ -1200,7 +1221,6 @@ void pvr_srv_rgx_destroy_render_context(int fd, void *render_context) VkResult pvr_srv_rgx_kick_render2(int fd, void *render_ctx, - uint32_t client_cache_op_seq_num, uint32_t client_geom_fence_count, void **client_geom_fence_sync_prim_block, uint32_t *client_geom_fence_sync_offset, @@ -1282,7 +1302,6 @@ VkResult pvr_srv_rgx_kick_render2(int fd, .cmd_3d_size = cmd_frag_size, .cmd_3d_pr_size = cmd_frag_pr_size, .client_3d_update_count = client_frag_update_count, - .client_cache_op_seq_num = client_cache_op_seq_num, .client_ta_fence_count = client_geom_fence_count, .client_ta_update_count = client_geom_update_count, .ext_job_ref = ext_job_ref, diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h index 3ea2a4b8e5e..59b5f57b879 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_bridge.h @@ -67,7 +67,7 @@ #define PVR_SRV_BRIDGE_DMABUF 11UL #define PVR_SRV_BRIDGE_DMABUF_PHYSMEMIMPORTDMABUF 0UL -#define PVR_SRV_BRIDGE_DMABUF_PHYSMEMEXPORTDMABUF 1UL +#define PVR_SRV_BRIDGE_DMABUF_PHYSMEMEXPORTDMABUF 2UL #define PVR_SRV_BRIDGE_RGXCMP 129UL @@ -91,11 +91,14 @@ /* DRM command numbers, relative to DRM_COMMAND_BASE. * These defines must be prefixed with "DRM_". */ -#define DRM_SRVKM_CMD 0U /* Used for Services ioctls */ +#define DRM_SRVKM_CMD 0U /* PVR Services command. */ +#define DRM_SRVKM_INIT 5U /* PVR Services Render Device Init command. */ /* These defines must be prefixed with "DRM_IOCTL_". */ #define DRM_IOCTL_SRVKM_CMD \ DRM_IOWR(DRM_COMMAND_BASE + DRM_SRVKM_CMD, struct drm_srvkm_cmd) +#define DRM_IOCTL_SRVKM_INIT \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_SRVKM_INIT, struct drm_srvkm_init_data) /****************************************************************************** Misc defines @@ -111,13 +114,13 @@ SUPPORT_BUFFER_SYNC_SET_OFFSET | OPTIONS_BIT31) #define PVR_SRV_VERSION_MAJ 1U -#define PVR_SRV_VERSION_MIN 14U +#define PVR_SRV_VERSION_MIN 17U #define PVR_SRV_VERSION \ (((uint32_t)((uint32_t)(PVR_SRV_VERSION_MAJ)&0xFFFFU) << 16U) | \ (((PVR_SRV_VERSION_MIN)&0xFFFFU) << 0U)) -#define PVR_SRV_VERSION_BUILD 5843584 +#define PVR_SRV_VERSION_BUILD 6210866 /*! This flags gets set if the client is 64 Bit compatible. */ #define PVR_SRV_FLAGS_CLIENT_64BIT_COMPAT BITFIELD_BIT(5U) @@ -352,6 +355,7 @@ struct pvr_srv_physmem_new_ram_backed_locked_pmr_cmd { struct pvr_srv_physmem_new_ram_backed_locked_pmr_ret { void *pmr; enum pvr_srv_error error; + uint64_t out_flags; } PACKED; /****************************************************************************** @@ -500,18 +504,20 @@ struct pvr_srv_rgx_kick_cdm2_cmd { void *compute_context; uint32_t *client_update_offset; uint32_t *client_update_value; + uint32_t *sync_pmr_flags; uint8_t *cdm_cmd; char *update_fence_name; void **client_update_ufo_sync_prim_block; + void **sync_pmrs; int32_t check_fence; int32_t update_timeline; - uint32_t client_cache_op_seq_num; uint32_t client_update_count; uint32_t cmd_size; uint32_t ext_job_ref; uint32_t num_work_groups; uint32_t num_work_items; uint32_t pdump_flags; + uint32_t sync_pmr_count; } PACKED; struct pvr_srv_rgx_kick_cdm2_ret { @@ -524,27 +530,24 @@ struct pvr_srv_rgx_kick_cdm2_ret { ******************************************************************************/ struct pvr_srv_rgx_create_hwrt_dataset_cmd { - pvr_dev_addr_t pm_mlist_dev_addr0; - pvr_dev_addr_t pm_mlist_dev_addr1; - pvr_dev_addr_t tail_ptrs_dev_addr; - pvr_dev_addr_t macrotile_array_dev_addr0; - pvr_dev_addr_t macrotile_array_dev_addr1; - pvr_dev_addr_t rtc_dev_addr; - pvr_dev_addr_t rgn_header_dev_addr0; - pvr_dev_addr_t rgn_header_dev_addr1; - pvr_dev_addr_t vheap_table_dev_add; uint64_t flipped_multi_sample_ctl; uint64_t multi_sample_ctl; - uint64_t rgn_header_size; + /* ROGUE_FWIF_NUM_RTDATAS sized array. */ + const pvr_dev_addr_t *macrotile_array_dev_addrs; + /* ROGUE_FWIF_NUM_RTDATAS sized array. */ + const pvr_dev_addr_t *pm_mlist_dev_addrs; + /* ROGUE_FWIF_NUM_GEOMDATAS sized array. */ + const pvr_dev_addr_t *rtc_dev_addrs; + /* ROGUE_FWIF_NUM_RTDATAS sized array. */ + const pvr_dev_addr_t *rgn_header_dev_addrs; + /* ROGUE_FWIF_NUM_GEOMDATAS sized array. */ + const pvr_dev_addr_t *tail_ptrs_dev_addrs; + /* ROGUE_FWIF_NUM_GEOMDATAS sized array. */ + const pvr_dev_addr_t *vheap_table_dev_adds; + /* ROGUE_FWIF_NUM_RTDATAS sized array of handles. */ + void **hwrt_dataset; + /* ROGUE_FW_MAX_FREELISTS size array of handles. */ void **free_lists; - uint32_t mtile_stride; - uint32_t ppp_screen; - uint32_t te_aa; - uint32_t te_mtile1; - uint32_t te_mtile2; - uint32_t te_screen; - uint32_t tpc_size; - uint32_t tpc_stride; uint32_t isp_merge_lower_x; uint32_t isp_merge_lower_y; uint32_t isp_merge_scale_x; @@ -552,12 +555,21 @@ struct pvr_srv_rgx_create_hwrt_dataset_cmd { uint32_t isp_merge_upper_x; uint32_t isp_merge_upper_y; uint32_t isp_mtile_size; + uint32_t mtile_stride; + uint32_t ppp_screen; + uint32_t rgn_header_size; + uint32_t te_aa; + uint32_t te_mtile1; + uint32_t te_mtile2; + uint32_t te_screen; + uint32_t tpc_size; + uint32_t tpc_stride; uint16_t max_rts; } PACKED; struct pvr_srv_rgx_create_hwrt_dataset_ret { - void *hwrt_dataset0; - void *hwrt_dataset1; + /* ROGUE_FWIF_NUM_RTDATAS sized array of handles. */ + void **hwrt_dataset; enum pvr_srv_error error; } PACKED; @@ -629,6 +641,7 @@ struct pvr_srv_rgx_create_render_context_cmd { #define RGX_CONTEXT_PRIORITY_LOW 0U uint32_t priority; uint32_t static_render_context_state_size; + uint32_t call_stack_depth; } PACKED; struct pvr_srv_rgx_create_render_context_ret { @@ -686,16 +699,15 @@ struct pvr_srv_rgx_kick_ta3d2_cmd { uint32_t cmd_3d_size; uint32_t cmd_3d_pr_size; uint32_t client_3d_update_count; - uint32_t client_cache_op_seq_num; uint32_t client_ta_fence_count; uint32_t client_ta_update_count; uint32_t ext_job_ref; - uint32_t client_pr_fence_ufo_sync_offset; - uint32_t client_pr_fence_value; uint32_t num_draw_calls; uint32_t num_indices; uint32_t num_mrts; uint32_t pdump_flags; + uint32_t client_pr_fence_ufo_sync_offset; + uint32_t client_pr_fence_value; uint32_t render_target_size; uint32_t sync_pmr_count; uint32_t cmd_ta_size; @@ -708,9 +720,10 @@ struct pvr_srv_rgx_kick_ta3d2_ret { } PACKED; /****************************************************************************** - Ioctl structure to pass cmd and ret structures + Ioctl structures ******************************************************************************/ +/* Ioctl to pass cmd and ret structures. */ struct drm_srvkm_cmd { uint32_t bridge_id; uint32_t bridge_func_id; @@ -720,8 +733,30 @@ struct drm_srvkm_cmd { uint32_t out_data_size; }; +/* Ioctl to initialize a module. */ +struct drm_srvkm_init_data { +#define PVR_SRVKM_SERVICES_INIT 1U +#define PVR_SRVKM_SYNC_INIT 2U + uint32_t init_module; +}; + /****************************************************************************** - Bridge function prototype + DRM helper enum + ******************************************************************************/ + +enum pvr_srvkm_module_type { + PVR_SRVKM_MODULE_TYPE_SERVICES = PVR_SRVKM_SERVICES_INIT, + PVR_SRVKM_MODULE_TYPE_SYNC = PVR_SRVKM_SYNC_INIT, +}; + +/****************************************************************************** + Ioctl function prototypes + ******************************************************************************/ + +VkResult pvr_srv_init_module(int fd, enum pvr_srvkm_module_type module); + +/****************************************************************************** + Bridge function prototypes ******************************************************************************/ VkResult pvr_srv_connection_create(int fd, uint64_t *const bvnc_out); @@ -825,7 +860,6 @@ void pvr_srv_rgx_destroy_compute_context(int fd, void *compute_context); VkResult pvr_srv_rgx_kick_compute2(int fd, void *compute_context, - uint32_t client_cache_op_seq_num, uint32_t client_update_count, void **client_update_ufo_sync_prim_block, uint32_t *client_update_offset, @@ -835,6 +869,9 @@ VkResult pvr_srv_rgx_kick_compute2(int fd, uint32_t cmd_size, uint8_t *cdm_cmd, uint32_t ext_job_ref, + uint32_t sync_pmr_count, + uint32_t *sync_pmr_flags, + void **sync_pmrs, uint32_t num_work_groups, uint32_t num_work_items, uint32_t pdump_flags, @@ -844,27 +881,15 @@ VkResult pvr_srv_rgx_kick_compute2(int fd, VkResult pvr_srv_rgx_create_hwrt_dataset(int fd, - pvr_dev_addr_t pm_mlist_dev_addr0, - pvr_dev_addr_t pm_mlist_dev_addr1, - pvr_dev_addr_t tail_ptrs_dev_addr, - pvr_dev_addr_t macrotile_array_dev_addr0, - pvr_dev_addr_t macrotile_array_dev_addr1, - pvr_dev_addr_t rtc_dev_addr, - pvr_dev_addr_t rgn_header_dev_addr0, - pvr_dev_addr_t rgn_header_dev_addr1, - pvr_dev_addr_t vheap_table_dev_add, uint64_t flipped_multi_sample_ctl, uint64_t multi_sample_ctl, - uint64_t rgn_header_size, + const pvr_dev_addr_t *macrotile_array_dev_addrs, + const pvr_dev_addr_t *pm_mlist_dev_addrs, + const pvr_dev_addr_t *rtc_dev_addrs, + const pvr_dev_addr_t *rgn_header_dev_addrs, + const pvr_dev_addr_t *tail_ptrs_dev_addrs, + const pvr_dev_addr_t *vheap_table_dev_adds, void **free_lists, - uint32_t mtile_stride, - uint32_t ppp_screen, - uint32_t te_aa, - uint32_t te_mtile1, - uint32_t te_mtile2, - uint32_t te_screen, - uint32_t tpc_size, - uint32_t tpc_stride, uint32_t isp_merge_lower_x, uint32_t isp_merge_lower_y, uint32_t isp_merge_scale_x, @@ -872,9 +897,17 @@ pvr_srv_rgx_create_hwrt_dataset(int fd, uint32_t isp_merge_upper_x, uint32_t isp_merge_upper_y, uint32_t isp_mtile_size, + uint32_t mtile_stride, + uint32_t ppp_screen, + uint32_t rgn_header_size, + uint32_t te_aa, + uint32_t te_mtile1, + uint32_t te_mtile2, + uint32_t te_screen, + uint32_t tpc_size, + uint32_t tpc_stride, uint16_t max_rts, - void **const hwrt_dataset0_out, - void **const hwrt_dataset1_out); + void **hwrt_dataset_out); void pvr_srv_rgx_destroy_hwrt_dataset(int fd, void *hwrt_dataset); @@ -897,6 +930,7 @@ VkResult pvr_srv_rgx_create_render_context(int fd, uint32_t priority, pvr_dev_addr_t vdm_callstack_addr, + uint32_t call_stack_depth, uint32_t reset_framework_cmd_size, uint8_t *reset_framework_cmd, void *priv_data, @@ -913,7 +947,6 @@ void pvr_srv_rgx_destroy_render_context(int fd, void *render_context); VkResult pvr_srv_rgx_kick_render2(int fd, void *render_ctx, - uint32_t client_cache_op_seq_num, uint32_t client_geom_fence_count, void **client_geom_fence_sync_prim_block, uint32_t *client_geom_fence_sync_offset, diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_common.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_common.c new file mode 100644 index 00000000000..d75585c060a --- /dev/null +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_common.c @@ -0,0 +1,67 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#include "pvr_srv_bridge.h" +#include "pvr_srv_job_common.h" +#include "vk_log.h" + +VkResult pvr_srv_create_timeline(int render_fd, int *const fd_out) +{ + const char *render_path; + VkResult result; + int fd; + + render_path = drmGetRenderDeviceNameFromFd(render_fd); + if (!render_path) { + return vk_errorf(NULL, + VK_ERROR_UNKNOWN, + "Could not get render path from fd."); + } + + fd = open(render_path, O_CLOEXEC | O_RDWR); + drmFree((void *)render_path); + if (fd == -1) { + return vk_errorf(NULL, + VK_ERROR_UNKNOWN, + "Could not create timeline fd, errno: %s", + strerror(errno)); + } + + result = pvr_srv_init_module(fd, PVR_SRVKM_MODULE_TYPE_SYNC); + if (result != VK_SUCCESS) { + close(fd); + return result; + } + + *fd_out = fd; + + return VK_SUCCESS; +} diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_common.h b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_common.h index 71a5755d6db..65d0581b7f4 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_common.h +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_common.h @@ -30,7 +30,7 @@ #include "pvr_winsys.h" #include "util/macros.h" -#define PVR_SRV_SYNC_DEV_PATH "/dev/pvr_sync" +#include static inline uint32_t pvr_srv_from_winsys_priority(enum pvr_winsys_ctx_priority priority) @@ -47,4 +47,6 @@ pvr_srv_from_winsys_priority(enum pvr_winsys_ctx_priority priority) } } +VkResult pvr_srv_create_timeline(int render_fd, int *const fd_out); + #endif /* PVR_SRV_JOB_COMMON_H */ diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_compute.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_compute.c index b6fd8e0533c..013d011f189 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_compute.c +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_compute.c @@ -59,9 +59,6 @@ VkResult pvr_srv_winsys_compute_ctx_create( { struct rogue_fwif_static_computecontext_state static_state = { .ctx_switch_regs = { - .cdm_context_state_base_addr = - create_info->static_state.cdm_ctx_state_base_addr, - .cdm_context_pds0 = create_info->static_state.cdm_ctx_store_pds0, .cdm_context_pds0_b = create_info->static_state.cdm_ctx_store_pds0_b, @@ -76,9 +73,7 @@ VkResult pvr_srv_winsys_compute_ctx_create( }, }; - struct rogue_fwif_rf_cmd reset_cmd = { - .flags = 0U, - }; + struct rogue_fwif_rf_cmd reset_cmd = { 0 }; struct pvr_srv_winsys *srv_ws = to_pvr_srv_winsys(ws); struct pvr_srv_winsys_compute_ctx *srv_ctx; @@ -91,8 +86,8 @@ VkResult pvr_srv_winsys_compute_ctx_create( if (!srv_ctx) return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY); - srv_ctx->timeline = open(PVR_SRV_SYNC_DEV_PATH, O_CLOEXEC | O_RDWR); - if (srv_ctx->timeline < 0) + result = pvr_srv_create_timeline(srv_ws->render_fd, &srv_ctx->timeline); + if (result != VK_SUCCESS) goto err_free_srv_ctx; result = pvr_srv_rgx_create_compute_context( @@ -151,6 +146,8 @@ static void pvr_srv_compute_cmd_init( fw_regs->cdm_item = submit_info->regs.cdm_item; fw_regs->compute_cluster = submit_info->regs.compute_cluster; fw_regs->cdm_ctrl_stream_base = submit_info->regs.cdm_ctrl_stream_base; + fw_regs->cdm_contex_state_base_addr = + submit_info->regs.cdm_ctx_state_base_addr; fw_regs->tpu = submit_info->regs.tpu; fw_regs->cdm_resume_pds1 = submit_info->regs.cdm_resume_pds1; @@ -207,8 +204,6 @@ VkResult pvr_srv_winsys_compute_submit( do { result = pvr_srv_rgx_kick_compute2(srv_ws->render_fd, srv_ctx->handle, - /* No support cache operations. */ - 0U, 0U, NULL, NULL, @@ -218,6 +213,9 @@ VkResult pvr_srv_winsys_compute_submit( sizeof(compute_cmd), (uint8_t *)&compute_cmd, submit_info->job_num, + 0, + NULL, + NULL, 0U, 0U, 0U, diff --git a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_render.c b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_render.c index 2a40b62aef7..5493b8babb4 100644 --- a/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_render.c +++ b/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_job_render.c @@ -161,11 +161,25 @@ VkResult pvr_srv_render_target_dataset_create( const struct pvr_winsys_rt_dataset_create_info *create_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]; VkResult result; free_lists[ROGUE_FW_LOCAL_FREELIST] = srv_local_free_list->handle; @@ -182,29 +196,24 @@ VkResult pvr_srv_render_target_dataset_create( 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); + result = pvr_srv_rgx_create_hwrt_dataset( srv_ws->render_fd, - create_info->rt_datas[0].pm_mlist_dev_addr, - create_info->rt_datas[1].pm_mlist_dev_addr, - create_info->tpc_dev_addr, - create_info->rt_datas[0].macrotile_array_dev_addr, - create_info->rt_datas[1].macrotile_array_dev_addr, - create_info->rtc_dev_addr, - create_info->rt_datas[0].rgn_header_dev_addr, - create_info->rt_datas[1].rgn_header_dev_addr, - create_info->vheap_table_dev_addr, create_info->ppp_multi_sample_ctl_y_flipped, create_info->ppp_multi_sample_ctl, - create_info->rgn_header_size, + 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->mtile_stride, - create_info->ppp_screen, - create_info->te_aa, - create_info->te_mtile1, - create_info->te_mtile2, - create_info->te_screen, - create_info->tpc_size, - create_info->tpc_stride, create_info->isp_merge_lower_x, create_info->isp_merge_lower_y, create_info->isp_merge_scale_x, @@ -212,12 +221,23 @@ VkResult pvr_srv_render_target_dataset_create( create_info->isp_merge_upper_x, create_info->isp_merge_upper_y, create_info->isp_mtile_size, + create_info->mtile_stride, + create_info->ppp_screen, + create_info->rgn_header_size, + create_info->te_aa, + create_info->te_mtile1, + create_info->te_mtile2, + create_info->te_screen, + create_info->tpc_size, + create_info->tpc_stride, create_info->max_rts, - &srv_rt_dataset->rt_datas[0].handle, - &srv_rt_dataset->rt_datas[1].handle); + 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) @@ -271,7 +291,10 @@ static void pvr_srv_render_ctx_fw_static_state_init( { 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_regs; + struct rogue_fwif_ta_regs_cswitch *regs = + &static_state->ctx_switch_geom_regs[0]; + + STATIC_ASSERT(ARRAY_SIZE(static_state->ctx_switch_geom_regs) == 1); memset(static_state, 0, sizeof(*static_state)); @@ -303,12 +326,11 @@ VkResult pvr_srv_winsys_render_ctx_create( struct pvr_winsys_render_ctx **const ctx_out) { struct pvr_srv_winsys *srv_ws = to_pvr_srv_winsys(ws); - struct rogue_fwif_rf_cmd reset_cmd = { - .flags = 0, - }; + struct rogue_fwif_rf_cmd reset_cmd = { 0 }; struct rogue_fwif_static_rendercontext_state static_state; struct pvr_srv_winsys_render_ctx *srv_ctx; + const uint32_t call_stack_depth = 1U; VkResult result; srv_ctx = vk_zalloc(srv_ws->alloc, @@ -318,12 +340,12 @@ VkResult pvr_srv_winsys_render_ctx_create( if (!srv_ctx) return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY); - srv_ctx->timeline_geom = open(PVR_SRV_SYNC_DEV_PATH, O_CLOEXEC | O_RDWR); - if (srv_ctx->timeline_geom < 0) + result = pvr_srv_create_timeline(srv_ws->render_fd, &srv_ctx->timeline_geom); + if (result != VK_SUCCESS) goto err_free_srv_ctx; - srv_ctx->timeline_frag = open(PVR_SRV_SYNC_DEV_PATH, O_CLOEXEC | O_RDWR); - if (srv_ctx->timeline_frag < 0) + result = pvr_srv_create_timeline(srv_ws->render_fd, &srv_ctx->timeline_frag); + if (result != VK_SUCCESS) goto err_close_timeline_geom; pvr_srv_render_ctx_fw_static_state_init(create_info, &static_state); @@ -332,6 +354,7 @@ VkResult pvr_srv_winsys_render_ctx_create( srv_ws->render_fd, pvr_srv_from_winsys_priority(create_info->priority), create_info->vdm_callstack_addr, + call_stack_depth, sizeof(reset_cmd) - sizeof(reset_cmd.regs), (uint8_t *)&reset_cmd, srv_ws->server_memctx_data, @@ -609,7 +632,6 @@ VkResult pvr_srv_winsys_render_submit( /* Currently no support for cache operations. */ 0, - 0, NULL, NULL, NULL,