summaryrefslogtreecommitdiff
path: root/src/imagination/vulkan/winsys/pvr_winsys.h
blob: 469d41dea3e66c19213fde61aa57fe44bd8c385b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
/*
 * Copyright © 2022 Imagination Technologies Ltd.
 *
 * Based on radv_radeon_winsys.h which is:
 * Copyright © 2016 Red Hat.
 * Copyright © 2016 Bas Nieuwenhuizen
 *
 * 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.
 */

#ifndef PVR_WINSYS_H
#define PVR_WINSYS_H

#include <pthread.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
#include <vulkan/vulkan.h>

#include "hwdef/rogue_hw_defs.h"
#include "pvr_limits.h"
#include "pvr_rogue_fw.h"
#include "pvr_types.h"
#include "util/macros.h"
#include "util/vma.h"
#include "vk_sync.h"
#include "vk_sync_timeline.h"

struct pvr_device_info;
struct pvr_device_runtime_info;

struct pvr_winsys_heaps {
   struct pvr_winsys_heap *general_heap;
   struct pvr_winsys_heap *pds_heap;
   struct pvr_winsys_heap *rgn_hdr_heap;
   struct pvr_winsys_heap *transfer_3d_heap;
   struct pvr_winsys_heap *usc_heap;
   struct pvr_winsys_heap *vis_test_heap;
};

struct pvr_winsys_static_data_offsets {
   uint64_t eot;
   uint64_t fence;
   uint64_t vdm_sync;
   uint64_t yuv_csc;
};

struct pvr_winsys_heap {
   struct pvr_winsys *ws;

   pvr_dev_addr_t base_addr;
   pvr_dev_addr_t reserved_addr;

   uint64_t size;
   uint64_t reserved_size;

   uint32_t page_size;
   uint32_t log2_page_size;

   struct util_vma_heap vma_heap;
   int ref_count;
   pthread_mutex_t lock;

   /* These are the offsets from the base at which static data might be
    * uploaded. Some of these might be invalid since the kernel might not
    * return all of these offsets per each heap as they might not be
    * applicable.
    * You should know which to use beforehand. There should be no need to check
    * whether an offset is valid or invalid.
    */
   struct pvr_winsys_static_data_offsets static_data_offsets;
};

enum pvr_winsys_bo_type {
   PVR_WINSYS_BO_TYPE_GPU = 0,
   PVR_WINSYS_BO_TYPE_DISPLAY = 1,
};

/**
 * \brief Flag passed to #pvr_winsys_ops.buffer_create to indicate that the
 * buffer should be CPU accessible. This is required in order to map the buffer
 * using #pvr_winsys_ops.buffer_map.
 */
#define PVR_WINSYS_BO_FLAG_CPU_ACCESS BITFIELD_BIT(0U)
/**
 * \brief Flag passed to #pvr_winsys_ops.buffer_create to indicate that, when
 * the buffer is mapped to the GPU using #pvr_winsys.vma_map, it should be
 * mapped uncached.
 */
#define PVR_WINSYS_BO_FLAG_GPU_UNCACHED BITFIELD_BIT(1U)
/**
 * \brief Flag passed to #pvr_winsys_ops.buffer_create to indicate that, when
 * the buffer is mapped to the GPU using #pvr_winsys.vma_map, it should only be
 * accessible to the Parameter Manager unit and firmware processor.
 */
#define PVR_WINSYS_BO_FLAG_PM_FW_PROTECT BITFIELD_BIT(2U)
/**
 * \brief Flag passed to #pvr_winsys_ops.buffer_create to indicate that the
 * buffer should be zeroed at allocation time.
 */
#define PVR_WINSYS_BO_FLAG_ZERO_ON_ALLOC BITFIELD_BIT(3U)

struct pvr_winsys_bo {
   struct pvr_winsys *ws;
   void *map;
   uint64_t size;

   bool is_imported;

#if defined(HAVE_VALGRIND)
   char *vbits;
#endif /* defined(HAVE_VALGRIND) */
};

struct pvr_winsys_vma {
   struct pvr_winsys_heap *heap;

   /* Buffer and offset this vma is bound to. */
   struct pvr_winsys_bo *bo;
   VkDeviceSize bo_offset;

   pvr_dev_addr_t dev_addr;
   uint64_t size;
   uint64_t mapped_size;
};

struct pvr_winsys_free_list {
   struct pvr_winsys *ws;
};

struct pvr_winsys_rt_dataset_create_info {
   /* Local freelist */
   struct pvr_winsys_free_list *local_free_list;

   /* ISP register values */
   uint32_t isp_merge_lower_x;
   uint32_t isp_merge_lower_y;
   uint32_t isp_merge_scale_x;
   uint32_t isp_merge_scale_y;
   uint32_t isp_merge_upper_x;
   uint32_t isp_merge_upper_y;
   uint32_t isp_mtile_size;

   /* PPP register values */
   uint64_t ppp_multi_sample_ctl;
   uint64_t ppp_multi_sample_ctl_y_flipped;
   uint32_t ppp_screen;

   /* TE register values */
   uint32_t te_aa;
   uint32_t te_mtile1;
   uint32_t te_mtile2;
   uint32_t te_screen;

   /* Allocations and associated information */
   pvr_dev_addr_t vheap_table_dev_addr;
   pvr_dev_addr_t rtc_dev_addr;

   pvr_dev_addr_t tpc_dev_addr;
   uint32_t tpc_stride;
   uint32_t tpc_size;

   struct {
      pvr_dev_addr_t pm_mlist_dev_addr;
      pvr_dev_addr_t macrotile_array_dev_addr;
      pvr_dev_addr_t rgn_header_dev_addr;
   } rt_datas[ROGUE_NUM_RTDATAS];
   uint64_t rgn_header_size;

   /* Miscellaneous */
   uint32_t mtile_stride;
   uint16_t max_rts;
};

struct pvr_winsys_rt_dataset {
   struct pvr_winsys *ws;
};

enum pvr_winsys_ctx_priority {
   PVR_WINSYS_CTX_PRIORITY_LOW,
   PVR_WINSYS_CTX_PRIORITY_MEDIUM,
   PVR_WINSYS_CTX_PRIORITY_HIGH,
};

struct pvr_winsys_render_ctx_create_info {
   enum pvr_winsys_ctx_priority priority;
   pvr_dev_addr_t vdm_callstack_addr;

   struct pvr_winsys_render_ctx_static_state {
      uint64_t vdm_ctx_state_base_addr;
      uint64_t geom_ctx_state_base_addr;

      struct {
         uint64_t vdm_ctx_store_task0;
         uint32_t vdm_ctx_store_task1;
         uint64_t vdm_ctx_store_task2;

         uint64_t vdm_ctx_resume_task0;
         uint32_t vdm_ctx_resume_task1;
         uint64_t vdm_ctx_resume_task2;
      } geom_state[2];
   } static_state;
};

struct pvr_winsys_render_ctx {
   struct pvr_winsys *ws;
};

struct pvr_winsys_compute_ctx_create_info {
   enum pvr_winsys_ctx_priority priority;

   struct pvr_winsys_compute_ctx_static_state {
      uint64_t cdm_ctx_store_pds0;
      uint64_t cdm_ctx_store_pds0_b;
      uint32_t cdm_ctx_store_pds1;

      uint64_t cdm_ctx_terminate_pds;
      uint32_t cdm_ctx_terminate_pds1;

      uint64_t cdm_ctx_resume_pds0;
      uint64_t cdm_ctx_resume_pds0_b;
   } static_state;
};

struct pvr_winsys_compute_ctx {
   struct pvr_winsys *ws;
};

struct pvr_winsys_transfer_ctx_create_info {
   enum pvr_winsys_ctx_priority priority;
};

struct pvr_winsys_transfer_ctx {
   struct pvr_winsys *ws;
};

#define PVR_WINSYS_TRANSFER_FLAG_SINGLE_CORE BITFIELD_BIT(0U)

#define PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT 16U
#define PVR_TRANSFER_MAX_RENDER_TARGETS 3U

struct pvr_winsys_transfer_regs {
   uint32_t event_pixel_pds_code;
   uint32_t event_pixel_pds_data;
   uint32_t event_pixel_pds_info;
   uint32_t frag_screen;
   uint32_t isp_aa;
   uint32_t isp_bgobjvals;
   uint32_t isp_ctl;
   uint64_t isp_mtile_base;
   uint32_t isp_mtile_size;
   uint32_t isp_render;
   uint32_t isp_render_origin;
   uint32_t isp_rgn;
   uint64_t pbe_wordx_mrty[PVR_TRANSFER_MAX_RENDER_TARGETS *
                           ROGUE_NUM_PBESTATE_REG_WORDS];
   uint64_t pds_bgnd0_base;
   uint64_t pds_bgnd1_base;
   uint64_t pds_bgnd3_sizeinfo;
   uint32_t usc_clear_register0;
   uint32_t usc_clear_register1;
   uint32_t usc_clear_register2;
   uint32_t usc_clear_register3;
   uint32_t usc_pixel_output_ctrl;
};

struct pvr_winsys_transfer_cmd {
   /* Firmware stream buffer. This is the maximum possible size taking into
    * consideration all HW features.
    */
   uint8_t fw_stream[172];
   uint32_t fw_stream_len;

   /* Must be 0 or a combination of PVR_WINSYS_TRANSFER_FLAG_* flags. */
   uint32_t flags;
};

struct pvr_winsys_transfer_submit_info {
   uint32_t frame_num;
   uint32_t job_num;

   struct vk_sync *wait;

   uint32_t cmd_count;
   struct pvr_winsys_transfer_cmd cmds[PVR_TRANSFER_MAX_PREPARES_PER_SUBMIT];
};

#define PVR_WINSYS_COMPUTE_FLAG_PREVENT_ALL_OVERLAP BITFIELD_BIT(0U)
#define PVR_WINSYS_COMPUTE_FLAG_SINGLE_CORE BITFIELD_BIT(1U)

struct pvr_winsys_compute_submit_info {
   uint32_t frame_num;
   uint32_t job_num;

   struct vk_sync *wait;

   /* Firmware stream buffer. This is the maximum possible size taking into
    * consideration all HW features.
    */
   uint8_t fw_stream[92];
   uint32_t fw_stream_len;

   /* Firmware extension stream buffer. This is the maximum possible size taking
    * into considation all quirks and enhancements.
    */
   uint8_t fw_ext_stream[8];
   uint32_t fw_ext_stream_len;

   /* Must be 0 or a combination of PVR_WINSYS_COMPUTE_FLAG_* flags. */
   uint32_t flags;
};

#define PVR_WINSYS_GEOM_FLAG_FIRST_GEOMETRY BITFIELD_BIT(0U)
#define PVR_WINSYS_GEOM_FLAG_LAST_GEOMETRY BITFIELD_BIT(1U)
#define PVR_WINSYS_GEOM_FLAG_SINGLE_CORE BITFIELD_BIT(2U)

#define PVR_WINSYS_FRAG_FLAG_DEPTH_BUFFER_PRESENT BITFIELD_BIT(0U)
#define PVR_WINSYS_FRAG_FLAG_STENCIL_BUFFER_PRESENT BITFIELD_BIT(1U)
#define PVR_WINSYS_FRAG_FLAG_PREVENT_CDM_OVERLAP BITFIELD_BIT(2U)
#define PVR_WINSYS_FRAG_FLAG_SINGLE_CORE BITFIELD_BIT(3U)
#define PVR_WINSYS_FRAG_FLAG_GET_VIS_RESULTS BITFIELD_BIT(4U)
#define PVR_WINSYS_FRAG_FLAG_SPMSCRATCHBUFFER (5U)

struct pvr_winsys_render_submit_info {
   struct pvr_winsys_rt_dataset *rt_dataset;
   uint8_t rt_data_idx;

   uint32_t frame_num;
   uint32_t job_num;

   /* FIXME: should this be flags instead? */
   bool run_frag;

   struct pvr_winsys_geometry_state {
      /* Firmware stream buffer. This is the maximum possible size taking into
       * consideration all HW features.
       */
      uint8_t fw_stream[52];
      uint32_t fw_stream_len;

      /* Firmware extension stream buffer. This is the maximum possible size
       * taking into considation all quirks and enhancements.
       */
      uint8_t fw_ext_stream[12];
      uint32_t fw_ext_stream_len;

      /* Must be 0 or a combination of PVR_WINSYS_GEOM_FLAG_* flags. */
      uint32_t flags;

      struct vk_sync *wait;
   } geometry;

   struct pvr_winsys_fragment_state {
      /* Firmware stream buffer. This is the maximum possible size taking into
       * consideration all HW features.
       */
      uint8_t fw_stream[432];
      uint32_t fw_stream_len;

      /* Firmware extension stream buffer. This is the maximum possible size
       * taking into considation all quirks and enhancements.
       */
      uint8_t fw_ext_stream[8];
      uint32_t fw_ext_stream_len;

      /* Must be 0 or a combination of PVR_WINSYS_FRAG_FLAG_* flags. */
      uint32_t flags;

      struct vk_sync *wait;
   } fragment;
};

struct pvr_winsys_ops {
   void (*destroy)(struct pvr_winsys *ws);
   int (*device_info_init)(struct pvr_winsys *ws,
                           struct pvr_device_info *dev_info,
                           struct pvr_device_runtime_info *runtime_info);
   void (*get_heaps_info)(struct pvr_winsys *ws,
                          struct pvr_winsys_heaps *heaps);

   VkResult (*buffer_create)(struct pvr_winsys *ws,
                             uint64_t size,
                             uint64_t alignment,
                             enum pvr_winsys_bo_type type,
                             uint32_t flags,
                             struct pvr_winsys_bo **const bo_out);
   VkResult (*buffer_create_from_fd)(struct pvr_winsys *ws,
                                     int fd,
                                     struct pvr_winsys_bo **const bo_out);
   void (*buffer_destroy)(struct pvr_winsys_bo *bo);

   VkResult (*buffer_get_fd)(struct pvr_winsys_bo *bo, int *const fd_out);

   void *(*buffer_map)(struct pvr_winsys_bo *bo);
   void (*buffer_unmap)(struct pvr_winsys_bo *bo);

   struct pvr_winsys_vma *(*heap_alloc)(struct pvr_winsys_heap *heap,
                                        uint64_t size,
                                        uint64_t alignment);
   void (*heap_free)(struct pvr_winsys_vma *vma);

   pvr_dev_addr_t (*vma_map)(struct pvr_winsys_vma *vma,
                             struct pvr_winsys_bo *bo,
                             uint64_t offset,
                             uint64_t size);
   void (*vma_unmap)(struct pvr_winsys_vma *vma);

   VkResult (*free_list_create)(
      struct pvr_winsys *ws,
      struct pvr_winsys_vma *free_list_vma,
      uint32_t initial_num_pages,
      uint32_t max_num_pages,
      uint32_t grow_num_pages,
      uint32_t grow_threshold,
      struct pvr_winsys_free_list *parent_free_list,
      struct pvr_winsys_free_list **const free_list_out);
   void (*free_list_destroy)(struct pvr_winsys_free_list *free_list);

   VkResult (*render_target_dataset_create)(
      struct pvr_winsys *ws,
      const struct pvr_winsys_rt_dataset_create_info *create_info,
      struct pvr_winsys_rt_dataset **const rt_dataset_out);
   void (*render_target_dataset_destroy)(
      struct pvr_winsys_rt_dataset *rt_dataset);

   VkResult (*render_ctx_create)(
      struct pvr_winsys *ws,
      struct pvr_winsys_render_ctx_create_info *create_info,
      struct pvr_winsys_render_ctx **const ctx_out);
   void (*render_ctx_destroy)(struct pvr_winsys_render_ctx *ctx);
   VkResult (*render_submit)(
      const struct pvr_winsys_render_ctx *ctx,
      const struct pvr_winsys_render_submit_info *submit_info,
      const struct pvr_device_info *dev_info,
      struct vk_sync *signal_sync_geom,
      struct vk_sync *signal_sync_frag);

   VkResult (*compute_ctx_create)(
      struct pvr_winsys *ws,
      const struct pvr_winsys_compute_ctx_create_info *create_info,
      struct pvr_winsys_compute_ctx **const ctx_out);
   void (*compute_ctx_destroy)(struct pvr_winsys_compute_ctx *ctx);
   VkResult (*compute_submit)(
      const struct pvr_winsys_compute_ctx *ctx,
      const struct pvr_winsys_compute_submit_info *submit_info,
      const struct pvr_device_info *dev_info,
      struct vk_sync *signal_sync);

   VkResult (*transfer_ctx_create)(
      struct pvr_winsys *ws,
      const struct pvr_winsys_transfer_ctx_create_info *create_info,
      struct pvr_winsys_transfer_ctx **const ctx_out);
   void (*transfer_ctx_destroy)(struct pvr_winsys_transfer_ctx *ctx);
   VkResult (*transfer_submit)(
      const struct pvr_winsys_transfer_ctx *ctx,
      const struct pvr_winsys_transfer_submit_info *submit_info,
      const struct pvr_device_info *dev_info,
      struct vk_sync *signal_sync);

   VkResult (*null_job_submit)(struct pvr_winsys *ws,
                               struct vk_sync_wait *waits,
                               uint32_t wait_count,
                               struct vk_sync_signal *signal_sync);
};

struct pvr_winsys {
   uint64_t page_size;
   uint32_t log2_page_size;

   const struct vk_sync_type *sync_types[3];
   struct vk_sync_type syncobj_type;
   struct vk_sync_timeline_type timeline_syncobj_type;

   struct {
      bool supports_threaded_submit : 1;
   } features;

   const struct pvr_winsys_ops *ops;
};

void pvr_winsys_destroy(struct pvr_winsys *ws);
struct pvr_winsys *pvr_winsys_create(int master_fd,
                                     int render_fd,
                                     const VkAllocationCallbacks *alloc);

#endif /* PVR_WINSYS_H */