svga: minor code reformatting
[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 * Results:
49 * id is filled out.
50 *
51 * Side effects:
52 * One surface relocation is performed for texture handle.
53 *
54 *----------------------------------------------------------------------
55 */
56
57 static INLINE
58 void surface_to_surfaceid(struct svga_winsys_context *swc, // IN
59 struct pipe_surface *surface, // IN
60 SVGA3dSurfaceImageId *id, // OUT
61 unsigned flags) // IN
62 {
63 if(surface) {
64 struct svga_surface *s = svga_surface(surface);
65 swc->surface_relocation(swc, &id->sid, s->handle, flags);
66 id->face = s->real_face; /* faces have the same order */
67 id->mipmap = s->real_level;
68 }
69 else {
70 swc->surface_relocation(swc, &id->sid, NULL, flags);
71 id->face = 0;
72 id->mipmap = 0;
73 }
74 }
75
76
77 /*
78 *----------------------------------------------------------------------
79 *
80 * SVGA3D_FIFOReserve --
81 *
82 * Reserve space for an SVGA3D FIFO command.
83 *
84 * The 2D SVGA commands have been around for a while, so they
85 * have a rather asymmetric structure. The SVGA3D protocol is
86 * more uniform: each command begins with a header containing the
87 * command number and the full size.
88 *
89 * This is a convenience wrapper around SVGA_FIFOReserve. We
90 * reserve space for the whole command, and write the header.
91 *
92 * This function must be paired with SVGA_FIFOCommitAll().
93 *
94 * Results:
95 * Returns a pointer to the space reserved for command-specific
96 * data. It must be 'cmdSize' bytes long.
97 *
98 * Side effects:
99 * Begins a FIFO reservation.
100 *
101 *----------------------------------------------------------------------
102 */
103
104 void *
105 SVGA3D_FIFOReserve(struct svga_winsys_context *swc,
106 uint32 cmd, // IN
107 uint32 cmdSize, // IN
108 uint32 nr_relocs) // IN
109 {
110 SVGA3dCmdHeader *header;
111
112 header = swc->reserve(swc, sizeof *header + cmdSize, nr_relocs);
113 if(!header)
114 return NULL;
115
116 header->id = cmd;
117 header->size = cmdSize;
118
119 return &header[1];
120 }
121
122
123 void
124 SVGA_FIFOCommitAll(struct svga_winsys_context *swc)
125 {
126 swc->commit(swc);
127 }
128
129
130 /*
131 *----------------------------------------------------------------------
132 *
133 * SVGA3D_DefineContext --
134 *
135 * Create a new context, to be referred to with the provided ID.
136 *
137 * Context objects encapsulate all render state, and shader
138 * objects are per-context.
139 *
140 * Surfaces are not per-context. The same surface can be shared
141 * between multiple contexts, and surface operations can occur
142 * without a context.
143 *
144 * If the provided context ID already existed, it is redefined.
145 *
146 * Context IDs are arbitrary small non-negative integers,
147 * global to the entire SVGA device.
148 *
149 * Results:
150 * None.
151 *
152 * Side effects:
153 * None.
154 *
155 *----------------------------------------------------------------------
156 */
157
158 enum pipe_error
159 SVGA3D_DefineContext(struct svga_winsys_context *swc) // IN
160 {
161 SVGA3dCmdDefineContext *cmd;
162
163 cmd = SVGA3D_FIFOReserve(swc,
164 SVGA_3D_CMD_CONTEXT_DEFINE, sizeof *cmd, 0);
165 if(!cmd)
166 return PIPE_ERROR_OUT_OF_MEMORY;
167
168 cmd->cid = swc->cid;
169
170 swc->commit(swc);
171
172 return PIPE_OK;
173 }
174
175
176 /*
177 *----------------------------------------------------------------------
178 *
179 * SVGA3D_DestroyContext --
180 *
181 * Delete a context created with SVGA3D_DefineContext.
182 *
183 * Results:
184 * None.
185 *
186 * Side effects:
187 * None.
188 *
189 *----------------------------------------------------------------------
190 */
191
192 enum pipe_error
193 SVGA3D_DestroyContext(struct svga_winsys_context *swc) // IN
194 {
195 SVGA3dCmdDestroyContext *cmd;
196
197 cmd = SVGA3D_FIFOReserve(swc,
198 SVGA_3D_CMD_CONTEXT_DESTROY, sizeof *cmd, 0);
199 if(!cmd)
200 return PIPE_ERROR_OUT_OF_MEMORY;
201
202 cmd->cid = swc->cid;
203
204 swc->commit(swc);
205
206 return PIPE_OK;
207 }
208
209
210 /*
211 *----------------------------------------------------------------------
212 *
213 * SVGA3D_BeginDefineSurface --
214 *
215 * Begin a SURFACE_DEFINE command. This reserves space for it in
216 * the FIFO, and returns pointers to the command's faces and
217 * mipsizes arrays.
218 *
219 * This function must be paired with SVGA_FIFOCommitAll().
220 * The faces and mipSizes arrays are initialized to zero.
221 *
222 * This creates a "surface" object in the SVGA3D device,
223 * with the provided surface ID (sid). Surfaces are generic
224 * containers for host VRAM objects like textures, vertex
225 * buffers, and depth/stencil buffers.
226 *
227 * Surfaces are hierarchical:
228 *
229 * - Surface may have multiple faces (for cube maps)
230 *
231 * - Each face has a list of mipmap levels
232 *
233 * - Each mipmap image may have multiple volume
234 * slices, if the image is three dimensional.
235 *
236 * - Each slice is a 2D array of 'blocks'
237 *
238 * - Each block may be one or more pixels.
239 * (Usually 1, more for DXT or YUV formats.)
240 *
241 * Surfaces are generic host VRAM objects. The SVGA3D device
242 * may optimize surfaces according to the format they were
243 * created with, but this format does not limit the ways in
244 * which the surface may be used. For example, a depth surface
245 * can be used as a texture, or a floating point image may
246 * be used as a vertex buffer. Some surface usages may be
247 * lower performance, due to software emulation, but any
248 * usage should work with any surface.
249 *
250 * If 'sid' is already defined, the old surface is deleted
251 * and this new surface replaces it.
252 *
253 * Surface IDs are arbitrary small non-negative integers,
254 * global to the entire SVGA device.
255 *
256 * Results:
257 * Returns pointers to arrays allocated in the FIFO for 'faces'
258 * and 'mipSizes'.
259 *
260 * Side effects:
261 * Begins a FIFO reservation.
262 *
263 *----------------------------------------------------------------------
264 */
265
266 enum pipe_error
267 SVGA3D_BeginDefineSurface(struct svga_winsys_context *swc,
268 struct svga_winsys_surface *sid, // IN
269 SVGA3dSurfaceFlags flags, // IN
270 SVGA3dSurfaceFormat format, // IN
271 SVGA3dSurfaceFace **faces, // OUT
272 SVGA3dSize **mipSizes, // OUT
273 uint32 numMipSizes) // IN
274 {
275 SVGA3dCmdDefineSurface *cmd;
276
277 cmd = SVGA3D_FIFOReserve(swc,
278 SVGA_3D_CMD_SURFACE_DEFINE, sizeof *cmd +
279 sizeof **mipSizes * numMipSizes, 1);
280 if(!cmd)
281 return PIPE_ERROR_OUT_OF_MEMORY;
282
283 swc->surface_relocation(swc, &cmd->sid, sid, SVGA_RELOC_WRITE);
284 cmd->surfaceFlags = flags;
285 cmd->format = format;
286
287 *faces = &cmd->face[0];
288 *mipSizes = (SVGA3dSize*) &cmd[1];
289
290 memset(*faces, 0, sizeof **faces * SVGA3D_MAX_SURFACE_FACES);
291 memset(*mipSizes, 0, sizeof **mipSizes * numMipSizes);
292
293 return PIPE_OK;
294 }
295
296
297 /*
298 *----------------------------------------------------------------------
299 *
300 * SVGA3D_DefineSurface2D --
301 *
302 * This is a simplified version of SVGA3D_BeginDefineSurface(),
303 * which does not support cube maps, mipmaps, or volume textures.
304 *
305 * Results:
306 * None.
307 *
308 * Side effects:
309 * None.
310 *
311 *----------------------------------------------------------------------
312 */
313
314 enum pipe_error
315 SVGA3D_DefineSurface2D(struct svga_winsys_context *swc, // IN
316 struct svga_winsys_surface *sid, // IN
317 uint32 width, // IN
318 uint32 height, // IN
319 SVGA3dSurfaceFormat format) // IN
320 {
321 SVGA3dSize *mipSizes;
322 SVGA3dSurfaceFace *faces;
323 enum pipe_error ret;
324
325 ret = SVGA3D_BeginDefineSurface(swc,
326 sid, 0, format, &faces, &mipSizes, 1);
327 if(ret != PIPE_OK)
328 return ret;
329
330 faces[0].numMipLevels = 1;
331
332 mipSizes[0].width = width;
333 mipSizes[0].height = height;
334 mipSizes[0].depth = 1;
335
336 swc->commit(swc);;
337
338 return PIPE_OK;
339 }
340
341
342 /*
343 *----------------------------------------------------------------------
344 *
345 * SVGA3D_DestroySurface --
346 *
347 * Release the host VRAM encapsulated by a particular surface ID.
348 *
349 * Results:
350 * None.
351 *
352 * Side effects:
353 * None.
354 *
355 *----------------------------------------------------------------------
356 */
357
358 enum pipe_error
359 SVGA3D_DestroySurface(struct svga_winsys_context *swc,
360 struct svga_winsys_surface *sid) // IN
361 {
362 SVGA3dCmdDestroySurface *cmd;
363
364 cmd = SVGA3D_FIFOReserve(swc,
365 SVGA_3D_CMD_SURFACE_DESTROY, sizeof *cmd, 1);
366 if(!cmd)
367 return PIPE_ERROR_OUT_OF_MEMORY;
368
369 swc->surface_relocation(swc, &cmd->sid, sid, SVGA_RELOC_READ);
370 swc->commit(swc);;
371
372 return PIPE_OK;
373 }
374
375
376 /*
377 *----------------------------------------------------------------------
378 *
379 * SVGA3D_SurfaceDMA--
380 *
381 * Emit a SURFACE_DMA command.
382 *
383 * When the SVGA3D device asynchronously processes this FIFO
384 * command, a DMA operation is performed between host VRAM and
385 * a generic SVGAGuestPtr. The guest pointer may refer to guest
386 * VRAM (provided by the SVGA PCI device) or to guest system
387 * memory that has been set up as a Guest Memory Region (GMR)
388 * by the SVGA device.
389 *
390 * The guest's DMA buffer must remain valid (not freed, paged out,
391 * or overwritten) until the host has finished processing this
392 * command. The guest can determine that the host has finished
393 * by using the SVGA device's FIFO Fence mechanism.
394 *
395 * The guest's image buffer can be an arbitrary size and shape.
396 * Guest image data is interpreted according to the SVGA3D surface
397 * format specified when the surface was defined.
398 *
399 * The caller may optionally define the guest image's pitch.
400 * guestImage->pitch can either be zero (assume image is tightly
401 * packed) or it must be the number of bytes between vertically
402 * adjacent image blocks.
403 *
404 * The provided copybox list specifies which regions of the source
405 * image are to be copied, and where they appear on the destination.
406 *
407 * NOTE: srcx/srcy are always on the guest image and x/y are
408 * always on the host image, regardless of the actual transfer
409 * direction!
410 *
411 * For efficiency, the SVGA3D device is free to copy more data
412 * than specified. For example, it may round copy boxes outwards
413 * such that they lie on particular alignment boundaries.
414 *
415 *----------------------------------------------------------------------
416 */
417
418 enum pipe_error
419 SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
420 struct svga_transfer *st, // IN
421 SVGA3dTransferType transfer, // IN
422 const SVGA3dCopyBox *boxes, // IN
423 uint32 numBoxes, // IN
424 SVGA3dSurfaceDMAFlags flags) // IN
425 {
426 struct svga_texture *texture = svga_texture(st->base.resource);
427 SVGA3dCmdSurfaceDMA *cmd;
428 SVGA3dCmdSurfaceDMASuffix *pSuffix;
429 uint32 boxesSize = sizeof *boxes * numBoxes;
430 unsigned region_flags;
431 unsigned surface_flags;
432
433 if(transfer == SVGA3D_WRITE_HOST_VRAM) {
434 region_flags = SVGA_RELOC_READ;
435 surface_flags = SVGA_RELOC_WRITE;
436 }
437 else if(transfer == SVGA3D_READ_HOST_VRAM) {
438 region_flags = SVGA_RELOC_WRITE;
439 surface_flags = SVGA_RELOC_READ;
440 }
441 else {
442 assert(0);
443 return PIPE_ERROR_BAD_INPUT;
444 }
445
446 cmd = SVGA3D_FIFOReserve(swc,
447 SVGA_3D_CMD_SURFACE_DMA,
448 sizeof *cmd + boxesSize + sizeof *pSuffix,
449 2);
450 if(!cmd)
451 return PIPE_ERROR_OUT_OF_MEMORY;
452
453 swc->region_relocation(swc, &cmd->guest.ptr, st->hwbuf, 0, region_flags);
454 cmd->guest.pitch = st->base.stride;
455
456 swc->surface_relocation(swc, &cmd->host.sid, texture->handle, surface_flags);
457 cmd->host.face = st->face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */
458 cmd->host.mipmap = st->base.level;
459
460 cmd->transfer = transfer;
461
462 memcpy(&cmd[1], boxes, boxesSize);
463
464 pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + boxesSize);
465 pSuffix->suffixSize = sizeof *pSuffix;
466 pSuffix->maximumOffset = st->hw_nblocksy*st->base.stride;
467 pSuffix->flags = flags;
468
469 swc->commit(swc);
470
471 return PIPE_OK;
472 }
473
474
475 enum pipe_error
476 SVGA3D_BufferDMA(struct svga_winsys_context *swc,
477 struct svga_winsys_buffer *guest,
478 struct svga_winsys_surface *host,
479 SVGA3dTransferType transfer, // IN
480 uint32 size, // IN
481 uint32 guest_offset, // IN
482 uint32 host_offset, // IN
483 SVGA3dSurfaceDMAFlags flags) // IN
484 {
485 SVGA3dCmdSurfaceDMA *cmd;
486 SVGA3dCopyBox *box;
487 SVGA3dCmdSurfaceDMASuffix *pSuffix;
488 unsigned region_flags;
489 unsigned surface_flags;
490
491 if(transfer == SVGA3D_WRITE_HOST_VRAM) {
492 region_flags = SVGA_RELOC_READ;
493 surface_flags = SVGA_RELOC_WRITE;
494 }
495 else if(transfer == SVGA3D_READ_HOST_VRAM) {
496 region_flags = SVGA_RELOC_WRITE;
497 surface_flags = SVGA_RELOC_READ;
498 }
499 else {
500 assert(0);
501 return PIPE_ERROR_BAD_INPUT;
502 }
503
504 cmd = SVGA3D_FIFOReserve(swc,
505 SVGA_3D_CMD_SURFACE_DMA,
506 sizeof *cmd + sizeof *box + sizeof *pSuffix,
507 2);
508 if(!cmd)
509 return PIPE_ERROR_OUT_OF_MEMORY;
510
511 swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags);
512 cmd->guest.pitch = 0;
513
514 swc->surface_relocation(swc, &cmd->host.sid, host, surface_flags);
515 cmd->host.face = 0;
516 cmd->host.mipmap = 0;
517
518 cmd->transfer = transfer;
519
520 box = (SVGA3dCopyBox *)&cmd[1];
521 box->x = host_offset;
522 box->y = 0;
523 box->z = 0;
524 box->w = size;
525 box->h = 1;
526 box->d = 1;
527 box->srcx = guest_offset;
528 box->srcy = 0;
529 box->srcz = 0;
530
531 pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box);
532 pSuffix->suffixSize = sizeof *pSuffix;
533 pSuffix->maximumOffset = guest_offset + size;
534 pSuffix->flags = flags;
535
536 swc->commit(swc);
537
538 return PIPE_OK;
539 }
540
541
542 /*
543 *----------------------------------------------------------------------
544 *
545 * SVGA3D_SetRenderTarget --
546 *
547 * Bind a surface object to a particular render target attachment
548 * point on the current context. Render target attachment points
549 * exist for color buffers, a depth buffer, and a stencil buffer.
550 *
551 * The SVGA3D device is quite lenient about the types of surfaces
552 * that may be used as render targets. The color buffers must
553 * all be the same size, but the depth and stencil buffers do not
554 * have to be the same size as the color buffer. All attachments
555 * are optional.
556 *
557 * Some combinations of render target formats may require software
558 * emulation, depending on the capabilities of the host graphics
559 * API and graphics hardware.
560 *
561 * Results:
562 * None.
563 *
564 * Side effects:
565 * None.
566 *
567 *----------------------------------------------------------------------
568 */
569
570 enum pipe_error
571 SVGA3D_SetRenderTarget(struct svga_winsys_context *swc,
572 SVGA3dRenderTargetType type, // IN
573 struct pipe_surface *surface) // IN
574 {
575 SVGA3dCmdSetRenderTarget *cmd;
576
577 cmd = SVGA3D_FIFOReserve(swc,
578 SVGA_3D_CMD_SETRENDERTARGET, sizeof *cmd, 1);
579 if(!cmd)
580 return PIPE_ERROR_OUT_OF_MEMORY;
581
582
583 cmd->cid = swc->cid;
584
585 cmd->type = type;
586
587 surface_to_surfaceid(swc, surface, &cmd->target, SVGA_RELOC_WRITE);
588
589 swc->commit(swc);
590
591 return PIPE_OK;
592 }
593
594
595
596
597
598
599 /*
600 *----------------------------------------------------------------------
601 *
602 * SVGA3D_DefineShader --
603 *
604 * Upload the bytecode for a new shader. The bytecode is "SVGA3D
605 * format", which is theoretically a binary-compatible superset
606 * of Microsoft's DirectX shader bytecode. In practice, the
607 * SVGA3D bytecode doesn't yet have any extensions to DirectX's
608 * bytecode format.
609 *
610 * The SVGA3D device supports shader models 1.1 through 2.0.
611 *
612 * The caller chooses a shader ID (small positive integer) by
613 * which this shader will be identified in future commands. This
614 * ID is in a namespace which is per-context and per-shader-type.
615 *
616 * 'bytecodeLen' is specified in bytes. It must be a multiple of 4.
617 *
618 * Results:
619 * None.
620 *
621 * Side effects:
622 * None.
623 *
624 *----------------------------------------------------------------------
625 */
626
627 enum pipe_error
628 SVGA3D_DefineShader(struct svga_winsys_context *swc,
629 uint32 shid, // IN
630 SVGA3dShaderType type, // IN
631 const uint32 *bytecode, // IN
632 uint32 bytecodeLen) // IN
633 {
634 SVGA3dCmdDefineShader *cmd;
635
636 assert(bytecodeLen % 4 == 0);
637
638 cmd = SVGA3D_FIFOReserve(swc,
639 SVGA_3D_CMD_SHADER_DEFINE, sizeof *cmd + bytecodeLen,
640 0);
641 if(!cmd)
642 return PIPE_ERROR_OUT_OF_MEMORY;
643
644 cmd->cid = swc->cid;
645 cmd->shid = shid;
646 cmd->type = type;
647 memcpy(&cmd[1], bytecode, bytecodeLen);
648 swc->commit(swc);
649
650 return PIPE_OK;
651 }
652
653
654 /*
655 *----------------------------------------------------------------------
656 *
657 * SVGA3D_DestroyShader --
658 *
659 * Delete a shader that was created by SVGA3D_DefineShader. If
660 * the shader was the current vertex or pixel shader for its
661 * context, rendering results are undefined until a new shader is
662 * bound.
663 *
664 * Results:
665 * None.
666 *
667 * Side effects:
668 * None.
669 *
670 *----------------------------------------------------------------------
671 */
672
673 enum pipe_error
674 SVGA3D_DestroyShader(struct svga_winsys_context *swc,
675 uint32 shid, // IN
676 SVGA3dShaderType type) // IN
677 {
678 SVGA3dCmdDestroyShader *cmd;
679
680 cmd = SVGA3D_FIFOReserve(swc,
681 SVGA_3D_CMD_SHADER_DESTROY, sizeof *cmd,
682 0);
683 if(!cmd)
684 return PIPE_ERROR_OUT_OF_MEMORY;
685
686 cmd->cid = swc->cid;
687 cmd->shid = shid;
688 cmd->type = type;
689 swc->commit(swc);
690
691 return PIPE_OK;
692 }
693
694
695 /*
696 *----------------------------------------------------------------------
697 *
698 * SVGA3D_SetShaderConst --
699 *
700 * Set the value of a shader constant.
701 *
702 * Shader constants are analogous to uniform variables in GLSL,
703 * except that they belong to the render context rather than to
704 * an individual shader.
705 *
706 * Constants may have one of three types: A 4-vector of floats,
707 * a 4-vector of integers, or a single boolean flag.
708 *
709 * Results:
710 * None.
711 *
712 * Side effects:
713 * None.
714 *
715 *----------------------------------------------------------------------
716 */
717
718 enum pipe_error
719 SVGA3D_SetShaderConst(struct svga_winsys_context *swc,
720 uint32 reg, // IN
721 SVGA3dShaderType type, // IN
722 SVGA3dShaderConstType ctype, // IN
723 const void *value) // IN
724 {
725 SVGA3dCmdSetShaderConst *cmd;
726
727 cmd = SVGA3D_FIFOReserve(swc,
728 SVGA_3D_CMD_SET_SHADER_CONST, sizeof *cmd,
729 0);
730 if(!cmd)
731 return PIPE_ERROR_OUT_OF_MEMORY;
732
733 cmd->cid = swc->cid;
734 cmd->reg = reg;
735 cmd->type = type;
736 cmd->ctype = ctype;
737
738 switch (ctype) {
739
740 case SVGA3D_CONST_TYPE_FLOAT:
741 case SVGA3D_CONST_TYPE_INT:
742 memcpy(&cmd->values, value, sizeof cmd->values);
743 break;
744
745 case SVGA3D_CONST_TYPE_BOOL:
746 memset(&cmd->values, 0, sizeof cmd->values);
747 cmd->values[0] = *(uint32*)value;
748 break;
749
750 default:
751 assert(0);
752 break;
753
754 }
755 swc->commit(swc);
756
757 return PIPE_OK;
758 }
759
760
761 /*
762 *----------------------------------------------------------------------
763 *
764 * SVGA3D_SetShaderConsts --
765 *
766 * Set the value of successive shader constants.
767 *
768 * Shader constants are analogous to uniform variables in GLSL,
769 * except that they belong to the render context rather than to
770 * an individual shader.
771 *
772 * Constants may have one of three types: A 4-vector of floats,
773 * a 4-vector of integers, or a single boolean flag.
774 *
775 * Results:
776 * None.
777 *
778 * Side effects:
779 * None.
780 *
781 *----------------------------------------------------------------------
782 */
783
784 enum pipe_error
785 SVGA3D_SetShaderConsts(struct svga_winsys_context *swc,
786 uint32 reg, // IN
787 uint32 numRegs, // IN
788 SVGA3dShaderType type, // IN
789 SVGA3dShaderConstType ctype, // IN
790 const void *values) // IN
791 {
792 SVGA3dCmdSetShaderConst *cmd;
793
794 cmd = SVGA3D_FIFOReserve(swc,
795 SVGA_3D_CMD_SET_SHADER_CONST,
796 sizeof *cmd + (numRegs - 1) * sizeof cmd->values,
797 0);
798 if(!cmd)
799 return PIPE_ERROR_OUT_OF_MEMORY;
800
801 cmd->cid = swc->cid;
802 cmd->reg = reg;
803 cmd->type = type;
804 cmd->ctype = ctype;
805
806 memcpy(&cmd->values, values, numRegs * sizeof cmd->values);
807
808 swc->commit(swc);
809
810 return PIPE_OK;
811 }
812
813
814
815
816
817 /*
818 *----------------------------------------------------------------------
819 *
820 * SVGA3D_SetShader --
821 *
822 * Switch active shaders. This binds a new vertex or pixel shader
823 * to the specified context.
824 *
825 * A shader ID of SVGA3D_INVALID_ID unbinds any shader, switching
826 * back to the fixed function vertex or pixel pipeline.
827 *
828 * Results:
829 * None.
830 *
831 * Side effects:
832 * None.
833 *
834 *----------------------------------------------------------------------
835 */
836
837 enum pipe_error
838 SVGA3D_SetShader(struct svga_winsys_context *swc,
839 SVGA3dShaderType type, // IN
840 uint32 shid) // IN
841 {
842 SVGA3dCmdSetShader *cmd;
843
844 cmd = SVGA3D_FIFOReserve(swc,
845 SVGA_3D_CMD_SET_SHADER, sizeof *cmd,
846 0);
847 if(!cmd)
848 return PIPE_ERROR_OUT_OF_MEMORY;
849
850 cmd->cid = swc->cid;
851 cmd->type = type;
852 cmd->shid = shid;
853 swc->commit(swc);
854
855 return PIPE_OK;
856 }
857
858
859 /*
860 *----------------------------------------------------------------------
861 *
862 * SVGA3D_BeginClear --
863 *
864 * Begin a CLEAR command. This reserves space for it in the FIFO,
865 * and returns a pointer to the command's rectangle array. This
866 * function must be paired with SVGA_FIFOCommitAll().
867 *
868 * Clear is a rendering operation which fills a list of
869 * rectangles with constant values on all render target types
870 * indicated by 'flags'.
871 *
872 * Clear is not affected by clipping, depth test, or other
873 * render state which affects the fragment pipeline.
874 *
875 * Results:
876 * None.
877 *
878 * Side effects:
879 * May write to attached render target surfaces.
880 *
881 *----------------------------------------------------------------------
882 */
883
884 enum pipe_error
885 SVGA3D_BeginClear(struct svga_winsys_context *swc,
886 SVGA3dClearFlag flags, // IN
887 uint32 color, // IN
888 float depth, // IN
889 uint32 stencil, // IN
890 SVGA3dRect **rects, // OUT
891 uint32 numRects) // IN
892 {
893 SVGA3dCmdClear *cmd;
894
895 cmd = SVGA3D_FIFOReserve(swc,
896 SVGA_3D_CMD_CLEAR,
897 sizeof *cmd + sizeof **rects * numRects,
898 0);
899 if(!cmd)
900 return PIPE_ERROR_OUT_OF_MEMORY;
901
902 cmd->cid = swc->cid;
903 cmd->clearFlag = flags;
904 cmd->color = color;
905 cmd->depth = depth;
906 cmd->stencil = stencil;
907 *rects = (SVGA3dRect*) &cmd[1];
908
909 return PIPE_OK;
910 }
911
912
913 /*
914 *----------------------------------------------------------------------
915 *
916 * SVGA3D_ClearRect --
917 *
918 * This is a simplified version of SVGA3D_BeginClear().
919 *
920 * Results:
921 * None.
922 *
923 * Side effects:
924 * None.
925 *
926 *----------------------------------------------------------------------
927 */
928
929 enum pipe_error
930 SVGA3D_ClearRect(struct svga_winsys_context *swc,
931 SVGA3dClearFlag flags, // IN
932 uint32 color, // IN
933 float depth, // IN
934 uint32 stencil, // IN
935 uint32 x, // IN
936 uint32 y, // IN
937 uint32 w, // IN
938 uint32 h) // IN
939 {
940 SVGA3dRect *rect;
941 enum pipe_error ret;
942
943 ret = SVGA3D_BeginClear(swc, flags, color, depth, stencil, &rect, 1);
944 if(ret != PIPE_OK)
945 return PIPE_ERROR_OUT_OF_MEMORY;
946
947 memset(rect, 0, sizeof *rect);
948 rect->x = x;
949 rect->y = y;
950 rect->w = w;
951 rect->h = h;
952 swc->commit(swc);
953
954 return PIPE_OK;
955 }
956
957
958 /*
959 *----------------------------------------------------------------------
960 *
961 * SVGA3D_BeginDrawPrimitives --
962 *
963 * Begin a DRAW_PRIMITIVES command. This reserves space for it in
964 * the FIFO, and returns a pointer to the command's arrays.
965 * This function must be paired with SVGA_FIFOCommitAll().
966 *
967 * Drawing commands consist of two variable-length arrays:
968 * SVGA3dVertexDecl elements declare a set of vertex buffers to
969 * use while rendering, and SVGA3dPrimitiveRange elements specify
970 * groups of primitives each with an optional index buffer.
971 *
972 * The decls and ranges arrays are initialized to zero.
973 *
974 * Results:
975 * None.
976 *
977 * Side effects:
978 * May write to attached render target surfaces.
979 *
980 *----------------------------------------------------------------------
981 */
982
983 enum pipe_error
984 SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc,
985 SVGA3dVertexDecl **decls, // OUT
986 uint32 numVertexDecls, // IN
987 SVGA3dPrimitiveRange **ranges, // OUT
988 uint32 numRanges) // IN
989 {
990 SVGA3dCmdDrawPrimitives *cmd;
991 SVGA3dVertexDecl *declArray;
992 SVGA3dPrimitiveRange *rangeArray;
993 uint32 declSize = sizeof **decls * numVertexDecls;
994 uint32 rangeSize = sizeof **ranges * numRanges;
995
996 cmd = SVGA3D_FIFOReserve(swc,
997 SVGA_3D_CMD_DRAW_PRIMITIVES,
998 sizeof *cmd + declSize + rangeSize,
999 numVertexDecls + numRanges);
1000 if(!cmd)
1001 return PIPE_ERROR_OUT_OF_MEMORY;
1002
1003 cmd->cid = swc->cid;
1004 cmd->numVertexDecls = numVertexDecls;
1005 cmd->numRanges = numRanges;
1006
1007 declArray = (SVGA3dVertexDecl*) &cmd[1];
1008 rangeArray = (SVGA3dPrimitiveRange*) &declArray[numVertexDecls];
1009
1010 memset(declArray, 0, declSize);
1011 memset(rangeArray, 0, rangeSize);
1012
1013 *decls = declArray;
1014 *ranges = rangeArray;
1015
1016 return PIPE_OK;
1017 }
1018
1019
1020 /*
1021 *----------------------------------------------------------------------
1022 *
1023 * SVGA3D_BeginSurfaceCopy --
1024 *
1025 * Begin a SURFACE_COPY command. This reserves space for it in
1026 * the FIFO, and returns a pointer to the command's arrays. This
1027 * function must be paired with SVGA_FIFOCommitAll().
1028 *
1029 * The box array is initialized with zeroes.
1030 *
1031 * Results:
1032 * None.
1033 *
1034 * Side effects:
1035 * Asynchronously copies a list of boxes from surface to surface.
1036 *
1037 *----------------------------------------------------------------------
1038 */
1039
1040 enum pipe_error
1041 SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc,
1042 struct pipe_surface *src, // IN
1043 struct pipe_surface *dest, // IN
1044 SVGA3dCopyBox **boxes, // OUT
1045 uint32 numBoxes) // IN
1046 {
1047 SVGA3dCmdSurfaceCopy *cmd;
1048 uint32 boxesSize = sizeof **boxes * numBoxes;
1049
1050 cmd = SVGA3D_FIFOReserve(swc,
1051 SVGA_3D_CMD_SURFACE_COPY, sizeof *cmd + boxesSize,
1052 2);
1053 if(!cmd)
1054 return PIPE_ERROR_OUT_OF_MEMORY;
1055
1056 surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
1057 surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
1058 *boxes = (SVGA3dCopyBox*) &cmd[1];
1059
1060 memset(*boxes, 0, boxesSize);
1061
1062 return PIPE_OK;
1063 }
1064
1065
1066 /*
1067 *----------------------------------------------------------------------
1068 *
1069 * SVGA3D_SurfaceStretchBlt --
1070 *
1071 * Issue a SURFACE_STRETCHBLT command: an asynchronous
1072 * surface-to-surface blit, with scaling.
1073 *
1074 * Results:
1075 * None.
1076 *
1077 * Side effects:
1078 * Asynchronously copies one box from surface to surface.
1079 *
1080 *----------------------------------------------------------------------
1081 */
1082
1083 enum pipe_error
1084 SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc,
1085 struct pipe_surface *src, // IN
1086 struct pipe_surface *dest, // IN
1087 SVGA3dBox *boxSrc, // IN
1088 SVGA3dBox *boxDest, // IN
1089 SVGA3dStretchBltMode mode) // IN
1090 {
1091 SVGA3dCmdSurfaceStretchBlt *cmd;
1092
1093 cmd = SVGA3D_FIFOReserve(swc,
1094 SVGA_3D_CMD_SURFACE_STRETCHBLT, sizeof *cmd,
1095 2);
1096 if(!cmd)
1097 return PIPE_ERROR_OUT_OF_MEMORY;
1098
1099 surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
1100 surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
1101 cmd->boxSrc = *boxSrc;
1102 cmd->boxDest = *boxDest;
1103 cmd->mode = mode;
1104 swc->commit(swc);
1105
1106 return PIPE_OK;
1107 }
1108
1109
1110 /*
1111 *----------------------------------------------------------------------
1112 *
1113 * SVGA3D_SetViewport --
1114 *
1115 * Set the current context's viewport rectangle. The viewport
1116 * is clipped to the dimensions of the current render target,
1117 * then all rendering is clipped to the viewport.
1118 *
1119 * Results:
1120 * None.
1121 *
1122 * Side effects:
1123 * None.
1124 *
1125 *----------------------------------------------------------------------
1126 */
1127
1128 enum pipe_error
1129 SVGA3D_SetViewport(struct svga_winsys_context *swc,
1130 SVGA3dRect *rect) // IN
1131 {
1132 SVGA3dCmdSetViewport *cmd;
1133
1134 cmd = SVGA3D_FIFOReserve(swc,
1135 SVGA_3D_CMD_SETVIEWPORT, sizeof *cmd,
1136 0);
1137 if(!cmd)
1138 return PIPE_ERROR_OUT_OF_MEMORY;
1139
1140 cmd->cid = swc->cid;
1141 cmd->rect = *rect;
1142 swc->commit(swc);
1143
1144 return PIPE_OK;
1145 }
1146
1147
1148
1149
1150 /*
1151 *----------------------------------------------------------------------
1152 *
1153 * SVGA3D_SetScissorRect --
1154 *
1155 * Set the current context's scissor rectangle. If scissor
1156 * is enabled then all rendering is clipped to the scissor.
1157 *
1158 * Results:
1159 * None.
1160 *
1161 * Side effects:
1162 * None.
1163 *
1164 *----------------------------------------------------------------------
1165 */
1166
1167 enum pipe_error
1168 SVGA3D_SetScissorRect(struct svga_winsys_context *swc,
1169 SVGA3dRect *rect) // IN
1170 {
1171 SVGA3dCmdSetScissorRect *cmd;
1172
1173 cmd = SVGA3D_FIFOReserve(swc,
1174 SVGA_3D_CMD_SETSCISSORRECT, sizeof *cmd,
1175 0);
1176 if(!cmd)
1177 return PIPE_ERROR_OUT_OF_MEMORY;
1178
1179 cmd->cid = swc->cid;
1180 cmd->rect = *rect;
1181 swc->commit(swc);
1182
1183 return PIPE_OK;
1184 }
1185
1186 /*
1187 *----------------------------------------------------------------------
1188 *
1189 * SVGA3D_SetClipPlane --
1190 *
1191 * Set one of the current context's clip planes. If the clip
1192 * plane is enabled then all 3d rendering is clipped to against
1193 * the plane.
1194 *
1195 * Results:
1196 * None.
1197 *
1198 * Side effects:
1199 * None.
1200 *
1201 *----------------------------------------------------------------------
1202 */
1203
1204 enum pipe_error
1205 SVGA3D_SetClipPlane(struct svga_winsys_context *swc,
1206 uint32 index, const float *plane)
1207 {
1208 SVGA3dCmdSetClipPlane *cmd;
1209
1210 cmd = SVGA3D_FIFOReserve(swc,
1211 SVGA_3D_CMD_SETCLIPPLANE, sizeof *cmd,
1212 0);
1213 if(!cmd)
1214 return PIPE_ERROR_OUT_OF_MEMORY;
1215
1216 cmd->cid = swc->cid;
1217 cmd->index = index;
1218 cmd->plane[0] = plane[0];
1219 cmd->plane[1] = plane[1];
1220 cmd->plane[2] = plane[2];
1221 cmd->plane[3] = plane[3];
1222 swc->commit(swc);
1223
1224 return PIPE_OK;
1225 }
1226
1227 /*
1228 *----------------------------------------------------------------------
1229 *
1230 * SVGA3D_SetZRange --
1231 *
1232 * Set the range of the depth buffer to use. 'min' and 'max'
1233 * are values between 0.0 and 1.0.
1234 *
1235 * Results:
1236 * None.
1237 *
1238 * Side effects:
1239 * None.
1240 *
1241 *----------------------------------------------------------------------
1242 */
1243
1244 enum pipe_error
1245 SVGA3D_SetZRange(struct svga_winsys_context *swc,
1246 float zMin, // IN
1247 float zMax) // IN
1248 {
1249 SVGA3dCmdSetZRange *cmd;
1250
1251 cmd = SVGA3D_FIFOReserve(swc,
1252 SVGA_3D_CMD_SETZRANGE, sizeof *cmd,
1253 0);
1254 if(!cmd)
1255 return PIPE_ERROR_OUT_OF_MEMORY;
1256
1257 cmd->cid = swc->cid;
1258 cmd->zRange.min = zMin;
1259 cmd->zRange.max = zMax;
1260 swc->commit(swc);
1261
1262 return PIPE_OK;
1263 }
1264
1265
1266 /*
1267 *----------------------------------------------------------------------
1268 *
1269 * SVGA3D_BeginSetTextureState --
1270 *
1271 * Begin a SETTEXTURESTATE command. This reserves space for it in
1272 * the FIFO, and returns a pointer to the command's texture state
1273 * array. This function must be paired with SVGA_FIFOCommitAll().
1274 *
1275 * This command sets rendering state which is per-texture-unit.
1276 *
1277 * XXX: Individual texture states need documentation. However,
1278 * they are very similar to the texture states defined by
1279 * Direct3D. The D3D documentation is a good starting point
1280 * for understanding SVGA3D texture states.
1281 *
1282 * Results:
1283 * None.
1284 *
1285 * Side effects:
1286 * None.
1287 *
1288 *----------------------------------------------------------------------
1289 */
1290
1291 enum pipe_error
1292 SVGA3D_BeginSetTextureState(struct svga_winsys_context *swc,
1293 SVGA3dTextureState **states, // OUT
1294 uint32 numStates) // IN
1295 {
1296 SVGA3dCmdSetTextureState *cmd;
1297
1298 cmd = SVGA3D_FIFOReserve(swc,
1299 SVGA_3D_CMD_SETTEXTURESTATE,
1300 sizeof *cmd + sizeof **states * numStates,
1301 numStates);
1302 if(!cmd)
1303 return PIPE_ERROR_OUT_OF_MEMORY;
1304
1305 cmd->cid = swc->cid;
1306 *states = (SVGA3dTextureState*) &cmd[1];
1307
1308 return PIPE_OK;
1309 }
1310
1311
1312 /*
1313 *----------------------------------------------------------------------
1314 *
1315 * SVGA3D_BeginSetRenderState --
1316 *
1317 * Begin a SETRENDERSTATE command. This reserves space for it in
1318 * the FIFO, and returns a pointer to the command's texture state
1319 * array. This function must be paired with SVGA_FIFOCommitAll().
1320 *
1321 * This command sets rendering state which is global to the context.
1322 *
1323 * XXX: Individual render states need documentation. However,
1324 * they are very similar to the render states defined by
1325 * Direct3D. The D3D documentation is a good starting point
1326 * for understanding SVGA3D render states.
1327 *
1328 * Results:
1329 * None.
1330 *
1331 * Side effects:
1332 * None.
1333 *
1334 *----------------------------------------------------------------------
1335 */
1336
1337 enum pipe_error
1338 SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc,
1339 SVGA3dRenderState **states, // OUT
1340 uint32 numStates) // IN
1341 {
1342 SVGA3dCmdSetRenderState *cmd;
1343
1344 cmd = SVGA3D_FIFOReserve(swc,
1345 SVGA_3D_CMD_SETRENDERSTATE,
1346 sizeof *cmd + sizeof **states * numStates,
1347 0);
1348 if(!cmd)
1349 return PIPE_ERROR_OUT_OF_MEMORY;
1350
1351 cmd->cid = swc->cid;
1352 *states = (SVGA3dRenderState*) &cmd[1];
1353
1354 return PIPE_OK;
1355 }
1356
1357
1358 /*
1359 *----------------------------------------------------------------------
1360 *
1361 * SVGA3D_BeginQuery--
1362 *
1363 * Issues a SVGA_3D_CMD_BEGIN_QUERY command.
1364 *
1365 * Results:
1366 * None.
1367 *
1368 * Side effects:
1369 * Commits space in the FIFO memory.
1370 *
1371 *----------------------------------------------------------------------
1372 */
1373
1374 enum pipe_error
1375 SVGA3D_BeginQuery(struct svga_winsys_context *swc,
1376 SVGA3dQueryType type) // IN
1377 {
1378 SVGA3dCmdBeginQuery *cmd;
1379
1380 cmd = SVGA3D_FIFOReserve(swc,
1381 SVGA_3D_CMD_BEGIN_QUERY,
1382 sizeof *cmd,
1383 0);
1384 if(!cmd)
1385 return PIPE_ERROR_OUT_OF_MEMORY;
1386
1387 cmd->cid = swc->cid;
1388 cmd->type = type;
1389
1390 swc->commit(swc);
1391
1392 return PIPE_OK;
1393 }
1394
1395
1396 /*
1397 *----------------------------------------------------------------------
1398 *
1399 * SVGA3D_EndQuery--
1400 *
1401 * Issues a SVGA_3D_CMD_END_QUERY command.
1402 *
1403 * Results:
1404 * None.
1405 *
1406 * Side effects:
1407 * Commits space in the FIFO memory.
1408 *
1409 *----------------------------------------------------------------------
1410 */
1411
1412 enum pipe_error
1413 SVGA3D_EndQuery(struct svga_winsys_context *swc,
1414 SVGA3dQueryType type, // IN
1415 struct svga_winsys_buffer *buffer) // IN/OUT
1416 {
1417 SVGA3dCmdEndQuery *cmd;
1418
1419 cmd = SVGA3D_FIFOReserve(swc,
1420 SVGA_3D_CMD_END_QUERY,
1421 sizeof *cmd,
1422 1);
1423 if(!cmd)
1424 return PIPE_ERROR_OUT_OF_MEMORY;
1425
1426 cmd->cid = swc->cid;
1427 cmd->type = type;
1428
1429 swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
1430 SVGA_RELOC_WRITE);
1431
1432 swc->commit(swc);
1433
1434 return PIPE_OK;
1435 }
1436
1437
1438 /*
1439 *----------------------------------------------------------------------
1440 *
1441 * SVGA3D_WaitForQuery--
1442 *
1443 * Issues a SVGA_3D_CMD_WAIT_FOR_QUERY command. This reserves space
1444 * for it in the FIFO. This doesn't actually wait for the query to
1445 * finish but instead tells the host to start a wait at the driver
1446 * level. The caller can wait on the status variable in the
1447 * guestPtr memory or send an insert fence instruction after this
1448 * command and wait on the fence.
1449 *
1450 * Results:
1451 * None.
1452 *
1453 * Side effects:
1454 * Commits space in the FIFO memory.
1455 *
1456 *----------------------------------------------------------------------
1457 */
1458
1459 enum pipe_error
1460 SVGA3D_WaitForQuery(struct svga_winsys_context *swc,
1461 SVGA3dQueryType type, // IN
1462 struct svga_winsys_buffer *buffer) // IN/OUT
1463 {
1464 SVGA3dCmdWaitForQuery *cmd;
1465
1466 cmd = SVGA3D_FIFOReserve(swc,
1467 SVGA_3D_CMD_WAIT_FOR_QUERY,
1468 sizeof *cmd,
1469 1);
1470 if(!cmd)
1471 return PIPE_ERROR_OUT_OF_MEMORY;
1472
1473 cmd->cid = swc->cid;
1474 cmd->type = type;
1475
1476 swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
1477 SVGA_RELOC_WRITE);
1478
1479 swc->commit(swc);
1480
1481 return PIPE_OK;
1482 }