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 <inttypes.h> 33 #include <stdbool.h> 34 #include <stdint.h> 35 #include <vulkan/vulkan.h> 36 37 #include "hwdef/rogue_hw_defs.h" 38 #include "pvr_limits.h" 39 #include "pvr_rogue_fw.h" 40 #include "pvr_types.h" 41 #include "util/macros.h" 42 #include "util/vma.h" 43 #include "vk_sync.h" 44 #include "vk_sync_timeline.h" 45 46 struct pvr_device_info; 47 struct pvr_device_runtime_info; 48 49 struct pvr_winsys_heaps { 50 struct pvr_winsys_heap *general_heap; 51 struct pvr_winsys_heap *pds_heap; 52 struct pvr_winsys_heap *rgn_hdr_heap; 53 struct pvr_winsys_heap *transfer_frag_heap; 54 struct pvr_winsys_heap *usc_heap; 55 struct pvr_winsys_heap *vis_test_heap; 56 }; 57 58 struct pvr_winsys_static_data_offsets { 59 uint64_t eot; 60 uint64_t fence; 61 uint64_t vdm_sync; 62 uint64_t yuv_csc; 63 }; 64 65 struct pvr_winsys_heap { 66 struct pvr_winsys *ws; 67 68 pvr_dev_addr_t base_addr; 69 pvr_dev_addr_t static_data_carveout_addr; 70 71 uint64_t size; 72 uint64_t static_data_carveout_size; 73 74 uint32_t page_size; 75 uint32_t log2_page_size; 76 77 struct util_vma_heap vma_heap; 78 int ref_count; 79 pthread_mutex_t lock; 80 81 /* These are the offsets from the base at which static data might be 82 * uploaded. Some of these might be invalid since the kernel might not 83 * return all of these offsets per each heap as they might not be 84 * applicable. 85 * You should know which to use beforehand. There should be no need to check 86 * whether an offset is valid or invalid. 87 */ 88 struct pvr_winsys_static_data_offsets static_data_offsets; 89 }; 90 91 enum pvr_winsys_bo_type { 92 PVR_WINSYS_BO_TYPE_GPU = 0, 93 PVR_WINSYS_BO_TYPE_DISPLAY = 1, 94 }; 95 96 /** 97 * \brief Flag passed to #pvr_winsys_ops.buffer_create to indicate that the 98 * buffer should be CPU accessible. This is required in order to map the buffer 99 * using #pvr_winsys_ops.buffer_map. 100 */ 101 #define PVR_WINSYS_BO_FLAG_CPU_ACCESS BITFIELD_BIT(0U) 102 /** 103 * \brief Flag passed to #pvr_winsys_ops.buffer_create to indicate that, when 104 * the buffer is mapped to the GPU using #pvr_winsys.vma_map, it should be 105 * mapped uncached. 106 */ 107 #define PVR_WINSYS_BO_FLAG_GPU_UNCACHED BITFIELD_BIT(1U) 108 /** 109 * \brief Flag passed to #pvr_winsys_ops.buffer_create to indicate that, when 110 * the buffer is mapped to the GPU using #pvr_winsys.vma_map, it should only be 111 * accessible to the Parameter Manager unit and firmware processor. 112 */ 113 #define PVR_WINSYS_BO_FLAG_PM_FW_PROTECT BITFIELD_BIT(2U) 114 115 struct pvr_winsys_bo { 116 struct pvr_winsys *ws; 117 void *map; 118 uint64_t size; 119 120 bool is_imported; 121 122 #if defined(HAVE_VALGRIND) 123 char *vbits; 124 #endif /* defined(HAVE_VALGRIND) */ 125 }; 126 127 struct pvr_winsys_vma { 128 struct pvr_winsys_heap *heap; 129 130 /* Buffer and offset this vma is bound to. */ 131 struct pvr_winsys_bo *bo; 132 VkDeviceSize bo_offset; 133 134 pvr_dev_addr_t dev_addr; 135 uint64_t size; 136 uint64_t mapped_size; 137 }; 138 139 struct pvr_winsys_free_list { 140 struct pvr_winsys *ws; 141 }; 142 143 struct pvr_winsys_rt_dataset_create_info { 144 /* Local freelist */ 145 struct pvr_winsys_free_list *local_free_list; 146 147 uint32_t width; 148 uint32_t height; 149 uint32_t samples; 150 uint16_t layers; 151 152 /* ISP register values */ 153 uint32_t isp_merge_lower_x; 154 uint32_t isp_merge_lower_y; 155 uint32_t isp_merge_scale_x; 156 uint32_t isp_merge_scale_y; 157 uint32_t isp_merge_upper_x; 158 uint32_t isp_merge_upper_y; 159 160 /* Allocations and associated information */ 161 pvr_dev_addr_t vheap_table_dev_addr; 162 pvr_dev_addr_t rtc_dev_addr; 163 164 pvr_dev_addr_t tpc_dev_addr; 165 uint32_t tpc_stride; 166 uint32_t tpc_size; 167 168 struct { 169 pvr_dev_addr_t pm_mlist_dev_addr; 170 pvr_dev_addr_t macrotile_array_dev_addr; 171 pvr_dev_addr_t rgn_header_dev_addr; 172 } rt_datas[ROGUE_NUM_RTDATAS]; 173 uint64_t rgn_header_size; 174 }; 175 176 struct pvr_winsys_rt_dataset { 177 struct pvr_winsys *ws; 178 }; 179 180 enum pvr_winsys_ctx_priority { 181 PVR_WINSYS_CTX_PRIORITY_LOW, 182 PVR_WINSYS_CTX_PRIORITY_MEDIUM, 183 PVR_WINSYS_CTX_PRIORITY_HIGH, 184 }; 185 186 struct pvr_winsys_render_ctx_create_info { 187 enum pvr_winsys_ctx_priority priority; 188 pvr_dev_addr_t vdm_callstack_addr; 189 190 struct pvr_winsys_render_ctx_static_state { 191 uint64_t vdm_ctx_state_base_addr; 192 uint64_t geom_ctx_state_base_addr; 193 194 struct { 195 uint64_t vdm_ctx_store_task0; 196 uint32_t vdm_ctx_store_task1; 197 uint64_t vdm_ctx_store_task2; 198 199 uint64_t vdm_ctx_resume_task0; 200 uint32_t vdm_ctx_resume_task1; 201 uint64_t vdm_ctx_resume_task2; 202 } geom_state[2]; 203 } static_state; 204 }; 205 206 struct pvr_winsys_render_ctx { 207 struct pvr_winsys *ws; 208 }; 209 210 struct pvr_winsys_compute_ctx_create_info { 211 enum pvr_winsys_ctx_priority priority; 212 213 struct pvr_winsys_compute_ctx_static_state { 214 uint64_t cdm_ctx_store_pds0; 215 uint64_t cdm_ctx_store_pds0_b; 216 uint32_t cdm_ctx_store_pds1; 217 218 uint64_t cdm_ctx_terminate_pds; 219 uint32_t cdm_ctx_terminate_pds1; 220 221 uint64_t cdm_ctx_resume_pds0; 222 uint64_t cdm_ctx_resume_pds0_b; 223 } static_state; 224 }; 225 226 struct pvr_winsys_compute_ctx { 227 struct pvr_winsys *ws; 228 }; 229 230 struct pvr_winsys_transfer_ctx_create_info { 231 enum pvr_winsys_ctx_priority priority; 232 }; 233 234 struct pvr_winsys_transfer_ctx { 235 struct pvr_winsys *ws; 236 }; 237 238 #define PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT 16U 239 #define PVR_TRANSFER_MAX_RENDER_TARGETS 3U 240 241 struct pvr_winsys_transfer_regs { 242 uint32_t event_pixel_pds_code; 243 uint32_t event_pixel_pds_data; 244 uint32_t event_pixel_pds_info; 245 uint32_t frag_screen; 246 uint32_t isp_aa; 247 uint32_t isp_bgobjvals; 248 uint32_t isp_ctl; 249 uint64_t isp_mtile_base; 250 uint32_t isp_mtile_size; 251 uint32_t isp_render; 252 uint32_t isp_render_origin; 253 uint32_t isp_rgn; 254 uint64_t pbe_wordx_mrty[PVR_TRANSFER_MAX_RENDER_TARGETS * 255 ROGUE_NUM_PBESTATE_REG_WORDS]; 256 uint64_t pds_bgnd0_base; 257 uint64_t pds_bgnd1_base; 258 uint64_t pds_bgnd3_sizeinfo; 259 uint32_t usc_clear_register0; 260 uint32_t usc_clear_register1; 261 uint32_t usc_clear_register2; 262 uint32_t usc_clear_register3; 263 uint32_t usc_pixel_output_ctrl; 264 }; 265 266 struct pvr_winsys_transfer_cmd { 267 /* Firmware stream buffer. This is the maximum possible size taking into 268 * consideration all HW features, quirks and enhancements. 269 */ 270 uint8_t fw_stream[176]; 271 uint32_t fw_stream_len; 272 273 struct pvr_winsys_transfer_cmd_flags { 274 bool use_single_core : 1; 275 } flags; 276 }; 277 278 struct pvr_winsys_transfer_submit_info { 279 uint32_t frame_num; 280 uint32_t job_num; 281 282 struct vk_sync *wait; 283 284 uint32_t cmd_count; 285 struct pvr_winsys_transfer_cmd cmds[PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT]; 286 }; 287 288 struct pvr_winsys_compute_submit_info { 289 uint32_t frame_num; 290 uint32_t job_num; 291 292 struct vk_sync *wait; 293 294 /* Firmware stream buffer. This is the maximum possible size taking into 295 * consideration all HW features, quirks and enhancements. 296 */ 297 uint8_t fw_stream[100]; 298 uint32_t fw_stream_len; 299 300 struct pvr_winsys_compute_submit_flags { 301 bool prevent_all_overlap : 1; 302 bool use_single_core : 1; 303 } flags; 304 }; 305 306 struct pvr_winsys_render_submit_info { 307 struct pvr_winsys_rt_dataset *rt_dataset; 308 uint8_t rt_data_idx; 309 310 uint32_t frame_num; 311 uint32_t job_num; 312 bool has_fragment_job; 313 314 struct pvr_winsys_geometry_state { 315 /* Firmware stream buffer. This is the maximum possible size taking into 316 * consideration all HW features, quirks and enhancements. 317 */ 318 uint8_t fw_stream[64]; 319 uint32_t fw_stream_len; 320 321 struct pvr_winsys_geometry_state_flags { 322 bool is_first_geometry : 1; 323 bool is_last_geometry : 1; 324 bool use_single_core : 1; 325 } flags; 326 327 struct vk_sync *wait; 328 } geometry; 329 330 struct pvr_winsys_fragment_state { 331 /* Firmware stream buffer. This is the maximum possible size taking into 332 * consideration all HW features, quirks and enhancements. 333 */ 334 uint8_t fw_stream[440]; 335 uint32_t fw_stream_len; 336 337 struct pvr_winsys_fragment_state_flags { 338 bool has_depth_buffer : 1; 339 bool has_stencil_buffer : 1; 340 bool prevent_cdm_overlap : 1; 341 bool use_single_core : 1; 342 bool get_vis_results : 1; 343 bool has_spm_scratch_buffer : 1; 344 } flags; 345 346 struct vk_sync *wait; 347 } fragment, fragment_pr; 348 }; 349 350 struct pvr_winsys_ops { 351 void (*destroy)(struct pvr_winsys *ws); 352 VkResult (*device_info_init)(struct pvr_winsys *ws, 353 struct pvr_device_info *dev_info, 354 struct pvr_device_runtime_info *runtime_info); 355 void (*get_heaps_info)(struct pvr_winsys *ws, 356 struct pvr_winsys_heaps *heaps); 357 358 VkResult (*buffer_create)(struct pvr_winsys *ws, 359 uint64_t size, 360 uint64_t alignment, 361 enum pvr_winsys_bo_type type, 362 uint32_t flags, 363 struct pvr_winsys_bo **const bo_out); 364 VkResult (*buffer_create_from_fd)(struct pvr_winsys *ws, 365 int fd, 366 struct pvr_winsys_bo **const bo_out); 367 void (*buffer_destroy)(struct pvr_winsys_bo *bo); 368 369 VkResult (*buffer_get_fd)(struct pvr_winsys_bo *bo, int *const fd_out); 370 371 VkResult (*buffer_map)(struct pvr_winsys_bo *bo); 372 void (*buffer_unmap)(struct pvr_winsys_bo *bo); 373 374 VkResult (*heap_alloc)(struct pvr_winsys_heap *heap, 375 uint64_t size, 376 uint64_t alignment, 377 struct pvr_winsys_vma **vma_out); 378 void (*heap_free)(struct pvr_winsys_vma *vma); 379 380 VkResult (*vma_map)(struct pvr_winsys_vma *vma, 381 struct pvr_winsys_bo *bo, 382 uint64_t offset, 383 uint64_t size, 384 pvr_dev_addr_t *dev_addr_out); 385 void (*vma_unmap)(struct pvr_winsys_vma *vma); 386 387 VkResult (*free_list_create)( 388 struct pvr_winsys *ws, 389 struct pvr_winsys_vma *free_list_vma, 390 uint32_t initial_num_pages, 391 uint32_t max_num_pages, 392 uint32_t grow_num_pages, 393 uint32_t grow_threshold, 394 struct pvr_winsys_free_list *parent_free_list, 395 struct pvr_winsys_free_list **const free_list_out); 396 void (*free_list_destroy)(struct pvr_winsys_free_list *free_list); 397 398 VkResult (*render_target_dataset_create)( 399 struct pvr_winsys *ws, 400 const struct pvr_winsys_rt_dataset_create_info *create_info, 401 const struct pvr_device_info *dev_info, 402 struct pvr_winsys_rt_dataset **const rt_dataset_out); 403 void (*render_target_dataset_destroy)( 404 struct pvr_winsys_rt_dataset *rt_dataset); 405 406 VkResult (*render_ctx_create)( 407 struct pvr_winsys *ws, 408 struct pvr_winsys_render_ctx_create_info *create_info, 409 struct pvr_winsys_render_ctx **const ctx_out); 410 void (*render_ctx_destroy)(struct pvr_winsys_render_ctx *ctx); 411 VkResult (*render_submit)( 412 const struct pvr_winsys_render_ctx *ctx, 413 const struct pvr_winsys_render_submit_info *submit_info, 414 const struct pvr_device_info *dev_info, 415 struct vk_sync *signal_sync_geom, 416 struct vk_sync *signal_sync_frag); 417 418 VkResult (*compute_ctx_create)( 419 struct pvr_winsys *ws, 420 const struct pvr_winsys_compute_ctx_create_info *create_info, 421 struct pvr_winsys_compute_ctx **const ctx_out); 422 void (*compute_ctx_destroy)(struct pvr_winsys_compute_ctx *ctx); 423 VkResult (*compute_submit)( 424 const struct pvr_winsys_compute_ctx *ctx, 425 const struct pvr_winsys_compute_submit_info *submit_info, 426 const struct pvr_device_info *dev_info, 427 struct vk_sync *signal_sync); 428 429 VkResult (*transfer_ctx_create)( 430 struct pvr_winsys *ws, 431 const struct pvr_winsys_transfer_ctx_create_info *create_info, 432 struct pvr_winsys_transfer_ctx **const ctx_out); 433 void (*transfer_ctx_destroy)(struct pvr_winsys_transfer_ctx *ctx); 434 VkResult (*transfer_submit)( 435 const struct pvr_winsys_transfer_ctx *ctx, 436 const struct pvr_winsys_transfer_submit_info *submit_info, 437 const struct pvr_device_info *dev_info, 438 struct vk_sync *signal_sync); 439 440 VkResult (*null_job_submit)(struct pvr_winsys *ws, 441 struct vk_sync_wait *waits, 442 uint32_t wait_count, 443 struct vk_sync_signal *signal_sync); 444 }; 445 446 struct pvr_winsys { 447 uint64_t page_size; 448 uint32_t log2_page_size; 449 450 const struct vk_sync_type *sync_types[3]; 451 struct vk_sync_type syncobj_type; 452 struct vk_sync_timeline_type timeline_syncobj_type; 453 454 int render_fd; 455 int display_fd; 456 457 const VkAllocationCallbacks *alloc; 458 459 struct { 460 bool supports_threaded_submit : 1; 461 } features; 462 463 const struct pvr_winsys_ops *ops; 464 }; 465 466 void pvr_winsys_destroy(struct pvr_winsys *ws); 467 VkResult pvr_winsys_create(const char *render_path, 468 const char *display_path, 469 const VkAllocationCallbacks *alloc, 470 struct pvr_winsys **ws_out); 471 472 #endif /* PVR_WINSYS_H */ 473