17ec681f3Smrg/* 27ec681f3Smrg * Copyright 2018 Collabora Ltd. 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 87ec681f3Smrg * license, and/or sell copies of the Software, and to permit persons to whom 97ec681f3Smrg * the Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice (including the next 127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 137ec681f3Smrg * Software. 147ec681f3Smrg * 157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 187ec681f3Smrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 197ec681f3Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 207ec681f3Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 217ec681f3Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. 227ec681f3Smrg */ 237ec681f3Smrg 247ec681f3Smrg#include "zink_state.h" 257ec681f3Smrg 267ec681f3Smrg#include "zink_context.h" 277ec681f3Smrg#include "zink_format.h" 287ec681f3Smrg#include "zink_program.h" 297ec681f3Smrg#include "zink_screen.h" 307ec681f3Smrg 317ec681f3Smrg#include "compiler/shader_enums.h" 327ec681f3Smrg#include "util/u_dual_blend.h" 337ec681f3Smrg#include "util/u_memory.h" 347ec681f3Smrg 357ec681f3Smrg#include <math.h> 367ec681f3Smrg 377ec681f3Smrgstatic void * 387ec681f3Smrgzink_create_vertex_elements_state(struct pipe_context *pctx, 397ec681f3Smrg unsigned num_elements, 407ec681f3Smrg const struct pipe_vertex_element *elements) 417ec681f3Smrg{ 427ec681f3Smrg struct zink_screen *screen = zink_screen(pctx->screen); 437ec681f3Smrg unsigned int i; 447ec681f3Smrg struct zink_vertex_elements_state *ves = CALLOC_STRUCT(zink_vertex_elements_state); 457ec681f3Smrg if (!ves) 467ec681f3Smrg return NULL; 477ec681f3Smrg ves->hw_state.hash = _mesa_hash_pointer(ves); 487ec681f3Smrg 497ec681f3Smrg int buffer_map[PIPE_MAX_ATTRIBS]; 507ec681f3Smrg for (int i = 0; i < ARRAY_SIZE(buffer_map); ++i) 517ec681f3Smrg buffer_map[i] = -1; 527ec681f3Smrg 537ec681f3Smrg int num_bindings = 0; 547ec681f3Smrg unsigned num_decomposed = 0; 557ec681f3Smrg uint32_t size8 = 0; 567ec681f3Smrg uint32_t size16 = 0; 577ec681f3Smrg uint32_t size32 = 0; 587ec681f3Smrg for (i = 0; i < num_elements; ++i) { 597ec681f3Smrg const struct pipe_vertex_element *elem = elements + i; 607ec681f3Smrg 617ec681f3Smrg int binding = elem->vertex_buffer_index; 627ec681f3Smrg if (buffer_map[binding] < 0) { 637ec681f3Smrg ves->binding_map[num_bindings] = binding; 647ec681f3Smrg buffer_map[binding] = num_bindings++; 657ec681f3Smrg } 667ec681f3Smrg binding = buffer_map[binding]; 677ec681f3Smrg 687ec681f3Smrg ves->bindings[binding].binding = binding; 697ec681f3Smrg ves->bindings[binding].inputRate = elem->instance_divisor ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; 707ec681f3Smrg 717ec681f3Smrg assert(!elem->instance_divisor || zink_screen(pctx->screen)->info.have_EXT_vertex_attribute_divisor); 727ec681f3Smrg if (elem->instance_divisor > screen->info.vdiv_props.maxVertexAttribDivisor) 737ec681f3Smrg debug_printf("zink: clamping instance divisor %u to %u\n", elem->instance_divisor, screen->info.vdiv_props.maxVertexAttribDivisor); 747ec681f3Smrg ves->divisor[binding] = MIN2(elem->instance_divisor, screen->info.vdiv_props.maxVertexAttribDivisor); 757ec681f3Smrg 767ec681f3Smrg VkFormat format; 777ec681f3Smrg if (screen->format_props[elem->src_format].bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) 787ec681f3Smrg format = zink_get_format(screen, elem->src_format); 797ec681f3Smrg else { 807ec681f3Smrg enum pipe_format new_format = zink_decompose_vertex_format(elem->src_format); 817ec681f3Smrg assert(new_format); 827ec681f3Smrg num_decomposed++; 837ec681f3Smrg assert(screen->format_props[new_format].bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT); 847ec681f3Smrg if (util_format_get_blocksize(new_format) == 4) 857ec681f3Smrg size32 |= BITFIELD_BIT(i); 867ec681f3Smrg else if (util_format_get_blocksize(new_format) == 2) 877ec681f3Smrg size16 |= BITFIELD_BIT(i); 887ec681f3Smrg else 897ec681f3Smrg size8 |= BITFIELD_BIT(i); 907ec681f3Smrg format = zink_get_format(screen, new_format); 917ec681f3Smrg unsigned size; 927ec681f3Smrg if (i < 8) 937ec681f3Smrg size = 1; 947ec681f3Smrg else if (i < 16) 957ec681f3Smrg size = 2; 967ec681f3Smrg else 977ec681f3Smrg size = 4; 987ec681f3Smrg if (util_format_get_nr_components(elem->src_format) == 4) { 997ec681f3Smrg ves->decomposed_attrs |= BITFIELD_BIT(i); 1007ec681f3Smrg ves->decomposed_attrs_size = size; 1017ec681f3Smrg } else { 1027ec681f3Smrg ves->decomposed_attrs_without_w |= BITFIELD_BIT(i); 1037ec681f3Smrg ves->decomposed_attrs_without_w_size = size; 1047ec681f3Smrg } 1057ec681f3Smrg } 1067ec681f3Smrg 1077ec681f3Smrg if (screen->info.have_EXT_vertex_input_dynamic_state) { 1087ec681f3Smrg ves->hw_state.dynattribs[i].sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT; 1097ec681f3Smrg ves->hw_state.dynattribs[i].binding = binding; 1107ec681f3Smrg ves->hw_state.dynattribs[i].location = i; 1117ec681f3Smrg ves->hw_state.dynattribs[i].format = format; 1127ec681f3Smrg assert(ves->hw_state.dynattribs[i].format != VK_FORMAT_UNDEFINED); 1137ec681f3Smrg ves->hw_state.dynattribs[i].offset = elem->src_offset; 1147ec681f3Smrg } else { 1157ec681f3Smrg ves->hw_state.attribs[i].binding = binding; 1167ec681f3Smrg ves->hw_state.attribs[i].location = i; 1177ec681f3Smrg ves->hw_state.attribs[i].format = format; 1187ec681f3Smrg assert(ves->hw_state.attribs[i].format != VK_FORMAT_UNDEFINED); 1197ec681f3Smrg ves->hw_state.attribs[i].offset = elem->src_offset; 1207ec681f3Smrg } 1217ec681f3Smrg } 1227ec681f3Smrg assert(num_decomposed + num_elements <= PIPE_MAX_ATTRIBS); 1237ec681f3Smrg u_foreach_bit(i, ves->decomposed_attrs | ves->decomposed_attrs_without_w) { 1247ec681f3Smrg const struct pipe_vertex_element *elem = elements + i; 1257ec681f3Smrg const struct util_format_description *desc = util_format_description(elem->src_format); 1267ec681f3Smrg unsigned size = 1; 1277ec681f3Smrg if (size32 & BITFIELD_BIT(i)) 1287ec681f3Smrg size = 4; 1297ec681f3Smrg else if (size16 & BITFIELD_BIT(i)) 1307ec681f3Smrg size = 2; 1317ec681f3Smrg for (unsigned j = 1; j < desc->nr_channels; j++) { 1327ec681f3Smrg if (screen->info.have_EXT_vertex_input_dynamic_state) { 1337ec681f3Smrg memcpy(&ves->hw_state.dynattribs[num_elements], &ves->hw_state.dynattribs[i], sizeof(VkVertexInputAttributeDescription2EXT)); 1347ec681f3Smrg ves->hw_state.dynattribs[num_elements].location = num_elements; 1357ec681f3Smrg ves->hw_state.dynattribs[num_elements].offset += j * size; 1367ec681f3Smrg } else { 1377ec681f3Smrg memcpy(&ves->hw_state.attribs[num_elements], &ves->hw_state.attribs[i], sizeof(VkVertexInputAttributeDescription)); 1387ec681f3Smrg ves->hw_state.attribs[num_elements].location = num_elements; 1397ec681f3Smrg ves->hw_state.attribs[num_elements].offset += j * size; 1407ec681f3Smrg } 1417ec681f3Smrg num_elements++; 1427ec681f3Smrg } 1437ec681f3Smrg } 1447ec681f3Smrg ves->hw_state.num_bindings = num_bindings; 1457ec681f3Smrg ves->hw_state.num_attribs = num_elements; 1467ec681f3Smrg if (screen->info.have_EXT_vertex_input_dynamic_state) { 1477ec681f3Smrg for (int i = 0; i < num_bindings; ++i) { 1487ec681f3Smrg ves->hw_state.dynbindings[i].sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT; 1497ec681f3Smrg ves->hw_state.dynbindings[i].binding = ves->bindings[i].binding; 1507ec681f3Smrg ves->hw_state.dynbindings[i].inputRate = ves->bindings[i].inputRate; 1517ec681f3Smrg if (ves->divisor[i]) 1527ec681f3Smrg ves->hw_state.dynbindings[i].divisor = ves->divisor[i]; 1537ec681f3Smrg else 1547ec681f3Smrg ves->hw_state.dynbindings[i].divisor = 1; 1557ec681f3Smrg } 1567ec681f3Smrg } else { 1577ec681f3Smrg for (int i = 0; i < num_bindings; ++i) { 1587ec681f3Smrg ves->hw_state.b.bindings[i].binding = ves->bindings[i].binding; 1597ec681f3Smrg ves->hw_state.b.bindings[i].inputRate = ves->bindings[i].inputRate; 1607ec681f3Smrg if (ves->divisor[i]) { 1617ec681f3Smrg ves->hw_state.b.divisors[ves->hw_state.b.divisors_present].divisor = ves->divisor[i]; 1627ec681f3Smrg ves->hw_state.b.divisors[ves->hw_state.b.divisors_present].binding = ves->bindings[i].binding; 1637ec681f3Smrg ves->hw_state.b.divisors_present++; 1647ec681f3Smrg } 1657ec681f3Smrg } 1667ec681f3Smrg } 1677ec681f3Smrg return ves; 1687ec681f3Smrg} 1697ec681f3Smrg 1707ec681f3Smrgstatic void 1717ec681f3Smrgzink_bind_vertex_elements_state(struct pipe_context *pctx, 1727ec681f3Smrg void *cso) 1737ec681f3Smrg{ 1747ec681f3Smrg struct zink_context *ctx = zink_context(pctx); 1757ec681f3Smrg struct zink_gfx_pipeline_state *state = &ctx->gfx_pipeline_state; 1767ec681f3Smrg ctx->element_state = cso; 1777ec681f3Smrg if (cso) { 1787ec681f3Smrg if (state->element_state != &ctx->element_state->hw_state) { 1797ec681f3Smrg ctx->vertex_state_changed = !zink_screen(pctx->screen)->info.have_EXT_vertex_input_dynamic_state; 1807ec681f3Smrg ctx->vertex_buffers_dirty = ctx->element_state->hw_state.num_bindings > 0; 1817ec681f3Smrg } 1827ec681f3Smrg const struct zink_vs_key *vs = zink_get_vs_key(ctx); 1837ec681f3Smrg uint32_t decomposed_attrs = 0, decomposed_attrs_without_w = 0; 1847ec681f3Smrg switch (vs->size) { 1857ec681f3Smrg case 1: 1867ec681f3Smrg decomposed_attrs = vs->u8.decomposed_attrs; 1877ec681f3Smrg decomposed_attrs_without_w = vs->u8.decomposed_attrs_without_w; 1887ec681f3Smrg break; 1897ec681f3Smrg case 2: 1907ec681f3Smrg decomposed_attrs = vs->u16.decomposed_attrs; 1917ec681f3Smrg decomposed_attrs_without_w = vs->u16.decomposed_attrs_without_w; 1927ec681f3Smrg break; 1937ec681f3Smrg case 4: 1947ec681f3Smrg decomposed_attrs = vs->u16.decomposed_attrs; 1957ec681f3Smrg decomposed_attrs_without_w = vs->u16.decomposed_attrs_without_w; 1967ec681f3Smrg break; 1977ec681f3Smrg } 1987ec681f3Smrg if (ctx->element_state->decomposed_attrs != decomposed_attrs || 1997ec681f3Smrg ctx->element_state->decomposed_attrs_without_w != decomposed_attrs_without_w) { 2007ec681f3Smrg unsigned size = MAX2(ctx->element_state->decomposed_attrs_size, ctx->element_state->decomposed_attrs_without_w_size); 2017ec681f3Smrg struct zink_shader_key *key = (struct zink_shader_key *)zink_set_vs_key(ctx); 2027ec681f3Smrg key->size -= 2 * key->key.vs.size; 2037ec681f3Smrg switch (size) { 2047ec681f3Smrg case 1: 2057ec681f3Smrg key->key.vs.u8.decomposed_attrs = ctx->element_state->decomposed_attrs; 2067ec681f3Smrg key->key.vs.u8.decomposed_attrs_without_w = ctx->element_state->decomposed_attrs_without_w; 2077ec681f3Smrg break; 2087ec681f3Smrg case 2: 2097ec681f3Smrg key->key.vs.u16.decomposed_attrs = ctx->element_state->decomposed_attrs; 2107ec681f3Smrg key->key.vs.u16.decomposed_attrs_without_w = ctx->element_state->decomposed_attrs_without_w; 2117ec681f3Smrg break; 2127ec681f3Smrg case 4: 2137ec681f3Smrg key->key.vs.u32.decomposed_attrs = ctx->element_state->decomposed_attrs; 2147ec681f3Smrg key->key.vs.u32.decomposed_attrs_without_w = ctx->element_state->decomposed_attrs_without_w; 2157ec681f3Smrg break; 2167ec681f3Smrg default: break; 2177ec681f3Smrg } 2187ec681f3Smrg key->key.vs.size = size; 2197ec681f3Smrg key->size += 2 * size; 2207ec681f3Smrg } 2217ec681f3Smrg state->element_state = &ctx->element_state->hw_state; 2227ec681f3Smrg } else { 2237ec681f3Smrg state->element_state = NULL; 2247ec681f3Smrg ctx->vertex_buffers_dirty = false; 2257ec681f3Smrg } 2267ec681f3Smrg} 2277ec681f3Smrg 2287ec681f3Smrgstatic void 2297ec681f3Smrgzink_delete_vertex_elements_state(struct pipe_context *pctx, 2307ec681f3Smrg void *ves) 2317ec681f3Smrg{ 2327ec681f3Smrg FREE(ves); 2337ec681f3Smrg} 2347ec681f3Smrg 2357ec681f3Smrgstatic VkBlendFactor 2367ec681f3Smrgblend_factor(enum pipe_blendfactor factor) 2377ec681f3Smrg{ 2387ec681f3Smrg switch (factor) { 2397ec681f3Smrg case PIPE_BLENDFACTOR_ONE: return VK_BLEND_FACTOR_ONE; 2407ec681f3Smrg case PIPE_BLENDFACTOR_SRC_COLOR: return VK_BLEND_FACTOR_SRC_COLOR; 2417ec681f3Smrg case PIPE_BLENDFACTOR_SRC_ALPHA: return VK_BLEND_FACTOR_SRC_ALPHA; 2427ec681f3Smrg case PIPE_BLENDFACTOR_DST_ALPHA: return VK_BLEND_FACTOR_DST_ALPHA; 2437ec681f3Smrg case PIPE_BLENDFACTOR_DST_COLOR: return VK_BLEND_FACTOR_DST_COLOR; 2447ec681f3Smrg case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 2457ec681f3Smrg return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE; 2467ec681f3Smrg case PIPE_BLENDFACTOR_CONST_COLOR: return VK_BLEND_FACTOR_CONSTANT_COLOR; 2477ec681f3Smrg case PIPE_BLENDFACTOR_CONST_ALPHA: return VK_BLEND_FACTOR_CONSTANT_ALPHA; 2487ec681f3Smrg case PIPE_BLENDFACTOR_SRC1_COLOR: return VK_BLEND_FACTOR_SRC1_COLOR; 2497ec681f3Smrg case PIPE_BLENDFACTOR_SRC1_ALPHA: return VK_BLEND_FACTOR_SRC1_ALPHA; 2507ec681f3Smrg 2517ec681f3Smrg case PIPE_BLENDFACTOR_ZERO: return VK_BLEND_FACTOR_ZERO; 2527ec681f3Smrg 2537ec681f3Smrg case PIPE_BLENDFACTOR_INV_SRC_COLOR: 2547ec681f3Smrg return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR; 2557ec681f3Smrg case PIPE_BLENDFACTOR_INV_SRC_ALPHA: 2567ec681f3Smrg return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; 2577ec681f3Smrg case PIPE_BLENDFACTOR_INV_DST_ALPHA: 2587ec681f3Smrg return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA; 2597ec681f3Smrg case PIPE_BLENDFACTOR_INV_DST_COLOR: 2607ec681f3Smrg return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR; 2617ec681f3Smrg 2627ec681f3Smrg case PIPE_BLENDFACTOR_INV_CONST_COLOR: 2637ec681f3Smrg return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR; 2647ec681f3Smrg case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 2657ec681f3Smrg return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA; 2667ec681f3Smrg case PIPE_BLENDFACTOR_INV_SRC1_COLOR: 2677ec681f3Smrg return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR; 2687ec681f3Smrg case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: 2697ec681f3Smrg return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA; 2707ec681f3Smrg } 2717ec681f3Smrg unreachable("unexpected blend factor"); 2727ec681f3Smrg} 2737ec681f3Smrg 2747ec681f3Smrg 2757ec681f3Smrgstatic bool 2767ec681f3Smrgneed_blend_constants(enum pipe_blendfactor factor) 2777ec681f3Smrg{ 2787ec681f3Smrg switch (factor) { 2797ec681f3Smrg case PIPE_BLENDFACTOR_CONST_COLOR: 2807ec681f3Smrg case PIPE_BLENDFACTOR_CONST_ALPHA: 2817ec681f3Smrg case PIPE_BLENDFACTOR_INV_CONST_COLOR: 2827ec681f3Smrg case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 2837ec681f3Smrg return true; 2847ec681f3Smrg 2857ec681f3Smrg default: 2867ec681f3Smrg return false; 2877ec681f3Smrg } 2887ec681f3Smrg} 2897ec681f3Smrg 2907ec681f3Smrgstatic VkBlendOp 2917ec681f3Smrgblend_op(enum pipe_blend_func func) 2927ec681f3Smrg{ 2937ec681f3Smrg switch (func) { 2947ec681f3Smrg case PIPE_BLEND_ADD: return VK_BLEND_OP_ADD; 2957ec681f3Smrg case PIPE_BLEND_SUBTRACT: return VK_BLEND_OP_SUBTRACT; 2967ec681f3Smrg case PIPE_BLEND_REVERSE_SUBTRACT: return VK_BLEND_OP_REVERSE_SUBTRACT; 2977ec681f3Smrg case PIPE_BLEND_MIN: return VK_BLEND_OP_MIN; 2987ec681f3Smrg case PIPE_BLEND_MAX: return VK_BLEND_OP_MAX; 2997ec681f3Smrg } 3007ec681f3Smrg unreachable("unexpected blend function"); 3017ec681f3Smrg} 3027ec681f3Smrg 3037ec681f3Smrgstatic VkLogicOp 3047ec681f3Smrglogic_op(enum pipe_logicop func) 3057ec681f3Smrg{ 3067ec681f3Smrg switch (func) { 3077ec681f3Smrg case PIPE_LOGICOP_CLEAR: return VK_LOGIC_OP_CLEAR; 3087ec681f3Smrg case PIPE_LOGICOP_NOR: return VK_LOGIC_OP_NOR; 3097ec681f3Smrg case PIPE_LOGICOP_AND_INVERTED: return VK_LOGIC_OP_AND_INVERTED; 3107ec681f3Smrg case PIPE_LOGICOP_COPY_INVERTED: return VK_LOGIC_OP_COPY_INVERTED; 3117ec681f3Smrg case PIPE_LOGICOP_AND_REVERSE: return VK_LOGIC_OP_AND_REVERSE; 3127ec681f3Smrg case PIPE_LOGICOP_INVERT: return VK_LOGIC_OP_INVERT; 3137ec681f3Smrg case PIPE_LOGICOP_XOR: return VK_LOGIC_OP_XOR; 3147ec681f3Smrg case PIPE_LOGICOP_NAND: return VK_LOGIC_OP_NAND; 3157ec681f3Smrg case PIPE_LOGICOP_AND: return VK_LOGIC_OP_AND; 3167ec681f3Smrg case PIPE_LOGICOP_EQUIV: return VK_LOGIC_OP_EQUIVALENT; 3177ec681f3Smrg case PIPE_LOGICOP_NOOP: return VK_LOGIC_OP_NO_OP; 3187ec681f3Smrg case PIPE_LOGICOP_OR_INVERTED: return VK_LOGIC_OP_OR_INVERTED; 3197ec681f3Smrg case PIPE_LOGICOP_COPY: return VK_LOGIC_OP_COPY; 3207ec681f3Smrg case PIPE_LOGICOP_OR_REVERSE: return VK_LOGIC_OP_OR_REVERSE; 3217ec681f3Smrg case PIPE_LOGICOP_OR: return VK_LOGIC_OP_OR; 3227ec681f3Smrg case PIPE_LOGICOP_SET: return VK_LOGIC_OP_SET; 3237ec681f3Smrg } 3247ec681f3Smrg unreachable("unexpected logicop function"); 3257ec681f3Smrg} 3267ec681f3Smrg 3277ec681f3Smrg/* from iris */ 3287ec681f3Smrgstatic enum pipe_blendfactor 3297ec681f3Smrgfix_blendfactor(enum pipe_blendfactor f, bool alpha_to_one) 3307ec681f3Smrg{ 3317ec681f3Smrg if (alpha_to_one) { 3327ec681f3Smrg if (f == PIPE_BLENDFACTOR_SRC1_ALPHA) 3337ec681f3Smrg return PIPE_BLENDFACTOR_ONE; 3347ec681f3Smrg 3357ec681f3Smrg if (f == PIPE_BLENDFACTOR_INV_SRC1_ALPHA) 3367ec681f3Smrg return PIPE_BLENDFACTOR_ZERO; 3377ec681f3Smrg } 3387ec681f3Smrg 3397ec681f3Smrg return f; 3407ec681f3Smrg} 3417ec681f3Smrg 3427ec681f3Smrgstatic void * 3437ec681f3Smrgzink_create_blend_state(struct pipe_context *pctx, 3447ec681f3Smrg const struct pipe_blend_state *blend_state) 3457ec681f3Smrg{ 3467ec681f3Smrg struct zink_blend_state *cso = CALLOC_STRUCT(zink_blend_state); 3477ec681f3Smrg if (!cso) 3487ec681f3Smrg return NULL; 3497ec681f3Smrg cso->hash = _mesa_hash_pointer(cso); 3507ec681f3Smrg 3517ec681f3Smrg if (blend_state->logicop_enable) { 3527ec681f3Smrg cso->logicop_enable = VK_TRUE; 3537ec681f3Smrg cso->logicop_func = logic_op(blend_state->logicop_func); 3547ec681f3Smrg } 3557ec681f3Smrg 3567ec681f3Smrg /* TODO: figure out what to do with dither (nothing is probably "OK" for now, 3577ec681f3Smrg * as dithering is undefined in GL 3587ec681f3Smrg */ 3597ec681f3Smrg 3607ec681f3Smrg /* TODO: these are multisampling-state, and should be set there instead of 3617ec681f3Smrg * here, as that's closer tied to the update-frequency 3627ec681f3Smrg */ 3637ec681f3Smrg cso->alpha_to_coverage = blend_state->alpha_to_coverage; 3647ec681f3Smrg cso->alpha_to_one = blend_state->alpha_to_one; 3657ec681f3Smrg 3667ec681f3Smrg cso->need_blend_constants = false; 3677ec681f3Smrg 3687ec681f3Smrg for (int i = 0; i < blend_state->max_rt + 1; ++i) { 3697ec681f3Smrg const struct pipe_rt_blend_state *rt = blend_state->rt; 3707ec681f3Smrg if (blend_state->independent_blend_enable) 3717ec681f3Smrg rt = blend_state->rt + i; 3727ec681f3Smrg 3737ec681f3Smrg VkPipelineColorBlendAttachmentState att = {0}; 3747ec681f3Smrg 3757ec681f3Smrg if (rt->blend_enable) { 3767ec681f3Smrg att.blendEnable = VK_TRUE; 3777ec681f3Smrg att.srcColorBlendFactor = blend_factor(fix_blendfactor(rt->rgb_src_factor, cso->alpha_to_one)); 3787ec681f3Smrg att.dstColorBlendFactor = blend_factor(fix_blendfactor(rt->rgb_dst_factor, cso->alpha_to_one)); 3797ec681f3Smrg att.colorBlendOp = blend_op(rt->rgb_func); 3807ec681f3Smrg att.srcAlphaBlendFactor = blend_factor(fix_blendfactor(rt->alpha_src_factor, cso->alpha_to_one)); 3817ec681f3Smrg att.dstAlphaBlendFactor = blend_factor(fix_blendfactor(rt->alpha_dst_factor, cso->alpha_to_one)); 3827ec681f3Smrg att.alphaBlendOp = blend_op(rt->alpha_func); 3837ec681f3Smrg 3847ec681f3Smrg if (need_blend_constants(rt->rgb_src_factor) || 3857ec681f3Smrg need_blend_constants(rt->rgb_dst_factor) || 3867ec681f3Smrg need_blend_constants(rt->alpha_src_factor) || 3877ec681f3Smrg need_blend_constants(rt->alpha_dst_factor)) 3887ec681f3Smrg cso->need_blend_constants = true; 3897ec681f3Smrg } 3907ec681f3Smrg 3917ec681f3Smrg if (rt->colormask & PIPE_MASK_R) 3927ec681f3Smrg att.colorWriteMask |= VK_COLOR_COMPONENT_R_BIT; 3937ec681f3Smrg if (rt->colormask & PIPE_MASK_G) 3947ec681f3Smrg att.colorWriteMask |= VK_COLOR_COMPONENT_G_BIT; 3957ec681f3Smrg if (rt->colormask & PIPE_MASK_B) 3967ec681f3Smrg att.colorWriteMask |= VK_COLOR_COMPONENT_B_BIT; 3977ec681f3Smrg if (rt->colormask & PIPE_MASK_A) 3987ec681f3Smrg att.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT; 3997ec681f3Smrg 4007ec681f3Smrg cso->attachments[i] = att; 4017ec681f3Smrg } 4027ec681f3Smrg cso->dual_src_blend = util_blend_state_is_dual(blend_state, 0); 4037ec681f3Smrg 4047ec681f3Smrg return cso; 4057ec681f3Smrg} 4067ec681f3Smrg 4077ec681f3Smrgstatic void 4087ec681f3Smrgzink_bind_blend_state(struct pipe_context *pctx, void *cso) 4097ec681f3Smrg{ 4107ec681f3Smrg struct zink_context *ctx = zink_context(pctx); 4117ec681f3Smrg struct zink_gfx_pipeline_state* state = &zink_context(pctx)->gfx_pipeline_state; 4127ec681f3Smrg struct zink_blend_state *blend = cso; 4137ec681f3Smrg 4147ec681f3Smrg if (state->blend_state != cso) { 4157ec681f3Smrg state->blend_state = cso; 4167ec681f3Smrg state->blend_id = blend ? blend->hash : 0; 4177ec681f3Smrg state->dirty = true; 4187ec681f3Smrg bool force_dual_color_blend = zink_screen(pctx->screen)->driconf.dual_color_blend_by_location && 4197ec681f3Smrg blend && blend->dual_src_blend && state->blend_state->attachments[1].blendEnable; 4207ec681f3Smrg if (force_dual_color_blend != zink_get_fs_key(ctx)->force_dual_color_blend) 4217ec681f3Smrg zink_set_fs_key(ctx)->force_dual_color_blend = force_dual_color_blend; 4227ec681f3Smrg ctx->blend_state_changed = true; 4237ec681f3Smrg } 4247ec681f3Smrg} 4257ec681f3Smrg 4267ec681f3Smrgstatic void 4277ec681f3Smrgzink_delete_blend_state(struct pipe_context *pctx, void *blend_state) 4287ec681f3Smrg{ 4297ec681f3Smrg FREE(blend_state); 4307ec681f3Smrg} 4317ec681f3Smrg 4327ec681f3Smrgstatic VkCompareOp 4337ec681f3Smrgcompare_op(enum pipe_compare_func func) 4347ec681f3Smrg{ 4357ec681f3Smrg switch (func) { 4367ec681f3Smrg case PIPE_FUNC_NEVER: return VK_COMPARE_OP_NEVER; 4377ec681f3Smrg case PIPE_FUNC_LESS: return VK_COMPARE_OP_LESS; 4387ec681f3Smrg case PIPE_FUNC_EQUAL: return VK_COMPARE_OP_EQUAL; 4397ec681f3Smrg case PIPE_FUNC_LEQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL; 4407ec681f3Smrg case PIPE_FUNC_GREATER: return VK_COMPARE_OP_GREATER; 4417ec681f3Smrg case PIPE_FUNC_NOTEQUAL: return VK_COMPARE_OP_NOT_EQUAL; 4427ec681f3Smrg case PIPE_FUNC_GEQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL; 4437ec681f3Smrg case PIPE_FUNC_ALWAYS: return VK_COMPARE_OP_ALWAYS; 4447ec681f3Smrg } 4457ec681f3Smrg unreachable("unexpected func"); 4467ec681f3Smrg} 4477ec681f3Smrg 4487ec681f3Smrgstatic VkStencilOp 4497ec681f3Smrgstencil_op(enum pipe_stencil_op op) 4507ec681f3Smrg{ 4517ec681f3Smrg switch (op) { 4527ec681f3Smrg case PIPE_STENCIL_OP_KEEP: return VK_STENCIL_OP_KEEP; 4537ec681f3Smrg case PIPE_STENCIL_OP_ZERO: return VK_STENCIL_OP_ZERO; 4547ec681f3Smrg case PIPE_STENCIL_OP_REPLACE: return VK_STENCIL_OP_REPLACE; 4557ec681f3Smrg case PIPE_STENCIL_OP_INCR: return VK_STENCIL_OP_INCREMENT_AND_CLAMP; 4567ec681f3Smrg case PIPE_STENCIL_OP_DECR: return VK_STENCIL_OP_DECREMENT_AND_CLAMP; 4577ec681f3Smrg case PIPE_STENCIL_OP_INCR_WRAP: return VK_STENCIL_OP_INCREMENT_AND_WRAP; 4587ec681f3Smrg case PIPE_STENCIL_OP_DECR_WRAP: return VK_STENCIL_OP_DECREMENT_AND_WRAP; 4597ec681f3Smrg case PIPE_STENCIL_OP_INVERT: return VK_STENCIL_OP_INVERT; 4607ec681f3Smrg } 4617ec681f3Smrg unreachable("unexpected op"); 4627ec681f3Smrg} 4637ec681f3Smrg 4647ec681f3Smrgstatic VkStencilOpState 4657ec681f3Smrgstencil_op_state(const struct pipe_stencil_state *src) 4667ec681f3Smrg{ 4677ec681f3Smrg VkStencilOpState ret; 4687ec681f3Smrg ret.failOp = stencil_op(src->fail_op); 4697ec681f3Smrg ret.passOp = stencil_op(src->zpass_op); 4707ec681f3Smrg ret.depthFailOp = stencil_op(src->zfail_op); 4717ec681f3Smrg ret.compareOp = compare_op(src->func); 4727ec681f3Smrg ret.compareMask = src->valuemask; 4737ec681f3Smrg ret.writeMask = src->writemask; 4747ec681f3Smrg ret.reference = 0; // not used: we'll use a dynamic state for this 4757ec681f3Smrg return ret; 4767ec681f3Smrg} 4777ec681f3Smrg 4787ec681f3Smrgstatic void * 4797ec681f3Smrgzink_create_depth_stencil_alpha_state(struct pipe_context *pctx, 4807ec681f3Smrg const struct pipe_depth_stencil_alpha_state *depth_stencil_alpha) 4817ec681f3Smrg{ 4827ec681f3Smrg struct zink_depth_stencil_alpha_state *cso = CALLOC_STRUCT(zink_depth_stencil_alpha_state); 4837ec681f3Smrg if (!cso) 4847ec681f3Smrg return NULL; 4857ec681f3Smrg 4867ec681f3Smrg cso->base = *depth_stencil_alpha; 4877ec681f3Smrg 4887ec681f3Smrg if (depth_stencil_alpha->depth_enabled) { 4897ec681f3Smrg cso->hw_state.depth_test = VK_TRUE; 4907ec681f3Smrg cso->hw_state.depth_compare_op = compare_op(depth_stencil_alpha->depth_func); 4917ec681f3Smrg } 4927ec681f3Smrg 4937ec681f3Smrg if (depth_stencil_alpha->depth_bounds_test) { 4947ec681f3Smrg cso->hw_state.depth_bounds_test = VK_TRUE; 4957ec681f3Smrg cso->hw_state.min_depth_bounds = depth_stencil_alpha->depth_bounds_min; 4967ec681f3Smrg cso->hw_state.max_depth_bounds = depth_stencil_alpha->depth_bounds_max; 4977ec681f3Smrg } 4987ec681f3Smrg 4997ec681f3Smrg if (depth_stencil_alpha->stencil[0].enabled) { 5007ec681f3Smrg cso->hw_state.stencil_test = VK_TRUE; 5017ec681f3Smrg cso->hw_state.stencil_front = stencil_op_state(depth_stencil_alpha->stencil); 5027ec681f3Smrg } 5037ec681f3Smrg 5047ec681f3Smrg if (depth_stencil_alpha->stencil[1].enabled) 5057ec681f3Smrg cso->hw_state.stencil_back = stencil_op_state(depth_stencil_alpha->stencil + 1); 5067ec681f3Smrg else 5077ec681f3Smrg cso->hw_state.stencil_back = cso->hw_state.stencil_front; 5087ec681f3Smrg 5097ec681f3Smrg cso->hw_state.depth_write = depth_stencil_alpha->depth_writemask; 5107ec681f3Smrg 5117ec681f3Smrg return cso; 5127ec681f3Smrg} 5137ec681f3Smrg 5147ec681f3Smrgstatic void 5157ec681f3Smrgzink_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *cso) 5167ec681f3Smrg{ 5177ec681f3Smrg struct zink_context *ctx = zink_context(pctx); 5187ec681f3Smrg 5197ec681f3Smrg bool prev_zwrite = ctx->dsa_state ? ctx->dsa_state->hw_state.depth_write : false; 5207ec681f3Smrg ctx->dsa_state = cso; 5217ec681f3Smrg 5227ec681f3Smrg if (cso) { 5237ec681f3Smrg struct zink_gfx_pipeline_state *state = &ctx->gfx_pipeline_state; 5247ec681f3Smrg if (state->dyn_state1.depth_stencil_alpha_state != &ctx->dsa_state->hw_state) { 5257ec681f3Smrg state->dyn_state1.depth_stencil_alpha_state = &ctx->dsa_state->hw_state; 5267ec681f3Smrg state->dirty |= !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state; 5277ec681f3Smrg ctx->dsa_state_changed = true; 5287ec681f3Smrg } 5297ec681f3Smrg } 5307ec681f3Smrg if (prev_zwrite != (ctx->dsa_state ? ctx->dsa_state->hw_state.depth_write : false)) { 5317ec681f3Smrg ctx->rp_changed = true; 5327ec681f3Smrg zink_batch_no_rp(ctx); 5337ec681f3Smrg } 5347ec681f3Smrg} 5357ec681f3Smrg 5367ec681f3Smrgstatic void 5377ec681f3Smrgzink_delete_depth_stencil_alpha_state(struct pipe_context *pctx, 5387ec681f3Smrg void *depth_stencil_alpha) 5397ec681f3Smrg{ 5407ec681f3Smrg FREE(depth_stencil_alpha); 5417ec681f3Smrg} 5427ec681f3Smrg 5437ec681f3Smrgstatic float 5447ec681f3Smrground_to_granularity(float value, float granularity) 5457ec681f3Smrg{ 5467ec681f3Smrg return roundf(value / granularity) * granularity; 5477ec681f3Smrg} 5487ec681f3Smrg 5497ec681f3Smrgstatic float 5507ec681f3Smrgline_width(float width, float granularity, const float range[2]) 5517ec681f3Smrg{ 5527ec681f3Smrg assert(granularity >= 0); 5537ec681f3Smrg assert(range[0] <= range[1]); 5547ec681f3Smrg 5557ec681f3Smrg if (granularity > 0) 5567ec681f3Smrg width = round_to_granularity(width, granularity); 5577ec681f3Smrg 5587ec681f3Smrg return CLAMP(width, range[0], range[1]); 5597ec681f3Smrg} 5607ec681f3Smrg 5617ec681f3Smrg#define warn_line_feature(feat) \ 5627ec681f3Smrg do { \ 5637ec681f3Smrg static bool warned = false; \ 5647ec681f3Smrg if (!warned) { \ 5657ec681f3Smrg fprintf(stderr, "WARNING: Incorrect rendering will happen, " \ 5667ec681f3Smrg "because the Vulkan device doesn't support " \ 5677ec681f3Smrg "the %s feature of " \ 5687ec681f3Smrg "VK_EXT_line_rasterization\n", feat); \ 5697ec681f3Smrg warned = true; \ 5707ec681f3Smrg } \ 5717ec681f3Smrg } while (0) 5727ec681f3Smrg 5737ec681f3Smrgstatic void * 5747ec681f3Smrgzink_create_rasterizer_state(struct pipe_context *pctx, 5757ec681f3Smrg const struct pipe_rasterizer_state *rs_state) 5767ec681f3Smrg{ 5777ec681f3Smrg struct zink_screen *screen = zink_screen(pctx->screen); 5787ec681f3Smrg 5797ec681f3Smrg struct zink_rasterizer_state *state = CALLOC_STRUCT(zink_rasterizer_state); 5807ec681f3Smrg if (!state) 5817ec681f3Smrg return NULL; 5827ec681f3Smrg 5837ec681f3Smrg state->base = *rs_state; 5847ec681f3Smrg state->base.line_stipple_factor++; 5857ec681f3Smrg state->hw_state.line_stipple_enable = rs_state->line_stipple_enable; 5867ec681f3Smrg 5877ec681f3Smrg assert(rs_state->depth_clip_far == rs_state->depth_clip_near); 5887ec681f3Smrg state->hw_state.depth_clamp = rs_state->depth_clip_near == 0; 5897ec681f3Smrg state->hw_state.rasterizer_discard = rs_state->rasterizer_discard; 5907ec681f3Smrg state->hw_state.force_persample_interp = rs_state->force_persample_interp; 5917ec681f3Smrg state->hw_state.pv_last = !rs_state->flatshade_first; 5927ec681f3Smrg state->hw_state.clip_halfz = rs_state->clip_halfz; 5937ec681f3Smrg 5947ec681f3Smrg assert(rs_state->fill_front <= PIPE_POLYGON_MODE_POINT); 5957ec681f3Smrg if (rs_state->fill_back != rs_state->fill_front) 5967ec681f3Smrg debug_printf("BUG: vulkan doesn't support different front and back fill modes\n"); 5977ec681f3Smrg state->hw_state.polygon_mode = rs_state->fill_front; // same values 5987ec681f3Smrg state->hw_state.cull_mode = rs_state->cull_face; // same bits 5997ec681f3Smrg 6007ec681f3Smrg state->front_face = rs_state->front_ccw ? 6017ec681f3Smrg VK_FRONT_FACE_COUNTER_CLOCKWISE : 6027ec681f3Smrg VK_FRONT_FACE_CLOCKWISE; 6037ec681f3Smrg 6047ec681f3Smrg VkPhysicalDeviceLineRasterizationFeaturesEXT *line_feats = 6057ec681f3Smrg &screen->info.line_rast_feats; 6067ec681f3Smrg state->hw_state.line_mode = 6077ec681f3Smrg VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT; 6087ec681f3Smrg 6097ec681f3Smrg if (rs_state->line_stipple_enable) { 6107ec681f3Smrg if (screen->info.have_EXT_line_rasterization) { 6117ec681f3Smrg if (rs_state->line_rectangular) { 6127ec681f3Smrg if (rs_state->line_smooth) { 6137ec681f3Smrg if (line_feats->stippledSmoothLines) 6147ec681f3Smrg state->hw_state.line_mode = 6157ec681f3Smrg VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT; 6167ec681f3Smrg else 6177ec681f3Smrg warn_line_feature("stippledSmoothLines"); 6187ec681f3Smrg } else if (line_feats->stippledRectangularLines) 6197ec681f3Smrg state->hw_state.line_mode = 6207ec681f3Smrg VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT; 6217ec681f3Smrg else 6227ec681f3Smrg warn_line_feature("stippledRectangularLines"); 6237ec681f3Smrg } else if (line_feats->stippledBresenhamLines) 6247ec681f3Smrg state->hw_state.line_mode = 6257ec681f3Smrg VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT; 6267ec681f3Smrg else { 6277ec681f3Smrg warn_line_feature("stippledBresenhamLines"); 6287ec681f3Smrg 6297ec681f3Smrg /* no suitable mode that supports line stippling */ 6307ec681f3Smrg state->base.line_stipple_factor = 0; 6317ec681f3Smrg state->base.line_stipple_pattern = UINT16_MAX; 6327ec681f3Smrg } 6337ec681f3Smrg } 6347ec681f3Smrg } else { 6357ec681f3Smrg if (screen->info.have_EXT_line_rasterization) { 6367ec681f3Smrg if (rs_state->line_rectangular) { 6377ec681f3Smrg if (rs_state->line_smooth) { 6387ec681f3Smrg if (line_feats->smoothLines) 6397ec681f3Smrg state->hw_state.line_mode = 6407ec681f3Smrg VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT; 6417ec681f3Smrg else 6427ec681f3Smrg warn_line_feature("smoothLines"); 6437ec681f3Smrg } else if (line_feats->rectangularLines) 6447ec681f3Smrg state->hw_state.line_mode = 6457ec681f3Smrg VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT; 6467ec681f3Smrg else 6477ec681f3Smrg warn_line_feature("rectangularLines"); 6487ec681f3Smrg } else if (line_feats->bresenhamLines) 6497ec681f3Smrg state->hw_state.line_mode = 6507ec681f3Smrg VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT; 6517ec681f3Smrg else 6527ec681f3Smrg warn_line_feature("bresenhamLines"); 6537ec681f3Smrg } 6547ec681f3Smrg state->base.line_stipple_factor = 0; 6557ec681f3Smrg state->base.line_stipple_pattern = UINT16_MAX; 6567ec681f3Smrg } 6577ec681f3Smrg 6587ec681f3Smrg state->offset_point = rs_state->offset_point; 6597ec681f3Smrg state->offset_line = rs_state->offset_line; 6607ec681f3Smrg state->offset_tri = rs_state->offset_tri; 6617ec681f3Smrg state->offset_units = rs_state->offset_units; 6627ec681f3Smrg state->offset_clamp = rs_state->offset_clamp; 6637ec681f3Smrg state->offset_scale = rs_state->offset_scale; 6647ec681f3Smrg 6657ec681f3Smrg state->line_width = line_width(rs_state->line_width, 6667ec681f3Smrg screen->info.props.limits.lineWidthGranularity, 6677ec681f3Smrg screen->info.props.limits.lineWidthRange); 6687ec681f3Smrg 6697ec681f3Smrg return state; 6707ec681f3Smrg} 6717ec681f3Smrg 6727ec681f3Smrgstatic void 6737ec681f3Smrgzink_bind_rasterizer_state(struct pipe_context *pctx, void *cso) 6747ec681f3Smrg{ 6757ec681f3Smrg struct zink_context *ctx = zink_context(pctx); 6767ec681f3Smrg struct zink_screen *screen = zink_screen(pctx->screen); 6777ec681f3Smrg bool point_quad_rasterization = ctx->rast_state ? ctx->rast_state->base.point_quad_rasterization : false; 6787ec681f3Smrg bool scissor = ctx->rast_state ? ctx->rast_state->base.scissor : false; 6797ec681f3Smrg bool pv_last = ctx->rast_state ? ctx->rast_state->hw_state.pv_last : false; 6807ec681f3Smrg ctx->rast_state = cso; 6817ec681f3Smrg 6827ec681f3Smrg if (ctx->rast_state) { 6837ec681f3Smrg if (screen->info.have_EXT_provoking_vertex && 6847ec681f3Smrg pv_last != ctx->rast_state->hw_state.pv_last && 6857ec681f3Smrg /* without this prop, change in pv mode requires new rp */ 6867ec681f3Smrg !screen->info.pv_props.provokingVertexModePerPipeline) 6877ec681f3Smrg zink_batch_no_rp(ctx); 6887ec681f3Smrg uint32_t rast_bits = 0; 6897ec681f3Smrg memcpy(&rast_bits, &ctx->rast_state->hw_state, sizeof(struct zink_rasterizer_hw_state)); 6907ec681f3Smrg ctx->gfx_pipeline_state.rast_state = rast_bits & BITFIELD_MASK(ZINK_RAST_HW_STATE_SIZE); 6917ec681f3Smrg 6927ec681f3Smrg ctx->gfx_pipeline_state.dirty = true; 6937ec681f3Smrg ctx->rast_state_changed = true; 6947ec681f3Smrg 6957ec681f3Smrg if (zink_get_last_vertex_key(ctx)->clip_halfz != ctx->rast_state->base.clip_halfz) { 6967ec681f3Smrg zink_set_last_vertex_key(ctx)->clip_halfz = ctx->rast_state->base.clip_halfz; 6977ec681f3Smrg ctx->vp_state_changed = true; 6987ec681f3Smrg } 6997ec681f3Smrg 7007ec681f3Smrg if (ctx->gfx_pipeline_state.dyn_state1.front_face != ctx->rast_state->front_face) { 7017ec681f3Smrg ctx->gfx_pipeline_state.dyn_state1.front_face = ctx->rast_state->front_face; 7027ec681f3Smrg ctx->gfx_pipeline_state.dirty |= !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state; 7037ec681f3Smrg } 7047ec681f3Smrg if (ctx->rast_state->base.point_quad_rasterization != point_quad_rasterization) 7057ec681f3Smrg zink_set_fs_point_coord_key(ctx); 7067ec681f3Smrg if (ctx->rast_state->base.scissor != scissor) 7077ec681f3Smrg ctx->scissor_changed = true; 7087ec681f3Smrg } 7097ec681f3Smrg} 7107ec681f3Smrg 7117ec681f3Smrgstatic void 7127ec681f3Smrgzink_delete_rasterizer_state(struct pipe_context *pctx, void *rs_state) 7137ec681f3Smrg{ 7147ec681f3Smrg FREE(rs_state); 7157ec681f3Smrg} 7167ec681f3Smrg 7177ec681f3Smrgvoid 7187ec681f3Smrgzink_context_state_init(struct pipe_context *pctx) 7197ec681f3Smrg{ 7207ec681f3Smrg pctx->create_vertex_elements_state = zink_create_vertex_elements_state; 7217ec681f3Smrg pctx->bind_vertex_elements_state = zink_bind_vertex_elements_state; 7227ec681f3Smrg pctx->delete_vertex_elements_state = zink_delete_vertex_elements_state; 7237ec681f3Smrg 7247ec681f3Smrg pctx->create_blend_state = zink_create_blend_state; 7257ec681f3Smrg pctx->bind_blend_state = zink_bind_blend_state; 7267ec681f3Smrg pctx->delete_blend_state = zink_delete_blend_state; 7277ec681f3Smrg 7287ec681f3Smrg pctx->create_depth_stencil_alpha_state = zink_create_depth_stencil_alpha_state; 7297ec681f3Smrg pctx->bind_depth_stencil_alpha_state = zink_bind_depth_stencil_alpha_state; 7307ec681f3Smrg pctx->delete_depth_stencil_alpha_state = zink_delete_depth_stencil_alpha_state; 7317ec681f3Smrg 7327ec681f3Smrg pctx->create_rasterizer_state = zink_create_rasterizer_state; 7337ec681f3Smrg pctx->bind_rasterizer_state = zink_bind_rasterizer_state; 7347ec681f3Smrg pctx->delete_rasterizer_state = zink_delete_rasterizer_state; 7357ec681f3Smrg} 736