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 48struct svga_hwtnl * 49svga_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 61fail: 62 return NULL; 63} 64 65 66void 67svga_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 87void 88svga_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 108void 109svga_hwtnl_set_fillmode(struct svga_hwtnl *hwtnl, unsigned mode) 110{ 111 hwtnl->api_fillmode = mode; 112} 113 114 115void 116svga_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 */ 134void 135svga_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 */ 160boolean 161svga_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 190static enum pipe_error 191draw_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 329static SVGA3dSurfaceFormat 330xlate_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 345static enum pipe_error 346validate_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 411static enum pipe_error 412validate_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 */ 476static bool 477last_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 */ 497static boolean 498vertex_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/* 511 * Prepare the vertex buffers for a drawing command. 512 */ 513static enum pipe_error 514validate_vertex_buffers(struct svga_hwtnl *hwtnl) 515{ 516 struct svga_context *svga = hwtnl->svga; 517 struct pipe_resource *vbuffers[SVGA3D_INPUTREG_MAX]; 518 struct svga_winsys_surface *vbuffer_handles[SVGA3D_INPUTREG_MAX]; 519 const unsigned vbuf_count = hwtnl->cmd.vbuf_count; 520 int last_vbuf = -1; 521 unsigned i; 522 523 assert(svga_have_vgpu10(svga)); 524 525 /* Get handle for each referenced vertex buffer */ 526 for (i = 0; i < vbuf_count; i++) { 527 struct svga_buffer *sbuf = 528 svga_buffer(hwtnl->cmd.vbufs[i].buffer.resource); 529 530 if (sbuf) { 531 vbuffer_handles[i] = svga_buffer_handle(svga, &sbuf->b.b, 532 PIPE_BIND_VERTEX_BUFFER); 533 assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER); 534 if (vbuffer_handles[i] == NULL) 535 return PIPE_ERROR_OUT_OF_MEMORY; 536 vbuffers[i] = &sbuf->b.b; 537 last_vbuf = i; 538 } 539 else { 540 vbuffers[i] = NULL; 541 vbuffer_handles[i] = NULL; 542 } 543 } 544 545 for (; i < svga->state.hw_draw.num_vbuffers; i++) { 546 vbuffers[i] = NULL; 547 vbuffer_handles[i] = NULL; 548 } 549 550 /* setup vertex attribute input layout */ 551 if (svga->state.hw_draw.layout_id != hwtnl->cmd.vdecl_layout_id) { 552 enum pipe_error ret = 553 SVGA3D_vgpu10_SetInputLayout(svga->swc, 554 hwtnl->cmd.vdecl_layout_id); 555 if (ret != PIPE_OK) 556 return ret; 557 558 svga->state.hw_draw.layout_id = hwtnl->cmd.vdecl_layout_id; 559 } 560 561 /* setup vertex buffers */ 562 { 563 SVGA3dVertexBuffer vbuffer_attrs[PIPE_MAX_ATTRIBS]; 564 565 for (i = 0; i < vbuf_count; i++) { 566 vbuffer_attrs[i].stride = hwtnl->cmd.vbufs[i].stride; 567 vbuffer_attrs[i].offset = hwtnl->cmd.vbufs[i].buffer_offset; 568 vbuffer_attrs[i].sid = 0; 569 } 570 571 /* If any of the vertex buffer state has changed, issue 572 * the SetVertexBuffers command. Otherwise, we will just 573 * need to rebind the resources. 574 */ 575 if (vbuf_count != svga->state.hw_draw.num_vbuffers || 576 !vertex_buffers_equal(vbuf_count, 577 vbuffer_attrs, 578 vbuffers, 579 svga->state.hw_draw.vbuffer_attrs, 580 svga->state.hw_draw.vbuffers)) { 581 582 unsigned num_vbuffers; 583 584 /* get the max of the current bound vertex buffers count and 585 * the to-be-bound vertex buffers count, so as to unbind 586 * the unused vertex buffers. 587 */ 588 num_vbuffers = MAX2(vbuf_count, svga->state.hw_draw.num_vbuffers); 589 590 /* Zero-out the old buffers we want to unbind (the number of loop 591 * iterations here is typically very small, and often zero.) 592 */ 593 for (i = vbuf_count; i < num_vbuffers; i++) { 594 vbuffer_attrs[i].sid = 0; 595 vbuffer_attrs[i].stride = 0; 596 vbuffer_attrs[i].offset = 0; 597 vbuffer_handles[i] = NULL; 598 } 599 600 if (num_vbuffers > 0) { 601 SVGA3dVertexBuffer *pbufAttrs = vbuffer_attrs; 602 struct svga_winsys_surface **pbufHandles = vbuffer_handles; 603 unsigned numVBuf = 0; 604 605 /* Loop through the vertex buffer lists to only emit 606 * those vertex buffers that are not already in the 607 * corresponding entries in the device's vertex buffer list. 608 */ 609 for (i = 0; i < num_vbuffers; i++) { 610 boolean emit = 611 vertex_buffers_equal(1, 612 &vbuffer_attrs[i], 613 &vbuffers[i], 614 &svga->state.hw_draw.vbuffer_attrs[i], 615 &svga->state.hw_draw.vbuffers[i]); 616 617 if (!emit && i == num_vbuffers-1) { 618 /* Include the last vertex buffer in the next emit 619 * if it is different. 620 */ 621 emit = TRUE; 622 numVBuf++; 623 i++; 624 } 625 626 if (emit) { 627 /* numVBuf can only be 0 if the first vertex buffer 628 * is the same as the one in the device's list. 629 * In this case, there is nothing to send yet. 630 */ 631 if (numVBuf) { 632 enum pipe_error ret = 633 SVGA3D_vgpu10_SetVertexBuffers(svga->swc, 634 numVBuf, 635 i - numVBuf, 636 pbufAttrs, pbufHandles); 637 if (ret != PIPE_OK) 638 return ret; 639 } 640 pbufAttrs += (numVBuf + 1); 641 pbufHandles += (numVBuf + 1); 642 numVBuf = 0; 643 } 644 else 645 numVBuf++; 646 } 647 648 /* save the number of vertex buffers sent to the device, not 649 * including trailing unbound vertex buffers. 650 */ 651 svga->state.hw_draw.num_vbuffers = last_vbuf + 1; 652 memcpy(svga->state.hw_draw.vbuffer_attrs, vbuffer_attrs, 653 num_vbuffers * sizeof(vbuffer_attrs[0])); 654 for (i = 0; i < num_vbuffers; i++) { 655 pipe_resource_reference(&svga->state.hw_draw.vbuffers[i], 656 vbuffers[i]); 657 } 658 } 659 } 660 else { 661 /* Even though we can avoid emitting the redundant SetVertexBuffers 662 * command, we still need to reference the vertex buffers surfaces. 663 */ 664 for (i = 0; i < vbuf_count; i++) { 665 if (vbuffer_handles[i] && !last_command_was_draw(svga)) { 666 enum pipe_error ret = 667 svga->swc->resource_rebind(svga->swc, vbuffer_handles[i], 668 NULL, SVGA_RELOC_READ); 669 if (ret != PIPE_OK) 670 return ret; 671 } 672 } 673 } 674 } 675 676 return PIPE_OK; 677} 678 679 680/* 681 * Prepare the index buffer for a drawing command. 682 */ 683static enum pipe_error 684validate_index_buffer(struct svga_hwtnl *hwtnl, 685 const SVGA3dPrimitiveRange *range, 686 struct pipe_resource *ib) 687{ 688 struct svga_context *svga = hwtnl->svga; 689 struct svga_winsys_surface *ib_handle = 690 svga_buffer_handle(svga, ib, PIPE_BIND_INDEX_BUFFER); 691 692 if (!ib_handle) 693 return PIPE_ERROR_OUT_OF_MEMORY; 694 695 struct svga_buffer *sbuf = svga_buffer(ib); 696 assert(sbuf->key.flags & SVGA3D_SURFACE_BIND_INDEX_BUFFER); 697 (void) sbuf; /* silence unused var warning */ 698 699 SVGA3dSurfaceFormat indexFormat = xlate_index_format(range->indexWidth); 700 701 if (ib != svga->state.hw_draw.ib || 702 indexFormat != svga->state.hw_draw.ib_format || 703 range->indexArray.offset != svga->state.hw_draw.ib_offset) { 704 705 assert(indexFormat != SVGA3D_FORMAT_INVALID); 706 enum pipe_error ret = 707 SVGA3D_vgpu10_SetIndexBuffer(svga->swc, ib_handle, 708 indexFormat, 709 range->indexArray.offset); 710 if (ret != PIPE_OK) 711 return ret; 712 713 pipe_resource_reference(&svga->state.hw_draw.ib, ib); 714 svga->state.hw_draw.ib_format = indexFormat; 715 svga->state.hw_draw.ib_offset = range->indexArray.offset; 716 } 717 else { 718 /* Even though we can avoid emitting the redundant SetIndexBuffer 719 * command, we still need to reference the index buffer surface. 720 */ 721 if (!last_command_was_draw(svga)) { 722 enum pipe_error ret = svga->swc->resource_rebind(svga->swc, 723 ib_handle, 724 NULL, 725 SVGA_RELOC_READ); 726 if (ret != PIPE_OK) 727 return ret; 728 } 729 } 730 731 return PIPE_OK; 732} 733 734 735static enum pipe_error 736draw_vgpu10(struct svga_hwtnl *hwtnl, 737 const SVGA3dPrimitiveRange *range, 738 unsigned vcount, 739 struct pipe_resource *ib, 740 unsigned start_instance, unsigned instance_count) 741{ 742 struct svga_context *svga = hwtnl->svga; 743 enum pipe_error ret; 744 745 assert(svga_have_vgpu10(svga)); 746 assert(hwtnl->cmd.prim_count == 0); 747 748 /* We need to reemit all the current resource bindings along with the Draw 749 * command to be sure that the referenced resources are available for the 750 * Draw command, just in case the surfaces associated with the resources 751 * are paged out. 752 */ 753 if (svga->rebind.val) { 754 ret = svga_rebind_framebuffer_bindings(svga); 755 if (ret != PIPE_OK) 756 return ret; 757 758 ret = svga_rebind_shaders(svga); 759 if (ret != PIPE_OK) 760 return ret; 761 762 /* Rebind stream output targets */ 763 ret = svga_rebind_stream_output_targets(svga); 764 if (ret != PIPE_OK) 765 return ret; 766 767 /* No need to explicitly rebind index buffer and vertex buffers here. 768 * Even if the same index buffer or vertex buffers are referenced for this 769 * draw and we skip emitting the redundant set command, we will still 770 * reference the associated resources. 771 */ 772 } 773 774 ret = validate_sampler_resources(svga); 775 if (ret != PIPE_OK) 776 return ret; 777 778 ret = validate_constant_buffers(svga); 779 if (ret != PIPE_OK) 780 return ret; 781 782 ret = validate_vertex_buffers(hwtnl); 783 if (ret != PIPE_OK) 784 return ret; 785 786 if (ib) { 787 ret = validate_index_buffer(hwtnl, range, ib); 788 if (ret != PIPE_OK) 789 return ret; 790 } 791 792 /* Set primitive type (line, tri, etc) */ 793 if (svga->state.hw_draw.topology != range->primType) { 794 ret = SVGA3D_vgpu10_SetTopology(svga->swc, range->primType); 795 if (ret != PIPE_OK) 796 return ret; 797 798 svga->state.hw_draw.topology = range->primType; 799 } 800 801 if (ib) { 802 /* indexed drawing */ 803 if (instance_count > 1) { 804 ret = SVGA3D_vgpu10_DrawIndexedInstanced(svga->swc, 805 vcount, 806 instance_count, 807 0, /* startIndexLocation */ 808 range->indexBias, 809 start_instance); 810 if (ret != PIPE_OK) 811 return ret; 812 } 813 else { 814 /* non-instanced drawing */ 815 ret = SVGA3D_vgpu10_DrawIndexed(svga->swc, 816 vcount, 817 0, /* startIndexLocation */ 818 range->indexBias); 819 if (ret != PIPE_OK) 820 return ret; 821 } 822 } 823 else { 824 /* non-indexed drawing */ 825 if (svga->state.hw_draw.ib_format != SVGA3D_FORMAT_INVALID || 826 svga->state.hw_draw.ib != NULL) { 827 /* Unbind previously bound index buffer */ 828 ret = SVGA3D_vgpu10_SetIndexBuffer(svga->swc, NULL, 829 SVGA3D_FORMAT_INVALID, 0); 830 if (ret != PIPE_OK) 831 return ret; 832 pipe_resource_reference(&svga->state.hw_draw.ib, NULL); 833 svga->state.hw_draw.ib_format = SVGA3D_FORMAT_INVALID; 834 } 835 836 assert(svga->state.hw_draw.ib == NULL); 837 838 if (instance_count > 1) { 839 ret = SVGA3D_vgpu10_DrawInstanced(svga->swc, 840 vcount, 841 instance_count, 842 range->indexBias, 843 start_instance); 844 if (ret != PIPE_OK) 845 return ret; 846 } 847 else { 848 /* non-instanced */ 849 ret = SVGA3D_vgpu10_Draw(svga->swc, 850 vcount, 851 range->indexBias); 852 if (ret != PIPE_OK) 853 return ret; 854 } 855 } 856 857 hwtnl->cmd.prim_count = 0; 858 859 return PIPE_OK; 860} 861 862 863 864/** 865 * Emit any pending drawing commands to the command buffer. 866 * When we receive VGPU9 drawing commands we accumulate them and don't 867 * immediately emit them into the command buffer. 868 * This function needs to be called before we change state that could 869 * effect those pending draws. 870 */ 871enum pipe_error 872svga_hwtnl_flush(struct svga_hwtnl *hwtnl) 873{ 874 enum pipe_error ret = PIPE_OK; 875 876 SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLFLUSH); 877 878 if (!svga_have_vgpu10(hwtnl->svga) && hwtnl->cmd.prim_count) { 879 /* we only queue up primitive for VGPU9 */ 880 ret = draw_vgpu9(hwtnl); 881 } 882 883 SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws); 884 return ret; 885} 886 887 888void 889svga_hwtnl_set_index_bias(struct svga_hwtnl *hwtnl, int index_bias) 890{ 891 hwtnl->index_bias = index_bias; 892} 893 894 895 896/*********************************************************************** 897 * Internal functions: 898 */ 899 900/** 901 * For debugging only. 902 */ 903static void 904check_draw_params(struct svga_hwtnl *hwtnl, 905 const SVGA3dPrimitiveRange *range, 906 unsigned min_index, unsigned max_index, 907 struct pipe_resource *ib) 908{ 909 unsigned i; 910 911 assert(!svga_have_vgpu10(hwtnl->svga)); 912 913 for (i = 0; i < hwtnl->cmd.vdecl_count; i++) { 914 unsigned j = hwtnl->cmd.vdecl_buffer_index[i]; 915 const struct pipe_vertex_buffer *vb = &hwtnl->cmd.vbufs[j]; 916 unsigned size = vb->buffer.resource ? vb->buffer.resource->width0 : 0; 917 unsigned offset = hwtnl->cmd.vdecl[i].array.offset; 918 unsigned stride = hwtnl->cmd.vdecl[i].array.stride; 919 int index_bias = (int) range->indexBias + hwtnl->index_bias; 920 unsigned width; 921 922 if (size == 0) 923 continue; 924 925 assert(vb); 926 assert(size); 927 assert(offset < size); 928 assert(min_index <= max_index); 929 (void) width; 930 (void) stride; 931 (void) offset; 932 (void) size; 933 934 switch (hwtnl->cmd.vdecl[i].identity.type) { 935 case SVGA3D_DECLTYPE_FLOAT1: 936 width = 4; 937 break; 938 case SVGA3D_DECLTYPE_FLOAT2: 939 width = 4 * 2; 940 break; 941 case SVGA3D_DECLTYPE_FLOAT3: 942 width = 4 * 3; 943 break; 944 case SVGA3D_DECLTYPE_FLOAT4: 945 width = 4 * 4; 946 break; 947 case SVGA3D_DECLTYPE_D3DCOLOR: 948 width = 4; 949 break; 950 case SVGA3D_DECLTYPE_UBYTE4: 951 width = 1 * 4; 952 break; 953 case SVGA3D_DECLTYPE_SHORT2: 954 width = 2 * 2; 955 break; 956 case SVGA3D_DECLTYPE_SHORT4: 957 width = 2 * 4; 958 break; 959 case SVGA3D_DECLTYPE_UBYTE4N: 960 width = 1 * 4; 961 break; 962 case SVGA3D_DECLTYPE_SHORT2N: 963 width = 2 * 2; 964 break; 965 case SVGA3D_DECLTYPE_SHORT4N: 966 width = 2 * 4; 967 break; 968 case SVGA3D_DECLTYPE_USHORT2N: 969 width = 2 * 2; 970 break; 971 case SVGA3D_DECLTYPE_USHORT4N: 972 width = 2 * 4; 973 break; 974 case SVGA3D_DECLTYPE_UDEC3: 975 width = 4; 976 break; 977 case SVGA3D_DECLTYPE_DEC3N: 978 width = 4; 979 break; 980 case SVGA3D_DECLTYPE_FLOAT16_2: 981 width = 2 * 2; 982 break; 983 case SVGA3D_DECLTYPE_FLOAT16_4: 984 width = 2 * 4; 985 break; 986 default: 987 assert(0); 988 width = 0; 989 break; 990 } 991 992 if (index_bias >= 0) { 993 assert(offset + index_bias * stride + width <= size); 994 } 995 996 /* 997 * min_index/max_index are merely conservative guesses, so we can't 998 * make buffer overflow detection based on their values. 999 */ 1000 } 1001 1002 assert(range->indexWidth == range->indexArray.stride); 1003 1004 if (ib) { 1005 MAYBE_UNUSED unsigned size = ib->width0; 1006 MAYBE_UNUSED unsigned offset = range->indexArray.offset; 1007 MAYBE_UNUSED unsigned stride = range->indexArray.stride; 1008 MAYBE_UNUSED unsigned count; 1009 1010 assert(size); 1011 assert(offset < size); 1012 assert(stride); 1013 1014 switch (range->primType) { 1015 case SVGA3D_PRIMITIVE_POINTLIST: 1016 count = range->primitiveCount; 1017 break; 1018 case SVGA3D_PRIMITIVE_LINELIST: 1019 count = range->primitiveCount * 2; 1020 break; 1021 case SVGA3D_PRIMITIVE_LINESTRIP: 1022 count = range->primitiveCount + 1; 1023 break; 1024 case SVGA3D_PRIMITIVE_TRIANGLELIST: 1025 count = range->primitiveCount * 3; 1026 break; 1027 case SVGA3D_PRIMITIVE_TRIANGLESTRIP: 1028 count = range->primitiveCount + 2; 1029 break; 1030 case SVGA3D_PRIMITIVE_TRIANGLEFAN: 1031 count = range->primitiveCount + 2; 1032 break; 1033 default: 1034 assert(0); 1035 count = 0; 1036 break; 1037 } 1038 1039 assert(offset + count * stride <= size); 1040 } 1041} 1042 1043 1044/** 1045 * All drawing filters down into this function, either directly 1046 * on the hardware path or after doing software vertex processing. 1047 */ 1048enum pipe_error 1049svga_hwtnl_prim(struct svga_hwtnl *hwtnl, 1050 const SVGA3dPrimitiveRange * range, 1051 unsigned vcount, 1052 unsigned min_index, 1053 unsigned max_index, struct pipe_resource *ib, 1054 unsigned start_instance, unsigned instance_count) 1055{ 1056 enum pipe_error ret = PIPE_OK; 1057 1058 SVGA_STATS_TIME_PUSH(svga_sws(hwtnl->svga), SVGA_STATS_TIME_HWTNLPRIM); 1059 1060 if (svga_have_vgpu10(hwtnl->svga)) { 1061 /* draw immediately */ 1062 ret = draw_vgpu10(hwtnl, range, vcount, ib, 1063 start_instance, instance_count); 1064 if (ret != PIPE_OK) { 1065 svga_context_flush(hwtnl->svga, NULL); 1066 ret = draw_vgpu10(hwtnl, range, vcount, ib, 1067 start_instance, instance_count); 1068 assert(ret == PIPE_OK); 1069 } 1070 } 1071 else { 1072 /* batch up drawing commands */ 1073#ifdef DEBUG 1074 check_draw_params(hwtnl, range, min_index, max_index, ib); 1075 assert(start_instance == 0); 1076 assert(instance_count <= 1); 1077#else 1078 (void) check_draw_params; 1079#endif 1080 1081 if (hwtnl->cmd.prim_count + 1 >= QSZ) { 1082 ret = svga_hwtnl_flush(hwtnl); 1083 if (ret != PIPE_OK) 1084 goto done; 1085 } 1086 1087 /* min/max indices are relative to bias */ 1088 hwtnl->cmd.min_index[hwtnl->cmd.prim_count] = min_index; 1089 hwtnl->cmd.max_index[hwtnl->cmd.prim_count] = max_index; 1090 1091 hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range; 1092 hwtnl->cmd.prim[hwtnl->cmd.prim_count].indexBias += hwtnl->index_bias; 1093 1094 pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib); 1095 hwtnl->cmd.prim_count++; 1096 } 1097 1098done: 1099 SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws); 1100 return ret; 1101} 1102