1
2 /**********************************************************
3 * Copyright 2008-2009 VMware, Inc. All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person
6 * obtaining a copy of this software and associated documentation
7 * files (the "Software"), to deal in the Software without
8 * restriction, including without limitation the rights to use, copy,
9 * modify, merge, publish, distribute, sublicense, and/or sell copies
10 * of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 **********************************************************/
26
27 #include "util/format/u_format.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 /*
46 * Don't try to send more than 4kb of successive constants.
47 */
48 #define MAX_CONST_REG_COUNT 256 /**< number of float[4] constants */
49
50 /**
51 * Extra space for svga-specific VS/PS constants (such as texcoord
52 * scale factors, vertex transformation scale/translation).
53 */
54 #define MAX_EXTRA_CONSTS 32
55
56 /** Guest-backed surface constant buffers must be this size */
57 #define GB_CONSTBUF_SIZE (SVGA3D_CONSTREG_MAX)
58
59
60 /**
61 * Emit any extra shader-type-independent shader constants into the buffer
62 * pointed to by 'dest'.
63 * \return number of float[4] constants put into the 'dest' buffer
64 */
65 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)66 svga_get_extra_constants_common(const struct svga_context *svga,
67 const struct svga_shader_variant *variant,
68 enum pipe_shader_type shader, float *dest)
69 {
70 uint32_t *dest_u = (uint32_t *) dest; // uint version of dest
71 unsigned i;
72 unsigned count = 0;
73
74 for (i = 0; i < variant->key.num_textures; i++) {
75 const struct pipe_sampler_view *sv = svga->curr.sampler_views[shader][i];
76 if (sv) {
77 const struct pipe_resource *tex = sv->texture;
78 /* Scaling factors needed for handling unnormalized texture coordinates
79 * for texture rectangles.
80 */
81 if (variant->key.tex[i].unnormalized) {
82 /* debug/sanity check */
83 assert(variant->key.tex[i].width_height_idx == count);
84
85 *dest++ = 1.0f / (float) tex->width0;
86 *dest++ = 1.0f / (float) tex->height0;
87 *dest++ = 1.0f;
88 *dest++ = 1.0f;
89
90 count++;
91 }
92
93 /* Store the sizes for texture buffers.
94 */
95 if (tex->target == PIPE_BUFFER) {
96 unsigned bytes_per_element = util_format_get_blocksize(sv->format);
97 *dest_u++ = tex->width0 / bytes_per_element;
98 *dest_u++ = 1;
99 *dest_u++ = 1;
100 *dest_u++ = 1;
101
102 count++;
103 }
104 }
105 }
106
107 return count;
108 }
109
110
111 /**
112 * Emit any extra fragment shader constants into the buffer pointed
113 * to by 'dest'.
114 * \return number of float[4] constants put into the dest buffer
115 */
116 static unsigned
svga_get_extra_fs_constants(const struct svga_context * svga,float * dest)117 svga_get_extra_fs_constants(const struct svga_context *svga, float *dest)
118 {
119 const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
120 unsigned count = 0;
121
122 count += svga_get_extra_constants_common(svga, variant,
123 PIPE_SHADER_FRAGMENT, dest);
124
125 assert(count <= MAX_EXTRA_CONSTS);
126
127 return count;
128 }
129
130 /**
131 * Emit extra constants needed for prescale computation into the
132 * the buffer pointed to by '*dest'. The updated buffer pointer
133 * will be returned in 'dest'.
134 */
135 static unsigned
svga_get_prescale_constants(const struct svga_context * svga,float ** dest,const struct svga_prescale * prescale)136 svga_get_prescale_constants(const struct svga_context *svga, float **dest,
137 const struct svga_prescale *prescale)
138 {
139 memcpy(*dest, prescale->scale, 4 * sizeof(float));
140 *dest += 4;
141
142 memcpy(*dest, prescale->translate, 4 * sizeof(float));
143 *dest += 4;
144
145 return 2;
146 }
147
148 /**
149 * Emit extra constants needed for point sprite emulation.
150 */
151 static unsigned
svga_get_pt_sprite_constants(const struct svga_context * svga,float ** dest)152 svga_get_pt_sprite_constants(const struct svga_context *svga, float **dest)
153 {
154 const struct svga_screen *screen = svga_screen(svga->pipe.screen);
155 float *dst = *dest;
156
157 dst[0] = 1.0 / (svga->curr.viewport[0].scale[0] * 2);
158 dst[1] = 1.0 / (svga->curr.viewport[0].scale[1] * 2);
159 dst[2] = svga->curr.rast->pointsize;
160 dst[3] = screen->maxPointSize;
161 *dest = *dest + 4;
162 return 1;
163 }
164
165 /**
166 * Emit user-defined clip plane coefficients into the buffer pointed to
167 * by '*dest'. The updated buffer pointer will be returned in 'dest'.
168 */
169 static unsigned
svga_get_clip_plane_constants(const struct svga_context * svga,const struct svga_shader_variant * variant,float ** dest)170 svga_get_clip_plane_constants(const struct svga_context *svga,
171 const struct svga_shader_variant *variant,
172 float **dest)
173 {
174 unsigned count = 0;
175
176 /* SVGA_NEW_CLIP */
177 if (svga_have_vgpu10(svga)) {
178 /* append user-defined clip plane coefficients onto constant buffer */
179 unsigned clip_planes = variant->key.clip_plane_enable;
180 while (clip_planes) {
181 int i = u_bit_scan(&clip_planes);
182 COPY_4V(*dest, svga->curr.clip.ucp[i]);
183 *dest += 4;
184 count += 1;
185 }
186 }
187 return count;
188 }
189
190
191 /**
192 * Emit any extra vertex shader constants into the buffer pointed
193 * to by 'dest'.
194 * In particular, these would be the scale and bias factors computed
195 * from the framebuffer size which are used to copy with differences in
196 * GL vs D3D coordinate spaces. See svga_tgsi_insn.c for more info.
197 * \return number of float[4] constants put into the dest buffer
198 */
199 static unsigned
svga_get_extra_vs_constants(const struct svga_context * svga,float * dest)200 svga_get_extra_vs_constants(const struct svga_context *svga, float *dest)
201 {
202 const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
203 unsigned count = 0;
204
205 /* SVGA_NEW_VS_VARIANT
206 */
207 if (variant->key.vs.need_prescale) {
208 count += svga_get_prescale_constants(svga, &dest,
209 &svga->state.hw_clear.prescale[0]);
210 }
211
212 if (variant->key.vs.undo_viewport) {
213 /* Used to convert window coords back to NDC coords */
214 dest[0] = 1.0f / svga->curr.viewport[0].scale[0];
215 dest[1] = 1.0f / svga->curr.viewport[0].scale[1];
216 dest[2] = -svga->curr.viewport[0].translate[0];
217 dest[3] = -svga->curr.viewport[0].translate[1];
218 dest += 4;
219 count += 1;
220 }
221
222 /* Bias to be added to VertexID */
223 if (variant->key.vs.need_vertex_id_bias) {
224 uint32_t *dest_u = (uint32_t *) dest; // uint version of dest
225 dest_u[0] = svga->curr.vertex_id_bias;
226 dest_u[1] = 1;
227 dest_u[2] = 1;
228 dest_u[3] = 1;
229 dest+=4;
230 count++;
231 }
232
233 /* SVGA_NEW_CLIP */
234 count += svga_get_clip_plane_constants(svga, variant, &dest);
235
236 /* common constants */
237 count += svga_get_extra_constants_common(svga, variant,
238 PIPE_SHADER_VERTEX, dest);
239
240 assert(count <= MAX_EXTRA_CONSTS);
241
242 return count;
243 }
244
245 /**
246 * Emit any extra geometry shader constants into the buffer pointed
247 * to by 'dest'.
248 */
249 static unsigned
svga_get_extra_gs_constants(const struct svga_context * svga,float * dest)250 svga_get_extra_gs_constants(const struct svga_context *svga, float *dest)
251 {
252 const struct svga_shader_variant *variant = svga->state.hw_draw.gs;
253 unsigned count = 0;
254
255 /* SVGA_NEW_GS_VARIANT
256 */
257
258 /* Constants for point sprite
259 * These are used in the transformed gs that supports point sprite.
260 * They need to be added before the prescale constants.
261 */
262 if (variant->key.gs.wide_point) {
263 count += svga_get_pt_sprite_constants(svga, &dest);
264 }
265
266 if (variant->key.gs.need_prescale) {
267 unsigned i, num_prescale = 1;
268
269 /* If prescale is needed and the geometry shader writes to viewport
270 * index, then prescale for all viewports will be added to the
271 * constant buffer.
272 */
273 if (variant->key.gs.writes_viewport_index)
274 num_prescale = svga->state.hw_clear.num_prescale;
275
276 for (i = 0; i < num_prescale; i++) {
277 count +=
278 svga_get_prescale_constants(svga, &dest,
279 &svga->state.hw_clear.prescale[i]);
280 }
281 }
282
283 /* SVGA_NEW_CLIP */
284 count += svga_get_clip_plane_constants(svga, variant, &dest);
285
286 /* common constants */
287 count += svga_get_extra_constants_common(svga, variant,
288 PIPE_SHADER_GEOMETRY, dest);
289
290 assert(count <= MAX_EXTRA_CONSTS);
291 return count;
292 }
293
294
295 /**
296 * Emit any extra tessellation control shader constants into the
297 * buffer pointed to by 'dest'.
298 */
299 static unsigned
svga_get_extra_tcs_constants(struct svga_context * svga,float * dest)300 svga_get_extra_tcs_constants(struct svga_context *svga, float *dest)
301 {
302 const struct svga_shader_variant *variant = svga->state.hw_draw.tcs;
303 unsigned count = 0;
304
305 /* SVGA_NEW_CLIP */
306 count += svga_get_clip_plane_constants(svga, variant, &dest);
307
308 /* common constants */
309 count += svga_get_extra_constants_common(svga, variant,
310 PIPE_SHADER_TESS_CTRL,
311 dest);
312
313 assert(count <= MAX_EXTRA_CONSTS);
314 return count;
315 }
316
317
318 /**
319 * Emit any extra tessellation evaluation shader constants into
320 * the buffer pointed to by 'dest'.
321 */
322 static unsigned
svga_get_extra_tes_constants(struct svga_context * svga,float * dest)323 svga_get_extra_tes_constants(struct svga_context *svga, float *dest)
324 {
325 const struct svga_shader_variant *variant = svga->state.hw_draw.tes;
326 unsigned count = 0;
327
328 if (variant->key.tes.need_prescale) {
329 count += svga_get_prescale_constants(svga, &dest,
330 &svga->state.hw_clear.prescale[0]);
331 }
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_EVAL,
339 dest);
340
341 assert(count <= MAX_EXTRA_CONSTS);
342 return count;
343 }
344
345
346 /**
347 * Emit any extra compute shader constants into
348 * the buffer pointed to by 'dest'.
349 */
350 static unsigned
svga_get_extra_cs_constants(struct svga_context * svga,float * dest)351 svga_get_extra_cs_constants(struct svga_context *svga, float *dest)
352 {
353 const struct svga_shader_variant *variant = svga->state.hw_draw.cs;
354 unsigned count = 0;
355
356 /* common constants */
357 count += svga_get_extra_constants_common(svga, variant,
358 PIPE_SHADER_COMPUTE,
359 dest);
360
361 assert(count <= MAX_EXTRA_CONSTS);
362 return count;
363 }
364
365
366 /*
367 * Check and emit a range of shader constant registers, trying to coalesce
368 * successive shader constant updates in a single command in order to save
369 * space on the command buffer. This is a HWv8 feature.
370 */
371 static enum pipe_error
emit_const_range(struct svga_context * svga,enum pipe_shader_type shader,unsigned offset,unsigned count,const float (* values)[4])372 emit_const_range(struct svga_context *svga,
373 enum pipe_shader_type shader,
374 unsigned offset,
375 unsigned count,
376 const float (*values)[4])
377 {
378 unsigned i, j;
379 enum pipe_error ret;
380
381 assert(shader == PIPE_SHADER_VERTEX ||
382 shader == PIPE_SHADER_FRAGMENT);
383 assert(!svga_have_vgpu10(svga));
384
385 #ifdef DEBUG
386 if (offset + count > SVGA3D_CONSTREG_MAX) {
387 debug_printf("svga: too many constants (offset %u + count %u = %u (max = %u))\n",
388 offset, count, offset + count, SVGA3D_CONSTREG_MAX);
389 }
390 #endif
391
392 if (offset > SVGA3D_CONSTREG_MAX) {
393 /* This isn't OK, but if we propagate an error all the way up we'll
394 * just get into more trouble.
395 * XXX note that offset is always zero at this time so this is moot.
396 */
397 return PIPE_OK;
398 }
399
400 if (offset + count > SVGA3D_CONSTREG_MAX) {
401 /* Just drop the extra constants for now.
402 * Ideally we should not have allowed the app to create a shader
403 * that exceeds our constant buffer size but there's no way to
404 * express that in gallium at this time.
405 */
406 count = SVGA3D_CONSTREG_MAX - offset;
407 }
408
409 i = 0;
410 while (i < count) {
411 if (memcmp(svga->state.hw_draw.cb[shader][offset + i],
412 values[i],
413 4 * sizeof(float)) != 0) {
414 /* Found one dirty constant
415 */
416 if (SVGA_DEBUG & DEBUG_CONSTS)
417 debug_printf("%s %s %d: %f %f %f %f\n",
418 __FUNCTION__,
419 shader == PIPE_SHADER_VERTEX ? "VERT" : "FRAG",
420 offset + i,
421 values[i][0],
422 values[i][1],
423 values[i][2],
424 values[i][3]);
425
426 /* Look for more consecutive dirty constants.
427 */
428 j = i + 1;
429 while (j < count &&
430 j < i + MAX_CONST_REG_COUNT &&
431 memcmp(svga->state.hw_draw.cb[shader][offset + j],
432 values[j],
433 4 * sizeof(float)) != 0) {
434
435 if (SVGA_DEBUG & DEBUG_CONSTS)
436 debug_printf("%s %s %d: %f %f %f %f\n",
437 __FUNCTION__,
438 shader == PIPE_SHADER_VERTEX ? "VERT" : "FRAG",
439 offset + j,
440 values[j][0],
441 values[j][1],
442 values[j][2],
443 values[j][3]);
444
445 ++j;
446 }
447
448 assert(j >= i + 1);
449
450 /* Send them all together.
451 */
452 if (svga_have_gb_objects(svga)) {
453 ret = SVGA3D_SetGBShaderConstsInline(svga->swc,
454 offset + i, /* start */
455 j - i, /* count */
456 svga_shader_type(shader),
457 SVGA3D_CONST_TYPE_FLOAT,
458 values + i);
459 }
460 else {
461 ret = SVGA3D_SetShaderConsts(svga->swc,
462 offset + i, j - i,
463 svga_shader_type(shader),
464 SVGA3D_CONST_TYPE_FLOAT,
465 values + i);
466 }
467 if (ret != PIPE_OK) {
468 return ret;
469 }
470
471 /*
472 * Local copy of the hardware state.
473 */
474 memcpy(svga->state.hw_draw.cb[shader][offset + i],
475 values[i],
476 (j - i) * 4 * sizeof(float));
477
478 i = j + 1;
479
480 svga->hud.num_const_updates++;
481
482 } else {
483 ++i;
484 }
485 }
486
487 return PIPE_OK;
488 }
489
490
491 /**
492 * Emit all the constants in a constant buffer for a shader stage.
493 * On VGPU10, emit_consts_vgpu10 is used instead.
494 */
495 static enum pipe_error
emit_consts_vgpu9(struct svga_context * svga,enum pipe_shader_type shader)496 emit_consts_vgpu9(struct svga_context *svga, enum pipe_shader_type shader)
497 {
498 const struct pipe_constant_buffer *cbuf;
499 struct pipe_transfer *transfer = NULL;
500 unsigned count;
501 const float (*data)[4] = NULL;
502 enum pipe_error ret = PIPE_OK;
503 const unsigned offset = 0;
504
505 assert(shader < PIPE_SHADER_TYPES);
506 assert(!svga_have_vgpu10(svga));
507 /* Only one constant buffer per shader is supported before VGPU10.
508 * This is only an approximate check against that.
509 */
510 assert(svga->curr.constbufs[shader][1].buffer == NULL);
511
512 cbuf = &svga->curr.constbufs[shader][0];
513
514 if (svga->curr.constbufs[shader][0].buffer) {
515 /* emit user-provided constants */
516 data = (const float (*)[4])
517 pipe_buffer_map(&svga->pipe, svga->curr.constbufs[shader][0].buffer,
518 PIPE_MAP_READ, &transfer);
519 if (!data) {
520 return PIPE_ERROR_OUT_OF_MEMORY;
521 }
522
523 /* sanity check */
524 assert(cbuf->buffer->width0 >= cbuf->buffer_size);
525
526 /* Use/apply the constant buffer size and offsets here */
527 count = cbuf->buffer_size / (4 * sizeof(float));
528 data += cbuf->buffer_offset / (4 * sizeof(float));
529
530 ret = emit_const_range( svga, shader, offset, count, data );
531
532 pipe_buffer_unmap(&svga->pipe, transfer);
533
534 if (ret != PIPE_OK) {
535 return ret;
536 }
537 }
538
539 /* emit extra shader constants */
540 {
541 const struct svga_shader_variant *variant = NULL;
542 unsigned offset;
543 float extras[MAX_EXTRA_CONSTS][4];
544 unsigned count;
545
546 switch (shader) {
547 case PIPE_SHADER_VERTEX:
548 variant = svga->state.hw_draw.vs;
549 count = svga_get_extra_vs_constants(svga, (float *) extras);
550 break;
551 case PIPE_SHADER_FRAGMENT:
552 variant = svga->state.hw_draw.fs;
553 count = svga_get_extra_fs_constants(svga, (float *) extras);
554 break;
555 default:
556 assert(!"Unexpected shader type");
557 count = 0;
558 }
559
560 assert(variant);
561 offset = variant->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
562 assert(count <= ARRAY_SIZE(extras));
563
564 if (count > 0) {
565 ret = emit_const_range(svga, shader, offset, count,
566 (const float (*) [4])extras);
567 }
568 }
569
570 return ret;
571 }
572
573
574 /**
575 * A helper function to emit a constant buffer binding at the
576 * specified slot for the specified shader type
577 */
578 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)579 emit_constbuf(struct svga_context *svga,
580 unsigned slot,
581 enum pipe_shader_type shader,
582 unsigned buffer_offset,
583 unsigned buffer_size,
584 const void *buffer,
585 unsigned extra_buffer_offset,
586 unsigned extra_buffer_size,
587 const void *extra_buffer)
588 {
589 struct svga_buffer *sbuf = svga_buffer((struct pipe_resource *)buffer);
590 struct pipe_resource *dst_buffer = NULL;
591 enum pipe_error ret = PIPE_OK;
592 struct pipe_transfer *src_transfer;
593 struct svga_winsys_surface *dst_handle = NULL;
594 unsigned new_buf_size = 0;
595 unsigned alloc_buf_size;
596 unsigned offset = 0;;
597 void *src_map = NULL, *dst_map;
598
599 if ((sbuf && sbuf->swbuf) || extra_buffer) {
600
601 /* buffer here is a user-space buffer so mapping it is really cheap. */
602 if (buffer_size > 0) {
603 src_map = pipe_buffer_map_range(&svga->pipe,
604 (struct pipe_resource *)buffer,
605 buffer_offset, buffer_size,
606 PIPE_MAP_READ, &src_transfer);
607 assert(src_map);
608 if (!src_map) {
609 return PIPE_ERROR_OUT_OF_MEMORY;
610 }
611 }
612
613 new_buf_size = MAX2(buffer_size, extra_buffer_offset) + extra_buffer_size;
614
615 /* According to the DX10 spec, the constant buffer size must be
616 * in multiples of 16.
617 */
618 new_buf_size = align(new_buf_size, 16);
619
620 /* Constant buffer size in the upload buffer must be in multiples of 256.
621 * In order to maximize the chance of merging the upload buffer chunks
622 * when svga_buffer_add_range() is called,
623 * the allocate buffer size needs to be in multiples of 256 as well.
624 * Otherwise, since there is gap between each dirty range of the upload buffer,
625 * each dirty range will end up in its own UPDATE_GB_IMAGE command.
626 */
627 alloc_buf_size = align(new_buf_size, CONST0_UPLOAD_ALIGNMENT);
628
629 u_upload_alloc(svga->const0_upload, 0, alloc_buf_size,
630 CONST0_UPLOAD_ALIGNMENT, &offset,
631 &dst_buffer, &dst_map);
632
633 if (!dst_map) {
634 if (src_map)
635 pipe_buffer_unmap(&svga->pipe, src_transfer);
636 return PIPE_ERROR_OUT_OF_MEMORY;
637 }
638
639 /* Initialize the allocated buffer slot to 0 to ensure the padding is
640 * filled with 0.
641 */
642 memset(dst_map, 0, alloc_buf_size);
643
644 if (src_map) {
645 memcpy(dst_map, src_map, buffer_size);
646 pipe_buffer_unmap(&svga->pipe, src_transfer);
647 }
648
649 if (extra_buffer_size) {
650 assert(extra_buffer_offset + extra_buffer_size <= new_buf_size);
651 memcpy((char *) dst_map + extra_buffer_offset, extra_buffer,
652 extra_buffer_size);
653 }
654
655 /* Get winsys handle for the constant buffer */
656 if (svga->state.hw_draw.const0_buffer == dst_buffer &&
657 svga->state.hw_draw.const0_handle) {
658 /* re-reference already mapped buffer */
659 dst_handle = svga->state.hw_draw.const0_handle;
660 }
661 else {
662 /* we must unmap the buffer before getting the winsys handle */
663 u_upload_unmap(svga->const0_upload);
664
665 dst_handle = svga_buffer_handle(svga, dst_buffer,
666 PIPE_BIND_CONSTANT_BUFFER);
667 if (!dst_handle) {
668 pipe_resource_reference(&dst_buffer, NULL);
669 return PIPE_ERROR_OUT_OF_MEMORY;
670 }
671 }
672 }
673 else if (sbuf) {
674 dst_handle = svga_buffer_handle(svga, &sbuf->b, PIPE_BIND_CONSTANT_BUFFER);
675 new_buf_size = align(buffer_size, 16);
676 offset = buffer_offset;
677 }
678
679 assert(new_buf_size % 16 == 0);
680
681 const struct svga_screen *screen = svga_screen(svga->pipe.screen);
682 const struct svga_winsys_screen *sws = screen->sws;
683
684 /* Issue the SetSingleConstantBuffer command */
685 if (!sws->have_constant_buffer_offset_cmd ||
686 svga->state.hw_draw.constbufoffsets[shader][slot].handle != dst_handle ||
687 svga->state.hw_draw.constbufoffsets[shader][slot].size != new_buf_size) {
688 ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
689 slot, /* index */
690 svga_shader_type(shader),
691 dst_handle,
692 offset,
693 new_buf_size);
694 }
695 else if (dst_handle){
696 unsigned command = SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET + shader;
697 ret = SVGA3D_vgpu10_SetConstantBufferOffset(svga->swc,
698 command,
699 slot, /* index */
700 offset);
701 }
702
703 if (ret != PIPE_OK) {
704 pipe_resource_reference(&dst_buffer, NULL);
705 return ret;
706 }
707
708 /* save the upload buffer / handle for next time */
709 if (dst_buffer != buffer && dst_buffer) {
710 pipe_resource_reference(&svga->state.hw_draw.const0_buffer, dst_buffer);
711 svga->state.hw_draw.const0_handle = dst_handle;
712 }
713
714 /* Save this const buffer until it's replaced in the future.
715 * Otherwise, all references to the buffer will go away after the
716 * command buffer is submitted, it'll get recycled and we will have
717 * incorrect constant buffer bindings.
718 */
719 pipe_resource_reference(&svga->state.hw_draw.constbuf[shader][slot], dst_buffer);
720 svga->state.hw_draw.constbufoffsets[shader][slot].handle = dst_handle;
721 svga->state.hw_draw.constbufoffsets[shader][slot].size = new_buf_size;
722
723 pipe_resource_reference(&dst_buffer, NULL);
724
725 return PIPE_OK;
726 }
727
728
729 /* For constbuf 0 */
730 static enum pipe_error
emit_consts_vgpu10(struct svga_context * svga,enum pipe_shader_type shader)731 emit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
732 {
733 const struct pipe_constant_buffer *cbuf;
734 enum pipe_error ret = PIPE_OK;
735 float extras[MAX_EXTRA_CONSTS][4];
736 unsigned extra_count, extra_size, extra_offset;
737 const struct svga_shader_variant *variant;
738
739 assert(shader == PIPE_SHADER_VERTEX ||
740 shader == PIPE_SHADER_GEOMETRY ||
741 shader == PIPE_SHADER_FRAGMENT ||
742 shader == PIPE_SHADER_TESS_CTRL ||
743 shader == PIPE_SHADER_TESS_EVAL ||
744 shader == PIPE_SHADER_COMPUTE);
745
746 cbuf = &svga->curr.constbufs[shader][0];
747
748 switch (shader) {
749 case PIPE_SHADER_VERTEX:
750 variant = svga->state.hw_draw.vs;
751 extra_count = svga_get_extra_vs_constants(svga, (float *) extras);
752 break;
753 case PIPE_SHADER_FRAGMENT:
754 variant = svga->state.hw_draw.fs;
755 extra_count = svga_get_extra_fs_constants(svga, (float *) extras);
756 break;
757 case PIPE_SHADER_GEOMETRY:
758 variant = svga->state.hw_draw.gs;
759 extra_count = svga_get_extra_gs_constants(svga, (float *) extras);
760 break;
761 case PIPE_SHADER_TESS_CTRL:
762 variant = svga->state.hw_draw.tcs;
763 extra_count = svga_get_extra_tcs_constants(svga, (float *) extras);
764 break;
765 case PIPE_SHADER_TESS_EVAL:
766 variant = svga->state.hw_draw.tes;
767 extra_count = svga_get_extra_tes_constants(svga, (float *) extras);
768 break;
769 case PIPE_SHADER_COMPUTE:
770 variant = svga->state.hw_draw.cs;
771 extra_count = svga_get_extra_cs_constants(svga, (float *) extras);
772 break;
773 default:
774 assert(!"Unexpected shader type");
775 /* Don't return an error code since we don't want to keep re-trying
776 * this function and getting stuck in an infinite loop.
777 */
778 return PIPE_OK;
779 }
780
781 assert(variant);
782
783 cbuf = &svga->curr.constbufs[shader][0];
784
785 /* Compute extra constants size and offset in bytes */
786 extra_size = extra_count * 4 * sizeof(float);
787 extra_offset = 4 * sizeof(float) * variant->extra_const_start;
788
789 if (cbuf->buffer_size + extra_size == 0)
790 return PIPE_OK; /* nothing to do */
791
792 ret = emit_constbuf(svga, 0, shader,
793 cbuf->buffer_offset, cbuf->buffer_size, cbuf->buffer,
794 extra_offset, extra_size, extras);
795 if (ret != PIPE_OK)
796 return ret;
797
798 svga->state.hw_draw.default_constbuf_size[shader] =
799 svga->state.hw_draw.constbufoffsets[shader][0].size;
800
801 svga->hud.num_const_updates++;
802
803 return ret;
804 }
805
806
807 static enum pipe_error
emit_constbuf_vgpu10(struct svga_context * svga,enum pipe_shader_type shader)808 emit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
809 {
810 enum pipe_error ret = PIPE_OK;
811 unsigned dirty_constbufs;
812 unsigned enabled_constbufs;
813
814 enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] | 1u;
815 dirty_constbufs = (svga->state.dirty_constbufs[shader]|enabled_constbufs) & ~1u;
816
817 while (dirty_constbufs) {
818 unsigned index = u_bit_scan(&dirty_constbufs);
819 unsigned offset = svga->curr.constbufs[shader][index].buffer_offset;
820 unsigned size = svga->curr.constbufs[shader][index].buffer_size;
821 struct svga_buffer *buffer =
822 svga_buffer(svga->curr.constbufs[shader][index].buffer);
823
824 if (buffer) {
825 enabled_constbufs |= 1 << index;
826 }
827 else {
828 enabled_constbufs &= ~(1 << index);
829 assert(offset == 0);
830 assert(size == 0);
831 }
832
833 if (size % 16 != 0) {
834 /* GL's buffer range sizes can be any number of bytes but the
835 * SVGA3D device requires a multiple of 16 bytes.
836 */
837 const unsigned total_size = buffer->b.width0;
838
839 if (offset + align(size, 16) <= total_size) {
840 /* round up size to multiple of 16 */
841 size = align(size, 16);
842 }
843 else {
844 /* round down to multiple of 16 (this may cause rendering problems
845 * but should avoid a device error).
846 */
847 size &= ~15;
848 }
849 }
850
851 assert(size % 16 == 0);
852
853 ret = emit_constbuf(svga, index, shader, offset, size, buffer,
854 0, 0, NULL);
855 if (ret != PIPE_OK)
856 return ret;
857
858 svga->hud.num_const_buf_updates++;
859 }
860
861 svga->state.hw_draw.enabled_constbufs[shader] = enabled_constbufs;
862 svga->state.dirty_constbufs[shader] = 0;
863
864 return ret;
865 }
866
867 static enum pipe_error
emit_fs_consts(struct svga_context * svga,uint64_t dirty)868 emit_fs_consts(struct svga_context *svga, uint64_t dirty)
869 {
870 const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
871 enum pipe_error ret = PIPE_OK;
872
873 /* SVGA_NEW_FS_VARIANT
874 */
875 if (!variant)
876 return PIPE_OK;
877
878 /* SVGA_NEW_FS_CONSTS
879 */
880 if (svga_have_vgpu10(svga)) {
881 ret = emit_consts_vgpu10(svga, PIPE_SHADER_FRAGMENT);
882 }
883 else {
884 ret = emit_consts_vgpu9(svga, PIPE_SHADER_FRAGMENT);
885 }
886
887 return ret;
888 }
889
890 static enum pipe_error
emit_fs_constbuf(struct svga_context * svga,uint64_t dirty)891 emit_fs_constbuf(struct svga_context *svga, uint64_t dirty)
892 {
893 const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
894 enum pipe_error ret = PIPE_OK;
895
896 /* SVGA_NEW_FS_VARIANT
897 */
898 if (!variant)
899 return PIPE_OK;
900
901 /* SVGA_NEW_FS_CONSTBUF
902 */
903 assert(svga_have_vgpu10(svga));
904 ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_FRAGMENT);
905
906 return ret;
907 }
908
909 struct svga_tracked_state svga_hw_fs_constants =
910 {
911 "hw fs params",
912 (SVGA_NEW_FS_CONSTS |
913 SVGA_NEW_FS_VARIANT |
914 SVGA_NEW_TEXTURE_CONSTS),
915 emit_fs_consts
916 };
917
918
919 struct svga_tracked_state svga_hw_fs_constbufs =
920 {
921 "hw fs params",
922 SVGA_NEW_FS_CONST_BUFFER,
923 emit_fs_constbuf
924 };
925
926
927 static enum pipe_error
emit_vs_consts(struct svga_context * svga,uint64_t dirty)928 emit_vs_consts(struct svga_context *svga, uint64_t dirty)
929 {
930 const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
931 enum pipe_error ret = PIPE_OK;
932
933 /* SVGA_NEW_VS_VARIANT
934 */
935 if (!variant)
936 return PIPE_OK;
937
938 /* SVGA_NEW_VS_CONST_BUFFER
939 */
940 if (svga_have_vgpu10(svga)) {
941 ret = emit_consts_vgpu10(svga, PIPE_SHADER_VERTEX);
942 }
943 else {
944 ret = emit_consts_vgpu9(svga, PIPE_SHADER_VERTEX);
945 }
946
947 return ret;
948 }
949
950
951 static enum pipe_error
emit_vs_constbuf(struct svga_context * svga,uint64_t dirty)952 emit_vs_constbuf(struct svga_context *svga, uint64_t dirty)
953 {
954 const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
955 enum pipe_error ret = PIPE_OK;
956
957 /* SVGA_NEW_FS_VARIANT
958 */
959 if (!variant)
960 return PIPE_OK;
961
962 /* SVGA_NEW_FS_CONSTBUF
963 */
964 assert(svga_have_vgpu10(svga));
965 ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_VERTEX);
966
967 return ret;
968 }
969
970
971 struct svga_tracked_state svga_hw_vs_constants =
972 {
973 "hw vs params",
974 (SVGA_NEW_PRESCALE |
975 SVGA_NEW_VS_CONSTS |
976 SVGA_NEW_VS_VARIANT |
977 SVGA_NEW_TEXTURE_CONSTS),
978 emit_vs_consts
979 };
980
981
982 struct svga_tracked_state svga_hw_vs_constbufs =
983 {
984 "hw vs params",
985 SVGA_NEW_VS_CONST_BUFFER,
986 emit_vs_constbuf
987 };
988
989
990 static enum pipe_error
emit_gs_consts(struct svga_context * svga,uint64_t dirty)991 emit_gs_consts(struct svga_context *svga, uint64_t dirty)
992 {
993 const struct svga_shader_variant *variant = svga->state.hw_draw.gs;
994 enum pipe_error ret = PIPE_OK;
995
996 /* SVGA_NEW_GS_VARIANT
997 */
998 if (!variant)
999 return PIPE_OK;
1000
1001 /* SVGA_NEW_GS_CONST_BUFFER
1002 */
1003 assert(svga_have_vgpu10(svga));
1004
1005 /**
1006 * If only the rasterizer state has changed and the current geometry
1007 * shader does not emit wide points, then there is no reason to
1008 * re-emit the GS constants, so skip it.
1009 */
1010 if (dirty == SVGA_NEW_RAST && !variant->key.gs.wide_point)
1011 return PIPE_OK;
1012
1013 ret = emit_consts_vgpu10(svga, PIPE_SHADER_GEOMETRY);
1014
1015 return ret;
1016 }
1017
1018
1019 static enum pipe_error
emit_gs_constbuf(struct svga_context * svga,uint64_t dirty)1020 emit_gs_constbuf(struct svga_context *svga, uint64_t dirty)
1021 {
1022 const struct svga_shader_variant *variant = svga->state.hw_draw.gs;
1023 enum pipe_error ret = PIPE_OK;
1024
1025 /* SVGA_NEW_GS_VARIANT
1026 */
1027 if (!variant)
1028 return PIPE_OK;
1029
1030 /* SVGA_NEW_GS_CONSTBUF
1031 */
1032 assert(svga_have_vgpu10(svga));
1033 ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_GEOMETRY);
1034
1035 return ret;
1036 }
1037
1038
1039 struct svga_tracked_state svga_hw_gs_constants =
1040 {
1041 "hw gs params",
1042 (SVGA_NEW_PRESCALE |
1043 SVGA_NEW_GS_CONSTS |
1044 SVGA_NEW_RAST |
1045 SVGA_NEW_GS_VARIANT |
1046 SVGA_NEW_TEXTURE_CONSTS),
1047 emit_gs_consts
1048 };
1049
1050
1051 struct svga_tracked_state svga_hw_gs_constbufs =
1052 {
1053 "hw gs params",
1054 SVGA_NEW_GS_CONST_BUFFER,
1055 emit_gs_constbuf
1056 };
1057
1058
1059 /**
1060 * Emit constant buffer for tessellation control shader
1061 */
1062 static enum pipe_error
emit_tcs_consts(struct svga_context * svga,uint64_t dirty)1063 emit_tcs_consts(struct svga_context *svga, uint64_t dirty)
1064 {
1065 const struct svga_shader_variant *variant = svga->state.hw_draw.tcs;
1066 enum pipe_error ret = PIPE_OK;
1067
1068 assert(svga_have_sm5(svga));
1069
1070 /* SVGA_NEW_TCS_VARIANT */
1071 if (!variant)
1072 return PIPE_OK;
1073
1074 /* SVGA_NEW_TCS_CONST_BUFFER */
1075
1076 ret = emit_consts_vgpu10(svga, PIPE_SHADER_TESS_CTRL);
1077
1078 return ret;
1079 }
1080
1081
1082 static enum pipe_error
emit_tcs_constbuf(struct svga_context * svga,uint64_t dirty)1083 emit_tcs_constbuf(struct svga_context *svga, uint64_t dirty)
1084 {
1085 const struct svga_shader_variant *variant = svga->state.hw_draw.tcs;
1086 enum pipe_error ret = PIPE_OK;
1087
1088 /* SVGA_NEW_TCS_VARIANT
1089 */
1090 if (!variant)
1091 return PIPE_OK;
1092
1093 /* SVGA_NEW_TCS_CONSTBUF
1094 */
1095 assert(svga_have_vgpu10(svga));
1096 ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_TESS_CTRL);
1097
1098 return ret;
1099 }
1100
1101
1102 struct svga_tracked_state svga_hw_tcs_constants =
1103 {
1104 "hw tcs params",
1105 (SVGA_NEW_TCS_CONSTS |
1106 SVGA_NEW_TCS_VARIANT),
1107 emit_tcs_consts
1108 };
1109
1110
1111 struct svga_tracked_state svga_hw_tcs_constbufs =
1112 {
1113 "hw tcs params",
1114 SVGA_NEW_TCS_CONST_BUFFER,
1115 emit_tcs_constbuf
1116 };
1117
1118
1119 /**
1120 * Emit constant buffer for tessellation evaluation shader
1121 */
1122 static enum pipe_error
emit_tes_consts(struct svga_context * svga,uint64_t dirty)1123 emit_tes_consts(struct svga_context *svga, uint64_t dirty)
1124 {
1125 const struct svga_shader_variant *variant = svga->state.hw_draw.tes;
1126 enum pipe_error ret = PIPE_OK;
1127
1128 assert(svga_have_sm5(svga));
1129
1130 /* SVGA_NEW_TES_VARIANT */
1131 if (!variant)
1132 return PIPE_OK;
1133
1134 ret = emit_consts_vgpu10(svga, PIPE_SHADER_TESS_EVAL);
1135
1136 return ret;
1137 }
1138
1139
1140 static enum pipe_error
emit_tes_constbuf(struct svga_context * svga,uint64_t dirty)1141 emit_tes_constbuf(struct svga_context *svga, uint64_t dirty)
1142 {
1143 const struct svga_shader_variant *variant = svga->state.hw_draw.tes;
1144 enum pipe_error ret = PIPE_OK;
1145
1146 /* SVGA_NEW_TES_VARIANT
1147 */
1148 if (!variant)
1149 return PIPE_OK;
1150
1151 /* SVGA_NEW_TES_CONSTBUF
1152 */
1153 assert(svga_have_vgpu10(svga));
1154 ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_TESS_EVAL);
1155
1156 return ret;
1157 }
1158
1159
1160 struct svga_tracked_state svga_hw_tes_constants =
1161 {
1162 "hw tes params",
1163 (SVGA_NEW_PRESCALE |
1164 SVGA_NEW_TES_CONSTS |
1165 SVGA_NEW_TES_VARIANT),
1166 emit_tes_consts
1167 };
1168
1169
1170 struct svga_tracked_state svga_hw_tes_constbufs =
1171 {
1172 "hw gs params",
1173 SVGA_NEW_TES_CONST_BUFFER,
1174 emit_tes_constbuf
1175 };
1176