1 /*
2 * Copyright (c) 2008-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 "pipe/p_defines.h"
9 #include "util/u_bitmask.h"
10 #include "util/format/u_format.h"
11 #include "util/u_inlines.h"
12 #include "util/u_memory.h"
13 #include "util/u_math.h"
14 #include "util/u_memory.h"
15
16 #include "svga_context.h"
17 #include "svga_screen.h"
18 #include "svga_state.h"
19 #include "svga_cmd.h"
20 #include "svga_format.h"
21 #include "svga_shader.h"
22
23
24 struct rs_queue {
25 unsigned rs_count;
26 SVGA3dRenderState rs[SVGA3D_RS_MAX];
27 };
28
29
30 #define EMIT_RS(svga, value, token) \
31 do { \
32 STATIC_ASSERT(SVGA3D_RS_##token < ARRAY_SIZE(svga->state.hw_draw.rs)); \
33 if (svga->state.hw_draw.rs[SVGA3D_RS_##token] != value) { \
34 svga_queue_rs(&queue, SVGA3D_RS_##token, value); \
35 svga->state.hw_draw.rs[SVGA3D_RS_##token] = value; \
36 } \
37 } while (0)
38
39 #define EMIT_RS_FLOAT(svga, fvalue, token) \
40 do { \
41 unsigned value = fui(fvalue); \
42 STATIC_ASSERT(SVGA3D_RS_##token < ARRAY_SIZE(svga->state.hw_draw.rs)); \
43 if (svga->state.hw_draw.rs[SVGA3D_RS_##token] != value) { \
44 svga_queue_rs(&queue, SVGA3D_RS_##token, value); \
45 svga->state.hw_draw.rs[SVGA3D_RS_##token] = value; \
46 } \
47 } while (0)
48
49
50 static inline void
svga_queue_rs(struct rs_queue * q,unsigned rss,unsigned value)51 svga_queue_rs(struct rs_queue *q, unsigned rss, unsigned value)
52 {
53 assert(q->rs_count < ARRAY_SIZE(q->rs));
54 q->rs[q->rs_count].state = rss;
55 q->rs[q->rs_count].uintValue = value;
56 q->rs_count++;
57 }
58
59
60 static unsigned
translate_fill_mode(unsigned fill)61 translate_fill_mode(unsigned fill)
62 {
63 switch (fill) {
64 case PIPE_POLYGON_MODE_POINT:
65 return SVGA3D_FILLMODE_POINT;
66 case PIPE_POLYGON_MODE_LINE:
67 return SVGA3D_FILLMODE_LINE;
68 case PIPE_POLYGON_MODE_FILL:
69 return SVGA3D_FILLMODE_FILL;
70 default:
71 assert(!"Bad fill mode");
72 return SVGA3D_FILLMODE_FILL;
73 }
74 }
75
76
77 /* Compare old and new render states and emit differences between them
78 * to hardware. Simplest implementation would be to emit the whole of
79 * the "to" state.
80 */
81 static enum pipe_error
emit_rss_vgpu9(struct svga_context * svga,uint64_t dirty)82 emit_rss_vgpu9(struct svga_context *svga, uint64_t dirty)
83 {
84 struct svga_screen *screen = svga_screen(svga->pipe.screen);
85 struct rs_queue queue;
86 float point_size_min;
87
88 queue.rs_count = 0;
89
90 if (dirty & (SVGA_NEW_BLEND | SVGA_NEW_BLEND_COLOR)) {
91 const struct svga_blend_state *curr = svga->curr.blend;
92
93 EMIT_RS(svga, curr->rt[0].writemask, COLORWRITEENABLE);
94 EMIT_RS(svga, curr->rt[0].blend_enable, BLENDENABLE);
95
96 if (curr->rt[0].blend_enable) {
97 EMIT_RS(svga, curr->rt[0].srcblend, SRCBLEND);
98 EMIT_RS(svga, curr->rt[0].dstblend, DSTBLEND);
99 EMIT_RS(svga, curr->rt[0].blendeq, BLENDEQUATION);
100
101 EMIT_RS(svga, curr->rt[0].separate_alpha_blend_enable,
102 SEPARATEALPHABLENDENABLE);
103
104 if (curr->rt[0].separate_alpha_blend_enable) {
105 EMIT_RS(svga, curr->rt[0].srcblend_alpha, SRCBLENDALPHA);
106 EMIT_RS(svga, curr->rt[0].dstblend_alpha, DSTBLENDALPHA);
107 EMIT_RS(svga, curr->rt[0].blendeq_alpha, BLENDEQUATIONALPHA);
108 }
109 }
110 }
111
112 if (dirty & SVGA_NEW_BLEND_COLOR) {
113 uint32 color;
114 uint32 r = float_to_ubyte(svga->curr.blend_color.color[0]);
115 uint32 g = float_to_ubyte(svga->curr.blend_color.color[1]);
116 uint32 b = float_to_ubyte(svga->curr.blend_color.color[2]);
117 uint32 a = float_to_ubyte(svga->curr.blend_color.color[3]);
118
119 color = (a << 24) | (r << 16) | (g << 8) | b;
120
121 EMIT_RS(svga, color, BLENDCOLOR);
122 }
123
124 if (dirty & (SVGA_NEW_DEPTH_STENCIL_ALPHA | SVGA_NEW_RAST)) {
125 const struct svga_depth_stencil_state *curr = svga->curr.depth;
126 const struct svga_rasterizer_state *rast = svga->curr.rast;
127
128 if (!curr->stencil[0].enabled) {
129 /* Stencil disabled
130 */
131 EMIT_RS(svga, false, STENCILENABLE);
132 EMIT_RS(svga, false, STENCILENABLE2SIDED);
133 }
134 else if (curr->stencil[0].enabled && !curr->stencil[1].enabled) {
135 /* Regular stencil
136 */
137 EMIT_RS(svga, true, STENCILENABLE);
138 EMIT_RS(svga, false, STENCILENABLE2SIDED);
139
140 EMIT_RS(svga, curr->stencil[0].func, STENCILFUNC);
141 EMIT_RS(svga, curr->stencil[0].fail, STENCILFAIL);
142 EMIT_RS(svga, curr->stencil[0].zfail, STENCILZFAIL);
143 EMIT_RS(svga, curr->stencil[0].pass, STENCILPASS);
144
145 EMIT_RS(svga, curr->stencil_mask, STENCILMASK);
146 EMIT_RS(svga, curr->stencil_writemask, STENCILWRITEMASK);
147 }
148 else {
149 int cw, ccw;
150
151 /* Hardware frontwinding is always CW, so if ours is also CW,
152 * then our definition of front face agrees with hardware.
153 * Otherwise need to flip.
154 */
155 if (rast->templ.front_ccw) {
156 ccw = 0;
157 cw = 1;
158 }
159 else {
160 ccw = 1;
161 cw = 0;
162 }
163
164 /* Twoside stencil
165 */
166 EMIT_RS(svga, true, STENCILENABLE);
167 EMIT_RS(svga, true, STENCILENABLE2SIDED);
168
169 EMIT_RS(svga, curr->stencil[cw].func, STENCILFUNC);
170 EMIT_RS(svga, curr->stencil[cw].fail, STENCILFAIL);
171 EMIT_RS(svga, curr->stencil[cw].zfail, STENCILZFAIL);
172 EMIT_RS(svga, curr->stencil[cw].pass, STENCILPASS);
173
174 EMIT_RS(svga, curr->stencil[ccw].func, CCWSTENCILFUNC);
175 EMIT_RS(svga, curr->stencil[ccw].fail, CCWSTENCILFAIL);
176 EMIT_RS(svga, curr->stencil[ccw].zfail, CCWSTENCILZFAIL);
177 EMIT_RS(svga, curr->stencil[ccw].pass, CCWSTENCILPASS);
178
179 EMIT_RS(svga, curr->stencil_mask, STENCILMASK);
180 EMIT_RS(svga, curr->stencil_writemask, STENCILWRITEMASK);
181 }
182
183 EMIT_RS(svga, curr->zenable, ZENABLE);
184 if (curr->zenable) {
185 EMIT_RS(svga, curr->zfunc, ZFUNC);
186 EMIT_RS(svga, curr->zwriteenable, ZWRITEENABLE);
187 }
188
189 EMIT_RS(svga, curr->alphatestenable, ALPHATESTENABLE);
190 if (curr->alphatestenable) {
191 EMIT_RS(svga, curr->alphafunc, ALPHAFUNC);
192 EMIT_RS_FLOAT(svga, curr->alpharef, ALPHAREF);
193 }
194 }
195
196 if (dirty & SVGA_NEW_STENCIL_REF) {
197 EMIT_RS(svga, svga->curr.stencil_ref.ref_value[0], STENCILREF);
198 }
199
200 if (dirty & (SVGA_NEW_RAST | SVGA_NEW_NEED_PIPELINE)) {
201 const struct svga_rasterizer_state *curr = svga->curr.rast;
202 unsigned cullmode = curr->cullmode;
203
204 /* Shademode: still need to rearrange index list to move
205 * flat-shading PV first vertex.
206 */
207 EMIT_RS(svga, curr->shademode, SHADEMODE);
208
209 EMIT_RS(svga, translate_fill_mode(curr->hw_fillmode), FILLMODE);
210
211 /* Don't do culling while the software pipeline is active. It
212 * does it for us, and additionally introduces potentially
213 * back-facing triangles.
214 */
215 if (svga->state.sw.need_pipeline)
216 cullmode = SVGA3D_FACE_NONE;
217
218 point_size_min = util_get_min_point_size(&curr->templ);
219
220 EMIT_RS(svga, cullmode, CULLMODE);
221 EMIT_RS(svga, curr->scissortestenable, SCISSORTESTENABLE);
222 EMIT_RS(svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS);
223 EMIT_RS(svga, curr->lastpixel, LASTPIXEL);
224 EMIT_RS_FLOAT(svga, curr->pointsize, POINTSIZE);
225 EMIT_RS_FLOAT(svga, point_size_min, POINTSIZEMIN);
226 EMIT_RS_FLOAT(svga, screen->maxPointSize, POINTSIZEMAX);
227 EMIT_RS(svga, curr->pointsprite, POINTSPRITEENABLE);
228
229 /* Emit line state, when the device understands it */
230 if (screen->haveLineStipple)
231 EMIT_RS(svga, curr->linepattern, LINEPATTERN);
232 if (screen->haveLineSmooth)
233 EMIT_RS(svga, curr->antialiasedlineenable, ANTIALIASEDLINEENABLE);
234 if (screen->maxLineWidth > 1.0F)
235 EMIT_RS_FLOAT(svga, curr->linewidth, LINEWIDTH);
236 }
237
238 if (dirty & (SVGA_NEW_RAST |
239 SVGA_NEW_FRAME_BUFFER |
240 SVGA_NEW_NEED_PIPELINE)) {
241 const struct svga_rasterizer_state *curr = svga->curr.rast;
242 float slope = 0.0;
243 float bias = 0.0;
244
245 /* Need to modify depth bias according to bound depthbuffer
246 * format. Don't do hardware depthbias while the software
247 * pipeline is active.
248 */
249 if (!svga->state.sw.need_pipeline &&
250 svga->curr.framebuffer.zsbuf)
251 {
252 slope = curr->slopescaledepthbias;
253 bias = svga->curr.depthscale * curr->depthbias;
254 }
255
256 EMIT_RS_FLOAT(svga, slope, SLOPESCALEDEPTHBIAS);
257 EMIT_RS_FLOAT(svga, bias, DEPTHBIAS);
258 }
259
260 if (dirty & SVGA_NEW_FRAME_BUFFER) {
261 /* XXX: we only look at the first color buffer's sRGB state */
262 float gamma = 1.0f;
263 if (svga->curr.framebuffer.cbufs[0] &&
264 util_format_is_srgb(svga->curr.framebuffer.cbufs[0]->format)) {
265 gamma = 2.2f;
266 }
267 EMIT_RS_FLOAT(svga, gamma, OUTPUTGAMMA);
268 }
269
270 if (dirty & SVGA_NEW_RAST) {
271 /* bitmask of the enabled clip planes */
272 unsigned enabled = svga->curr.rast->templ.clip_plane_enable;
273 EMIT_RS(svga, enabled, CLIPPLANEENABLE);
274 }
275
276 if (queue.rs_count) {
277 SVGA3dRenderState *rs;
278
279 if (SVGA3D_BeginSetRenderState(svga->swc, &rs, queue.rs_count)
280 != PIPE_OK) {
281 /* XXX: need to poison cached hardware state on failure to ensure
282 * dirty state gets re-emitted. Fix this by re-instating partial
283 * FIFOCommit command and only updating cached hw state once the
284 * initial allocation has succeeded.
285 */
286 memset(svga->state.hw_draw.rs, 0xcd, sizeof(svga->state.hw_draw.rs));
287
288 return PIPE_ERROR_OUT_OF_MEMORY;
289 }
290
291 memcpy(rs, queue.rs, queue.rs_count * sizeof queue.rs[0]);
292
293 SVGA_FIFOCommitAll(svga->swc);
294 }
295
296 return PIPE_OK;
297 }
298
299
300 /** Returns a non-culling rasterizer state object to be used with
301 * point sprite.
302 */
303 static struct svga_rasterizer_state *
get_no_cull_rasterizer_state(struct svga_context * svga)304 get_no_cull_rasterizer_state(struct svga_context *svga)
305 {
306 struct svga_rasterizer_state *r = svga->curr.rast;
307
308 if (!r->no_cull_rasterizer) {
309 struct pipe_rasterizer_state rast;
310
311 memset(&rast, 0, sizeof(rast));
312 rast.flatshade = 1;
313 rast.front_ccw = 1;
314 rast.point_smooth = r->templ.point_smooth;
315
316 /* All rasterizer states have the same half_pixel_center,
317 * bottom_edge_rule and clip_halfz values since they are
318 * constant for a context. If we ever implement
319 * GL_ARB_clip_control, the clip_halfz field would have to be observed.
320 */
321 rast.half_pixel_center = r->templ.half_pixel_center;
322 rast.bottom_edge_rule = r->templ.bottom_edge_rule;
323 rast.clip_halfz = r->templ.clip_halfz;
324
325 r->no_cull_rasterizer =
326 svga->pipe.create_rasterizer_state(&svga->pipe, &rast);
327 }
328 return r->no_cull_rasterizer;
329 }
330
331
332 /** Returns a depth stencil state object with depth and stencil test disabled.
333 */
334 static struct svga_depth_stencil_state *
get_no_depth_stencil_test_state(struct svga_context * svga)335 get_no_depth_stencil_test_state(struct svga_context *svga)
336 {
337 if (!svga->depthstencil_disable) {
338 struct pipe_depth_stencil_alpha_state ds = {{{0}}};
339 svga->depthstencil_disable =
340 svga->pipe.create_depth_stencil_alpha_state(&svga->pipe, &ds);
341 }
342 return svga->depthstencil_disable;
343 }
344
345
346 /**
347 * A helper function to create an alternate svga rasterizer state object to use
348 * forcedSampleCount to support multisampled framebuffer without attachments.
349 */
350 static SVGA3dRasterizerStateId
get_alt_rasterizer_state_id(struct svga_context * svga,struct svga_rasterizer_state * rast,unsigned samples)351 get_alt_rasterizer_state_id(struct svga_context *svga,
352 struct svga_rasterizer_state *rast,
353 unsigned samples)
354 {
355 assert(samples <= SVGA_MAX_FRAMEBUFFER_DEFAULT_SAMPLES);
356 assert(samples >= 0);
357
358 if (samples <= 1)
359 return rast->id;
360
361 if (rast->altRastIds[samples] == SVGA3D_INVALID_ID) {
362 rast->altRastIds[samples] = svga_define_rasterizer_object(svga, rast, samples);
363 }
364
365 return rast->altRastIds[samples];
366 }
367
368
369 static enum pipe_error
emit_rss_vgpu10(struct svga_context * svga,uint64_t dirty)370 emit_rss_vgpu10(struct svga_context *svga, uint64_t dirty)
371 {
372 enum pipe_error ret = PIPE_OK;
373
374 svga_hwtnl_flush_retry(svga);
375
376 if (dirty & (SVGA_NEW_BLEND | SVGA_NEW_BLEND_COLOR)) {
377 const struct svga_blend_state *curr;
378 float blend_factor[4];
379
380 if (svga_has_any_integer_cbufs(svga)) {
381 /* Blending is not supported in integer-valued render targets. */
382 curr = svga->noop_blend;
383 blend_factor[0] =
384 blend_factor[1] =
385 blend_factor[2] =
386 blend_factor[3] = 0;
387 }
388 else {
389 curr = svga->curr.blend;
390
391 if (curr->blend_color_alpha) {
392 blend_factor[0] =
393 blend_factor[1] =
394 blend_factor[2] =
395 blend_factor[3] = svga->curr.blend_color.color[3];
396 }
397 else {
398 blend_factor[0] = svga->curr.blend_color.color[0];
399 blend_factor[1] = svga->curr.blend_color.color[1];
400 blend_factor[2] = svga->curr.blend_color.color[2];
401 blend_factor[3] = svga->curr.blend_color.color[3];
402 }
403 }
404
405 /* Set/bind the blend state object */
406 if (svga->state.hw_draw.blend_id != curr->id ||
407 svga->state.hw_draw.blend_factor[0] != blend_factor[0] ||
408 svga->state.hw_draw.blend_factor[1] != blend_factor[1] ||
409 svga->state.hw_draw.blend_factor[2] != blend_factor[2] ||
410 svga->state.hw_draw.blend_factor[3] != blend_factor[3] ||
411 svga->state.hw_draw.blend_sample_mask != svga->curr.sample_mask) {
412 ret = SVGA3D_vgpu10_SetBlendState(svga->swc, curr->id,
413 blend_factor,
414 svga->curr.sample_mask);
415 if (ret != PIPE_OK)
416 return ret;
417
418 svga->state.hw_draw.blend_id = curr->id;
419 svga->state.hw_draw.blend_factor[0] = blend_factor[0];
420 svga->state.hw_draw.blend_factor[1] = blend_factor[1];
421 svga->state.hw_draw.blend_factor[2] = blend_factor[2];
422 svga->state.hw_draw.blend_factor[3] = blend_factor[3];
423 svga->state.hw_draw.blend_sample_mask = svga->curr.sample_mask;
424 }
425 }
426
427 if (svga->disable_rasterizer) {
428 if (!svga->state.hw_draw.rasterizer_discard) {
429 struct svga_depth_stencil_state *ds;
430
431 /* If rasterization is to be disabled, disable depth and stencil
432 * testing as well.
433 */
434 ds = get_no_depth_stencil_test_state(svga);
435 if (ds->id != svga->state.hw_draw.depth_stencil_id) {
436 ret = SVGA3D_vgpu10_SetDepthStencilState(svga->swc, ds->id, 0);
437 if (ret != PIPE_OK)
438 return ret;
439
440 svga->state.hw_draw.depth_stencil_id = ds->id;
441 svga->state.hw_draw.stencil_ref = 0;
442 }
443 svga->state.hw_draw.rasterizer_discard = true;
444 }
445 } else {
446 if ((dirty & (SVGA_NEW_DEPTH_STENCIL_ALPHA | SVGA_NEW_STENCIL_REF)) ||
447 svga->state.hw_draw.rasterizer_discard) {
448 const struct svga_depth_stencil_state *curr = svga->curr.depth;
449 unsigned curr_ref = svga->curr.stencil_ref.ref_value[0];
450
451 if (curr->id != svga->state.hw_draw.depth_stencil_id ||
452 curr_ref != svga->state.hw_draw.stencil_ref) {
453 /* Set/bind the depth/stencil state object */
454 ret = SVGA3D_vgpu10_SetDepthStencilState(svga->swc, curr->id,
455 curr_ref);
456 if (ret != PIPE_OK)
457 return ret;
458
459 svga->state.hw_draw.depth_stencil_id = curr->id;
460 svga->state.hw_draw.stencil_ref = curr_ref;
461 }
462 }
463
464 if (dirty & (SVGA_NEW_REDUCED_PRIMITIVE | SVGA_NEW_RAST |
465 SVGA_NEW_FRAME_BUFFER)) {
466 struct svga_rasterizer_state *rast = svga->curr.rast;
467
468 if (svga->curr.reduced_prim == MESA_PRIM_POINTS &&
469 svga->curr.gs && svga->curr.gs->wide_point) {
470
471 /* If we are drawing a point sprite, we will need to
472 * bind a non-culling rasterizer state object
473 */
474 rast = get_no_cull_rasterizer_state(svga);
475 }
476
477 int rastId = rast->id;
478
479 /* In the case of no-attachment framebuffer, the sample count will be
480 * specified in forcedSampleCount in the RasterizerState_v2 object.
481 */
482 if ((svga->curr.framebuffer.nr_cbufs == 0) &&
483 (svga->curr.framebuffer.zsbuf == NULL)) {
484 rastId =
485 get_alt_rasterizer_state_id(svga, rast,
486 svga->curr.framebuffer.samples);
487
488 if (rastId == SVGA3D_INVALID_ID)
489 return PIPE_ERROR;
490 }
491
492 if (svga->state.hw_draw.rasterizer_id != rastId) {
493 /* Set/bind the rasterizer state object */
494 ret = SVGA3D_vgpu10_SetRasterizerState(svga->swc, rastId);
495 if (ret != PIPE_OK)
496 return ret;
497 svga->state.hw_draw.rasterizer_id = rastId;
498 }
499 }
500 svga->state.hw_draw.rasterizer_discard = false;
501 }
502 return PIPE_OK;
503 }
504
505
506 static enum pipe_error
emit_rss(struct svga_context * svga,uint64_t dirty)507 emit_rss(struct svga_context *svga, uint64_t dirty)
508 {
509 if (svga_have_vgpu10(svga)) {
510 return emit_rss_vgpu10(svga, dirty);
511 }
512 else {
513 return emit_rss_vgpu9(svga, dirty);
514 }
515 }
516
517
518 struct svga_tracked_state svga_hw_rss =
519 {
520 "hw rss state",
521
522 (SVGA_NEW_BLEND |
523 SVGA_NEW_BLEND_COLOR |
524 SVGA_NEW_DEPTH_STENCIL_ALPHA |
525 SVGA_NEW_STENCIL_REF |
526 SVGA_NEW_RAST |
527 SVGA_NEW_FRAME_BUFFER |
528 SVGA_NEW_NEED_PIPELINE |
529 SVGA_NEW_FS |
530 SVGA_NEW_REDUCED_PRIMITIVE),
531
532 emit_rss
533 };
534