Merge commit 'origin/7.8'
[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 filld out.
50 *
51 * Side effects:
52 * One surface relocation is preformed 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 id->sid = SVGA3D_INVALID_ID;
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 hierarchial:
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_BeginSurfaceDMA--
380 *
381 * Begin a SURFACE_DMA command. This reserves space for it in
382 * the FIFO, and returns a pointer to the command's box array.
383 * This function must be paired with SVGA_FIFOCommitAll().
384 *
385 * When the SVGA3D device asynchronously processes this FIFO
386 * command, a DMA operation is performed between host VRAM and
387 * a generic SVGAGuestPtr. The guest pointer may refer to guest
388 * VRAM (provided by the SVGA PCI device) or to guest system
389 * memory that has been set up as a Guest Memory Region (GMR)
390 * by the SVGA device.
391 *
392 * The guest's DMA buffer must remain valid (not freed, paged out,
393 * or overwritten) until the host has finished processing this
394 * command. The guest can determine that the host has finished
395 * by using the SVGA device's FIFO Fence mechanism.
396 *
397 * The guest's image buffer can be an arbitrary size and shape.
398 * Guest image data is interpreted according to the SVGA3D surface
399 * format specified when the surface was defined.
400 *
401 * The caller may optionally define the guest image's pitch.
402 * guestImage->pitch can either be zero (assume image is tightly
403 * packed) or it must be the number of bytes between vertically
404 * adjacent image blocks.
405 *
406 * The provided copybox list specifies which regions of the source
407 * image are to be copied, and where they appear on the destination.
408 *
409 * NOTE: srcx/srcy are always on the guest image and x/y are
410 * always on the host image, regardless of the actual transfer
411 * direction!
412 *
413 * For efficiency, the SVGA3D device is free to copy more data
414 * than specified. For example, it may round copy boxes outwards
415 * such that they lie on particular alignment boundaries.
416 *
417 *----------------------------------------------------------------------
418 */
419
420 enum pipe_error
421 SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
422 struct svga_transfer *st, // IN
423 SVGA3dTransferType transfer, // IN
424 const SVGA3dCopyBox *boxes, // IN
425 uint32 numBoxes) // IN
426 {
427 struct svga_texture *texture = svga_texture(st->base.resource);
428 SVGA3dCmdSurfaceDMA *cmd;
429 SVGA3dCmdSurfaceDMASuffix *pSuffix;
430 uint32 boxesSize = sizeof *boxes * numBoxes;
431 unsigned region_flags;
432 unsigned surface_flags;
433
434 if(transfer == SVGA3D_WRITE_HOST_VRAM) {
435 region_flags = SVGA_RELOC_READ;
436 surface_flags = SVGA_RELOC_WRITE;
437 }
438 else if(transfer == SVGA3D_READ_HOST_VRAM) {
439 region_flags = SVGA_RELOC_WRITE;
440 surface_flags = SVGA_RELOC_READ;
441 }
442 else {
443 assert(0);
444 return PIPE_ERROR_BAD_INPUT;
445 }
446
447 cmd = SVGA3D_FIFOReserve(swc,
448 SVGA_3D_CMD_SURFACE_DMA,
449 sizeof *cmd + boxesSize + sizeof *pSuffix,
450 2);
451 if(!cmd)
452 return PIPE_ERROR_OUT_OF_MEMORY;
453
454 swc->region_relocation(swc, &cmd->guest.ptr, st->hwbuf, 0, region_flags);
455 cmd->guest.pitch = st->base.stride;
456
457 swc->surface_relocation(swc, &cmd->host.sid, texture->handle, surface_flags);
458 cmd->host.face = st->base.sr.face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */
459 cmd->host.mipmap = st->base.sr.level;
460
461 cmd->transfer = transfer;
462
463 memcpy(&cmd[1], boxes, boxesSize);
464
465 pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + boxesSize);
466 pSuffix->suffixSize = sizeof *pSuffix;
467 pSuffix->maximumOffset = st->hw_nblocksy*st->base.stride;
468 memset(&pSuffix->flags, 0, sizeof pSuffix->flags);
469
470 swc->commit(swc);
471
472 return PIPE_OK;
473 }
474
475
476 enum pipe_error
477 SVGA3D_BufferDMA(struct svga_winsys_context *swc,
478 struct svga_winsys_buffer *guest,
479 struct svga_winsys_surface *host,
480 SVGA3dTransferType transfer, // IN
481 uint32 size, // IN
482 uint32 guest_offset, // IN
483 uint32 host_offset, // IN
484 SVGA3dSurfaceDMAFlags flags) // IN
485 {
486 SVGA3dCmdSurfaceDMA *cmd;
487 SVGA3dCopyBox *box;
488 SVGA3dCmdSurfaceDMASuffix *pSuffix;
489 unsigned region_flags;
490 unsigned surface_flags;
491
492 if(transfer == SVGA3D_WRITE_HOST_VRAM) {
493 region_flags = SVGA_RELOC_READ;
494 surface_flags = SVGA_RELOC_WRITE;
495 }
496 else if(transfer == SVGA3D_READ_HOST_VRAM) {
497 region_flags = SVGA_RELOC_WRITE;
498 surface_flags = SVGA_RELOC_READ;
499 }
500 else {
501 assert(0);
502 return PIPE_ERROR_BAD_INPUT;
503 }
504
505 cmd = SVGA3D_FIFOReserve(swc,
506 SVGA_3D_CMD_SURFACE_DMA,
507 sizeof *cmd + sizeof *box + sizeof *pSuffix,
508 2);
509 if(!cmd)
510 return PIPE_ERROR_OUT_OF_MEMORY;
511
512 swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags);
513 cmd->guest.pitch = 0;
514
515 swc->surface_relocation(swc, &cmd->host.sid, host, surface_flags);
516 cmd->host.face = 0;
517 cmd->host.mipmap = 0;
518
519 cmd->transfer = transfer;
520
521 box = (SVGA3dCopyBox *)&cmd[1];
522 box->x = host_offset;
523 box->y = 0;
524 box->z = 0;
525 box->w = size;
526 box->h = 1;
527 box->d = 1;
528 box->srcx = guest_offset;
529 box->srcy = 0;
530 box->srcz = 0;
531
532 pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box);
533 pSuffix->suffixSize = sizeof *pSuffix;
534 pSuffix->maximumOffset = guest_offset + size;
535 pSuffix->flags = flags;
536
537 swc->commit(swc);
538
539 return PIPE_OK;
540 }
541
542
543 /*
544 *----------------------------------------------------------------------
545 *
546 * SVGA3D_SetRenderTarget --
547 *
548 * Bind a surface object to a particular render target attachment
549 * point on the current context. Render target attachment points
550 * exist for color buffers, a depth buffer, and a stencil buffer.
551 *
552 * The SVGA3D device is quite lenient about the types of surfaces
553 * that may be used as render targets. The color buffers must
554 * all be the same size, but the depth and stencil buffers do not
555 * have to be the same size as the color buffer. All attachments
556 * are optional.
557 *
558 * Some combinations of render target formats may require software
559 * emulation, depending on the capabilities of the host graphics
560 * API and graphics hardware.
561 *
562 * Results:
563 * None.
564 *
565 * Side effects:
566 * None.
567 *
568 *----------------------------------------------------------------------
569 */
570
571 enum pipe_error
572 SVGA3D_SetRenderTarget(struct svga_winsys_context *swc,
573 SVGA3dRenderTargetType type, // IN
574 struct pipe_surface *surface) // IN
575 {
576 SVGA3dCmdSetRenderTarget *cmd;
577
578 cmd = SVGA3D_FIFOReserve(swc,
579 SVGA_3D_CMD_SETRENDERTARGET, sizeof *cmd, 1);
580 if(!cmd)
581 return PIPE_ERROR_OUT_OF_MEMORY;
582
583
584 cmd->cid = swc->cid;
585
586 cmd->type = type;
587
588 surface_to_surfaceid(swc, surface, &cmd->target, SVGA_RELOC_WRITE);
589
590 swc->commit(swc);
591
592 return PIPE_OK;
593 }
594
595
596
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 /*
766 *----------------------------------------------------------------------
767 *
768 * SVGA3D_SetShader --
769 *
770 * Switch active shaders. This binds a new vertex or pixel shader
771 * to the specified context.
772 *
773 * A shader ID of SVGA3D_INVALID_ID unbinds any shader, switching
774 * back to the fixed function vertex or pixel pipeline.
775 *
776 * Results:
777 * None.
778 *
779 * Side effects:
780 * None.
781 *
782 *----------------------------------------------------------------------
783 */
784
785 enum pipe_error
786 SVGA3D_SetShader(struct svga_winsys_context *swc,
787 SVGA3dShaderType type, // IN
788 uint32 shid) // IN
789 {
790 SVGA3dCmdSetShader *cmd;
791
792 cmd = SVGA3D_FIFOReserve(swc,
793 SVGA_3D_CMD_SET_SHADER, sizeof *cmd,
794 0);
795 if(!cmd)
796 return PIPE_ERROR_OUT_OF_MEMORY;
797
798 cmd->cid = swc->cid;
799 cmd->type = type;
800 cmd->shid = shid;
801 swc->commit(swc);
802
803 return PIPE_OK;
804 }
805
806
807 /*
808 *----------------------------------------------------------------------
809 *
810 * SVGA3D_BeginClear --
811 *
812 * Begin a CLEAR command. This reserves space for it in the FIFO,
813 * and returns a pointer to the command's rectangle array. This
814 * function must be paired with SVGA_FIFOCommitAll().
815 *
816 * Clear is a rendering operation which fills a list of
817 * rectangles with constant values on all render target types
818 * indicated by 'flags'.
819 *
820 * Clear is not affected by clipping, depth test, or other
821 * render state which affects the fragment pipeline.
822 *
823 * Results:
824 * None.
825 *
826 * Side effects:
827 * May write to attached render target surfaces.
828 *
829 *----------------------------------------------------------------------
830 */
831
832 enum pipe_error
833 SVGA3D_BeginClear(struct svga_winsys_context *swc,
834 SVGA3dClearFlag flags, // IN
835 uint32 color, // IN
836 float depth, // IN
837 uint32 stencil, // IN
838 SVGA3dRect **rects, // OUT
839 uint32 numRects) // IN
840 {
841 SVGA3dCmdClear *cmd;
842
843 cmd = SVGA3D_FIFOReserve(swc,
844 SVGA_3D_CMD_CLEAR,
845 sizeof *cmd + sizeof **rects * numRects,
846 0);
847 if(!cmd)
848 return PIPE_ERROR_OUT_OF_MEMORY;
849
850 cmd->cid = swc->cid;
851 cmd->clearFlag = flags;
852 cmd->color = color;
853 cmd->depth = depth;
854 cmd->stencil = stencil;
855 *rects = (SVGA3dRect*) &cmd[1];
856
857 return PIPE_OK;
858 }
859
860
861 /*
862 *----------------------------------------------------------------------
863 *
864 * SVGA3D_ClearRect --
865 *
866 * This is a simplified version of SVGA3D_BeginClear().
867 *
868 * Results:
869 * None.
870 *
871 * Side effects:
872 * None.
873 *
874 *----------------------------------------------------------------------
875 */
876
877 enum pipe_error
878 SVGA3D_ClearRect(struct svga_winsys_context *swc,
879 SVGA3dClearFlag flags, // IN
880 uint32 color, // IN
881 float depth, // IN
882 uint32 stencil, // IN
883 uint32 x, // IN
884 uint32 y, // IN
885 uint32 w, // IN
886 uint32 h) // IN
887 {
888 SVGA3dRect *rect;
889 enum pipe_error ret;
890
891 ret = SVGA3D_BeginClear(swc, flags, color, depth, stencil, &rect, 1);
892 if(ret != PIPE_OK)
893 return PIPE_ERROR_OUT_OF_MEMORY;
894
895 memset(rect, 0, sizeof *rect);
896 rect->x = x;
897 rect->y = y;
898 rect->w = w;
899 rect->h = h;
900 swc->commit(swc);
901
902 return PIPE_OK;
903 }
904
905
906 /*
907 *----------------------------------------------------------------------
908 *
909 * SVGA3D_BeginDrawPrimitives --
910 *
911 * Begin a DRAW_PRIMITIVES command. This reserves space for it in
912 * the FIFO, and returns a pointer to the command's arrays.
913 * This function must be paired with SVGA_FIFOCommitAll().
914 *
915 * Drawing commands consist of two variable-length arrays:
916 * SVGA3dVertexDecl elements declare a set of vertex buffers to
917 * use while rendering, and SVGA3dPrimitiveRange elements specify
918 * groups of primitives each with an optional index buffer.
919 *
920 * The decls and ranges arrays are initialized to zero.
921 *
922 * Results:
923 * None.
924 *
925 * Side effects:
926 * May write to attached render target surfaces.
927 *
928 *----------------------------------------------------------------------
929 */
930
931 enum pipe_error
932 SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc,
933 SVGA3dVertexDecl **decls, // OUT
934 uint32 numVertexDecls, // IN
935 SVGA3dPrimitiveRange **ranges, // OUT
936 uint32 numRanges) // IN
937 {
938 SVGA3dCmdDrawPrimitives *cmd;
939 SVGA3dVertexDecl *declArray;
940 SVGA3dPrimitiveRange *rangeArray;
941 uint32 declSize = sizeof **decls * numVertexDecls;
942 uint32 rangeSize = sizeof **ranges * numRanges;
943
944 cmd = SVGA3D_FIFOReserve(swc,
945 SVGA_3D_CMD_DRAW_PRIMITIVES,
946 sizeof *cmd + declSize + rangeSize,
947 numVertexDecls + numRanges);
948 if(!cmd)
949 return PIPE_ERROR_OUT_OF_MEMORY;
950
951 cmd->cid = swc->cid;
952 cmd->numVertexDecls = numVertexDecls;
953 cmd->numRanges = numRanges;
954
955 declArray = (SVGA3dVertexDecl*) &cmd[1];
956 rangeArray = (SVGA3dPrimitiveRange*) &declArray[numVertexDecls];
957
958 memset(declArray, 0, declSize);
959 memset(rangeArray, 0, rangeSize);
960
961 *decls = declArray;
962 *ranges = rangeArray;
963
964 return PIPE_OK;
965 }
966
967
968 /*
969 *----------------------------------------------------------------------
970 *
971 * SVGA3D_BeginSurfaceCopy --
972 *
973 * Begin a SURFACE_COPY command. This reserves space for it in
974 * the FIFO, and returns a pointer to the command's arrays. This
975 * function must be paired with SVGA_FIFOCommitAll().
976 *
977 * The box array is initialized with zeroes.
978 *
979 * Results:
980 * None.
981 *
982 * Side effects:
983 * Asynchronously copies a list of boxes from surface to surface.
984 *
985 *----------------------------------------------------------------------
986 */
987
988 enum pipe_error
989 SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc,
990 struct pipe_surface *src, // IN
991 struct pipe_surface *dest, // IN
992 SVGA3dCopyBox **boxes, // OUT
993 uint32 numBoxes) // IN
994 {
995 SVGA3dCmdSurfaceCopy *cmd;
996 uint32 boxesSize = sizeof **boxes * numBoxes;
997
998 cmd = SVGA3D_FIFOReserve(swc,
999 SVGA_3D_CMD_SURFACE_COPY, sizeof *cmd + boxesSize,
1000 2);
1001 if(!cmd)
1002 return PIPE_ERROR_OUT_OF_MEMORY;
1003
1004 surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
1005 surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
1006 *boxes = (SVGA3dCopyBox*) &cmd[1];
1007
1008 memset(*boxes, 0, boxesSize);
1009
1010 return PIPE_OK;
1011 }
1012
1013
1014 /*
1015 *----------------------------------------------------------------------
1016 *
1017 * SVGA3D_SurfaceStretchBlt --
1018 *
1019 * Issue a SURFACE_STRETCHBLT command: an asynchronous
1020 * surface-to-surface blit, with scaling.
1021 *
1022 * Results:
1023 * None.
1024 *
1025 * Side effects:
1026 * Asynchronously copies one box from surface to surface.
1027 *
1028 *----------------------------------------------------------------------
1029 */
1030
1031 enum pipe_error
1032 SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc,
1033 struct pipe_surface *src, // IN
1034 struct pipe_surface *dest, // IN
1035 SVGA3dBox *boxSrc, // IN
1036 SVGA3dBox *boxDest, // IN
1037 SVGA3dStretchBltMode mode) // IN
1038 {
1039 SVGA3dCmdSurfaceStretchBlt *cmd;
1040
1041 cmd = SVGA3D_FIFOReserve(swc,
1042 SVGA_3D_CMD_SURFACE_STRETCHBLT, sizeof *cmd,
1043 2);
1044 if(!cmd)
1045 return PIPE_ERROR_OUT_OF_MEMORY;
1046
1047 surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
1048 surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
1049 cmd->boxSrc = *boxSrc;
1050 cmd->boxDest = *boxDest;
1051 cmd->mode = mode;
1052 swc->commit(swc);
1053
1054 return PIPE_OK;
1055 }
1056
1057
1058 /*
1059 *----------------------------------------------------------------------
1060 *
1061 * SVGA3D_SetViewport --
1062 *
1063 * Set the current context's viewport rectangle. The viewport
1064 * is clipped to the dimensions of the current render target,
1065 * then all rendering is clipped to the viewport.
1066 *
1067 * Results:
1068 * None.
1069 *
1070 * Side effects:
1071 * None.
1072 *
1073 *----------------------------------------------------------------------
1074 */
1075
1076 enum pipe_error
1077 SVGA3D_SetViewport(struct svga_winsys_context *swc,
1078 SVGA3dRect *rect) // IN
1079 {
1080 SVGA3dCmdSetViewport *cmd;
1081
1082 cmd = SVGA3D_FIFOReserve(swc,
1083 SVGA_3D_CMD_SETVIEWPORT, sizeof *cmd,
1084 0);
1085 if(!cmd)
1086 return PIPE_ERROR_OUT_OF_MEMORY;
1087
1088 cmd->cid = swc->cid;
1089 cmd->rect = *rect;
1090 swc->commit(swc);
1091
1092 return PIPE_OK;
1093 }
1094
1095
1096
1097
1098 /*
1099 *----------------------------------------------------------------------
1100 *
1101 * SVGA3D_SetScissorRect --
1102 *
1103 * Set the current context's scissor rectangle. If scissor
1104 * is enabled then all rendering is clipped to the scissor.
1105 *
1106 * Results:
1107 * None.
1108 *
1109 * Side effects:
1110 * None.
1111 *
1112 *----------------------------------------------------------------------
1113 */
1114
1115 enum pipe_error
1116 SVGA3D_SetScissorRect(struct svga_winsys_context *swc,
1117 SVGA3dRect *rect) // IN
1118 {
1119 SVGA3dCmdSetScissorRect *cmd;
1120
1121 cmd = SVGA3D_FIFOReserve(swc,
1122 SVGA_3D_CMD_SETSCISSORRECT, sizeof *cmd,
1123 0);
1124 if(!cmd)
1125 return PIPE_ERROR_OUT_OF_MEMORY;
1126
1127 cmd->cid = swc->cid;
1128 cmd->rect = *rect;
1129 swc->commit(swc);
1130
1131 return PIPE_OK;
1132 }
1133
1134 /*
1135 *----------------------------------------------------------------------
1136 *
1137 * SVGA3D_SetClipPlane --
1138 *
1139 * Set one of the current context's clip planes. If the clip
1140 * plane is enabled then all 3d rendering is clipped to against
1141 * the plane.
1142 *
1143 * Results:
1144 * None.
1145 *
1146 * Side effects:
1147 * None.
1148 *
1149 *----------------------------------------------------------------------
1150 */
1151
1152 enum pipe_error SVGA3D_SetClipPlane(struct svga_winsys_context *swc,
1153 uint32 index, const float *plane)
1154 {
1155 SVGA3dCmdSetClipPlane *cmd;
1156
1157 cmd = SVGA3D_FIFOReserve(swc,
1158 SVGA_3D_CMD_SETCLIPPLANE, sizeof *cmd,
1159 0);
1160 if(!cmd)
1161 return PIPE_ERROR_OUT_OF_MEMORY;
1162
1163 cmd->cid = swc->cid;
1164 cmd->index = index;
1165 cmd->plane[0] = plane[0];
1166 cmd->plane[1] = plane[1];
1167 cmd->plane[2] = plane[2];
1168 cmd->plane[3] = plane[3];
1169 swc->commit(swc);
1170
1171 return PIPE_OK;
1172 }
1173
1174 /*
1175 *----------------------------------------------------------------------
1176 *
1177 * SVGA3D_SetZRange --
1178 *
1179 * Set the range of the depth buffer to use. 'min' and 'max'
1180 * are values between 0.0 and 1.0.
1181 *
1182 * Results:
1183 * None.
1184 *
1185 * Side effects:
1186 * None.
1187 *
1188 *----------------------------------------------------------------------
1189 */
1190
1191 enum pipe_error
1192 SVGA3D_SetZRange(struct svga_winsys_context *swc,
1193 float zMin, // IN
1194 float zMax) // IN
1195 {
1196 SVGA3dCmdSetZRange *cmd;
1197
1198 cmd = SVGA3D_FIFOReserve(swc,
1199 SVGA_3D_CMD_SETZRANGE, sizeof *cmd,
1200 0);
1201 if(!cmd)
1202 return PIPE_ERROR_OUT_OF_MEMORY;
1203
1204 cmd->cid = swc->cid;
1205 cmd->zRange.min = zMin;
1206 cmd->zRange.max = zMax;
1207 swc->commit(swc);
1208
1209 return PIPE_OK;
1210 }
1211
1212
1213 /*
1214 *----------------------------------------------------------------------
1215 *
1216 * SVGA3D_BeginSetTextureState --
1217 *
1218 * Begin a SETTEXTURESTATE command. This reserves space for it in
1219 * the FIFO, and returns a pointer to the command's texture state
1220 * array. This function must be paired with SVGA_FIFOCommitAll().
1221 *
1222 * This command sets rendering state which is per-texture-unit.
1223 *
1224 * XXX: Individual texture states need documentation. However,
1225 * they are very similar to the texture states defined by
1226 * Direct3D. The D3D documentation is a good starting point
1227 * for understanding SVGA3D texture states.
1228 *
1229 * Results:
1230 * None.
1231 *
1232 * Side effects:
1233 * None.
1234 *
1235 *----------------------------------------------------------------------
1236 */
1237
1238 enum pipe_error
1239 SVGA3D_BeginSetTextureState(struct svga_winsys_context *swc,
1240 SVGA3dTextureState **states, // OUT
1241 uint32 numStates) // IN
1242 {
1243 SVGA3dCmdSetTextureState *cmd;
1244
1245 cmd = SVGA3D_FIFOReserve(swc,
1246 SVGA_3D_CMD_SETTEXTURESTATE,
1247 sizeof *cmd + sizeof **states * numStates,
1248 numStates);
1249 if(!cmd)
1250 return PIPE_ERROR_OUT_OF_MEMORY;
1251
1252 cmd->cid = swc->cid;
1253 *states = (SVGA3dTextureState*) &cmd[1];
1254
1255 return PIPE_OK;
1256 }
1257
1258
1259 /*
1260 *----------------------------------------------------------------------
1261 *
1262 * SVGA3D_BeginSetRenderState --
1263 *
1264 * Begin a SETRENDERSTATE command. This reserves space for it in
1265 * the FIFO, and returns a pointer to the command's texture state
1266 * array. This function must be paired with SVGA_FIFOCommitAll().
1267 *
1268 * This command sets rendering state which is global to the context.
1269 *
1270 * XXX: Individual render states need documentation. However,
1271 * they are very similar to the render states defined by
1272 * Direct3D. The D3D documentation is a good starting point
1273 * for understanding SVGA3D render states.
1274 *
1275 * Results:
1276 * None.
1277 *
1278 * Side effects:
1279 * None.
1280 *
1281 *----------------------------------------------------------------------
1282 */
1283
1284 enum pipe_error
1285 SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc,
1286 SVGA3dRenderState **states, // OUT
1287 uint32 numStates) // IN
1288 {
1289 SVGA3dCmdSetRenderState *cmd;
1290
1291 cmd = SVGA3D_FIFOReserve(swc,
1292 SVGA_3D_CMD_SETRENDERSTATE,
1293 sizeof *cmd + sizeof **states * numStates,
1294 0);
1295 if(!cmd)
1296 return PIPE_ERROR_OUT_OF_MEMORY;
1297
1298 cmd->cid = swc->cid;
1299 *states = (SVGA3dRenderState*) &cmd[1];
1300
1301 return PIPE_OK;
1302 }
1303
1304
1305 /*
1306 *----------------------------------------------------------------------
1307 *
1308 * SVGA3D_BeginQuery--
1309 *
1310 * Issues a SVGA_3D_CMD_BEGIN_QUERY command.
1311 *
1312 * Results:
1313 * None.
1314 *
1315 * Side effects:
1316 * Commits space in the FIFO memory.
1317 *
1318 *----------------------------------------------------------------------
1319 */
1320
1321 enum pipe_error
1322 SVGA3D_BeginQuery(struct svga_winsys_context *swc,
1323 SVGA3dQueryType type) // IN
1324 {
1325 SVGA3dCmdBeginQuery *cmd;
1326
1327 cmd = SVGA3D_FIFOReserve(swc,
1328 SVGA_3D_CMD_BEGIN_QUERY,
1329 sizeof *cmd,
1330 0);
1331 if(!cmd)
1332 return PIPE_ERROR_OUT_OF_MEMORY;
1333
1334 cmd->cid = swc->cid;
1335 cmd->type = type;
1336
1337 swc->commit(swc);
1338
1339 return PIPE_OK;
1340 }
1341
1342
1343 /*
1344 *----------------------------------------------------------------------
1345 *
1346 * SVGA3D_EndQuery--
1347 *
1348 * Issues a SVGA_3D_CMD_END_QUERY command.
1349 *
1350 * Results:
1351 * None.
1352 *
1353 * Side effects:
1354 * Commits space in the FIFO memory.
1355 *
1356 *----------------------------------------------------------------------
1357 */
1358
1359 enum pipe_error
1360 SVGA3D_EndQuery(struct svga_winsys_context *swc,
1361 SVGA3dQueryType type, // IN
1362 struct svga_winsys_buffer *buffer) // IN/OUT
1363 {
1364 SVGA3dCmdEndQuery *cmd;
1365
1366 cmd = SVGA3D_FIFOReserve(swc,
1367 SVGA_3D_CMD_END_QUERY,
1368 sizeof *cmd,
1369 1);
1370 if(!cmd)
1371 return PIPE_ERROR_OUT_OF_MEMORY;
1372
1373 cmd->cid = swc->cid;
1374 cmd->type = type;
1375
1376 swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
1377 SVGA_RELOC_WRITE);
1378
1379 swc->commit(swc);
1380
1381 return PIPE_OK;
1382 }
1383
1384
1385 /*
1386 *----------------------------------------------------------------------
1387 *
1388 * SVGA3D_WaitForQuery--
1389 *
1390 * Issues a SVGA_3D_CMD_WAIT_FOR_QUERY command. This reserves space
1391 * for it in the FIFO. This doesn't actually wait for the query to
1392 * finish but instead tells the host to start a wait at the driver
1393 * level. The caller can wait on the status variable in the
1394 * guestPtr memory or send an insert fence instruction after this
1395 * command and wait on the fence.
1396 *
1397 * Results:
1398 * None.
1399 *
1400 * Side effects:
1401 * Commits space in the FIFO memory.
1402 *
1403 *----------------------------------------------------------------------
1404 */
1405
1406 enum pipe_error
1407 SVGA3D_WaitForQuery(struct svga_winsys_context *swc,
1408 SVGA3dQueryType type, // IN
1409 struct svga_winsys_buffer *buffer) // IN/OUT
1410 {
1411 SVGA3dCmdWaitForQuery *cmd;
1412
1413 cmd = SVGA3D_FIFOReserve(swc,
1414 SVGA_3D_CMD_WAIT_FOR_QUERY,
1415 sizeof *cmd,
1416 1);
1417 if(!cmd)
1418 return PIPE_ERROR_OUT_OF_MEMORY;
1419
1420 cmd->cid = swc->cid;
1421 cmd->type = type;
1422
1423 swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
1424 SVGA_RELOC_WRITE);
1425
1426 swc->commit(swc);
1427
1428 return PIPE_OK;
1429 }