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