xref: /aosp_15_r20/external/mesa3d/src/asahi/lib/shaders/tessellation.cl (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker/*
2*61046927SAndroid Build Coastguard Worker * Copyright 2023 Alyssa Rosenzweig
3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker */
5*61046927SAndroid Build Coastguard Worker
6*61046927SAndroid Build Coastguard Worker#include "geometry.h"
7*61046927SAndroid Build Coastguard Worker#include "tessellator.h"
8*61046927SAndroid Build Coastguard Worker#include <agx_pack.h>
9*61046927SAndroid Build Coastguard Worker
10*61046927SAndroid Build Coastguard Workeruint
11*61046927SAndroid Build Coastguard Workerlibagx_tcs_patch_vertices_in(constant struct libagx_tess_args *p)
12*61046927SAndroid Build Coastguard Worker{
13*61046927SAndroid Build Coastguard Worker   return p->input_patch_size;
14*61046927SAndroid Build Coastguard Worker}
15*61046927SAndroid Build Coastguard Worker
16*61046927SAndroid Build Coastguard Workeruint
17*61046927SAndroid Build Coastguard Workerlibagx_tes_patch_vertices_in(constant struct libagx_tess_args *p)
18*61046927SAndroid Build Coastguard Worker{
19*61046927SAndroid Build Coastguard Worker   return p->output_patch_size;
20*61046927SAndroid Build Coastguard Worker}
21*61046927SAndroid Build Coastguard Worker
22*61046927SAndroid Build Coastguard Workeruint
23*61046927SAndroid Build Coastguard Workerlibagx_tcs_unrolled_id(constant struct libagx_tess_args *p, uint3 wg_id)
24*61046927SAndroid Build Coastguard Worker{
25*61046927SAndroid Build Coastguard Worker   return (wg_id.y * p->patches_per_instance) + wg_id.x;
26*61046927SAndroid Build Coastguard Worker}
27*61046927SAndroid Build Coastguard Worker
28*61046927SAndroid Build Coastguard Workeruint64_t
29*61046927SAndroid Build Coastguard Workerlibagx_tes_buffer(constant struct libagx_tess_args *p)
30*61046927SAndroid Build Coastguard Worker{
31*61046927SAndroid Build Coastguard Worker   return p->tes_buffer;
32*61046927SAndroid Build Coastguard Worker}
33*61046927SAndroid Build Coastguard Worker
34*61046927SAndroid Build Coastguard Worker/*
35*61046927SAndroid Build Coastguard Worker * Helper to lower indexing for a tess eval shader ran as a compute shader. This
36*61046927SAndroid Build Coastguard Worker * handles the tess+geom case. This is simpler than the general input assembly
37*61046927SAndroid Build Coastguard Worker * lowering, as we know:
38*61046927SAndroid Build Coastguard Worker *
39*61046927SAndroid Build Coastguard Worker * 1. the index buffer is U32
40*61046927SAndroid Build Coastguard Worker * 2. the index is in bounds
41*61046927SAndroid Build Coastguard Worker *
42*61046927SAndroid Build Coastguard Worker * Therefore we do a simple load. No bounds checking needed.
43*61046927SAndroid Build Coastguard Worker */
44*61046927SAndroid Build Coastguard Workeruint32_t
45*61046927SAndroid Build Coastguard Workerlibagx_load_tes_index(constant struct libagx_tess_args *p, uint32_t index)
46*61046927SAndroid Build Coastguard Worker{
47*61046927SAndroid Build Coastguard Worker   return p->index_buffer[index];
48*61046927SAndroid Build Coastguard Worker}
49*61046927SAndroid Build Coastguard Worker
50*61046927SAndroid Build Coastguard Workerushort
51*61046927SAndroid Build Coastguard Workerlibagx_tcs_in_offset(uint vtx, gl_varying_slot location,
52*61046927SAndroid Build Coastguard Worker                     uint64_t crosslane_vs_out_mask)
53*61046927SAndroid Build Coastguard Worker{
54*61046927SAndroid Build Coastguard Worker   return libagx_tcs_in_offs(vtx, location, crosslane_vs_out_mask);
55*61046927SAndroid Build Coastguard Worker}
56*61046927SAndroid Build Coastguard Worker
57*61046927SAndroid Build Coastguard Workeruintptr_t
58*61046927SAndroid Build Coastguard Workerlibagx_tcs_out_address(constant struct libagx_tess_args *p, uint patch_id,
59*61046927SAndroid Build Coastguard Worker                       uint vtx_id, gl_varying_slot location, uint nr_patch_out,
60*61046927SAndroid Build Coastguard Worker                       uint out_patch_size, uint64_t vtx_out_mask)
61*61046927SAndroid Build Coastguard Worker{
62*61046927SAndroid Build Coastguard Worker   uint stride =
63*61046927SAndroid Build Coastguard Worker      libagx_tcs_out_stride(nr_patch_out, out_patch_size, vtx_out_mask);
64*61046927SAndroid Build Coastguard Worker
65*61046927SAndroid Build Coastguard Worker   uint offs = libagx_tcs_out_offs(vtx_id, location, nr_patch_out,
66*61046927SAndroid Build Coastguard Worker                                   out_patch_size, vtx_out_mask);
67*61046927SAndroid Build Coastguard Worker
68*61046927SAndroid Build Coastguard Worker   return (uintptr_t)(p->tcs_buffer) + (patch_id * stride) + offs;
69*61046927SAndroid Build Coastguard Worker}
70*61046927SAndroid Build Coastguard Worker
71*61046927SAndroid Build Coastguard Workerstatic uint
72*61046927SAndroid Build Coastguard Workerlibagx_tes_unrolled_patch_id(uint raw_id)
73*61046927SAndroid Build Coastguard Worker{
74*61046927SAndroid Build Coastguard Worker   return raw_id / LIBAGX_TES_PATCH_ID_STRIDE;
75*61046927SAndroid Build Coastguard Worker}
76*61046927SAndroid Build Coastguard Worker
77*61046927SAndroid Build Coastguard Workeruint
78*61046927SAndroid Build Coastguard Workerlibagx_tes_patch_id(constant struct libagx_tess_args *p, uint raw_id)
79*61046927SAndroid Build Coastguard Worker{
80*61046927SAndroid Build Coastguard Worker   return libagx_tes_unrolled_patch_id(raw_id) % p->patches_per_instance;
81*61046927SAndroid Build Coastguard Worker}
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Workerstatic uint
84*61046927SAndroid Build Coastguard Workertes_vertex_id_in_patch(uint raw_id)
85*61046927SAndroid Build Coastguard Worker{
86*61046927SAndroid Build Coastguard Worker   return raw_id % LIBAGX_TES_PATCH_ID_STRIDE;
87*61046927SAndroid Build Coastguard Worker}
88*61046927SAndroid Build Coastguard Worker
89*61046927SAndroid Build Coastguard Workerfloat2
90*61046927SAndroid Build Coastguard Workerlibagx_load_tess_coord(constant struct libagx_tess_args *p, uint raw_id)
91*61046927SAndroid Build Coastguard Worker{
92*61046927SAndroid Build Coastguard Worker   uint patch = libagx_tes_unrolled_patch_id(raw_id);
93*61046927SAndroid Build Coastguard Worker   uint vtx = tes_vertex_id_in_patch(raw_id);
94*61046927SAndroid Build Coastguard Worker
95*61046927SAndroid Build Coastguard Worker   global struct libagx_tess_point *t =
96*61046927SAndroid Build Coastguard Worker      &p->patch_coord_buffer[p->coord_allocs[patch] + vtx];
97*61046927SAndroid Build Coastguard Worker
98*61046927SAndroid Build Coastguard Worker   /* Written weirdly because NIR struggles with loads of structs */
99*61046927SAndroid Build Coastguard Worker   return *((global float2 *)t);
100*61046927SAndroid Build Coastguard Worker}
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Workeruintptr_t
103*61046927SAndroid Build Coastguard Workerlibagx_tes_in_address(constant struct libagx_tess_args *p, uint raw_id,
104*61046927SAndroid Build Coastguard Worker                      uint vtx_id, gl_varying_slot location)
105*61046927SAndroid Build Coastguard Worker{
106*61046927SAndroid Build Coastguard Worker   uint patch = libagx_tes_unrolled_patch_id(raw_id);
107*61046927SAndroid Build Coastguard Worker
108*61046927SAndroid Build Coastguard Worker   return libagx_tcs_out_address(p, patch, vtx_id, location,
109*61046927SAndroid Build Coastguard Worker                                 p->tcs_patch_constants, p->output_patch_size,
110*61046927SAndroid Build Coastguard Worker                                 p->tcs_per_vertex_outputs);
111*61046927SAndroid Build Coastguard Worker}
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Workerfloat4
114*61046927SAndroid Build Coastguard Workerlibagx_tess_level_outer_default(constant struct libagx_tess_args *p)
115*61046927SAndroid Build Coastguard Worker{
116*61046927SAndroid Build Coastguard Worker   return (
117*61046927SAndroid Build Coastguard Worker      float4)(p->tess_level_outer_default[0], p->tess_level_outer_default[1],
118*61046927SAndroid Build Coastguard Worker              p->tess_level_outer_default[2], p->tess_level_outer_default[3]);
119*61046927SAndroid Build Coastguard Worker}
120*61046927SAndroid Build Coastguard Worker
121*61046927SAndroid Build Coastguard Workerfloat2
122*61046927SAndroid Build Coastguard Workerlibagx_tess_level_inner_default(constant struct libagx_tess_args *p)
123*61046927SAndroid Build Coastguard Worker{
124*61046927SAndroid Build Coastguard Worker   return (float2)(p->tess_level_inner_default[0],
125*61046927SAndroid Build Coastguard Worker                   p->tess_level_inner_default[1]);
126*61046927SAndroid Build Coastguard Worker}
127*61046927SAndroid Build Coastguard Worker
128*61046927SAndroid Build Coastguard Workervoid
129*61046927SAndroid Build Coastguard Workerlibagx_tess_setup_indirect(global struct libagx_tess_args *p, bool with_counts,
130*61046927SAndroid Build Coastguard Worker                           bool point_mode)
131*61046927SAndroid Build Coastguard Worker{
132*61046927SAndroid Build Coastguard Worker   uint count = p->indirect[0], instance_count = p->indirect[1];
133*61046927SAndroid Build Coastguard Worker   unsigned in_patches = count / p->input_patch_size;
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker   /* TCS invocation counter increments once per-patch */
136*61046927SAndroid Build Coastguard Worker   if (p->tcs_statistic) {
137*61046927SAndroid Build Coastguard Worker      *(p->tcs_statistic) += in_patches;
138*61046927SAndroid Build Coastguard Worker   }
139*61046927SAndroid Build Coastguard Worker
140*61046927SAndroid Build Coastguard Worker   size_t draw_stride =
141*61046927SAndroid Build Coastguard Worker      ((!with_counts && point_mode) ? 4 : 6) * sizeof(uint32_t);
142*61046927SAndroid Build Coastguard Worker
143*61046927SAndroid Build Coastguard Worker   unsigned unrolled_patches = in_patches * instance_count;
144*61046927SAndroid Build Coastguard Worker
145*61046927SAndroid Build Coastguard Worker   uint32_t alloc = 0;
146*61046927SAndroid Build Coastguard Worker   uint32_t tcs_out_offs = alloc;
147*61046927SAndroid Build Coastguard Worker   alloc += unrolled_patches * p->tcs_stride_el * 4;
148*61046927SAndroid Build Coastguard Worker
149*61046927SAndroid Build Coastguard Worker   uint32_t patch_coord_offs = alloc;
150*61046927SAndroid Build Coastguard Worker   alloc += unrolled_patches * 4;
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker   uint32_t count_offs = alloc;
153*61046927SAndroid Build Coastguard Worker   if (with_counts)
154*61046927SAndroid Build Coastguard Worker      alloc += unrolled_patches * sizeof(uint32_t);
155*61046927SAndroid Build Coastguard Worker
156*61046927SAndroid Build Coastguard Worker   uint vb_offs = alloc;
157*61046927SAndroid Build Coastguard Worker   uint vb_size = libagx_tcs_in_size(count * instance_count, p->vertex_outputs);
158*61046927SAndroid Build Coastguard Worker   alloc += vb_size;
159*61046927SAndroid Build Coastguard Worker
160*61046927SAndroid Build Coastguard Worker   /* Allocate all patch calculations in one go */
161*61046927SAndroid Build Coastguard Worker   global uchar *blob = p->heap->heap + p->heap->heap_bottom;
162*61046927SAndroid Build Coastguard Worker   p->heap->heap_bottom += alloc;
163*61046927SAndroid Build Coastguard Worker
164*61046927SAndroid Build Coastguard Worker   p->tcs_buffer = (global float *)(blob + tcs_out_offs);
165*61046927SAndroid Build Coastguard Worker   p->patches_per_instance = in_patches;
166*61046927SAndroid Build Coastguard Worker   p->coord_allocs = (global uint *)(blob + patch_coord_offs);
167*61046927SAndroid Build Coastguard Worker   p->nr_patches = unrolled_patches;
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker   *(p->vertex_output_buffer_ptr) = (uintptr_t)(blob + vb_offs);
170*61046927SAndroid Build Coastguard Worker
171*61046927SAndroid Build Coastguard Worker   if (with_counts) {
172*61046927SAndroid Build Coastguard Worker      p->counts = (global uint32_t *)(blob + count_offs);
173*61046927SAndroid Build Coastguard Worker   } else {
174*61046927SAndroid Build Coastguard Worker#if 0
175*61046927SAndroid Build Coastguard Worker      /* Arrange so we return after all generated draws. agx_pack would be nicer
176*61046927SAndroid Build Coastguard Worker       * here but designated initializers lead to scratch access...
177*61046927SAndroid Build Coastguard Worker       */
178*61046927SAndroid Build Coastguard Worker      global uint32_t *ret =
179*61046927SAndroid Build Coastguard Worker         (global uint32_t *)(blob + draw_offs +
180*61046927SAndroid Build Coastguard Worker                             (draw_stride * unrolled_patches));
181*61046927SAndroid Build Coastguard Worker
182*61046927SAndroid Build Coastguard Worker      *ret = (AGX_VDM_BLOCK_TYPE_BARRIER << 29) | /* with return */ (1u << 27);
183*61046927SAndroid Build Coastguard Worker#endif
184*61046927SAndroid Build Coastguard Worker      /* TODO */
185*61046927SAndroid Build Coastguard Worker   }
186*61046927SAndroid Build Coastguard Worker
187*61046927SAndroid Build Coastguard Worker   /* VS grid size */
188*61046927SAndroid Build Coastguard Worker   p->grids[0] = count;
189*61046927SAndroid Build Coastguard Worker   p->grids[1] = instance_count;
190*61046927SAndroid Build Coastguard Worker   p->grids[2] = 1;
191*61046927SAndroid Build Coastguard Worker
192*61046927SAndroid Build Coastguard Worker   /* VS workgroup size */
193*61046927SAndroid Build Coastguard Worker   p->grids[3] = 64;
194*61046927SAndroid Build Coastguard Worker   p->grids[4] = 1;
195*61046927SAndroid Build Coastguard Worker   p->grids[5] = 1;
196*61046927SAndroid Build Coastguard Worker
197*61046927SAndroid Build Coastguard Worker   /* TCS grid size */
198*61046927SAndroid Build Coastguard Worker   p->grids[6] = in_patches * p->output_patch_size;
199*61046927SAndroid Build Coastguard Worker   p->grids[7] = instance_count;
200*61046927SAndroid Build Coastguard Worker   p->grids[8] = 1;
201*61046927SAndroid Build Coastguard Worker
202*61046927SAndroid Build Coastguard Worker   /* TCS workgroup size */
203*61046927SAndroid Build Coastguard Worker   p->grids[9] = p->output_patch_size;
204*61046927SAndroid Build Coastguard Worker   p->grids[10] = 1;
205*61046927SAndroid Build Coastguard Worker   p->grids[11] = 1;
206*61046927SAndroid Build Coastguard Worker
207*61046927SAndroid Build Coastguard Worker   /* Tess grid size */
208*61046927SAndroid Build Coastguard Worker   p->grids[12] = unrolled_patches;
209*61046927SAndroid Build Coastguard Worker   p->grids[13] = 1;
210*61046927SAndroid Build Coastguard Worker   p->grids[14] = 1;
211*61046927SAndroid Build Coastguard Worker
212*61046927SAndroid Build Coastguard Worker   /* Tess workgroup size */
213*61046927SAndroid Build Coastguard Worker   p->grids[15] = 64;
214*61046927SAndroid Build Coastguard Worker   p->grids[16] = 1;
215*61046927SAndroid Build Coastguard Worker   p->grids[17] = 1;
216*61046927SAndroid Build Coastguard Worker}
217