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
44struct pvr_device_info;
45struct pvr_device_runtime_info;
46
47struct 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
56struct 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
63struct 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
89enum 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
118struct pvr_winsys_bo {
119   struct pvr_winsys *ws;
120   void *map;
121   uint64_t size;
122
123   bool is_imported;
124};
125
126struct 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
138struct pvr_winsys_free_list {
139   struct pvr_winsys *ws;
140};
141
142struct 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
186struct pvr_winsys_rt_dataset {
187   struct pvr_winsys *ws;
188};
189
190enum pvr_winsys_ctx_priority {
191   PVR_WINSYS_CTX_PRIORITY_LOW,
192   PVR_WINSYS_CTX_PRIORITY_MEDIUM,
193   PVR_WINSYS_CTX_PRIORITY_HIGH,
194};
195
196struct 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
216struct pvr_winsys_render_ctx {
217   struct pvr_winsys *ws;
218};
219
220struct 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
236struct pvr_winsys_compute_ctx {
237   struct pvr_winsys *ws;
238};
239
240struct pvr_winsys_transfer_ctx_create_info {
241   enum pvr_winsys_ctx_priority priority;
242};
243
244struct 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
254struct 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
278struct 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
299struct 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
324struct 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
339struct 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
404struct 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
494struct 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
504void pvr_winsys_destroy(struct pvr_winsys *ws);
505struct pvr_winsys *pvr_winsys_create(int master_fd,
506                                     int render_fd,
507                                     const VkAllocationCallbacks *alloc);
508
509#endif /* PVR_WINSYS_H */
510