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 "util/format/u_format.h"
9 #include "util/u_bitmask.h"
10 #include "util/u_inlines.h"
11 #include "util/u_memory.h"
12 #include "pipe/p_defines.h"
13 #include "util/u_upload_mgr.h"
14
15 #include "svga_screen.h"
16 #include "svga_context.h"
17 #include "svga_state.h"
18 #include "svga_cmd.h"
19 #include "svga_tgsi.h"
20 #include "svga_debug.h"
21 #include "svga_resource_buffer.h"
22 #include "svga_shader.h"
23
24 #include "svga_hw_reg.h"
25
26
27 static unsigned
svga_get_image_size_constant(const struct svga_context * svga,float ** dest,enum pipe_shader_type shader,unsigned num_image_views,const struct svga_image_view images[PIPE_SHADER_TYPES][SVGA3D_MAX_UAVIEWS])28 svga_get_image_size_constant(const struct svga_context *svga, float **dest,
29 enum pipe_shader_type shader,
30 unsigned num_image_views,
31 const struct svga_image_view images[PIPE_SHADER_TYPES][SVGA3D_MAX_UAVIEWS])
32 {
33 uint32_t *dest_u = (uint32_t *) *dest;
34
35 for (int i = 0; i < num_image_views; i++) {
36 if (images[shader][i].desc.resource) {
37 if (images[shader][i].desc.resource->target == PIPE_BUFFER) {
38 unsigned bytes_per_element = util_format_get_blocksize(images[shader][i].desc.format);
39 *dest_u++ = images[shader][i].desc.resource->width0 / bytes_per_element;
40 }
41 else
42 *dest_u++ = images[shader][i].desc.resource->width0;
43
44 if (images[shader][i].desc.resource->target == PIPE_TEXTURE_1D_ARRAY)
45 *dest_u++ = images[shader][i].desc.resource->array_size;
46 else
47 *dest_u++ = images[shader][i].desc.resource->height0;
48
49 if (images[shader][i].desc.resource->target == PIPE_TEXTURE_2D_ARRAY)
50 *dest_u++ = images[shader][i].desc.resource->array_size;
51 else if (images[shader][i].desc.resource->target == PIPE_TEXTURE_CUBE_ARRAY)
52 *dest_u++ = images[shader][i].desc.resource->array_size / 6;
53 else
54 *dest_u++ = images[shader][i].desc.resource->depth0;
55 *dest_u++ = 1; // Later this can be used for sample counts
56 }
57 else {
58 *dest_u += 4;
59 }
60 }
61 return num_image_views;
62 }
63
64
65 /*
66 * Don't try to send more than 4kb of successive constants.
67 */
68 #define MAX_CONST_REG_COUNT 256 /**< number of float[4] constants */
69
70 /**
71 * Extra space for svga-specific VS/PS constants (such as texcoord
72 * scale factors, vertex transformation scale/translation).
73 */
74 #define MAX_EXTRA_CONSTS 32
75
76 /** Guest-backed surface constant buffers must be this size */
77 #define GB_CONSTBUF_SIZE (SVGA3D_CONSTREG_MAX)
78
79
80 /**
81 * Emit any extra shader-type-independent shader constants into the buffer
82 * pointed to by 'dest'.
83 * \return number of float[4] constants put into the 'dest' buffer
84 */
85 static unsigned
svga_get_extra_constants_common(const struct svga_context * svga,const struct svga_shader_variant * variant,enum pipe_shader_type shader,float * dest)86 svga_get_extra_constants_common(const struct svga_context *svga,
87 const struct svga_shader_variant *variant,
88 enum pipe_shader_type shader, float *dest)
89 {
90 uint32_t *dest_u = (uint32_t *) dest; // uint version of dest
91 unsigned i;
92 unsigned count = 0;
93
94 for (i = 0; i < variant->key.num_textures; i++) {
95 const struct pipe_sampler_view *sv = svga->curr.sampler_views[shader][i];
96 if (sv) {
97 const struct pipe_resource *tex = sv->texture;
98 /* Scaling factors needed for handling unnormalized texture coordinates
99 * for texture rectangles.
100 */
101 if (variant->key.tex[i].unnormalized) {
102 /* debug/sanity check */
103 assert(variant->key.tex[i].width_height_idx == count);
104
105 *dest++ = 1.0f / (float) tex->width0;
106 *dest++ = 1.0f / (float) tex->height0;
107 *dest++ = 1.0f;
108 *dest++ = 1.0f;
109
110 count++;
111 }
112
113 /* Store the sizes for texture buffers.
114 */
115 if (tex->target == PIPE_BUFFER) {
116 unsigned bytes_per_element = util_format_get_blocksize(sv->format);
117 *dest_u++ = tex->width0 / bytes_per_element;
118 *dest_u++ = 1;
119 *dest_u++ = 1;
120 *dest_u++ = 1;
121
122 count++;
123 }
124 }
125 }
126
127 /* image_size */
128 if (variant->key.image_size_used) {
129 count += svga_get_image_size_constant(svga, &dest, shader,
130 svga->state.hw_draw.num_image_views[shader],
131 svga->state.hw_draw.image_views);
132 }
133
134
135 return count;
136 }
137
138
139 /**
140 * Emit any extra fragment shader constants into the buffer pointed
141 * to by 'dest'.
142 * \return number of float[4] constants put into the dest buffer
143 */
144 static unsigned
svga_get_extra_fs_constants(const struct svga_context * svga,float * dest)145 svga_get_extra_fs_constants(const struct svga_context *svga, float *dest)
146 {
147 const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
148 unsigned count = 0;
149
150 count += svga_get_extra_constants_common(svga, variant,
151 PIPE_SHADER_FRAGMENT, dest);
152
153 assert(count <= MAX_EXTRA_CONSTS);
154
155 return count;
156 }
157
158 /**
159 * Emit extra constants needed for prescale computation into the
160 * the buffer pointed to by '*dest'. The updated buffer pointer
161 * will be returned in 'dest'.
162 */
163 static unsigned
svga_get_prescale_constants(const struct svga_context * svga,float ** dest,const struct svga_prescale * prescale)164 svga_get_prescale_constants(const struct svga_context *svga, float **dest,
165 const struct svga_prescale *prescale)
166 {
167 memcpy(*dest, prescale->scale, 4 * sizeof(float));
168 *dest += 4;
169
170 memcpy(*dest, prescale->translate, 4 * sizeof(float));
171 *dest += 4;
172
173 return 2;
174 }
175
176 /**
177 * Emit extra constants needed for point sprite emulation.
178 */
179 static unsigned
svga_get_pt_sprite_constants(const struct svga_context * svga,float ** dest)180 svga_get_pt_sprite_constants(const struct svga_context *svga, float **dest)
181 {
182 const struct svga_screen *screen = svga_screen(svga->pipe.screen);
183 float *dst = *dest;
184
185 dst[0] = 1.0 / (svga->curr.viewport[0].scale[0] * 2);
186 dst[1] = 1.0 / (svga->curr.viewport[0].scale[1] * 2);
187 dst[2] = svga->curr.rast->pointsize;
188 dst[3] = screen->maxPointSize;
189 *dest = *dest + 4;
190 return 1;
191 }
192
193 /**
194 * Emit user-defined clip plane coefficients into the buffer pointed to
195 * by '*dest'. The updated buffer pointer will be returned in 'dest'.
196 */
197 static unsigned
svga_get_clip_plane_constants(const struct svga_context * svga,const struct svga_shader_variant * variant,float ** dest)198 svga_get_clip_plane_constants(const struct svga_context *svga,
199 const struct svga_shader_variant *variant,
200 float **dest)
201 {
202 unsigned count = 0;
203
204 /* SVGA_NEW_CLIP */
205 if (svga_have_vgpu10(svga)) {
206 /* append user-defined clip plane coefficients onto constant buffer */
207 unsigned clip_planes = variant->key.clip_plane_enable;
208 while (clip_planes) {
209 int i = u_bit_scan(&clip_planes);
210 COPY_4V(*dest, svga->curr.clip.ucp[i]);
211 *dest += 4;
212 count += 1;
213 }
214 }
215 return count;
216 }
217
218
219 /**
220 * Emit any extra vertex shader constants into the buffer pointed
221 * to by 'dest'.
222 * In particular, these would be the scale and bias factors computed
223 * from the framebuffer size which are used to copy with differences in
224 * GL vs D3D coordinate spaces. See svga_tgsi_insn.c for more info.
225 * \return number of float[4] constants put into the dest buffer
226 */
227 static unsigned
svga_get_extra_vs_constants(const struct svga_context * svga,float * dest)228 svga_get_extra_vs_constants(const struct svga_context *svga, float *dest)
229 {
230 const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
231 unsigned count = 0;
232
233 /* SVGA_NEW_VS_VARIANT
234 */
235 if (variant->key.vs.need_prescale) {
236 count += svga_get_prescale_constants(svga, &dest,
237 &svga->state.hw_clear.prescale[0]);
238 }
239
240 if (variant->key.vs.undo_viewport) {
241 /* Used to convert window coords back to NDC coords */
242 dest[0] = 1.0f / svga->curr.viewport[0].scale[0];
243 dest[1] = 1.0f / svga->curr.viewport[0].scale[1];
244 dest[2] = -svga->curr.viewport[0].translate[0];
245 dest[3] = -svga->curr.viewport[0].translate[1];
246 dest += 4;
247 count += 1;
248 }
249
250 /* Bias to be added to VertexID */
251 if (variant->key.vs.need_vertex_id_bias) {
252 uint32_t *dest_u = (uint32_t *) dest; // uint version of dest
253 dest_u[0] = svga->curr.vertex_id_bias;
254 dest_u[1] = 1;
255 dest_u[2] = 1;
256 dest_u[3] = 1;
257 dest+=4;
258 count++;
259 }
260
261 /* SVGA_NEW_CLIP */
262 count += svga_get_clip_plane_constants(svga, variant, &dest);
263
264 /* common constants */
265 count += svga_get_extra_constants_common(svga, variant,
266 PIPE_SHADER_VERTEX, dest);
267
268 assert(count <= MAX_EXTRA_CONSTS);
269
270 return count;
271 }
272
273 /**
274 * Emit any extra geometry shader constants into the buffer pointed
275 * to by 'dest'.
276 */
277 static unsigned
svga_get_extra_gs_constants(const struct svga_context * svga,float * dest)278 svga_get_extra_gs_constants(const struct svga_context *svga, float *dest)
279 {
280 const struct svga_shader_variant *variant = svga->state.hw_draw.gs;
281 unsigned count = 0;
282
283 /* SVGA_NEW_GS_VARIANT
284 */
285
286 /* Constants for point sprite
287 * These are used in the transformed gs that supports point sprite.
288 * They need to be added before the prescale constants.
289 */
290 if (variant->key.gs.wide_point) {
291 count += svga_get_pt_sprite_constants(svga, &dest);
292 }
293
294 if (variant->key.gs.need_prescale) {
295 unsigned i, num_prescale = 1;
296
297 /* If prescale is needed and the geometry shader writes to viewport
298 * index, then prescale for all viewports will be added to the
299 * constant buffer.
300 */
301 if (variant->key.gs.writes_viewport_index)
302 num_prescale = svga->state.hw_clear.num_prescale;
303
304 for (i = 0; i < num_prescale; i++) {
305 count +=
306 svga_get_prescale_constants(svga, &dest,
307 &svga->state.hw_clear.prescale[i]);
308 }
309 }
310
311 /* SVGA_NEW_CLIP */
312 count += svga_get_clip_plane_constants(svga, variant, &dest);
313
314 /* common constants */
315 count += svga_get_extra_constants_common(svga, variant,
316 PIPE_SHADER_GEOMETRY, dest);
317
318 assert(count <= MAX_EXTRA_CONSTS);
319 return count;
320 }
321
322
323 /**
324 * Emit any extra tessellation control shader constants into the
325 * buffer pointed to by 'dest'.
326 */
327 static unsigned
svga_get_extra_tcs_constants(struct svga_context * svga,float * dest)328 svga_get_extra_tcs_constants(struct svga_context *svga, float *dest)
329 {
330 const struct svga_shader_variant *variant = svga->state.hw_draw.tcs;
331 unsigned count = 0;
332
333 /* SVGA_NEW_CLIP */
334 count += svga_get_clip_plane_constants(svga, variant, &dest);
335
336 /* common constants */
337 count += svga_get_extra_constants_common(svga, variant,
338 PIPE_SHADER_TESS_CTRL,
339 dest);
340
341 assert(count <= MAX_EXTRA_CONSTS);
342 return count;
343 }
344
345
346 /**
347 * Emit any extra tessellation evaluation shader constants into
348 * the buffer pointed to by 'dest'.
349 */
350 static unsigned
svga_get_extra_tes_constants(struct svga_context * svga,float * dest)351 svga_get_extra_tes_constants(struct svga_context *svga, float *dest)
352 {
353 const struct svga_shader_variant *variant = svga->state.hw_draw.tes;
354 unsigned count = 0;
355
356 if (variant->key.tes.need_prescale) {
357 count += svga_get_prescale_constants(svga, &dest,
358 &svga->state.hw_clear.prescale[0]);
359 }
360
361 /* SVGA_NEW_CLIP */
362 count += svga_get_clip_plane_constants(svga, variant, &dest);
363
364 /* common constants */
365 count += svga_get_extra_constants_common(svga, variant,
366 PIPE_SHADER_TESS_EVAL,
367 dest);
368
369 assert(count <= MAX_EXTRA_CONSTS);
370 return count;
371 }
372
373
374 /**
375 * Emit any extra compute shader constants into
376 * the buffer pointed to by 'dest'.
377 */
378 static unsigned
svga_get_extra_cs_constants(struct svga_context * svga,float * dest)379 svga_get_extra_cs_constants(struct svga_context *svga, float *dest)
380 {
381 const struct svga_shader_variant *variant = svga->state.hw_draw.cs;
382 unsigned count = 0;
383
384 /* common constants */
385 count += svga_get_extra_constants_common(svga, variant,
386 PIPE_SHADER_COMPUTE,
387 dest);
388
389 assert(count <= MAX_EXTRA_CONSTS);
390 return count;
391 }
392
393
394 /*
395 * Check and emit a range of shader constant registers, trying to coalesce
396 * successive shader constant updates in a single command in order to save
397 * space on the command buffer. This is a HWv8 feature.
398 */
399 static enum pipe_error
emit_const_range(struct svga_context * svga,enum pipe_shader_type shader,unsigned offset,unsigned count,const float (* values)[4])400 emit_const_range(struct svga_context *svga,
401 enum pipe_shader_type shader,
402 unsigned offset,
403 unsigned count,
404 const float (*values)[4])
405 {
406 unsigned i, j;
407 enum pipe_error ret;
408
409 assert(shader == PIPE_SHADER_VERTEX ||
410 shader == PIPE_SHADER_FRAGMENT);
411 assert(!svga_have_vgpu10(svga));
412
413 #if MESA_DEBUG
414 if (offset + count > SVGA3D_CONSTREG_MAX) {
415 debug_printf("svga: too many constants (offset %u + count %u = %u (max = %u))\n",
416 offset, count, offset + count, SVGA3D_CONSTREG_MAX);
417 }
418 #endif
419
420 if (offset > SVGA3D_CONSTREG_MAX) {
421 /* This isn't OK, but if we propagate an error all the way up we'll
422 * just get into more trouble.
423 * XXX note that offset is always zero at this time so this is moot.
424 */
425 return PIPE_OK;
426 }
427
428 if (offset + count > SVGA3D_CONSTREG_MAX) {
429 /* Just drop the extra constants for now.
430 * Ideally we should not have allowed the app to create a shader
431 * that exceeds our constant buffer size but there's no way to
432 * express that in gallium at this time.
433 */
434 count = SVGA3D_CONSTREG_MAX - offset;
435 }
436
437 i = 0;
438 while (i < count) {
439 if (memcmp(svga->state.hw_draw.cb[shader][offset + i],
440 values[i],
441 4 * sizeof(float)) != 0) {
442 /* Found one dirty constant
443 */
444 if (SVGA_DEBUG & DEBUG_CONSTS)
445 debug_printf("%s %s %d: %f %f %f %f\n",
446 __func__,
447 shader == PIPE_SHADER_VERTEX ? "VERT" : "FRAG",
448 offset + i,
449 values[i][0],
450 values[i][1],
451 values[i][2],
452 values[i][3]);
453
454 /* Look for more consecutive dirty constants.
455 */
456 j = i + 1;
457 while (j < count &&
458 j < i + MAX_CONST_REG_COUNT &&
459 memcmp(svga->state.hw_draw.cb[shader][offset + j],
460 values[j],
461 4 * sizeof(float)) != 0) {
462
463 if (SVGA_DEBUG & DEBUG_CONSTS)
464 debug_printf("%s %s %d: %f %f %f %f\n",
465 __func__,
466 shader == PIPE_SHADER_VERTEX ? "VERT" : "FRAG",
467 offset + j,
468 values[j][0],
469 values[j][1],
470 values[j][2],
471 values[j][3]);
472
473 ++j;
474 }
475
476 assert(j >= i + 1);
477
478 /* Send them all together.
479 */
480 if (svga_have_gb_objects(svga)) {
481 ret = SVGA3D_SetGBShaderConstsInline(svga->swc,
482 offset + i, /* start */
483 j - i, /* count */
484 svga_shader_type(shader),
485 SVGA3D_CONST_TYPE_FLOAT,
486 values + i);
487 }
488 else {
489 ret = SVGA3D_SetShaderConsts(svga->swc,
490 offset + i, j - i,
491 svga_shader_type(shader),
492 SVGA3D_CONST_TYPE_FLOAT,
493 values + i);
494 }
495 if (ret != PIPE_OK) {
496 return ret;
497 }
498
499 /*
500 * Local copy of the hardware state.
501 */
502 memcpy(svga->state.hw_draw.cb[shader][offset + i],
503 values[i],
504 (j - i) * 4 * sizeof(float));
505
506 i = j + 1;
507
508 svga->hud.num_const_updates++;
509
510 } else {
511 ++i;
512 }
513 }
514
515 return PIPE_OK;
516 }
517
518
519 /**
520 * Emit all the constants in a constant buffer for a shader stage.
521 * On VGPU10, emit_consts_vgpu10 is used instead.
522 */
523 static enum pipe_error
emit_consts_vgpu9(struct svga_context * svga,enum pipe_shader_type shader)524 emit_consts_vgpu9(struct svga_context *svga, enum pipe_shader_type shader)
525 {
526 const struct pipe_constant_buffer *cbuf;
527 struct pipe_transfer *transfer = NULL;
528 unsigned count;
529 const float (*data)[4] = NULL;
530 enum pipe_error ret = PIPE_OK;
531 const unsigned offset = 0;
532
533 assert(shader < PIPE_SHADER_TYPES);
534 assert(!svga_have_vgpu10(svga));
535 /* Only one constant buffer per shader is supported before VGPU10.
536 * This is only an approximate check against that.
537 */
538 assert(svga->curr.constbufs[shader][1].buffer == NULL);
539
540 cbuf = &svga->curr.constbufs[shader][0];
541
542 if (svga->curr.constbufs[shader][0].buffer) {
543 /* emit user-provided constants */
544 data = (const float (*)[4])
545 pipe_buffer_map(&svga->pipe, svga->curr.constbufs[shader][0].buffer,
546 PIPE_MAP_READ, &transfer);
547 if (!data) {
548 return PIPE_ERROR_OUT_OF_MEMORY;
549 }
550
551 /* sanity check */
552 assert(cbuf->buffer->width0 >= cbuf->buffer_size);
553
554 /* Use/apply the constant buffer size and offsets here */
555 count = cbuf->buffer_size / (4 * sizeof(float));
556 data += cbuf->buffer_offset / (4 * sizeof(float));
557
558 ret = emit_const_range( svga, shader, offset, count, data );
559
560 pipe_buffer_unmap(&svga->pipe, transfer);
561
562 if (ret != PIPE_OK) {
563 return ret;
564 }
565 }
566
567 /* emit extra shader constants */
568 {
569 const struct svga_shader_variant *variant = NULL;
570 unsigned offset;
571 float extras[MAX_EXTRA_CONSTS][4];
572 unsigned count;
573
574 switch (shader) {
575 case PIPE_SHADER_VERTEX:
576 variant = svga->state.hw_draw.vs;
577 count = svga_get_extra_vs_constants(svga, (float *) extras);
578 break;
579 case PIPE_SHADER_FRAGMENT:
580 variant = svga->state.hw_draw.fs;
581 count = svga_get_extra_fs_constants(svga, (float *) extras);
582 break;
583 default:
584 assert(!"Unexpected shader type");
585 count = 0;
586 }
587
588 assert(variant);
589 offset = variant->shader->info.constbuf0_num_uniforms;
590 assert(count <= ARRAY_SIZE(extras));
591
592 if (count > 0) {
593 ret = emit_const_range(svga, shader, offset, count,
594 (const float (*) [4])extras);
595 }
596 }
597
598 return ret;
599 }
600
601
602 /**
603 * A helper function to destroy any pending unused srv.
604 */
605 void
svga_destroy_rawbuf_srv(struct svga_context * svga)606 svga_destroy_rawbuf_srv(struct svga_context *svga)
607 {
608 unsigned index = 0;
609
610 while ((index = util_bitmask_get_next_index(
611 svga->sampler_view_to_free_id_bm, index))
612 != UTIL_BITMASK_INVALID_INDEX) {
613
614 SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyShaderResourceView(svga->swc,
615 index));
616 util_bitmask_clear(svga->sampler_view_id_bm, index);
617 util_bitmask_clear(svga->sampler_view_to_free_id_bm, index);
618 }
619 }
620
621 /**
622 * A helper function to emit constant buffer as srv raw buffer.
623 */
624 enum pipe_error
svga_emit_rawbuf(struct svga_context * svga,unsigned slot,enum pipe_shader_type shader,unsigned buffer_offset,unsigned buffer_size,void * buffer)625 svga_emit_rawbuf(struct svga_context *svga,
626 unsigned slot,
627 enum pipe_shader_type shader,
628 unsigned buffer_offset,
629 unsigned buffer_size,
630 void *buffer)
631 {
632 enum pipe_error ret = PIPE_OK;
633
634 assert(slot < SVGA_MAX_RAW_BUFS);
635
636 struct svga_raw_buffer *rawbuf = &svga->state.hw_draw.rawbufs[shader][slot];
637 struct svga_winsys_surface *buf_handle = NULL;
638 unsigned srvid = SVGA3D_INVALID_ID;
639 unsigned enabled_rawbufs = svga->state.hw_draw.enabled_rawbufs[shader];
640
641 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITRAWBUFFER);
642
643 if (buffer == NULL) {
644 if ((svga->state.hw_draw.enabled_rawbufs[shader] & (1 << slot)) == 0) {
645 goto done;
646 }
647 enabled_rawbufs &= ~(1 << slot);
648 }
649 else {
650 if ((rawbuf->buffer_offset != buffer_offset) ||
651 (rawbuf->buffer_size != buffer_size) ||
652 (rawbuf->buffer != buffer)) {
653
654 /* Add the current srvid to the delete list */
655 if (rawbuf->srvid != SVGA3D_INVALID_ID) {
656 util_bitmask_set(svga->sampler_view_to_free_id_bm, rawbuf->srvid);
657 rawbuf->srvid = SVGA3D_INVALID_ID;
658 }
659
660 buf_handle = svga_buffer_handle(svga, buffer,
661 PIPE_BIND_SAMPLER_VIEW);
662 if (!buf_handle) {
663 ret = PIPE_ERROR_OUT_OF_MEMORY;
664 goto done;
665 }
666
667 /* Create a srv for the constant buffer */
668 srvid = util_bitmask_add(svga->sampler_view_id_bm);
669
670 SVGA3dShaderResourceViewDesc viewDesc;
671 viewDesc.bufferex.firstElement = buffer_offset / 4;
672 viewDesc.bufferex.numElements = buffer_size / 4;
673 viewDesc.bufferex.flags = SVGA3D_BUFFEREX_SRV_RAW;
674
675 ret = SVGA3D_vgpu10_DefineShaderResourceView(svga->swc,
676 srvid, buf_handle, SVGA3D_R32_TYPELESS,
677 SVGA3D_RESOURCE_BUFFEREX, &viewDesc);
678
679 if (ret != PIPE_OK) {
680 util_bitmask_clear(svga->sampler_view_id_bm, srvid);
681 goto done;
682 }
683
684 /* Save the current raw buffer attributes in the slot */
685 rawbuf->srvid = srvid;
686 rawbuf->buffer_size = buffer_size;
687 rawbuf->buffer = buffer;
688 rawbuf->handle = buf_handle;
689
690 SVGA_STATS_COUNT_INC(svga_sws(svga), SVGA_STATS_COUNT_RAWBUFFERSRVIEW);
691 }
692 else {
693 /* Same buffer attributes in the slot. Can use the same SRV. */
694 assert(rawbuf->srvid != SVGA3D_INVALID_ID);
695 srvid = rawbuf->srvid;
696 buf_handle = rawbuf->handle;
697 }
698 enabled_rawbufs |= (1 << slot);
699 }
700
701 ret = SVGA3D_vgpu10_SetShaderResources(svga->swc,
702 svga_shader_type(shader),
703 slot + PIPE_MAX_SAMPLERS,
704 1,
705 &srvid,
706 &buf_handle);
707 if (ret != PIPE_OK) {
708 goto done;
709 }
710
711 /* Save the enabled rawbuf state */
712 svga->state.hw_draw.enabled_rawbufs[shader] = enabled_rawbufs;
713
714 done:
715 SVGA_STATS_TIME_POP(svga_sws(svga));
716 return ret;
717 }
718
719
720 /**
721 * A helper function to emit a constant buffer binding at the
722 * specified slot for the specified shader type
723 */
724 static enum pipe_error
emit_constbuf(struct svga_context * svga,unsigned slot,enum pipe_shader_type shader,unsigned buffer_offset,unsigned buffer_size,const void * buffer,unsigned extra_buffer_offset,unsigned extra_buffer_size,const void * extra_buffer)725 emit_constbuf(struct svga_context *svga,
726 unsigned slot,
727 enum pipe_shader_type shader,
728 unsigned buffer_offset,
729 unsigned buffer_size,
730 const void *buffer,
731 unsigned extra_buffer_offset,
732 unsigned extra_buffer_size,
733 const void *extra_buffer)
734 {
735 struct svga_buffer *sbuf = svga_buffer((struct pipe_resource *)buffer);
736 struct pipe_resource *dst_buffer = NULL;
737 enum pipe_error ret = PIPE_OK;
738 struct pipe_transfer *src_transfer;
739 struct svga_winsys_surface *dst_handle = NULL;
740 unsigned new_buf_size = 0;
741 unsigned alloc_buf_size;
742 unsigned offset = 0;;
743 void *src_map = NULL, *dst_map;
744
745 if ((sbuf && sbuf->swbuf) || extra_buffer) {
746
747 /* buffer here is a user-space buffer so mapping it is really cheap. */
748 if (buffer_size > 0) {
749 src_map = pipe_buffer_map_range(&svga->pipe,
750 (struct pipe_resource *)buffer,
751 buffer_offset, buffer_size,
752 PIPE_MAP_READ, &src_transfer);
753 assert(src_map);
754 if (!src_map) {
755 return PIPE_ERROR_OUT_OF_MEMORY;
756 }
757 }
758
759 new_buf_size = MAX2(buffer_size, extra_buffer_offset) + extra_buffer_size;
760
761 /* According to the DX10 spec, the constant buffer size must be
762 * in multiples of 16.
763 */
764 new_buf_size = align(new_buf_size, 16);
765
766 /* Constant buffer size in the upload buffer must be in multiples of 256.
767 * In order to maximize the chance of merging the upload buffer chunks
768 * when svga_buffer_add_range() is called,
769 * the allocate buffer size needs to be in multiples of 256 as well.
770 * Otherwise, since there is gap between each dirty range of the upload buffer,
771 * each dirty range will end up in its own UPDATE_GB_IMAGE command.
772 */
773 alloc_buf_size = align(new_buf_size, CONST0_UPLOAD_ALIGNMENT);
774
775 u_upload_alloc(svga->const0_upload, 0, alloc_buf_size,
776 CONST0_UPLOAD_ALIGNMENT, &offset,
777 &dst_buffer, &dst_map);
778
779 if (!dst_map) {
780 if (src_map)
781 pipe_buffer_unmap(&svga->pipe, src_transfer);
782 return PIPE_ERROR_OUT_OF_MEMORY;
783 }
784
785 /* Initialize the allocated buffer slot to 0 to ensure the padding is
786 * filled with 0.
787 */
788 memset(dst_map, 0, alloc_buf_size);
789
790 if (src_map) {
791 memcpy(dst_map, src_map, buffer_size);
792 pipe_buffer_unmap(&svga->pipe, src_transfer);
793 }
794
795 if (extra_buffer_size) {
796 assert(extra_buffer_offset + extra_buffer_size <= new_buf_size);
797 memcpy((char *) dst_map + extra_buffer_offset, extra_buffer,
798 extra_buffer_size);
799 }
800
801 /* Get winsys handle for the constant buffer */
802 if (svga->state.hw_draw.const0_buffer == dst_buffer &&
803 svga->state.hw_draw.const0_handle) {
804 /* re-reference already mapped buffer */
805 dst_handle = svga->state.hw_draw.const0_handle;
806 }
807 else {
808 /* we must unmap the buffer before getting the winsys handle */
809 u_upload_unmap(svga->const0_upload);
810
811 dst_handle = svga_buffer_handle(svga, dst_buffer,
812 PIPE_BIND_CONSTANT_BUFFER);
813 if (!dst_handle) {
814 pipe_resource_reference(&dst_buffer, NULL);
815 return PIPE_ERROR_OUT_OF_MEMORY;
816 }
817 }
818 }
819 else if (sbuf) {
820 dst_handle = svga_buffer_handle(svga, &sbuf->b, PIPE_BIND_CONSTANT_BUFFER);
821 new_buf_size = align(buffer_size, 16);
822 offset = buffer_offset;
823 }
824
825 assert(new_buf_size % 16 == 0);
826
827 /* clamp the buf size before sending the command */
828 new_buf_size = MIN2(new_buf_size, SVGA3D_DX_MAX_CONSTBUF_BINDING_SIZE);
829
830 const struct svga_screen *screen = svga_screen(svga->pipe.screen);
831 const struct svga_winsys_screen *sws = screen->sws;
832
833 /* Issue the SetSingleConstantBuffer command */
834 if (!sws->have_constant_buffer_offset_cmd ||
835 svga->state.hw_draw.constbufoffsets[shader][slot].handle != dst_handle ||
836 svga->state.hw_draw.constbufoffsets[shader][slot].size != new_buf_size) {
837 ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
838 slot, /* index */
839 svga_shader_type(shader),
840 dst_handle,
841 offset,
842 new_buf_size);
843 }
844 else if (dst_handle){
845 unsigned command = SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET +
846 svga_shader_type(shader) - SVGA3D_SHADERTYPE_VS;
847 ret = SVGA3D_vgpu10_SetConstantBufferOffset(svga->swc,
848 command,
849 slot, /* index */
850 offset);
851 }
852
853 if (ret != PIPE_OK) {
854 pipe_resource_reference(&dst_buffer, NULL);
855 return ret;
856 }
857
858 /* save the upload buffer / handle for next time */
859 if (dst_buffer != buffer && dst_buffer) {
860 pipe_resource_reference(&svga->state.hw_draw.const0_buffer, dst_buffer);
861 svga->state.hw_draw.const0_handle = dst_handle;
862 }
863
864 /* Save this const buffer until it's replaced in the future.
865 * Otherwise, all references to the buffer will go away after the
866 * command buffer is submitted, it'll get recycled and we will have
867 * incorrect constant buffer bindings.
868 */
869 pipe_resource_reference(&svga->state.hw_draw.constbuf[shader][slot], dst_buffer);
870 svga->state.hw_draw.constbufoffsets[shader][slot].handle = dst_handle;
871 svga->state.hw_draw.constbufoffsets[shader][slot].size = new_buf_size;
872
873 pipe_resource_reference(&dst_buffer, NULL);
874
875 return PIPE_OK;
876 }
877
878
879 /* For constbuf 0 */
880 static enum pipe_error
emit_consts_vgpu10(struct svga_context * svga,enum pipe_shader_type shader)881 emit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
882 {
883 const struct pipe_constant_buffer *cbuf;
884 enum pipe_error ret = PIPE_OK;
885 float extras[MAX_EXTRA_CONSTS][4];
886 unsigned extra_count, extra_size, extra_offset;
887 const struct svga_shader_variant *variant;
888
889 assert(shader == PIPE_SHADER_VERTEX ||
890 shader == PIPE_SHADER_GEOMETRY ||
891 shader == PIPE_SHADER_FRAGMENT ||
892 shader == PIPE_SHADER_TESS_CTRL ||
893 shader == PIPE_SHADER_TESS_EVAL ||
894 shader == PIPE_SHADER_COMPUTE);
895
896 cbuf = &svga->curr.constbufs[shader][0];
897
898 switch (shader) {
899 case PIPE_SHADER_VERTEX:
900 variant = svga->state.hw_draw.vs;
901 extra_count = svga_get_extra_vs_constants(svga, (float *) extras);
902 break;
903 case PIPE_SHADER_FRAGMENT:
904 variant = svga->state.hw_draw.fs;
905 extra_count = svga_get_extra_fs_constants(svga, (float *) extras);
906 break;
907 case PIPE_SHADER_GEOMETRY:
908 variant = svga->state.hw_draw.gs;
909 extra_count = svga_get_extra_gs_constants(svga, (float *) extras);
910 break;
911 case PIPE_SHADER_TESS_CTRL:
912 variant = svga->state.hw_draw.tcs;
913 extra_count = svga_get_extra_tcs_constants(svga, (float *) extras);
914 break;
915 case PIPE_SHADER_TESS_EVAL:
916 variant = svga->state.hw_draw.tes;
917 extra_count = svga_get_extra_tes_constants(svga, (float *) extras);
918 break;
919 case PIPE_SHADER_COMPUTE:
920 variant = svga->state.hw_draw.cs;
921 extra_count = svga_get_extra_cs_constants(svga, (float *) extras);
922 break;
923 default:
924 assert(!"Unexpected shader type");
925 /* Don't return an error code since we don't want to keep re-trying
926 * this function and getting stuck in an infinite loop.
927 */
928 return PIPE_OK;
929 }
930
931 assert(variant);
932
933 cbuf = &svga->curr.constbufs[shader][0];
934
935 /* Compute extra constants size and offset in bytes */
936 extra_size = extra_count * 4 * sizeof(float);
937 extra_offset = 4 * sizeof(float) * variant->extra_const_start;
938
939 if (cbuf->buffer_size + extra_size == 0)
940 return PIPE_OK; /* nothing to do */
941
942 ret = emit_constbuf(svga, 0, shader,
943 cbuf->buffer_offset, cbuf->buffer_size, cbuf->buffer,
944 extra_offset, extra_size, extras);
945 if (ret != PIPE_OK)
946 return ret;
947
948 svga->state.hw_draw.default_constbuf_size[shader] =
949 svga->state.hw_draw.constbufoffsets[shader][0].size;
950
951 svga->hud.num_const_updates++;
952
953 return ret;
954 }
955
956
957 static enum pipe_error
emit_constbuf_vgpu10(struct svga_context * svga,enum pipe_shader_type shader)958 emit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
959 {
960 enum pipe_error ret = PIPE_OK;
961 unsigned dirty_constbufs;
962 unsigned enabled_constbufs;
963
964 enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] | 1u;
965 dirty_constbufs = (svga->state.dirty_constbufs[shader]|enabled_constbufs) & ~1u;
966
967 while (dirty_constbufs) {
968 unsigned index = u_bit_scan(&dirty_constbufs);
969 unsigned offset = svga->curr.constbufs[shader][index].buffer_offset;
970 unsigned size = svga->curr.constbufs[shader][index].buffer_size;
971 struct svga_buffer *buffer =
972 svga_buffer(svga->curr.constbufs[shader][index].buffer);
973
974 if (buffer) {
975 enabled_constbufs |= 1 << index;
976 }
977 else {
978 enabled_constbufs &= ~(1 << index);
979 assert(offset == 0);
980 assert(size == 0);
981 }
982
983 if (size % 16 != 0) {
984 /* GL's buffer range sizes can be any number of bytes but the
985 * SVGA3D device requires a multiple of 16 bytes.
986 */
987 const unsigned total_size = buffer->b.width0;
988
989 if (offset + align(size, 16) <= total_size) {
990 /* round up size to multiple of 16 */
991 size = align(size, 16);
992 }
993 else {
994 /* round down to multiple of 16 (this may cause rendering problems
995 * but should avoid a device error).
996 */
997 size &= ~15;
998 }
999 }
1000
1001 assert(size % 16 == 0);
1002
1003 /**
1004 * If the buffer has been bound as an uav buffer, it will
1005 * need to be bound as a shader resource raw buffer.
1006 */
1007 if (svga->state.raw_constbufs[shader] & (1 << index)) {
1008 ret = svga_emit_rawbuf(svga, index, shader, offset, size, buffer);
1009 if (ret != PIPE_OK) {
1010 return ret;
1011 }
1012
1013 ret = emit_constbuf(svga, index, shader, 0, 0, NULL,
1014 0, 0, NULL);
1015 if (ret != PIPE_OK) {
1016 return ret;
1017 }
1018
1019 /* Remove the rawbuf from the to-be-enabled constbuf list
1020 * so the buffer will not be referenced again as constant buffer
1021 * at resource validation time.
1022 */
1023 enabled_constbufs &= ~(1 << index);
1024 }
1025 else {
1026 if (svga->state.hw_draw.enabled_rawbufs[shader] & (1 << index)) {
1027 ret = svga_emit_rawbuf(svga, index, shader, offset, size, NULL);
1028 if (ret != PIPE_OK) {
1029 return ret;
1030 }
1031 }
1032
1033 ret = emit_constbuf(svga, index, shader, offset, size, buffer,
1034 0, 0, NULL);
1035 if (ret != PIPE_OK) {
1036 return ret;
1037 }
1038 }
1039 svga->hud.num_const_buf_updates++;
1040 }
1041
1042 svga->state.hw_draw.enabled_constbufs[shader] = enabled_constbufs;
1043 svga->state.dirty_constbufs[shader] = 0;
1044
1045 return ret;
1046 }
1047
1048 static enum pipe_error
emit_fs_consts(struct svga_context * svga,uint64_t dirty)1049 emit_fs_consts(struct svga_context *svga, uint64_t dirty)
1050 {
1051 const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
1052 enum pipe_error ret = PIPE_OK;
1053
1054 /* SVGA_NEW_FS_VARIANT
1055 */
1056 if (!variant)
1057 return PIPE_OK;
1058
1059 /* SVGA_NEW_FS_CONSTS
1060 */
1061 if (svga_have_vgpu10(svga)) {
1062 ret = emit_consts_vgpu10(svga, PIPE_SHADER_FRAGMENT);
1063 }
1064 else {
1065 ret = emit_consts_vgpu9(svga, PIPE_SHADER_FRAGMENT);
1066 }
1067
1068 return ret;
1069 }
1070
1071 static enum pipe_error
emit_fs_constbuf(struct svga_context * svga,uint64_t dirty)1072 emit_fs_constbuf(struct svga_context *svga, uint64_t dirty)
1073 {
1074 const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
1075 enum pipe_error ret = PIPE_OK;
1076
1077 /* SVGA_NEW_FS_VARIANT
1078 */
1079 if (!variant)
1080 return PIPE_OK;
1081
1082 /* SVGA_NEW_FS_CONSTBUF
1083 */
1084 assert(svga_have_vgpu10(svga));
1085 ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_FRAGMENT);
1086
1087 return ret;
1088 }
1089
1090 struct svga_tracked_state svga_hw_fs_constants =
1091 {
1092 "hw fs params",
1093 (SVGA_NEW_IMAGE_VIEW |
1094 SVGA_NEW_FS_CONSTS |
1095 SVGA_NEW_FS_VARIANT |
1096 SVGA_NEW_TEXTURE_CONSTS),
1097 emit_fs_consts
1098 };
1099
1100
1101 struct svga_tracked_state svga_hw_fs_constbufs =
1102 {
1103 "hw fs params",
1104 SVGA_NEW_FS_CONST_BUFFER,
1105 emit_fs_constbuf
1106 };
1107
1108
1109 static enum pipe_error
emit_vs_consts(struct svga_context * svga,uint64_t dirty)1110 emit_vs_consts(struct svga_context *svga, uint64_t dirty)
1111 {
1112 const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
1113 enum pipe_error ret = PIPE_OK;
1114
1115 /* SVGA_NEW_VS_VARIANT
1116 */
1117 if (!variant)
1118 return PIPE_OK;
1119
1120 /* SVGA_NEW_VS_CONST_BUFFER
1121 */
1122 if (svga_have_vgpu10(svga)) {
1123 ret = emit_consts_vgpu10(svga, PIPE_SHADER_VERTEX);
1124 }
1125 else {
1126 ret = emit_consts_vgpu9(svga, PIPE_SHADER_VERTEX);
1127 }
1128
1129 return ret;
1130 }
1131
1132
1133 static enum pipe_error
emit_vs_constbuf(struct svga_context * svga,uint64_t dirty)1134 emit_vs_constbuf(struct svga_context *svga, uint64_t dirty)
1135 {
1136 const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
1137 enum pipe_error ret = PIPE_OK;
1138
1139 /* SVGA_NEW_FS_VARIANT
1140 */
1141 if (!variant)
1142 return PIPE_OK;
1143
1144 /* SVGA_NEW_FS_CONSTBUF
1145 */
1146 assert(svga_have_vgpu10(svga));
1147 ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_VERTEX);
1148
1149 return ret;
1150 }
1151
1152
1153 struct svga_tracked_state svga_hw_vs_constants =
1154 {
1155 "hw vs params",
1156 (SVGA_NEW_PRESCALE |
1157 SVGA_NEW_IMAGE_VIEW |
1158 SVGA_NEW_VS_CONSTS |
1159 SVGA_NEW_VS_VARIANT |
1160 SVGA_NEW_TEXTURE_CONSTS),
1161 emit_vs_consts
1162 };
1163
1164
1165 struct svga_tracked_state svga_hw_vs_constbufs =
1166 {
1167 "hw vs params",
1168 SVGA_NEW_VS_CONST_BUFFER,
1169 emit_vs_constbuf
1170 };
1171
1172
1173 static enum pipe_error
emit_gs_consts(struct svga_context * svga,uint64_t dirty)1174 emit_gs_consts(struct svga_context *svga, uint64_t dirty)
1175 {
1176 const struct svga_shader_variant *variant = svga->state.hw_draw.gs;
1177 enum pipe_error ret = PIPE_OK;
1178
1179 /* SVGA_NEW_GS_VARIANT
1180 */
1181 if (!variant)
1182 return PIPE_OK;
1183
1184 /* SVGA_NEW_GS_CONST_BUFFER
1185 */
1186 assert(svga_have_vgpu10(svga));
1187
1188 /**
1189 * If only the rasterizer state has changed and the current geometry
1190 * shader does not emit wide points, then there is no reason to
1191 * re-emit the GS constants, so skip it.
1192 */
1193 if (dirty == SVGA_NEW_RAST && !variant->key.gs.wide_point)
1194 return PIPE_OK;
1195
1196 ret = emit_consts_vgpu10(svga, PIPE_SHADER_GEOMETRY);
1197
1198 return ret;
1199 }
1200
1201
1202 static enum pipe_error
emit_gs_constbuf(struct svga_context * svga,uint64_t dirty)1203 emit_gs_constbuf(struct svga_context *svga, uint64_t dirty)
1204 {
1205 const struct svga_shader_variant *variant = svga->state.hw_draw.gs;
1206 enum pipe_error ret = PIPE_OK;
1207
1208 /* SVGA_NEW_GS_VARIANT
1209 */
1210 if (!variant)
1211 return PIPE_OK;
1212
1213 /* SVGA_NEW_GS_CONSTBUF
1214 */
1215 assert(svga_have_vgpu10(svga));
1216 ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_GEOMETRY);
1217
1218 return ret;
1219 }
1220
1221
1222 struct svga_tracked_state svga_hw_gs_constants =
1223 {
1224 "hw gs params",
1225 (SVGA_NEW_PRESCALE |
1226 SVGA_NEW_IMAGE_VIEW |
1227 SVGA_NEW_GS_CONSTS |
1228 SVGA_NEW_RAST |
1229 SVGA_NEW_GS_VARIANT |
1230 SVGA_NEW_TEXTURE_CONSTS),
1231 emit_gs_consts
1232 };
1233
1234
1235 struct svga_tracked_state svga_hw_gs_constbufs =
1236 {
1237 "hw gs params",
1238 SVGA_NEW_GS_CONST_BUFFER,
1239 emit_gs_constbuf
1240 };
1241
1242
1243 /**
1244 * Emit constant buffer for tessellation control shader
1245 */
1246 static enum pipe_error
emit_tcs_consts(struct svga_context * svga,uint64_t dirty)1247 emit_tcs_consts(struct svga_context *svga, uint64_t dirty)
1248 {
1249 const struct svga_shader_variant *variant = svga->state.hw_draw.tcs;
1250 enum pipe_error ret = PIPE_OK;
1251
1252 assert(svga_have_sm5(svga));
1253
1254 /* SVGA_NEW_TCS_VARIANT */
1255 if (!variant)
1256 return PIPE_OK;
1257
1258 /* SVGA_NEW_TCS_CONST_BUFFER */
1259
1260 ret = emit_consts_vgpu10(svga, PIPE_SHADER_TESS_CTRL);
1261
1262 return ret;
1263 }
1264
1265
1266 static enum pipe_error
emit_tcs_constbuf(struct svga_context * svga,uint64_t dirty)1267 emit_tcs_constbuf(struct svga_context *svga, uint64_t dirty)
1268 {
1269 const struct svga_shader_variant *variant = svga->state.hw_draw.tcs;
1270 enum pipe_error ret = PIPE_OK;
1271
1272 /* SVGA_NEW_TCS_VARIANT
1273 */
1274 if (!variant)
1275 return PIPE_OK;
1276
1277 /* SVGA_NEW_TCS_CONSTBUF
1278 */
1279 assert(svga_have_vgpu10(svga));
1280 ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_TESS_CTRL);
1281
1282 return ret;
1283 }
1284
1285
1286 struct svga_tracked_state svga_hw_tcs_constants =
1287 {
1288 "hw tcs params",
1289 (SVGA_NEW_IMAGE_VIEW |
1290 SVGA_NEW_TCS_CONSTS |
1291 SVGA_NEW_TCS_VARIANT),
1292 emit_tcs_consts
1293 };
1294
1295
1296 struct svga_tracked_state svga_hw_tcs_constbufs =
1297 {
1298 "hw tcs params",
1299 SVGA_NEW_TCS_CONST_BUFFER,
1300 emit_tcs_constbuf
1301 };
1302
1303
1304 /**
1305 * Emit constant buffer for tessellation evaluation shader
1306 */
1307 static enum pipe_error
emit_tes_consts(struct svga_context * svga,uint64_t dirty)1308 emit_tes_consts(struct svga_context *svga, uint64_t dirty)
1309 {
1310 const struct svga_shader_variant *variant = svga->state.hw_draw.tes;
1311 enum pipe_error ret = PIPE_OK;
1312
1313 assert(svga_have_sm5(svga));
1314
1315 /* SVGA_NEW_TES_VARIANT */
1316 if (!variant)
1317 return PIPE_OK;
1318
1319 ret = emit_consts_vgpu10(svga, PIPE_SHADER_TESS_EVAL);
1320
1321 return ret;
1322 }
1323
1324
1325 static enum pipe_error
emit_tes_constbuf(struct svga_context * svga,uint64_t dirty)1326 emit_tes_constbuf(struct svga_context *svga, uint64_t dirty)
1327 {
1328 const struct svga_shader_variant *variant = svga->state.hw_draw.tes;
1329 enum pipe_error ret = PIPE_OK;
1330
1331 /* SVGA_NEW_TES_VARIANT
1332 */
1333 if (!variant)
1334 return PIPE_OK;
1335
1336 /* SVGA_NEW_TES_CONSTBUF
1337 */
1338 assert(svga_have_vgpu10(svga));
1339 ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_TESS_EVAL);
1340
1341 return ret;
1342 }
1343
1344
1345 struct svga_tracked_state svga_hw_tes_constants =
1346 {
1347 "hw tes params",
1348 (SVGA_NEW_PRESCALE |
1349 SVGA_NEW_IMAGE_VIEW |
1350 SVGA_NEW_TES_CONSTS |
1351 SVGA_NEW_TES_VARIANT),
1352 emit_tes_consts
1353 };
1354
1355
1356 struct svga_tracked_state svga_hw_tes_constbufs =
1357 {
1358 "hw gs params",
1359 SVGA_NEW_TES_CONST_BUFFER,
1360 emit_tes_constbuf
1361 };
1362
1363
1364 /**
1365 * Emit constant buffer for compute shader
1366 */
1367 static enum pipe_error
emit_cs_consts(struct svga_context * svga,uint64_t dirty)1368 emit_cs_consts(struct svga_context *svga, uint64_t dirty)
1369 {
1370 const struct svga_shader_variant *variant = svga->state.hw_draw.cs;
1371 enum pipe_error ret = PIPE_OK;
1372
1373 assert(svga_have_sm5(svga));
1374
1375 /* SVGA_NEW_CS_VARIANT */
1376 if (!variant)
1377 return PIPE_OK;
1378
1379 /* SVGA_NEW_CS_CONST_BUFFER */
1380 ret = emit_consts_vgpu10(svga, PIPE_SHADER_COMPUTE);
1381
1382 return ret;
1383 }
1384
1385
1386 static enum pipe_error
emit_cs_constbuf(struct svga_context * svga,uint64_t dirty)1387 emit_cs_constbuf(struct svga_context *svga, uint64_t dirty)
1388 {
1389 const struct svga_shader_variant *variant = svga->state.hw_draw.cs;
1390 enum pipe_error ret = PIPE_OK;
1391
1392 /* SVGA_NEW_CS_VARIANT
1393 */
1394 if (!variant)
1395 return PIPE_OK;
1396
1397 /* SVGA_NEW_CS_CONSTBUF
1398 */
1399 assert(svga_have_vgpu10(svga));
1400 ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_COMPUTE);
1401
1402 return ret;
1403 }
1404
1405
1406 struct svga_tracked_state svga_hw_cs_constants =
1407 {
1408 "hw cs params",
1409 (SVGA_NEW_IMAGE_VIEW |
1410 SVGA_NEW_CS_CONSTS |
1411 SVGA_NEW_CS_VARIANT |
1412 SVGA_NEW_TEXTURE_CONSTS),
1413 emit_cs_consts
1414 };
1415
1416
1417 struct svga_tracked_state svga_hw_cs_constbufs =
1418 {
1419 "hw cs params",
1420 SVGA_NEW_CS_CONST_BUFFER,
1421 emit_cs_constbuf
1422 };
1423
1424
1425 /**
1426 * A helper function to update the rawbuf for constbuf mask
1427 */
1428 static void
update_rawbuf_mask(struct svga_context * svga,enum pipe_shader_type shader)1429 update_rawbuf_mask(struct svga_context *svga, enum pipe_shader_type shader)
1430 {
1431 unsigned dirty_constbufs;
1432 unsigned enabled_constbufs;
1433
1434 enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] | 1u;
1435 dirty_constbufs = (svga->state.dirty_constbufs[shader]|enabled_constbufs) & ~1u;
1436
1437 while (dirty_constbufs) {
1438 unsigned index = u_bit_scan(&dirty_constbufs);
1439 struct svga_buffer *sbuf =
1440 svga_buffer(svga->curr.constbufs[shader][index].buffer);
1441
1442 if (sbuf && svga_has_raw_buffer_view(sbuf)) {
1443 svga->state.raw_constbufs[shader] |= (1 << index);
1444 } else {
1445 svga->state.raw_constbufs[shader] &= ~(1 << index);
1446 }
1447 }
1448 }
1449
1450
1451 /**
1452 * update_rawbuf is called at hw state update time to determine
1453 * if any of the bound constant buffers need to be bound as
1454 * raw buffer srv. This function is called after uav state is
1455 * updated and before shader variants are bound.
1456 */
1457 static enum pipe_error
update_rawbuf(struct svga_context * svga,uint64 dirty)1458 update_rawbuf(struct svga_context *svga, uint64 dirty)
1459 {
1460 uint64_t rawbuf_dirtybit[] = {
1461 SVGA_NEW_VS_RAW_BUFFER, /* PIPE_SHADER_VERTEX */
1462 SVGA_NEW_FS_RAW_BUFFER, /* PIPE_SHADER_FRAGMENT */
1463 SVGA_NEW_GS_RAW_BUFFER, /* PIPE_SHADER_GEOMETRY */
1464 SVGA_NEW_TCS_RAW_BUFFER, /* PIPE_SHADER_TESS_CTRL */
1465 SVGA_NEW_TES_RAW_BUFFER, /* PIPE_SHADER_TESS_EVAL */
1466 };
1467
1468 for (enum pipe_shader_type shader = PIPE_SHADER_VERTEX;
1469 shader < PIPE_SHADER_COMPUTE; shader++) {
1470 unsigned rawbuf_mask = svga->state.raw_constbufs[shader];
1471 unsigned rawbuf_sbuf_mask = svga->state.raw_shaderbufs[shader];
1472
1473 update_rawbuf_mask(svga, shader);
1474
1475 /* If the rawbuf state is different for the shader stage,
1476 * send SVGA_NEW_XX_RAW_BUFFER to trigger a new shader
1477 * variant that will use srv for ubo access.
1478 */
1479 if ((svga->state.raw_constbufs[shader] != rawbuf_mask) ||
1480 (svga->state.raw_shaderbufs[shader] != rawbuf_sbuf_mask))
1481 svga->dirty |= rawbuf_dirtybit[shader];
1482 }
1483
1484 return PIPE_OK;
1485 }
1486
1487
1488 struct svga_tracked_state svga_need_rawbuf_srv =
1489 {
1490 "raw buffer srv",
1491 (SVGA_NEW_IMAGE_VIEW |
1492 SVGA_NEW_SHADER_BUFFER |
1493 SVGA_NEW_CONST_BUFFER),
1494 update_rawbuf
1495 };
1496
1497
1498 /**
1499 * update_cs_rawbuf is called at compute dispatch time to determine
1500 * if any of the bound constant buffers need to be bound as
1501 * raw buffer srv. This function is called after uav state is
1502 * updated and before a compute shader variant is bound.
1503 */
1504 static enum pipe_error
update_cs_rawbuf(struct svga_context * svga,uint64 dirty)1505 update_cs_rawbuf(struct svga_context *svga, uint64 dirty)
1506 {
1507 unsigned rawbuf_mask = svga->state.raw_constbufs[PIPE_SHADER_COMPUTE];
1508
1509 update_rawbuf_mask(svga, PIPE_SHADER_COMPUTE);
1510
1511 /* if the rawbuf state is different for the shader stage,
1512 * send SVGA_NEW_RAW_BUFFER to trigger a new shader
1513 * variant to use srv for ubo access.
1514 */
1515 if (svga->state.raw_constbufs[PIPE_SHADER_COMPUTE] != rawbuf_mask)
1516 svga->dirty |= SVGA_NEW_CS_RAW_BUFFER;
1517
1518 return PIPE_OK;
1519 }
1520
1521
1522 struct svga_tracked_state svga_cs_need_rawbuf_srv =
1523 {
1524 "raw buffer srv",
1525 (SVGA_NEW_IMAGE_VIEW |
1526 SVGA_NEW_SHADER_BUFFER |
1527 SVGA_NEW_CONST_BUFFER),
1528 update_cs_rawbuf
1529 };
1530