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