• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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