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