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