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