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