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_format.h"
28 #include "zink_program.h"
29 #include "zink_screen.h"
30
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"
35 #include "vk_format.h"
36
37 #include <math.h>
38
39 static void *
zink_create_vertex_elements_state(struct pipe_context * pctx,unsigned num_elements,const struct pipe_vertex_element * elements)40 zink_create_vertex_elements_state(struct pipe_context *pctx,
41 unsigned num_elements,
42 const struct pipe_vertex_element *elements)
43 {
44 struct zink_screen *screen = zink_screen(pctx->screen);
45 unsigned int i;
46 struct zink_vertex_elements_state *ves = CALLOC_STRUCT(zink_vertex_elements_state);
47 if (!ves)
48 return NULL;
49 ves->hw_state.hash = _mesa_hash_pointer(ves);
50
51 int buffer_map[PIPE_MAX_ATTRIBS];
52 for (int j = 0; j < ARRAY_SIZE(buffer_map); ++j)
53 buffer_map[j] = -1;
54
55 int num_bindings = 0;
56 unsigned num_decomposed = 0;
57 uint32_t size8 = 0;
58 uint32_t size16 = 0;
59 uint32_t size32 = 0;
60 uint16_t strides[PIPE_MAX_ATTRIBS];
61 for (i = 0; i < num_elements; ++i) {
62 const struct pipe_vertex_element *elem = elements + i;
63
64 int binding = elem->vertex_buffer_index;
65 if (buffer_map[binding] < 0) {
66 ves->hw_state.binding_map[num_bindings] = binding;
67 buffer_map[binding] = num_bindings++;
68 }
69 binding = buffer_map[binding];
70
71 ves->bindings[binding].binding = binding;
72 ves->bindings[binding].inputRate = elem->instance_divisor ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
73
74 assert(!elem->instance_divisor || zink_screen(pctx->screen)->info.have_EXT_vertex_attribute_divisor);
75 if (elem->instance_divisor > screen->info.vdiv_props.maxVertexAttribDivisor)
76 debug_printf("zink: clamping instance divisor %u to %u\n", elem->instance_divisor, screen->info.vdiv_props.maxVertexAttribDivisor);
77 ves->divisor[binding] = MIN2(elem->instance_divisor, screen->info.vdiv_props.maxVertexAttribDivisor);
78
79 VkFormat format;
80 if (screen->format_props[elem->src_format].bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)
81 format = zink_get_format(screen, elem->src_format);
82 else {
83 enum pipe_format new_format = zink_decompose_vertex_format(elem->src_format);
84 assert(new_format);
85 num_decomposed++;
86 assert(screen->format_props[new_format].bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT);
87 if (util_format_get_blocksize(new_format) == 4)
88 size32 |= BITFIELD_BIT(i);
89 else if (util_format_get_blocksize(new_format) == 2)
90 size16 |= BITFIELD_BIT(i);
91 else
92 size8 |= BITFIELD_BIT(i);
93 format = zink_get_format(screen, new_format);
94 unsigned size;
95 if (i < 8)
96 size = 1;
97 else if (i < 16)
98 size = 2;
99 else
100 size = 4;
101 if (util_format_get_nr_components(elem->src_format) == 4) {
102 ves->decomposed_attrs |= BITFIELD_BIT(i);
103 ves->decomposed_attrs_size = size;
104 } else {
105 ves->decomposed_attrs_without_w |= BITFIELD_BIT(i);
106 ves->decomposed_attrs_without_w_size = size;
107 }
108 ves->has_decomposed_attrs = true;
109 }
110
111 if (screen->info.have_EXT_vertex_input_dynamic_state) {
112 ves->hw_state.dynattribs[i].sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT;
113 ves->hw_state.dynattribs[i].binding = binding;
114 ves->hw_state.dynattribs[i].location = i;
115 ves->hw_state.dynattribs[i].format = format;
116 strides[binding] = elem->src_stride;
117 assert(ves->hw_state.dynattribs[i].format != VK_FORMAT_UNDEFINED);
118 ves->hw_state.dynattribs[i].offset = elem->src_offset;
119 } else {
120 ves->hw_state.attribs[i].binding = binding;
121 ves->hw_state.attribs[i].location = i;
122 ves->hw_state.attribs[i].format = format;
123 ves->hw_state.b.strides[binding] = elem->src_stride;
124 assert(ves->hw_state.attribs[i].format != VK_FORMAT_UNDEFINED);
125 ves->hw_state.attribs[i].offset = elem->src_offset;
126 ves->min_stride[binding] = MAX2(ves->min_stride[binding], elem->src_offset + vk_format_get_blocksize(format));
127 }
128 }
129 assert(num_decomposed + num_elements <= PIPE_MAX_ATTRIBS);
130 u_foreach_bit(attr_index, ves->decomposed_attrs | ves->decomposed_attrs_without_w) {
131 const struct pipe_vertex_element *elem = elements + attr_index;
132 const struct util_format_description *desc = util_format_description(elem->src_format);
133 unsigned size = 1;
134 if (size32 & BITFIELD_BIT(attr_index))
135 size = 4;
136 else if (size16 & BITFIELD_BIT(attr_index))
137 size = 2;
138 else
139 assert(size8 & BITFIELD_BIT(attr_index));
140 for (unsigned j = 1; j < desc->nr_channels; j++) {
141 if (screen->info.have_EXT_vertex_input_dynamic_state) {
142 memcpy(&ves->hw_state.dynattribs[num_elements], &ves->hw_state.dynattribs[attr_index], sizeof(VkVertexInputAttributeDescription2EXT));
143 ves->hw_state.dynattribs[num_elements].location = num_elements;
144 ves->hw_state.dynattribs[num_elements].offset += j * size;
145 } else {
146 memcpy(&ves->hw_state.attribs[num_elements], &ves->hw_state.attribs[attr_index], sizeof(VkVertexInputAttributeDescription));
147 ves->hw_state.attribs[num_elements].location = num_elements;
148 ves->hw_state.attribs[num_elements].offset += j * size;
149 }
150 num_elements++;
151 }
152 }
153 ves->hw_state.num_bindings = num_bindings;
154 ves->hw_state.num_attribs = num_elements;
155 if (screen->info.have_EXT_vertex_input_dynamic_state) {
156 for (int j = 0; j < num_bindings; ++j) {
157 ves->hw_state.dynbindings[j].sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT;
158 ves->hw_state.dynbindings[j].binding = ves->bindings[j].binding;
159 ves->hw_state.dynbindings[j].inputRate = ves->bindings[j].inputRate;
160 ves->hw_state.dynbindings[j].stride = strides[j];
161 if (ves->divisor[j])
162 ves->hw_state.dynbindings[j].divisor = ves->divisor[j];
163 else
164 ves->hw_state.dynbindings[j].divisor = 1;
165 }
166 } else {
167 for (int j = 0; j < num_bindings; ++j) {
168 ves->hw_state.b.bindings[j].binding = ves->bindings[j].binding;
169 ves->hw_state.b.bindings[j].inputRate = ves->bindings[j].inputRate;
170 if (ves->divisor[j]) {
171 ves->hw_state.b.divisors[ves->hw_state.b.divisors_present].divisor = ves->divisor[j];
172 ves->hw_state.b.divisors[ves->hw_state.b.divisors_present].binding = ves->bindings[j].binding;
173 ves->hw_state.b.divisors_present++;
174 }
175 }
176 }
177 return ves;
178 }
179
180 static void
zink_bind_vertex_elements_state(struct pipe_context * pctx,void * cso)181 zink_bind_vertex_elements_state(struct pipe_context *pctx,
182 void *cso)
183 {
184 struct zink_context *ctx = zink_context(pctx);
185 struct zink_gfx_pipeline_state *state = &ctx->gfx_pipeline_state;
186 ctx->element_state = cso;
187 if (cso) {
188 if (state->element_state != &ctx->element_state->hw_state) {
189 ctx->vertex_state_changed = !zink_screen(pctx->screen)->info.have_EXT_vertex_input_dynamic_state;
190 ctx->vertex_buffers_dirty = ctx->element_state->hw_state.num_bindings > 0;
191 }
192 state->element_state = &ctx->element_state->hw_state;
193 if (zink_screen(pctx->screen)->optimal_keys)
194 return;
195 const struct zink_vs_key *vs = zink_get_vs_key(ctx);
196 uint32_t decomposed_attrs = 0, decomposed_attrs_without_w = 0;
197 switch (vs->size) {
198 case 1:
199 decomposed_attrs = vs->u8.decomposed_attrs;
200 decomposed_attrs_without_w = vs->u8.decomposed_attrs_without_w;
201 break;
202 case 2:
203 decomposed_attrs = vs->u16.decomposed_attrs;
204 decomposed_attrs_without_w = vs->u16.decomposed_attrs_without_w;
205 break;
206 case 4:
207 decomposed_attrs = vs->u16.decomposed_attrs;
208 decomposed_attrs_without_w = vs->u16.decomposed_attrs_without_w;
209 break;
210 }
211 if (ctx->element_state->decomposed_attrs != decomposed_attrs ||
212 ctx->element_state->decomposed_attrs_without_w != decomposed_attrs_without_w) {
213 unsigned size = MAX2(ctx->element_state->decomposed_attrs_size, ctx->element_state->decomposed_attrs_without_w_size);
214 struct zink_shader_key *key = (struct zink_shader_key *)zink_set_vs_key(ctx);
215 key->size -= 2 * key->key.vs.size;
216 switch (size) {
217 case 1:
218 key->key.vs.u8.decomposed_attrs = ctx->element_state->decomposed_attrs;
219 key->key.vs.u8.decomposed_attrs_without_w = ctx->element_state->decomposed_attrs_without_w;
220 break;
221 case 2:
222 key->key.vs.u16.decomposed_attrs = ctx->element_state->decomposed_attrs;
223 key->key.vs.u16.decomposed_attrs_without_w = ctx->element_state->decomposed_attrs_without_w;
224 break;
225 case 4:
226 key->key.vs.u32.decomposed_attrs = ctx->element_state->decomposed_attrs;
227 key->key.vs.u32.decomposed_attrs_without_w = ctx->element_state->decomposed_attrs_without_w;
228 break;
229 default: break;
230 }
231 key->key.vs.size = size;
232 key->size += 2 * size;
233 }
234 } else {
235 state->element_state = NULL;
236 ctx->vertex_buffers_dirty = false;
237 }
238 }
239
240 static void
zink_delete_vertex_elements_state(struct pipe_context * pctx,void * ves)241 zink_delete_vertex_elements_state(struct pipe_context *pctx,
242 void *ves)
243 {
244 FREE(ves);
245 }
246
247 static VkBlendFactor
blend_factor(enum pipe_blendfactor factor)248 blend_factor(enum pipe_blendfactor factor)
249 {
250 switch (factor) {
251 case PIPE_BLENDFACTOR_ONE: return VK_BLEND_FACTOR_ONE;
252 case PIPE_BLENDFACTOR_SRC_COLOR: return VK_BLEND_FACTOR_SRC_COLOR;
253 case PIPE_BLENDFACTOR_SRC_ALPHA: return VK_BLEND_FACTOR_SRC_ALPHA;
254 case PIPE_BLENDFACTOR_DST_ALPHA: return VK_BLEND_FACTOR_DST_ALPHA;
255 case PIPE_BLENDFACTOR_DST_COLOR: return VK_BLEND_FACTOR_DST_COLOR;
256 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
257 return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
258 case PIPE_BLENDFACTOR_CONST_COLOR: return VK_BLEND_FACTOR_CONSTANT_COLOR;
259 case PIPE_BLENDFACTOR_CONST_ALPHA: return VK_BLEND_FACTOR_CONSTANT_ALPHA;
260 case PIPE_BLENDFACTOR_SRC1_COLOR: return VK_BLEND_FACTOR_SRC1_COLOR;
261 case PIPE_BLENDFACTOR_SRC1_ALPHA: return VK_BLEND_FACTOR_SRC1_ALPHA;
262
263 case PIPE_BLENDFACTOR_ZERO: return VK_BLEND_FACTOR_ZERO;
264
265 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
266 return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
267 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
268 return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
269 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
270 return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
271 case PIPE_BLENDFACTOR_INV_DST_COLOR:
272 return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
273
274 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
275 return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
276 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
277 return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
278 case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
279 return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
280 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
281 return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
282 }
283 unreachable("unexpected blend factor");
284 }
285
286
287 static VkBlendOp
blend_op(enum pipe_blend_func func)288 blend_op(enum pipe_blend_func func)
289 {
290 switch (func) {
291 case PIPE_BLEND_ADD: return VK_BLEND_OP_ADD;
292 case PIPE_BLEND_SUBTRACT: return VK_BLEND_OP_SUBTRACT;
293 case PIPE_BLEND_REVERSE_SUBTRACT: return VK_BLEND_OP_REVERSE_SUBTRACT;
294 case PIPE_BLEND_MIN: return VK_BLEND_OP_MIN;
295 case PIPE_BLEND_MAX: return VK_BLEND_OP_MAX;
296 }
297 unreachable("unexpected blend function");
298 }
299
300 static VkLogicOp
logic_op(enum pipe_logicop func)301 logic_op(enum pipe_logicop func)
302 {
303 switch (func) {
304 case PIPE_LOGICOP_CLEAR: return VK_LOGIC_OP_CLEAR;
305 case PIPE_LOGICOP_NOR: return VK_LOGIC_OP_NOR;
306 case PIPE_LOGICOP_AND_INVERTED: return VK_LOGIC_OP_AND_INVERTED;
307 case PIPE_LOGICOP_COPY_INVERTED: return VK_LOGIC_OP_COPY_INVERTED;
308 case PIPE_LOGICOP_AND_REVERSE: return VK_LOGIC_OP_AND_REVERSE;
309 case PIPE_LOGICOP_INVERT: return VK_LOGIC_OP_INVERT;
310 case PIPE_LOGICOP_XOR: return VK_LOGIC_OP_XOR;
311 case PIPE_LOGICOP_NAND: return VK_LOGIC_OP_NAND;
312 case PIPE_LOGICOP_AND: return VK_LOGIC_OP_AND;
313 case PIPE_LOGICOP_EQUIV: return VK_LOGIC_OP_EQUIVALENT;
314 case PIPE_LOGICOP_NOOP: return VK_LOGIC_OP_NO_OP;
315 case PIPE_LOGICOP_OR_INVERTED: return VK_LOGIC_OP_OR_INVERTED;
316 case PIPE_LOGICOP_COPY: return VK_LOGIC_OP_COPY;
317 case PIPE_LOGICOP_OR_REVERSE: return VK_LOGIC_OP_OR_REVERSE;
318 case PIPE_LOGICOP_OR: return VK_LOGIC_OP_OR;
319 case PIPE_LOGICOP_SET: return VK_LOGIC_OP_SET;
320 }
321 unreachable("unexpected logicop function");
322 }
323
324 /* from iris */
325 static enum pipe_blendfactor
fix_blendfactor(enum pipe_blendfactor f,bool alpha_to_one)326 fix_blendfactor(enum pipe_blendfactor f, bool alpha_to_one)
327 {
328 if (alpha_to_one) {
329 if (f == PIPE_BLENDFACTOR_SRC1_ALPHA)
330 return PIPE_BLENDFACTOR_ONE;
331
332 if (f == PIPE_BLENDFACTOR_INV_SRC1_ALPHA)
333 return PIPE_BLENDFACTOR_ZERO;
334 }
335
336 return f;
337 }
338
339 static void *
zink_create_blend_state(struct pipe_context * pctx,const struct pipe_blend_state * blend_state)340 zink_create_blend_state(struct pipe_context *pctx,
341 const struct pipe_blend_state *blend_state)
342 {
343 struct zink_blend_state *cso = CALLOC_STRUCT(zink_blend_state);
344 if (!cso)
345 return NULL;
346 cso->hash = _mesa_hash_pointer(cso);
347
348 if (blend_state->logicop_enable) {
349 cso->logicop_enable = VK_TRUE;
350 cso->logicop_func = logic_op(blend_state->logicop_func);
351 }
352
353 /* TODO: figure out what to do with dither (nothing is probably "OK" for now,
354 * as dithering is undefined in GL
355 */
356
357 /* TODO: these are multisampling-state, and should be set there instead of
358 * here, as that's closer tied to the update-frequency
359 */
360 cso->alpha_to_coverage = blend_state->alpha_to_coverage;
361 cso->alpha_to_one = blend_state->alpha_to_one;
362 cso->num_rts = blend_state->max_rt + 1;
363
364 for (int i = 0; i < blend_state->max_rt + 1; ++i) {
365 const struct pipe_rt_blend_state *rt = blend_state->rt;
366 if (blend_state->independent_blend_enable)
367 rt = blend_state->rt + i;
368
369 VkPipelineColorBlendAttachmentState att = {0};
370
371 if (rt->blend_enable) {
372 att.blendEnable = VK_TRUE;
373 att.srcColorBlendFactor = blend_factor(fix_blendfactor(rt->rgb_src_factor, cso->alpha_to_one));
374 att.dstColorBlendFactor = blend_factor(fix_blendfactor(rt->rgb_dst_factor, cso->alpha_to_one));
375 att.colorBlendOp = blend_op(rt->rgb_func);
376 att.srcAlphaBlendFactor = blend_factor(fix_blendfactor(rt->alpha_src_factor, cso->alpha_to_one));
377 att.dstAlphaBlendFactor = blend_factor(fix_blendfactor(rt->alpha_dst_factor, cso->alpha_to_one));
378 att.alphaBlendOp = blend_op(rt->alpha_func);
379 }
380
381 if (rt->colormask & PIPE_MASK_R)
382 att.colorWriteMask |= VK_COLOR_COMPONENT_R_BIT;
383 if (rt->colormask & PIPE_MASK_G)
384 att.colorWriteMask |= VK_COLOR_COMPONENT_G_BIT;
385 if (rt->colormask & PIPE_MASK_B)
386 att.colorWriteMask |= VK_COLOR_COMPONENT_B_BIT;
387 if (rt->colormask & PIPE_MASK_A)
388 att.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT;
389
390 cso->wrmask |= (rt->colormask << i);
391 if (rt->blend_enable)
392 cso->enables |= BITFIELD_BIT(i);
393
394 cso->attachments[i] = att;
395
396 cso->ds3.enables[i] = att.blendEnable;
397 cso->ds3.eq[i].alphaBlendOp = att.alphaBlendOp;
398 cso->ds3.eq[i].dstAlphaBlendFactor = att.dstAlphaBlendFactor;
399 cso->ds3.eq[i].srcAlphaBlendFactor = att.srcAlphaBlendFactor;
400 cso->ds3.eq[i].colorBlendOp = att.colorBlendOp;
401 cso->ds3.eq[i].dstColorBlendFactor = att.dstColorBlendFactor;
402 cso->ds3.eq[i].srcColorBlendFactor = att.srcColorBlendFactor;
403 cso->ds3.wrmask[i] = att.colorWriteMask;
404 }
405 cso->dual_src_blend = util_blend_state_is_dual(blend_state, 0);
406
407 return cso;
408 }
409
410 static void
zink_bind_blend_state(struct pipe_context * pctx,void * cso)411 zink_bind_blend_state(struct pipe_context *pctx, void *cso)
412 {
413 struct zink_context *ctx = zink_context(pctx);
414 struct zink_screen *screen = zink_screen(pctx->screen);
415 struct zink_gfx_pipeline_state* state = &zink_context(pctx)->gfx_pipeline_state;
416 struct zink_blend_state *blend = cso;
417 struct zink_blend_state *old_blend = state->blend_state;
418
419 if (state->blend_state != cso) {
420 state->blend_state = cso;
421 if (!screen->have_full_ds3) {
422 state->blend_id = blend ? blend->hash : 0;
423 state->dirty = true;
424 }
425 bool force_dual_color_blend = screen->driconf.dual_color_blend_by_location &&
426 blend && blend->dual_src_blend && state->blend_state->attachments[0].blendEnable;
427 if (force_dual_color_blend != zink_get_fs_base_key(ctx)->force_dual_color_blend)
428 zink_set_fs_base_key(ctx)->force_dual_color_blend = force_dual_color_blend;
429 ctx->blend_state_changed = true;
430
431 if (cso && screen->have_full_ds3) {
432 #define STATE_CHECK(NAME, FLAG) \
433 if ((!old_blend || old_blend->NAME != blend->NAME)) \
434 ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_BLEND_##FLAG)
435
436 STATE_CHECK(alpha_to_coverage, A2C);
437 if (screen->info.dynamic_state3_feats.extendedDynamicState3AlphaToOneEnable) {
438 STATE_CHECK(alpha_to_one, A21);
439 }
440 STATE_CHECK(enables, ON);
441 STATE_CHECK(wrmask, WRITE);
442 if (old_blend && blend->num_rts == old_blend->num_rts) {
443 if (memcmp(blend->ds3.eq, old_blend->ds3.eq, blend->num_rts * sizeof(blend->ds3.eq[0])))
444 ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_BLEND_EQ);
445 } else {
446 ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_BLEND_EQ);
447 }
448 STATE_CHECK(logicop_enable, LOGIC_ON);
449 STATE_CHECK(logicop_func, LOGIC);
450
451 #undef STATE_CHECK
452 }
453
454 }
455 }
456
457 static void
zink_delete_blend_state(struct pipe_context * pctx,void * blend_state)458 zink_delete_blend_state(struct pipe_context *pctx, void *blend_state)
459 {
460 FREE(blend_state);
461 }
462
463 static VkCompareOp
compare_op(enum pipe_compare_func func)464 compare_op(enum pipe_compare_func func)
465 {
466 switch (func) {
467 case PIPE_FUNC_NEVER: return VK_COMPARE_OP_NEVER;
468 case PIPE_FUNC_LESS: return VK_COMPARE_OP_LESS;
469 case PIPE_FUNC_EQUAL: return VK_COMPARE_OP_EQUAL;
470 case PIPE_FUNC_LEQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL;
471 case PIPE_FUNC_GREATER: return VK_COMPARE_OP_GREATER;
472 case PIPE_FUNC_NOTEQUAL: return VK_COMPARE_OP_NOT_EQUAL;
473 case PIPE_FUNC_GEQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL;
474 case PIPE_FUNC_ALWAYS: return VK_COMPARE_OP_ALWAYS;
475 }
476 unreachable("unexpected func");
477 }
478
479 static VkStencilOp
stencil_op(enum pipe_stencil_op op)480 stencil_op(enum pipe_stencil_op op)
481 {
482 switch (op) {
483 case PIPE_STENCIL_OP_KEEP: return VK_STENCIL_OP_KEEP;
484 case PIPE_STENCIL_OP_ZERO: return VK_STENCIL_OP_ZERO;
485 case PIPE_STENCIL_OP_REPLACE: return VK_STENCIL_OP_REPLACE;
486 case PIPE_STENCIL_OP_INCR: return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
487 case PIPE_STENCIL_OP_DECR: return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
488 case PIPE_STENCIL_OP_INCR_WRAP: return VK_STENCIL_OP_INCREMENT_AND_WRAP;
489 case PIPE_STENCIL_OP_DECR_WRAP: return VK_STENCIL_OP_DECREMENT_AND_WRAP;
490 case PIPE_STENCIL_OP_INVERT: return VK_STENCIL_OP_INVERT;
491 }
492 unreachable("unexpected op");
493 }
494
495 static VkStencilOpState
stencil_op_state(const struct pipe_stencil_state * src)496 stencil_op_state(const struct pipe_stencil_state *src)
497 {
498 VkStencilOpState ret;
499 ret.failOp = stencil_op(src->fail_op);
500 ret.passOp = stencil_op(src->zpass_op);
501 ret.depthFailOp = stencil_op(src->zfail_op);
502 ret.compareOp = compare_op(src->func);
503 ret.compareMask = src->valuemask;
504 ret.writeMask = src->writemask;
505 ret.reference = 0; // not used: we'll use a dynamic state for this
506 return ret;
507 }
508
509 static void *
zink_create_depth_stencil_alpha_state(struct pipe_context * pctx,const struct pipe_depth_stencil_alpha_state * depth_stencil_alpha)510 zink_create_depth_stencil_alpha_state(struct pipe_context *pctx,
511 const struct pipe_depth_stencil_alpha_state *depth_stencil_alpha)
512 {
513 struct zink_depth_stencil_alpha_state *cso = CALLOC_STRUCT(zink_depth_stencil_alpha_state);
514 if (!cso)
515 return NULL;
516
517 cso->base = *depth_stencil_alpha;
518
519 if (depth_stencil_alpha->depth_enabled) {
520 cso->hw_state.depth_test = VK_TRUE;
521 cso->hw_state.depth_compare_op = compare_op(depth_stencil_alpha->depth_func);
522 }
523
524 if (depth_stencil_alpha->depth_bounds_test) {
525 cso->hw_state.depth_bounds_test = VK_TRUE;
526 cso->hw_state.min_depth_bounds = depth_stencil_alpha->depth_bounds_min;
527 cso->hw_state.max_depth_bounds = depth_stencil_alpha->depth_bounds_max;
528 }
529
530 if (depth_stencil_alpha->stencil[0].enabled) {
531 cso->hw_state.stencil_test = VK_TRUE;
532 cso->hw_state.stencil_front = stencil_op_state(depth_stencil_alpha->stencil);
533 }
534
535 if (depth_stencil_alpha->stencil[1].enabled)
536 cso->hw_state.stencil_back = stencil_op_state(depth_stencil_alpha->stencil + 1);
537 else
538 cso->hw_state.stencil_back = cso->hw_state.stencil_front;
539
540 cso->hw_state.depth_write = depth_stencil_alpha->depth_writemask;
541
542 return cso;
543 }
544
545 static void
zink_bind_depth_stencil_alpha_state(struct pipe_context * pctx,void * cso)546 zink_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *cso)
547 {
548 struct zink_context *ctx = zink_context(pctx);
549
550 ctx->dsa_state = cso;
551
552 if (cso) {
553 struct zink_gfx_pipeline_state *state = &ctx->gfx_pipeline_state;
554 if (state->dyn_state1.depth_stencil_alpha_state != &ctx->dsa_state->hw_state) {
555 state->dyn_state1.depth_stencil_alpha_state = &ctx->dsa_state->hw_state;
556 state->dirty |= !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state;
557 ctx->dsa_state_changed = true;
558 }
559 }
560 if (!ctx->track_renderpasses && !ctx->blitting)
561 ctx->rp_tc_info_updated = true;
562 }
563
564 static void
zink_delete_depth_stencil_alpha_state(struct pipe_context * pctx,void * depth_stencil_alpha)565 zink_delete_depth_stencil_alpha_state(struct pipe_context *pctx,
566 void *depth_stencil_alpha)
567 {
568 FREE(depth_stencil_alpha);
569 }
570
571 static float
round_to_granularity(float value,float granularity)572 round_to_granularity(float value, float granularity)
573 {
574 return roundf(value / granularity) * granularity;
575 }
576
577 static float
line_width(float width,float granularity,const float range[2])578 line_width(float width, float granularity, const float range[2])
579 {
580 assert(granularity >= 0);
581 assert(range[0] <= range[1]);
582
583 if (granularity > 0)
584 width = round_to_granularity(width, granularity);
585
586 return CLAMP(width, range[0], range[1]);
587 }
588
589 static void *
zink_create_rasterizer_state(struct pipe_context * pctx,const struct pipe_rasterizer_state * rs_state)590 zink_create_rasterizer_state(struct pipe_context *pctx,
591 const struct pipe_rasterizer_state *rs_state)
592 {
593 struct zink_screen *screen = zink_screen(pctx->screen);
594
595 struct zink_rasterizer_state *state = CALLOC_STRUCT(zink_rasterizer_state);
596 if (!state)
597 return NULL;
598
599 state->base = *rs_state;
600 state->base.line_stipple_factor++;
601
602 state->hw_state.line_stipple_enable =
603 rs_state->line_stipple_enable &&
604 !screen->driver_workarounds.no_linestipple;
605
606 assert(rs_state->depth_clip_far == rs_state->depth_clip_near);
607 state->hw_state.depth_clip = rs_state->depth_clip_near;
608 state->hw_state.depth_clamp = rs_state->depth_clamp;
609 state->hw_state.pv_last = !rs_state->flatshade_first;
610 state->hw_state.clip_halfz = rs_state->clip_halfz;
611
612 assert(rs_state->fill_front <= PIPE_POLYGON_MODE_POINT);
613 if (rs_state->fill_back != rs_state->fill_front)
614 debug_printf("BUG: vulkan doesn't support different front and back fill modes\n");
615
616 if (rs_state->fill_front == PIPE_POLYGON_MODE_POINT &&
617 screen->driver_workarounds.no_hw_gl_point) {
618 state->hw_state.polygon_mode = VK_POLYGON_MODE_FILL;
619 state->cull_mode = VK_CULL_MODE_NONE;
620 } else {
621 state->hw_state.polygon_mode = rs_state->fill_front; // same values
622 state->cull_mode = rs_state->cull_face; // same bits
623 }
624
625 state->front_face = rs_state->front_ccw ?
626 VK_FRONT_FACE_COUNTER_CLOCKWISE :
627 VK_FRONT_FACE_CLOCKWISE;
628
629 state->hw_state.line_mode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
630 if (rs_state->line_rectangular) {
631 if (rs_state->line_smooth &&
632 !screen->driver_workarounds.no_linesmooth)
633 state->hw_state.line_mode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
634 else
635 state->hw_state.line_mode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
636 } else {
637 state->hw_state.line_mode = VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT;
638 }
639 state->dynamic_line_mode = state->hw_state.line_mode;
640 switch (state->hw_state.line_mode) {
641 case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT:
642 if (!screen->info.line_rast_feats.rectangularLines)
643 state->dynamic_line_mode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
644 break;
645 case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT:
646 if (!screen->info.line_rast_feats.smoothLines)
647 state->dynamic_line_mode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
648 break;
649 case VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT:
650 if (!screen->info.line_rast_feats.bresenhamLines)
651 state->dynamic_line_mode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
652 break;
653 default: break;
654 }
655
656 if (!rs_state->line_stipple_enable) {
657 state->base.line_stipple_factor = 1;
658 state->base.line_stipple_pattern = UINT16_MAX;
659 }
660
661 state->offset_fill = util_get_offset(rs_state, rs_state->fill_front);
662 state->offset_units = rs_state->offset_units;
663 if (!rs_state->offset_units_unscaled)
664 state->offset_units *= 2;
665 state->offset_clamp = rs_state->offset_clamp;
666 state->offset_scale = rs_state->offset_scale;
667
668 state->line_width = line_width(rs_state->line_width,
669 screen->info.props.limits.lineWidthGranularity,
670 screen->info.props.limits.lineWidthRange);
671
672 return state;
673 }
674
675 static void
zink_bind_rasterizer_state(struct pipe_context * pctx,void * cso)676 zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso)
677 {
678 struct zink_context *ctx = zink_context(pctx);
679 struct zink_screen *screen = zink_screen(pctx->screen);
680 struct zink_rasterizer_state *prev_state = ctx->rast_state;
681 bool point_quad_rasterization = ctx->rast_state ? ctx->rast_state->base.point_quad_rasterization : false;
682 bool scissor = ctx->rast_state ? ctx->rast_state->base.scissor : false;
683 bool pv_last = ctx->rast_state ? ctx->rast_state->hw_state.pv_last : false;
684 bool force_persample_interp = ctx->gfx_pipeline_state.force_persample_interp;
685 bool clip_halfz = ctx->rast_state ? ctx->rast_state->hw_state.clip_halfz : false;
686 bool rasterizer_discard = ctx->rast_state ? ctx->rast_state->base.rasterizer_discard : false;
687 bool half_pixel_center = ctx->rast_state ? ctx->rast_state->base.half_pixel_center : true;
688 float line_width = ctx->rast_state ? ctx->rast_state->base.line_width : 1.0;
689 ctx->rast_state = cso;
690
691 if (ctx->rast_state) {
692 if (screen->info.have_EXT_provoking_vertex &&
693 pv_last != ctx->rast_state->hw_state.pv_last &&
694 /* without this prop, change in pv mode requires new rp */
695 !screen->info.pv_props.provokingVertexModePerPipeline)
696 zink_batch_no_rp(ctx);
697 memcpy(&ctx->gfx_pipeline_state.dyn_state3, &ctx->rast_state->hw_state, sizeof(struct zink_rasterizer_hw_state));
698
699 ctx->gfx_pipeline_state.dirty |= !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state3;
700 ctx->rast_state_changed = true;
701
702 if (clip_halfz != ctx->rast_state->base.clip_halfz) {
703 if (screen->info.have_EXT_depth_clip_control)
704 ctx->gfx_pipeline_state.dirty = true;
705 else
706 zink_set_last_vertex_key(ctx)->clip_halfz = ctx->rast_state->base.clip_halfz;
707 ctx->vp_state_changed = true;
708 }
709
710 if (screen->info.have_EXT_extended_dynamic_state3) {
711 #define STATE_CHECK(NAME, FLAG) \
712 if (cso && (!prev_state || prev_state->NAME != ctx->rast_state->NAME)) \
713 ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_RAST_##FLAG)
714
715 if (!screen->driver_workarounds.no_linestipple) {
716 if (ctx->rast_state->base.line_stipple_enable) {
717 STATE_CHECK(base.line_stipple_factor, STIPPLE);
718 STATE_CHECK(base.line_stipple_pattern, STIPPLE);
719 } else {
720 ctx->ds3_states &= ~BITFIELD_BIT(ZINK_DS3_RAST_STIPPLE);
721 }
722 if (screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable) {
723 STATE_CHECK(hw_state.line_stipple_enable, STIPPLE_ON);
724 }
725 }
726 STATE_CHECK(hw_state.depth_clip, CLIP);
727 STATE_CHECK(hw_state.depth_clamp, CLAMP);
728 STATE_CHECK(hw_state.polygon_mode, POLYGON);
729 STATE_CHECK(hw_state.clip_halfz, HALFZ);
730 STATE_CHECK(hw_state.pv_last, PV);
731 STATE_CHECK(dynamic_line_mode, LINE);
732
733 #undef STATE_CHECK
734 }
735
736 if (fabs(ctx->rast_state->base.line_width - line_width) > FLT_EPSILON)
737 ctx->line_width_changed = true;
738
739 bool lower_gl_point = screen->driver_workarounds.no_hw_gl_point;
740 lower_gl_point &= ctx->rast_state->base.fill_front == PIPE_POLYGON_MODE_POINT;
741 if (zink_get_gs_key(ctx)->lower_gl_point != lower_gl_point)
742 zink_set_gs_key(ctx)->lower_gl_point = lower_gl_point;
743
744 if (ctx->gfx_pipeline_state.dyn_state1.front_face != ctx->rast_state->front_face) {
745 ctx->gfx_pipeline_state.dyn_state1.front_face = ctx->rast_state->front_face;
746 ctx->gfx_pipeline_state.dirty |= !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state;
747 }
748 if (ctx->gfx_pipeline_state.dyn_state1.cull_mode != ctx->rast_state->cull_mode) {
749 ctx->gfx_pipeline_state.dyn_state1.cull_mode = ctx->rast_state->cull_mode;
750 ctx->gfx_pipeline_state.dirty |= !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state;
751 }
752 if (!ctx->primitives_generated_active)
753 zink_set_rasterizer_discard(ctx, false);
754 else if (rasterizer_discard != ctx->rast_state->base.rasterizer_discard)
755 zink_set_null_fs(ctx);
756
757 if (ctx->rast_state->base.point_quad_rasterization ||
758 ctx->rast_state->base.point_quad_rasterization != point_quad_rasterization)
759 zink_set_fs_point_coord_key(ctx);
760 if (ctx->rast_state->base.scissor != scissor)
761 ctx->scissor_changed = true;
762
763 if (ctx->rast_state->base.force_persample_interp != force_persample_interp) {
764 zink_set_fs_base_key(ctx)->force_persample_interp = ctx->rast_state->base.force_persample_interp;
765 ctx->gfx_pipeline_state.dirty = true;
766 }
767 ctx->gfx_pipeline_state.force_persample_interp = ctx->rast_state->base.force_persample_interp;
768
769 if (ctx->rast_state->base.half_pixel_center != half_pixel_center)
770 ctx->vp_state_changed = true;
771
772 if (!screen->optimal_keys)
773 zink_update_gs_key_rectangular_line(ctx);
774 }
775 }
776
777 static void
zink_delete_rasterizer_state(struct pipe_context * pctx,void * rs_state)778 zink_delete_rasterizer_state(struct pipe_context *pctx, void *rs_state)
779 {
780 FREE(rs_state);
781 }
782
783 struct pipe_vertex_state *
zink_create_vertex_state(struct pipe_screen * pscreen,struct pipe_vertex_buffer * buffer,const struct pipe_vertex_element * elements,unsigned num_elements,struct pipe_resource * indexbuf,uint32_t full_velem_mask)784 zink_create_vertex_state(struct pipe_screen *pscreen,
785 struct pipe_vertex_buffer *buffer,
786 const struct pipe_vertex_element *elements,
787 unsigned num_elements,
788 struct pipe_resource *indexbuf,
789 uint32_t full_velem_mask)
790 {
791 struct zink_vertex_state *zstate = CALLOC_STRUCT(zink_vertex_state);
792 if (!zstate) {
793 mesa_loge("ZINK: failed to allocate zstate!");
794 return NULL;
795 }
796
797 util_init_pipe_vertex_state(pscreen, buffer, elements, num_elements, indexbuf, full_velem_mask,
798 &zstate->b);
799
800 /* Initialize the vertex element state in state->element.
801 * Do it by creating a vertex element state object and copying it there.
802 */
803 struct zink_context ctx;
804 ctx.base.screen = pscreen;
805 struct zink_vertex_elements_state *elems = zink_create_vertex_elements_state(&ctx.base, num_elements, elements);
806 zstate->velems = *elems;
807 zink_delete_vertex_elements_state(&ctx.base, elems);
808
809 return &zstate->b;
810 }
811
812 void
zink_vertex_state_destroy(struct pipe_screen * pscreen,struct pipe_vertex_state * vstate)813 zink_vertex_state_destroy(struct pipe_screen *pscreen, struct pipe_vertex_state *vstate)
814 {
815 pipe_vertex_buffer_unreference(&vstate->input.vbuffer);
816 pipe_resource_reference(&vstate->input.indexbuf, NULL);
817 FREE(vstate);
818 }
819
820 struct pipe_vertex_state *
zink_cache_create_vertex_state(struct pipe_screen * pscreen,struct pipe_vertex_buffer * buffer,const struct pipe_vertex_element * elements,unsigned num_elements,struct pipe_resource * indexbuf,uint32_t full_velem_mask)821 zink_cache_create_vertex_state(struct pipe_screen *pscreen,
822 struct pipe_vertex_buffer *buffer,
823 const struct pipe_vertex_element *elements,
824 unsigned num_elements,
825 struct pipe_resource *indexbuf,
826 uint32_t full_velem_mask)
827 {
828 struct zink_screen *screen = zink_screen(pscreen);
829
830 return util_vertex_state_cache_get(pscreen, buffer, elements, num_elements, indexbuf,
831 full_velem_mask, &screen->vertex_state_cache);
832 }
833
834 void
zink_cache_vertex_state_destroy(struct pipe_screen * pscreen,struct pipe_vertex_state * vstate)835 zink_cache_vertex_state_destroy(struct pipe_screen *pscreen, struct pipe_vertex_state *vstate)
836 {
837 struct zink_screen *screen = zink_screen(pscreen);
838
839 util_vertex_state_destroy(pscreen, &screen->vertex_state_cache, vstate);
840 }
841
842 void
zink_context_state_init(struct pipe_context * pctx)843 zink_context_state_init(struct pipe_context *pctx)
844 {
845 pctx->create_vertex_elements_state = zink_create_vertex_elements_state;
846 pctx->bind_vertex_elements_state = zink_bind_vertex_elements_state;
847 pctx->delete_vertex_elements_state = zink_delete_vertex_elements_state;
848
849 pctx->create_blend_state = zink_create_blend_state;
850 pctx->bind_blend_state = zink_bind_blend_state;
851 pctx->delete_blend_state = zink_delete_blend_state;
852
853 pctx->create_depth_stencil_alpha_state = zink_create_depth_stencil_alpha_state;
854 pctx->bind_depth_stencil_alpha_state = zink_bind_depth_stencil_alpha_state;
855 pctx->delete_depth_stencil_alpha_state = zink_delete_depth_stencil_alpha_state;
856
857 pctx->create_rasterizer_state = zink_create_rasterizer_state;
858 pctx->bind_rasterizer_state = zink_bind_rasterizer_state;
859 pctx->delete_rasterizer_state = zink_delete_rasterizer_state;
860 }
861