svga: SVGA_3D_CMD_BIND_GB_SHADER needs to reserve two relocations.
[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_face; /* 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->face; /* 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 cmd = SVGA3D_FIFOReserve(swc,
846 SVGA_3D_CMD_SET_SHADER, sizeof *cmd,
847 0);
848 if (!cmd)
849 return PIPE_ERROR_OUT_OF_MEMORY;
850
851 cmd->cid = swc->cid;
852 cmd->type = type;
853 cmd->shid = shid;
854 swc->commit(swc);
855
856 return PIPE_OK;
857 }
858
859
860 /*
861 *----------------------------------------------------------------------
862 *
863 * SVGA3D_BeginClear --
864 *
865 * Begin a CLEAR command. This reserves space for it in the FIFO,
866 * and returns a pointer to the command's rectangle array. This
867 * function must be paired with SVGA_FIFOCommitAll().
868 *
869 * Clear is a rendering operation which fills a list of
870 * rectangles with constant values on all render target types
871 * indicated by 'flags'.
872 *
873 * Clear is not affected by clipping, depth test, or other
874 * render state which affects the fragment pipeline.
875 *
876 * Results:
877 * None.
878 *
879 * Side effects:
880 * May write to attached render target surfaces.
881 *
882 *----------------------------------------------------------------------
883 */
884
885 enum pipe_error
886 SVGA3D_BeginClear(struct svga_winsys_context *swc,
887 SVGA3dClearFlag flags, // IN
888 uint32 color, // IN
889 float depth, // IN
890 uint32 stencil, // IN
891 SVGA3dRect **rects, // OUT
892 uint32 numRects) // IN
893 {
894 SVGA3dCmdClear *cmd;
895
896 cmd = SVGA3D_FIFOReserve(swc,
897 SVGA_3D_CMD_CLEAR,
898 sizeof *cmd + sizeof **rects * numRects,
899 0);
900 if (!cmd)
901 return PIPE_ERROR_OUT_OF_MEMORY;
902
903 cmd->cid = swc->cid;
904 cmd->clearFlag = flags;
905 cmd->color = color;
906 cmd->depth = depth;
907 cmd->stencil = stencil;
908 *rects = (SVGA3dRect*) &cmd[1];
909
910 return PIPE_OK;
911 }
912
913
914 /*
915 *----------------------------------------------------------------------
916 *
917 * SVGA3D_ClearRect --
918 *
919 * This is a simplified version of SVGA3D_BeginClear().
920 *
921 * Results:
922 * None.
923 *
924 * Side effects:
925 * None.
926 *
927 *----------------------------------------------------------------------
928 */
929
930 enum pipe_error
931 SVGA3D_ClearRect(struct svga_winsys_context *swc,
932 SVGA3dClearFlag flags, // IN
933 uint32 color, // IN
934 float depth, // IN
935 uint32 stencil, // IN
936 uint32 x, // IN
937 uint32 y, // IN
938 uint32 w, // IN
939 uint32 h) // IN
940 {
941 SVGA3dRect *rect;
942 enum pipe_error ret;
943
944 ret = SVGA3D_BeginClear(swc, flags, color, depth, stencil, &rect, 1);
945 if (ret != PIPE_OK)
946 return PIPE_ERROR_OUT_OF_MEMORY;
947
948 memset(rect, 0, sizeof *rect);
949 rect->x = x;
950 rect->y = y;
951 rect->w = w;
952 rect->h = h;
953 swc->commit(swc);
954
955 return PIPE_OK;
956 }
957
958
959 /*
960 *----------------------------------------------------------------------
961 *
962 * SVGA3D_BeginDrawPrimitives --
963 *
964 * Begin a DRAW_PRIMITIVES command. This reserves space for it in
965 * the FIFO, and returns a pointer to the command's arrays.
966 * This function must be paired with SVGA_FIFOCommitAll().
967 *
968 * Drawing commands consist of two variable-length arrays:
969 * SVGA3dVertexDecl elements declare a set of vertex buffers to
970 * use while rendering, and SVGA3dPrimitiveRange elements specify
971 * groups of primitives each with an optional index buffer.
972 *
973 * The decls and ranges arrays are initialized to zero.
974 *
975 * Results:
976 * None.
977 *
978 * Side effects:
979 * May write to attached render target surfaces.
980 *
981 *----------------------------------------------------------------------
982 */
983
984 enum pipe_error
985 SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc,
986 SVGA3dVertexDecl **decls, // OUT
987 uint32 numVertexDecls, // IN
988 SVGA3dPrimitiveRange **ranges, // OUT
989 uint32 numRanges) // IN
990 {
991 SVGA3dCmdDrawPrimitives *cmd;
992 SVGA3dVertexDecl *declArray;
993 SVGA3dPrimitiveRange *rangeArray;
994 uint32 declSize = sizeof **decls * numVertexDecls;
995 uint32 rangeSize = sizeof **ranges * numRanges;
996
997 cmd = SVGA3D_FIFOReserve(swc,
998 SVGA_3D_CMD_DRAW_PRIMITIVES,
999 sizeof *cmd + declSize + rangeSize,
1000 numVertexDecls + numRanges);
1001 if (!cmd)
1002 return PIPE_ERROR_OUT_OF_MEMORY;
1003
1004 cmd->cid = swc->cid;
1005 cmd->numVertexDecls = numVertexDecls;
1006 cmd->numRanges = numRanges;
1007
1008 declArray = (SVGA3dVertexDecl*) &cmd[1];
1009 rangeArray = (SVGA3dPrimitiveRange*) &declArray[numVertexDecls];
1010
1011 memset(declArray, 0, declSize);
1012 memset(rangeArray, 0, rangeSize);
1013
1014 *decls = declArray;
1015 *ranges = rangeArray;
1016
1017 return PIPE_OK;
1018 }
1019
1020
1021 /*
1022 *----------------------------------------------------------------------
1023 *
1024 * SVGA3D_BeginSurfaceCopy --
1025 *
1026 * Begin a SURFACE_COPY command. This reserves space for it in
1027 * the FIFO, and returns a pointer to the command's arrays. This
1028 * function must be paired with SVGA_FIFOCommitAll().
1029 *
1030 * The box array is initialized with zeroes.
1031 *
1032 * Results:
1033 * None.
1034 *
1035 * Side effects:
1036 * Asynchronously copies a list of boxes from surface to surface.
1037 *
1038 *----------------------------------------------------------------------
1039 */
1040
1041 enum pipe_error
1042 SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc,
1043 struct pipe_surface *src, // IN
1044 struct pipe_surface *dest, // IN
1045 SVGA3dCopyBox **boxes, // OUT
1046 uint32 numBoxes) // IN
1047 {
1048 SVGA3dCmdSurfaceCopy *cmd;
1049 uint32 boxesSize = sizeof **boxes * numBoxes;
1050
1051 cmd = SVGA3D_FIFOReserve(swc,
1052 SVGA_3D_CMD_SURFACE_COPY, sizeof *cmd + boxesSize,
1053 2);
1054 if (!cmd)
1055 return PIPE_ERROR_OUT_OF_MEMORY;
1056
1057 surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
1058 surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
1059 *boxes = (SVGA3dCopyBox*) &cmd[1];
1060
1061 memset(*boxes, 0, boxesSize);
1062
1063 return PIPE_OK;
1064 }
1065
1066
1067 /*
1068 *----------------------------------------------------------------------
1069 *
1070 * SVGA3D_SurfaceStretchBlt --
1071 *
1072 * Issue a SURFACE_STRETCHBLT command: an asynchronous
1073 * surface-to-surface blit, with scaling.
1074 *
1075 * Results:
1076 * None.
1077 *
1078 * Side effects:
1079 * Asynchronously copies one box from surface to surface.
1080 *
1081 *----------------------------------------------------------------------
1082 */
1083
1084 enum pipe_error
1085 SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc,
1086 struct pipe_surface *src, // IN
1087 struct pipe_surface *dest, // IN
1088 SVGA3dBox *boxSrc, // IN
1089 SVGA3dBox *boxDest, // IN
1090 SVGA3dStretchBltMode mode) // IN
1091 {
1092 SVGA3dCmdSurfaceStretchBlt *cmd;
1093
1094 cmd = SVGA3D_FIFOReserve(swc,
1095 SVGA_3D_CMD_SURFACE_STRETCHBLT, sizeof *cmd,
1096 2);
1097 if (!cmd)
1098 return PIPE_ERROR_OUT_OF_MEMORY;
1099
1100 surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
1101 surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
1102 cmd->boxSrc = *boxSrc;
1103 cmd->boxDest = *boxDest;
1104 cmd->mode = mode;
1105 swc->commit(swc);
1106
1107 return PIPE_OK;
1108 }
1109
1110
1111 /*
1112 *----------------------------------------------------------------------
1113 *
1114 * SVGA3D_SetViewport --
1115 *
1116 * Set the current context's viewport rectangle. The viewport
1117 * is clipped to the dimensions of the current render target,
1118 * then all rendering is clipped to the viewport.
1119 *
1120 * Results:
1121 * None.
1122 *
1123 * Side effects:
1124 * None.
1125 *
1126 *----------------------------------------------------------------------
1127 */
1128
1129 enum pipe_error
1130 SVGA3D_SetViewport(struct svga_winsys_context *swc,
1131 SVGA3dRect *rect) // IN
1132 {
1133 SVGA3dCmdSetViewport *cmd;
1134
1135 cmd = SVGA3D_FIFOReserve(swc,
1136 SVGA_3D_CMD_SETVIEWPORT, sizeof *cmd,
1137 0);
1138 if (!cmd)
1139 return PIPE_ERROR_OUT_OF_MEMORY;
1140
1141 cmd->cid = swc->cid;
1142 cmd->rect = *rect;
1143 swc->commit(swc);
1144
1145 return PIPE_OK;
1146 }
1147
1148
1149
1150
1151 /*
1152 *----------------------------------------------------------------------
1153 *
1154 * SVGA3D_SetScissorRect --
1155 *
1156 * Set the current context's scissor rectangle. If scissoring
1157 * is enabled then all rendering is clipped to the scissor bounds.
1158 *
1159 * Results:
1160 * None.
1161 *
1162 * Side effects:
1163 * None.
1164 *
1165 *----------------------------------------------------------------------
1166 */
1167
1168 enum pipe_error
1169 SVGA3D_SetScissorRect(struct svga_winsys_context *swc,
1170 SVGA3dRect *rect) // IN
1171 {
1172 SVGA3dCmdSetScissorRect *cmd;
1173
1174 cmd = SVGA3D_FIFOReserve(swc,
1175 SVGA_3D_CMD_SETSCISSORRECT, sizeof *cmd,
1176 0);
1177 if (!cmd)
1178 return PIPE_ERROR_OUT_OF_MEMORY;
1179
1180 cmd->cid = swc->cid;
1181 cmd->rect = *rect;
1182 swc->commit(swc);
1183
1184 return PIPE_OK;
1185 }
1186
1187 /*
1188 *----------------------------------------------------------------------
1189 *
1190 * SVGA3D_SetClipPlane --
1191 *
1192 * Set one of the current context's clip planes. If the clip
1193 * plane is enabled then all 3d rendering is clipped against
1194 * the plane.
1195 *
1196 * Results:
1197 * None.
1198 *
1199 * Side effects:
1200 * None.
1201 *
1202 *----------------------------------------------------------------------
1203 */
1204
1205 enum pipe_error
1206 SVGA3D_SetClipPlane(struct svga_winsys_context *swc,
1207 uint32 index, const float *plane)
1208 {
1209 SVGA3dCmdSetClipPlane *cmd;
1210
1211 cmd = SVGA3D_FIFOReserve(swc,
1212 SVGA_3D_CMD_SETCLIPPLANE, sizeof *cmd,
1213 0);
1214 if (!cmd)
1215 return PIPE_ERROR_OUT_OF_MEMORY;
1216
1217 cmd->cid = swc->cid;
1218 cmd->index = index;
1219 cmd->plane[0] = plane[0];
1220 cmd->plane[1] = plane[1];
1221 cmd->plane[2] = plane[2];
1222 cmd->plane[3] = plane[3];
1223 swc->commit(swc);
1224
1225 return PIPE_OK;
1226 }
1227
1228 /*
1229 *----------------------------------------------------------------------
1230 *
1231 * SVGA3D_SetZRange --
1232 *
1233 * Set the range of the depth buffer to use. 'min' and 'max'
1234 * are values between 0.0 and 1.0.
1235 *
1236 * Results:
1237 * None.
1238 *
1239 * Side effects:
1240 * None.
1241 *
1242 *----------------------------------------------------------------------
1243 */
1244
1245 enum pipe_error
1246 SVGA3D_SetZRange(struct svga_winsys_context *swc,
1247 float zMin, // IN
1248 float zMax) // IN
1249 {
1250 SVGA3dCmdSetZRange *cmd;
1251
1252 cmd = SVGA3D_FIFOReserve(swc,
1253 SVGA_3D_CMD_SETZRANGE, sizeof *cmd,
1254 0);
1255 if (!cmd)
1256 return PIPE_ERROR_OUT_OF_MEMORY;
1257
1258 cmd->cid = swc->cid;
1259 cmd->zRange.min = zMin;
1260 cmd->zRange.max = zMax;
1261 swc->commit(swc);
1262
1263 return PIPE_OK;
1264 }
1265
1266
1267 /*
1268 *----------------------------------------------------------------------
1269 *
1270 * SVGA3D_BeginSetTextureState --
1271 *
1272 * Begin a SETTEXTURESTATE command. This reserves space for it in
1273 * the FIFO, and returns a pointer to the command's texture state
1274 * array. This function must be paired with SVGA_FIFOCommitAll().
1275 *
1276 * This command sets rendering state which is per-texture-unit.
1277 *
1278 * XXX: Individual texture states need documentation. However,
1279 * they are very similar to the texture states defined by
1280 * Direct3D. The D3D documentation is a good starting point
1281 * for understanding SVGA3D texture states.
1282 *
1283 * Results:
1284 * None.
1285 *
1286 * Side effects:
1287 * None.
1288 *
1289 *----------------------------------------------------------------------
1290 */
1291
1292 enum pipe_error
1293 SVGA3D_BeginSetTextureState(struct svga_winsys_context *swc,
1294 SVGA3dTextureState **states, // OUT
1295 uint32 numStates) // IN
1296 {
1297 SVGA3dCmdSetTextureState *cmd;
1298
1299 cmd = SVGA3D_FIFOReserve(swc,
1300 SVGA_3D_CMD_SETTEXTURESTATE,
1301 sizeof *cmd + sizeof **states * numStates,
1302 numStates);
1303 if (!cmd)
1304 return PIPE_ERROR_OUT_OF_MEMORY;
1305
1306 cmd->cid = swc->cid;
1307 *states = (SVGA3dTextureState*) &cmd[1];
1308
1309 return PIPE_OK;
1310 }
1311
1312
1313 /*
1314 *----------------------------------------------------------------------
1315 *
1316 * SVGA3D_BeginSetRenderState --
1317 *
1318 * Begin a SETRENDERSTATE command. This reserves space for it in
1319 * the FIFO, and returns a pointer to the command's texture state
1320 * array. This function must be paired with SVGA_FIFOCommitAll().
1321 *
1322 * This command sets rendering state which is global to the context.
1323 *
1324 * XXX: Individual render states need documentation. However,
1325 * they are very similar to the render states defined by
1326 * Direct3D. The D3D documentation is a good starting point
1327 * for understanding SVGA3D render states.
1328 *
1329 * Results:
1330 * None.
1331 *
1332 * Side effects:
1333 * None.
1334 *
1335 *----------------------------------------------------------------------
1336 */
1337
1338 enum pipe_error
1339 SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc,
1340 SVGA3dRenderState **states, // OUT
1341 uint32 numStates) // IN
1342 {
1343 SVGA3dCmdSetRenderState *cmd;
1344
1345 cmd = SVGA3D_FIFOReserve(swc,
1346 SVGA_3D_CMD_SETRENDERSTATE,
1347 sizeof *cmd + sizeof **states * numStates,
1348 0);
1349 if (!cmd)
1350 return PIPE_ERROR_OUT_OF_MEMORY;
1351
1352 cmd->cid = swc->cid;
1353 *states = (SVGA3dRenderState*) &cmd[1];
1354
1355 return PIPE_OK;
1356 }
1357
1358
1359 /*
1360 *----------------------------------------------------------------------
1361 *
1362 * SVGA3D_BeginGBQuery--
1363 *
1364 * GB resource version of SVGA3D_BeginQuery.
1365 *
1366 * Results:
1367 * None.
1368 *
1369 * Side effects:
1370 * Commits space in the FIFO memory.
1371 *
1372 *----------------------------------------------------------------------
1373 */
1374
1375 static enum pipe_error
1376 SVGA3D_BeginGBQuery(struct svga_winsys_context *swc,
1377 SVGA3dQueryType type) // IN
1378 {
1379 SVGA3dCmdBeginGBQuery *cmd;
1380
1381 cmd = SVGA3D_FIFOReserve(swc,
1382 SVGA_3D_CMD_BEGIN_GB_QUERY,
1383 sizeof *cmd,
1384 1);
1385 if(!cmd)
1386 return PIPE_ERROR_OUT_OF_MEMORY;
1387
1388 swc->context_relocation(swc, &cmd->cid);
1389 cmd->type = type;
1390
1391 swc->commit(swc);
1392
1393 return PIPE_OK;
1394 }
1395
1396
1397 /*
1398 *----------------------------------------------------------------------
1399 *
1400 * SVGA3D_BeginQuery--
1401 *
1402 * Issues a SVGA_3D_CMD_BEGIN_QUERY command.
1403 *
1404 * Results:
1405 * None.
1406 *
1407 * Side effects:
1408 * Commits space in the FIFO memory.
1409 *
1410 *----------------------------------------------------------------------
1411 */
1412
1413 enum pipe_error
1414 SVGA3D_BeginQuery(struct svga_winsys_context *swc,
1415 SVGA3dQueryType type) // IN
1416 {
1417 SVGA3dCmdBeginQuery *cmd;
1418
1419 if (swc->have_gb_objects)
1420 return SVGA3D_BeginGBQuery(swc, type);
1421
1422 cmd = SVGA3D_FIFOReserve(swc,
1423 SVGA_3D_CMD_BEGIN_QUERY,
1424 sizeof *cmd,
1425 0);
1426 if (!cmd)
1427 return PIPE_ERROR_OUT_OF_MEMORY;
1428
1429 cmd->cid = swc->cid;
1430 cmd->type = type;
1431
1432 swc->commit(swc);
1433
1434 return PIPE_OK;
1435 }
1436
1437
1438 /*
1439 *----------------------------------------------------------------------
1440 *
1441 * SVGA3D_EndGBQuery--
1442 *
1443 * GB resource version of SVGA3D_EndQuery.
1444 *
1445 * Results:
1446 * None.
1447 *
1448 * Side effects:
1449 * Commits space in the FIFO memory.
1450 *
1451 *----------------------------------------------------------------------
1452 */
1453
1454 static enum pipe_error
1455 SVGA3D_EndGBQuery(struct svga_winsys_context *swc,
1456 SVGA3dQueryType type, // IN
1457 struct svga_winsys_buffer *buffer) // IN/OUT
1458 {
1459 SVGA3dCmdEndGBQuery *cmd;
1460
1461 cmd = SVGA3D_FIFOReserve(swc,
1462 SVGA_3D_CMD_END_GB_QUERY,
1463 sizeof *cmd,
1464 2);
1465 if(!cmd)
1466 return PIPE_ERROR_OUT_OF_MEMORY;
1467
1468 swc->context_relocation(swc, &cmd->cid);
1469 cmd->type = type;
1470
1471 swc->mob_relocation(swc, &cmd->mobid, &cmd->offset, buffer,
1472 0, SVGA_RELOC_READ | SVGA_RELOC_WRITE);
1473
1474 swc->commit(swc);
1475
1476 return PIPE_OK;
1477 }
1478
1479
1480 /*
1481 *----------------------------------------------------------------------
1482 *
1483 * SVGA3D_EndQuery--
1484 *
1485 * Issues a SVGA_3D_CMD_END_QUERY command.
1486 *
1487 * Results:
1488 * None.
1489 *
1490 * Side effects:
1491 * Commits space in the FIFO memory.
1492 *
1493 *----------------------------------------------------------------------
1494 */
1495
1496 enum pipe_error
1497 SVGA3D_EndQuery(struct svga_winsys_context *swc,
1498 SVGA3dQueryType type, // IN
1499 struct svga_winsys_buffer *buffer) // IN/OUT
1500 {
1501 SVGA3dCmdEndQuery *cmd;
1502
1503 if (swc->have_gb_objects)
1504 return SVGA3D_EndGBQuery(swc, type, buffer);
1505
1506 cmd = SVGA3D_FIFOReserve(swc,
1507 SVGA_3D_CMD_END_QUERY,
1508 sizeof *cmd,
1509 1);
1510 if (!cmd)
1511 return PIPE_ERROR_OUT_OF_MEMORY;
1512
1513 cmd->cid = swc->cid;
1514 cmd->type = type;
1515
1516 swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
1517 SVGA_RELOC_READ | SVGA_RELOC_WRITE);
1518
1519 swc->commit(swc);
1520
1521 return PIPE_OK;
1522 }
1523
1524
1525 /*
1526 *----------------------------------------------------------------------
1527 *
1528 * SVGA3D_WaitForGBQuery--
1529 *
1530 * GB resource version of SVGA3D_WaitForQuery.
1531 *
1532 * Results:
1533 * None.
1534 *
1535 * Side effects:
1536 * Commits space in the FIFO memory.
1537 *
1538 *----------------------------------------------------------------------
1539 */
1540
1541 static enum pipe_error
1542 SVGA3D_WaitForGBQuery(struct svga_winsys_context *swc,
1543 SVGA3dQueryType type, // IN
1544 struct svga_winsys_buffer *buffer) // IN/OUT
1545 {
1546 SVGA3dCmdWaitForGBQuery *cmd;
1547
1548 cmd = SVGA3D_FIFOReserve(swc,
1549 SVGA_3D_CMD_WAIT_FOR_GB_QUERY,
1550 sizeof *cmd,
1551 2);
1552 if(!cmd)
1553 return PIPE_ERROR_OUT_OF_MEMORY;
1554
1555 swc->context_relocation(swc, &cmd->cid);
1556 cmd->type = type;
1557
1558 swc->mob_relocation(swc, &cmd->mobid, &cmd->offset, buffer,
1559 0, SVGA_RELOC_READ | SVGA_RELOC_WRITE);
1560
1561 swc->commit(swc);
1562
1563 return PIPE_OK;
1564 }
1565
1566
1567 /*
1568 *----------------------------------------------------------------------
1569 *
1570 * SVGA3D_WaitForQuery--
1571 *
1572 * Issues a SVGA_3D_CMD_WAIT_FOR_QUERY command. This reserves space
1573 * for it in the FIFO. This doesn't actually wait for the query to
1574 * finish but instead tells the host to start a wait at the driver
1575 * level. The caller can wait on the status variable in the
1576 * guestPtr memory or send an insert fence instruction after this
1577 * command and wait on the fence.
1578 *
1579 * Results:
1580 * None.
1581 *
1582 * Side effects:
1583 * Commits space in the FIFO memory.
1584 *
1585 *----------------------------------------------------------------------
1586 */
1587
1588 enum pipe_error
1589 SVGA3D_WaitForQuery(struct svga_winsys_context *swc,
1590 SVGA3dQueryType type, // IN
1591 struct svga_winsys_buffer *buffer) // IN/OUT
1592 {
1593 SVGA3dCmdWaitForQuery *cmd;
1594
1595 if (swc->have_gb_objects)
1596 return SVGA3D_WaitForGBQuery(swc, type, buffer);
1597
1598 cmd = SVGA3D_FIFOReserve(swc,
1599 SVGA_3D_CMD_WAIT_FOR_QUERY,
1600 sizeof *cmd,
1601 1);
1602 if (!cmd)
1603 return PIPE_ERROR_OUT_OF_MEMORY;
1604
1605 cmd->cid = swc->cid;
1606 cmd->type = type;
1607
1608 swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
1609 SVGA_RELOC_READ | SVGA_RELOC_WRITE);
1610
1611 swc->commit(swc);
1612
1613 return PIPE_OK;
1614 }
1615
1616
1617 enum pipe_error
1618 SVGA3D_DefineGBShader(struct svga_winsys_context *swc,
1619 struct svga_winsys_gb_shader *gbshader,
1620 SVGA3dShaderType type,
1621 uint32 sizeInBytes)
1622 {
1623 SVGA3dCmdDefineGBShader *cmd;
1624
1625 assert(sizeInBytes % 4 == 0);
1626 assert(type == SVGA3D_SHADERTYPE_VS ||
1627 type == SVGA3D_SHADERTYPE_PS);
1628
1629 cmd = SVGA3D_FIFOReserve(swc,
1630 SVGA_3D_CMD_DEFINE_GB_SHADER,
1631 sizeof *cmd,
1632 1); /* one relocation */
1633
1634 if (!cmd)
1635 return PIPE_ERROR_OUT_OF_MEMORY;
1636
1637 swc->shader_relocation(swc, &cmd->shid, NULL, NULL, gbshader);
1638 cmd->type = type;
1639 cmd->sizeInBytes = sizeInBytes;
1640
1641 swc->commit(swc);
1642
1643 return PIPE_OK;
1644 }
1645
1646
1647 enum pipe_error
1648 SVGA3D_BindGBShader(struct svga_winsys_context *swc,
1649 struct svga_winsys_gb_shader *gbshader)
1650 {
1651 SVGA3dCmdBindGBShader *cmd =
1652 SVGA3D_FIFOReserve(swc,
1653 SVGA_3D_CMD_BIND_GB_SHADER,
1654 sizeof *cmd,
1655 2); /* two relocations */
1656
1657 if (!cmd)
1658 return PIPE_ERROR_OUT_OF_MEMORY;
1659
1660 swc->shader_relocation(swc, &cmd->shid, &cmd->mobid,
1661 &cmd->offsetInBytes, gbshader);
1662
1663 swc->commit(swc);
1664
1665 return PIPE_OK;
1666 }
1667
1668
1669 enum pipe_error
1670 SVGA3D_SetGBShader(struct svga_winsys_context *swc,
1671 SVGA3dShaderType type, // IN
1672 struct svga_winsys_gb_shader *gbshader)
1673 {
1674 SVGA3dCmdSetShader *cmd;
1675
1676 cmd = SVGA3D_FIFOReserve(swc,
1677 SVGA_3D_CMD_SET_SHADER,
1678 sizeof *cmd,
1679 2); /* two relocations */
1680 if (!cmd)
1681 return PIPE_ERROR_OUT_OF_MEMORY;
1682
1683 swc->context_relocation(swc, &cmd->cid);
1684 cmd->type = type;
1685 if (gbshader)
1686 swc->shader_relocation(swc, &cmd->shid, NULL, NULL, gbshader);
1687 else
1688 cmd->shid = SVGA_ID_INVALID;
1689 swc->commit(swc);
1690
1691 return PIPE_OK;
1692 }
1693
1694
1695 enum pipe_error
1696 SVGA3D_DestroyGBShader(struct svga_winsys_context *swc,
1697 struct svga_winsys_gb_shader *gbshader)
1698 {
1699 SVGA3dCmdDestroyGBShader *cmd =
1700 SVGA3D_FIFOReserve(swc,
1701 SVGA_3D_CMD_DESTROY_GB_SHADER,
1702 sizeof *cmd,
1703 1); /* one relocation */
1704
1705 if (!cmd)
1706 return PIPE_ERROR_OUT_OF_MEMORY;
1707
1708 swc->shader_relocation(swc, &cmd->shid, NULL, NULL, gbshader);
1709
1710 swc->commit(swc);
1711
1712 return PIPE_OK;
1713 }
1714
1715
1716 /**
1717 * \param flags mask of SVGA_RELOC_READ / _WRITE
1718 */
1719 enum pipe_error
1720 SVGA3D_BindGBSurface(struct svga_winsys_context *swc,
1721 struct svga_winsys_surface *surface)
1722 {
1723 SVGA3dCmdBindGBSurface *cmd =
1724 SVGA3D_FIFOReserve(swc,
1725 SVGA_3D_CMD_BIND_GB_SURFACE,
1726 sizeof *cmd,
1727 2); /* two relocations */
1728
1729 if (!cmd)
1730 return PIPE_ERROR_OUT_OF_MEMORY;
1731
1732 swc->surface_relocation(swc, &cmd->sid, &cmd->mobid, surface,
1733 SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
1734
1735 swc->commit(swc);
1736
1737 return PIPE_OK;
1738 }
1739
1740
1741 enum pipe_error
1742 SVGA3D_DefineGBContext(struct svga_winsys_context *swc)
1743 {
1744 SVGA3dCmdDefineGBContext *cmd =
1745 SVGA3D_FIFOReserve(swc,
1746 SVGA_3D_CMD_DEFINE_GB_CONTEXT,
1747 sizeof *cmd,
1748 1); /* one relocation */
1749
1750 if (!cmd)
1751 return PIPE_ERROR_OUT_OF_MEMORY;
1752
1753 swc->context_relocation(swc, &cmd->cid);
1754
1755 swc->commit(swc);
1756
1757 return PIPE_OK;
1758 }
1759
1760
1761 enum pipe_error
1762 SVGA3D_DestroyGBContext(struct svga_winsys_context *swc)
1763 {
1764 SVGA3dCmdDestroyGBContext *cmd =
1765 SVGA3D_FIFOReserve(swc,
1766 SVGA_3D_CMD_DESTROY_GB_CONTEXT,
1767 sizeof *cmd,
1768 1); /* one relocation */
1769
1770 if (!cmd)
1771 return PIPE_ERROR_OUT_OF_MEMORY;
1772
1773 swc->context_relocation(swc, &cmd->cid);
1774
1775 swc->commit(swc);
1776
1777 return PIPE_OK;
1778 }
1779
1780
1781 enum pipe_error
1782 SVGA3D_BindGBContext(struct svga_winsys_context *swc)
1783 {
1784 SVGA3dCmdBindGBContext *cmd =
1785 SVGA3D_FIFOReserve(swc,
1786 SVGA_3D_CMD_BIND_GB_CONTEXT,
1787 sizeof *cmd,
1788 2); /* two relocations */
1789
1790 if (!cmd)
1791 return PIPE_ERROR_OUT_OF_MEMORY;
1792
1793 swc->context_relocation(swc, &cmd->cid);
1794 swc->context_relocation(swc, &cmd->mobid);
1795 cmd->validContents = 0; /* XXX pass as a parameter? */
1796
1797 swc->commit(swc);
1798
1799 return PIPE_OK;
1800 }
1801
1802
1803 enum pipe_error
1804 SVGA3D_InvalidateGBContext(struct svga_winsys_context *swc)
1805 {
1806 SVGA3dCmdInvalidateGBContext *cmd =
1807 SVGA3D_FIFOReserve(swc,
1808 SVGA_3D_CMD_INVALIDATE_GB_CONTEXT,
1809 sizeof *cmd,
1810 1); /* one relocation */
1811
1812 if (!cmd)
1813 return PIPE_ERROR_OUT_OF_MEMORY;
1814
1815 swc->context_relocation(swc, &cmd->cid);
1816
1817 swc->commit(swc);
1818
1819 return PIPE_OK;
1820 }
1821
1822
1823
1824 /**
1825 * Update an image in a guest-backed surface.
1826 * (Inform the device that the guest-contents have been updated.)
1827 */
1828 enum pipe_error
1829 SVGA3D_UpdateGBImage(struct svga_winsys_context *swc,
1830 struct svga_winsys_surface *surface,
1831 const SVGA3dBox *box,
1832 unsigned face, unsigned mipLevel)
1833
1834 {
1835 SVGA3dCmdUpdateGBImage *cmd =
1836 SVGA3D_FIFOReserve(swc,
1837 SVGA_3D_CMD_UPDATE_GB_IMAGE,
1838 sizeof *cmd,
1839 1); /* one relocation */
1840
1841 if (!cmd)
1842 return PIPE_ERROR_OUT_OF_MEMORY;
1843
1844 swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
1845 SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
1846 cmd->image.face = face;
1847 cmd->image.mipmap = mipLevel;
1848 cmd->box = *box;
1849
1850 swc->commit(swc);
1851
1852 return PIPE_OK;
1853 }
1854
1855
1856 /**
1857 * Update an entire guest-backed surface.
1858 * (Inform the device that the guest-contents have been updated.)
1859 */
1860 enum pipe_error
1861 SVGA3D_UpdateGBSurface(struct svga_winsys_context *swc,
1862 struct svga_winsys_surface *surface)
1863 {
1864 SVGA3dCmdUpdateGBSurface *cmd =
1865 SVGA3D_FIFOReserve(swc,
1866 SVGA_3D_CMD_UPDATE_GB_SURFACE,
1867 sizeof *cmd,
1868 1); /* one relocation */
1869
1870 if (!cmd)
1871 return PIPE_ERROR_OUT_OF_MEMORY;
1872
1873 swc->surface_relocation(swc, &cmd->sid, NULL, surface,
1874 SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
1875
1876 swc->commit(swc);
1877
1878 return PIPE_OK;
1879 }
1880
1881
1882 /**
1883 * Readback an image in a guest-backed surface.
1884 * (Request the device to flush the dirty contents into the guest.)
1885 */
1886 enum pipe_error
1887 SVGA3D_ReadbackGBImage(struct svga_winsys_context *swc,
1888 struct svga_winsys_surface *surface,
1889 unsigned face, unsigned mipLevel)
1890 {
1891 SVGA3dCmdReadbackGBImage *cmd =
1892 SVGA3D_FIFOReserve(swc,
1893 SVGA_3D_CMD_READBACK_GB_IMAGE,
1894 sizeof *cmd,
1895 1); /* one relocation */
1896
1897 if (!cmd)
1898 return PIPE_ERROR_OUT_OF_MEMORY;
1899
1900 swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
1901 SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
1902 cmd->image.face = face;
1903 cmd->image.mipmap = mipLevel;
1904
1905 swc->commit(swc);
1906
1907 return PIPE_OK;
1908 }
1909
1910
1911 /**
1912 * Readback an entire guest-backed surface.
1913 * (Request the device to flush the dirty contents into the guest.)
1914 */
1915 enum pipe_error
1916 SVGA3D_ReadbackGBSurface(struct svga_winsys_context *swc,
1917 struct svga_winsys_surface *surface)
1918 {
1919 SVGA3dCmdReadbackGBSurface *cmd =
1920 SVGA3D_FIFOReserve(swc,
1921 SVGA_3D_CMD_READBACK_GB_SURFACE,
1922 sizeof *cmd,
1923 1); /* one relocation */
1924
1925 if (!cmd)
1926 return PIPE_ERROR_OUT_OF_MEMORY;
1927
1928 swc->surface_relocation(swc, &cmd->sid, NULL, surface,
1929 SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
1930
1931 swc->commit(swc);
1932
1933 return PIPE_OK;
1934 }
1935
1936
1937 enum pipe_error
1938 SVGA3D_ReadbackGBImagePartial(struct svga_winsys_context *swc,
1939 struct svga_winsys_surface *surface,
1940 unsigned face, unsigned mipLevel,
1941 const SVGA3dBox *box,
1942 bool invertBox)
1943 {
1944 SVGA3dCmdReadbackGBImagePartial *cmd =
1945 SVGA3D_FIFOReserve(swc,
1946 SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL,
1947 sizeof *cmd,
1948 1); /* one relocation */
1949 if (!cmd)
1950 return PIPE_ERROR_OUT_OF_MEMORY;
1951
1952 swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
1953 SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
1954 cmd->image.face = face;
1955 cmd->image.mipmap = mipLevel;
1956 cmd->box = *box;
1957 cmd->invertBox = invertBox;
1958
1959 swc->commit(swc);
1960
1961 return PIPE_OK;
1962 }
1963
1964
1965 enum pipe_error
1966 SVGA3D_InvalidateGBImagePartial(struct svga_winsys_context *swc,
1967 struct svga_winsys_surface *surface,
1968 unsigned face, unsigned mipLevel,
1969 const SVGA3dBox *box,
1970 bool invertBox)
1971 {
1972 SVGA3dCmdInvalidateGBImagePartial *cmd =
1973 SVGA3D_FIFOReserve(swc,
1974 SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL,
1975 sizeof *cmd,
1976 1); /* one relocation */
1977 if (!cmd)
1978 return PIPE_ERROR_OUT_OF_MEMORY;
1979
1980 swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
1981 SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
1982 cmd->image.face = face;
1983 cmd->image.mipmap = mipLevel;
1984 cmd->box = *box;
1985 cmd->invertBox = invertBox;
1986
1987 swc->commit(swc);
1988
1989 return PIPE_OK;
1990 }
1991
1992
1993 enum pipe_error
1994 SVGA3D_SetGBShaderConstsInline(struct svga_winsys_context *swc,
1995 unsigned regStart,
1996 unsigned numRegs,
1997 SVGA3dShaderType shaderType,
1998 SVGA3dShaderConstType constType,
1999 const void *values)
2000 {
2001 SVGA3dCmdSetGBShaderConstInline *cmd;
2002
2003 assert(numRegs > 0);
2004
2005 cmd = SVGA3D_FIFOReserve(swc,
2006 SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE,
2007 sizeof *cmd + numRegs * sizeof(float[4]),
2008 0); /* no relocations */
2009 if (!cmd)
2010 return PIPE_ERROR_OUT_OF_MEMORY;
2011
2012 cmd->cid = swc->cid;
2013 cmd->regStart = regStart;
2014 cmd->shaderType = shaderType;
2015 cmd->constType = constType;
2016
2017 memcpy(&cmd[1], values, numRegs * sizeof(float[4]));
2018
2019 swc->commit(swc);
2020
2021 return PIPE_OK;
2022 }