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