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 
57 static INLINE
surface_to_surfaceid(struct svga_winsys_context * swc,struct pipe_surface * surface,SVGA3dSurfaceImageId * id,unsigned flags)58 void 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 
104 void *
SVGA3D_FIFOReserve(struct svga_winsys_context * swc,uint32 cmd,uint32 cmdSize,uint32 nr_relocs)105 SVGA3D_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 
123 void
SVGA_FIFOCommitAll(struct svga_winsys_context * swc)124 SVGA_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 
158 enum pipe_error
SVGA3D_DefineContext(struct svga_winsys_context * swc)159 SVGA3D_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 
192 enum pipe_error
SVGA3D_DestroyContext(struct svga_winsys_context * swc)193 SVGA3D_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 
266 enum pipe_error
SVGA3D_BeginDefineSurface(struct svga_winsys_context * swc,struct svga_winsys_surface * sid,SVGA3dSurfaceFlags flags,SVGA3dSurfaceFormat format,SVGA3dSurfaceFace ** faces,SVGA3dSize ** mipSizes,uint32 numMipSizes)267 SVGA3D_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 
314 enum pipe_error
SVGA3D_DefineSurface2D(struct svga_winsys_context * swc,struct svga_winsys_surface * sid,uint32 width,uint32 height,SVGA3dSurfaceFormat format)315 SVGA3D_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 
358 enum pipe_error
SVGA3D_DestroySurface(struct svga_winsys_context * swc,struct svga_winsys_surface * sid)359 SVGA3D_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 
418 enum pipe_error
SVGA3D_SurfaceDMA(struct svga_winsys_context * swc,struct svga_transfer * st,SVGA3dTransferType transfer,const SVGA3dCopyBox * boxes,uint32 numBoxes,SVGA3dSurfaceDMAFlags flags)419 SVGA3D_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 
475 enum pipe_error
SVGA3D_BufferDMA(struct svga_winsys_context * swc,struct svga_winsys_buffer * guest,struct svga_winsys_surface * host,SVGA3dTransferType transfer,uint32 size,uint32 guest_offset,uint32 host_offset,SVGA3dSurfaceDMAFlags flags)476 SVGA3D_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 
570 enum pipe_error
SVGA3D_SetRenderTarget(struct svga_winsys_context * swc,SVGA3dRenderTargetType type,struct pipe_surface * surface)571 SVGA3D_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 
627 enum pipe_error
SVGA3D_DefineShader(struct svga_winsys_context * swc,uint32 shid,SVGA3dShaderType type,const uint32 * bytecode,uint32 bytecodeLen)628 SVGA3D_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 
673 enum pipe_error
SVGA3D_DestroyShader(struct svga_winsys_context * swc,uint32 shid,SVGA3dShaderType type)674 SVGA3D_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 
718 enum pipe_error
SVGA3D_SetShaderConst(struct svga_winsys_context * swc,uint32 reg,SVGA3dShaderType type,SVGA3dShaderConstType ctype,const void * value)719 SVGA3D_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  * SVGA3D_SetShaderConsts --
765  *
766  *      Set the value of successive shader constants.
767  *
768  *      Shader constants are analogous to uniform variables in GLSL,
769  *      except that they belong to the render context rather than to
770  *      an individual shader.
771  *
772  *      Constants may have one of three types: A 4-vector of floats,
773  *      a 4-vector of integers, or a single boolean flag.
774  *
775  * Results:
776  *      None.
777  *
778  * Side effects:
779  *      None.
780  *
781  *----------------------------------------------------------------------
782  */
783 
784 enum pipe_error
SVGA3D_SetShaderConsts(struct svga_winsys_context * swc,uint32 reg,uint32 numRegs,SVGA3dShaderType type,SVGA3dShaderConstType ctype,const void * values)785 SVGA3D_SetShaderConsts(struct svga_winsys_context *swc,
786                         uint32 reg,                   // IN
787                         uint32 numRegs,               // IN
788                         SVGA3dShaderType type,        // IN
789                         SVGA3dShaderConstType ctype,  // IN
790                         const void *values)           // IN
791 {
792    SVGA3dCmdSetShaderConst *cmd;
793 
794    cmd = SVGA3D_FIFOReserve(swc,
795                             SVGA_3D_CMD_SET_SHADER_CONST,
796                             sizeof *cmd + (numRegs - 1) * sizeof cmd->values,
797                             0);
798    if(!cmd)
799       return PIPE_ERROR_OUT_OF_MEMORY;
800 
801    cmd->cid = swc->cid;
802    cmd->reg = reg;
803    cmd->type = type;
804    cmd->ctype = ctype;
805 
806    memcpy(&cmd->values, values, numRegs * sizeof cmd->values);
807 
808    swc->commit(swc);
809 
810    return PIPE_OK;
811 }
812 
813 
814 
815 
816 
817 /*
818  *----------------------------------------------------------------------
819  *
820  * SVGA3D_SetShader --
821  *
822  *      Switch active shaders. This binds a new vertex or pixel shader
823  *      to the specified context.
824  *
825  *      A shader ID of SVGA3D_INVALID_ID unbinds any shader, switching
826  *      back to the fixed function vertex or pixel pipeline.
827  *
828  * Results:
829  *      None.
830  *
831  * Side effects:
832  *      None.
833  *
834  *----------------------------------------------------------------------
835  */
836 
837 enum pipe_error
SVGA3D_SetShader(struct svga_winsys_context * swc,SVGA3dShaderType type,uint32 shid)838 SVGA3D_SetShader(struct svga_winsys_context *swc,
839                  SVGA3dShaderType type,  // IN
840                  uint32 shid)            // IN
841 {
842    SVGA3dCmdSetShader *cmd;
843 
844    cmd = SVGA3D_FIFOReserve(swc,
845                             SVGA_3D_CMD_SET_SHADER, sizeof *cmd,
846                             0);
847    if(!cmd)
848       return PIPE_ERROR_OUT_OF_MEMORY;
849 
850    cmd->cid = swc->cid;
851    cmd->type = type;
852    cmd->shid = shid;
853    swc->commit(swc);
854 
855    return PIPE_OK;
856 }
857 
858 
859 /*
860  *----------------------------------------------------------------------
861  *
862  * SVGA3D_BeginClear --
863  *
864  *      Begin a CLEAR command. This reserves space for it in the FIFO,
865  *      and returns a pointer to the command's rectangle array.  This
866  *      function must be paired with SVGA_FIFOCommitAll().
867  *
868  *      Clear is a rendering operation which fills a list of
869  *      rectangles with constant values on all render target types
870  *      indicated by 'flags'.
871  *
872  *      Clear is not affected by clipping, depth test, or other
873  *      render state which affects the fragment pipeline.
874  *
875  * Results:
876  *      None.
877  *
878  * Side effects:
879  *      May write to attached render target surfaces.
880  *
881  *----------------------------------------------------------------------
882  */
883 
884 enum pipe_error
SVGA3D_BeginClear(struct svga_winsys_context * swc,SVGA3dClearFlag flags,uint32 color,float depth,uint32 stencil,SVGA3dRect ** rects,uint32 numRects)885 SVGA3D_BeginClear(struct svga_winsys_context *swc,
886                   SVGA3dClearFlag flags,  // IN
887                   uint32 color,           // IN
888                   float depth,            // IN
889                   uint32 stencil,         // IN
890                   SVGA3dRect **rects,     // OUT
891                   uint32 numRects)        // IN
892 {
893    SVGA3dCmdClear *cmd;
894 
895    cmd = SVGA3D_FIFOReserve(swc,
896                             SVGA_3D_CMD_CLEAR,
897                             sizeof *cmd + sizeof **rects * numRects,
898                             0);
899    if(!cmd)
900       return PIPE_ERROR_OUT_OF_MEMORY;
901 
902    cmd->cid = swc->cid;
903    cmd->clearFlag = flags;
904    cmd->color = color;
905    cmd->depth = depth;
906    cmd->stencil = stencil;
907    *rects = (SVGA3dRect*) &cmd[1];
908 
909    return PIPE_OK;
910 }
911 
912 
913 /*
914  *----------------------------------------------------------------------
915  *
916  * SVGA3D_ClearRect --
917  *
918  *      This is a simplified version of SVGA3D_BeginClear().
919  *
920  * Results:
921  *      None.
922  *
923  * Side effects:
924  *      None.
925  *
926  *----------------------------------------------------------------------
927  */
928 
929 enum pipe_error
SVGA3D_ClearRect(struct svga_winsys_context * swc,SVGA3dClearFlag flags,uint32 color,float depth,uint32 stencil,uint32 x,uint32 y,uint32 w,uint32 h)930 SVGA3D_ClearRect(struct svga_winsys_context *swc,
931                  SVGA3dClearFlag flags,  // IN
932                  uint32 color,           // IN
933                  float depth,            // IN
934                  uint32 stencil,         // IN
935                  uint32 x,               // IN
936                  uint32 y,               // IN
937                  uint32 w,               // IN
938                  uint32 h)               // IN
939 {
940    SVGA3dRect *rect;
941    enum pipe_error ret;
942 
943    ret = SVGA3D_BeginClear(swc, flags, color, depth, stencil, &rect, 1);
944    if(ret != PIPE_OK)
945       return PIPE_ERROR_OUT_OF_MEMORY;
946 
947    memset(rect, 0, sizeof *rect);
948    rect->x = x;
949    rect->y = y;
950    rect->w = w;
951    rect->h = h;
952    swc->commit(swc);
953 
954    return PIPE_OK;
955 }
956 
957 
958 /*
959  *----------------------------------------------------------------------
960  *
961  * SVGA3D_BeginDrawPrimitives --
962  *
963  *      Begin a DRAW_PRIMITIVES command. This reserves space for it in
964  *      the FIFO, and returns a pointer to the command's arrays.
965  *      This function must be paired with SVGA_FIFOCommitAll().
966  *
967  *      Drawing commands consist of two variable-length arrays:
968  *      SVGA3dVertexDecl elements declare a set of vertex buffers to
969  *      use while rendering, and SVGA3dPrimitiveRange elements specify
970  *      groups of primitives each with an optional index buffer.
971  *
972  *      The decls and ranges arrays are initialized to zero.
973  *
974  * Results:
975  *      None.
976  *
977  * Side effects:
978  *      May write to attached render target surfaces.
979  *
980  *----------------------------------------------------------------------
981  */
982 
983 enum pipe_error
SVGA3D_BeginDrawPrimitives(struct svga_winsys_context * swc,SVGA3dVertexDecl ** decls,uint32 numVertexDecls,SVGA3dPrimitiveRange ** ranges,uint32 numRanges)984 SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc,
985                            SVGA3dVertexDecl **decls,      // OUT
986                            uint32 numVertexDecls,         // IN
987                            SVGA3dPrimitiveRange **ranges, // OUT
988                            uint32 numRanges)              // IN
989 {
990    SVGA3dCmdDrawPrimitives *cmd;
991    SVGA3dVertexDecl *declArray;
992    SVGA3dPrimitiveRange *rangeArray;
993    uint32 declSize = sizeof **decls * numVertexDecls;
994    uint32 rangeSize = sizeof **ranges * numRanges;
995 
996    cmd = SVGA3D_FIFOReserve(swc,
997                             SVGA_3D_CMD_DRAW_PRIMITIVES,
998                             sizeof *cmd + declSize + rangeSize,
999                             numVertexDecls + numRanges);
1000    if(!cmd)
1001       return PIPE_ERROR_OUT_OF_MEMORY;
1002 
1003    cmd->cid = swc->cid;
1004    cmd->numVertexDecls = numVertexDecls;
1005    cmd->numRanges = numRanges;
1006 
1007    declArray = (SVGA3dVertexDecl*) &cmd[1];
1008    rangeArray = (SVGA3dPrimitiveRange*) &declArray[numVertexDecls];
1009 
1010    memset(declArray, 0, declSize);
1011    memset(rangeArray, 0, rangeSize);
1012 
1013    *decls = declArray;
1014    *ranges = rangeArray;
1015 
1016    return PIPE_OK;
1017 }
1018 
1019 
1020 /*
1021  *----------------------------------------------------------------------
1022  *
1023  * SVGA3D_BeginSurfaceCopy --
1024  *
1025  *      Begin a SURFACE_COPY command. This reserves space for it in
1026  *      the FIFO, and returns a pointer to the command's arrays.  This
1027  *      function must be paired with SVGA_FIFOCommitAll().
1028  *
1029  *      The box array is initialized with zeroes.
1030  *
1031  * Results:
1032  *      None.
1033  *
1034  * Side effects:
1035  *      Asynchronously copies a list of boxes from surface to surface.
1036  *
1037  *----------------------------------------------------------------------
1038  */
1039 
1040 enum pipe_error
SVGA3D_BeginSurfaceCopy(struct svga_winsys_context * swc,struct pipe_surface * src,struct pipe_surface * dest,SVGA3dCopyBox ** boxes,uint32 numBoxes)1041 SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc,
1042                         struct pipe_surface *src,    // IN
1043                         struct pipe_surface *dest,   // IN
1044                         SVGA3dCopyBox **boxes,       // OUT
1045                         uint32 numBoxes)             // IN
1046 {
1047    SVGA3dCmdSurfaceCopy *cmd;
1048    uint32 boxesSize = sizeof **boxes * numBoxes;
1049 
1050    cmd = SVGA3D_FIFOReserve(swc,
1051                             SVGA_3D_CMD_SURFACE_COPY, sizeof *cmd + boxesSize,
1052                             2);
1053    if(!cmd)
1054       return PIPE_ERROR_OUT_OF_MEMORY;
1055 
1056    surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
1057    surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
1058    *boxes = (SVGA3dCopyBox*) &cmd[1];
1059 
1060    memset(*boxes, 0, boxesSize);
1061 
1062    return PIPE_OK;
1063 }
1064 
1065 
1066 /*
1067  *----------------------------------------------------------------------
1068  *
1069  * SVGA3D_SurfaceStretchBlt --
1070  *
1071  *      Issue a SURFACE_STRETCHBLT command: an asynchronous
1072  *      surface-to-surface blit, with scaling.
1073  *
1074  * Results:
1075  *      None.
1076  *
1077  * Side effects:
1078  *      Asynchronously copies one box from surface to surface.
1079  *
1080  *----------------------------------------------------------------------
1081  */
1082 
1083 enum pipe_error
SVGA3D_SurfaceStretchBlt(struct svga_winsys_context * swc,struct pipe_surface * src,struct pipe_surface * dest,SVGA3dBox * boxSrc,SVGA3dBox * boxDest,SVGA3dStretchBltMode mode)1084 SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc,
1085                          struct pipe_surface *src,    // IN
1086                          struct pipe_surface *dest,   // IN
1087                          SVGA3dBox *boxSrc,           // IN
1088                          SVGA3dBox *boxDest,          // IN
1089                          SVGA3dStretchBltMode mode)   // IN
1090 {
1091    SVGA3dCmdSurfaceStretchBlt *cmd;
1092 
1093    cmd = SVGA3D_FIFOReserve(swc,
1094                             SVGA_3D_CMD_SURFACE_STRETCHBLT, sizeof *cmd,
1095                             2);
1096    if(!cmd)
1097       return PIPE_ERROR_OUT_OF_MEMORY;
1098 
1099    surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
1100    surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
1101    cmd->boxSrc = *boxSrc;
1102    cmd->boxDest = *boxDest;
1103    cmd->mode = mode;
1104    swc->commit(swc);
1105 
1106    return PIPE_OK;
1107 }
1108 
1109 
1110 /*
1111  *----------------------------------------------------------------------
1112  *
1113  * SVGA3D_SetViewport --
1114  *
1115  *      Set the current context's viewport rectangle. The viewport
1116  *      is clipped to the dimensions of the current render target,
1117  *      then all rendering is clipped to the viewport.
1118  *
1119  * Results:
1120  *      None.
1121  *
1122  * Side effects:
1123  *      None.
1124  *
1125  *----------------------------------------------------------------------
1126  */
1127 
1128 enum pipe_error
SVGA3D_SetViewport(struct svga_winsys_context * swc,SVGA3dRect * rect)1129 SVGA3D_SetViewport(struct svga_winsys_context *swc,
1130                    SVGA3dRect *rect)  // IN
1131 {
1132    SVGA3dCmdSetViewport *cmd;
1133 
1134    cmd = SVGA3D_FIFOReserve(swc,
1135                             SVGA_3D_CMD_SETVIEWPORT, sizeof *cmd,
1136                             0);
1137    if(!cmd)
1138       return PIPE_ERROR_OUT_OF_MEMORY;
1139 
1140    cmd->cid = swc->cid;
1141    cmd->rect = *rect;
1142    swc->commit(swc);
1143 
1144    return PIPE_OK;
1145 }
1146 
1147 
1148 
1149 
1150 /*
1151  *----------------------------------------------------------------------
1152  *
1153  * SVGA3D_SetScissorRect --
1154  *
1155  *      Set the current context's scissor rectangle. If scissor
1156  *      is enabled then all rendering is clipped to the scissor.
1157  *
1158  * Results:
1159  *      None.
1160  *
1161  * Side effects:
1162  *      None.
1163  *
1164  *----------------------------------------------------------------------
1165  */
1166 
1167 enum pipe_error
SVGA3D_SetScissorRect(struct svga_winsys_context * swc,SVGA3dRect * rect)1168 SVGA3D_SetScissorRect(struct svga_winsys_context *swc,
1169                       SVGA3dRect *rect)  // IN
1170 {
1171    SVGA3dCmdSetScissorRect *cmd;
1172 
1173    cmd = SVGA3D_FIFOReserve(swc,
1174                             SVGA_3D_CMD_SETSCISSORRECT, sizeof *cmd,
1175                             0);
1176    if(!cmd)
1177       return PIPE_ERROR_OUT_OF_MEMORY;
1178 
1179    cmd->cid = swc->cid;
1180    cmd->rect = *rect;
1181    swc->commit(swc);
1182 
1183    return PIPE_OK;
1184 }
1185 
1186 /*
1187  *----------------------------------------------------------------------
1188  *
1189  * SVGA3D_SetClipPlane --
1190  *
1191  *      Set one of the current context's clip planes. If the clip
1192  *      plane is enabled then all 3d rendering is clipped to against
1193  *      the plane.
1194  *
1195  * Results:
1196  *      None.
1197  *
1198  * Side effects:
1199  *      None.
1200  *
1201  *----------------------------------------------------------------------
1202  */
1203 
1204 enum pipe_error
SVGA3D_SetClipPlane(struct svga_winsys_context * swc,uint32 index,const float * plane)1205 SVGA3D_SetClipPlane(struct svga_winsys_context *swc,
1206                     uint32 index, const float *plane)
1207 {
1208    SVGA3dCmdSetClipPlane *cmd;
1209 
1210    cmd = SVGA3D_FIFOReserve(swc,
1211                             SVGA_3D_CMD_SETCLIPPLANE, sizeof *cmd,
1212                             0);
1213    if(!cmd)
1214       return PIPE_ERROR_OUT_OF_MEMORY;
1215 
1216    cmd->cid = swc->cid;
1217    cmd->index = index;
1218    cmd->plane[0] = plane[0];
1219    cmd->plane[1] = plane[1];
1220    cmd->plane[2] = plane[2];
1221    cmd->plane[3] = plane[3];
1222    swc->commit(swc);
1223 
1224    return PIPE_OK;
1225 }
1226 
1227 /*
1228  *----------------------------------------------------------------------
1229  *
1230  * SVGA3D_SetZRange --
1231  *
1232  *      Set the range of the depth buffer to use. 'min' and 'max'
1233  *      are values between 0.0 and 1.0.
1234  *
1235  * Results:
1236  *      None.
1237  *
1238  * Side effects:
1239  *      None.
1240  *
1241  *----------------------------------------------------------------------
1242  */
1243 
1244 enum pipe_error
SVGA3D_SetZRange(struct svga_winsys_context * swc,float zMin,float zMax)1245 SVGA3D_SetZRange(struct svga_winsys_context *swc,
1246                  float zMin,  // IN
1247                  float zMax)  // IN
1248 {
1249    SVGA3dCmdSetZRange *cmd;
1250 
1251    cmd = SVGA3D_FIFOReserve(swc,
1252                             SVGA_3D_CMD_SETZRANGE, sizeof *cmd,
1253                             0);
1254    if(!cmd)
1255       return PIPE_ERROR_OUT_OF_MEMORY;
1256 
1257    cmd->cid = swc->cid;
1258    cmd->zRange.min = zMin;
1259    cmd->zRange.max = zMax;
1260    swc->commit(swc);
1261 
1262    return PIPE_OK;
1263 }
1264 
1265 
1266 /*
1267  *----------------------------------------------------------------------
1268  *
1269  * SVGA3D_BeginSetTextureState --
1270  *
1271  *      Begin a SETTEXTURESTATE command. This reserves space for it in
1272  *      the FIFO, and returns a pointer to the command's texture state
1273  *      array.  This function must be paired with SVGA_FIFOCommitAll().
1274  *
1275  *      This command sets rendering state which is per-texture-unit.
1276  *
1277  *      XXX: Individual texture states need documentation. However,
1278  *           they are very similar to the texture states defined by
1279  *           Direct3D. The D3D documentation is a good starting point
1280  *           for understanding SVGA3D texture states.
1281  *
1282  * Results:
1283  *      None.
1284  *
1285  * Side effects:
1286  *      None.
1287  *
1288  *----------------------------------------------------------------------
1289  */
1290 
1291 enum pipe_error
SVGA3D_BeginSetTextureState(struct svga_winsys_context * swc,SVGA3dTextureState ** states,uint32 numStates)1292 SVGA3D_BeginSetTextureState(struct svga_winsys_context *swc,
1293                             SVGA3dTextureState **states,  // OUT
1294                             uint32 numStates)             // IN
1295 {
1296    SVGA3dCmdSetTextureState *cmd;
1297 
1298    cmd = SVGA3D_FIFOReserve(swc,
1299                             SVGA_3D_CMD_SETTEXTURESTATE,
1300                             sizeof *cmd + sizeof **states * numStates,
1301                             numStates);
1302    if(!cmd)
1303       return PIPE_ERROR_OUT_OF_MEMORY;
1304 
1305    cmd->cid = swc->cid;
1306    *states = (SVGA3dTextureState*) &cmd[1];
1307 
1308    return PIPE_OK;
1309 }
1310 
1311 
1312 /*
1313  *----------------------------------------------------------------------
1314  *
1315  * SVGA3D_BeginSetRenderState --
1316  *
1317  *      Begin a SETRENDERSTATE command. This reserves space for it in
1318  *      the FIFO, and returns a pointer to the command's texture state
1319  *      array.  This function must be paired with SVGA_FIFOCommitAll().
1320  *
1321  *      This command sets rendering state which is global to the context.
1322  *
1323  *      XXX: Individual render states need documentation. However,
1324  *           they are very similar to the render states defined by
1325  *           Direct3D. The D3D documentation is a good starting point
1326  *           for understanding SVGA3D render states.
1327  *
1328  * Results:
1329  *      None.
1330  *
1331  * Side effects:
1332  *      None.
1333  *
1334  *----------------------------------------------------------------------
1335  */
1336 
1337 enum pipe_error
SVGA3D_BeginSetRenderState(struct svga_winsys_context * swc,SVGA3dRenderState ** states,uint32 numStates)1338 SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc,
1339                            SVGA3dRenderState **states,  // OUT
1340                            uint32 numStates)            // IN
1341 {
1342    SVGA3dCmdSetRenderState *cmd;
1343 
1344    cmd = SVGA3D_FIFOReserve(swc,
1345                             SVGA_3D_CMD_SETRENDERSTATE,
1346                             sizeof *cmd + sizeof **states * numStates,
1347                             0);
1348    if(!cmd)
1349       return PIPE_ERROR_OUT_OF_MEMORY;
1350 
1351    cmd->cid = swc->cid;
1352    *states = (SVGA3dRenderState*) &cmd[1];
1353 
1354    return PIPE_OK;
1355 }
1356 
1357 
1358 /*
1359  *----------------------------------------------------------------------
1360  *
1361  * SVGA3D_BeginQuery--
1362  *
1363  *      Issues a SVGA_3D_CMD_BEGIN_QUERY command.
1364  *
1365  * Results:
1366  *      None.
1367  *
1368  * Side effects:
1369  *      Commits space in the FIFO memory.
1370  *
1371  *----------------------------------------------------------------------
1372  */
1373 
1374 enum pipe_error
SVGA3D_BeginQuery(struct svga_winsys_context * swc,SVGA3dQueryType type)1375 SVGA3D_BeginQuery(struct svga_winsys_context *swc,
1376                   SVGA3dQueryType type) // IN
1377 {
1378    SVGA3dCmdBeginQuery *cmd;
1379 
1380    cmd = SVGA3D_FIFOReserve(swc,
1381                             SVGA_3D_CMD_BEGIN_QUERY,
1382                             sizeof *cmd,
1383                             0);
1384    if(!cmd)
1385       return PIPE_ERROR_OUT_OF_MEMORY;
1386 
1387    cmd->cid = swc->cid;
1388    cmd->type = type;
1389 
1390    swc->commit(swc);
1391 
1392    return PIPE_OK;
1393 }
1394 
1395 
1396 /*
1397  *----------------------------------------------------------------------
1398  *
1399  * SVGA3D_EndQuery--
1400  *
1401  *      Issues a SVGA_3D_CMD_END_QUERY command.
1402  *
1403  * Results:
1404  *      None.
1405  *
1406  * Side effects:
1407  *      Commits space in the FIFO memory.
1408  *
1409  *----------------------------------------------------------------------
1410  */
1411 
1412 enum pipe_error
SVGA3D_EndQuery(struct svga_winsys_context * swc,SVGA3dQueryType type,struct svga_winsys_buffer * buffer)1413 SVGA3D_EndQuery(struct svga_winsys_context *swc,
1414                 SVGA3dQueryType type,              // IN
1415                 struct svga_winsys_buffer *buffer) // IN/OUT
1416 {
1417    SVGA3dCmdEndQuery *cmd;
1418 
1419    cmd = SVGA3D_FIFOReserve(swc,
1420                             SVGA_3D_CMD_END_QUERY,
1421                             sizeof *cmd,
1422                             1);
1423    if(!cmd)
1424       return PIPE_ERROR_OUT_OF_MEMORY;
1425 
1426    cmd->cid = swc->cid;
1427    cmd->type = type;
1428 
1429    swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
1430                           SVGA_RELOC_WRITE);
1431 
1432    swc->commit(swc);
1433 
1434    return PIPE_OK;
1435 }
1436 
1437 
1438 /*
1439  *----------------------------------------------------------------------
1440  *
1441  * SVGA3D_WaitForQuery--
1442  *
1443  *      Issues a SVGA_3D_CMD_WAIT_FOR_QUERY command.  This reserves space
1444  *      for it in the FIFO.  This doesn't actually wait for the query to
1445  *      finish but instead tells the host to start a wait at the driver
1446  *      level.  The caller can wait on the status variable in the
1447  *      guestPtr memory or send an insert fence instruction after this
1448  *      command and wait on the fence.
1449  *
1450  * Results:
1451  *      None.
1452  *
1453  * Side effects:
1454  *      Commits space in the FIFO memory.
1455  *
1456  *----------------------------------------------------------------------
1457  */
1458 
1459 enum pipe_error
SVGA3D_WaitForQuery(struct svga_winsys_context * swc,SVGA3dQueryType type,struct svga_winsys_buffer * buffer)1460 SVGA3D_WaitForQuery(struct svga_winsys_context *swc,
1461                     SVGA3dQueryType type,              // IN
1462                     struct svga_winsys_buffer *buffer) // IN/OUT
1463 {
1464    SVGA3dCmdWaitForQuery *cmd;
1465 
1466    cmd = SVGA3D_FIFOReserve(swc,
1467                             SVGA_3D_CMD_WAIT_FOR_QUERY,
1468                             sizeof *cmd,
1469                             1);
1470    if(!cmd)
1471       return PIPE_ERROR_OUT_OF_MEMORY;
1472 
1473    cmd->cid = swc->cid;
1474    cmd->type = type;
1475 
1476    swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
1477                           SVGA_RELOC_WRITE);
1478 
1479    swc->commit(swc);
1480 
1481    return PIPE_OK;
1482 }
1483