Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/zink/zink_state.c
4570 views
1
/*
2
* Copyright 2018 Collabora Ltd.
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* on the rights to use, copy, modify, merge, publish, distribute, sub
8
* license, and/or sell copies of the Software, and to permit persons to whom
9
* the Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21
* USE OR OTHER DEALINGS IN THE SOFTWARE.
22
*/
23
24
#include "zink_state.h"
25
26
#include "zink_context.h"
27
#include "zink_screen.h"
28
29
#include "compiler/shader_enums.h"
30
#include "util/u_dual_blend.h"
31
#include "util/u_memory.h"
32
33
#include <math.h>
34
35
static void *
36
zink_create_vertex_elements_state(struct pipe_context *pctx,
37
unsigned num_elements,
38
const struct pipe_vertex_element *elements)
39
{
40
struct zink_screen *screen = zink_screen(pctx->screen);
41
unsigned int i;
42
struct zink_vertex_elements_state *ves = CALLOC_STRUCT(zink_vertex_elements_state);
43
if (!ves)
44
return NULL;
45
46
int buffer_map[PIPE_MAX_ATTRIBS];
47
for (int i = 0; i < ARRAY_SIZE(buffer_map); ++i)
48
buffer_map[i] = -1;
49
50
int num_bindings = 0;
51
for (i = 0; i < num_elements; ++i) {
52
const struct pipe_vertex_element *elem = elements + i;
53
54
int binding = elem->vertex_buffer_index;
55
if (buffer_map[binding] < 0) {
56
ves->binding_map[num_bindings] = binding;
57
buffer_map[binding] = num_bindings++;
58
}
59
binding = buffer_map[binding];
60
61
62
ves->bindings[binding].binding = binding;
63
ves->bindings[binding].inputRate = elem->instance_divisor ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
64
65
assert(!elem->instance_divisor || zink_screen(pctx->screen)->info.have_EXT_vertex_attribute_divisor);
66
ves->divisor[binding] = elem->instance_divisor;
67
assert(elem->instance_divisor <= screen->info.vdiv_props.maxVertexAttribDivisor);
68
69
ves->hw_state.attribs[i].binding = binding;
70
ves->hw_state.attribs[i].location = i;
71
ves->hw_state.attribs[i].format = zink_get_format(screen,
72
elem->src_format);
73
assert(ves->hw_state.attribs[i].format != VK_FORMAT_UNDEFINED);
74
ves->hw_state.attribs[i].offset = elem->src_offset;
75
}
76
77
ves->hw_state.num_bindings = num_bindings;
78
ves->hw_state.num_attribs = num_elements;
79
for (int i = 0; i < num_bindings; ++i) {
80
ves->hw_state.bindings[i].binding = ves->bindings[i].binding;
81
ves->hw_state.bindings[i].inputRate = ves->bindings[i].inputRate;
82
if (ves->divisor[i]) {
83
ves->hw_state.divisors[ves->hw_state.divisors_present].divisor = ves->divisor[i];
84
ves->hw_state.divisors[ves->hw_state.divisors_present].binding = ves->bindings[i].binding;
85
ves->hw_state.divisors_present++;
86
}
87
}
88
return ves;
89
}
90
91
static void
92
zink_bind_vertex_elements_state(struct pipe_context *pctx,
93
void *cso)
94
{
95
struct zink_context *ctx = zink_context(pctx);
96
struct zink_gfx_pipeline_state *state = &ctx->gfx_pipeline_state;
97
ctx->element_state = cso;
98
if (cso) {
99
if (state->element_state != &ctx->element_state->hw_state) {
100
state->vertex_state_dirty = true;
101
ctx->vertex_buffers_dirty = ctx->element_state->hw_state.num_bindings > 0;
102
}
103
state->element_state = &ctx->element_state->hw_state;
104
} else {
105
state->element_state = NULL;
106
ctx->vertex_buffers_dirty = false;
107
}
108
}
109
110
static void
111
zink_delete_vertex_elements_state(struct pipe_context *pctx,
112
void *ves)
113
{
114
FREE(ves);
115
}
116
117
static VkBlendFactor
118
blend_factor(enum pipe_blendfactor factor)
119
{
120
switch (factor) {
121
case PIPE_BLENDFACTOR_ONE: return VK_BLEND_FACTOR_ONE;
122
case PIPE_BLENDFACTOR_SRC_COLOR: return VK_BLEND_FACTOR_SRC_COLOR;
123
case PIPE_BLENDFACTOR_SRC_ALPHA: return VK_BLEND_FACTOR_SRC_ALPHA;
124
case PIPE_BLENDFACTOR_DST_ALPHA: return VK_BLEND_FACTOR_DST_ALPHA;
125
case PIPE_BLENDFACTOR_DST_COLOR: return VK_BLEND_FACTOR_DST_COLOR;
126
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
127
return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
128
case PIPE_BLENDFACTOR_CONST_COLOR: return VK_BLEND_FACTOR_CONSTANT_COLOR;
129
case PIPE_BLENDFACTOR_CONST_ALPHA: return VK_BLEND_FACTOR_CONSTANT_ALPHA;
130
case PIPE_BLENDFACTOR_SRC1_COLOR: return VK_BLEND_FACTOR_SRC1_COLOR;
131
case PIPE_BLENDFACTOR_SRC1_ALPHA: return VK_BLEND_FACTOR_SRC1_ALPHA;
132
133
case PIPE_BLENDFACTOR_ZERO: return VK_BLEND_FACTOR_ZERO;
134
135
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
136
return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
137
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
138
return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
139
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
140
return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
141
case PIPE_BLENDFACTOR_INV_DST_COLOR:
142
return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
143
144
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
145
return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
146
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
147
return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
148
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
149
return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
150
case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
151
return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
152
}
153
unreachable("unexpected blend factor");
154
}
155
156
157
static bool
158
need_blend_constants(enum pipe_blendfactor factor)
159
{
160
switch (factor) {
161
case PIPE_BLENDFACTOR_CONST_COLOR:
162
case PIPE_BLENDFACTOR_CONST_ALPHA:
163
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
164
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
165
return true;
166
167
default:
168
return false;
169
}
170
}
171
172
static VkBlendOp
173
blend_op(enum pipe_blend_func func)
174
{
175
switch (func) {
176
case PIPE_BLEND_ADD: return VK_BLEND_OP_ADD;
177
case PIPE_BLEND_SUBTRACT: return VK_BLEND_OP_SUBTRACT;
178
case PIPE_BLEND_REVERSE_SUBTRACT: return VK_BLEND_OP_REVERSE_SUBTRACT;
179
case PIPE_BLEND_MIN: return VK_BLEND_OP_MIN;
180
case PIPE_BLEND_MAX: return VK_BLEND_OP_MAX;
181
}
182
unreachable("unexpected blend function");
183
}
184
185
static VkLogicOp
186
logic_op(enum pipe_logicop func)
187
{
188
switch (func) {
189
case PIPE_LOGICOP_CLEAR: return VK_LOGIC_OP_CLEAR;
190
case PIPE_LOGICOP_NOR: return VK_LOGIC_OP_NOR;
191
case PIPE_LOGICOP_AND_INVERTED: return VK_LOGIC_OP_AND_INVERTED;
192
case PIPE_LOGICOP_COPY_INVERTED: return VK_LOGIC_OP_COPY_INVERTED;
193
case PIPE_LOGICOP_AND_REVERSE: return VK_LOGIC_OP_AND_REVERSE;
194
case PIPE_LOGICOP_INVERT: return VK_LOGIC_OP_INVERT;
195
case PIPE_LOGICOP_XOR: return VK_LOGIC_OP_XOR;
196
case PIPE_LOGICOP_NAND: return VK_LOGIC_OP_NAND;
197
case PIPE_LOGICOP_AND: return VK_LOGIC_OP_AND;
198
case PIPE_LOGICOP_EQUIV: return VK_LOGIC_OP_EQUIVALENT;
199
case PIPE_LOGICOP_NOOP: return VK_LOGIC_OP_NO_OP;
200
case PIPE_LOGICOP_OR_INVERTED: return VK_LOGIC_OP_OR_INVERTED;
201
case PIPE_LOGICOP_COPY: return VK_LOGIC_OP_COPY;
202
case PIPE_LOGICOP_OR_REVERSE: return VK_LOGIC_OP_OR_REVERSE;
203
case PIPE_LOGICOP_OR: return VK_LOGIC_OP_OR;
204
case PIPE_LOGICOP_SET: return VK_LOGIC_OP_SET;
205
}
206
unreachable("unexpected logicop function");
207
}
208
209
/* from iris */
210
static enum pipe_blendfactor
211
fix_blendfactor(enum pipe_blendfactor f, bool alpha_to_one)
212
{
213
if (alpha_to_one) {
214
if (f == PIPE_BLENDFACTOR_SRC1_ALPHA)
215
return PIPE_BLENDFACTOR_ONE;
216
217
if (f == PIPE_BLENDFACTOR_INV_SRC1_ALPHA)
218
return PIPE_BLENDFACTOR_ZERO;
219
}
220
221
return f;
222
}
223
224
static void *
225
zink_create_blend_state(struct pipe_context *pctx,
226
const struct pipe_blend_state *blend_state)
227
{
228
struct zink_blend_state *cso = CALLOC_STRUCT(zink_blend_state);
229
if (!cso)
230
return NULL;
231
232
if (blend_state->logicop_enable) {
233
cso->logicop_enable = VK_TRUE;
234
cso->logicop_func = logic_op(blend_state->logicop_func);
235
}
236
237
/* TODO: figure out what to do with dither (nothing is probably "OK" for now,
238
* as dithering is undefined in GL
239
*/
240
241
/* TODO: these are multisampling-state, and should be set there instead of
242
* here, as that's closer tied to the update-frequency
243
*/
244
cso->alpha_to_coverage = blend_state->alpha_to_coverage;
245
cso->alpha_to_one = blend_state->alpha_to_one;
246
247
cso->need_blend_constants = false;
248
249
for (int i = 0; i < blend_state->max_rt + 1; ++i) {
250
const struct pipe_rt_blend_state *rt = blend_state->rt;
251
if (blend_state->independent_blend_enable)
252
rt = blend_state->rt + i;
253
254
VkPipelineColorBlendAttachmentState att = {0};
255
256
if (rt->blend_enable) {
257
att.blendEnable = VK_TRUE;
258
att.srcColorBlendFactor = blend_factor(fix_blendfactor(rt->rgb_src_factor, cso->alpha_to_one));
259
att.dstColorBlendFactor = blend_factor(fix_blendfactor(rt->rgb_dst_factor, cso->alpha_to_one));
260
att.colorBlendOp = blend_op(rt->rgb_func);
261
att.srcAlphaBlendFactor = blend_factor(fix_blendfactor(rt->alpha_src_factor, cso->alpha_to_one));
262
att.dstAlphaBlendFactor = blend_factor(fix_blendfactor(rt->alpha_dst_factor, cso->alpha_to_one));
263
att.alphaBlendOp = blend_op(rt->alpha_func);
264
265
if (need_blend_constants(rt->rgb_src_factor) ||
266
need_blend_constants(rt->rgb_dst_factor) ||
267
need_blend_constants(rt->alpha_src_factor) ||
268
need_blend_constants(rt->alpha_dst_factor))
269
cso->need_blend_constants = true;
270
}
271
272
if (rt->colormask & PIPE_MASK_R)
273
att.colorWriteMask |= VK_COLOR_COMPONENT_R_BIT;
274
if (rt->colormask & PIPE_MASK_G)
275
att.colorWriteMask |= VK_COLOR_COMPONENT_G_BIT;
276
if (rt->colormask & PIPE_MASK_B)
277
att.colorWriteMask |= VK_COLOR_COMPONENT_B_BIT;
278
if (rt->colormask & PIPE_MASK_A)
279
att.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT;
280
281
cso->attachments[i] = att;
282
}
283
cso->dual_src_blend = util_blend_state_is_dual(blend_state, 0);
284
285
return cso;
286
}
287
288
static void
289
zink_bind_blend_state(struct pipe_context *pctx, void *cso)
290
{
291
struct zink_gfx_pipeline_state* state = &zink_context(pctx)->gfx_pipeline_state;
292
293
if (state->blend_state != cso) {
294
state->blend_state = cso;
295
state->dirty = true;
296
}
297
}
298
299
static void
300
zink_delete_blend_state(struct pipe_context *pctx, void *blend_state)
301
{
302
FREE(blend_state);
303
}
304
305
static VkCompareOp
306
compare_op(enum pipe_compare_func func)
307
{
308
switch (func) {
309
case PIPE_FUNC_NEVER: return VK_COMPARE_OP_NEVER;
310
case PIPE_FUNC_LESS: return VK_COMPARE_OP_LESS;
311
case PIPE_FUNC_EQUAL: return VK_COMPARE_OP_EQUAL;
312
case PIPE_FUNC_LEQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL;
313
case PIPE_FUNC_GREATER: return VK_COMPARE_OP_GREATER;
314
case PIPE_FUNC_NOTEQUAL: return VK_COMPARE_OP_NOT_EQUAL;
315
case PIPE_FUNC_GEQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL;
316
case PIPE_FUNC_ALWAYS: return VK_COMPARE_OP_ALWAYS;
317
}
318
unreachable("unexpected func");
319
}
320
321
static VkStencilOp
322
stencil_op(enum pipe_stencil_op op)
323
{
324
switch (op) {
325
case PIPE_STENCIL_OP_KEEP: return VK_STENCIL_OP_KEEP;
326
case PIPE_STENCIL_OP_ZERO: return VK_STENCIL_OP_ZERO;
327
case PIPE_STENCIL_OP_REPLACE: return VK_STENCIL_OP_REPLACE;
328
case PIPE_STENCIL_OP_INCR: return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
329
case PIPE_STENCIL_OP_DECR: return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
330
case PIPE_STENCIL_OP_INCR_WRAP: return VK_STENCIL_OP_INCREMENT_AND_WRAP;
331
case PIPE_STENCIL_OP_DECR_WRAP: return VK_STENCIL_OP_DECREMENT_AND_WRAP;
332
case PIPE_STENCIL_OP_INVERT: return VK_STENCIL_OP_INVERT;
333
}
334
unreachable("unexpected op");
335
}
336
337
static VkStencilOpState
338
stencil_op_state(const struct pipe_stencil_state *src)
339
{
340
VkStencilOpState ret;
341
ret.failOp = stencil_op(src->fail_op);
342
ret.passOp = stencil_op(src->zpass_op);
343
ret.depthFailOp = stencil_op(src->zfail_op);
344
ret.compareOp = compare_op(src->func);
345
ret.compareMask = src->valuemask;
346
ret.writeMask = src->writemask;
347
ret.reference = 0; // not used: we'll use a dynamic state for this
348
return ret;
349
}
350
351
static void *
352
zink_create_depth_stencil_alpha_state(struct pipe_context *pctx,
353
const struct pipe_depth_stencil_alpha_state *depth_stencil_alpha)
354
{
355
struct zink_depth_stencil_alpha_state *cso = CALLOC_STRUCT(zink_depth_stencil_alpha_state);
356
if (!cso)
357
return NULL;
358
359
cso->base = *depth_stencil_alpha;
360
361
if (depth_stencil_alpha->depth_enabled) {
362
cso->hw_state.depth_test = VK_TRUE;
363
cso->hw_state.depth_compare_op = compare_op(depth_stencil_alpha->depth_func);
364
}
365
366
if (depth_stencil_alpha->depth_bounds_test) {
367
cso->hw_state.depth_bounds_test = VK_TRUE;
368
cso->hw_state.min_depth_bounds = depth_stencil_alpha->depth_bounds_min;
369
cso->hw_state.max_depth_bounds = depth_stencil_alpha->depth_bounds_max;
370
}
371
372
if (depth_stencil_alpha->stencil[0].enabled) {
373
cso->hw_state.stencil_test = VK_TRUE;
374
cso->hw_state.stencil_front = stencil_op_state(depth_stencil_alpha->stencil);
375
}
376
377
if (depth_stencil_alpha->stencil[1].enabled)
378
cso->hw_state.stencil_back = stencil_op_state(depth_stencil_alpha->stencil + 1);
379
else
380
cso->hw_state.stencil_back = cso->hw_state.stencil_front;
381
382
cso->hw_state.depth_write = depth_stencil_alpha->depth_writemask;
383
384
return cso;
385
}
386
387
static void
388
zink_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *cso)
389
{
390
struct zink_context *ctx = zink_context(pctx);
391
392
bool prev_zwrite = ctx->dsa_state ? ctx->dsa_state->hw_state.depth_write : false;
393
ctx->dsa_state = cso;
394
395
if (cso) {
396
struct zink_gfx_pipeline_state *state = &ctx->gfx_pipeline_state;
397
if (state->depth_stencil_alpha_state != &ctx->dsa_state->hw_state) {
398
state->depth_stencil_alpha_state = &ctx->dsa_state->hw_state;
399
state->dirty |= !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state;
400
ctx->dsa_state_changed = true;
401
}
402
}
403
if (prev_zwrite != (ctx->dsa_state ? ctx->dsa_state->hw_state.depth_write : false)) {
404
ctx->rp_changed = true;
405
zink_batch_no_rp(ctx);
406
}
407
}
408
409
static void
410
zink_delete_depth_stencil_alpha_state(struct pipe_context *pctx,
411
void *depth_stencil_alpha)
412
{
413
FREE(depth_stencil_alpha);
414
}
415
416
static float
417
round_to_granularity(float value, float granularity)
418
{
419
return roundf(value / granularity) * granularity;
420
}
421
422
static float
423
line_width(float width, float granularity, const float range[2])
424
{
425
assert(granularity >= 0);
426
assert(range[0] <= range[1]);
427
428
if (granularity > 0)
429
width = round_to_granularity(width, granularity);
430
431
return CLAMP(width, range[0], range[1]);
432
}
433
434
static void *
435
zink_create_rasterizer_state(struct pipe_context *pctx,
436
const struct pipe_rasterizer_state *rs_state)
437
{
438
struct zink_screen *screen = zink_screen(pctx->screen);
439
440
struct zink_rasterizer_state *state = CALLOC_STRUCT(zink_rasterizer_state);
441
if (!state)
442
return NULL;
443
444
state->base = *rs_state;
445
446
assert(rs_state->depth_clip_far == rs_state->depth_clip_near);
447
state->hw_state.depth_clamp = rs_state->depth_clip_near == 0;
448
state->hw_state.rasterizer_discard = rs_state->rasterizer_discard;
449
state->hw_state.force_persample_interp = rs_state->force_persample_interp;
450
state->hw_state.pv_mode = rs_state->flatshade_first ? VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT : VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT;
451
452
assert(rs_state->fill_front <= PIPE_POLYGON_MODE_POINT);
453
if (rs_state->fill_back != rs_state->fill_front)
454
debug_printf("BUG: vulkan doesn't support different front and back fill modes\n");
455
state->hw_state.polygon_mode = (VkPolygonMode)rs_state->fill_front; // same values
456
state->hw_state.cull_mode = (VkCullModeFlags)rs_state->cull_face; // same bits
457
458
state->front_face = rs_state->front_ccw ?
459
VK_FRONT_FACE_COUNTER_CLOCKWISE :
460
VK_FRONT_FACE_CLOCKWISE;
461
462
VkPhysicalDeviceLineRasterizationFeaturesEXT *line_feats =
463
&screen->info.line_rast_feats;
464
state->hw_state.line_mode =
465
VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
466
467
if (rs_state->line_stipple_enable) {
468
state->hw_state.line_stipple_factor = rs_state->line_stipple_factor;
469
state->hw_state.line_stipple_pattern = rs_state->line_stipple_pattern;
470
471
if (screen->info.have_EXT_line_rasterization) {
472
if (rs_state->line_rectangular) {
473
if (rs_state->line_smooth) {
474
if (line_feats->stippledSmoothLines)
475
state->hw_state.line_mode =
476
VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
477
} else if (line_feats->stippledRectangularLines)
478
state->hw_state.line_mode =
479
VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
480
} else if (line_feats->stippledBresenhamLines)
481
state->hw_state.line_mode =
482
VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT;
483
else {
484
/* no suitable mode that supports line stippling */
485
state->hw_state.line_stipple_factor = 0;
486
state->hw_state.line_stipple_pattern = UINT16_MAX;
487
}
488
}
489
} else {
490
if (screen->info.have_EXT_line_rasterization) {
491
if (rs_state->line_rectangular) {
492
if (rs_state->line_smooth) {
493
if (line_feats->smoothLines)
494
state->hw_state.line_mode =
495
VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
496
} else if (line_feats->rectangularLines)
497
state->hw_state.line_mode =
498
VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
499
} else if (line_feats->bresenhamLines)
500
state->hw_state.line_mode =
501
VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT;
502
}
503
state->hw_state.line_stipple_factor = 0;
504
state->hw_state.line_stipple_pattern = UINT16_MAX;
505
}
506
507
state->offset_point = rs_state->offset_point;
508
state->offset_line = rs_state->offset_line;
509
state->offset_tri = rs_state->offset_tri;
510
state->offset_units = rs_state->offset_units;
511
state->offset_clamp = rs_state->offset_clamp;
512
state->offset_scale = rs_state->offset_scale;
513
514
state->line_width = line_width(rs_state->line_width,
515
screen->info.props.limits.lineWidthGranularity,
516
screen->info.props.limits.lineWidthRange);
517
518
return state;
519
}
520
521
static void
522
zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso)
523
{
524
struct zink_context *ctx = zink_context(pctx);
525
struct zink_screen *screen = zink_screen(pctx->screen);
526
bool clip_halfz = ctx->rast_state ? ctx->rast_state->base.clip_halfz : false;
527
bool point_quad_rasterization = ctx->rast_state ? ctx->rast_state->base.point_quad_rasterization : false;
528
bool scissor = ctx->rast_state ? ctx->rast_state->base.scissor : false;
529
ctx->rast_state = cso;
530
531
if (ctx->rast_state) {
532
if (ctx->gfx_pipeline_state.rast_state != &ctx->rast_state->hw_state) {
533
if (screen->info.have_EXT_provoking_vertex &&
534
(!ctx->gfx_pipeline_state.rast_state ||
535
ctx->gfx_pipeline_state.rast_state->pv_mode != ctx->rast_state->hw_state.pv_mode) &&
536
/* without this prop, change in pv mode requires new rp */
537
!screen->info.pv_props.provokingVertexModePerPipeline)
538
zink_batch_no_rp(ctx);
539
ctx->gfx_pipeline_state.rast_state = &ctx->rast_state->hw_state;
540
ctx->gfx_pipeline_state.dirty = true;
541
ctx->rast_state_changed = true;
542
}
543
544
if (clip_halfz != ctx->rast_state->base.clip_halfz) {
545
ctx->last_vertex_stage_dirty = true;
546
ctx->vp_state_changed = true;
547
}
548
549
if (ctx->gfx_pipeline_state.front_face != ctx->rast_state->front_face) {
550
ctx->gfx_pipeline_state.front_face = ctx->rast_state->front_face;
551
ctx->gfx_pipeline_state.dirty |= !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state;
552
}
553
if (ctx->line_width != ctx->rast_state->line_width) {
554
ctx->line_width = ctx->rast_state->line_width;
555
ctx->gfx_pipeline_state.dirty = true;
556
}
557
if (ctx->rast_state->base.point_quad_rasterization != point_quad_rasterization)
558
ctx->dirty_shader_stages |= BITFIELD_BIT(PIPE_SHADER_FRAGMENT);
559
if (ctx->rast_state->base.scissor != scissor)
560
ctx->scissor_changed = true;
561
}
562
}
563
564
static void
565
zink_delete_rasterizer_state(struct pipe_context *pctx, void *rs_state)
566
{
567
FREE(rs_state);
568
}
569
570
void
571
zink_context_state_init(struct pipe_context *pctx)
572
{
573
pctx->create_vertex_elements_state = zink_create_vertex_elements_state;
574
pctx->bind_vertex_elements_state = zink_bind_vertex_elements_state;
575
pctx->delete_vertex_elements_state = zink_delete_vertex_elements_state;
576
577
pctx->create_blend_state = zink_create_blend_state;
578
pctx->bind_blend_state = zink_bind_blend_state;
579
pctx->delete_blend_state = zink_delete_blend_state;
580
581
pctx->create_depth_stencil_alpha_state = zink_create_depth_stencil_alpha_state;
582
pctx->bind_depth_stencil_alpha_state = zink_bind_depth_stencil_alpha_state;
583
pctx->delete_depth_stencil_alpha_state = zink_delete_depth_stencil_alpha_state;
584
585
pctx->create_rasterizer_state = zink_create_rasterizer_state;
586
pctx->bind_rasterizer_state = zink_bind_rasterizer_state;
587
pctx->delete_rasterizer_state = zink_delete_rasterizer_state;
588
}
589
590