2
* Copyright 2018 Collabora Ltd.
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:
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
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.
24
#include "zink_state.h"
26
#include "zink_context.h"
27
#include "zink_format.h"
28
#include "zink_program.h"
29
#include "zink_screen.h"
31
#include "compiler/shader_enums.h"
32
#include "util/u_dual_blend.h"
33
#include "util/u_memory.h"
34
#include "util/u_helpers.h"
39
zink_create_vertex_elements_state(struct pipe_context *pctx,
40
unsigned num_elements,
41
const struct pipe_vertex_element *elements)
43
struct zink_screen *screen = zink_screen(pctx->screen);
45
struct zink_vertex_elements_state *ves = CALLOC_STRUCT(zink_vertex_elements_state);
48
ves->hw_state.hash = _mesa_hash_pointer(ves);
50
int buffer_map[PIPE_MAX_ATTRIBS];
51
for (int i = 0; i < ARRAY_SIZE(buffer_map); ++i)
55
unsigned num_decomposed = 0;
59
for (i = 0; i < num_elements; ++i) {
60
const struct pipe_vertex_element *elem = elements + i;
62
int binding = elem->vertex_buffer_index;
63
if (buffer_map[binding] < 0) {
64
ves->binding_map[num_bindings] = binding;
65
buffer_map[binding] = num_bindings++;
67
binding = buffer_map[binding];
69
ves->bindings[binding].binding = binding;
70
ves->bindings[binding].inputRate = elem->instance_divisor ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
72
assert(!elem->instance_divisor || zink_screen(pctx->screen)->info.have_EXT_vertex_attribute_divisor);
73
if (elem->instance_divisor > screen->info.vdiv_props.maxVertexAttribDivisor)
74
debug_printf("zink: clamping instance divisor %u to %u\n", elem->instance_divisor, screen->info.vdiv_props.maxVertexAttribDivisor);
75
ves->divisor[binding] = MIN2(elem->instance_divisor, screen->info.vdiv_props.maxVertexAttribDivisor);
78
if (screen->format_props[elem->src_format].bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)
79
format = zink_get_format(screen, elem->src_format);
81
enum pipe_format new_format = zink_decompose_vertex_format(elem->src_format);
84
assert(screen->format_props[new_format].bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT);
85
if (util_format_get_blocksize(new_format) == 4)
86
size32 |= BITFIELD_BIT(i);
87
else if (util_format_get_blocksize(new_format) == 2)
88
size16 |= BITFIELD_BIT(i);
90
size8 |= BITFIELD_BIT(i);
91
format = zink_get_format(screen, new_format);
99
if (util_format_get_nr_components(elem->src_format) == 4) {
100
ves->decomposed_attrs |= BITFIELD_BIT(i);
101
ves->decomposed_attrs_size = size;
103
ves->decomposed_attrs_without_w |= BITFIELD_BIT(i);
104
ves->decomposed_attrs_without_w_size = size;
108
if (screen->info.have_EXT_vertex_input_dynamic_state) {
109
ves->hw_state.dynattribs[i].sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT;
110
ves->hw_state.dynattribs[i].binding = binding;
111
ves->hw_state.dynattribs[i].location = i;
112
ves->hw_state.dynattribs[i].format = format;
113
assert(ves->hw_state.dynattribs[i].format != VK_FORMAT_UNDEFINED);
114
ves->hw_state.dynattribs[i].offset = elem->src_offset;
116
ves->hw_state.attribs[i].binding = binding;
117
ves->hw_state.attribs[i].location = i;
118
ves->hw_state.attribs[i].format = format;
119
assert(ves->hw_state.attribs[i].format != VK_FORMAT_UNDEFINED);
120
ves->hw_state.attribs[i].offset = elem->src_offset;
123
assert(num_decomposed + num_elements <= PIPE_MAX_ATTRIBS);
124
u_foreach_bit(i, ves->decomposed_attrs | ves->decomposed_attrs_without_w) {
125
const struct pipe_vertex_element *elem = elements + i;
126
const struct util_format_description *desc = util_format_description(elem->src_format);
128
if (size32 & BITFIELD_BIT(i))
130
else if (size16 & BITFIELD_BIT(i))
133
assert(size8 & BITFIELD_BIT(i));
134
for (unsigned j = 1; j < desc->nr_channels; j++) {
135
if (screen->info.have_EXT_vertex_input_dynamic_state) {
136
memcpy(&ves->hw_state.dynattribs[num_elements], &ves->hw_state.dynattribs[i], sizeof(VkVertexInputAttributeDescription2EXT));
137
ves->hw_state.dynattribs[num_elements].location = num_elements;
138
ves->hw_state.dynattribs[num_elements].offset += j * size;
140
memcpy(&ves->hw_state.attribs[num_elements], &ves->hw_state.attribs[i], sizeof(VkVertexInputAttributeDescription));
141
ves->hw_state.attribs[num_elements].location = num_elements;
142
ves->hw_state.attribs[num_elements].offset += j * size;
147
ves->hw_state.num_bindings = num_bindings;
148
ves->hw_state.num_attribs = num_elements;
149
if (screen->info.have_EXT_vertex_input_dynamic_state) {
150
for (int i = 0; i < num_bindings; ++i) {
151
ves->hw_state.dynbindings[i].sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT;
152
ves->hw_state.dynbindings[i].binding = ves->bindings[i].binding;
153
ves->hw_state.dynbindings[i].inputRate = ves->bindings[i].inputRate;
155
ves->hw_state.dynbindings[i].divisor = ves->divisor[i];
157
ves->hw_state.dynbindings[i].divisor = 1;
160
for (int i = 0; i < num_bindings; ++i) {
161
ves->hw_state.b.bindings[i].binding = ves->bindings[i].binding;
162
ves->hw_state.b.bindings[i].inputRate = ves->bindings[i].inputRate;
163
if (ves->divisor[i]) {
164
ves->hw_state.b.divisors[ves->hw_state.b.divisors_present].divisor = ves->divisor[i];
165
ves->hw_state.b.divisors[ves->hw_state.b.divisors_present].binding = ves->bindings[i].binding;
166
ves->hw_state.b.divisors_present++;
174
zink_bind_vertex_elements_state(struct pipe_context *pctx,
177
struct zink_context *ctx = zink_context(pctx);
178
struct zink_gfx_pipeline_state *state = &ctx->gfx_pipeline_state;
179
ctx->element_state = cso;
181
if (state->element_state != &ctx->element_state->hw_state) {
182
ctx->vertex_state_changed = !zink_screen(pctx->screen)->info.have_EXT_vertex_input_dynamic_state;
183
ctx->vertex_buffers_dirty = ctx->element_state->hw_state.num_bindings > 0;
185
const struct zink_vs_key *vs = zink_get_vs_key(ctx);
186
uint32_t decomposed_attrs = 0, decomposed_attrs_without_w = 0;
189
decomposed_attrs = vs->u8.decomposed_attrs;
190
decomposed_attrs_without_w = vs->u8.decomposed_attrs_without_w;
193
decomposed_attrs = vs->u16.decomposed_attrs;
194
decomposed_attrs_without_w = vs->u16.decomposed_attrs_without_w;
197
decomposed_attrs = vs->u16.decomposed_attrs;
198
decomposed_attrs_without_w = vs->u16.decomposed_attrs_without_w;
201
if (ctx->element_state->decomposed_attrs != decomposed_attrs ||
202
ctx->element_state->decomposed_attrs_without_w != decomposed_attrs_without_w) {
203
unsigned size = MAX2(ctx->element_state->decomposed_attrs_size, ctx->element_state->decomposed_attrs_without_w_size);
204
struct zink_shader_key *key = (struct zink_shader_key *)zink_set_vs_key(ctx);
205
key->size -= 2 * key->key.vs.size;
208
key->key.vs.u8.decomposed_attrs = ctx->element_state->decomposed_attrs;
209
key->key.vs.u8.decomposed_attrs_without_w = ctx->element_state->decomposed_attrs_without_w;
212
key->key.vs.u16.decomposed_attrs = ctx->element_state->decomposed_attrs;
213
key->key.vs.u16.decomposed_attrs_without_w = ctx->element_state->decomposed_attrs_without_w;
216
key->key.vs.u32.decomposed_attrs = ctx->element_state->decomposed_attrs;
217
key->key.vs.u32.decomposed_attrs_without_w = ctx->element_state->decomposed_attrs_without_w;
221
key->key.vs.size = size;
222
key->size += 2 * size;
224
state->element_state = &ctx->element_state->hw_state;
226
state->element_state = NULL;
227
ctx->vertex_buffers_dirty = false;
232
zink_delete_vertex_elements_state(struct pipe_context *pctx,
239
blend_factor(enum pipe_blendfactor factor)
242
case PIPE_BLENDFACTOR_ONE: return VK_BLEND_FACTOR_ONE;
243
case PIPE_BLENDFACTOR_SRC_COLOR: return VK_BLEND_FACTOR_SRC_COLOR;
244
case PIPE_BLENDFACTOR_SRC_ALPHA: return VK_BLEND_FACTOR_SRC_ALPHA;
245
case PIPE_BLENDFACTOR_DST_ALPHA: return VK_BLEND_FACTOR_DST_ALPHA;
246
case PIPE_BLENDFACTOR_DST_COLOR: return VK_BLEND_FACTOR_DST_COLOR;
247
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
248
return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
249
case PIPE_BLENDFACTOR_CONST_COLOR: return VK_BLEND_FACTOR_CONSTANT_COLOR;
250
case PIPE_BLENDFACTOR_CONST_ALPHA: return VK_BLEND_FACTOR_CONSTANT_ALPHA;
251
case PIPE_BLENDFACTOR_SRC1_COLOR: return VK_BLEND_FACTOR_SRC1_COLOR;
252
case PIPE_BLENDFACTOR_SRC1_ALPHA: return VK_BLEND_FACTOR_SRC1_ALPHA;
254
case PIPE_BLENDFACTOR_ZERO: return VK_BLEND_FACTOR_ZERO;
256
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
257
return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
258
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
259
return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
260
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
261
return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
262
case PIPE_BLENDFACTOR_INV_DST_COLOR:
263
return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
265
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
266
return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
267
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
268
return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
269
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
270
return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
271
case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
272
return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
274
unreachable("unexpected blend factor");
279
need_blend_constants(enum pipe_blendfactor factor)
282
case PIPE_BLENDFACTOR_CONST_COLOR:
283
case PIPE_BLENDFACTOR_CONST_ALPHA:
284
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
285
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
294
blend_op(enum pipe_blend_func func)
297
case PIPE_BLEND_ADD: return VK_BLEND_OP_ADD;
298
case PIPE_BLEND_SUBTRACT: return VK_BLEND_OP_SUBTRACT;
299
case PIPE_BLEND_REVERSE_SUBTRACT: return VK_BLEND_OP_REVERSE_SUBTRACT;
300
case PIPE_BLEND_MIN: return VK_BLEND_OP_MIN;
301
case PIPE_BLEND_MAX: return VK_BLEND_OP_MAX;
303
unreachable("unexpected blend function");
307
logic_op(enum pipe_logicop func)
310
case PIPE_LOGICOP_CLEAR: return VK_LOGIC_OP_CLEAR;
311
case PIPE_LOGICOP_NOR: return VK_LOGIC_OP_NOR;
312
case PIPE_LOGICOP_AND_INVERTED: return VK_LOGIC_OP_AND_INVERTED;
313
case PIPE_LOGICOP_COPY_INVERTED: return VK_LOGIC_OP_COPY_INVERTED;
314
case PIPE_LOGICOP_AND_REVERSE: return VK_LOGIC_OP_AND_REVERSE;
315
case PIPE_LOGICOP_INVERT: return VK_LOGIC_OP_INVERT;
316
case PIPE_LOGICOP_XOR: return VK_LOGIC_OP_XOR;
317
case PIPE_LOGICOP_NAND: return VK_LOGIC_OP_NAND;
318
case PIPE_LOGICOP_AND: return VK_LOGIC_OP_AND;
319
case PIPE_LOGICOP_EQUIV: return VK_LOGIC_OP_EQUIVALENT;
320
case PIPE_LOGICOP_NOOP: return VK_LOGIC_OP_NO_OP;
321
case PIPE_LOGICOP_OR_INVERTED: return VK_LOGIC_OP_OR_INVERTED;
322
case PIPE_LOGICOP_COPY: return VK_LOGIC_OP_COPY;
323
case PIPE_LOGICOP_OR_REVERSE: return VK_LOGIC_OP_OR_REVERSE;
324
case PIPE_LOGICOP_OR: return VK_LOGIC_OP_OR;
325
case PIPE_LOGICOP_SET: return VK_LOGIC_OP_SET;
327
unreachable("unexpected logicop function");
331
static enum pipe_blendfactor
332
fix_blendfactor(enum pipe_blendfactor f, bool alpha_to_one)
335
if (f == PIPE_BLENDFACTOR_SRC1_ALPHA)
336
return PIPE_BLENDFACTOR_ONE;
338
if (f == PIPE_BLENDFACTOR_INV_SRC1_ALPHA)
339
return PIPE_BLENDFACTOR_ZERO;
346
zink_create_blend_state(struct pipe_context *pctx,
347
const struct pipe_blend_state *blend_state)
349
struct zink_blend_state *cso = CALLOC_STRUCT(zink_blend_state);
352
cso->hash = _mesa_hash_pointer(cso);
354
if (blend_state->logicop_enable) {
355
cso->logicop_enable = VK_TRUE;
356
cso->logicop_func = logic_op(blend_state->logicop_func);
359
/* TODO: figure out what to do with dither (nothing is probably "OK" for now,
360
* as dithering is undefined in GL
363
/* TODO: these are multisampling-state, and should be set there instead of
364
* here, as that's closer tied to the update-frequency
366
cso->alpha_to_coverage = blend_state->alpha_to_coverage;
367
cso->alpha_to_one = blend_state->alpha_to_one;
369
cso->need_blend_constants = false;
371
for (int i = 0; i < blend_state->max_rt + 1; ++i) {
372
const struct pipe_rt_blend_state *rt = blend_state->rt;
373
if (blend_state->independent_blend_enable)
374
rt = blend_state->rt + i;
376
VkPipelineColorBlendAttachmentState att = {0};
378
if (rt->blend_enable) {
379
att.blendEnable = VK_TRUE;
380
att.srcColorBlendFactor = blend_factor(fix_blendfactor(rt->rgb_src_factor, cso->alpha_to_one));
381
att.dstColorBlendFactor = blend_factor(fix_blendfactor(rt->rgb_dst_factor, cso->alpha_to_one));
382
att.colorBlendOp = blend_op(rt->rgb_func);
383
att.srcAlphaBlendFactor = blend_factor(fix_blendfactor(rt->alpha_src_factor, cso->alpha_to_one));
384
att.dstAlphaBlendFactor = blend_factor(fix_blendfactor(rt->alpha_dst_factor, cso->alpha_to_one));
385
att.alphaBlendOp = blend_op(rt->alpha_func);
387
if (need_blend_constants(rt->rgb_src_factor) ||
388
need_blend_constants(rt->rgb_dst_factor) ||
389
need_blend_constants(rt->alpha_src_factor) ||
390
need_blend_constants(rt->alpha_dst_factor))
391
cso->need_blend_constants = true;
394
if (rt->colormask & PIPE_MASK_R)
395
att.colorWriteMask |= VK_COLOR_COMPONENT_R_BIT;
396
if (rt->colormask & PIPE_MASK_G)
397
att.colorWriteMask |= VK_COLOR_COMPONENT_G_BIT;
398
if (rt->colormask & PIPE_MASK_B)
399
att.colorWriteMask |= VK_COLOR_COMPONENT_B_BIT;
400
if (rt->colormask & PIPE_MASK_A)
401
att.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT;
403
cso->attachments[i] = att;
405
cso->dual_src_blend = util_blend_state_is_dual(blend_state, 0);
411
zink_bind_blend_state(struct pipe_context *pctx, void *cso)
413
struct zink_context *ctx = zink_context(pctx);
414
struct zink_gfx_pipeline_state* state = &zink_context(pctx)->gfx_pipeline_state;
415
struct zink_blend_state *blend = cso;
417
if (state->blend_state != cso) {
418
state->blend_state = cso;
419
state->blend_id = blend ? blend->hash : 0;
421
bool force_dual_color_blend = zink_screen(pctx->screen)->driconf.dual_color_blend_by_location &&
422
blend && blend->dual_src_blend && state->blend_state->attachments[0].blendEnable;
423
if (force_dual_color_blend != zink_get_fs_key(ctx)->force_dual_color_blend)
424
zink_set_fs_key(ctx)->force_dual_color_blend = force_dual_color_blend;
425
ctx->blend_state_changed = true;
430
zink_delete_blend_state(struct pipe_context *pctx, void *blend_state)
436
compare_op(enum pipe_compare_func func)
439
case PIPE_FUNC_NEVER: return VK_COMPARE_OP_NEVER;
440
case PIPE_FUNC_LESS: return VK_COMPARE_OP_LESS;
441
case PIPE_FUNC_EQUAL: return VK_COMPARE_OP_EQUAL;
442
case PIPE_FUNC_LEQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL;
443
case PIPE_FUNC_GREATER: return VK_COMPARE_OP_GREATER;
444
case PIPE_FUNC_NOTEQUAL: return VK_COMPARE_OP_NOT_EQUAL;
445
case PIPE_FUNC_GEQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL;
446
case PIPE_FUNC_ALWAYS: return VK_COMPARE_OP_ALWAYS;
448
unreachable("unexpected func");
452
stencil_op(enum pipe_stencil_op op)
455
case PIPE_STENCIL_OP_KEEP: return VK_STENCIL_OP_KEEP;
456
case PIPE_STENCIL_OP_ZERO: return VK_STENCIL_OP_ZERO;
457
case PIPE_STENCIL_OP_REPLACE: return VK_STENCIL_OP_REPLACE;
458
case PIPE_STENCIL_OP_INCR: return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
459
case PIPE_STENCIL_OP_DECR: return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
460
case PIPE_STENCIL_OP_INCR_WRAP: return VK_STENCIL_OP_INCREMENT_AND_WRAP;
461
case PIPE_STENCIL_OP_DECR_WRAP: return VK_STENCIL_OP_DECREMENT_AND_WRAP;
462
case PIPE_STENCIL_OP_INVERT: return VK_STENCIL_OP_INVERT;
464
unreachable("unexpected op");
467
static VkStencilOpState
468
stencil_op_state(const struct pipe_stencil_state *src)
470
VkStencilOpState ret;
471
ret.failOp = stencil_op(src->fail_op);
472
ret.passOp = stencil_op(src->zpass_op);
473
ret.depthFailOp = stencil_op(src->zfail_op);
474
ret.compareOp = compare_op(src->func);
475
ret.compareMask = src->valuemask;
476
ret.writeMask = src->writemask;
477
ret.reference = 0; // not used: we'll use a dynamic state for this
482
zink_create_depth_stencil_alpha_state(struct pipe_context *pctx,
483
const struct pipe_depth_stencil_alpha_state *depth_stencil_alpha)
485
struct zink_depth_stencil_alpha_state *cso = CALLOC_STRUCT(zink_depth_stencil_alpha_state);
489
cso->base = *depth_stencil_alpha;
491
if (depth_stencil_alpha->depth_enabled) {
492
cso->hw_state.depth_test = VK_TRUE;
493
cso->hw_state.depth_compare_op = compare_op(depth_stencil_alpha->depth_func);
496
if (depth_stencil_alpha->depth_bounds_test) {
497
cso->hw_state.depth_bounds_test = VK_TRUE;
498
cso->hw_state.min_depth_bounds = depth_stencil_alpha->depth_bounds_min;
499
cso->hw_state.max_depth_bounds = depth_stencil_alpha->depth_bounds_max;
502
if (depth_stencil_alpha->stencil[0].enabled) {
503
cso->hw_state.stencil_test = VK_TRUE;
504
cso->hw_state.stencil_front = stencil_op_state(depth_stencil_alpha->stencil);
507
if (depth_stencil_alpha->stencil[1].enabled)
508
cso->hw_state.stencil_back = stencil_op_state(depth_stencil_alpha->stencil + 1);
510
cso->hw_state.stencil_back = cso->hw_state.stencil_front;
512
cso->hw_state.depth_write = depth_stencil_alpha->depth_writemask;
518
zink_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *cso)
520
struct zink_context *ctx = zink_context(pctx);
522
bool prev_zwrite = ctx->dsa_state ? ctx->dsa_state->hw_state.depth_write : false;
523
ctx->dsa_state = cso;
526
struct zink_gfx_pipeline_state *state = &ctx->gfx_pipeline_state;
527
if (state->dyn_state1.depth_stencil_alpha_state != &ctx->dsa_state->hw_state) {
528
state->dyn_state1.depth_stencil_alpha_state = &ctx->dsa_state->hw_state;
529
state->dirty |= !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state;
530
ctx->dsa_state_changed = true;
533
if (prev_zwrite != (ctx->dsa_state ? ctx->dsa_state->hw_state.depth_write : false)) {
534
ctx->rp_changed = true;
535
zink_batch_no_rp(ctx);
540
zink_delete_depth_stencil_alpha_state(struct pipe_context *pctx,
541
void *depth_stencil_alpha)
543
FREE(depth_stencil_alpha);
547
round_to_granularity(float value, float granularity)
549
return roundf(value / granularity) * granularity;
553
line_width(float width, float granularity, const float range[2])
555
assert(granularity >= 0);
556
assert(range[0] <= range[1]);
559
width = round_to_granularity(width, granularity);
561
return CLAMP(width, range[0], range[1]);
565
zink_create_rasterizer_state(struct pipe_context *pctx,
566
const struct pipe_rasterizer_state *rs_state)
568
struct zink_screen *screen = zink_screen(pctx->screen);
570
struct zink_rasterizer_state *state = CALLOC_STRUCT(zink_rasterizer_state);
574
state->base = *rs_state;
575
state->base.line_stipple_factor++;
576
state->hw_state.line_stipple_enable = rs_state->line_stipple_enable;
578
assert(rs_state->depth_clip_far == rs_state->depth_clip_near);
579
state->hw_state.depth_clamp = rs_state->depth_clip_near == 0;
580
state->hw_state.force_persample_interp = rs_state->force_persample_interp;
581
state->hw_state.pv_last = !rs_state->flatshade_first;
582
state->hw_state.clip_halfz = rs_state->clip_halfz;
584
assert(rs_state->fill_front <= PIPE_POLYGON_MODE_POINT);
585
if (rs_state->fill_back != rs_state->fill_front)
586
debug_printf("BUG: vulkan doesn't support different front and back fill modes\n");
587
state->hw_state.polygon_mode = rs_state->fill_front; // same values
588
state->hw_state.cull_mode = rs_state->cull_face; // same bits
590
state->front_face = rs_state->front_ccw ?
591
VK_FRONT_FACE_COUNTER_CLOCKWISE :
592
VK_FRONT_FACE_CLOCKWISE;
594
state->hw_state.line_mode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
595
if (rs_state->line_rectangular) {
596
if (rs_state->line_smooth)
597
state->hw_state.line_mode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
599
state->hw_state.line_mode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
601
state->hw_state.line_mode = VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT;
604
if (!rs_state->line_stipple_enable) {
605
state->base.line_stipple_factor = 0;
606
state->base.line_stipple_pattern = UINT16_MAX;
609
state->offset_point = rs_state->offset_point;
610
state->offset_line = rs_state->offset_line;
611
state->offset_tri = rs_state->offset_tri;
612
state->offset_units = rs_state->offset_units;
613
state->offset_clamp = rs_state->offset_clamp;
614
state->offset_scale = rs_state->offset_scale;
616
state->line_width = line_width(rs_state->line_width,
617
screen->info.props.limits.lineWidthGranularity,
618
screen->info.props.limits.lineWidthRange);
624
zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso)
626
struct zink_context *ctx = zink_context(pctx);
627
struct zink_screen *screen = zink_screen(pctx->screen);
628
bool point_quad_rasterization = ctx->rast_state ? ctx->rast_state->base.point_quad_rasterization : false;
629
bool scissor = ctx->rast_state ? ctx->rast_state->base.scissor : false;
630
bool pv_last = ctx->rast_state ? ctx->rast_state->hw_state.pv_last : false;
631
bool force_persample_interp = ctx->rast_state ? ctx->rast_state->hw_state.force_persample_interp : false;
632
bool clip_halfz = ctx->rast_state ? ctx->rast_state->hw_state.clip_halfz : false;
633
bool rasterizer_discard = ctx->rast_state ? ctx->rast_state->base.rasterizer_discard : false;
634
ctx->rast_state = cso;
636
if (ctx->rast_state) {
637
if (screen->info.have_EXT_provoking_vertex &&
638
pv_last != ctx->rast_state->hw_state.pv_last &&
639
/* without this prop, change in pv mode requires new rp */
640
!screen->info.pv_props.provokingVertexModePerPipeline)
641
zink_batch_no_rp(ctx);
642
uint32_t rast_bits = 0;
643
memcpy(&rast_bits, &ctx->rast_state->hw_state, sizeof(struct zink_rasterizer_hw_state));
644
ctx->gfx_pipeline_state.rast_state = rast_bits & BITFIELD_MASK(ZINK_RAST_HW_STATE_SIZE);
646
ctx->gfx_pipeline_state.dirty = true;
647
ctx->rast_state_changed = true;
649
if (clip_halfz != ctx->rast_state->base.clip_halfz) {
650
if (!screen->driver_workarounds.depth_clip_control_missing)
651
ctx->gfx_pipeline_state.dirty = true;
653
zink_set_last_vertex_key(ctx)->clip_halfz = ctx->rast_state->base.clip_halfz;
654
ctx->vp_state_changed = true;
657
if (ctx->gfx_pipeline_state.dyn_state1.front_face != ctx->rast_state->front_face) {
658
ctx->gfx_pipeline_state.dyn_state1.front_face = ctx->rast_state->front_face;
659
ctx->gfx_pipeline_state.dirty |= !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state;
661
if (!ctx->primitives_generated_active)
662
zink_set_rasterizer_discard(ctx, false);
663
else if (rasterizer_discard != ctx->rast_state->base.rasterizer_discard)
664
zink_set_color_write_enables(ctx);
666
if (ctx->rast_state->base.point_quad_rasterization != point_quad_rasterization)
667
zink_set_fs_point_coord_key(ctx);
668
if (ctx->rast_state->base.scissor != scissor)
669
ctx->scissor_changed = true;
671
if (ctx->rast_state->base.force_persample_interp != force_persample_interp)
672
zink_set_fs_key(ctx)->force_persample_interp = ctx->rast_state->base.force_persample_interp;
677
zink_delete_rasterizer_state(struct pipe_context *pctx, void *rs_state)
682
struct pipe_vertex_state *
683
zink_create_vertex_state(struct pipe_screen *pscreen,
684
struct pipe_vertex_buffer *buffer,
685
const struct pipe_vertex_element *elements,
686
unsigned num_elements,
687
struct pipe_resource *indexbuf,
688
uint32_t full_velem_mask)
690
struct zink_vertex_state *zstate = CALLOC_STRUCT(zink_vertex_state);
691
_mesa_set_init(&zstate->masks, NULL, NULL, _mesa_key_pointer_equal);
693
util_init_pipe_vertex_state(pscreen, buffer, elements, num_elements, indexbuf, full_velem_mask,
696
/* Initialize the vertex element state in state->element.
697
* Do it by creating a vertex element state object and copying it there.
699
struct zink_context ctx;
700
ctx.base.screen = pscreen;
701
struct zink_vertex_elements_state *elems = zink_create_vertex_elements_state(&ctx.base, num_elements, elements);
702
for (unsigned i = 0; i < elems->hw_state.num_bindings; i++) {
703
if (zink_screen(pscreen)->info.have_EXT_vertex_input_dynamic_state)
704
elems->hw_state.dynbindings[i].stride = buffer->stride;
706
zstate->velems = *elems;
707
zink_delete_vertex_elements_state(&ctx.base, elems);
713
zink_vertex_state_destroy(struct pipe_screen *pscreen, struct pipe_vertex_state *vstate)
715
struct zink_vertex_state *zstate = (struct zink_vertex_state *)vstate;
716
ralloc_free(zstate->masks.table);
717
pipe_vertex_buffer_unreference(&vstate->input.vbuffer);
718
pipe_resource_reference(&vstate->input.indexbuf, NULL);
722
const struct zink_vertex_elements_hw_state *
723
zink_vertex_state_mask(struct pipe_vertex_state *vstate, uint32_t partial_velem_mask, bool have_EXT_vertex_input_dynamic_state)
725
struct zink_vertex_state *zstate = (struct zink_vertex_state *)vstate;
727
if (partial_velem_mask == vstate->input.full_velem_mask)
728
return &zstate->velems.hw_state;
729
struct set_entry *he = _mesa_set_search_pre_hashed(&zstate->masks, partial_velem_mask, (void*)(uintptr_t)partial_velem_mask);
733
struct zink_vertex_elements_hw_state *hw_state = rzalloc(zstate->masks.table, struct zink_vertex_elements_hw_state);
735
if (have_EXT_vertex_input_dynamic_state) {
736
u_foreach_bit(elem, vstate->input.full_velem_mask & partial_velem_mask) {
737
unsigned idx = util_bitcount(vstate->input.full_velem_mask & BITFIELD_MASK(elem));
738
hw_state->dynattribs[i] = zstate->velems.hw_state.dynattribs[idx];
739
hw_state->dynattribs[i].location = i;
742
memcpy(hw_state->dynbindings, zstate->velems.hw_state.dynbindings,
743
zstate->velems.hw_state.num_bindings * sizeof(VkVertexInputBindingDescription2EXT));
746
hw_state->num_attribs = i;
747
hw_state->num_bindings = zstate->velems.hw_state.num_bindings;
748
_mesa_set_add_pre_hashed(&zstate->masks, partial_velem_mask, hw_state);
752
struct pipe_vertex_state *
753
zink_cache_create_vertex_state(struct pipe_screen *pscreen,
754
struct pipe_vertex_buffer *buffer,
755
const struct pipe_vertex_element *elements,
756
unsigned num_elements,
757
struct pipe_resource *indexbuf,
758
uint32_t full_velem_mask)
760
struct zink_screen *screen = zink_screen(pscreen);
762
return util_vertex_state_cache_get(pscreen, buffer, elements, num_elements, indexbuf,
763
full_velem_mask, &screen->vertex_state_cache);
767
zink_cache_vertex_state_destroy(struct pipe_screen *pscreen, struct pipe_vertex_state *vstate)
769
struct zink_screen *screen = zink_screen(pscreen);
771
util_vertex_state_destroy(pscreen, &screen->vertex_state_cache, vstate);
775
zink_context_state_init(struct pipe_context *pctx)
777
pctx->create_vertex_elements_state = zink_create_vertex_elements_state;
778
pctx->bind_vertex_elements_state = zink_bind_vertex_elements_state;
779
pctx->delete_vertex_elements_state = zink_delete_vertex_elements_state;
781
pctx->create_blend_state = zink_create_blend_state;
782
pctx->bind_blend_state = zink_bind_blend_state;
783
pctx->delete_blend_state = zink_delete_blend_state;
785
pctx->create_depth_stencil_alpha_state = zink_create_depth_stencil_alpha_state;
786
pctx->bind_depth_stencil_alpha_state = zink_bind_depth_stencil_alpha_state;
787
pctx->delete_depth_stencil_alpha_state = zink_delete_depth_stencil_alpha_state;
789
pctx->create_rasterizer_state = zink_create_rasterizer_state;
790
pctx->bind_rasterizer_state = zink_bind_rasterizer_state;
791
pctx->delete_rasterizer_state = zink_delete_rasterizer_state;