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