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