xref: /aosp_15_r20/external/mesa3d/src/asahi/lib/agx_uvs.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2024 Valve Corporation
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #pragma once
7 
8 #include <stdint.h>
9 #include "agx_pack.h"
10 #include "shader_enums.h"
11 
12 struct nir_shader;
13 
14 /* Matches the hardware order */
15 enum uvs_group {
16    UVS_POSITION,
17    UVS_VARYINGS,
18    UVS_PSIZ,
19    UVS_LAYER_VIEWPORT,
20    UVS_CLIP_DIST,
21    UVS_NUM_GROUP,
22 };
23 
24 /**
25  * Represents an "unlinked" UVS layout. This is computable from an unlinked
26  * vertex shader without knowing the associated fragment shader. The various UVS
27  * groups have fixed offsets, but the varyings within the varying group have
28  * indeterminate order since we don't yet know the fragment shader interpolation
29  * qualifiers.
30  */
31 struct agx_unlinked_uvs_layout {
32    /* Bit i set <===> components[i] != 0 && i != POS && i != PSIZ. For fast
33     * iteration of user varyings.
34     */
35    uint64_t written;
36 
37    /* Fully packed data structure */
38    struct agx_vdm_state_vertex_outputs_packed vdm;
39 
40    /* Partial data structure, must be merged with FS selects */
41    struct agx_output_select_packed osel;
42 
43    /* Offset of each group in the UVS in words. */
44    uint8_t group_offs[UVS_NUM_GROUP];
45 
46    /* Size of the UVS allocation in words. >= last group_offs element */
47    uint8_t size;
48 
49    /* Size of the UVS_VARYINGS */
50    uint8_t user_size;
51 
52    uint8_t pad;
53 
54    /* Number of 32-bit components written for each slot. TODO: Model 16-bit.
55     *
56     * Invariant: sum_{slot} (components[slot]) =
57     *            group_offs[PSIZ] - group_offs[VARYINGS]
58     */
59    uint8_t components[VARYING_SLOT_MAX];
60 };
61 static_assert(sizeof(struct agx_unlinked_uvs_layout) == 88, "packed");
62 
63 bool agx_nir_lower_uvs(struct nir_shader *s,
64                        struct agx_unlinked_uvs_layout *layout);
65 
66 /**
67  * Represents a linked UVS layout.
68  */
69 struct agx_varyings_vs {
70    /* Associated linked hardware data structures */
71    struct agx_varying_counts_packed counts_32, counts_16;
72 
73    /* If the user varying slot is written, this is the base index that the first
74     * component of the slot is written to. The next components are found in the
75     * next indices. Otherwise 0, aliasing position.
76     */
77    unsigned slots[VARYING_SLOT_MAX];
78 };
79 
80 void agx_assign_uvs(struct agx_varyings_vs *varyings,
81                     struct agx_unlinked_uvs_layout *layout, uint64_t flat_mask,
82                     uint64_t linear_mask);
83 
84 struct agx_varyings_fs;
85 
86 void agx_link_varyings_vs_fs(void *out, struct agx_varyings_vs *vs,
87                              unsigned nr_user_indices,
88                              struct agx_varyings_fs *fs,
89                              unsigned provoking_vertex,
90                              uint8_t sprite_coord_enable,
91                              bool *generate_primitive_id);
92