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/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(struct svga_context * svga,const struct svga_shader_variant * variant,enum pipe_shader_type shader,float * dest)66 svga_get_extra_constants_common(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.0 / (float)tex->width0;
86 *dest++ = 1.0 / (float)tex->height0;
87 *dest++ = 1.0;
88 *dest++ = 1.0;
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(struct svga_context * svga,float * dest)117 svga_get_extra_fs_constants(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(struct svga_context * svga,float ** dest)136 svga_get_prescale_constants(struct svga_context *svga, float **dest)
137 {
138 memcpy(*dest, svga->state.hw_clear.prescale.scale, 4 * sizeof(float));
139 *dest += 4;
140
141 memcpy(*dest, svga->state.hw_clear.prescale.translate, 4 * sizeof(float));
142 *dest += 4;
143
144 return 2;
145 }
146
147 /**
148 * Emit extra constants needed for point sprite emulation.
149 */
150 static unsigned
svga_get_pt_sprite_constants(struct svga_context * svga,float ** dest)151 svga_get_pt_sprite_constants(struct svga_context *svga, float **dest)
152 {
153 const struct svga_screen *screen = svga_screen(svga->pipe.screen);
154 float *dst = *dest;
155
156 dst[0] = 1.0 / (svga->curr.viewport.scale[0] * 2);
157 dst[1] = 1.0 / (svga->curr.viewport.scale[1] * 2);
158 dst[2] = svga->curr.rast->pointsize;
159 dst[3] = screen->maxPointSize;
160 *dest = *dest + 4;
161 return 1;
162 }
163
164 /**
165 * Emit user-defined clip plane coefficients into the buffer pointed to
166 * by '*dest'. The updated buffer pointer will be returned in 'dest'.
167 */
168 static unsigned
svga_get_clip_plane_constants(struct svga_context * svga,const struct svga_shader_variant * variant,float ** dest)169 svga_get_clip_plane_constants(struct svga_context *svga,
170 const struct svga_shader_variant *variant,
171 float **dest)
172 {
173 unsigned count = 0;
174
175 /* SVGA_NEW_CLIP */
176 if (svga_have_vgpu10(svga)) {
177 /* append user-defined clip plane coefficients onto constant buffer */
178 unsigned clip_planes = variant->key.clip_plane_enable;
179 while (clip_planes) {
180 int i = u_bit_scan(&clip_planes);
181 COPY_4V(*dest, svga->curr.clip.ucp[i]);
182 *dest += 4;
183 count += 1;
184 }
185 }
186 return count;
187 }
188
189 /**
190 * Emit any extra vertex shader constants into the buffer pointed
191 * to by 'dest'.
192 * In particular, these would be the scale and bias factors computed
193 * from the framebuffer size which are used to copy with differences in
194 * GL vs D3D coordinate spaces. See svga_tgsi_insn.c for more info.
195 * \return number of float[4] constants put into the dest buffer
196 */
197 static unsigned
svga_get_extra_vs_constants(struct svga_context * svga,float * dest)198 svga_get_extra_vs_constants(struct svga_context *svga, float *dest)
199 {
200 const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
201 unsigned count = 0;
202
203 /* SVGA_NEW_VS_VARIANT
204 */
205 if (variant->key.vs.need_prescale) {
206 count += svga_get_prescale_constants(svga, &dest);
207 }
208
209 if (variant->key.vs.undo_viewport) {
210 /* Used to convert window coords back to NDC coords */
211 dest[0] = 1.0f / svga->curr.viewport.scale[0];
212 dest[1] = 1.0f / svga->curr.viewport.scale[1];
213 dest[2] = -svga->curr.viewport.translate[0];
214 dest[3] = -svga->curr.viewport.translate[1];
215 dest += 4;
216 count += 1;
217 }
218
219 /* SVGA_NEW_CLIP */
220 count += svga_get_clip_plane_constants(svga, variant, &dest);
221
222 /* common constants */
223 count += svga_get_extra_constants_common(svga, variant,
224 PIPE_SHADER_VERTEX, dest);
225
226 assert(count <= MAX_EXTRA_CONSTS);
227
228 return count;
229 }
230
231 /**
232 * Emit any extra geometry shader constants into the buffer pointed
233 * to by 'dest'.
234 */
235 static unsigned
svga_get_extra_gs_constants(struct svga_context * svga,float * dest)236 svga_get_extra_gs_constants(struct svga_context *svga, float *dest)
237 {
238 const struct svga_shader_variant *variant = svga->state.hw_draw.gs;
239 unsigned count = 0;
240
241 /* SVGA_NEW_GS_VARIANT
242 */
243
244 /* Constants for point sprite
245 * These are used in the transformed gs that supports point sprite.
246 * They need to be added before the prescale constants.
247 */
248 if (variant->key.gs.wide_point) {
249 count += svga_get_pt_sprite_constants(svga, &dest);
250 }
251
252 if (variant->key.gs.need_prescale) {
253 count += svga_get_prescale_constants(svga, &dest);
254 }
255
256 /* SVGA_NEW_CLIP */
257 count += svga_get_clip_plane_constants(svga, variant, &dest);
258
259 /* common constants */
260 count += svga_get_extra_constants_common(svga, variant,
261 PIPE_SHADER_GEOMETRY, dest);
262
263 assert(count <= MAX_EXTRA_CONSTS);
264 return count;
265 }
266
267
268 /*
269 * Check and emit a range of shader constant registers, trying to coalesce
270 * successive shader constant updates in a single command in order to save
271 * space on the command buffer. This is a HWv8 feature.
272 */
273 static enum pipe_error
emit_const_range(struct svga_context * svga,enum pipe_shader_type shader,unsigned offset,unsigned count,const float (* values)[4])274 emit_const_range(struct svga_context *svga,
275 enum pipe_shader_type shader,
276 unsigned offset,
277 unsigned count,
278 const float (*values)[4])
279 {
280 unsigned i, j;
281 enum pipe_error ret;
282
283 assert(shader == PIPE_SHADER_VERTEX ||
284 shader == PIPE_SHADER_FRAGMENT);
285 assert(!svga_have_vgpu10(svga));
286
287 #ifdef DEBUG
288 if (offset + count > SVGA3D_CONSTREG_MAX) {
289 debug_printf("svga: too many constants (offset %u + count %u = %u (max = %u))\n",
290 offset, count, offset + count, SVGA3D_CONSTREG_MAX);
291 }
292 #endif
293
294 if (offset > SVGA3D_CONSTREG_MAX) {
295 /* This isn't OK, but if we propagate an error all the way up we'll
296 * just get into more trouble.
297 * XXX note that offset is always zero at this time so this is moot.
298 */
299 return PIPE_OK;
300 }
301
302 if (offset + count > SVGA3D_CONSTREG_MAX) {
303 /* Just drop the extra constants for now.
304 * Ideally we should not have allowed the app to create a shader
305 * that exceeds our constant buffer size but there's no way to
306 * express that in gallium at this time.
307 */
308 count = SVGA3D_CONSTREG_MAX - offset;
309 }
310
311 i = 0;
312 while (i < count) {
313 if (memcmp(svga->state.hw_draw.cb[shader][offset + i],
314 values[i],
315 4 * sizeof(float)) != 0) {
316 /* Found one dirty constant
317 */
318 if (SVGA_DEBUG & DEBUG_CONSTS)
319 debug_printf("%s %s %d: %f %f %f %f\n",
320 __FUNCTION__,
321 shader == PIPE_SHADER_VERTEX ? "VERT" : "FRAG",
322 offset + i,
323 values[i][0],
324 values[i][1],
325 values[i][2],
326 values[i][3]);
327
328 /* Look for more consecutive dirty constants.
329 */
330 j = i + 1;
331 while (j < count &&
332 j < i + MAX_CONST_REG_COUNT &&
333 memcmp(svga->state.hw_draw.cb[shader][offset + j],
334 values[j],
335 4 * sizeof(float)) != 0) {
336
337 if (SVGA_DEBUG & DEBUG_CONSTS)
338 debug_printf("%s %s %d: %f %f %f %f\n",
339 __FUNCTION__,
340 shader == PIPE_SHADER_VERTEX ? "VERT" : "FRAG",
341 offset + j,
342 values[j][0],
343 values[j][1],
344 values[j][2],
345 values[j][3]);
346
347 ++j;
348 }
349
350 assert(j >= i + 1);
351
352 /* Send them all together.
353 */
354 if (svga_have_gb_objects(svga)) {
355 ret = SVGA3D_SetGBShaderConstsInline(svga->swc,
356 offset + i, /* start */
357 j - i, /* count */
358 svga_shader_type(shader),
359 SVGA3D_CONST_TYPE_FLOAT,
360 values + i);
361 }
362 else {
363 ret = SVGA3D_SetShaderConsts(svga->swc,
364 offset + i, j - i,
365 svga_shader_type(shader),
366 SVGA3D_CONST_TYPE_FLOAT,
367 values + i);
368 }
369 if (ret != PIPE_OK) {
370 return ret;
371 }
372
373 /*
374 * Local copy of the hardware state.
375 */
376 memcpy(svga->state.hw_draw.cb[shader][offset + i],
377 values[i],
378 (j - i) * 4 * sizeof(float));
379
380 i = j + 1;
381
382 svga->hud.num_const_updates++;
383
384 } else {
385 ++i;
386 }
387 }
388
389 return PIPE_OK;
390 }
391
392
393 /**
394 * Emit all the constants in a constant buffer for a shader stage.
395 * On VGPU10, emit_consts_vgpu10 is used instead.
396 */
397 static enum pipe_error
emit_consts_vgpu9(struct svga_context * svga,enum pipe_shader_type shader)398 emit_consts_vgpu9(struct svga_context *svga, enum pipe_shader_type shader)
399 {
400 const struct pipe_constant_buffer *cbuf;
401 struct pipe_transfer *transfer = NULL;
402 unsigned count;
403 const float (*data)[4] = NULL;
404 enum pipe_error ret = PIPE_OK;
405 const unsigned offset = 0;
406
407 assert(shader < PIPE_SHADER_TYPES);
408 assert(!svga_have_vgpu10(svga));
409 /* Only one constant buffer per shader is supported before VGPU10.
410 * This is only an approximate check against that.
411 */
412 assert(svga->curr.constbufs[shader][1].buffer == NULL);
413
414 cbuf = &svga->curr.constbufs[shader][0];
415
416 if (svga->curr.constbufs[shader][0].buffer) {
417 /* emit user-provided constants */
418 data = (const float (*)[4])
419 pipe_buffer_map(&svga->pipe, svga->curr.constbufs[shader][0].buffer,
420 PIPE_TRANSFER_READ, &transfer);
421 if (!data) {
422 return PIPE_ERROR_OUT_OF_MEMORY;
423 }
424
425 /* sanity check */
426 assert(cbuf->buffer->width0 >= cbuf->buffer_size);
427
428 /* Use/apply the constant buffer size and offsets here */
429 count = cbuf->buffer_size / (4 * sizeof(float));
430 data += cbuf->buffer_offset / (4 * sizeof(float));
431
432 ret = emit_const_range( svga, shader, offset, count, data );
433
434 pipe_buffer_unmap(&svga->pipe, transfer);
435
436 if (ret != PIPE_OK) {
437 return ret;
438 }
439 }
440
441 /* emit extra shader constants */
442 {
443 const struct svga_shader_variant *variant = NULL;
444 unsigned offset;
445 float extras[MAX_EXTRA_CONSTS][4];
446 unsigned count;
447
448 switch (shader) {
449 case PIPE_SHADER_VERTEX:
450 variant = svga->state.hw_draw.vs;
451 count = svga_get_extra_vs_constants(svga, (float *) extras);
452 break;
453 case PIPE_SHADER_FRAGMENT:
454 variant = svga->state.hw_draw.fs;
455 count = svga_get_extra_fs_constants(svga, (float *) extras);
456 break;
457 default:
458 assert(!"Unexpected shader type");
459 count = 0;
460 }
461
462 assert(variant);
463 offset = variant->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
464 assert(count <= ARRAY_SIZE(extras));
465
466 if (count > 0) {
467 ret = emit_const_range(svga, shader, offset, count,
468 (const float (*) [4])extras);
469 }
470 }
471
472 return ret;
473 }
474
475
476
477 static enum pipe_error
emit_constbuf_vgpu10(struct svga_context * svga,enum pipe_shader_type shader)478 emit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
479 {
480 const struct pipe_constant_buffer *cbuf;
481 struct pipe_resource *dst_buffer = NULL;
482 enum pipe_error ret = PIPE_OK;
483 struct pipe_transfer *src_transfer;
484 struct svga_winsys_surface *dst_handle;
485 float extras[MAX_EXTRA_CONSTS][4];
486 unsigned extra_count, extra_size, extra_offset;
487 unsigned new_buf_size;
488 void *src_map = NULL, *dst_map;
489 unsigned offset;
490 const struct svga_shader_variant *variant;
491 unsigned alloc_buf_size;
492
493 assert(shader == PIPE_SHADER_VERTEX ||
494 shader == PIPE_SHADER_GEOMETRY ||
495 shader == PIPE_SHADER_FRAGMENT);
496
497 cbuf = &svga->curr.constbufs[shader][0];
498
499 switch (shader) {
500 case PIPE_SHADER_VERTEX:
501 variant = svga->state.hw_draw.vs;
502 extra_count = svga_get_extra_vs_constants(svga, (float *) extras);
503 break;
504 case PIPE_SHADER_FRAGMENT:
505 variant = svga->state.hw_draw.fs;
506 extra_count = svga_get_extra_fs_constants(svga, (float *) extras);
507 break;
508 case PIPE_SHADER_GEOMETRY:
509 variant = svga->state.hw_draw.gs;
510 extra_count = svga_get_extra_gs_constants(svga, (float *) extras);
511 break;
512 default:
513 assert(!"Unexpected shader type");
514 /* Don't return an error code since we don't want to keep re-trying
515 * this function and getting stuck in an infinite loop.
516 */
517 return PIPE_OK;
518 }
519
520 assert(variant);
521
522 /* Compute extra constants size and offset in bytes */
523 extra_size = extra_count * 4 * sizeof(float);
524 extra_offset = 4 * sizeof(float) * variant->extra_const_start;
525
526 if (cbuf->buffer_size + extra_size == 0)
527 return PIPE_OK; /* nothing to do */
528
529 /* Typically, the cbuf->buffer here is a user-space buffer so mapping
530 * it is really cheap. If we ever get real HW buffers for constants
531 * we should void mapping and instead use a ResourceCopy command.
532 */
533 if (cbuf->buffer_size > 0) {
534 src_map = pipe_buffer_map_range(&svga->pipe, cbuf->buffer,
535 cbuf->buffer_offset, cbuf->buffer_size,
536 PIPE_TRANSFER_READ, &src_transfer);
537 assert(src_map);
538 if (!src_map) {
539 return PIPE_ERROR_OUT_OF_MEMORY;
540 }
541 }
542
543 /* The new/dest buffer's size must be large enough to hold the original,
544 * user-specified constants, plus the extra constants.
545 * The size of the original constant buffer _should_ agree with what the
546 * shader is expecting, but it might not (it's not enforced anywhere by
547 * gallium).
548 */
549 new_buf_size = MAX2(cbuf->buffer_size, extra_offset) + extra_size;
550
551 /* According to the DX10 spec, the constant buffer size must be
552 * in multiples of 16.
553 */
554 new_buf_size = align(new_buf_size, 16);
555
556 /* Constant buffer size in the upload buffer must be in multiples of 256.
557 * In order to maximize the chance of merging the upload buffer chunks
558 * when svga_buffer_add_range() is called,
559 * the allocate buffer size needs to be in multiples of 256 as well.
560 * Otherwise, since there is gap between each dirty range of the upload buffer,
561 * each dirty range will end up in its own UPDATE_GB_IMAGE command.
562 */
563 alloc_buf_size = align(new_buf_size, CONST0_UPLOAD_ALIGNMENT);
564
565 u_upload_alloc(svga->const0_upload, 0, alloc_buf_size,
566 CONST0_UPLOAD_ALIGNMENT, &offset,
567 &dst_buffer, &dst_map);
568 if (!dst_map) {
569 if (src_map)
570 pipe_buffer_unmap(&svga->pipe, src_transfer);
571 return PIPE_ERROR_OUT_OF_MEMORY;
572 }
573
574 if (src_map) {
575 memcpy(dst_map, src_map, cbuf->buffer_size);
576 pipe_buffer_unmap(&svga->pipe, src_transfer);
577 }
578
579 if (extra_size) {
580 assert(extra_offset + extra_size <= new_buf_size);
581 memcpy((char *) dst_map + extra_offset, extras, extra_size);
582 }
583
584 /* Get winsys handle for the constant buffer */
585 if (svga->state.hw_draw.const0_buffer == dst_buffer &&
586 svga->state.hw_draw.const0_handle) {
587 /* re-reference already mapped buffer */
588 dst_handle = svga->state.hw_draw.const0_handle;
589 }
590 else {
591 /* we must unmap the buffer before getting the winsys handle */
592 u_upload_unmap(svga->const0_upload);
593
594 dst_handle = svga_buffer_handle(svga, dst_buffer,
595 PIPE_BIND_CONSTANT_BUFFER);
596 if (!dst_handle) {
597 pipe_resource_reference(&dst_buffer, NULL);
598 return PIPE_ERROR_OUT_OF_MEMORY;
599 }
600
601 /* save the buffer / handle for next time */
602 pipe_resource_reference(&svga->state.hw_draw.const0_buffer, dst_buffer);
603 svga->state.hw_draw.const0_handle = dst_handle;
604 }
605
606 /* Issue the SetSingleConstantBuffer command */
607 assert(new_buf_size % 16 == 0);
608 ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
609 0, /* index */
610 svga_shader_type(shader),
611 dst_handle,
612 offset,
613 new_buf_size);
614
615 if (ret != PIPE_OK) {
616 pipe_resource_reference(&dst_buffer, NULL);
617 return ret;
618 }
619
620 /* Save this const buffer until it's replaced in the future.
621 * Otherwise, all references to the buffer will go away after the
622 * command buffer is submitted, it'll get recycled and we will have
623 * incorrect constant buffer bindings.
624 */
625 pipe_resource_reference(&svga->state.hw_draw.constbuf[shader], dst_buffer);
626
627 svga->state.hw_draw.default_constbuf_size[shader] = new_buf_size;
628
629 pipe_resource_reference(&dst_buffer, NULL);
630
631 svga->hud.num_const_buf_updates++;
632
633 return ret;
634 }
635
636
637 static enum pipe_error
emit_consts_vgpu10(struct svga_context * svga,enum pipe_shader_type shader)638 emit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
639 {
640 enum pipe_error ret;
641 unsigned dirty_constbufs;
642 unsigned enabled_constbufs;
643
644 /* Emit 0th constant buffer (with extra constants) */
645 ret = emit_constbuf_vgpu10(svga, shader);
646 if (ret != PIPE_OK) {
647 return ret;
648 }
649
650 enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] | 1u;
651
652 /* Emit other constant buffers (UBOs) */
653 dirty_constbufs = svga->state.dirty_constbufs[shader] & ~1u;
654
655 while (dirty_constbufs) {
656 unsigned index = u_bit_scan(&dirty_constbufs);
657 unsigned offset = svga->curr.constbufs[shader][index].buffer_offset;
658 unsigned size = svga->curr.constbufs[shader][index].buffer_size;
659 struct svga_buffer *buffer =
660 svga_buffer(svga->curr.constbufs[shader][index].buffer);
661 struct svga_winsys_surface *handle;
662
663 if (buffer) {
664 handle = svga_buffer_handle(svga, &buffer->b.b,
665 PIPE_BIND_CONSTANT_BUFFER);
666 enabled_constbufs |= 1 << index;
667 }
668 else {
669 handle = NULL;
670 enabled_constbufs &= ~(1 << index);
671 assert(offset == 0);
672 assert(size == 0);
673 }
674
675 if (size % 16 != 0) {
676 /* GL's buffer range sizes can be any number of bytes but the
677 * SVGA3D device requires a multiple of 16 bytes.
678 */
679 const unsigned total_size = buffer->b.b.width0;
680
681 if (offset + align(size, 16) <= total_size) {
682 /* round up size to multiple of 16 */
683 size = align(size, 16);
684 }
685 else {
686 /* round down to mulitple of 16 (this may cause rendering problems
687 * but should avoid a device error).
688 */
689 size &= ~15;
690 }
691 }
692
693 assert(size % 16 == 0);
694 ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
695 index,
696 svga_shader_type(shader),
697 handle,
698 offset,
699 size);
700 if (ret != PIPE_OK)
701 return ret;
702
703 svga->hud.num_const_buf_updates++;
704 }
705
706 svga->state.hw_draw.enabled_constbufs[shader] = enabled_constbufs;
707 svga->state.dirty_constbufs[shader] = 0;
708
709 return ret;
710 }
711
712 static enum pipe_error
emit_fs_consts(struct svga_context * svga,unsigned dirty)713 emit_fs_consts(struct svga_context *svga, unsigned dirty)
714 {
715 const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
716 enum pipe_error ret = PIPE_OK;
717
718 /* SVGA_NEW_FS_VARIANT
719 */
720 if (!variant)
721 return PIPE_OK;
722
723 /* SVGA_NEW_FS_CONST_BUFFER
724 */
725 if (svga_have_vgpu10(svga)) {
726 ret = emit_consts_vgpu10(svga, PIPE_SHADER_FRAGMENT);
727 }
728 else {
729 ret = emit_consts_vgpu9(svga, PIPE_SHADER_FRAGMENT);
730 }
731
732 return ret;
733 }
734
735
736 struct svga_tracked_state svga_hw_fs_constants =
737 {
738 "hw fs params",
739 (SVGA_NEW_FS_CONST_BUFFER |
740 SVGA_NEW_FS_VARIANT |
741 SVGA_NEW_TEXTURE_CONSTS),
742 emit_fs_consts
743 };
744
745
746
747 static enum pipe_error
emit_vs_consts(struct svga_context * svga,unsigned dirty)748 emit_vs_consts(struct svga_context *svga, unsigned dirty)
749 {
750 const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
751 enum pipe_error ret = PIPE_OK;
752
753 /* SVGA_NEW_VS_VARIANT
754 */
755 if (!variant)
756 return PIPE_OK;
757
758 /* SVGA_NEW_VS_CONST_BUFFER
759 */
760 if (svga_have_vgpu10(svga)) {
761 ret = emit_consts_vgpu10(svga, PIPE_SHADER_VERTEX);
762 }
763 else {
764 ret = emit_consts_vgpu9(svga, PIPE_SHADER_VERTEX);
765 }
766
767 return ret;
768 }
769
770
771 struct svga_tracked_state svga_hw_vs_constants =
772 {
773 "hw vs params",
774 (SVGA_NEW_PRESCALE |
775 SVGA_NEW_VS_CONST_BUFFER |
776 SVGA_NEW_VS_VARIANT),
777 emit_vs_consts
778 };
779
780
781 static enum pipe_error
emit_gs_consts(struct svga_context * svga,unsigned dirty)782 emit_gs_consts(struct svga_context *svga, unsigned dirty)
783 {
784 const struct svga_shader_variant *variant = svga->state.hw_draw.gs;
785 enum pipe_error ret = PIPE_OK;
786
787 /* SVGA_NEW_GS_VARIANT
788 */
789 if (!variant)
790 return PIPE_OK;
791
792 /* SVGA_NEW_GS_CONST_BUFFER
793 */
794 if (svga_have_vgpu10(svga)) {
795 /**
796 * If only the rasterizer state has changed and the current geometry
797 * shader does not emit wide points, then there is no reason to
798 * re-emit the GS constants, so skip it.
799 */
800 if (dirty == SVGA_NEW_RAST && !variant->key.gs.wide_point)
801 return PIPE_OK;
802
803 ret = emit_consts_vgpu10(svga, PIPE_SHADER_GEOMETRY);
804 }
805
806 return ret;
807 }
808
809
810 struct svga_tracked_state svga_hw_gs_constants =
811 {
812 "hw gs params",
813 (SVGA_NEW_GS_CONST_BUFFER |
814 SVGA_NEW_RAST |
815 SVGA_NEW_GS_VARIANT),
816 emit_gs_consts
817 };
818