svga_cmd.c revision 2d22186ca80cee2c5929f8fb59b18eec12995534
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 * Results: 49 * id is filled out. 50 * 51 * Side effects: 52 * One surface relocation is performed for texture handle. 53 * 54 *---------------------------------------------------------------------- 55 */ 56 57static INLINE 58void surface_to_surfaceid(struct svga_winsys_context *swc, // IN 59 struct pipe_surface *surface, // IN 60 SVGA3dSurfaceImageId *id, // OUT 61 unsigned flags) // IN 62{ 63 if(surface) { 64 struct svga_surface *s = svga_surface(surface); 65 swc->surface_relocation(swc, &id->sid, s->handle, flags); 66 id->face = s->real_face; /* faces have the same order */ 67 id->mipmap = s->real_level; 68 } 69 else { 70 swc->surface_relocation(swc, &id->sid, NULL, flags); 71 id->face = 0; 72 id->mipmap = 0; 73 } 74} 75 76 77/* 78 *---------------------------------------------------------------------- 79 * 80 * SVGA3D_FIFOReserve -- 81 * 82 * Reserve space for an SVGA3D FIFO command. 83 * 84 * The 2D SVGA commands have been around for a while, so they 85 * have a rather asymmetric structure. The SVGA3D protocol is 86 * more uniform: each command begins with a header containing the 87 * command number and the full size. 88 * 89 * This is a convenience wrapper around SVGA_FIFOReserve. We 90 * reserve space for the whole command, and write the header. 91 * 92 * This function must be paired with SVGA_FIFOCommitAll(). 93 * 94 * Results: 95 * Returns a pointer to the space reserved for command-specific 96 * data. It must be 'cmdSize' bytes long. 97 * 98 * Side effects: 99 * Begins a FIFO reservation. 100 * 101 *---------------------------------------------------------------------- 102 */ 103 104void * 105SVGA3D_FIFOReserve(struct svga_winsys_context *swc, 106 uint32 cmd, // IN 107 uint32 cmdSize, // IN 108 uint32 nr_relocs) // IN 109{ 110 SVGA3dCmdHeader *header; 111 112 header = swc->reserve(swc, sizeof *header + cmdSize, nr_relocs); 113 if(!header) 114 return NULL; 115 116 header->id = cmd; 117 header->size = cmdSize; 118 119 return &header[1]; 120} 121 122 123void 124SVGA_FIFOCommitAll(struct svga_winsys_context *swc) 125{ 126 swc->commit(swc); 127} 128 129 130/* 131 *---------------------------------------------------------------------- 132 * 133 * SVGA3D_DefineContext -- 134 * 135 * Create a new context, to be referred to with the provided ID. 136 * 137 * Context objects encapsulate all render state, and shader 138 * objects are per-context. 139 * 140 * Surfaces are not per-context. The same surface can be shared 141 * between multiple contexts, and surface operations can occur 142 * without a context. 143 * 144 * If the provided context ID already existed, it is redefined. 145 * 146 * Context IDs are arbitrary small non-negative integers, 147 * global to the entire SVGA device. 148 * 149 * Results: 150 * None. 151 * 152 * Side effects: 153 * None. 154 * 155 *---------------------------------------------------------------------- 156 */ 157 158enum pipe_error 159SVGA3D_DefineContext(struct svga_winsys_context *swc) // IN 160{ 161 SVGA3dCmdDefineContext *cmd; 162 163 cmd = SVGA3D_FIFOReserve(swc, 164 SVGA_3D_CMD_CONTEXT_DEFINE, sizeof *cmd, 0); 165 if(!cmd) 166 return PIPE_ERROR_OUT_OF_MEMORY; 167 168 cmd->cid = swc->cid; 169 170 swc->commit(swc); 171 172 return PIPE_OK; 173} 174 175 176/* 177 *---------------------------------------------------------------------- 178 * 179 * SVGA3D_DestroyContext -- 180 * 181 * Delete a context created with SVGA3D_DefineContext. 182 * 183 * Results: 184 * None. 185 * 186 * Side effects: 187 * None. 188 * 189 *---------------------------------------------------------------------- 190 */ 191 192enum pipe_error 193SVGA3D_DestroyContext(struct svga_winsys_context *swc) // IN 194{ 195 SVGA3dCmdDestroyContext *cmd; 196 197 cmd = SVGA3D_FIFOReserve(swc, 198 SVGA_3D_CMD_CONTEXT_DESTROY, sizeof *cmd, 0); 199 if(!cmd) 200 return PIPE_ERROR_OUT_OF_MEMORY; 201 202 cmd->cid = swc->cid; 203 204 swc->commit(swc); 205 206 return PIPE_OK; 207} 208 209 210/* 211 *---------------------------------------------------------------------- 212 * 213 * SVGA3D_BeginDefineSurface -- 214 * 215 * Begin a SURFACE_DEFINE command. This reserves space for it in 216 * the FIFO, and returns pointers to the command's faces and 217 * mipsizes arrays. 218 * 219 * This function must be paired with SVGA_FIFOCommitAll(). 220 * The faces and mipSizes arrays are initialized to zero. 221 * 222 * This creates a "surface" object in the SVGA3D device, 223 * with the provided surface ID (sid). Surfaces are generic 224 * containers for host VRAM objects like textures, vertex 225 * buffers, and depth/stencil buffers. 226 * 227 * Surfaces are hierarchical: 228 * 229 * - Surface may have multiple faces (for cube maps) 230 * 231 * - Each face has a list of mipmap levels 232 * 233 * - Each mipmap image may have multiple volume 234 * slices, if the image is three dimensional. 235 * 236 * - Each slice is a 2D array of 'blocks' 237 * 238 * - Each block may be one or more pixels. 239 * (Usually 1, more for DXT or YUV formats.) 240 * 241 * Surfaces are generic host VRAM objects. The SVGA3D device 242 * may optimize surfaces according to the format they were 243 * created with, but this format does not limit the ways in 244 * which the surface may be used. For example, a depth surface 245 * can be used as a texture, or a floating point image may 246 * be used as a vertex buffer. Some surface usages may be 247 * lower performance, due to software emulation, but any 248 * usage should work with any surface. 249 * 250 * If 'sid' is already defined, the old surface is deleted 251 * and this new surface replaces it. 252 * 253 * Surface IDs are arbitrary small non-negative integers, 254 * global to the entire SVGA device. 255 * 256 * Results: 257 * Returns pointers to arrays allocated in the FIFO for 'faces' 258 * and 'mipSizes'. 259 * 260 * Side effects: 261 * Begins a FIFO reservation. 262 * 263 *---------------------------------------------------------------------- 264 */ 265 266enum pipe_error 267SVGA3D_BeginDefineSurface(struct svga_winsys_context *swc, 268 struct svga_winsys_surface *sid, // IN 269 SVGA3dSurfaceFlags flags, // IN 270 SVGA3dSurfaceFormat format, // IN 271 SVGA3dSurfaceFace **faces, // OUT 272 SVGA3dSize **mipSizes, // OUT 273 uint32 numMipSizes) // IN 274{ 275 SVGA3dCmdDefineSurface *cmd; 276 277 cmd = SVGA3D_FIFOReserve(swc, 278 SVGA_3D_CMD_SURFACE_DEFINE, sizeof *cmd + 279 sizeof **mipSizes * numMipSizes, 1); 280 if(!cmd) 281 return PIPE_ERROR_OUT_OF_MEMORY; 282 283 swc->surface_relocation(swc, &cmd->sid, sid, SVGA_RELOC_WRITE); 284 cmd->surfaceFlags = flags; 285 cmd->format = format; 286 287 *faces = &cmd->face[0]; 288 *mipSizes = (SVGA3dSize*) &cmd[1]; 289 290 memset(*faces, 0, sizeof **faces * SVGA3D_MAX_SURFACE_FACES); 291 memset(*mipSizes, 0, sizeof **mipSizes * numMipSizes); 292 293 return PIPE_OK; 294} 295 296 297/* 298 *---------------------------------------------------------------------- 299 * 300 * SVGA3D_DefineSurface2D -- 301 * 302 * This is a simplified version of SVGA3D_BeginDefineSurface(), 303 * which does not support cube maps, mipmaps, or volume textures. 304 * 305 * Results: 306 * None. 307 * 308 * Side effects: 309 * None. 310 * 311 *---------------------------------------------------------------------- 312 */ 313 314enum pipe_error 315SVGA3D_DefineSurface2D(struct svga_winsys_context *swc, // IN 316 struct svga_winsys_surface *sid, // IN 317 uint32 width, // IN 318 uint32 height, // IN 319 SVGA3dSurfaceFormat format) // IN 320{ 321 SVGA3dSize *mipSizes; 322 SVGA3dSurfaceFace *faces; 323 enum pipe_error ret; 324 325 ret = SVGA3D_BeginDefineSurface(swc, 326 sid, 0, format, &faces, &mipSizes, 1); 327 if(ret != PIPE_OK) 328 return ret; 329 330 faces[0].numMipLevels = 1; 331 332 mipSizes[0].width = width; 333 mipSizes[0].height = height; 334 mipSizes[0].depth = 1; 335 336 swc->commit(swc);; 337 338 return PIPE_OK; 339} 340 341 342/* 343 *---------------------------------------------------------------------- 344 * 345 * SVGA3D_DestroySurface -- 346 * 347 * Release the host VRAM encapsulated by a particular surface ID. 348 * 349 * Results: 350 * None. 351 * 352 * Side effects: 353 * None. 354 * 355 *---------------------------------------------------------------------- 356 */ 357 358enum pipe_error 359SVGA3D_DestroySurface(struct svga_winsys_context *swc, 360 struct svga_winsys_surface *sid) // IN 361{ 362 SVGA3dCmdDestroySurface *cmd; 363 364 cmd = SVGA3D_FIFOReserve(swc, 365 SVGA_3D_CMD_SURFACE_DESTROY, sizeof *cmd, 1); 366 if(!cmd) 367 return PIPE_ERROR_OUT_OF_MEMORY; 368 369 swc->surface_relocation(swc, &cmd->sid, sid, SVGA_RELOC_READ); 370 swc->commit(swc);; 371 372 return PIPE_OK; 373} 374 375 376/* 377 *---------------------------------------------------------------------- 378 * 379 * SVGA3D_SurfaceDMA-- 380 * 381 * Emit a SURFACE_DMA command. 382 * 383 * When the SVGA3D device asynchronously processes this FIFO 384 * command, a DMA operation is performed between host VRAM and 385 * a generic SVGAGuestPtr. The guest pointer may refer to guest 386 * VRAM (provided by the SVGA PCI device) or to guest system 387 * memory that has been set up as a Guest Memory Region (GMR) 388 * by the SVGA device. 389 * 390 * The guest's DMA buffer must remain valid (not freed, paged out, 391 * or overwritten) until the host has finished processing this 392 * command. The guest can determine that the host has finished 393 * by using the SVGA device's FIFO Fence mechanism. 394 * 395 * The guest's image buffer can be an arbitrary size and shape. 396 * Guest image data is interpreted according to the SVGA3D surface 397 * format specified when the surface was defined. 398 * 399 * The caller may optionally define the guest image's pitch. 400 * guestImage->pitch can either be zero (assume image is tightly 401 * packed) or it must be the number of bytes between vertically 402 * adjacent image blocks. 403 * 404 * The provided copybox list specifies which regions of the source 405 * image are to be copied, and where they appear on the destination. 406 * 407 * NOTE: srcx/srcy are always on the guest image and x/y are 408 * always on the host image, regardless of the actual transfer 409 * direction! 410 * 411 * For efficiency, the SVGA3D device is free to copy more data 412 * than specified. For example, it may round copy boxes outwards 413 * such that they lie on particular alignment boundaries. 414 * 415 *---------------------------------------------------------------------- 416 */ 417 418enum pipe_error 419SVGA3D_SurfaceDMA(struct svga_winsys_context *swc, 420 struct svga_transfer *st, // IN 421 SVGA3dTransferType transfer, // IN 422 const SVGA3dCopyBox *boxes, // IN 423 uint32 numBoxes, // IN 424 SVGA3dSurfaceDMAFlags flags) // IN 425{ 426 struct svga_texture *texture = svga_texture(st->base.resource); 427 SVGA3dCmdSurfaceDMA *cmd; 428 SVGA3dCmdSurfaceDMASuffix *pSuffix; 429 uint32 boxesSize = sizeof *boxes * numBoxes; 430 unsigned region_flags; 431 unsigned surface_flags; 432 433 if(transfer == SVGA3D_WRITE_HOST_VRAM) { 434 region_flags = SVGA_RELOC_READ; 435 surface_flags = SVGA_RELOC_WRITE; 436 } 437 else if(transfer == SVGA3D_READ_HOST_VRAM) { 438 region_flags = SVGA_RELOC_WRITE; 439 surface_flags = SVGA_RELOC_READ; 440 } 441 else { 442 assert(0); 443 return PIPE_ERROR_BAD_INPUT; 444 } 445 446 cmd = SVGA3D_FIFOReserve(swc, 447 SVGA_3D_CMD_SURFACE_DMA, 448 sizeof *cmd + boxesSize + sizeof *pSuffix, 449 2); 450 if(!cmd) 451 return PIPE_ERROR_OUT_OF_MEMORY; 452 453 swc->region_relocation(swc, &cmd->guest.ptr, st->hwbuf, 0, region_flags); 454 cmd->guest.pitch = st->base.stride; 455 456 swc->surface_relocation(swc, &cmd->host.sid, texture->handle, surface_flags); 457 cmd->host.face = st->face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */ 458 cmd->host.mipmap = st->base.level; 459 460 cmd->transfer = transfer; 461 462 memcpy(&cmd[1], boxes, boxesSize); 463 464 pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + boxesSize); 465 pSuffix->suffixSize = sizeof *pSuffix; 466 pSuffix->maximumOffset = st->hw_nblocksy*st->base.stride; 467 pSuffix->flags = flags; 468 469 swc->commit(swc); 470 471 return PIPE_OK; 472} 473 474 475enum pipe_error 476SVGA3D_BufferDMA(struct svga_winsys_context *swc, 477 struct svga_winsys_buffer *guest, 478 struct svga_winsys_surface *host, 479 SVGA3dTransferType transfer, // IN 480 uint32 size, // IN 481 uint32 guest_offset, // IN 482 uint32 host_offset, // IN 483 SVGA3dSurfaceDMAFlags flags) // IN 484{ 485 SVGA3dCmdSurfaceDMA *cmd; 486 SVGA3dCopyBox *box; 487 SVGA3dCmdSurfaceDMASuffix *pSuffix; 488 unsigned region_flags; 489 unsigned surface_flags; 490 491 if(transfer == SVGA3D_WRITE_HOST_VRAM) { 492 region_flags = SVGA_RELOC_READ; 493 surface_flags = SVGA_RELOC_WRITE; 494 } 495 else if(transfer == SVGA3D_READ_HOST_VRAM) { 496 region_flags = SVGA_RELOC_WRITE; 497 surface_flags = SVGA_RELOC_READ; 498 } 499 else { 500 assert(0); 501 return PIPE_ERROR_BAD_INPUT; 502 } 503 504 cmd = SVGA3D_FIFOReserve(swc, 505 SVGA_3D_CMD_SURFACE_DMA, 506 sizeof *cmd + sizeof *box + sizeof *pSuffix, 507 2); 508 if(!cmd) 509 return PIPE_ERROR_OUT_OF_MEMORY; 510 511 swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags); 512 cmd->guest.pitch = 0; 513 514 swc->surface_relocation(swc, &cmd->host.sid, host, surface_flags); 515 cmd->host.face = 0; 516 cmd->host.mipmap = 0; 517 518 cmd->transfer = transfer; 519 520 box = (SVGA3dCopyBox *)&cmd[1]; 521 box->x = host_offset; 522 box->y = 0; 523 box->z = 0; 524 box->w = size; 525 box->h = 1; 526 box->d = 1; 527 box->srcx = guest_offset; 528 box->srcy = 0; 529 box->srcz = 0; 530 531 pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box); 532 pSuffix->suffixSize = sizeof *pSuffix; 533 pSuffix->maximumOffset = guest_offset + size; 534 pSuffix->flags = flags; 535 536 swc->commit(swc); 537 538 return PIPE_OK; 539} 540 541 542/* 543 *---------------------------------------------------------------------- 544 * 545 * SVGA3D_SetRenderTarget -- 546 * 547 * Bind a surface object to a particular render target attachment 548 * point on the current context. Render target attachment points 549 * exist for color buffers, a depth buffer, and a stencil buffer. 550 * 551 * The SVGA3D device is quite lenient about the types of surfaces 552 * that may be used as render targets. The color buffers must 553 * all be the same size, but the depth and stencil buffers do not 554 * have to be the same size as the color buffer. All attachments 555 * are optional. 556 * 557 * Some combinations of render target formats may require software 558 * emulation, depending on the capabilities of the host graphics 559 * API and graphics hardware. 560 * 561 * Results: 562 * None. 563 * 564 * Side effects: 565 * None. 566 * 567 *---------------------------------------------------------------------- 568 */ 569 570enum pipe_error 571SVGA3D_SetRenderTarget(struct svga_winsys_context *swc, 572 SVGA3dRenderTargetType type, // IN 573 struct pipe_surface *surface) // IN 574{ 575 SVGA3dCmdSetRenderTarget *cmd; 576 577 cmd = SVGA3D_FIFOReserve(swc, 578 SVGA_3D_CMD_SETRENDERTARGET, sizeof *cmd, 1); 579 if(!cmd) 580 return PIPE_ERROR_OUT_OF_MEMORY; 581 582 583 cmd->cid = swc->cid; 584 585 cmd->type = type; 586 587 surface_to_surfaceid(swc, surface, &cmd->target, SVGA_RELOC_WRITE); 588 589 swc->commit(swc); 590 591 return PIPE_OK; 592} 593 594 595 596 597 598 599/* 600 *---------------------------------------------------------------------- 601 * 602 * SVGA3D_DefineShader -- 603 * 604 * Upload the bytecode for a new shader. The bytecode is "SVGA3D 605 * format", which is theoretically a binary-compatible superset 606 * of Microsoft's DirectX shader bytecode. In practice, the 607 * SVGA3D bytecode doesn't yet have any extensions to DirectX's 608 * bytecode format. 609 * 610 * The SVGA3D device supports shader models 1.1 through 2.0. 611 * 612 * The caller chooses a shader ID (small positive integer) by 613 * which this shader will be identified in future commands. This 614 * ID is in a namespace which is per-context and per-shader-type. 615 * 616 * 'bytecodeLen' is specified in bytes. It must be a multiple of 4. 617 * 618 * Results: 619 * None. 620 * 621 * Side effects: 622 * None. 623 * 624 *---------------------------------------------------------------------- 625 */ 626 627enum pipe_error 628SVGA3D_DefineShader(struct svga_winsys_context *swc, 629 uint32 shid, // IN 630 SVGA3dShaderType type, // IN 631 const uint32 *bytecode, // IN 632 uint32 bytecodeLen) // IN 633{ 634 SVGA3dCmdDefineShader *cmd; 635 636 assert(bytecodeLen % 4 == 0); 637 638 cmd = SVGA3D_FIFOReserve(swc, 639 SVGA_3D_CMD_SHADER_DEFINE, sizeof *cmd + bytecodeLen, 640 0); 641 if(!cmd) 642 return PIPE_ERROR_OUT_OF_MEMORY; 643 644 cmd->cid = swc->cid; 645 cmd->shid = shid; 646 cmd->type = type; 647 memcpy(&cmd[1], bytecode, bytecodeLen); 648 swc->commit(swc); 649 650 return PIPE_OK; 651} 652 653 654/* 655 *---------------------------------------------------------------------- 656 * 657 * SVGA3D_DestroyShader -- 658 * 659 * Delete a shader that was created by SVGA3D_DefineShader. If 660 * the shader was the current vertex or pixel shader for its 661 * context, rendering results are undefined until a new shader is 662 * bound. 663 * 664 * Results: 665 * None. 666 * 667 * Side effects: 668 * None. 669 * 670 *---------------------------------------------------------------------- 671 */ 672 673enum pipe_error 674SVGA3D_DestroyShader(struct svga_winsys_context *swc, 675 uint32 shid, // IN 676 SVGA3dShaderType type) // IN 677{ 678 SVGA3dCmdDestroyShader *cmd; 679 680 cmd = SVGA3D_FIFOReserve(swc, 681 SVGA_3D_CMD_SHADER_DESTROY, sizeof *cmd, 682 0); 683 if(!cmd) 684 return PIPE_ERROR_OUT_OF_MEMORY; 685 686 cmd->cid = swc->cid; 687 cmd->shid = shid; 688 cmd->type = type; 689 swc->commit(swc); 690 691 return PIPE_OK; 692} 693 694 695/* 696 *---------------------------------------------------------------------- 697 * 698 * SVGA3D_SetShaderConst -- 699 * 700 * Set the value of a shader constant. 701 * 702 * Shader constants are analogous to uniform variables in GLSL, 703 * except that they belong to the render context rather than to 704 * an individual shader. 705 * 706 * Constants may have one of three types: A 4-vector of floats, 707 * a 4-vector of integers, or a single boolean flag. 708 * 709 * Results: 710 * None. 711 * 712 * Side effects: 713 * None. 714 * 715 *---------------------------------------------------------------------- 716 */ 717 718enum pipe_error 719SVGA3D_SetShaderConst(struct svga_winsys_context *swc, 720 uint32 reg, // IN 721 SVGA3dShaderType type, // IN 722 SVGA3dShaderConstType ctype, // IN 723 const void *value) // IN 724{ 725 SVGA3dCmdSetShaderConst *cmd; 726 727 cmd = SVGA3D_FIFOReserve(swc, 728 SVGA_3D_CMD_SET_SHADER_CONST, sizeof *cmd, 729 0); 730 if(!cmd) 731 return PIPE_ERROR_OUT_OF_MEMORY; 732 733 cmd->cid = swc->cid; 734 cmd->reg = reg; 735 cmd->type = type; 736 cmd->ctype = ctype; 737 738 switch (ctype) { 739 740 case SVGA3D_CONST_TYPE_FLOAT: 741 case SVGA3D_CONST_TYPE_INT: 742 memcpy(&cmd->values, value, sizeof cmd->values); 743 break; 744 745 case SVGA3D_CONST_TYPE_BOOL: 746 memset(&cmd->values, 0, sizeof cmd->values); 747 cmd->values[0] = *(uint32*)value; 748 break; 749 750 default: 751 assert(0); 752 break; 753 754 } 755 swc->commit(swc); 756 757 return PIPE_OK; 758} 759 760 761 762 763 764/* 765 *---------------------------------------------------------------------- 766 * 767 * SVGA3D_SetShader -- 768 * 769 * Switch active shaders. This binds a new vertex or pixel shader 770 * to the specified context. 771 * 772 * A shader ID of SVGA3D_INVALID_ID unbinds any shader, switching 773 * back to the fixed function vertex or pixel pipeline. 774 * 775 * Results: 776 * None. 777 * 778 * Side effects: 779 * None. 780 * 781 *---------------------------------------------------------------------- 782 */ 783 784enum pipe_error 785SVGA3D_SetShader(struct svga_winsys_context *swc, 786 SVGA3dShaderType type, // IN 787 uint32 shid) // IN 788{ 789 SVGA3dCmdSetShader *cmd; 790 791 cmd = SVGA3D_FIFOReserve(swc, 792 SVGA_3D_CMD_SET_SHADER, sizeof *cmd, 793 0); 794 if(!cmd) 795 return PIPE_ERROR_OUT_OF_MEMORY; 796 797 cmd->cid = swc->cid; 798 cmd->type = type; 799 cmd->shid = shid; 800 swc->commit(swc); 801 802 return PIPE_OK; 803} 804 805 806/* 807 *---------------------------------------------------------------------- 808 * 809 * SVGA3D_BeginClear -- 810 * 811 * Begin a CLEAR command. This reserves space for it in the FIFO, 812 * and returns a pointer to the command's rectangle array. This 813 * function must be paired with SVGA_FIFOCommitAll(). 814 * 815 * Clear is a rendering operation which fills a list of 816 * rectangles with constant values on all render target types 817 * indicated by 'flags'. 818 * 819 * Clear is not affected by clipping, depth test, or other 820 * render state which affects the fragment pipeline. 821 * 822 * Results: 823 * None. 824 * 825 * Side effects: 826 * May write to attached render target surfaces. 827 * 828 *---------------------------------------------------------------------- 829 */ 830 831enum pipe_error 832SVGA3D_BeginClear(struct svga_winsys_context *swc, 833 SVGA3dClearFlag flags, // IN 834 uint32 color, // IN 835 float depth, // IN 836 uint32 stencil, // IN 837 SVGA3dRect **rects, // OUT 838 uint32 numRects) // IN 839{ 840 SVGA3dCmdClear *cmd; 841 842 cmd = SVGA3D_FIFOReserve(swc, 843 SVGA_3D_CMD_CLEAR, 844 sizeof *cmd + sizeof **rects * numRects, 845 0); 846 if(!cmd) 847 return PIPE_ERROR_OUT_OF_MEMORY; 848 849 cmd->cid = swc->cid; 850 cmd->clearFlag = flags; 851 cmd->color = color; 852 cmd->depth = depth; 853 cmd->stencil = stencil; 854 *rects = (SVGA3dRect*) &cmd[1]; 855 856 return PIPE_OK; 857} 858 859 860/* 861 *---------------------------------------------------------------------- 862 * 863 * SVGA3D_ClearRect -- 864 * 865 * This is a simplified version of SVGA3D_BeginClear(). 866 * 867 * Results: 868 * None. 869 * 870 * Side effects: 871 * None. 872 * 873 *---------------------------------------------------------------------- 874 */ 875 876enum pipe_error 877SVGA3D_ClearRect(struct svga_winsys_context *swc, 878 SVGA3dClearFlag flags, // IN 879 uint32 color, // IN 880 float depth, // IN 881 uint32 stencil, // IN 882 uint32 x, // IN 883 uint32 y, // IN 884 uint32 w, // IN 885 uint32 h) // IN 886{ 887 SVGA3dRect *rect; 888 enum pipe_error ret; 889 890 ret = SVGA3D_BeginClear(swc, flags, color, depth, stencil, &rect, 1); 891 if(ret != PIPE_OK) 892 return PIPE_ERROR_OUT_OF_MEMORY; 893 894 memset(rect, 0, sizeof *rect); 895 rect->x = x; 896 rect->y = y; 897 rect->w = w; 898 rect->h = h; 899 swc->commit(swc); 900 901 return PIPE_OK; 902} 903 904 905/* 906 *---------------------------------------------------------------------- 907 * 908 * SVGA3D_BeginDrawPrimitives -- 909 * 910 * Begin a DRAW_PRIMITIVES command. This reserves space for it in 911 * the FIFO, and returns a pointer to the command's arrays. 912 * This function must be paired with SVGA_FIFOCommitAll(). 913 * 914 * Drawing commands consist of two variable-length arrays: 915 * SVGA3dVertexDecl elements declare a set of vertex buffers to 916 * use while rendering, and SVGA3dPrimitiveRange elements specify 917 * groups of primitives each with an optional index buffer. 918 * 919 * The decls and ranges arrays are initialized to zero. 920 * 921 * Results: 922 * None. 923 * 924 * Side effects: 925 * May write to attached render target surfaces. 926 * 927 *---------------------------------------------------------------------- 928 */ 929 930enum pipe_error 931SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc, 932 SVGA3dVertexDecl **decls, // OUT 933 uint32 numVertexDecls, // IN 934 SVGA3dPrimitiveRange **ranges, // OUT 935 uint32 numRanges) // IN 936{ 937 SVGA3dCmdDrawPrimitives *cmd; 938 SVGA3dVertexDecl *declArray; 939 SVGA3dPrimitiveRange *rangeArray; 940 uint32 declSize = sizeof **decls * numVertexDecls; 941 uint32 rangeSize = sizeof **ranges * numRanges; 942 943 cmd = SVGA3D_FIFOReserve(swc, 944 SVGA_3D_CMD_DRAW_PRIMITIVES, 945 sizeof *cmd + declSize + rangeSize, 946 numVertexDecls + numRanges); 947 if(!cmd) 948 return PIPE_ERROR_OUT_OF_MEMORY; 949 950 cmd->cid = swc->cid; 951 cmd->numVertexDecls = numVertexDecls; 952 cmd->numRanges = numRanges; 953 954 declArray = (SVGA3dVertexDecl*) &cmd[1]; 955 rangeArray = (SVGA3dPrimitiveRange*) &declArray[numVertexDecls]; 956 957 memset(declArray, 0, declSize); 958 memset(rangeArray, 0, rangeSize); 959 960 *decls = declArray; 961 *ranges = rangeArray; 962 963 return PIPE_OK; 964} 965 966 967/* 968 *---------------------------------------------------------------------- 969 * 970 * SVGA3D_BeginSurfaceCopy -- 971 * 972 * Begin a SURFACE_COPY command. This reserves space for it in 973 * the FIFO, and returns a pointer to the command's arrays. This 974 * function must be paired with SVGA_FIFOCommitAll(). 975 * 976 * The box array is initialized with zeroes. 977 * 978 * Results: 979 * None. 980 * 981 * Side effects: 982 * Asynchronously copies a list of boxes from surface to surface. 983 * 984 *---------------------------------------------------------------------- 985 */ 986 987enum pipe_error 988SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc, 989 struct pipe_surface *src, // IN 990 struct pipe_surface *dest, // IN 991 SVGA3dCopyBox **boxes, // OUT 992 uint32 numBoxes) // IN 993{ 994 SVGA3dCmdSurfaceCopy *cmd; 995 uint32 boxesSize = sizeof **boxes * numBoxes; 996 997 cmd = SVGA3D_FIFOReserve(swc, 998 SVGA_3D_CMD_SURFACE_COPY, sizeof *cmd + boxesSize, 999 2); 1000 if(!cmd) 1001 return PIPE_ERROR_OUT_OF_MEMORY; 1002 1003 surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ); 1004 surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE); 1005 *boxes = (SVGA3dCopyBox*) &cmd[1]; 1006 1007 memset(*boxes, 0, boxesSize); 1008 1009 return PIPE_OK; 1010} 1011 1012 1013/* 1014 *---------------------------------------------------------------------- 1015 * 1016 * SVGA3D_SurfaceStretchBlt -- 1017 * 1018 * Issue a SURFACE_STRETCHBLT command: an asynchronous 1019 * surface-to-surface blit, with scaling. 1020 * 1021 * Results: 1022 * None. 1023 * 1024 * Side effects: 1025 * Asynchronously copies one box from surface to surface. 1026 * 1027 *---------------------------------------------------------------------- 1028 */ 1029 1030enum pipe_error 1031SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc, 1032 struct pipe_surface *src, // IN 1033 struct pipe_surface *dest, // IN 1034 SVGA3dBox *boxSrc, // IN 1035 SVGA3dBox *boxDest, // IN 1036 SVGA3dStretchBltMode mode) // IN 1037{ 1038 SVGA3dCmdSurfaceStretchBlt *cmd; 1039 1040 cmd = SVGA3D_FIFOReserve(swc, 1041 SVGA_3D_CMD_SURFACE_STRETCHBLT, sizeof *cmd, 1042 2); 1043 if(!cmd) 1044 return PIPE_ERROR_OUT_OF_MEMORY; 1045 1046 surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ); 1047 surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE); 1048 cmd->boxSrc = *boxSrc; 1049 cmd->boxDest = *boxDest; 1050 cmd->mode = mode; 1051 swc->commit(swc); 1052 1053 return PIPE_OK; 1054} 1055 1056 1057/* 1058 *---------------------------------------------------------------------- 1059 * 1060 * SVGA3D_SetViewport -- 1061 * 1062 * Set the current context's viewport rectangle. The viewport 1063 * is clipped to the dimensions of the current render target, 1064 * then all rendering is clipped to the viewport. 1065 * 1066 * Results: 1067 * None. 1068 * 1069 * Side effects: 1070 * None. 1071 * 1072 *---------------------------------------------------------------------- 1073 */ 1074 1075enum pipe_error 1076SVGA3D_SetViewport(struct svga_winsys_context *swc, 1077 SVGA3dRect *rect) // IN 1078{ 1079 SVGA3dCmdSetViewport *cmd; 1080 1081 cmd = SVGA3D_FIFOReserve(swc, 1082 SVGA_3D_CMD_SETVIEWPORT, sizeof *cmd, 1083 0); 1084 if(!cmd) 1085 return PIPE_ERROR_OUT_OF_MEMORY; 1086 1087 cmd->cid = swc->cid; 1088 cmd->rect = *rect; 1089 swc->commit(swc); 1090 1091 return PIPE_OK; 1092} 1093 1094 1095 1096 1097/* 1098 *---------------------------------------------------------------------- 1099 * 1100 * SVGA3D_SetScissorRect -- 1101 * 1102 * Set the current context's scissor rectangle. If scissor 1103 * is enabled then all rendering is clipped to the scissor. 1104 * 1105 * Results: 1106 * None. 1107 * 1108 * Side effects: 1109 * None. 1110 * 1111 *---------------------------------------------------------------------- 1112 */ 1113 1114enum pipe_error 1115SVGA3D_SetScissorRect(struct svga_winsys_context *swc, 1116 SVGA3dRect *rect) // IN 1117{ 1118 SVGA3dCmdSetScissorRect *cmd; 1119 1120 cmd = SVGA3D_FIFOReserve(swc, 1121 SVGA_3D_CMD_SETSCISSORRECT, sizeof *cmd, 1122 0); 1123 if(!cmd) 1124 return PIPE_ERROR_OUT_OF_MEMORY; 1125 1126 cmd->cid = swc->cid; 1127 cmd->rect = *rect; 1128 swc->commit(swc); 1129 1130 return PIPE_OK; 1131} 1132 1133/* 1134 *---------------------------------------------------------------------- 1135 * 1136 * SVGA3D_SetClipPlane -- 1137 * 1138 * Set one of the current context's clip planes. If the clip 1139 * plane is enabled then all 3d rendering is clipped to against 1140 * the plane. 1141 * 1142 * Results: 1143 * None. 1144 * 1145 * Side effects: 1146 * None. 1147 * 1148 *---------------------------------------------------------------------- 1149 */ 1150 1151enum pipe_error SVGA3D_SetClipPlane(struct svga_winsys_context *swc, 1152 uint32 index, const float *plane) 1153{ 1154 SVGA3dCmdSetClipPlane *cmd; 1155 1156 cmd = SVGA3D_FIFOReserve(swc, 1157 SVGA_3D_CMD_SETCLIPPLANE, sizeof *cmd, 1158 0); 1159 if(!cmd) 1160 return PIPE_ERROR_OUT_OF_MEMORY; 1161 1162 cmd->cid = swc->cid; 1163 cmd->index = index; 1164 cmd->plane[0] = plane[0]; 1165 cmd->plane[1] = plane[1]; 1166 cmd->plane[2] = plane[2]; 1167 cmd->plane[3] = plane[3]; 1168 swc->commit(swc); 1169 1170 return PIPE_OK; 1171} 1172 1173/* 1174 *---------------------------------------------------------------------- 1175 * 1176 * SVGA3D_SetZRange -- 1177 * 1178 * Set the range of the depth buffer to use. 'min' and 'max' 1179 * are values between 0.0 and 1.0. 1180 * 1181 * Results: 1182 * None. 1183 * 1184 * Side effects: 1185 * None. 1186 * 1187 *---------------------------------------------------------------------- 1188 */ 1189 1190enum pipe_error 1191SVGA3D_SetZRange(struct svga_winsys_context *swc, 1192 float zMin, // IN 1193 float zMax) // IN 1194{ 1195 SVGA3dCmdSetZRange *cmd; 1196 1197 cmd = SVGA3D_FIFOReserve(swc, 1198 SVGA_3D_CMD_SETZRANGE, sizeof *cmd, 1199 0); 1200 if(!cmd) 1201 return PIPE_ERROR_OUT_OF_MEMORY; 1202 1203 cmd->cid = swc->cid; 1204 cmd->zRange.min = zMin; 1205 cmd->zRange.max = zMax; 1206 swc->commit(swc); 1207 1208 return PIPE_OK; 1209} 1210 1211 1212/* 1213 *---------------------------------------------------------------------- 1214 * 1215 * SVGA3D_BeginSetTextureState -- 1216 * 1217 * Begin a SETTEXTURESTATE command. This reserves space for it in 1218 * the FIFO, and returns a pointer to the command's texture state 1219 * array. This function must be paired with SVGA_FIFOCommitAll(). 1220 * 1221 * This command sets rendering state which is per-texture-unit. 1222 * 1223 * XXX: Individual texture states need documentation. However, 1224 * they are very similar to the texture states defined by 1225 * Direct3D. The D3D documentation is a good starting point 1226 * for understanding SVGA3D texture states. 1227 * 1228 * Results: 1229 * None. 1230 * 1231 * Side effects: 1232 * None. 1233 * 1234 *---------------------------------------------------------------------- 1235 */ 1236 1237enum pipe_error 1238SVGA3D_BeginSetTextureState(struct svga_winsys_context *swc, 1239 SVGA3dTextureState **states, // OUT 1240 uint32 numStates) // IN 1241{ 1242 SVGA3dCmdSetTextureState *cmd; 1243 1244 cmd = SVGA3D_FIFOReserve(swc, 1245 SVGA_3D_CMD_SETTEXTURESTATE, 1246 sizeof *cmd + sizeof **states * numStates, 1247 numStates); 1248 if(!cmd) 1249 return PIPE_ERROR_OUT_OF_MEMORY; 1250 1251 cmd->cid = swc->cid; 1252 *states = (SVGA3dTextureState*) &cmd[1]; 1253 1254 return PIPE_OK; 1255} 1256 1257 1258/* 1259 *---------------------------------------------------------------------- 1260 * 1261 * SVGA3D_BeginSetRenderState -- 1262 * 1263 * Begin a SETRENDERSTATE command. This reserves space for it in 1264 * the FIFO, and returns a pointer to the command's texture state 1265 * array. This function must be paired with SVGA_FIFOCommitAll(). 1266 * 1267 * This command sets rendering state which is global to the context. 1268 * 1269 * XXX: Individual render states need documentation. However, 1270 * they are very similar to the render states defined by 1271 * Direct3D. The D3D documentation is a good starting point 1272 * for understanding SVGA3D render states. 1273 * 1274 * Results: 1275 * None. 1276 * 1277 * Side effects: 1278 * None. 1279 * 1280 *---------------------------------------------------------------------- 1281 */ 1282 1283enum pipe_error 1284SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc, 1285 SVGA3dRenderState **states, // OUT 1286 uint32 numStates) // IN 1287{ 1288 SVGA3dCmdSetRenderState *cmd; 1289 1290 cmd = SVGA3D_FIFOReserve(swc, 1291 SVGA_3D_CMD_SETRENDERSTATE, 1292 sizeof *cmd + sizeof **states * numStates, 1293 0); 1294 if(!cmd) 1295 return PIPE_ERROR_OUT_OF_MEMORY; 1296 1297 cmd->cid = swc->cid; 1298 *states = (SVGA3dRenderState*) &cmd[1]; 1299 1300 return PIPE_OK; 1301} 1302 1303 1304/* 1305 *---------------------------------------------------------------------- 1306 * 1307 * SVGA3D_BeginQuery-- 1308 * 1309 * Issues a SVGA_3D_CMD_BEGIN_QUERY command. 1310 * 1311 * Results: 1312 * None. 1313 * 1314 * Side effects: 1315 * Commits space in the FIFO memory. 1316 * 1317 *---------------------------------------------------------------------- 1318 */ 1319 1320enum pipe_error 1321SVGA3D_BeginQuery(struct svga_winsys_context *swc, 1322 SVGA3dQueryType type) // IN 1323{ 1324 SVGA3dCmdBeginQuery *cmd; 1325 1326 cmd = SVGA3D_FIFOReserve(swc, 1327 SVGA_3D_CMD_BEGIN_QUERY, 1328 sizeof *cmd, 1329 0); 1330 if(!cmd) 1331 return PIPE_ERROR_OUT_OF_MEMORY; 1332 1333 cmd->cid = swc->cid; 1334 cmd->type = type; 1335 1336 swc->commit(swc); 1337 1338 return PIPE_OK; 1339} 1340 1341 1342/* 1343 *---------------------------------------------------------------------- 1344 * 1345 * SVGA3D_EndQuery-- 1346 * 1347 * Issues a SVGA_3D_CMD_END_QUERY command. 1348 * 1349 * Results: 1350 * None. 1351 * 1352 * Side effects: 1353 * Commits space in the FIFO memory. 1354 * 1355 *---------------------------------------------------------------------- 1356 */ 1357 1358enum pipe_error 1359SVGA3D_EndQuery(struct svga_winsys_context *swc, 1360 SVGA3dQueryType type, // IN 1361 struct svga_winsys_buffer *buffer) // IN/OUT 1362{ 1363 SVGA3dCmdEndQuery *cmd; 1364 1365 cmd = SVGA3D_FIFOReserve(swc, 1366 SVGA_3D_CMD_END_QUERY, 1367 sizeof *cmd, 1368 1); 1369 if(!cmd) 1370 return PIPE_ERROR_OUT_OF_MEMORY; 1371 1372 cmd->cid = swc->cid; 1373 cmd->type = type; 1374 1375 swc->region_relocation(swc, &cmd->guestResult, buffer, 0, 1376 SVGA_RELOC_WRITE); 1377 1378 swc->commit(swc); 1379 1380 return PIPE_OK; 1381} 1382 1383 1384/* 1385 *---------------------------------------------------------------------- 1386 * 1387 * SVGA3D_WaitForQuery-- 1388 * 1389 * Issues a SVGA_3D_CMD_WAIT_FOR_QUERY command. This reserves space 1390 * for it in the FIFO. This doesn't actually wait for the query to 1391 * finish but instead tells the host to start a wait at the driver 1392 * level. The caller can wait on the status variable in the 1393 * guestPtr memory or send an insert fence instruction after this 1394 * command and wait on the fence. 1395 * 1396 * Results: 1397 * None. 1398 * 1399 * Side effects: 1400 * Commits space in the FIFO memory. 1401 * 1402 *---------------------------------------------------------------------- 1403 */ 1404 1405enum pipe_error 1406SVGA3D_WaitForQuery(struct svga_winsys_context *swc, 1407 SVGA3dQueryType type, // IN 1408 struct svga_winsys_buffer *buffer) // IN/OUT 1409{ 1410 SVGA3dCmdWaitForQuery *cmd; 1411 1412 cmd = SVGA3D_FIFOReserve(swc, 1413 SVGA_3D_CMD_WAIT_FOR_QUERY, 1414 sizeof *cmd, 1415 1); 1416 if(!cmd) 1417 return PIPE_ERROR_OUT_OF_MEMORY; 1418 1419 cmd->cid = swc->cid; 1420 cmd->type = type; 1421 1422 swc->region_relocation(swc, &cmd->guestResult, buffer, 0, 1423 SVGA_RELOC_WRITE); 1424 1425 swc->commit(swc); 1426 1427 return PIPE_OK; 1428} 1429