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