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 /** 27 * svga_cmd.c -- 28 * 29 * Command construction utility for the SVGA3D protocol used by 30 * the VMware SVGA device, based on the svgautil library. 31 */ 32 33 #include "svga_winsys.h" 34 #include "svga_resource_buffer.h" 35 #include "svga_resource_texture.h" 36 #include "svga_surface.h" 37 #include "svga_cmd.h" 38 39 /* 40 *---------------------------------------------------------------------- 41 * 42 * surface_to_surfaceid -- 43 * 44 * Utility function for surface ids. 45 * Can handle null surface. Does a surface_reallocation so you need 46 * to have allocated the fifo space before converting. 47 * 48 * 49 * param flags mask of SVGA_RELOC_READ / _WRITE 50 * 51 * Results: 52 * id is filled out. 53 * 54 * Side effects: 55 * One surface relocation is performed for texture handle. 56 * 57 *---------------------------------------------------------------------- 58 */ 59 60 static inline void 61 surface_to_surfaceid(struct svga_winsys_context *swc, // IN 62 struct pipe_surface *surface, // IN 63 SVGA3dSurfaceImageId *id, // OUT 64 unsigned flags) // IN 65 { 66 if (surface) { 67 struct svga_surface *s = svga_surface(surface); 68 swc->surface_relocation(swc, &id->sid, NULL, s->handle, flags); 69 id->face = s->real_layer; /* faces have the same order */ 70 id->mipmap = s->real_level; 71 } 72 else { 73 swc->surface_relocation(swc, &id->sid, NULL, NULL, flags); 74 id->face = 0; 75 id->mipmap = 0; 76 } 77 } 78 79 80 /* 81 *---------------------------------------------------------------------- 82 * 83 * SVGA3D_FIFOReserve -- 84 * 85 * Reserve space for an SVGA3D FIFO command. 86 * 87 * The 2D SVGA commands have been around for a while, so they 88 * have a rather asymmetric structure. The SVGA3D protocol is 89 * more uniform: each command begins with a header containing the 90 * command number and the full size. 91 * 92 * This is a convenience wrapper around SVGA_FIFOReserve. We 93 * reserve space for the whole command, and write the header. 94 * 95 * This function must be paired with SVGA_FIFOCommitAll(). 96 * 97 * Results: 98 * Returns a pointer to the space reserved for command-specific 99 * data. It must be 'cmdSize' bytes long. 100 * 101 * Side effects: 102 * Begins a FIFO reservation. 103 * 104 *---------------------------------------------------------------------- 105 */ 106 107 void * 108 SVGA3D_FIFOReserve(struct svga_winsys_context *swc, 109 uint32 cmd, // IN 110 uint32 cmdSize, // IN 111 uint32 nr_relocs) // IN 112 { 113 SVGA3dCmdHeader *header; 114 115 header = swc->reserve(swc, sizeof *header + cmdSize, nr_relocs); 116 if (!header) 117 return NULL; 118 119 header->id = cmd; 120 header->size = cmdSize; 121 122 swc->last_command = cmd; 123 124 return &header[1]; 125 } 126 127 128 void 129 SVGA_FIFOCommitAll(struct svga_winsys_context *swc) 130 { 131 swc->commit(swc); 132 } 133 134 135 /* 136 *---------------------------------------------------------------------- 137 * 138 * SVGA3D_DefineContext -- 139 * 140 * Create a new context, to be referred to with the provided ID. 141 * 142 * Context objects encapsulate all render state, and shader 143 * objects are per-context. 144 * 145 * Surfaces are not per-context. The same surface can be shared 146 * between multiple contexts, and surface operations can occur 147 * without a context. 148 * 149 * If the provided context ID already existed, it is redefined. 150 * 151 * Context IDs are arbitrary small non-negative integers, 152 * global to the entire SVGA device. 153 * 154 * Results: 155 * None. 156 * 157 * Side effects: 158 * None. 159 * 160 *---------------------------------------------------------------------- 161 */ 162 163 enum pipe_error 164 SVGA3D_DefineContext(struct svga_winsys_context *swc) // IN 165 { 166 SVGA3dCmdDefineContext *cmd; 167 168 cmd = SVGA3D_FIFOReserve(swc, 169 SVGA_3D_CMD_CONTEXT_DEFINE, sizeof *cmd, 0); 170 if (!cmd) 171 return PIPE_ERROR_OUT_OF_MEMORY; 172 173 cmd->cid = swc->cid; 174 175 swc->commit(swc); 176 177 return PIPE_OK; 178 } 179 180 181 /* 182 *---------------------------------------------------------------------- 183 * 184 * SVGA3D_DestroyContext -- 185 * 186 * Delete a context created with SVGA3D_DefineContext. 187 * 188 * Results: 189 * None. 190 * 191 * Side effects: 192 * None. 193 * 194 *---------------------------------------------------------------------- 195 */ 196 197 enum pipe_error 198 SVGA3D_DestroyContext(struct svga_winsys_context *swc) // IN 199 { 200 SVGA3dCmdDestroyContext *cmd; 201 202 cmd = SVGA3D_FIFOReserve(swc, 203 SVGA_3D_CMD_CONTEXT_DESTROY, sizeof *cmd, 0); 204 if (!cmd) 205 return PIPE_ERROR_OUT_OF_MEMORY; 206 207 cmd->cid = swc->cid; 208 209 swc->commit(swc); 210 211 return PIPE_OK; 212 } 213 214 215 /* 216 *---------------------------------------------------------------------- 217 * 218 * SVGA3D_BeginDefineSurface -- 219 * 220 * Begin a SURFACE_DEFINE command. This reserves space for it in 221 * the FIFO, and returns pointers to the command's faces and 222 * mipsizes arrays. 223 * 224 * This function must be paired with SVGA_FIFOCommitAll(). 225 * The faces and mipSizes arrays are initialized to zero. 226 * 227 * This creates a "surface" object in the SVGA3D device, 228 * with the provided surface ID (sid). Surfaces are generic 229 * containers for host VRAM objects like textures, vertex 230 * buffers, and depth/stencil buffers. 231 * 232 * Surfaces are hierarchical: 233 * 234 * - Surface may have multiple faces (for cube maps) 235 * 236 * - Each face has a list of mipmap levels 237 * 238 * - Each mipmap image may have multiple volume 239 * slices, if the image is three dimensional. 240 * 241 * - Each slice is a 2D array of 'blocks' 242 * 243 * - Each block may be one or more pixels. 244 * (Usually 1, more for DXT or YUV formats.) 245 * 246 * Surfaces are generic host VRAM objects. The SVGA3D device 247 * may optimize surfaces according to the format they were 248 * created with, but this format does not limit the ways in 249 * which the surface may be used. For example, a depth surface 250 * can be used as a texture, or a floating point image may 251 * be used as a vertex buffer. Some surface usages may be 252 * lower performance, due to software emulation, but any 253 * usage should work with any surface. 254 * 255 * If 'sid' is already defined, the old surface is deleted 256 * and this new surface replaces it. 257 * 258 * Surface IDs are arbitrary small non-negative integers, 259 * global to the entire SVGA device. 260 * 261 * Results: 262 * Returns pointers to arrays allocated in the FIFO for 'faces' 263 * and 'mipSizes'. 264 * 265 * Side effects: 266 * Begins a FIFO reservation. 267 * 268 *---------------------------------------------------------------------- 269 */ 270 271 enum pipe_error 272 SVGA3D_BeginDefineSurface(struct svga_winsys_context *swc, 273 struct svga_winsys_surface *sid, // IN 274 SVGA3dSurfaceFlags flags, // IN 275 SVGA3dSurfaceFormat format, // IN 276 SVGA3dSurfaceFace **faces, // OUT 277 SVGA3dSize **mipSizes, // OUT 278 uint32 numMipSizes) // IN 279 { 280 SVGA3dCmdDefineSurface *cmd; 281 282 cmd = SVGA3D_FIFOReserve(swc, 283 SVGA_3D_CMD_SURFACE_DEFINE, sizeof *cmd + 284 sizeof **mipSizes * numMipSizes, 1); 285 if (!cmd) 286 return PIPE_ERROR_OUT_OF_MEMORY; 287 288 swc->surface_relocation(swc, &cmd->sid, NULL, sid, 289 SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL); 290 cmd->surfaceFlags = flags; 291 cmd->format = format; 292 293 *faces = &cmd->face[0]; 294 *mipSizes = (SVGA3dSize*) &cmd[1]; 295 296 memset(*faces, 0, sizeof **faces * SVGA3D_MAX_SURFACE_FACES); 297 memset(*mipSizes, 0, sizeof **mipSizes * numMipSizes); 298 299 return PIPE_OK; 300 } 301 302 303 /* 304 *---------------------------------------------------------------------- 305 * 306 * SVGA3D_DefineSurface2D -- 307 * 308 * This is a simplified version of SVGA3D_BeginDefineSurface(), 309 * which does not support cube maps, mipmaps, or volume textures. 310 * 311 * Results: 312 * None. 313 * 314 * Side effects: 315 * None. 316 * 317 *---------------------------------------------------------------------- 318 */ 319 320 enum pipe_error 321 SVGA3D_DefineSurface2D(struct svga_winsys_context *swc, // IN 322 struct svga_winsys_surface *sid, // IN 323 uint32 width, // IN 324 uint32 height, // IN 325 SVGA3dSurfaceFormat format) // IN 326 { 327 SVGA3dSize *mipSizes; 328 SVGA3dSurfaceFace *faces; 329 enum pipe_error ret; 330 331 ret = SVGA3D_BeginDefineSurface(swc, 332 sid, 0, format, &faces, &mipSizes, 1); 333 if (ret != PIPE_OK) 334 return ret; 335 336 faces[0].numMipLevels = 1; 337 338 mipSizes[0].width = width; 339 mipSizes[0].height = height; 340 mipSizes[0].depth = 1; 341 342 swc->commit(swc); 343 344 return PIPE_OK; 345 } 346 347 348 /* 349 *---------------------------------------------------------------------- 350 * 351 * SVGA3D_DestroySurface -- 352 * 353 * Release the host VRAM encapsulated by a particular surface ID. 354 * 355 * Results: 356 * None. 357 * 358 * Side effects: 359 * None. 360 * 361 *---------------------------------------------------------------------- 362 */ 363 364 enum pipe_error 365 SVGA3D_DestroySurface(struct svga_winsys_context *swc, 366 struct svga_winsys_surface *sid) // IN 367 { 368 SVGA3dCmdDestroySurface *cmd; 369 370 cmd = SVGA3D_FIFOReserve(swc, 371 SVGA_3D_CMD_SURFACE_DESTROY, sizeof *cmd, 1); 372 if (!cmd) 373 return PIPE_ERROR_OUT_OF_MEMORY; 374 375 swc->surface_relocation(swc, &cmd->sid, NULL, sid, 376 SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL); 377 swc->commit(swc); 378 379 return PIPE_OK; 380 } 381 382 383 /* 384 *---------------------------------------------------------------------- 385 * 386 * SVGA3D_SurfaceDMA-- 387 * 388 * Emit a SURFACE_DMA command. 389 * 390 * When the SVGA3D device asynchronously processes this FIFO 391 * command, a DMA operation is performed between host VRAM and 392 * a generic SVGAGuestPtr. The guest pointer may refer to guest 393 * VRAM (provided by the SVGA PCI device) or to guest system 394 * memory that has been set up as a Guest Memory Region (GMR) 395 * by the SVGA device. 396 * 397 * The guest's DMA buffer must remain valid (not freed, paged out, 398 * or overwritten) until the host has finished processing this 399 * command. The guest can determine that the host has finished 400 * by using the SVGA device's FIFO Fence mechanism. 401 * 402 * The guest's image buffer can be an arbitrary size and shape. 403 * Guest image data is interpreted according to the SVGA3D surface 404 * format specified when the surface was defined. 405 * 406 * The caller may optionally define the guest image's pitch. 407 * guestImage->pitch can either be zero (assume image is tightly 408 * packed) or it must be the number of bytes between vertically 409 * adjacent image blocks. 410 * 411 * The provided copybox list specifies which regions of the source 412 * image are to be copied, and where they appear on the destination. 413 * 414 * NOTE: srcx/srcy are always on the guest image and x/y are 415 * always on the host image, regardless of the actual transfer 416 * direction! 417 * 418 * For efficiency, the SVGA3D device is free to copy more data 419 * than specified. For example, it may round copy boxes outwards 420 * such that they lie on particular alignment boundaries. 421 * 422 *---------------------------------------------------------------------- 423 */ 424 425 enum pipe_error 426 SVGA3D_SurfaceDMA(struct svga_winsys_context *swc, 427 struct svga_transfer *st, // IN 428 SVGA3dTransferType transfer, // IN 429 const SVGA3dCopyBox *boxes, // IN 430 uint32 numBoxes, // IN 431 SVGA3dSurfaceDMAFlags flags) // IN 432 { 433 struct svga_texture *texture = svga_texture(st->base.resource); 434 SVGA3dCmdSurfaceDMA *cmd; 435 SVGA3dCmdSurfaceDMASuffix *pSuffix; 436 uint32 boxesSize = sizeof *boxes * numBoxes; 437 unsigned region_flags; 438 unsigned surface_flags; 439 440 if (transfer == SVGA3D_WRITE_HOST_VRAM) { 441 region_flags = SVGA_RELOC_READ; 442 surface_flags = SVGA_RELOC_WRITE; 443 } 444 else if (transfer == SVGA3D_READ_HOST_VRAM) { 445 region_flags = SVGA_RELOC_WRITE; 446 surface_flags = SVGA_RELOC_READ; 447 } 448 else { 449 assert(0); 450 return PIPE_ERROR_BAD_INPUT; 451 } 452 453 cmd = SVGA3D_FIFOReserve(swc, 454 SVGA_3D_CMD_SURFACE_DMA, 455 sizeof *cmd + boxesSize + sizeof *pSuffix, 456 2); 457 if (!cmd) 458 return PIPE_ERROR_OUT_OF_MEMORY; 459 460 swc->region_relocation(swc, &cmd->guest.ptr, st->hwbuf, 0, region_flags); 461 cmd->guest.pitch = st->base.stride; 462 463 swc->surface_relocation(swc, &cmd->host.sid, NULL, 464 texture->handle, surface_flags); 465 cmd->host.face = st->slice; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */ 466 cmd->host.mipmap = st->base.level; 467 468 cmd->transfer = transfer; 469 470 memcpy(&cmd[1], boxes, boxesSize); 471 472 pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + boxesSize); 473 pSuffix->suffixSize = sizeof *pSuffix; 474 pSuffix->maximumOffset = st->hw_nblocksy*st->base.stride; 475 pSuffix->flags = flags; 476 477 swc->commit(swc); 478 swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH; 479 480 return PIPE_OK; 481 } 482 483 484 enum pipe_error 485 SVGA3D_BufferDMA(struct svga_winsys_context *swc, 486 struct svga_winsys_buffer *guest, 487 struct svga_winsys_surface *host, 488 SVGA3dTransferType transfer, // IN 489 uint32 size, // IN 490 uint32 guest_offset, // IN 491 uint32 host_offset, // IN 492 SVGA3dSurfaceDMAFlags flags) // IN 493 { 494 SVGA3dCmdSurfaceDMA *cmd; 495 SVGA3dCopyBox *box; 496 SVGA3dCmdSurfaceDMASuffix *pSuffix; 497 unsigned region_flags; 498 unsigned surface_flags; 499 500 assert(!swc->have_gb_objects); 501 502 if (transfer == SVGA3D_WRITE_HOST_VRAM) { 503 region_flags = SVGA_RELOC_READ; 504 surface_flags = SVGA_RELOC_WRITE; 505 } 506 else if (transfer == SVGA3D_READ_HOST_VRAM) { 507 region_flags = SVGA_RELOC_WRITE; 508 surface_flags = SVGA_RELOC_READ; 509 } 510 else { 511 assert(0); 512 return PIPE_ERROR_BAD_INPUT; 513 } 514 515 cmd = SVGA3D_FIFOReserve(swc, 516 SVGA_3D_CMD_SURFACE_DMA, 517 sizeof *cmd + sizeof *box + sizeof *pSuffix, 518 2); 519 if (!cmd) 520 return PIPE_ERROR_OUT_OF_MEMORY; 521 522 swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags); 523 cmd->guest.pitch = 0; 524 525 swc->surface_relocation(swc, &cmd->host.sid, 526 NULL, host, surface_flags); 527 cmd->host.face = 0; 528 cmd->host.mipmap = 0; 529 530 cmd->transfer = transfer; 531 532 box = (SVGA3dCopyBox *)&cmd[1]; 533 box->x = host_offset; 534 box->y = 0; 535 box->z = 0; 536 box->w = size; 537 box->h = 1; 538 box->d = 1; 539 box->srcx = guest_offset; 540 box->srcy = 0; 541 box->srcz = 0; 542 543 pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box); 544 pSuffix->suffixSize = sizeof *pSuffix; 545 pSuffix->maximumOffset = guest_offset + size; 546 pSuffix->flags = flags; 547 548 swc->commit(swc); 549 swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH; 550 551 return PIPE_OK; 552 } 553 554 555 /* 556 *---------------------------------------------------------------------- 557 * 558 * SVGA3D_SetRenderTarget -- 559 * 560 * Bind a surface object to a particular render target attachment 561 * point on the current context. Render target attachment points 562 * exist for color buffers, a depth buffer, and a stencil buffer. 563 * 564 * The SVGA3D device is quite lenient about the types of surfaces 565 * that may be used as render targets. The color buffers must 566 * all be the same size, but the depth and stencil buffers do not 567 * have to be the same size as the color buffer. All attachments 568 * are optional. 569 * 570 * Some combinations of render target formats may require software 571 * emulation, depending on the capabilities of the host graphics 572 * API and graphics hardware. 573 * 574 * Results: 575 * None. 576 * 577 * Side effects: 578 * None. 579 * 580 *---------------------------------------------------------------------- 581 */ 582 583 enum pipe_error 584 SVGA3D_SetRenderTarget(struct svga_winsys_context *swc, 585 SVGA3dRenderTargetType type, // IN 586 struct pipe_surface *surface) // IN 587 { 588 SVGA3dCmdSetRenderTarget *cmd; 589 590 cmd = SVGA3D_FIFOReserve(swc, 591 SVGA_3D_CMD_SETRENDERTARGET, sizeof *cmd, 1); 592 if (!cmd) 593 return PIPE_ERROR_OUT_OF_MEMORY; 594 595 cmd->cid = swc->cid; 596 cmd->type = type; 597 surface_to_surfaceid(swc, surface, &cmd->target, SVGA_RELOC_WRITE); 598 swc->commit(swc); 599 600 return PIPE_OK; 601 } 602 603 604 /* 605 *---------------------------------------------------------------------- 606 * 607 * SVGA3D_DefineShader -- 608 * 609 * Upload the bytecode for a new shader. The bytecode is "SVGA3D 610 * format", which is theoretically a binary-compatible superset 611 * of Microsoft's DirectX shader bytecode. In practice, the 612 * SVGA3D bytecode doesn't yet have any extensions to DirectX's 613 * bytecode format. 614 * 615 * The SVGA3D device supports shader models 1.1 through 2.0. 616 * 617 * The caller chooses a shader ID (small positive integer) by 618 * which this shader will be identified in future commands. This 619 * ID is in a namespace which is per-context and per-shader-type. 620 * 621 * 'bytecodeLen' is specified in bytes. It must be a multiple of 4. 622 * 623 * Results: 624 * None. 625 * 626 * Side effects: 627 * None. 628 * 629 *---------------------------------------------------------------------- 630 */ 631 632 enum pipe_error 633 SVGA3D_DefineShader(struct svga_winsys_context *swc, 634 uint32 shid, // IN 635 SVGA3dShaderType type, // IN 636 const uint32 *bytecode, // IN 637 uint32 bytecodeLen) // IN 638 { 639 SVGA3dCmdDefineShader *cmd; 640 641 assert(bytecodeLen % 4 == 0); 642 643 cmd = SVGA3D_FIFOReserve(swc, 644 SVGA_3D_CMD_SHADER_DEFINE, sizeof *cmd + bytecodeLen, 645 0); 646 if (!cmd) 647 return PIPE_ERROR_OUT_OF_MEMORY; 648 649 cmd->cid = swc->cid; 650 cmd->shid = shid; 651 cmd->type = type; 652 memcpy(&cmd[1], bytecode, bytecodeLen); 653 swc->commit(swc); 654 655 return PIPE_OK; 656 } 657 658 659 /* 660 *---------------------------------------------------------------------- 661 * 662 * SVGA3D_DestroyShader -- 663 * 664 * Delete a shader that was created by SVGA3D_DefineShader. If 665 * the shader was the current vertex or pixel shader for its 666 * context, rendering results are undefined until a new shader is 667 * bound. 668 * 669 * Results: 670 * None. 671 * 672 * Side effects: 673 * None. 674 * 675 *---------------------------------------------------------------------- 676 */ 677 678 enum pipe_error 679 SVGA3D_DestroyShader(struct svga_winsys_context *swc, 680 uint32 shid, // IN 681 SVGA3dShaderType type) // IN 682 { 683 SVGA3dCmdDestroyShader *cmd; 684 685 cmd = SVGA3D_FIFOReserve(swc, 686 SVGA_3D_CMD_SHADER_DESTROY, sizeof *cmd, 687 0); 688 if (!cmd) 689 return PIPE_ERROR_OUT_OF_MEMORY; 690 691 cmd->cid = swc->cid; 692 cmd->shid = shid; 693 cmd->type = type; 694 swc->commit(swc); 695 696 return PIPE_OK; 697 } 698 699 700 /* 701 *---------------------------------------------------------------------- 702 * 703 * SVGA3D_SetShaderConst -- 704 * 705 * Set the value of a shader constant. 706 * 707 * Shader constants are analogous to uniform variables in GLSL, 708 * except that they belong to the render context rather than to 709 * an individual shader. 710 * 711 * Constants may have one of three types: A 4-vector of floats, 712 * a 4-vector of integers, or a single boolean flag. 713 * 714 * Results: 715 * None. 716 * 717 * Side effects: 718 * None. 719 * 720 *---------------------------------------------------------------------- 721 */ 722 723 enum pipe_error 724 SVGA3D_SetShaderConst(struct svga_winsys_context *swc, 725 uint32 reg, // IN 726 SVGA3dShaderType type, // IN 727 SVGA3dShaderConstType ctype, // IN 728 const void *value) // IN 729 { 730 SVGA3dCmdSetShaderConst *cmd; 731 732 cmd = SVGA3D_FIFOReserve(swc, 733 SVGA_3D_CMD_SET_SHADER_CONST, sizeof *cmd, 734 0); 735 if (!cmd) 736 return PIPE_ERROR_OUT_OF_MEMORY; 737 738 cmd->cid = swc->cid; 739 cmd->reg = reg; 740 cmd->type = type; 741 cmd->ctype = ctype; 742 743 switch (ctype) { 744 745 case SVGA3D_CONST_TYPE_FLOAT: 746 case SVGA3D_CONST_TYPE_INT: 747 memcpy(&cmd->values, value, sizeof cmd->values); 748 break; 749 750 case SVGA3D_CONST_TYPE_BOOL: 751 memset(&cmd->values, 0, sizeof cmd->values); 752 cmd->values[0] = *(uint32*)value; 753 break; 754 755 default: 756 assert(0); 757 break; 758 759 } 760 swc->commit(swc); 761 762 return PIPE_OK; 763 } 764 765 766 /* 767 *---------------------------------------------------------------------- 768 * 769 * SVGA3D_SetShaderConsts -- 770 * 771 * Set the value of successive shader constants. 772 * 773 * Shader constants are analogous to uniform variables in GLSL, 774 * except that they belong to the render context rather than to 775 * an individual shader. 776 * 777 * Constants may have one of three types: A 4-vector of floats, 778 * a 4-vector of integers, or a single boolean flag. 779 * 780 * Results: 781 * None. 782 * 783 * Side effects: 784 * None. 785 * 786 *---------------------------------------------------------------------- 787 */ 788 789 enum pipe_error 790 SVGA3D_SetShaderConsts(struct svga_winsys_context *swc, 791 uint32 reg, // IN 792 uint32 numRegs, // IN 793 SVGA3dShaderType type, // IN 794 SVGA3dShaderConstType ctype, // IN 795 const void *values) // IN 796 { 797 SVGA3dCmdSetShaderConst *cmd; 798 799 cmd = SVGA3D_FIFOReserve(swc, 800 SVGA_3D_CMD_SET_SHADER_CONST, 801 sizeof *cmd + (numRegs - 1) * sizeof cmd->values, 802 0); 803 if (!cmd) 804 return PIPE_ERROR_OUT_OF_MEMORY; 805 806 cmd->cid = swc->cid; 807 cmd->reg = reg; 808 cmd->type = type; 809 cmd->ctype = ctype; 810 811 memcpy(&cmd->values, values, numRegs * sizeof cmd->values); 812 813 swc->commit(swc); 814 815 return PIPE_OK; 816 } 817 818 819 820 821 822 /* 823 *---------------------------------------------------------------------- 824 * 825 * SVGA3D_SetShader -- 826 * 827 * Switch active shaders. This binds a new vertex or pixel shader 828 * to the specified context. 829 * 830 * A shader ID of SVGA3D_INVALID_ID unbinds any shader, switching 831 * back to the fixed function vertex or pixel pipeline. 832 * 833 * Results: 834 * None. 835 * 836 * Side effects: 837 * None. 838 * 839 *---------------------------------------------------------------------- 840 */ 841 842 enum pipe_error 843 SVGA3D_SetShader(struct svga_winsys_context *swc, 844 SVGA3dShaderType type, // IN 845 uint32 shid) // IN 846 { 847 SVGA3dCmdSetShader *cmd; 848 849 assert(type == SVGA3D_SHADERTYPE_VS || type == SVGA3D_SHADERTYPE_PS); 850 851 cmd = SVGA3D_FIFOReserve(swc, 852 SVGA_3D_CMD_SET_SHADER, sizeof *cmd, 853 0); 854 if (!cmd) 855 return PIPE_ERROR_OUT_OF_MEMORY; 856 857 cmd->cid = swc->cid; 858 cmd->type = type; 859 cmd->shid = shid; 860 swc->commit(swc); 861 862 return PIPE_OK; 863 } 864 865 866 /* 867 *---------------------------------------------------------------------- 868 * 869 * SVGA3D_BeginClear -- 870 * 871 * Begin a CLEAR command. This reserves space for it in the FIFO, 872 * and returns a pointer to the command's rectangle array. This 873 * function must be paired with SVGA_FIFOCommitAll(). 874 * 875 * Clear is a rendering operation which fills a list of 876 * rectangles with constant values on all render target types 877 * indicated by 'flags'. 878 * 879 * Clear is not affected by clipping, depth test, or other 880 * render state which affects the fragment pipeline. 881 * 882 * Results: 883 * None. 884 * 885 * Side effects: 886 * May write to attached render target surfaces. 887 * 888 *---------------------------------------------------------------------- 889 */ 890 891 enum pipe_error 892 SVGA3D_BeginClear(struct svga_winsys_context *swc, 893 SVGA3dClearFlag flags, // IN 894 uint32 color, // IN 895 float depth, // IN 896 uint32 stencil, // IN 897 SVGA3dRect **rects, // OUT 898 uint32 numRects) // IN 899 { 900 SVGA3dCmdClear *cmd; 901 902 cmd = SVGA3D_FIFOReserve(swc, 903 SVGA_3D_CMD_CLEAR, 904 sizeof *cmd + sizeof **rects * numRects, 905 0); 906 if (!cmd) 907 return PIPE_ERROR_OUT_OF_MEMORY; 908 909 cmd->cid = swc->cid; 910 cmd->clearFlag = flags; 911 cmd->color = color; 912 cmd->depth = depth; 913 cmd->stencil = stencil; 914 *rects = (SVGA3dRect*) &cmd[1]; 915 916 return PIPE_OK; 917 } 918 919 920 /* 921 *---------------------------------------------------------------------- 922 * 923 * SVGA3D_ClearRect -- 924 * 925 * This is a simplified version of SVGA3D_BeginClear(). 926 * 927 * Results: 928 * None. 929 * 930 * Side effects: 931 * None. 932 * 933 *---------------------------------------------------------------------- 934 */ 935 936 enum pipe_error 937 SVGA3D_ClearRect(struct svga_winsys_context *swc, 938 SVGA3dClearFlag flags, // IN 939 uint32 color, // IN 940 float depth, // IN 941 uint32 stencil, // IN 942 uint32 x, // IN 943 uint32 y, // IN 944 uint32 w, // IN 945 uint32 h) // IN 946 { 947 SVGA3dRect *rect; 948 enum pipe_error ret; 949 950 ret = SVGA3D_BeginClear(swc, flags, color, depth, stencil, &rect, 1); 951 if (ret != PIPE_OK) 952 return PIPE_ERROR_OUT_OF_MEMORY; 953 954 memset(rect, 0, sizeof *rect); 955 rect->x = x; 956 rect->y = y; 957 rect->w = w; 958 rect->h = h; 959 swc->commit(swc); 960 961 return PIPE_OK; 962 } 963 964 965 /* 966 *---------------------------------------------------------------------- 967 * 968 * SVGA3D_BeginDrawPrimitives -- 969 * 970 * Begin a DRAW_PRIMITIVES command. This reserves space for it in 971 * the FIFO, and returns a pointer to the command's arrays. 972 * This function must be paired with SVGA_FIFOCommitAll(). 973 * 974 * Drawing commands consist of two variable-length arrays: 975 * SVGA3dVertexDecl elements declare a set of vertex buffers to 976 * use while rendering, and SVGA3dPrimitiveRange elements specify 977 * groups of primitives each with an optional index buffer. 978 * 979 * The decls and ranges arrays are initialized to zero. 980 * 981 * Results: 982 * None. 983 * 984 * Side effects: 985 * May write to attached render target surfaces. 986 * 987 *---------------------------------------------------------------------- 988 */ 989 990 enum pipe_error 991 SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc, 992 SVGA3dVertexDecl **decls, // OUT 993 uint32 numVertexDecls, // IN 994 SVGA3dPrimitiveRange **ranges, // OUT 995 uint32 numRanges) // IN 996 { 997 SVGA3dCmdDrawPrimitives *cmd; 998 SVGA3dVertexDecl *declArray; 999 SVGA3dPrimitiveRange *rangeArray; 1000 uint32 declSize = sizeof **decls * numVertexDecls; 1001 uint32 rangeSize = sizeof **ranges * numRanges; 1002 1003 cmd = SVGA3D_FIFOReserve(swc, 1004 SVGA_3D_CMD_DRAW_PRIMITIVES, 1005 sizeof *cmd + declSize + rangeSize, 1006 numVertexDecls + numRanges); 1007 if (!cmd) 1008 return PIPE_ERROR_OUT_OF_MEMORY; 1009 1010 cmd->cid = swc->cid; 1011 cmd->numVertexDecls = numVertexDecls; 1012 cmd->numRanges = numRanges; 1013 1014 declArray = (SVGA3dVertexDecl*) &cmd[1]; 1015 rangeArray = (SVGA3dPrimitiveRange*) &declArray[numVertexDecls]; 1016 1017 memset(declArray, 0, declSize); 1018 memset(rangeArray, 0, rangeSize); 1019 1020 *decls = declArray; 1021 *ranges = rangeArray; 1022 1023 swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH; 1024 1025 return PIPE_OK; 1026 } 1027 1028 1029 /* 1030 *---------------------------------------------------------------------- 1031 * 1032 * SVGA3D_BeginSurfaceCopy -- 1033 * 1034 * Begin a SURFACE_COPY command. This reserves space for it in 1035 * the FIFO, and returns a pointer to the command's arrays. This 1036 * function must be paired with SVGA_FIFOCommitAll(). 1037 * 1038 * The box array is initialized with zeroes. 1039 * 1040 * Results: 1041 * None. 1042 * 1043 * Side effects: 1044 * Asynchronously copies a list of boxes from surface to surface. 1045 * 1046 *---------------------------------------------------------------------- 1047 */ 1048 1049 enum pipe_error 1050 SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc, 1051 struct pipe_surface *src, // IN 1052 struct pipe_surface *dest, // IN 1053 SVGA3dCopyBox **boxes, // OUT 1054 uint32 numBoxes) // IN 1055 { 1056 SVGA3dCmdSurfaceCopy *cmd; 1057 uint32 boxesSize = sizeof **boxes * numBoxes; 1058 1059 cmd = SVGA3D_FIFOReserve(swc, 1060 SVGA_3D_CMD_SURFACE_COPY, sizeof *cmd + boxesSize, 1061 2); 1062 if (!cmd) 1063 return PIPE_ERROR_OUT_OF_MEMORY; 1064 1065 surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ); 1066 surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE); 1067 *boxes = (SVGA3dCopyBox*) &cmd[1]; 1068 1069 memset(*boxes, 0, boxesSize); 1070 1071 return PIPE_OK; 1072 } 1073 1074 1075 /* 1076 *---------------------------------------------------------------------- 1077 * 1078 * SVGA3D_SurfaceStretchBlt -- 1079 * 1080 * Issue a SURFACE_STRETCHBLT command: an asynchronous 1081 * surface-to-surface blit, with scaling. 1082 * 1083 * Results: 1084 * None. 1085 * 1086 * Side effects: 1087 * Asynchronously copies one box from surface to surface. 1088 * 1089 *---------------------------------------------------------------------- 1090 */ 1091 1092 enum pipe_error 1093 SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc, 1094 struct pipe_surface *src, // IN 1095 struct pipe_surface *dest, // IN 1096 SVGA3dBox *boxSrc, // IN 1097 SVGA3dBox *boxDest, // IN 1098 SVGA3dStretchBltMode mode) // IN 1099 { 1100 SVGA3dCmdSurfaceStretchBlt *cmd; 1101 1102 cmd = SVGA3D_FIFOReserve(swc, 1103 SVGA_3D_CMD_SURFACE_STRETCHBLT, sizeof *cmd, 1104 2); 1105 if (!cmd) 1106 return PIPE_ERROR_OUT_OF_MEMORY; 1107 1108 surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ); 1109 surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE); 1110 cmd->boxSrc = *boxSrc; 1111 cmd->boxDest = *boxDest; 1112 cmd->mode = mode; 1113 swc->commit(swc); 1114 1115 return PIPE_OK; 1116 } 1117 1118 1119 /* 1120 *---------------------------------------------------------------------- 1121 * 1122 * SVGA3D_SetViewport -- 1123 * 1124 * Set the current context's viewport rectangle. The viewport 1125 * is clipped to the dimensions of the current render target, 1126 * then all rendering is clipped to the viewport. 1127 * 1128 * Results: 1129 * None. 1130 * 1131 * Side effects: 1132 * None. 1133 * 1134 *---------------------------------------------------------------------- 1135 */ 1136 1137 enum pipe_error 1138 SVGA3D_SetViewport(struct svga_winsys_context *swc, 1139 SVGA3dRect *rect) // IN 1140 { 1141 SVGA3dCmdSetViewport *cmd; 1142 1143 cmd = SVGA3D_FIFOReserve(swc, 1144 SVGA_3D_CMD_SETVIEWPORT, sizeof *cmd, 1145 0); 1146 if (!cmd) 1147 return PIPE_ERROR_OUT_OF_MEMORY; 1148 1149 cmd->cid = swc->cid; 1150 cmd->rect = *rect; 1151 swc->commit(swc); 1152 1153 return PIPE_OK; 1154 } 1155 1156 1157 1158 1159 /* 1160 *---------------------------------------------------------------------- 1161 * 1162 * SVGA3D_SetScissorRect -- 1163 * 1164 * Set the current context's scissor rectangle. If scissoring 1165 * is enabled then all rendering is clipped to the scissor bounds. 1166 * 1167 * Results: 1168 * None. 1169 * 1170 * Side effects: 1171 * None. 1172 * 1173 *---------------------------------------------------------------------- 1174 */ 1175 1176 enum pipe_error 1177 SVGA3D_SetScissorRect(struct svga_winsys_context *swc, 1178 SVGA3dRect *rect) // IN 1179 { 1180 SVGA3dCmdSetScissorRect *cmd; 1181 1182 cmd = SVGA3D_FIFOReserve(swc, 1183 SVGA_3D_CMD_SETSCISSORRECT, sizeof *cmd, 1184 0); 1185 if (!cmd) 1186 return PIPE_ERROR_OUT_OF_MEMORY; 1187 1188 cmd->cid = swc->cid; 1189 cmd->rect = *rect; 1190 swc->commit(swc); 1191 1192 return PIPE_OK; 1193 } 1194 1195 /* 1196 *---------------------------------------------------------------------- 1197 * 1198 * SVGA3D_SetClipPlane -- 1199 * 1200 * Set one of the current context's clip planes. If the clip 1201 * plane is enabled then all 3d rendering is clipped against 1202 * the plane. 1203 * 1204 * Results: 1205 * None. 1206 * 1207 * Side effects: 1208 * None. 1209 * 1210 *---------------------------------------------------------------------- 1211 */ 1212 1213 enum pipe_error 1214 SVGA3D_SetClipPlane(struct svga_winsys_context *swc, 1215 uint32 index, const float *plane) 1216 { 1217 SVGA3dCmdSetClipPlane *cmd; 1218 1219 cmd = SVGA3D_FIFOReserve(swc, 1220 SVGA_3D_CMD_SETCLIPPLANE, sizeof *cmd, 1221 0); 1222 if (!cmd) 1223 return PIPE_ERROR_OUT_OF_MEMORY; 1224 1225 cmd->cid = swc->cid; 1226 cmd->index = index; 1227 cmd->plane[0] = plane[0]; 1228 cmd->plane[1] = plane[1]; 1229 cmd->plane[2] = plane[2]; 1230 cmd->plane[3] = plane[3]; 1231 swc->commit(swc); 1232 1233 return PIPE_OK; 1234 } 1235 1236 /* 1237 *---------------------------------------------------------------------- 1238 * 1239 * SVGA3D_SetZRange -- 1240 * 1241 * Set the range of the depth buffer to use. 'min' and 'max' 1242 * are values between 0.0 and 1.0. 1243 * 1244 * Results: 1245 * None. 1246 * 1247 * Side effects: 1248 * None. 1249 * 1250 *---------------------------------------------------------------------- 1251 */ 1252 1253 enum pipe_error 1254 SVGA3D_SetZRange(struct svga_winsys_context *swc, 1255 float zMin, // IN 1256 float zMax) // IN 1257 { 1258 SVGA3dCmdSetZRange *cmd; 1259 1260 cmd = SVGA3D_FIFOReserve(swc, 1261 SVGA_3D_CMD_SETZRANGE, sizeof *cmd, 1262 0); 1263 if (!cmd) 1264 return PIPE_ERROR_OUT_OF_MEMORY; 1265 1266 cmd->cid = swc->cid; 1267 cmd->zRange.min = zMin; 1268 cmd->zRange.max = zMax; 1269 swc->commit(swc); 1270 1271 return PIPE_OK; 1272 } 1273 1274 1275 /* 1276 *---------------------------------------------------------------------- 1277 * 1278 * SVGA3D_BeginSetTextureState -- 1279 * 1280 * Begin a SETTEXTURESTATE command. This reserves space for it in 1281 * the FIFO, and returns a pointer to the command's texture state 1282 * array. This function must be paired with SVGA_FIFOCommitAll(). 1283 * 1284 * This command sets rendering state which is per-texture-unit. 1285 * 1286 * XXX: Individual texture states need documentation. However, 1287 * they are very similar to the texture states defined by 1288 * Direct3D. The D3D documentation is a good starting point 1289 * for understanding SVGA3D texture states. 1290 * 1291 * Results: 1292 * None. 1293 * 1294 * Side effects: 1295 * None. 1296 * 1297 *---------------------------------------------------------------------- 1298 */ 1299 1300 enum pipe_error 1301 SVGA3D_BeginSetTextureState(struct svga_winsys_context *swc, 1302 SVGA3dTextureState **states, // OUT 1303 uint32 numStates) // IN 1304 { 1305 SVGA3dCmdSetTextureState *cmd; 1306 1307 cmd = SVGA3D_FIFOReserve(swc, 1308 SVGA_3D_CMD_SETTEXTURESTATE, 1309 sizeof *cmd + sizeof **states * numStates, 1310 numStates); 1311 if (!cmd) 1312 return PIPE_ERROR_OUT_OF_MEMORY; 1313 1314 cmd->cid = swc->cid; 1315 *states = (SVGA3dTextureState*) &cmd[1]; 1316 1317 return PIPE_OK; 1318 } 1319 1320 1321 /* 1322 *---------------------------------------------------------------------- 1323 * 1324 * SVGA3D_BeginSetRenderState -- 1325 * 1326 * Begin a SETRENDERSTATE command. This reserves space for it in 1327 * the FIFO, and returns a pointer to the command's texture state 1328 * array. This function must be paired with SVGA_FIFOCommitAll(). 1329 * 1330 * This command sets rendering state which is global to the context. 1331 * 1332 * XXX: Individual render states need documentation. However, 1333 * they are very similar to the render states defined by 1334 * Direct3D. The D3D documentation is a good starting point 1335 * for understanding SVGA3D render states. 1336 * 1337 * Results: 1338 * None. 1339 * 1340 * Side effects: 1341 * None. 1342 * 1343 *---------------------------------------------------------------------- 1344 */ 1345 1346 enum pipe_error 1347 SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc, 1348 SVGA3dRenderState **states, // OUT 1349 uint32 numStates) // IN 1350 { 1351 SVGA3dCmdSetRenderState *cmd; 1352 1353 cmd = SVGA3D_FIFOReserve(swc, 1354 SVGA_3D_CMD_SETRENDERSTATE, 1355 sizeof *cmd + sizeof **states * numStates, 1356 0); 1357 if (!cmd) 1358 return PIPE_ERROR_OUT_OF_MEMORY; 1359 1360 cmd->cid = swc->cid; 1361 *states = (SVGA3dRenderState*) &cmd[1]; 1362 1363 return PIPE_OK; 1364 } 1365 1366 1367 /* 1368 *---------------------------------------------------------------------- 1369 * 1370 * SVGA3D_BeginGBQuery-- 1371 * 1372 * GB resource version of SVGA3D_BeginQuery. 1373 * 1374 * Results: 1375 * None. 1376 * 1377 * Side effects: 1378 * Commits space in the FIFO memory. 1379 * 1380 *---------------------------------------------------------------------- 1381 */ 1382 1383 static enum pipe_error 1384 SVGA3D_BeginGBQuery(struct svga_winsys_context *swc, 1385 SVGA3dQueryType type) // IN 1386 { 1387 SVGA3dCmdBeginGBQuery *cmd; 1388 1389 cmd = SVGA3D_FIFOReserve(swc, 1390 SVGA_3D_CMD_BEGIN_GB_QUERY, 1391 sizeof *cmd, 1392 1); 1393 if (!cmd) 1394 return PIPE_ERROR_OUT_OF_MEMORY; 1395 1396 cmd->cid = swc->cid; 1397 cmd->type = type; 1398 1399 swc->commit(swc); 1400 1401 return PIPE_OK; 1402 } 1403 1404 1405 /* 1406 *---------------------------------------------------------------------- 1407 * 1408 * SVGA3D_BeginQuery-- 1409 * 1410 * Issues a SVGA_3D_CMD_BEGIN_QUERY command. 1411 * 1412 * Results: 1413 * None. 1414 * 1415 * Side effects: 1416 * Commits space in the FIFO memory. 1417 * 1418 *---------------------------------------------------------------------- 1419 */ 1420 1421 enum pipe_error 1422 SVGA3D_BeginQuery(struct svga_winsys_context *swc, 1423 SVGA3dQueryType type) // IN 1424 { 1425 SVGA3dCmdBeginQuery *cmd; 1426 1427 if (swc->have_gb_objects) 1428 return SVGA3D_BeginGBQuery(swc, type); 1429 1430 cmd = SVGA3D_FIFOReserve(swc, 1431 SVGA_3D_CMD_BEGIN_QUERY, 1432 sizeof *cmd, 1433 0); 1434 if (!cmd) 1435 return PIPE_ERROR_OUT_OF_MEMORY; 1436 1437 cmd->cid = swc->cid; 1438 cmd->type = type; 1439 1440 swc->commit(swc); 1441 1442 return PIPE_OK; 1443 } 1444 1445 1446 /* 1447 *---------------------------------------------------------------------- 1448 * 1449 * SVGA3D_EndGBQuery-- 1450 * 1451 * GB resource version of SVGA3D_EndQuery. 1452 * 1453 * Results: 1454 * None. 1455 * 1456 * Side effects: 1457 * Commits space in the FIFO memory. 1458 * 1459 *---------------------------------------------------------------------- 1460 */ 1461 1462 static enum pipe_error 1463 SVGA3D_EndGBQuery(struct svga_winsys_context *swc, 1464 SVGA3dQueryType type, // IN 1465 struct svga_winsys_buffer *buffer) // IN/OUT 1466 { 1467 SVGA3dCmdEndGBQuery *cmd; 1468 1469 cmd = SVGA3D_FIFOReserve(swc, 1470 SVGA_3D_CMD_END_GB_QUERY, 1471 sizeof *cmd, 1472 2); 1473 if (!cmd) 1474 return PIPE_ERROR_OUT_OF_MEMORY; 1475 1476 cmd->cid = swc->cid; 1477 cmd->type = type; 1478 1479 swc->mob_relocation(swc, &cmd->mobid, &cmd->offset, buffer, 1480 0, SVGA_RELOC_READ | SVGA_RELOC_WRITE); 1481 1482 swc->commit(swc); 1483 1484 return PIPE_OK; 1485 } 1486 1487 1488 /* 1489 *---------------------------------------------------------------------- 1490 * 1491 * SVGA3D_EndQuery-- 1492 * 1493 * Issues a SVGA_3D_CMD_END_QUERY command. 1494 * 1495 * Results: 1496 * None. 1497 * 1498 * Side effects: 1499 * Commits space in the FIFO memory. 1500 * 1501 *---------------------------------------------------------------------- 1502 */ 1503 1504 enum pipe_error 1505 SVGA3D_EndQuery(struct svga_winsys_context *swc, 1506 SVGA3dQueryType type, // IN 1507 struct svga_winsys_buffer *buffer) // IN/OUT 1508 { 1509 SVGA3dCmdEndQuery *cmd; 1510 1511 if (swc->have_gb_objects) 1512 return SVGA3D_EndGBQuery(swc, type, buffer); 1513 1514 cmd = SVGA3D_FIFOReserve(swc, 1515 SVGA_3D_CMD_END_QUERY, 1516 sizeof *cmd, 1517 1); 1518 if (!cmd) 1519 return PIPE_ERROR_OUT_OF_MEMORY; 1520 1521 cmd->cid = swc->cid; 1522 cmd->type = type; 1523 1524 swc->region_relocation(swc, &cmd->guestResult, buffer, 0, 1525 SVGA_RELOC_READ | SVGA_RELOC_WRITE); 1526 1527 swc->commit(swc); 1528 1529 return PIPE_OK; 1530 } 1531 1532 1533 /* 1534 *---------------------------------------------------------------------- 1535 * 1536 * SVGA3D_WaitForGBQuery-- 1537 * 1538 * GB resource version of SVGA3D_WaitForQuery. 1539 * 1540 * Results: 1541 * None. 1542 * 1543 * Side effects: 1544 * Commits space in the FIFO memory. 1545 * 1546 *---------------------------------------------------------------------- 1547 */ 1548 1549 static enum pipe_error 1550 SVGA3D_WaitForGBQuery(struct svga_winsys_context *swc, 1551 SVGA3dQueryType type, // IN 1552 struct svga_winsys_buffer *buffer) // IN/OUT 1553 { 1554 SVGA3dCmdWaitForGBQuery *cmd; 1555 1556 cmd = SVGA3D_FIFOReserve(swc, 1557 SVGA_3D_CMD_WAIT_FOR_GB_QUERY, 1558 sizeof *cmd, 1559 2); 1560 if (!cmd) 1561 return PIPE_ERROR_OUT_OF_MEMORY; 1562 1563 cmd->cid = swc->cid; 1564 cmd->type = type; 1565 1566 swc->mob_relocation(swc, &cmd->mobid, &cmd->offset, buffer, 1567 0, SVGA_RELOC_READ | SVGA_RELOC_WRITE); 1568 1569 swc->commit(swc); 1570 1571 return PIPE_OK; 1572 } 1573 1574 1575 /* 1576 *---------------------------------------------------------------------- 1577 * 1578 * SVGA3D_WaitForQuery-- 1579 * 1580 * Issues a SVGA_3D_CMD_WAIT_FOR_QUERY command. This reserves space 1581 * for it in the FIFO. This doesn't actually wait for the query to 1582 * finish but instead tells the host to start a wait at the driver 1583 * level. The caller can wait on the status variable in the 1584 * guestPtr memory or send an insert fence instruction after this 1585 * command and wait on the fence. 1586 * 1587 * Results: 1588 * None. 1589 * 1590 * Side effects: 1591 * Commits space in the FIFO memory. 1592 * 1593 *---------------------------------------------------------------------- 1594 */ 1595 1596 enum pipe_error 1597 SVGA3D_WaitForQuery(struct svga_winsys_context *swc, 1598 SVGA3dQueryType type, // IN 1599 struct svga_winsys_buffer *buffer) // IN/OUT 1600 { 1601 SVGA3dCmdWaitForQuery *cmd; 1602 1603 if (swc->have_gb_objects) 1604 return SVGA3D_WaitForGBQuery(swc, type, buffer); 1605 1606 cmd = SVGA3D_FIFOReserve(swc, 1607 SVGA_3D_CMD_WAIT_FOR_QUERY, 1608 sizeof *cmd, 1609 1); 1610 if (!cmd) 1611 return PIPE_ERROR_OUT_OF_MEMORY; 1612 1613 cmd->cid = swc->cid; 1614 cmd->type = type; 1615 1616 swc->region_relocation(swc, &cmd->guestResult, buffer, 0, 1617 SVGA_RELOC_READ | SVGA_RELOC_WRITE); 1618 1619 swc->commit(swc); 1620 1621 return PIPE_OK; 1622 } 1623 1624 1625 enum pipe_error 1626 SVGA3D_BindGBShader(struct svga_winsys_context *swc, 1627 struct svga_winsys_gb_shader *gbshader) 1628 { 1629 SVGA3dCmdBindGBShader *cmd = 1630 SVGA3D_FIFOReserve(swc, 1631 SVGA_3D_CMD_BIND_GB_SHADER, 1632 sizeof *cmd, 1633 2); /* two relocations */ 1634 1635 if (!cmd) 1636 return PIPE_ERROR_OUT_OF_MEMORY; 1637 1638 swc->shader_relocation(swc, &cmd->shid, &cmd->mobid, 1639 &cmd->offsetInBytes, gbshader, 0); 1640 1641 swc->commit(swc); 1642 1643 return PIPE_OK; 1644 } 1645 1646 1647 enum pipe_error 1648 SVGA3D_SetGBShader(struct svga_winsys_context *swc, 1649 SVGA3dShaderType type, // IN 1650 struct svga_winsys_gb_shader *gbshader) 1651 { 1652 SVGA3dCmdSetShader *cmd; 1653 1654 assert(type == SVGA3D_SHADERTYPE_VS || type == SVGA3D_SHADERTYPE_PS); 1655 1656 cmd = SVGA3D_FIFOReserve(swc, 1657 SVGA_3D_CMD_SET_SHADER, 1658 sizeof *cmd, 1659 2); /* two relocations */ 1660 if (!cmd) 1661 return PIPE_ERROR_OUT_OF_MEMORY; 1662 1663 cmd->cid = swc->cid; 1664 cmd->type = type; 1665 if (gbshader) 1666 swc->shader_relocation(swc, &cmd->shid, NULL, NULL, gbshader, 0); 1667 else 1668 cmd->shid = SVGA_ID_INVALID; 1669 swc->commit(swc); 1670 1671 return PIPE_OK; 1672 } 1673 1674 1675 /** 1676 * \param flags mask of SVGA_RELOC_READ / _WRITE 1677 */ 1678 enum pipe_error 1679 SVGA3D_BindGBSurface(struct svga_winsys_context *swc, 1680 struct svga_winsys_surface *surface) 1681 { 1682 SVGA3dCmdBindGBSurface *cmd = 1683 SVGA3D_FIFOReserve(swc, 1684 SVGA_3D_CMD_BIND_GB_SURFACE, 1685 sizeof *cmd, 1686 2); /* two relocations */ 1687 1688 if (!cmd) 1689 return PIPE_ERROR_OUT_OF_MEMORY; 1690 1691 swc->surface_relocation(swc, &cmd->sid, &cmd->mobid, surface, 1692 SVGA_RELOC_READ | SVGA_RELOC_INTERNAL); 1693 1694 swc->commit(swc); 1695 1696 return PIPE_OK; 1697 } 1698 1699 1700 /** 1701 * Update an image in a guest-backed surface. 1702 * (Inform the device that the guest-contents have been updated.) 1703 */ 1704 enum pipe_error 1705 SVGA3D_UpdateGBImage(struct svga_winsys_context *swc, 1706 struct svga_winsys_surface *surface, 1707 const SVGA3dBox *box, 1708 unsigned face, unsigned mipLevel) 1709 1710 { 1711 SVGA3dCmdUpdateGBImage *cmd = 1712 SVGA3D_FIFOReserve(swc, 1713 SVGA_3D_CMD_UPDATE_GB_IMAGE, 1714 sizeof *cmd, 1715 1); /* one relocation */ 1716 1717 if (!cmd) 1718 return PIPE_ERROR_OUT_OF_MEMORY; 1719 1720 swc->surface_relocation(swc, &cmd->image.sid, NULL, surface, 1721 SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL); 1722 cmd->image.face = face; 1723 cmd->image.mipmap = mipLevel; 1724 cmd->box = *box; 1725 1726 swc->commit(swc); 1727 swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH; 1728 1729 return PIPE_OK; 1730 } 1731 1732 1733 /** 1734 * Update an entire guest-backed surface. 1735 * (Inform the device that the guest-contents have been updated.) 1736 */ 1737 enum pipe_error 1738 SVGA3D_UpdateGBSurface(struct svga_winsys_context *swc, 1739 struct svga_winsys_surface *surface) 1740 { 1741 SVGA3dCmdUpdateGBSurface *cmd = 1742 SVGA3D_FIFOReserve(swc, 1743 SVGA_3D_CMD_UPDATE_GB_SURFACE, 1744 sizeof *cmd, 1745 1); /* one relocation */ 1746 1747 if (!cmd) 1748 return PIPE_ERROR_OUT_OF_MEMORY; 1749 1750 swc->surface_relocation(swc, &cmd->sid, NULL, surface, 1751 SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL); 1752 1753 swc->commit(swc); 1754 swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH; 1755 1756 return PIPE_OK; 1757 } 1758 1759 1760 /** 1761 * Readback an image in a guest-backed surface. 1762 * (Request the device to flush the dirty contents into the guest.) 1763 */ 1764 enum pipe_error 1765 SVGA3D_ReadbackGBImage(struct svga_winsys_context *swc, 1766 struct svga_winsys_surface *surface, 1767 unsigned face, unsigned mipLevel) 1768 { 1769 SVGA3dCmdReadbackGBImage *cmd = 1770 SVGA3D_FIFOReserve(swc, 1771 SVGA_3D_CMD_READBACK_GB_IMAGE, 1772 sizeof *cmd, 1773 1); /* one relocation */ 1774 1775 if (!cmd) 1776 return PIPE_ERROR_OUT_OF_MEMORY; 1777 1778 swc->surface_relocation(swc, &cmd->image.sid, NULL, surface, 1779 SVGA_RELOC_READ | SVGA_RELOC_INTERNAL); 1780 cmd->image.face = face; 1781 cmd->image.mipmap = mipLevel; 1782 1783 swc->commit(swc); 1784 swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH; 1785 1786 return PIPE_OK; 1787 } 1788 1789 1790 /** 1791 * Readback an entire guest-backed surface. 1792 * (Request the device to flush the dirty contents into the guest.) 1793 */ 1794 enum pipe_error 1795 SVGA3D_ReadbackGBSurface(struct svga_winsys_context *swc, 1796 struct svga_winsys_surface *surface) 1797 { 1798 SVGA3dCmdReadbackGBSurface *cmd = 1799 SVGA3D_FIFOReserve(swc, 1800 SVGA_3D_CMD_READBACK_GB_SURFACE, 1801 sizeof *cmd, 1802 1); /* one relocation */ 1803 1804 if (!cmd) 1805 return PIPE_ERROR_OUT_OF_MEMORY; 1806 1807 swc->surface_relocation(swc, &cmd->sid, NULL, surface, 1808 SVGA_RELOC_READ | SVGA_RELOC_INTERNAL); 1809 1810 swc->commit(swc); 1811 swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH; 1812 1813 return PIPE_OK; 1814 } 1815 1816 1817 enum pipe_error 1818 SVGA3D_ReadbackGBImagePartial(struct svga_winsys_context *swc, 1819 struct svga_winsys_surface *surface, 1820 unsigned face, unsigned mipLevel, 1821 const SVGA3dBox *box, 1822 bool invertBox) 1823 { 1824 SVGA3dCmdReadbackGBImagePartial *cmd = 1825 SVGA3D_FIFOReserve(swc, 1826 SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL, 1827 sizeof *cmd, 1828 1); /* one relocation */ 1829 if (!cmd) 1830 return PIPE_ERROR_OUT_OF_MEMORY; 1831 1832 swc->surface_relocation(swc, &cmd->image.sid, NULL, surface, 1833 SVGA_RELOC_READ | SVGA_RELOC_INTERNAL); 1834 cmd->image.face = face; 1835 cmd->image.mipmap = mipLevel; 1836 cmd->box = *box; 1837 cmd->invertBox = invertBox; 1838 1839 swc->commit(swc); 1840 swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH; 1841 1842 return PIPE_OK; 1843 } 1844 1845 1846 enum pipe_error 1847 SVGA3D_InvalidateGBImagePartial(struct svga_winsys_context *swc, 1848 struct svga_winsys_surface *surface, 1849 unsigned face, unsigned mipLevel, 1850 const SVGA3dBox *box, 1851 bool invertBox) 1852 { 1853 SVGA3dCmdInvalidateGBImagePartial *cmd = 1854 SVGA3D_FIFOReserve(swc, 1855 SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL, 1856 sizeof *cmd, 1857 1); /* one relocation */ 1858 if (!cmd) 1859 return PIPE_ERROR_OUT_OF_MEMORY; 1860 1861 swc->surface_relocation(swc, &cmd->image.sid, NULL, surface, 1862 SVGA_RELOC_READ | SVGA_RELOC_INTERNAL); 1863 cmd->image.face = face; 1864 cmd->image.mipmap = mipLevel; 1865 cmd->box = *box; 1866 cmd->invertBox = invertBox; 1867 1868 swc->commit(swc); 1869 1870 return PIPE_OK; 1871 } 1872 1873 enum pipe_error 1874 SVGA3D_InvalidateGBSurface(struct svga_winsys_context *swc, 1875 struct svga_winsys_surface *surface) 1876 { 1877 SVGA3dCmdInvalidateGBSurface *cmd = 1878 SVGA3D_FIFOReserve(swc, 1879 SVGA_3D_CMD_INVALIDATE_GB_SURFACE, 1880 sizeof *cmd, 1881 1); /* one relocation */ 1882 if (!cmd) 1883 return PIPE_ERROR_OUT_OF_MEMORY; 1884 1885 swc->surface_relocation(swc, &cmd->sid, NULL, surface, 1886 SVGA_RELOC_READ | SVGA_RELOC_INTERNAL); 1887 swc->commit(swc); 1888 1889 return PIPE_OK; 1890 } 1891 1892 enum pipe_error 1893 SVGA3D_SetGBShaderConstsInline(struct svga_winsys_context *swc, 1894 unsigned regStart, 1895 unsigned numRegs, 1896 SVGA3dShaderType shaderType, 1897 SVGA3dShaderConstType constType, 1898 const void *values) 1899 { 1900 SVGA3dCmdSetGBShaderConstInline *cmd; 1901 1902 assert(numRegs > 0); 1903 1904 cmd = SVGA3D_FIFOReserve(swc, 1905 SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE, 1906 sizeof *cmd + numRegs * sizeof(float[4]), 1907 0); /* no relocations */ 1908 if (!cmd) 1909 return PIPE_ERROR_OUT_OF_MEMORY; 1910 1911 cmd->cid = swc->cid; 1912 cmd->regStart = regStart; 1913 cmd->shaderType = shaderType; 1914 cmd->constType = constType; 1915 1916 memcpy(&cmd[1], values, numRegs * sizeof(float[4])); 1917 1918 swc->commit(swc); 1919 1920 return PIPE_OK; 1921 } 1922