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