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 "compiler/spirv/spirv.h" 257ec681f3Smrg 267ec681f3Smrg#include "zink_pipeline.h" 277ec681f3Smrg 287ec681f3Smrg#include "zink_compiler.h" 297ec681f3Smrg#include "zink_context.h" 307ec681f3Smrg#include "zink_program.h" 317ec681f3Smrg#include "zink_render_pass.h" 327ec681f3Smrg#include "zink_screen.h" 337ec681f3Smrg#include "zink_state.h" 347ec681f3Smrg 357ec681f3Smrg#include "util/u_debug.h" 367ec681f3Smrg#include "util/u_prim.h" 377ec681f3Smrg 387ec681f3Smrgstatic VkBlendFactor 397ec681f3Smrgclamp_void_blend_factor(VkBlendFactor f) 407ec681f3Smrg{ 417ec681f3Smrg if (f == VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA) 427ec681f3Smrg return VK_BLEND_FACTOR_ZERO; 437ec681f3Smrg if (f == VK_BLEND_FACTOR_DST_ALPHA) 447ec681f3Smrg return VK_BLEND_FACTOR_ONE; 457ec681f3Smrg return f; 467ec681f3Smrg} 477ec681f3Smrg 487ec681f3SmrgVkPipeline 497ec681f3Smrgzink_create_gfx_pipeline(struct zink_screen *screen, 507ec681f3Smrg struct zink_gfx_program *prog, 517ec681f3Smrg struct zink_gfx_pipeline_state *state, 527ec681f3Smrg VkPrimitiveTopology primitive_topology) 537ec681f3Smrg{ 547ec681f3Smrg struct zink_rasterizer_hw_state *hw_rast_state = (void*)state; 557ec681f3Smrg VkPipelineVertexInputStateCreateInfo vertex_input_state; 567ec681f3Smrg if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->element_state->num_attribs) { 577ec681f3Smrg memset(&vertex_input_state, 0, sizeof(vertex_input_state)); 587ec681f3Smrg vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 597ec681f3Smrg vertex_input_state.pVertexBindingDescriptions = state->element_state->b.bindings; 607ec681f3Smrg vertex_input_state.vertexBindingDescriptionCount = state->element_state->num_bindings; 617ec681f3Smrg vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs; 627ec681f3Smrg vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs; 637ec681f3Smrg } 647ec681f3Smrg 657ec681f3Smrg VkPipelineVertexInputDivisorStateCreateInfoEXT vdiv_state; 667ec681f3Smrg if (!screen->info.have_EXT_vertex_input_dynamic_state && state->element_state->b.divisors_present) { 677ec681f3Smrg memset(&vdiv_state, 0, sizeof(vdiv_state)); 687ec681f3Smrg vertex_input_state.pNext = &vdiv_state; 697ec681f3Smrg vdiv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT; 707ec681f3Smrg vdiv_state.vertexBindingDivisorCount = state->element_state->b.divisors_present; 717ec681f3Smrg vdiv_state.pVertexBindingDivisors = state->element_state->b.divisors; 727ec681f3Smrg } 737ec681f3Smrg 747ec681f3Smrg VkPipelineInputAssemblyStateCreateInfo primitive_state = {0}; 757ec681f3Smrg primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 767ec681f3Smrg primitive_state.topology = primitive_topology; 777ec681f3Smrg if (!screen->info.have_EXT_extended_dynamic_state2) { 787ec681f3Smrg switch (primitive_topology) { 797ec681f3Smrg case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: 807ec681f3Smrg case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: 817ec681f3Smrg case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: 827ec681f3Smrg case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: 837ec681f3Smrg case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: 847ec681f3Smrg case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: 857ec681f3Smrg if (state->primitive_restart) 867ec681f3Smrg debug_printf("restart_index set with unsupported primitive topology %u\n", primitive_topology); 877ec681f3Smrg primitive_state.primitiveRestartEnable = VK_FALSE; 887ec681f3Smrg break; 897ec681f3Smrg default: 907ec681f3Smrg primitive_state.primitiveRestartEnable = state->primitive_restart ? VK_TRUE : VK_FALSE; 917ec681f3Smrg } 927ec681f3Smrg } 937ec681f3Smrg 947ec681f3Smrg VkPipelineColorBlendAttachmentState blend_att[PIPE_MAX_COLOR_BUFS]; 957ec681f3Smrg VkPipelineColorBlendStateCreateInfo blend_state = {0}; 967ec681f3Smrg blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 977ec681f3Smrg if (state->blend_state) { 987ec681f3Smrg unsigned num_attachments = state->render_pass->state.num_rts; 997ec681f3Smrg if (state->render_pass->state.have_zsbuf) 1007ec681f3Smrg num_attachments--; 1017ec681f3Smrg if (state->void_alpha_attachments) { 1027ec681f3Smrg for (unsigned i = 0; i < num_attachments; i++) { 1037ec681f3Smrg blend_att[i] = state->blend_state->attachments[i]; 1047ec681f3Smrg if (state->void_alpha_attachments & BITFIELD_BIT(i)) { 1057ec681f3Smrg blend_att[i].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; 1067ec681f3Smrg blend_att[i].srcColorBlendFactor = clamp_void_blend_factor(blend_att[i].srcColorBlendFactor); 1077ec681f3Smrg blend_att[i].dstColorBlendFactor = clamp_void_blend_factor(blend_att[i].dstColorBlendFactor); 1087ec681f3Smrg } 1097ec681f3Smrg } 1107ec681f3Smrg blend_state.pAttachments = blend_att; 1117ec681f3Smrg } else 1127ec681f3Smrg blend_state.pAttachments = state->blend_state->attachments; 1137ec681f3Smrg blend_state.attachmentCount = num_attachments; 1147ec681f3Smrg blend_state.logicOpEnable = state->blend_state->logicop_enable; 1157ec681f3Smrg blend_state.logicOp = state->blend_state->logicop_func; 1167ec681f3Smrg } 1177ec681f3Smrg 1187ec681f3Smrg VkPipelineMultisampleStateCreateInfo ms_state = {0}; 1197ec681f3Smrg ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 1207ec681f3Smrg ms_state.rasterizationSamples = state->rast_samples + 1; 1217ec681f3Smrg if (state->blend_state) { 1227ec681f3Smrg ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage; 1237ec681f3Smrg if (state->blend_state->alpha_to_one && !screen->info.feats.features.alphaToOne) 1247ec681f3Smrg warn_missing_feature("alphaToOne"); 1257ec681f3Smrg ms_state.alphaToOneEnable = state->blend_state->alpha_to_one; 1267ec681f3Smrg } 1277ec681f3Smrg /* "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1." 1287ec681f3Smrg * - Chapter 27. Rasterization 1297ec681f3Smrg * 1307ec681f3Smrg * thus it never makes sense to leave this as NULL since gallium will provide correct 1317ec681f3Smrg * data here as long as sample_mask is initialized on context creation 1327ec681f3Smrg */ 1337ec681f3Smrg ms_state.pSampleMask = &state->sample_mask; 1347ec681f3Smrg if (hw_rast_state->force_persample_interp) { 1357ec681f3Smrg ms_state.sampleShadingEnable = VK_TRUE; 1367ec681f3Smrg ms_state.minSampleShading = 1.0; 1377ec681f3Smrg } 1387ec681f3Smrg 1397ec681f3Smrg VkPipelineViewportStateCreateInfo viewport_state = {0}; 1407ec681f3Smrg viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 1417ec681f3Smrg viewport_state.viewportCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports; 1427ec681f3Smrg viewport_state.pViewports = NULL; 1437ec681f3Smrg viewport_state.scissorCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports; 1447ec681f3Smrg viewport_state.pScissors = NULL; 1457ec681f3Smrg 1467ec681f3Smrg VkPipelineRasterizationStateCreateInfo rast_state = {0}; 1477ec681f3Smrg rast_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 1487ec681f3Smrg 1497ec681f3Smrg rast_state.depthClampEnable = hw_rast_state->depth_clamp; 1507ec681f3Smrg rast_state.rasterizerDiscardEnable = hw_rast_state->rasterizer_discard; 1517ec681f3Smrg rast_state.polygonMode = hw_rast_state->polygon_mode; 1527ec681f3Smrg rast_state.cullMode = hw_rast_state->cull_mode; 1537ec681f3Smrg rast_state.frontFace = state->dyn_state1.front_face; 1547ec681f3Smrg 1557ec681f3Smrg rast_state.depthBiasEnable = VK_TRUE; 1567ec681f3Smrg rast_state.depthBiasConstantFactor = 0.0; 1577ec681f3Smrg rast_state.depthBiasClamp = 0.0; 1587ec681f3Smrg rast_state.depthBiasSlopeFactor = 0.0; 1597ec681f3Smrg rast_state.lineWidth = 1.0f; 1607ec681f3Smrg 1617ec681f3Smrg VkPipelineRasterizationProvokingVertexStateCreateInfoEXT pv_state; 1627ec681f3Smrg pv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT; 1637ec681f3Smrg pv_state.provokingVertexMode = hw_rast_state->pv_last ? 1647ec681f3Smrg VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT : 1657ec681f3Smrg VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT; 1667ec681f3Smrg if (screen->info.have_EXT_provoking_vertex && hw_rast_state->pv_last) { 1677ec681f3Smrg pv_state.pNext = rast_state.pNext; 1687ec681f3Smrg rast_state.pNext = &pv_state; 1697ec681f3Smrg } 1707ec681f3Smrg 1717ec681f3Smrg VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {0}; 1727ec681f3Smrg depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; 1737ec681f3Smrg depth_stencil_state.depthTestEnable = state->dyn_state1.depth_stencil_alpha_state->depth_test; 1747ec681f3Smrg depth_stencil_state.depthCompareOp = state->dyn_state1.depth_stencil_alpha_state->depth_compare_op; 1757ec681f3Smrg depth_stencil_state.depthBoundsTestEnable = state->dyn_state1.depth_stencil_alpha_state->depth_bounds_test; 1767ec681f3Smrg depth_stencil_state.minDepthBounds = state->dyn_state1.depth_stencil_alpha_state->min_depth_bounds; 1777ec681f3Smrg depth_stencil_state.maxDepthBounds = state->dyn_state1.depth_stencil_alpha_state->max_depth_bounds; 1787ec681f3Smrg depth_stencil_state.stencilTestEnable = state->dyn_state1.depth_stencil_alpha_state->stencil_test; 1797ec681f3Smrg depth_stencil_state.front = state->dyn_state1.depth_stencil_alpha_state->stencil_front; 1807ec681f3Smrg depth_stencil_state.back = state->dyn_state1.depth_stencil_alpha_state->stencil_back; 1817ec681f3Smrg depth_stencil_state.depthWriteEnable = state->dyn_state1.depth_stencil_alpha_state->depth_write; 1827ec681f3Smrg 1837ec681f3Smrg VkDynamicState dynamicStateEnables[30] = { 1847ec681f3Smrg VK_DYNAMIC_STATE_LINE_WIDTH, 1857ec681f3Smrg VK_DYNAMIC_STATE_DEPTH_BIAS, 1867ec681f3Smrg VK_DYNAMIC_STATE_BLEND_CONSTANTS, 1877ec681f3Smrg VK_DYNAMIC_STATE_STENCIL_REFERENCE, 1887ec681f3Smrg }; 1897ec681f3Smrg unsigned state_count = 4; 1907ec681f3Smrg if (screen->info.have_EXT_extended_dynamic_state) { 1917ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT; 1927ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT; 1937ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS; 1947ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT; 1957ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT; 1967ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT; 1977ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT; 1987ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK; 1997ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK; 2007ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_OP_EXT; 2017ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT; 2027ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_FRONT_FACE_EXT; 2037ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT; 2047ec681f3Smrg if (state->sample_locations_enabled) 2057ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT; 2067ec681f3Smrg } else { 2077ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT; 2087ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR; 2097ec681f3Smrg } 2107ec681f3Smrg if (state->element_state->num_attribs) { 2117ec681f3Smrg if (screen->info.have_EXT_vertex_input_dynamic_state) 2127ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT; 2137ec681f3Smrg else if (screen->info.have_EXT_extended_dynamic_state) 2147ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT; 2157ec681f3Smrg } 2167ec681f3Smrg if (screen->info.have_EXT_extended_dynamic_state2) 2177ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT; 2187ec681f3Smrg 2197ec681f3Smrg VkPipelineRasterizationLineStateCreateInfoEXT rast_line_state; 2207ec681f3Smrg if (screen->info.have_EXT_line_rasterization) { 2217ec681f3Smrg rast_line_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT; 2227ec681f3Smrg rast_line_state.pNext = rast_state.pNext; 2237ec681f3Smrg rast_line_state.stippledLineEnable = VK_FALSE; 2247ec681f3Smrg rast_line_state.lineRasterizationMode = hw_rast_state->line_mode; 2257ec681f3Smrg 2267ec681f3Smrg if (hw_rast_state->line_stipple_enable) { 2277ec681f3Smrg dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT; 2287ec681f3Smrg rast_line_state.stippledLineEnable = VK_TRUE; 2297ec681f3Smrg } 2307ec681f3Smrg rast_state.pNext = &rast_line_state; 2317ec681f3Smrg } 2327ec681f3Smrg 2337ec681f3Smrg VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0}; 2347ec681f3Smrg pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 2357ec681f3Smrg pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables; 2367ec681f3Smrg pipelineDynamicStateCreateInfo.dynamicStateCount = state_count; 2377ec681f3Smrg 2387ec681f3Smrg VkGraphicsPipelineCreateInfo pci = {0}; 2397ec681f3Smrg pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 2407ec681f3Smrg pci.layout = prog->base.layout; 2417ec681f3Smrg pci.renderPass = state->render_pass->render_pass; 2427ec681f3Smrg if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->element_state->num_attribs) 2437ec681f3Smrg pci.pVertexInputState = &vertex_input_state; 2447ec681f3Smrg pci.pInputAssemblyState = &primitive_state; 2457ec681f3Smrg pci.pRasterizationState = &rast_state; 2467ec681f3Smrg pci.pColorBlendState = &blend_state; 2477ec681f3Smrg pci.pMultisampleState = &ms_state; 2487ec681f3Smrg pci.pViewportState = &viewport_state; 2497ec681f3Smrg pci.pDepthStencilState = &depth_stencil_state; 2507ec681f3Smrg pci.pDynamicState = &pipelineDynamicStateCreateInfo; 2517ec681f3Smrg 2527ec681f3Smrg VkPipelineTessellationStateCreateInfo tci = {0}; 2537ec681f3Smrg VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0}; 2547ec681f3Smrg if (prog->shaders[PIPE_SHADER_TESS_CTRL] && prog->shaders[PIPE_SHADER_TESS_EVAL]) { 2557ec681f3Smrg tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; 2567ec681f3Smrg tci.patchControlPoints = state->vertices_per_patch + 1; 2577ec681f3Smrg pci.pTessellationState = &tci; 2587ec681f3Smrg tci.pNext = &tdci; 2597ec681f3Smrg tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO; 2607ec681f3Smrg tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT; 2617ec681f3Smrg } 2627ec681f3Smrg 2637ec681f3Smrg VkPipelineShaderStageCreateInfo shader_stages[ZINK_SHADER_COUNT]; 2647ec681f3Smrg uint32_t num_stages = 0; 2657ec681f3Smrg for (int i = 0; i < ZINK_SHADER_COUNT; ++i) { 2667ec681f3Smrg if (!prog->modules[i]) 2677ec681f3Smrg continue; 2687ec681f3Smrg 2697ec681f3Smrg VkPipelineShaderStageCreateInfo stage = {0}; 2707ec681f3Smrg stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 2717ec681f3Smrg stage.stage = zink_shader_stage(i); 2727ec681f3Smrg stage.module = prog->modules[i]->shader; 2737ec681f3Smrg stage.pName = "main"; 2747ec681f3Smrg shader_stages[num_stages++] = stage; 2757ec681f3Smrg } 2767ec681f3Smrg assert(num_stages > 0); 2777ec681f3Smrg 2787ec681f3Smrg pci.pStages = shader_stages; 2797ec681f3Smrg pci.stageCount = num_stages; 2807ec681f3Smrg 2817ec681f3Smrg VkPipeline pipeline; 2827ec681f3Smrg if (vkCreateGraphicsPipelines(screen->dev, prog->base.pipeline_cache, 1, &pci, 2837ec681f3Smrg NULL, &pipeline) != VK_SUCCESS) { 2847ec681f3Smrg debug_printf("vkCreateGraphicsPipelines failed\n"); 2857ec681f3Smrg return VK_NULL_HANDLE; 2867ec681f3Smrg } 2877ec681f3Smrg 2887ec681f3Smrg return pipeline; 2897ec681f3Smrg} 2907ec681f3Smrg 2917ec681f3SmrgVkPipeline 2927ec681f3Smrgzink_create_compute_pipeline(struct zink_screen *screen, struct zink_compute_program *comp, struct zink_compute_pipeline_state *state) 2937ec681f3Smrg{ 2947ec681f3Smrg VkComputePipelineCreateInfo pci = {0}; 2957ec681f3Smrg pci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; 2967ec681f3Smrg pci.layout = comp->base.layout; 2977ec681f3Smrg 2987ec681f3Smrg VkPipelineShaderStageCreateInfo stage = {0}; 2997ec681f3Smrg stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 3007ec681f3Smrg stage.stage = VK_SHADER_STAGE_COMPUTE_BIT; 3017ec681f3Smrg stage.module = comp->module->shader; 3027ec681f3Smrg stage.pName = "main"; 3037ec681f3Smrg 3047ec681f3Smrg VkSpecializationInfo sinfo = {0}; 3057ec681f3Smrg VkSpecializationMapEntry me[3]; 3067ec681f3Smrg if (state->use_local_size) { 3077ec681f3Smrg stage.pSpecializationInfo = &sinfo; 3087ec681f3Smrg sinfo.mapEntryCount = 3; 3097ec681f3Smrg sinfo.pMapEntries = &me[0]; 3107ec681f3Smrg sinfo.dataSize = sizeof(state->local_size); 3117ec681f3Smrg sinfo.pData = &state->local_size[0]; 3127ec681f3Smrg uint32_t ids[] = {ZINK_WORKGROUP_SIZE_X, ZINK_WORKGROUP_SIZE_Y, ZINK_WORKGROUP_SIZE_Z}; 3137ec681f3Smrg for (int i = 0; i < 3; i++) { 3147ec681f3Smrg me[i].size = sizeof(uint32_t); 3157ec681f3Smrg me[i].constantID = ids[i]; 3167ec681f3Smrg me[i].offset = i * sizeof(uint32_t); 3177ec681f3Smrg } 3187ec681f3Smrg } 3197ec681f3Smrg 3207ec681f3Smrg pci.stage = stage; 3217ec681f3Smrg 3227ec681f3Smrg VkPipeline pipeline; 3237ec681f3Smrg if (vkCreateComputePipelines(screen->dev, comp->base.pipeline_cache, 1, &pci, 3247ec681f3Smrg NULL, &pipeline) != VK_SUCCESS) { 3257ec681f3Smrg debug_printf("vkCreateComputePipelines failed\n"); 3267ec681f3Smrg return VK_NULL_HANDLE; 3277ec681f3Smrg } 3287ec681f3Smrg zink_screen_update_pipeline_cache(screen, &comp->base); 3297ec681f3Smrg 3307ec681f3Smrg return pipeline; 3317ec681f3Smrg} 332