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
surface_to_surfaceid(struct svga_winsys_context * swc,struct pipe_surface * surface,SVGA3dSurfaceImageId * id,unsigned flags)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 *
SVGA3D_FIFOReserve(struct svga_winsys_context * swc,uint32 cmd,uint32 cmdSize,uint32 nr_relocs)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
SVGA_FIFOCommitAll(struct svga_winsys_context * swc)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
SVGA3D_DefineContext(struct svga_winsys_context * swc)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
SVGA3D_DestroyContext(struct svga_winsys_context * swc)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
SVGA3D_BeginDefineSurface(struct svga_winsys_context * swc,struct svga_winsys_surface * sid,SVGA3dSurfaceFlags flags,SVGA3dSurfaceFormat format,SVGA3dSurfaceFace ** faces,SVGA3dSize ** mipSizes,uint32 numMipSizes)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
SVGA3D_DefineSurface2D(struct svga_winsys_context * swc,struct svga_winsys_surface * sid,uint32 width,uint32 height,SVGA3dSurfaceFormat format)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
SVGA3D_DestroySurface(struct svga_winsys_context * swc,struct svga_winsys_surface * sid)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
SVGA3D_SurfaceDMA(struct svga_winsys_context * swc,struct svga_transfer * st,SVGA3dTransferType transfer,const SVGA3dCopyBox * boxes,uint32 numBoxes,SVGA3dSurfaceDMAFlags flags)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
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)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
SVGA3D_SetRenderTarget(struct svga_winsys_context * swc,SVGA3dRenderTargetType type,struct pipe_surface * surface)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
SVGA3D_DefineShader(struct svga_winsys_context * swc,uint32 shid,SVGA3dShaderType type,const uint32 * bytecode,uint32 bytecodeLen)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
SVGA3D_DestroyShader(struct svga_winsys_context * swc,uint32 shid,SVGA3dShaderType type)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
SVGA3D_SetShaderConst(struct svga_winsys_context * swc,uint32 reg,SVGA3dShaderType type,SVGA3dShaderConstType ctype,const void * value)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
SVGA3D_SetShaderConsts(struct svga_winsys_context * swc,uint32 reg,uint32 numRegs,SVGA3dShaderType type,SVGA3dShaderConstType ctype,const void * values)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
SVGA3D_SetShader(struct svga_winsys_context * swc,SVGA3dShaderType type,uint32 shid)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
SVGA3D_BeginClear(struct svga_winsys_context * swc,SVGA3dClearFlag flags,uint32 color,float depth,uint32 stencil,SVGA3dRect ** rects,uint32 numRects)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
SVGA3D_ClearRect(struct svga_winsys_context * swc,SVGA3dClearFlag flags,uint32 color,float depth,uint32 stencil,uint32 x,uint32 y,uint32 w,uint32 h)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
SVGA3D_BeginDrawPrimitives(struct svga_winsys_context * swc,SVGA3dVertexDecl ** decls,uint32 numVertexDecls,SVGA3dPrimitiveRange ** ranges,uint32 numRanges)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
SVGA3D_BeginSurfaceCopy(struct svga_winsys_context * swc,struct pipe_surface * src,struct pipe_surface * dest,SVGA3dCopyBox ** boxes,uint32 numBoxes)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
SVGA3D_SurfaceStretchBlt(struct svga_winsys_context * swc,struct pipe_surface * src,struct pipe_surface * dest,SVGA3dBox * boxSrc,SVGA3dBox * boxDest,SVGA3dStretchBltMode mode)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
SVGA3D_SetViewport(struct svga_winsys_context * swc,SVGA3dRect * rect)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
SVGA3D_SetScissorRect(struct svga_winsys_context * swc,SVGA3dRect * rect)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
SVGA3D_SetClipPlane(struct svga_winsys_context * swc,uint32 index,const float * plane)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
SVGA3D_SetZRange(struct svga_winsys_context * swc,float zMin,float zMax)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
SVGA3D_BeginSetTextureState(struct svga_winsys_context * swc,SVGA3dTextureState ** states,uint32 numStates)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
SVGA3D_BeginSetRenderState(struct svga_winsys_context * swc,SVGA3dRenderState ** states,uint32 numStates)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
SVGA3D_BeginGBQuery(struct svga_winsys_context * swc,SVGA3dQueryType type)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
SVGA3D_BeginQuery(struct svga_winsys_context * swc,SVGA3dQueryType type)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
SVGA3D_EndGBQuery(struct svga_winsys_context * swc,SVGA3dQueryType type,struct svga_winsys_buffer * buffer)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
SVGA3D_EndQuery(struct svga_winsys_context * swc,SVGA3dQueryType type,struct svga_winsys_buffer * buffer)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
SVGA3D_WaitForGBQuery(struct svga_winsys_context * swc,SVGA3dQueryType type,struct svga_winsys_buffer * buffer)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
SVGA3D_WaitForQuery(struct svga_winsys_context * swc,SVGA3dQueryType type,struct svga_winsys_buffer * buffer)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
SVGA3D_BindGBShader(struct svga_winsys_context * swc,struct svga_winsys_gb_shader * gbshader)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
SVGA3D_SetGBShader(struct svga_winsys_context * swc,SVGA3dShaderType type,struct svga_winsys_gb_shader * gbshader)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
SVGA3D_BindGBSurface(struct svga_winsys_context * swc,struct svga_winsys_surface * surface)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
SVGA3D_UpdateGBImage(struct svga_winsys_context * swc,struct svga_winsys_surface * surface,const SVGA3dBox * box,unsigned face,unsigned mipLevel)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
SVGA3D_UpdateGBSurface(struct svga_winsys_context * swc,struct svga_winsys_surface * surface)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
SVGA3D_ReadbackGBImage(struct svga_winsys_context * swc,struct svga_winsys_surface * surface,unsigned face,unsigned mipLevel)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
SVGA3D_ReadbackGBSurface(struct svga_winsys_context * swc,struct svga_winsys_surface * surface)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
SVGA3D_ReadbackGBImagePartial(struct svga_winsys_context * swc,struct svga_winsys_surface * surface,unsigned face,unsigned mipLevel,const SVGA3dBox * box,bool invertBox)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
SVGA3D_InvalidateGBImagePartial(struct svga_winsys_context * swc,struct svga_winsys_surface * surface,unsigned face,unsigned mipLevel,const SVGA3dBox * box,bool invertBox)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
SVGA3D_InvalidateGBSurface(struct svga_winsys_context * swc,struct svga_winsys_surface * surface)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
SVGA3D_SetGBShaderConstsInline(struct svga_winsys_context * swc,unsigned regStart,unsigned numRegs,SVGA3dShaderType shaderType,SVGA3dShaderConstType constType,const void * values)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