util: Move gallium's PIPE_FORMAT utils to /util/format/
[mesa.git] / src / gallium / drivers / svga / svga_state_constants.c
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
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
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
136 svga_get_prescale_constants(const 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
151 svga_get_pt_sprite_constants(const 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
169 svga_get_clip_plane_constants(const 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
198 svga_get_extra_vs_constants(const 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
236 svga_get_extra_gs_constants(const 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
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
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
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 switch (shader) {
494 case PIPE_SHADER_VERTEX:
495 variant = svga->state.hw_draw.vs;
496 extra_count = svga_get_extra_vs_constants(svga, (float *) extras);
497 break;
498 case PIPE_SHADER_FRAGMENT:
499 variant = svga->state.hw_draw.fs;
500 extra_count = svga_get_extra_fs_constants(svga, (float *) extras);
501 break;
502 case PIPE_SHADER_GEOMETRY:
503 variant = svga->state.hw_draw.gs;
504 extra_count = svga_get_extra_gs_constants(svga, (float *) extras);
505 break;
506 default:
507 assert(!"Unexpected shader type");
508 /* Don't return an error code since we don't want to keep re-trying
509 * this function and getting stuck in an infinite loop.
510 */
511 return PIPE_OK;
512 }
513
514 assert(variant);
515
516 cbuf = &svga->curr.constbufs[shader][0];
517
518 /* Compute extra constants size and offset in bytes */
519 extra_size = extra_count * 4 * sizeof(float);
520 extra_offset = 4 * sizeof(float) * variant->extra_const_start;
521
522 if (cbuf->buffer_size + extra_size == 0)
523 return PIPE_OK; /* nothing to do */
524
525 /* Typically, the cbuf->buffer here is a user-space buffer so mapping
526 * it is really cheap. If we ever get real HW buffers for constants
527 * we should void mapping and instead use a ResourceCopy command.
528 */
529 if (cbuf->buffer_size > 0) {
530 src_map = pipe_buffer_map_range(&svga->pipe, cbuf->buffer,
531 cbuf->buffer_offset, cbuf->buffer_size,
532 PIPE_TRANSFER_READ, &src_transfer);
533 assert(src_map);
534 if (!src_map) {
535 return PIPE_ERROR_OUT_OF_MEMORY;
536 }
537 }
538
539 /* The new/dest buffer's size must be large enough to hold the original,
540 * user-specified constants, plus the extra constants.
541 * The size of the original constant buffer _should_ agree with what the
542 * shader is expecting, but it might not (it's not enforced anywhere by
543 * gallium).
544 */
545 new_buf_size = MAX2(cbuf->buffer_size, extra_offset) + extra_size;
546
547 /* According to the DX10 spec, the constant buffer size must be
548 * in multiples of 16.
549 */
550 new_buf_size = align(new_buf_size, 16);
551
552 /* Constant buffer size in the upload buffer must be in multiples of 256.
553 * In order to maximize the chance of merging the upload buffer chunks
554 * when svga_buffer_add_range() is called,
555 * the allocate buffer size needs to be in multiples of 256 as well.
556 * Otherwise, since there is gap between each dirty range of the upload buffer,
557 * each dirty range will end up in its own UPDATE_GB_IMAGE command.
558 */
559 alloc_buf_size = align(new_buf_size, CONST0_UPLOAD_ALIGNMENT);
560
561 u_upload_alloc(svga->const0_upload, 0, alloc_buf_size,
562 CONST0_UPLOAD_ALIGNMENT, &offset,
563 &dst_buffer, &dst_map);
564 if (!dst_map) {
565 if (src_map)
566 pipe_buffer_unmap(&svga->pipe, src_transfer);
567 return PIPE_ERROR_OUT_OF_MEMORY;
568 }
569
570 if (src_map) {
571 memcpy(dst_map, src_map, cbuf->buffer_size);
572 pipe_buffer_unmap(&svga->pipe, src_transfer);
573 }
574
575 if (extra_size) {
576 assert(extra_offset + extra_size <= new_buf_size);
577 memcpy((char *) dst_map + extra_offset, extras, extra_size);
578 }
579
580 /* Get winsys handle for the constant buffer */
581 if (svga->state.hw_draw.const0_buffer == dst_buffer &&
582 svga->state.hw_draw.const0_handle) {
583 /* re-reference already mapped buffer */
584 dst_handle = svga->state.hw_draw.const0_handle;
585 }
586 else {
587 /* we must unmap the buffer before getting the winsys handle */
588 u_upload_unmap(svga->const0_upload);
589
590 dst_handle = svga_buffer_handle(svga, dst_buffer,
591 PIPE_BIND_CONSTANT_BUFFER);
592 if (!dst_handle) {
593 pipe_resource_reference(&dst_buffer, NULL);
594 return PIPE_ERROR_OUT_OF_MEMORY;
595 }
596
597 /* save the buffer / handle for next time */
598 pipe_resource_reference(&svga->state.hw_draw.const0_buffer, dst_buffer);
599 svga->state.hw_draw.const0_handle = dst_handle;
600 }
601
602 /* Issue the SetSingleConstantBuffer command */
603 assert(new_buf_size % 16 == 0);
604 ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
605 0, /* index */
606 svga_shader_type(shader),
607 dst_handle,
608 offset,
609 new_buf_size);
610
611 if (ret != PIPE_OK) {
612 pipe_resource_reference(&dst_buffer, NULL);
613 return ret;
614 }
615
616 /* Save this const buffer until it's replaced in the future.
617 * Otherwise, all references to the buffer will go away after the
618 * command buffer is submitted, it'll get recycled and we will have
619 * incorrect constant buffer bindings.
620 */
621 pipe_resource_reference(&svga->state.hw_draw.constbuf[shader], dst_buffer);
622
623 svga->state.hw_draw.default_constbuf_size[shader] = new_buf_size;
624
625 pipe_resource_reference(&dst_buffer, NULL);
626
627 svga->hud.num_const_buf_updates++;
628
629 return ret;
630 }
631
632
633 static enum pipe_error
634 emit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
635 {
636 enum pipe_error ret;
637 unsigned dirty_constbufs;
638 unsigned enabled_constbufs;
639
640 /* Emit 0th constant buffer (with extra constants) */
641 ret = emit_constbuf_vgpu10(svga, shader);
642 if (ret != PIPE_OK) {
643 return ret;
644 }
645
646 enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] | 1u;
647
648 /* Emit other constant buffers (UBOs) */
649 dirty_constbufs = svga->state.dirty_constbufs[shader] & ~1u;
650
651 while (dirty_constbufs) {
652 unsigned index = u_bit_scan(&dirty_constbufs);
653 unsigned offset = svga->curr.constbufs[shader][index].buffer_offset;
654 unsigned size = svga->curr.constbufs[shader][index].buffer_size;
655 struct svga_buffer *buffer =
656 svga_buffer(svga->curr.constbufs[shader][index].buffer);
657 struct svga_winsys_surface *handle;
658
659 if (buffer) {
660 handle = svga_buffer_handle(svga, &buffer->b.b,
661 PIPE_BIND_CONSTANT_BUFFER);
662 enabled_constbufs |= 1 << index;
663 }
664 else {
665 handle = NULL;
666 enabled_constbufs &= ~(1 << index);
667 assert(offset == 0);
668 assert(size == 0);
669 }
670
671 if (size % 16 != 0) {
672 /* GL's buffer range sizes can be any number of bytes but the
673 * SVGA3D device requires a multiple of 16 bytes.
674 */
675 const unsigned total_size = buffer->b.b.width0;
676
677 if (offset + align(size, 16) <= total_size) {
678 /* round up size to multiple of 16 */
679 size = align(size, 16);
680 }
681 else {
682 /* round down to mulitple of 16 (this may cause rendering problems
683 * but should avoid a device error).
684 */
685 size &= ~15;
686 }
687 }
688
689 assert(size % 16 == 0);
690 ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
691 index,
692 svga_shader_type(shader),
693 handle,
694 offset,
695 size);
696 if (ret != PIPE_OK)
697 return ret;
698
699 svga->hud.num_const_buf_updates++;
700 }
701
702 svga->state.hw_draw.enabled_constbufs[shader] = enabled_constbufs;
703 svga->state.dirty_constbufs[shader] = 0;
704
705 return ret;
706 }
707
708 static enum pipe_error
709 emit_fs_consts(struct svga_context *svga, unsigned dirty)
710 {
711 const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
712 enum pipe_error ret = PIPE_OK;
713
714 /* SVGA_NEW_FS_VARIANT
715 */
716 if (!variant)
717 return PIPE_OK;
718
719 /* SVGA_NEW_FS_CONST_BUFFER
720 */
721 if (svga_have_vgpu10(svga)) {
722 ret = emit_consts_vgpu10(svga, PIPE_SHADER_FRAGMENT);
723 }
724 else {
725 ret = emit_consts_vgpu9(svga, PIPE_SHADER_FRAGMENT);
726 }
727
728 return ret;
729 }
730
731
732 struct svga_tracked_state svga_hw_fs_constants =
733 {
734 "hw fs params",
735 (SVGA_NEW_FS_CONST_BUFFER |
736 SVGA_NEW_FS_VARIANT |
737 SVGA_NEW_TEXTURE_CONSTS),
738 emit_fs_consts
739 };
740
741
742
743 static enum pipe_error
744 emit_vs_consts(struct svga_context *svga, unsigned dirty)
745 {
746 const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
747 enum pipe_error ret = PIPE_OK;
748
749 /* SVGA_NEW_VS_VARIANT
750 */
751 if (!variant)
752 return PIPE_OK;
753
754 /* SVGA_NEW_VS_CONST_BUFFER
755 */
756 if (svga_have_vgpu10(svga)) {
757 ret = emit_consts_vgpu10(svga, PIPE_SHADER_VERTEX);
758 }
759 else {
760 ret = emit_consts_vgpu9(svga, PIPE_SHADER_VERTEX);
761 }
762
763 return ret;
764 }
765
766
767 struct svga_tracked_state svga_hw_vs_constants =
768 {
769 "hw vs params",
770 (SVGA_NEW_PRESCALE |
771 SVGA_NEW_VS_CONST_BUFFER |
772 SVGA_NEW_VS_VARIANT |
773 SVGA_NEW_TEXTURE_CONSTS),
774 emit_vs_consts
775 };
776
777
778 static enum pipe_error
779 emit_gs_consts(struct svga_context *svga, unsigned dirty)
780 {
781 const struct svga_shader_variant *variant = svga->state.hw_draw.gs;
782 enum pipe_error ret = PIPE_OK;
783
784 /* SVGA_NEW_GS_VARIANT
785 */
786 if (!variant)
787 return PIPE_OK;
788
789 /* SVGA_NEW_GS_CONST_BUFFER
790 */
791 if (svga_have_vgpu10(svga)) {
792 /**
793 * If only the rasterizer state has changed and the current geometry
794 * shader does not emit wide points, then there is no reason to
795 * re-emit the GS constants, so skip it.
796 */
797 if (dirty == SVGA_NEW_RAST && !variant->key.gs.wide_point)
798 return PIPE_OK;
799
800 ret = emit_consts_vgpu10(svga, PIPE_SHADER_GEOMETRY);
801 }
802
803 return ret;
804 }
805
806
807 struct svga_tracked_state svga_hw_gs_constants =
808 {
809 "hw gs params",
810 (SVGA_NEW_PRESCALE |
811 SVGA_NEW_GS_CONST_BUFFER |
812 SVGA_NEW_RAST |
813 SVGA_NEW_GS_VARIANT |
814 SVGA_NEW_TEXTURE_CONSTS),
815 emit_gs_consts
816 };