Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/svga/svga_pipe_depthstencil.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
#include "pipe/p_defines.h"
27
#include "util/u_bitmask.h"
28
#include "util/u_inlines.h"
29
#include "util/u_math.h"
30
#include "util/u_memory.h"
31
32
#include "svga_context.h"
33
#include "svga_hw_reg.h"
34
#include "svga_cmd.h"
35
36
37
static inline unsigned
38
svga_translate_compare_func(unsigned func)
39
{
40
switch (func) {
41
case PIPE_FUNC_NEVER: return SVGA3D_CMP_NEVER;
42
case PIPE_FUNC_LESS: return SVGA3D_CMP_LESS;
43
case PIPE_FUNC_LEQUAL: return SVGA3D_CMP_LESSEQUAL;
44
case PIPE_FUNC_GREATER: return SVGA3D_CMP_GREATER;
45
case PIPE_FUNC_GEQUAL: return SVGA3D_CMP_GREATEREQUAL;
46
case PIPE_FUNC_NOTEQUAL: return SVGA3D_CMP_NOTEQUAL;
47
case PIPE_FUNC_EQUAL: return SVGA3D_CMP_EQUAL;
48
case PIPE_FUNC_ALWAYS: return SVGA3D_CMP_ALWAYS;
49
default:
50
assert(0);
51
return SVGA3D_CMP_ALWAYS;
52
}
53
}
54
55
static inline unsigned
56
svga_translate_stencil_op(unsigned op)
57
{
58
switch (op) {
59
case PIPE_STENCIL_OP_KEEP: return SVGA3D_STENCILOP_KEEP;
60
case PIPE_STENCIL_OP_ZERO: return SVGA3D_STENCILOP_ZERO;
61
case PIPE_STENCIL_OP_REPLACE: return SVGA3D_STENCILOP_REPLACE;
62
case PIPE_STENCIL_OP_INCR: return SVGA3D_STENCILOP_INCRSAT;
63
case PIPE_STENCIL_OP_DECR: return SVGA3D_STENCILOP_DECRSAT;
64
case PIPE_STENCIL_OP_INCR_WRAP: return SVGA3D_STENCILOP_INCR;
65
case PIPE_STENCIL_OP_DECR_WRAP: return SVGA3D_STENCILOP_DECR;
66
case PIPE_STENCIL_OP_INVERT: return SVGA3D_STENCILOP_INVERT;
67
default:
68
assert(0);
69
return SVGA3D_STENCILOP_KEEP;
70
}
71
}
72
73
74
/**
75
* Define a vgpu10 depth/stencil state object for the given
76
* svga depth/stencil state.
77
*/
78
static void
79
define_depth_stencil_state_object(struct svga_context *svga,
80
struct svga_depth_stencil_state *ds)
81
{
82
assert(svga_have_vgpu10(svga));
83
84
ds->id = util_bitmask_add(svga->ds_object_id_bm);
85
86
/* spot check that these comparision tokens are the same */
87
STATIC_ASSERT(SVGA3D_COMPARISON_NEVER == SVGA3D_CMP_NEVER);
88
STATIC_ASSERT(SVGA3D_COMPARISON_LESS == SVGA3D_CMP_LESS);
89
STATIC_ASSERT(SVGA3D_COMPARISON_NOT_EQUAL == SVGA3D_CMP_NOTEQUAL);
90
91
/* Note: we use the ds->stencil[0].enabled value for both the front
92
* and back-face enables. If single-side stencil is used, we'll have
93
* set the back state the same as the front state.
94
*/
95
SVGA_RETRY(svga, SVGA3D_vgpu10_DefineDepthStencilState
96
(svga->swc,
97
ds->id,
98
/* depth/Z */
99
ds->zenable,
100
ds->zwriteenable,
101
ds->zfunc,
102
/* Stencil */
103
ds->stencil[0].enabled, /*f|b*/
104
ds->stencil[0].enabled, /*f*/
105
ds->stencil[0].enabled, /*b*/
106
ds->stencil_mask,
107
ds->stencil_writemask,
108
/* front stencil */
109
ds->stencil[0].fail,
110
ds->stencil[0].zfail,
111
ds->stencil[0].pass,
112
ds->stencil[0].func,
113
/* back stencil */
114
ds->stencil[1].fail,
115
ds->stencil[1].zfail,
116
ds->stencil[1].pass,
117
ds->stencil[1].func));
118
}
119
120
121
static void *
122
svga_create_depth_stencil_state(struct pipe_context *pipe,
123
const struct pipe_depth_stencil_alpha_state *templ)
124
{
125
struct svga_context *svga = svga_context(pipe);
126
struct svga_depth_stencil_state *ds = CALLOC_STRUCT(svga_depth_stencil_state);
127
128
if (!ds)
129
return NULL;
130
131
/* Don't try to figure out CW/CCW correspondence with
132
* stencil[0]/[1] at this point. Presumably this can change as
133
* back/front face are modified.
134
*/
135
ds->stencil[0].enabled = templ->stencil[0].enabled;
136
if (ds->stencil[0].enabled) {
137
ds->stencil[0].func = svga_translate_compare_func(templ->stencil[0].func);
138
ds->stencil[0].fail = svga_translate_stencil_op(templ->stencil[0].fail_op);
139
ds->stencil[0].zfail = svga_translate_stencil_op(templ->stencil[0].zfail_op);
140
ds->stencil[0].pass = svga_translate_stencil_op(templ->stencil[0].zpass_op);
141
142
/* SVGA3D has one ref/mask/writemask triple shared between front &
143
* back face stencil. We really need two:
144
*/
145
ds->stencil_mask = templ->stencil[0].valuemask & 0xff;
146
ds->stencil_writemask = templ->stencil[0].writemask & 0xff;
147
}
148
else {
149
ds->stencil[0].func = SVGA3D_CMP_ALWAYS;
150
ds->stencil[0].fail = SVGA3D_STENCILOP_KEEP;
151
ds->stencil[0].zfail = SVGA3D_STENCILOP_KEEP;
152
ds->stencil[0].pass = SVGA3D_STENCILOP_KEEP;
153
}
154
155
ds->stencil[1].enabled = templ->stencil[1].enabled;
156
if (templ->stencil[1].enabled) {
157
assert(templ->stencil[0].enabled);
158
/* two-sided stencil */
159
ds->stencil[1].func = svga_translate_compare_func(templ->stencil[1].func);
160
ds->stencil[1].fail = svga_translate_stencil_op(templ->stencil[1].fail_op);
161
ds->stencil[1].zfail = svga_translate_stencil_op(templ->stencil[1].zfail_op);
162
ds->stencil[1].pass = svga_translate_stencil_op(templ->stencil[1].zpass_op);
163
164
ds->stencil_mask = templ->stencil[1].valuemask & 0xff;
165
ds->stencil_writemask = templ->stencil[1].writemask & 0xff;
166
167
if (templ->stencil[1].valuemask != templ->stencil[0].valuemask) {
168
pipe_debug_message(&svga->debug.callback, CONFORMANCE,
169
"two-sided stencil mask not supported "
170
"(front=0x%x, back=0x%x)",
171
templ->stencil[0].valuemask,
172
templ->stencil[1].valuemask);
173
}
174
if (templ->stencil[1].writemask != templ->stencil[0].writemask) {
175
pipe_debug_message(&svga->debug.callback, CONFORMANCE,
176
"two-sided stencil writemask not supported "
177
"(front=0x%x, back=0x%x)",
178
templ->stencil[0].writemask,
179
templ->stencil[1].writemask);
180
}
181
}
182
else {
183
/* back face state is same as front-face state */
184
ds->stencil[1].func = ds->stencil[0].func;
185
ds->stencil[1].fail = ds->stencil[0].fail;
186
ds->stencil[1].zfail = ds->stencil[0].zfail;
187
ds->stencil[1].pass = ds->stencil[0].pass;
188
}
189
190
191
ds->zenable = templ->depth_enabled;
192
if (ds->zenable) {
193
ds->zfunc = svga_translate_compare_func(templ->depth_func);
194
ds->zwriteenable = templ->depth_writemask;
195
}
196
else {
197
ds->zfunc = SVGA3D_CMP_ALWAYS;
198
}
199
200
ds->alphatestenable = templ->alpha_enabled;
201
if (ds->alphatestenable) {
202
ds->alphafunc = svga_translate_compare_func(templ->alpha_func);
203
ds->alpharef = templ->alpha_ref_value;
204
}
205
else {
206
ds->alphafunc = SVGA3D_CMP_ALWAYS;
207
}
208
209
if (svga_have_vgpu10(svga)) {
210
define_depth_stencil_state_object(svga, ds);
211
}
212
213
svga->hud.num_depthstencil_objects++;
214
215
SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws,
216
SVGA_STATS_COUNT_DEPTHSTENCILSTATE);
217
218
return ds;
219
}
220
221
222
static void
223
svga_bind_depth_stencil_state(struct pipe_context *pipe, void *depth_stencil)
224
{
225
struct svga_context *svga = svga_context(pipe);
226
227
if (svga_have_vgpu10(svga)) {
228
/* flush any previously queued drawing before changing state */
229
svga_hwtnl_flush_retry(svga);
230
}
231
232
svga->curr.depth = (const struct svga_depth_stencil_state *)depth_stencil;
233
svga->dirty |= SVGA_NEW_DEPTH_STENCIL_ALPHA;
234
}
235
236
237
static void
238
svga_delete_depth_stencil_state(struct pipe_context *pipe, void *depth_stencil)
239
{
240
struct svga_context *svga = svga_context(pipe);
241
struct svga_depth_stencil_state *ds =
242
(struct svga_depth_stencil_state *) depth_stencil;
243
244
if (svga_have_vgpu10(svga)) {
245
svga_hwtnl_flush_retry(svga);
246
247
assert(ds->id != SVGA3D_INVALID_ID);
248
249
SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyDepthStencilState(svga->swc,
250
ds->id));
251
252
if (ds->id == svga->state.hw_draw.depth_stencil_id)
253
svga->state.hw_draw.depth_stencil_id = SVGA3D_INVALID_ID;
254
255
util_bitmask_clear(svga->ds_object_id_bm, ds->id);
256
ds->id = SVGA3D_INVALID_ID;
257
}
258
259
FREE(depth_stencil);
260
svga->hud.num_depthstencil_objects--;
261
}
262
263
264
static void
265
svga_set_stencil_ref(struct pipe_context *pipe,
266
const struct pipe_stencil_ref stencil_ref)
267
{
268
struct svga_context *svga = svga_context(pipe);
269
270
if (svga_have_vgpu10(svga)) {
271
/* flush any previously queued drawing before changing state */
272
svga_hwtnl_flush_retry(svga);
273
}
274
275
svga->curr.stencil_ref = stencil_ref;
276
277
svga->dirty |= SVGA_NEW_STENCIL_REF;
278
}
279
280
281
static void
282
svga_set_sample_mask(struct pipe_context *pipe,
283
unsigned sample_mask)
284
{
285
struct svga_context *svga = svga_context(pipe);
286
287
svga->curr.sample_mask = sample_mask;
288
289
svga->dirty |= SVGA_NEW_BLEND; /* See emit_rss_vgpu10() */
290
}
291
292
293
static void
294
svga_set_min_samples(struct pipe_context *pipe, unsigned min_samples)
295
{
296
/* This specifies the minimum number of times the fragment shader
297
* must run when doing per-sample shading for a MSAA render target.
298
* For our SVGA3D device, the FS is automatically run in per-sample
299
* mode if it uses the sample ID or sample position registers.
300
*/
301
}
302
303
304
void
305
svga_init_depth_stencil_functions(struct svga_context *svga)
306
{
307
svga->pipe.create_depth_stencil_alpha_state = svga_create_depth_stencil_state;
308
svga->pipe.bind_depth_stencil_alpha_state = svga_bind_depth_stencil_state;
309
svga->pipe.delete_depth_stencil_alpha_state = svga_delete_depth_stencil_state;
310
311
svga->pipe.set_stencil_ref = svga_set_stencil_ref;
312
svga->pipe.set_sample_mask = svga_set_sample_mask;
313
svga->pipe.set_min_samples = svga_set_min_samples;
314
}
315
316