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