1 /*
2 * Copyright (c) 2014-2024 Broadcom. All Rights Reserved.
3 * The term “Broadcom” refers to Broadcom Inc.
4 * and/or its subsidiaries.
5 * SPDX-License-Identifier: MIT
6 */
7
8 #include "util/u_inlines.h"
9 #include "util/u_memory.h"
10 #include "util/u_bitmask.h"
11 #include "translate/translate.h"
12
13 #include "svga_context.h"
14 #include "svga_cmd.h"
15 #include "svga_shader.h"
16 #include "svga_tgsi.h"
17 #include "svga_streamout.h"
18 #include "svga_format.h"
19
20 /**
21 * If we fail to compile a geometry shader we'll use a dummy/fallback shader
22 * that simply emits the incoming vertices.
23 */
24 static const struct tgsi_token *
get_dummy_geometry_shader(void)25 get_dummy_geometry_shader(void)
26 {
27 //XXX
28 return NULL;
29 }
30
31
32 struct svga_shader_variant *
svga_get_compiled_dummy_geometry_shader(struct svga_context * svga,struct svga_shader * shader,const struct svga_compile_key * key)33 svga_get_compiled_dummy_geometry_shader(struct svga_context *svga,
34 struct svga_shader *shader,
35 const struct svga_compile_key *key)
36 {
37 const struct tgsi_token *dummy = get_dummy_geometry_shader();
38 struct svga_shader_variant *variant;
39 struct svga_geometry_shader *gs = (struct svga_geometry_shader *)shader;
40
41 if (!dummy)
42 return NULL;
43
44 FREE((void *) gs->base.tokens);
45 gs->base.tokens = dummy;
46 svga_tgsi_scan_shader(&gs->base);
47 variant = svga_tgsi_compile_shader(svga, shader, key);
48
49 return variant;
50 }
51
52
53 static void
make_gs_key(struct svga_context * svga,struct svga_compile_key * key)54 make_gs_key(struct svga_context *svga, struct svga_compile_key *key)
55 {
56 struct svga_geometry_shader *gs = svga->curr.gs;
57
58 memset(key, 0, sizeof *key);
59
60 /*
61 * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER
62 */
63 svga_init_shader_key_common(svga, PIPE_SHADER_GEOMETRY, &gs->base, key);
64
65 memcpy(key->generic_remap_table, gs->generic_remap_table,
66 sizeof(gs->generic_remap_table));
67
68 key->gs.vs_generic_outputs = svga->curr.vs->base.info.generic_outputs_mask;
69
70 key->gs.need_prescale = svga->state.hw_clear.prescale[0].enabled;
71
72 key->gs.writes_psize = gs->base.info.writes_psize;
73 key->gs.wide_point = gs->wide_point;
74 key->gs.writes_viewport_index = gs->base.info.writes_viewport_index;
75 if (key->gs.writes_viewport_index) {
76 key->gs.num_prescale = svga->state.hw_clear.num_prescale;
77 } else {
78 key->gs.num_prescale = 1;
79 }
80 key->sprite_coord_enable = svga->curr.rast->templ.sprite_coord_enable;
81 key->sprite_origin_lower_left = (svga->curr.rast->templ.sprite_coord_mode
82 == PIPE_SPRITE_COORD_LOWER_LEFT);
83
84 /* SVGA_NEW_RAST */
85 key->clip_plane_enable = svga->curr.rast->templ.clip_plane_enable;
86
87 /* Mark this as the last shader in the vertex processing stage */
88 key->last_vertex_stage = 1;
89 }
90
91
92 static enum pipe_error
emit_hw_gs(struct svga_context * svga,uint64_t dirty)93 emit_hw_gs(struct svga_context *svga, uint64_t dirty)
94 {
95 struct svga_shader_variant *variant;
96 struct svga_geometry_shader *gs = svga->curr.gs;
97 enum pipe_error ret = PIPE_OK;
98 struct svga_compile_key key;
99
100 assert(svga_have_vgpu10(svga));
101
102 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITGS);
103
104 /* If there's a user-defined GS, we should have a pointer to a derived
105 * GS. This should have been resolved in update_tgsi_transform().
106 */
107 if (svga->curr.user_gs)
108 assert(svga->curr.gs);
109
110 if (!gs) {
111 if (svga->state.hw_draw.gs != NULL) {
112
113 /** The previous geometry shader is made inactive.
114 * Needs to unbind the geometry shader.
115 */
116 ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL);
117 if (ret != PIPE_OK)
118 goto done;
119 svga->state.hw_draw.gs = NULL;
120 }
121 goto done;
122 }
123
124 /* If there is stream output info for this geometry shader, then use
125 * it instead of the one from the vertex shader.
126 */
127 if (svga_have_gs_streamout(svga)) {
128 ret = svga_set_stream_output(svga, gs->base.stream_output);
129 if (ret != PIPE_OK) {
130 goto done;
131 }
132 }
133 else if (!svga_have_vs_streamout(svga)) {
134 /* turn off stream out */
135 ret = svga_set_stream_output(svga, NULL);
136 if (ret != PIPE_OK) {
137 goto done;
138 }
139 }
140
141 /* SVGA_NEW_NEED_SWTNL */
142 if (svga->state.sw.need_swtnl && !svga_have_vgpu10(svga)) {
143 /* No geometry shader is needed */
144 variant = NULL;
145 }
146 else {
147 make_gs_key(svga, &key);
148
149 /* See if we already have a GS variant that matches the key */
150 variant = svga_search_shader_key(&gs->base, &key);
151
152 if (!variant) {
153 ret = svga_compile_shader(svga, &gs->base, &key, &variant);
154 if (ret != PIPE_OK)
155 goto done;
156 }
157 }
158
159 if (variant != svga->state.hw_draw.gs) {
160 /* Bind the new variant */
161 ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, variant);
162 if (ret != PIPE_OK)
163 goto done;
164
165 svga->rebind.flags.gs = false;
166 svga->dirty |= SVGA_NEW_GS_VARIANT;
167 svga->state.hw_draw.gs = variant;
168 }
169
170 done:
171 SVGA_STATS_TIME_POP(svga_sws(svga));
172 return ret;
173 }
174
175 struct svga_tracked_state svga_hw_gs =
176 {
177 "geometry shader (hwtnl)",
178 (SVGA_NEW_VS |
179 SVGA_NEW_FS |
180 SVGA_NEW_GS |
181 SVGA_NEW_TEXTURE_BINDING |
182 SVGA_NEW_SAMPLER |
183 SVGA_NEW_RAST |
184 SVGA_NEW_NEED_SWTNL |
185 SVGA_NEW_GS_RAW_BUFFER),
186 emit_hw_gs
187 };
188