1 /********************************************************** 2 * Copyright 2008-2009 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 "pipe/p_compiler.h" 27 #include "util/u_inlines.h" 28 #include "pipe/p_defines.h" 29 #include "util/u_helpers.h" 30 #include "util/u_memory.h" 31 #include "util/u_math.h" 32 33 #include "svga_context.h" 34 #include "svga_draw.h" 35 #include "svga_draw_private.h" 36 #include "svga_debug.h" 37 #include "svga_screen.h" 38 #include "svga_resource.h" 39 #include "svga_resource_buffer.h" 40 #include "svga_resource_texture.h" 41 #include "svga_shader.h" 42 #include "svga_surface.h" 43 #include "svga_winsys.h" 44 #include "svga_cmd.h" 45 46 47 struct svga_hwtnl * 48 svga_hwtnl_create(struct svga_context *svga) 49 { 50 struct svga_hwtnl *hwtnl = CALLOC_STRUCT(svga_hwtnl); 51 if (!hwtnl) 52 goto fail; 53 54 hwtnl->svga = svga; 55 56 hwtnl->cmd.swc = svga->swc; 57 58 return hwtnl; 59 60 fail: 61 return NULL; 62 } 63 64 65 void 66 svga_hwtnl_destroy(struct svga_hwtnl *hwtnl) 67 { 68 unsigned i, j; 69 70 for (i = 0; i < PIPE_PRIM_MAX; i++) { 71 for (j = 0; j < IDX_CACHE_MAX; j++) { 72 pipe_resource_reference(&hwtnl->index_cache[i][j].buffer, NULL); 73 } 74 } 75 76 for (i = 0; i < hwtnl->cmd.vbuf_count; i++) 77 pipe_resource_reference(&hwtnl->cmd.vbufs[i].buffer, NULL); 78 79 for (i = 0; i < hwtnl->cmd.prim_count; i++) 80 pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL); 81 82 FREE(hwtnl); 83 } 84 85 86 void 87 svga_hwtnl_set_flatshade(struct svga_hwtnl *hwtnl, 88 boolean flatshade, boolean flatshade_first) 89 { 90 struct svga_screen *svgascreen = svga_screen(hwtnl->svga->pipe.screen); 91 92 /* User-specified PV */ 93 hwtnl->api_pv = (flatshade && !flatshade_first) ? PV_LAST : PV_FIRST; 94 95 /* Device supported PV */ 96 if (svgascreen->haveProvokingVertex) { 97 /* use the mode specified by the user */ 98 hwtnl->hw_pv = hwtnl->api_pv; 99 } 100 else { 101 /* the device only support first provoking vertex */ 102 hwtnl->hw_pv = PV_FIRST; 103 } 104 } 105 106 107 void 108 svga_hwtnl_set_fillmode(struct svga_hwtnl *hwtnl, unsigned mode) 109 { 110 hwtnl->api_fillmode = mode; 111 } 112 113 114 void 115 svga_hwtnl_vertex_decls(struct svga_hwtnl *hwtnl, 116 unsigned count, 117 const SVGA3dVertexDecl * decls, 118 const unsigned *buffer_indexes, 119 SVGA3dElementLayoutId layout_id) 120 { 121 assert(hwtnl->cmd.prim_count == 0); 122 hwtnl->cmd.vdecl_count = count; 123 hwtnl->cmd.vdecl_layout_id = layout_id; 124 memcpy(hwtnl->cmd.vdecl, decls, count * sizeof(*decls)); 125 memcpy(hwtnl->cmd.vdecl_buffer_index, buffer_indexes, 126 count * sizeof(unsigned)); 127 } 128 129 130 /** 131 * Specify vertex buffers for hardware drawing. 132 */ 133 void 134 svga_hwtnl_vertex_buffers(struct svga_hwtnl *hwtnl, 135 unsigned count, struct pipe_vertex_buffer *buffers) 136 { 137 util_set_vertex_buffers_count(hwtnl->cmd.vbufs, 138 &hwtnl->cmd.vbuf_count, buffers, 0, count); 139 } 140 141 142 /** 143 * Determine whether the specified buffer is referred in the primitive queue, 144 * for which no commands have been written yet. 145 */ 146 boolean 147 svga_hwtnl_is_buffer_referred(struct svga_hwtnl *hwtnl, 148 struct pipe_resource *buffer) 149 { 150 unsigned i; 151 152 if (svga_buffer_is_user_buffer(buffer)) { 153 return FALSE; 154 } 155 156 if (!hwtnl->cmd.prim_count) { 157 return FALSE; 158 } 159 160 for (i = 0; i < hwtnl->cmd.vbuf_count; ++i) { 161 if (hwtnl->cmd.vbufs[i].buffer == buffer) { 162 return TRUE; 163 } 164 } 165 166 for (i = 0; i < hwtnl->cmd.prim_count; ++i) { 167 if (hwtnl->cmd.prim_ib[i] == buffer) { 168 return TRUE; 169 } 170 } 171 172 return FALSE; 173 } 174 175 176 static enum pipe_error 177 draw_vgpu9(struct svga_hwtnl *hwtnl) 178 { 179 struct svga_winsys_context *swc = hwtnl->cmd.swc; 180 struct svga_context *svga = hwtnl->svga; 181 enum pipe_error ret; 182 struct svga_winsys_surface *vb_handle[SVGA3D_INPUTREG_MAX]; 183 struct svga_winsys_surface *ib_handle[QSZ]; 184 struct svga_winsys_surface *handle; 185 SVGA3dVertexDecl *vdecl; 186 SVGA3dPrimitiveRange *prim; 187 unsigned i; 188 189 for (i = 0; i < hwtnl->cmd.vdecl_count; i++) { 190 unsigned j = hwtnl->cmd.vdecl_buffer_index[i]; 191 handle = svga_buffer_handle(svga, hwtnl->cmd.vbufs[j].buffer); 192 if (!handle) 193 return PIPE_ERROR_OUT_OF_MEMORY; 194 195 vb_handle[i] = handle; 196 } 197 198 for (i = 0; i < hwtnl->cmd.prim_count; i++) { 199 if (hwtnl->cmd.prim_ib[i]) { 200 handle = svga_buffer_handle(svga, hwtnl->cmd.prim_ib[i]); 201 if (!handle) 202 return PIPE_ERROR_OUT_OF_MEMORY; 203 } 204 else 205 handle = NULL; 206 207 ib_handle[i] = handle; 208 } 209 210 if (svga->rebind.flags.rendertargets) { 211 ret = svga_reemit_framebuffer_bindings(svga); 212 if (ret != PIPE_OK) { 213 return ret; 214 } 215 } 216 217 if (svga->rebind.flags.texture_samplers) { 218 ret = svga_reemit_tss_bindings(svga); 219 if (ret != PIPE_OK) { 220 return ret; 221 } 222 } 223 224 if (svga->rebind.flags.vs) { 225 ret = svga_reemit_vs_bindings(svga); 226 if (ret != PIPE_OK) { 227 return ret; 228 } 229 } 230 231 if (svga->rebind.flags.fs) { 232 ret = svga_reemit_fs_bindings(svga); 233 if (ret != PIPE_OK) { 234 return ret; 235 } 236 } 237 238 SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n", 239 svga->curr.framebuffer.cbufs[0] ? 240 svga_surface(svga->curr.framebuffer.cbufs[0])->handle : NULL, 241 hwtnl->cmd.prim_count); 242 243 ret = SVGA3D_BeginDrawPrimitives(swc, 244 &vdecl, 245 hwtnl->cmd.vdecl_count, 246 &prim, hwtnl->cmd.prim_count); 247 if (ret != PIPE_OK) 248 return ret; 249 250 memcpy(vdecl, 251 hwtnl->cmd.vdecl, 252 hwtnl->cmd.vdecl_count * sizeof hwtnl->cmd.vdecl[0]); 253 254 for (i = 0; i < hwtnl->cmd.vdecl_count; i++) { 255 /* check for 4-byte alignment */ 256 assert(vdecl[i].array.offset % 4 == 0); 257 assert(vdecl[i].array.stride % 4 == 0); 258 259 /* Given rangeHint is considered to be relative to indexBias, and 260 * indexBias varies per primitive, we cannot accurately supply an 261 * rangeHint when emitting more than one primitive per draw command. 262 */ 263 if (hwtnl->cmd.prim_count == 1) { 264 vdecl[i].rangeHint.first = hwtnl->cmd.min_index[0]; 265 vdecl[i].rangeHint.last = hwtnl->cmd.max_index[0] + 1; 266 } 267 else { 268 vdecl[i].rangeHint.first = 0; 269 vdecl[i].rangeHint.last = 0; 270 } 271 272 swc->surface_relocation(swc, 273 &vdecl[i].array.surfaceId, 274 NULL, vb_handle[i], SVGA_RELOC_READ); 275 } 276 277 memcpy(prim, 278 hwtnl->cmd.prim, hwtnl->cmd.prim_count * sizeof hwtnl->cmd.prim[0]); 279 280 for (i = 0; i < hwtnl->cmd.prim_count; i++) { 281 swc->surface_relocation(swc, 282 &prim[i].indexArray.surfaceId, 283 NULL, ib_handle[i], SVGA_RELOC_READ); 284 pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL); 285 } 286 287 SVGA_FIFOCommitAll(swc); 288 289 hwtnl->cmd.prim_count = 0; 290 291 return PIPE_OK; 292 } 293 294 295 static SVGA3dSurfaceFormat 296 xlate_index_format(unsigned indexWidth) 297 { 298 if (indexWidth == 2) { 299 return SVGA3D_R16_UINT; 300 } 301 else if (indexWidth == 4) { 302 return SVGA3D_R32_UINT; 303 } 304 else { 305 assert(!"Bad indexWidth"); 306 return SVGA3D_R32_UINT; 307 } 308 } 309 310 311 static enum pipe_error 312 validate_sampler_resources(struct svga_context *svga) 313 { 314 enum pipe_shader_type shader; 315 316 assert(svga_have_vgpu10(svga)); 317 318 for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) { 319 unsigned count = svga->curr.num_sampler_views[shader]; 320 unsigned i; 321 struct svga_winsys_surface *surfaces[PIPE_MAX_SAMPLERS]; 322 enum pipe_error ret; 323 324 /* 325 * Reference bound sampler resources to ensure pending updates are 326 * noticed by the device. 327 */ 328 for (i = 0; i < count; i++) { 329 struct svga_pipe_sampler_view *sv = 330 svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]); 331 332 if (sv) { 333 if (sv->base.texture->target == PIPE_BUFFER) { 334 surfaces[i] = svga_buffer_handle(svga, sv->base.texture); 335 } 336 else { 337 surfaces[i] = svga_texture(sv->base.texture)->handle; 338 } 339 } 340 else { 341 surfaces[i] = NULL; 342 } 343 } 344 345 if (shader == PIPE_SHADER_FRAGMENT && 346 svga->curr.rast->templ.poly_stipple_enable) { 347 const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit; 348 struct svga_pipe_sampler_view *sv = 349 svga->polygon_stipple.sampler_view; 350 351 assert(sv); 352 surfaces[unit] = svga_texture(sv->base.texture)->handle; 353 count = MAX2(count, unit+1); 354 } 355 356 /* rebind the shader resources if needed */ 357 if (svga->rebind.flags.texture_samplers) { 358 for (i = 0; i < count; i++) { 359 if (surfaces[i]) { 360 ret = svga->swc->resource_rebind(svga->swc, 361 surfaces[i], 362 NULL, 363 SVGA_RELOC_READ); 364 if (ret != PIPE_OK) 365 return ret; 366 } 367 } 368 } 369 } 370 svga->rebind.flags.texture_samplers = FALSE; 371 372 return PIPE_OK; 373 } 374 375 376 static enum pipe_error 377 validate_constant_buffers(struct svga_context *svga) 378 { 379 enum pipe_shader_type shader; 380 381 assert(svga_have_vgpu10(svga)); 382 383 for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) { 384 enum pipe_error ret; 385 struct svga_buffer *buffer; 386 struct svga_winsys_surface *handle; 387 unsigned enabled_constbufs; 388 389 /* Rebind the default constant buffer if needed */ 390 if (svga->rebind.flags.constbufs) { 391 buffer = svga_buffer(svga->state.hw_draw.constbuf[shader]); 392 if (buffer) { 393 ret = svga->swc->resource_rebind(svga->swc, 394 buffer->handle, 395 NULL, 396 SVGA_RELOC_READ); 397 if (ret != PIPE_OK) 398 return ret; 399 } 400 } 401 402 /* 403 * Reference other bound constant buffers to ensure pending updates are 404 * noticed by the device. 405 */ 406 enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] & ~1u; 407 while (enabled_constbufs) { 408 unsigned i = u_bit_scan(&enabled_constbufs); 409 buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer); 410 if (buffer) { 411 handle = svga_buffer_handle(svga, &buffer->b.b); 412 413 if (svga->rebind.flags.constbufs) { 414 ret = svga->swc->resource_rebind(svga->swc, 415 handle, 416 NULL, 417 SVGA_RELOC_READ); 418 if (ret != PIPE_OK) 419 return ret; 420 } 421 } 422 } 423 } 424 svga->rebind.flags.constbufs = FALSE; 425 426 return PIPE_OK; 427 } 428 429 430 /** 431 * Was the last command put into the command buffer a drawing command? 432 * We use this to determine if we can skip emitting buffer re-bind 433 * commands when we have a sequence of drawing commands that use the 434 * same vertex/index buffers with no intervening commands. 435 * 436 * The first drawing command will bind the vertex/index buffers. If 437 * the immediately following command is also a drawing command using the 438 * same buffers, we shouldn't have to rebind them. 439 */ 440 static bool 441 last_command_was_draw(const struct svga_context *svga) 442 { 443 switch (SVGA3D_GetLastCommand(svga->swc)) { 444 case SVGA_3D_CMD_DX_DRAW: 445 case SVGA_3D_CMD_DX_DRAW_INDEXED: 446 case SVGA_3D_CMD_DX_DRAW_INSTANCED: 447 case SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED: 448 case SVGA_3D_CMD_DX_DRAW_AUTO: 449 return true; 450 default: 451 return false; 452 } 453 } 454 455 456 static enum pipe_error 457 draw_vgpu10(struct svga_hwtnl *hwtnl, 458 const SVGA3dPrimitiveRange *range, 459 unsigned vcount, 460 unsigned min_index, 461 unsigned max_index, struct pipe_resource *ib, 462 unsigned start_instance, unsigned instance_count) 463 { 464 struct svga_context *svga = hwtnl->svga; 465 struct pipe_resource *vbuffers[SVGA3D_INPUTREG_MAX]; 466 struct svga_winsys_surface *vbuffer_handles[SVGA3D_INPUTREG_MAX]; 467 struct svga_winsys_surface *ib_handle; 468 const unsigned vbuf_count = hwtnl->cmd.vbuf_count; 469 int last_vbuf = -1; 470 enum pipe_error ret; 471 unsigned i; 472 473 assert(svga_have_vgpu10(svga)); 474 assert(hwtnl->cmd.prim_count == 0); 475 476 /* We need to reemit all the current resource bindings along with the Draw 477 * command to be sure that the referenced resources are available for the 478 * Draw command, just in case the surfaces associated with the resources 479 * are paged out. 480 */ 481 if (svga->rebind.val) { 482 ret = svga_rebind_framebuffer_bindings(svga); 483 if (ret != PIPE_OK) 484 return ret; 485 486 ret = svga_rebind_shaders(svga); 487 if (ret != PIPE_OK) 488 return ret; 489 490 /* Rebind stream output targets */ 491 ret = svga_rebind_stream_output_targets(svga); 492 if (ret != PIPE_OK) 493 return ret; 494 495 /* No need to explicitly rebind index buffer and vertex buffers here. 496 * Even if the same index buffer or vertex buffers are referenced for this 497 * draw and we skip emitting the redundant set command, we will still 498 * reference the associated resources. 499 */ 500 } 501 502 ret = validate_sampler_resources(svga); 503 if (ret != PIPE_OK) 504 return ret; 505 506 ret = validate_constant_buffers(svga); 507 if (ret != PIPE_OK) 508 return ret; 509 510 /* Get handle for each referenced vertex buffer */ 511 for (i = 0; i < vbuf_count; i++) { 512 struct svga_buffer *sbuf = svga_buffer(hwtnl->cmd.vbufs[i].buffer); 513 514 if (sbuf) { 515 assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER); 516 vbuffer_handles[i] = svga_buffer_handle(svga, &sbuf->b.b); 517 if (vbuffer_handles[i] == NULL) 518 return PIPE_ERROR_OUT_OF_MEMORY; 519 vbuffers[i] = &sbuf->b.b; 520 last_vbuf = i; 521 } 522 else { 523 vbuffers[i] = NULL; 524 vbuffer_handles[i] = NULL; 525 } 526 } 527 528 for (; i < svga->state.hw_draw.num_vbuffers; i++) { 529 vbuffers[i] = NULL; 530 vbuffer_handles[i] = NULL; 531 } 532 533 /* Get handle for the index buffer */ 534 if (ib) { 535 struct svga_buffer *sbuf = svga_buffer(ib); 536 537 assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_INDEX_BUFFER); 538 (void) sbuf; /* silence unused var warning */ 539 540 ib_handle = svga_buffer_handle(svga, ib); 541 if (!ib_handle) 542 return PIPE_ERROR_OUT_OF_MEMORY; 543 } 544 else { 545 ib_handle = NULL; 546 } 547 548 /* setup vertex attribute input layout */ 549 if (svga->state.hw_draw.layout_id != hwtnl->cmd.vdecl_layout_id) { 550 ret = SVGA3D_vgpu10_SetInputLayout(svga->swc, 551 hwtnl->cmd.vdecl_layout_id); 552 if (ret != PIPE_OK) 553 return ret; 554 555 svga->state.hw_draw.layout_id = hwtnl->cmd.vdecl_layout_id; 556 } 557 558 /* setup vertex buffers */ 559 { 560 SVGA3dVertexBuffer vbuffer_attrs[PIPE_MAX_ATTRIBS]; 561 562 for (i = 0; i < vbuf_count; i++) { 563 vbuffer_attrs[i].stride = hwtnl->cmd.vbufs[i].stride; 564 vbuffer_attrs[i].offset = hwtnl->cmd.vbufs[i].buffer_offset; 565 vbuffer_attrs[i].sid = 0; 566 } 567 568 /* If we haven't yet emitted a drawing command or if any 569 * vertex buffer state is changing, issue that state now. 570 */ 571 if (((hwtnl->cmd.swc->hints & SVGA_HINT_FLAG_CAN_PRE_FLUSH) == 0) || 572 vbuf_count != svga->state.hw_draw.num_vbuffers || 573 memcmp(vbuffer_attrs, svga->state.hw_draw.vbuffer_attrs, 574 vbuf_count * sizeof(vbuffer_attrs[0])) || 575 memcmp(vbuffers, svga->state.hw_draw.vbuffers, 576 vbuf_count * sizeof(vbuffers[0]))) { 577 578 unsigned num_vbuffers; 579 580 /* get the max of the current bound vertex buffers count and 581 * the to-be-bound vertex buffers count, so as to unbind 582 * the unused vertex buffers. 583 */ 584 num_vbuffers = MAX2(vbuf_count, svga->state.hw_draw.num_vbuffers); 585 586 if (num_vbuffers > 0) { 587 588 ret = SVGA3D_vgpu10_SetVertexBuffers(svga->swc, num_vbuffers, 589 0, /* startBuffer */ 590 vbuffer_attrs, 591 vbuffer_handles); 592 if (ret != PIPE_OK) 593 return ret; 594 595 /* save the number of vertex buffers sent to the device, not 596 * including trailing unbound vertex buffers. 597 */ 598 svga->state.hw_draw.num_vbuffers = last_vbuf + 1; 599 memcpy(svga->state.hw_draw.vbuffer_attrs, vbuffer_attrs, 600 num_vbuffers * sizeof(vbuffer_attrs[0])); 601 for (i = 0; i < num_vbuffers; i++) { 602 pipe_resource_reference(&svga->state.hw_draw.vbuffers[i], 603 vbuffers[i]); 604 } 605 } 606 } 607 else { 608 /* Even though we can avoid emitting the redundant SetVertexBuffers 609 * command, we still need to reference the vertex buffers surfaces. 610 */ 611 for (i = 0; i < vbuf_count; i++) { 612 if (vbuffer_handles[i] && !last_command_was_draw(svga)) { 613 ret = svga->swc->resource_rebind(svga->swc, vbuffer_handles[i], 614 NULL, SVGA_RELOC_READ); 615 if (ret != PIPE_OK) 616 return ret; 617 } 618 } 619 } 620 } 621 622 /* Set primitive type (line, tri, etc) */ 623 if (svga->state.hw_draw.topology != range->primType) { 624 ret = SVGA3D_vgpu10_SetTopology(svga->swc, range->primType); 625 if (ret != PIPE_OK) 626 return ret; 627 628 svga->state.hw_draw.topology = range->primType; 629 } 630 631 if (ib_handle) { 632 /* indexed drawing */ 633 SVGA3dSurfaceFormat indexFormat = xlate_index_format(range->indexWidth); 634 635 /* setup index buffer */ 636 if (ib != svga->state.hw_draw.ib || 637 indexFormat != svga->state.hw_draw.ib_format || 638 range->indexArray.offset != svga->state.hw_draw.ib_offset) { 639 640 assert(indexFormat != SVGA3D_FORMAT_INVALID); 641 ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, ib_handle, 642 indexFormat, 643 range->indexArray.offset); 644 if (ret != PIPE_OK) 645 return ret; 646 647 pipe_resource_reference(&svga->state.hw_draw.ib, ib); 648 svga->state.hw_draw.ib_format = indexFormat; 649 svga->state.hw_draw.ib_offset = range->indexArray.offset; 650 } 651 else { 652 /* Even though we can avoid emitting the redundant SetIndexBuffer 653 * command, we still need to reference the index buffer surface. 654 */ 655 if (!last_command_was_draw(svga)) { 656 ret = svga->swc->resource_rebind(svga->swc, ib_handle, 657 NULL, SVGA_RELOC_READ); 658 if (ret != PIPE_OK) 659 return ret; 660 } 661 } 662 663 if (instance_count > 1) { 664 ret = SVGA3D_vgpu10_DrawIndexedInstanced(svga->swc, 665 vcount, 666 instance_count, 667 0, /* startIndexLocation */ 668 range->indexBias, 669 start_instance); 670 if (ret != PIPE_OK) 671 return ret; 672 } 673 else { 674 /* non-instanced drawing */ 675 ret = SVGA3D_vgpu10_DrawIndexed(svga->swc, 676 vcount, 677 0, /* startIndexLocation */ 678 range->indexBias); 679 if (ret != PIPE_OK) 680 return ret; 681 } 682 } 683 else { 684 /* non-indexed drawing */ 685 if (svga->state.hw_draw.ib_format != SVGA3D_FORMAT_INVALID || 686 svga->state.hw_draw.ib != NULL) { 687 /* Unbind previously bound index buffer */ 688 ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, NULL, 689 SVGA3D_FORMAT_INVALID, 0); 690 if (ret != PIPE_OK) 691 return ret; 692 pipe_resource_reference(&svga->state.hw_draw.ib, NULL); 693 svga->state.hw_draw.ib_format = SVGA3D_FORMAT_INVALID; 694 } 695 696 assert(svga->state.hw_draw.ib == NULL); 697 698 if (instance_count > 1) { 699 ret = SVGA3D_vgpu10_DrawInstanced(svga->swc, 700 vcount, 701 instance_count, 702 range->indexBias, 703 start_instance); 704 if (ret != PIPE_OK) 705 return ret; 706 } 707 else { 708 /* non-instanced */ 709 ret = SVGA3D_vgpu10_Draw(svga->swc, 710 vcount, 711 range->indexBias); 712 if (ret != PIPE_OK) 713 return ret; 714 } 715 } 716 717 hwtnl->cmd.prim_count = 0; 718 719 return PIPE_OK; 720 } 721 722 723 724 /** 725 * Emit any pending drawing commands to the command buffer. 726 * When we receive VGPU9 drawing commands we accumulate them and don't 727 * immediately emit them into the command buffer. 728 * This function needs to be called before we change state that could 729 * effect those pending draws. 730 */ 731 enum pipe_error 732 svga_hwtnl_flush(struct svga_hwtnl *hwtnl) 733 { 734 enum pipe_error ret = PIPE_OK; 735 736 SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLFLUSH); 737 738 if (!svga_have_vgpu10(hwtnl->svga) && hwtnl->cmd.prim_count) { 739 /* we only queue up primitive for VGPU9 */ 740 ret = draw_vgpu9(hwtnl); 741 } 742 743 SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws); 744 return ret; 745 } 746 747 748 void 749 svga_hwtnl_set_index_bias(struct svga_hwtnl *hwtnl, int index_bias) 750 { 751 hwtnl->index_bias = index_bias; 752 } 753 754 755 756 /*********************************************************************** 757 * Internal functions: 758 */ 759 760 /** 761 * For debugging only. 762 */ 763 static void 764 check_draw_params(struct svga_hwtnl *hwtnl, 765 const SVGA3dPrimitiveRange *range, 766 unsigned min_index, unsigned max_index, 767 struct pipe_resource *ib) 768 { 769 unsigned i; 770 771 assert(!svga_have_vgpu10(hwtnl->svga)); 772 773 for (i = 0; i < hwtnl->cmd.vdecl_count; i++) { 774 unsigned j = hwtnl->cmd.vdecl_buffer_index[i]; 775 const struct pipe_vertex_buffer *vb = &hwtnl->cmd.vbufs[j]; 776 unsigned size = vb->buffer ? vb->buffer->width0 : 0; 777 unsigned offset = hwtnl->cmd.vdecl[i].array.offset; 778 unsigned stride = hwtnl->cmd.vdecl[i].array.stride; 779 int index_bias = (int) range->indexBias + hwtnl->index_bias; 780 unsigned width; 781 782 if (size == 0) 783 continue; 784 785 assert(vb); 786 assert(size); 787 assert(offset < size); 788 assert(min_index <= max_index); 789 (void) width; 790 (void) stride; 791 (void) offset; 792 (void) size; 793 794 switch (hwtnl->cmd.vdecl[i].identity.type) { 795 case SVGA3D_DECLTYPE_FLOAT1: 796 width = 4; 797 break; 798 case SVGA3D_DECLTYPE_FLOAT2: 799 width = 4 * 2; 800 break; 801 case SVGA3D_DECLTYPE_FLOAT3: 802 width = 4 * 3; 803 break; 804 case SVGA3D_DECLTYPE_FLOAT4: 805 width = 4 * 4; 806 break; 807 case SVGA3D_DECLTYPE_D3DCOLOR: 808 width = 4; 809 break; 810 case SVGA3D_DECLTYPE_UBYTE4: 811 width = 1 * 4; 812 break; 813 case SVGA3D_DECLTYPE_SHORT2: 814 width = 2 * 2; 815 break; 816 case SVGA3D_DECLTYPE_SHORT4: 817 width = 2 * 4; 818 break; 819 case SVGA3D_DECLTYPE_UBYTE4N: 820 width = 1 * 4; 821 break; 822 case SVGA3D_DECLTYPE_SHORT2N: 823 width = 2 * 2; 824 break; 825 case SVGA3D_DECLTYPE_SHORT4N: 826 width = 2 * 4; 827 break; 828 case SVGA3D_DECLTYPE_USHORT2N: 829 width = 2 * 2; 830 break; 831 case SVGA3D_DECLTYPE_USHORT4N: 832 width = 2 * 4; 833 break; 834 case SVGA3D_DECLTYPE_UDEC3: 835 width = 4; 836 break; 837 case SVGA3D_DECLTYPE_DEC3N: 838 width = 4; 839 break; 840 case SVGA3D_DECLTYPE_FLOAT16_2: 841 width = 2 * 2; 842 break; 843 case SVGA3D_DECLTYPE_FLOAT16_4: 844 width = 2 * 4; 845 break; 846 default: 847 assert(0); 848 width = 0; 849 break; 850 } 851 852 if (index_bias >= 0) { 853 assert(offset + index_bias * stride + width <= size); 854 } 855 856 /* 857 * min_index/max_index are merely conservative guesses, so we can't 858 * make buffer overflow detection based on their values. 859 */ 860 } 861 862 assert(range->indexWidth == range->indexArray.stride); 863 864 if (ib) { 865 MAYBE_UNUSED unsigned size = ib->width0; 866 MAYBE_UNUSED unsigned offset = range->indexArray.offset; 867 MAYBE_UNUSED unsigned stride = range->indexArray.stride; 868 MAYBE_UNUSED unsigned count; 869 870 assert(size); 871 assert(offset < size); 872 assert(stride); 873 874 switch (range->primType) { 875 case SVGA3D_PRIMITIVE_POINTLIST: 876 count = range->primitiveCount; 877 break; 878 case SVGA3D_PRIMITIVE_LINELIST: 879 count = range->primitiveCount * 2; 880 break; 881 case SVGA3D_PRIMITIVE_LINESTRIP: 882 count = range->primitiveCount + 1; 883 break; 884 case SVGA3D_PRIMITIVE_TRIANGLELIST: 885 count = range->primitiveCount * 3; 886 break; 887 case SVGA3D_PRIMITIVE_TRIANGLESTRIP: 888 count = range->primitiveCount + 2; 889 break; 890 case SVGA3D_PRIMITIVE_TRIANGLEFAN: 891 count = range->primitiveCount + 2; 892 break; 893 default: 894 assert(0); 895 count = 0; 896 break; 897 } 898 899 assert(offset + count * stride <= size); 900 } 901 } 902 903 904 /** 905 * All drawing filters down into this function, either directly 906 * on the hardware path or after doing software vertex processing. 907 */ 908 enum pipe_error 909 svga_hwtnl_prim(struct svga_hwtnl *hwtnl, 910 const SVGA3dPrimitiveRange * range, 911 unsigned vcount, 912 unsigned min_index, 913 unsigned max_index, struct pipe_resource *ib, 914 unsigned start_instance, unsigned instance_count) 915 { 916 enum pipe_error ret = PIPE_OK; 917 918 SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLPRIM); 919 920 if (svga_have_vgpu10(hwtnl->svga)) { 921 /* draw immediately */ 922 ret = draw_vgpu10(hwtnl, range, vcount, min_index, max_index, ib, 923 start_instance, instance_count); 924 if (ret != PIPE_OK) { 925 svga_context_flush(hwtnl->svga, NULL); 926 ret = draw_vgpu10(hwtnl, range, vcount, min_index, max_index, ib, 927 start_instance, instance_count); 928 assert(ret == PIPE_OK); 929 } 930 } 931 else { 932 /* batch up drawing commands */ 933 #ifdef DEBUG 934 check_draw_params(hwtnl, range, min_index, max_index, ib); 935 assert(start_instance == 0); 936 assert(instance_count <= 1); 937 #else 938 (void) check_draw_params; 939 #endif 940 941 if (hwtnl->cmd.prim_count + 1 >= QSZ) { 942 ret = svga_hwtnl_flush(hwtnl); 943 if (ret != PIPE_OK) 944 goto done; 945 } 946 947 /* min/max indices are relative to bias */ 948 hwtnl->cmd.min_index[hwtnl->cmd.prim_count] = min_index; 949 hwtnl->cmd.max_index[hwtnl->cmd.prim_count] = max_index; 950 951 hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range; 952 hwtnl->cmd.prim[hwtnl->cmd.prim_count].indexBias += hwtnl->index_bias; 953 954 pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib); 955 hwtnl->cmd.prim_count++; 956 } 957 958 done: 959 SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws); 960 return ret; 961 } 962