xref: /aosp_15_r20/external/mesa3d/src/asahi/lib/shaders/tessellator.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2024 Valve Corporation
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #pragma once
7 
8 #include "libagx.h"
9 
10 enum libagx_tess_partitioning {
11    LIBAGX_TESS_PARTITIONING_FRACTIONAL_ODD,
12    LIBAGX_TESS_PARTITIONING_FRACTIONAL_EVEN,
13    LIBAGX_TESS_PARTITIONING_INTEGER,
14 };
15 
16 enum libagx_tess_output_primitive {
17    LIBAGX_TESS_OUTPUT_POINT,
18    LIBAGX_TESS_OUTPUT_TRIANGLE_CW,
19    LIBAGX_TESS_OUTPUT_TRIANGLE_CCW,
20 };
21 
22 enum libagx_tess_mode {
23    /* Do not actually tessellate, just write the index counts */
24    LIBAGX_TESS_MODE_COUNT,
25 
26    /* Tessellate using the count buffers to allocate indices */
27    LIBAGX_TESS_MODE_WITH_COUNTS,
28 
29    /* Tessellate without count buffers by generating VDM index list words */
30    LIBAGX_TESS_MODE_VDM,
31 };
32 
33 struct libagx_tess_point {
34    float u;
35    float v;
36 };
37 AGX_STATIC_ASSERT(sizeof(struct libagx_tess_point) == 8);
38 
39 struct libagx_tess_args {
40    /* Heap to allocate tessellator outputs in */
41    GLOBAL(struct agx_geometry_state) heap;
42 
43    /* Patch coordinate buffer, indexed as:
44     *
45     *    coord_allocs[patch_ID] + vertex_in_patch
46     */
47    GLOBAL(struct libagx_tess_point) patch_coord_buffer;
48 
49    /* Per-patch index within the heap for the tess coords, written by the
50     * tessellator based on the allocated memory.
51     */
52    GLOBAL(uint32_t) coord_allocs;
53 
54    /* Space for output draws from the tessellator. Either API draw calls or
55     * VDM control words, depending on the mode. */
56    GLOBAL(uint32_t) out_draws;
57 
58    /* Tessellation control shader output buffer. */
59    GLOBAL(float) tcs_buffer;
60 
61    /* Count buffer. # of indices per patch written here, then prefix summed. */
62    GLOBAL(uint32_t) counts;
63 
64    /* Allocated index buffer for all patches, if we're prefix summing counts */
65    GLOBAL(uint32_t) index_buffer;
66 
67    /* Address of the tess eval invocation counter for implementing pipeline
68     * statistics, if active. Zero if inactive. Incremented by tessellator.
69     */
70    GLOBAL(uint32_t) statistic;
71 
72    /* Address of the tess control invocation counter for implementing pipeline
73     * statistics, if active. Zero if inactive. Incremented by indirect tess
74     * setup kernel.
75     */
76    GLOBAL(uint32_t) tcs_statistic;
77 
78    /* For indirect draws with tessellation, the grid sizes. VS then TCS then
79     * tess. Allocated by the CPU and written by the tessellation
80     * setup indirect kernel.
81     */
82    GLOBAL(uint32_t) grids;
83 
84    /* For indirect draws, the indirect draw descriptor. */
85    GLOBAL(uint32_t) indirect;
86 
87    /* For indirect draws, the allocation for the vertex buffer.
88     *
89     * TODO: We could move these fields to an indirect setup kernel, not sure if
90     * it's worth it though...
91     */
92    GLOBAL(uint64_t) vertex_output_buffer_ptr;
93 
94    /* When geom+tess used together, the buffer containing TES outputs (executed
95     * as a hardware compute shader).
96     */
97    uint64_t tes_buffer;
98 
99    /* For indirect draws, the bitfield of VS outputs */
100    uint64_t vertex_outputs;
101 
102    /* Bitfield of TCS per-vertex outputs */
103    uint64_t tcs_per_vertex_outputs;
104 
105    /* Default tess levels used in OpenGL when there is no TCS in the pipeline.
106     * Unused in Vulkan and OpenGL ES.
107     */
108    float tess_level_outer_default[4];
109    float tess_level_inner_default[2];
110 
111    /* Number of vertices in the input patch */
112    uint32_t input_patch_size;
113 
114    /* Number of vertices in the TCS output patch */
115    uint32_t output_patch_size;
116 
117    /* Number of patch constants written by TCS */
118    uint32_t tcs_patch_constants;
119 
120    /* Number of input patches per instance of the VS/TCS */
121    uint32_t patches_per_instance;
122 
123    /* Stride between tessellation facotrs in the TCS output buffer. */
124    uint32_t tcs_stride_el;
125 
126    /* Number of patches being tessellated */
127    uint32_t nr_patches;
128 } PACKED;
129 AGX_STATIC_ASSERT(sizeof(struct libagx_tess_args) == 42 * 4);
130