xref: /aosp_15_r20/external/mesa3d/src/gallium/auxiliary/draw/draw_mesh.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /**************************************************************************
2  *
3  * Copyright 2023 Red Hat.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  *
24  **************************************************************************/
25 
26 #include "draw_mesh.h"
27 #include "draw_context.h"
28 
29 #include "tgsi/tgsi_scan.h"
30 #include "nir/nir_to_tgsi_info.h"
31 #include "pipe/p_shader_tokens.h"
32 
33 struct draw_mesh_shader *
draw_create_mesh_shader(struct draw_context * draw,const struct pipe_shader_state * state)34 draw_create_mesh_shader(struct draw_context *draw,
35                         const struct pipe_shader_state *state)
36 {
37    struct draw_mesh_shader *ms;
38 
39    ms = CALLOC_STRUCT(draw_mesh_shader);
40 
41    if (!ms)
42       return NULL;
43 
44    ms->draw = draw;
45 
46    nir_tgsi_scan_shader(state->ir.nir, &ms->info, true);
47 
48    nir_shader *nir = state->ir.nir;
49 
50    ms->output_primitive = nir->info.mesh.primitive_type;
51 
52    ms->position_output = -1;
53    bool found_clipvertex = false;
54    for (unsigned i = 0; i < ms->info.num_outputs; i++) {
55       if (ms->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
56           ms->info.output_semantic_index[i] == 0)
57          ms->position_output = i;
58       if (ms->info.output_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX)
59          ms->viewport_index_output = i;
60       if (ms->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPVERTEX &&
61           ms->info.output_semantic_index[i] == 0) {
62          found_clipvertex = true;
63          ms->clipvertex_output = i;
64       }
65       if (ms->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) {
66          assert(ms->info.output_semantic_index[i] <
67                       PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
68          ms->ccdistance_output[ms->info.output_semantic_index[i]] = i;
69       }
70    }
71    if (!found_clipvertex)
72       ms->clipvertex_output = ms->position_output;
73    return ms;
74 }
75 
76 void
draw_bind_mesh_shader(struct draw_context * draw,struct draw_mesh_shader * dms)77 draw_bind_mesh_shader(struct draw_context *draw,
78                       struct draw_mesh_shader *dms)
79 {
80    draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
81 
82    if (dms) {
83       draw->ms.mesh_shader = dms;
84       draw->ms.num_ms_outputs = dms->info.num_outputs;
85       draw->ms.position_output = dms->position_output;
86       draw->ms.clipvertex_output = dms->clipvertex_output;
87    } else {
88       draw->ms.mesh_shader = NULL;
89       draw->ms.num_ms_outputs = 0;
90    }
91 }
92 
93 void
draw_delete_mesh_shader(struct draw_context * draw,struct draw_mesh_shader * dms)94 draw_delete_mesh_shader(struct draw_context *draw,
95                         struct draw_mesh_shader *dms)
96 {
97    if (!dms)
98       return;
99 
100    FREE(dms);
101 }
102