1 /* 2 * Copyright © 2022 Imagination Technologies Ltd. 3 * 4 * Based on radv_radeon_winsys.h which is: 5 * Copyright © 2016 Red Hat. 6 * Copyright © 2016 Bas Nieuwenhuizen 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * of this software and associated documentation files (the "Software"), to deal 10 * in the Software without restriction, including without limitation the rights 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * copies of the Software, and to permit persons to whom the Software is 13 * furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the next 16 * paragraph) shall be included in all copies or substantial portions of the 17 * Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 * SOFTWARE. 26 */ 27 28 #ifndef PVR_WINSYS_H 29 #define PVR_WINSYS_H 30 31 #include <pthread.h> 32 #include <stdbool.h> 33 #include <stdint.h> 34 #include <vulkan/vulkan.h> 35 36 #include "hwdef/rogue_hw_defs.h" 37 #include "pvr_limits.h" 38 #include "pvr_rogue_fw.h" 39 #include "pvr_types.h" 40 #include "util/macros.h" 41 #include "util/vma.h" 42 #include "vk_sync.h" 43 44 struct pvr_device_info; 45 struct pvr_device_runtime_info; 46 47 struct pvr_winsys_heaps { 48 struct pvr_winsys_heap *general_heap; 49 struct pvr_winsys_heap *pds_heap; 50 struct pvr_winsys_heap *rgn_hdr_heap; 51 struct pvr_winsys_heap *transfer_3d_heap; 52 struct pvr_winsys_heap *usc_heap; 53 struct pvr_winsys_heap *vis_test_heap; 54 }; 55 56 struct pvr_winsys_static_data_offsets { 57 uint64_t eot; 58 uint64_t fence; 59 uint64_t vdm_sync; 60 uint64_t yuv_csc; 61 }; 62 63 struct pvr_winsys_heap { 64 struct pvr_winsys *ws; 65 66 pvr_dev_addr_t base_addr; 67 pvr_dev_addr_t reserved_addr; 68 69 uint64_t size; 70 uint64_t reserved_size; 71 72 uint32_t page_size; 73 uint32_t log2_page_size; 74 75 struct util_vma_heap vma_heap; 76 int ref_count; 77 pthread_mutex_t lock; 78 79 /* These are the offsets from the base at which static data might be 80 * uploaded. Some of these might be invalid since the kernel might not 81 * return all of these offsets per each heap as they might not be 82 * applicable. 83 * You should know which to use beforehand. There should be no need to check 84 * whether an offset is valid or invalid. 85 */ 86 struct pvr_winsys_static_data_offsets static_data_offsets; 87 }; 88 89 enum pvr_winsys_bo_type { 90 PVR_WINSYS_BO_TYPE_GPU = 0, 91 PVR_WINSYS_BO_TYPE_DISPLAY = 1, 92 }; 93 94 /** 95 * \brief Flag passed to #pvr_winsys_ops.buffer_create to indicate that the 96 * buffer should be CPU accessible. This is required in order to map the buffer 97 * using #pvr_winsys_ops.buffer_map. 98 */ 99 #define PVR_WINSYS_BO_FLAG_CPU_ACCESS BITFIELD_BIT(0U) 100 /** 101 * \brief Flag passed to #pvr_winsys_ops.buffer_create to indicate that, when 102 * the buffer is mapped to the GPU using #pvr_winsys.vma_map, it should be 103 * mapped uncached. 104 */ 105 #define PVR_WINSYS_BO_FLAG_GPU_UNCACHED BITFIELD_BIT(1U) 106 /** 107 * \brief Flag passed to #pvr_winsys_ops.buffer_create to indicate that, when 108 * the buffer is mapped to the GPU using #pvr_winsys.vma_map, it should only be 109 * accessible to the Parameter Manager unit and firmware processor. 110 */ 111 #define PVR_WINSYS_BO_FLAG_PM_FW_PROTECT BITFIELD_BIT(2U) 112 /** 113 * \brief Flag passed to #pvr_winsys_ops.buffer_create to indicate that the 114 * buffer should be zeroed at allocation time. 115 */ 116 #define PVR_WINSYS_BO_FLAG_ZERO_ON_ALLOC BITFIELD_BIT(3U) 117 118 struct pvr_winsys_bo { 119 struct pvr_winsys *ws; 120 void *map; 121 uint64_t size; 122 123 bool is_imported; 124 }; 125 126 struct pvr_winsys_vma { 127 struct pvr_winsys_heap *heap; 128 129 /* Buffer and offset this vma is bound to. */ 130 struct pvr_winsys_bo *bo; 131 VkDeviceSize bo_offset; 132 133 pvr_dev_addr_t dev_addr; 134 uint64_t size; 135 uint64_t mapped_size; 136 }; 137 138 struct pvr_winsys_free_list { 139 struct pvr_winsys *ws; 140 }; 141 142 struct pvr_winsys_rt_dataset_create_info { 143 /* Local freelist */ 144 struct pvr_winsys_free_list *local_free_list; 145 146 /* ISP register values */ 147 uint32_t isp_merge_lower_x; 148 uint32_t isp_merge_lower_y; 149 uint32_t isp_merge_scale_x; 150 uint32_t isp_merge_scale_y; 151 uint32_t isp_merge_upper_x; 152 uint32_t isp_merge_upper_y; 153 uint32_t isp_mtile_size; 154 155 /* PPP register values */ 156 uint64_t ppp_multi_sample_ctl; 157 uint64_t ppp_multi_sample_ctl_y_flipped; 158 uint32_t ppp_screen; 159 160 /* TE register values */ 161 uint32_t te_aa; 162 uint32_t te_mtile1; 163 uint32_t te_mtile2; 164 uint32_t te_screen; 165 166 /* Allocations and associated information */ 167 pvr_dev_addr_t vheap_table_dev_addr; 168 pvr_dev_addr_t rtc_dev_addr; 169 170 pvr_dev_addr_t tpc_dev_addr; 171 uint32_t tpc_stride; 172 uint32_t tpc_size; 173 174 struct { 175 pvr_dev_addr_t pm_mlist_dev_addr; 176 pvr_dev_addr_t macrotile_array_dev_addr; 177 pvr_dev_addr_t rgn_header_dev_addr; 178 } rt_datas[ROGUE_NUM_RTDATAS]; 179 uint64_t rgn_header_size; 180 181 /* Miscellaneous */ 182 uint32_t mtile_stride; 183 uint16_t max_rts; 184 }; 185 186 struct pvr_winsys_rt_dataset { 187 struct pvr_winsys *ws; 188 }; 189 190 enum pvr_winsys_ctx_priority { 191 PVR_WINSYS_CTX_PRIORITY_LOW, 192 PVR_WINSYS_CTX_PRIORITY_MEDIUM, 193 PVR_WINSYS_CTX_PRIORITY_HIGH, 194 }; 195 196 struct pvr_winsys_render_ctx_create_info { 197 enum pvr_winsys_ctx_priority priority; 198 pvr_dev_addr_t vdm_callstack_addr; 199 200 struct pvr_winsys_render_ctx_static_state { 201 uint64_t vdm_ctx_state_base_addr; 202 uint64_t geom_ctx_state_base_addr; 203 204 struct { 205 uint64_t vdm_ctx_store_task0; 206 uint32_t vdm_ctx_store_task1; 207 uint64_t vdm_ctx_store_task2; 208 209 uint64_t vdm_ctx_resume_task0; 210 uint32_t vdm_ctx_resume_task1; 211 uint64_t vdm_ctx_resume_task2; 212 } geom_state[2]; 213 } static_state; 214 }; 215 216 struct pvr_winsys_render_ctx { 217 struct pvr_winsys *ws; 218 }; 219 220 struct pvr_winsys_compute_ctx_create_info { 221 enum pvr_winsys_ctx_priority priority; 222 223 struct pvr_winsys_compute_ctx_static_state { 224 uint64_t cdm_ctx_store_pds0; 225 uint64_t cdm_ctx_store_pds0_b; 226 uint32_t cdm_ctx_store_pds1; 227 228 uint64_t cdm_ctx_terminate_pds; 229 uint32_t cdm_ctx_terminate_pds1; 230 231 uint64_t cdm_ctx_resume_pds0; 232 uint64_t cdm_ctx_resume_pds0_b; 233 } static_state; 234 }; 235 236 struct pvr_winsys_compute_ctx { 237 struct pvr_winsys *ws; 238 }; 239 240 struct pvr_winsys_transfer_ctx_create_info { 241 enum pvr_winsys_ctx_priority priority; 242 }; 243 244 struct pvr_winsys_transfer_ctx { 245 struct pvr_winsys *ws; 246 }; 247 248 #define PVR_WINSYS_TRANSFER_FLAG_START BITFIELD_BIT(0U) 249 #define PVR_WINSYS_TRANSFER_FLAG_END BITFIELD_BIT(1U) 250 251 #define PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT 16U 252 #define PVR_TRANSFER_MAX_RENDER_TARGETS 3U 253 254 struct pvr_winsys_transfer_regs { 255 uint32_t event_pixel_pds_code; 256 uint32_t event_pixel_pds_data; 257 uint32_t event_pixel_pds_info; 258 uint32_t isp_aa; 259 uint32_t isp_bgobjvals; 260 uint32_t isp_ctl; 261 uint64_t isp_mtile_base; 262 uint32_t isp_mtile_size; 263 uint32_t isp_render; 264 uint32_t isp_render_origin; 265 uint32_t isp_rgn; 266 uint64_t pbe_wordx_mrty[PVR_TRANSFER_MAX_RENDER_TARGETS * 267 ROGUE_NUM_PBESTATE_REG_WORDS]; 268 uint64_t pds_bgnd0_base; 269 uint64_t pds_bgnd1_base; 270 uint64_t pds_bgnd3_sizeinfo; 271 uint32_t usc_clear_register0; 272 uint32_t usc_clear_register1; 273 uint32_t usc_clear_register2; 274 uint32_t usc_clear_register3; 275 uint32_t usc_pixel_output_ctrl; 276 }; 277 278 struct pvr_winsys_transfer_submit_info { 279 uint32_t frame_num; 280 uint32_t job_num; 281 282 /* waits and stage_flags are arrays of length wait_count. */ 283 struct vk_sync **waits; 284 uint32_t wait_count; 285 uint32_t *stage_flags; 286 287 uint32_t cmd_count; 288 struct { 289 struct pvr_winsys_transfer_regs regs; 290 291 /* Must be 0 or a combination of PVR_WINSYS_TRANSFER_FLAG_* flags. */ 292 uint32_t flags; 293 } cmds[PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT]; 294 }; 295 296 #define PVR_WINSYS_COMPUTE_FLAG_PREVENT_ALL_OVERLAP BITFIELD_BIT(0U) 297 #define PVR_WINSYS_COMPUTE_FLAG_SINGLE_CORE BITFIELD_BIT(1U) 298 299 struct pvr_winsys_compute_submit_info { 300 uint32_t frame_num; 301 uint32_t job_num; 302 303 /* waits and stage_flags are arrays of length wait_count. */ 304 struct vk_sync **waits; 305 uint32_t wait_count; 306 uint32_t *stage_flags; 307 308 struct { 309 uint64_t tpu_border_colour_table; 310 uint64_t cdm_item; 311 uint32_t compute_cluster; 312 uint64_t cdm_ctrl_stream_base; 313 uint64_t cdm_ctx_state_base_addr; 314 uint32_t tpu; 315 uint32_t cdm_resume_pds1; 316 } regs; 317 318 /* Must be 0 or a combination of PVR_WINSYS_COMPUTE_FLAG_* flags. */ 319 uint32_t flags; 320 }; 321 322 #define PVR_WINSYS_JOB_BO_FLAG_WRITE BITFIELD_BIT(0U) 323 324 struct pvr_winsys_job_bo { 325 struct pvr_winsys_bo *bo; 326 /* Must be 0 or a combination of PVR_WINSYS_JOB_BO_FLAG_* flags. */ 327 uint32_t flags; 328 }; 329 330 #define PVR_WINSYS_GEOM_FLAG_FIRST_GEOMETRY BITFIELD_BIT(0U) 331 #define PVR_WINSYS_GEOM_FLAG_LAST_GEOMETRY BITFIELD_BIT(1U) 332 #define PVR_WINSYS_GEOM_FLAG_SINGLE_CORE BITFIELD_BIT(2U) 333 334 #define PVR_WINSYS_FRAG_FLAG_DEPTH_BUFFER_PRESENT BITFIELD_BIT(0U) 335 #define PVR_WINSYS_FRAG_FLAG_STENCIL_BUFFER_PRESENT BITFIELD_BIT(1U) 336 #define PVR_WINSYS_FRAG_FLAG_PREVENT_CDM_OVERLAP BITFIELD_BIT(2U) 337 #define PVR_WINSYS_FRAG_FLAG_SINGLE_CORE BITFIELD_BIT(3U) 338 339 struct pvr_winsys_render_submit_info { 340 struct pvr_winsys_rt_dataset *rt_dataset; 341 uint8_t rt_data_idx; 342 343 uint32_t frame_num; 344 uint32_t job_num; 345 346 uint32_t bo_count; 347 const struct pvr_winsys_job_bo *bos; 348 349 /* FIXME: should this be flags instead? */ 350 bool run_frag; 351 352 /* waits and stage_flags are arrays of length wait_count. */ 353 struct vk_sync **waits; 354 uint32_t wait_count; 355 uint32_t *stage_flags; 356 357 struct pvr_winsys_geometry_state { 358 struct { 359 uint64_t pds_ctrl; 360 uint32_t ppp_ctrl; 361 uint32_t te_psg; 362 uint32_t tpu; 363 uint64_t tpu_border_colour_table; 364 uint64_t vdm_ctrl_stream_base; 365 uint32_t vdm_ctx_resume_task0_size; 366 } regs; 367 368 /* Must be 0 or a combination of PVR_WINSYS_GEOM_FLAG_* flags. */ 369 uint32_t flags; 370 } geometry; 371 372 struct pvr_winsys_fragment_state { 373 struct { 374 uint32_t event_pixel_pds_data; 375 uint32_t event_pixel_pds_info; 376 uint32_t isp_aa; 377 uint32_t isp_bgobjdepth; 378 uint32_t isp_bgobjvals; 379 uint32_t isp_ctl; 380 uint64_t isp_dbias_base; 381 uint64_t isp_oclqry_base; 382 uint64_t isp_scissor_base; 383 uint64_t isp_stencil_load_store_base; 384 uint64_t isp_zload_store_base; 385 uint64_t isp_zlsctl; 386 uint32_t isp_zls_pixels; 387 uint64_t pbe_word[PVR_MAX_COLOR_ATTACHMENTS] 388 [ROGUE_NUM_PBESTATE_REG_WORDS]; 389 uint32_t pixel_phantom; 390 uint64_t pds_bgnd[ROGUE_NUM_CR_PDS_BGRND_WORDS]; 391 uint64_t pds_pr_bgnd[ROGUE_NUM_CR_PDS_BGRND_WORDS]; 392 uint32_t tpu; 393 uint64_t tpu_border_colour_table; 394 uint32_t usc_pixel_output_ctrl; 395 } regs; 396 397 /* Must be 0 or a combination of PVR_WINSYS_FRAG_FLAG_* flags. */ 398 uint32_t flags; 399 uint32_t zls_stride; 400 uint32_t sls_stride; 401 } fragment; 402 }; 403 404 struct pvr_winsys_ops { 405 void (*destroy)(struct pvr_winsys *ws); 406 int (*device_info_init)(struct pvr_winsys *ws, 407 struct pvr_device_info *dev_info, 408 struct pvr_device_runtime_info *runtime_info); 409 void (*get_heaps_info)(struct pvr_winsys *ws, 410 struct pvr_winsys_heaps *heaps); 411 412 VkResult (*buffer_create)(struct pvr_winsys *ws, 413 uint64_t size, 414 uint64_t alignment, 415 enum pvr_winsys_bo_type type, 416 uint32_t flags, 417 struct pvr_winsys_bo **const bo_out); 418 VkResult (*buffer_create_from_fd)(struct pvr_winsys *ws, 419 int fd, 420 struct pvr_winsys_bo **const bo_out); 421 void (*buffer_destroy)(struct pvr_winsys_bo *bo); 422 423 VkResult (*buffer_get_fd)(struct pvr_winsys_bo *bo, int *const fd_out); 424 425 void *(*buffer_map)(struct pvr_winsys_bo *bo); 426 void (*buffer_unmap)(struct pvr_winsys_bo *bo); 427 428 struct pvr_winsys_vma *(*heap_alloc)(struct pvr_winsys_heap *heap, 429 uint64_t size, 430 uint64_t alignment); 431 void (*heap_free)(struct pvr_winsys_vma *vma); 432 433 pvr_dev_addr_t (*vma_map)(struct pvr_winsys_vma *vma, 434 struct pvr_winsys_bo *bo, 435 uint64_t offset, 436 uint64_t size); 437 void (*vma_unmap)(struct pvr_winsys_vma *vma); 438 439 VkResult (*free_list_create)( 440 struct pvr_winsys *ws, 441 struct pvr_winsys_vma *free_list_vma, 442 uint32_t initial_num_pages, 443 uint32_t max_num_pages, 444 uint32_t grow_num_pages, 445 uint32_t grow_threshold, 446 struct pvr_winsys_free_list *parent_free_list, 447 struct pvr_winsys_free_list **const free_list_out); 448 void (*free_list_destroy)(struct pvr_winsys_free_list *free_list); 449 450 VkResult (*render_target_dataset_create)( 451 struct pvr_winsys *ws, 452 const struct pvr_winsys_rt_dataset_create_info *create_info, 453 struct pvr_winsys_rt_dataset **const rt_dataset_out); 454 void (*render_target_dataset_destroy)( 455 struct pvr_winsys_rt_dataset *rt_dataset); 456 457 VkResult (*render_ctx_create)( 458 struct pvr_winsys *ws, 459 struct pvr_winsys_render_ctx_create_info *create_info, 460 struct pvr_winsys_render_ctx **const ctx_out); 461 void (*render_ctx_destroy)(struct pvr_winsys_render_ctx *ctx); 462 VkResult (*render_submit)( 463 const struct pvr_winsys_render_ctx *ctx, 464 const struct pvr_winsys_render_submit_info *submit_info, 465 struct vk_sync *signal_sync_geom, 466 struct vk_sync *signal_sync_frag); 467 468 VkResult (*compute_ctx_create)( 469 struct pvr_winsys *ws, 470 const struct pvr_winsys_compute_ctx_create_info *create_info, 471 struct pvr_winsys_compute_ctx **const ctx_out); 472 void (*compute_ctx_destroy)(struct pvr_winsys_compute_ctx *ctx); 473 VkResult (*compute_submit)( 474 const struct pvr_winsys_compute_ctx *ctx, 475 const struct pvr_winsys_compute_submit_info *submit_info, 476 struct vk_sync *signal_sync); 477 478 VkResult (*transfer_ctx_create)( 479 struct pvr_winsys *ws, 480 const struct pvr_winsys_transfer_ctx_create_info *create_info, 481 struct pvr_winsys_transfer_ctx **const ctx_out); 482 void (*transfer_ctx_destroy)(struct pvr_winsys_transfer_ctx *ctx); 483 VkResult (*transfer_submit)( 484 const struct pvr_winsys_transfer_ctx *ctx, 485 const struct pvr_winsys_transfer_submit_info *submit_info, 486 struct vk_sync *signal_sync); 487 488 VkResult (*null_job_submit)(struct pvr_winsys *ws, 489 struct vk_sync **waits, 490 uint32_t wait_count, 491 struct vk_sync *signal_sync); 492 }; 493 494 struct pvr_winsys { 495 uint64_t page_size; 496 uint32_t log2_page_size; 497 498 const struct vk_sync_type *sync_types[2]; 499 struct vk_sync_type syncobj_type; 500 501 const struct pvr_winsys_ops *ops; 502 }; 503 504 void pvr_winsys_destroy(struct pvr_winsys *ws); 505 struct pvr_winsys *pvr_winsys_create(int master_fd, 506 int render_fd, 507 const VkAllocationCallbacks *alloc); 508 509 #endif /* PVR_WINSYS_H */ 510