Path: blob/21.2-virgl/src/gallium/drivers/zink/zink_pipeline.c
4570 views
/*1* Copyright 2018 Collabora Ltd.2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* on the rights to use, copy, modify, merge, publish, distribute, sub7* license, and/or sell copies of the Software, and to permit persons to whom8* the Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL17* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,18* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR19* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE20* USE OR OTHER DEALINGS IN THE SOFTWARE.21*/2223#include "compiler/spirv/spirv.h"2425#include "zink_pipeline.h"2627#include "zink_compiler.h"28#include "zink_context.h"29#include "zink_program.h"30#include "zink_render_pass.h"31#include "zink_screen.h"32#include "zink_state.h"3334#include "util/u_debug.h"35#include "util/u_prim.h"3637static VkBlendFactor38clamp_void_blend_factor(VkBlendFactor f)39{40if (f == VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA)41return VK_BLEND_FACTOR_ZERO;42if (f == VK_BLEND_FACTOR_DST_ALPHA)43return VK_BLEND_FACTOR_ONE;44return f;45}4647VkPipeline48zink_create_gfx_pipeline(struct zink_screen *screen,49struct zink_gfx_program *prog,50struct zink_gfx_pipeline_state *state,51VkPrimitiveTopology primitive_topology)52{53VkPipelineVertexInputStateCreateInfo vertex_input_state = {0};54vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;55vertex_input_state.pVertexBindingDescriptions = state->element_state->bindings;56vertex_input_state.vertexBindingDescriptionCount = state->element_state->num_bindings;57vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs;58vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs;5960VkPipelineVertexInputDivisorStateCreateInfoEXT vdiv_state = {0};61if (state->element_state->divisors_present) {62vertex_input_state.pNext = &vdiv_state;63vdiv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;64vdiv_state.vertexBindingDivisorCount = state->element_state->divisors_present;65vdiv_state.pVertexBindingDivisors = state->element_state->divisors;66}6768VkPipelineInputAssemblyStateCreateInfo primitive_state = {0};69primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;70primitive_state.topology = primitive_topology;71switch (primitive_topology) {72case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:73case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:74case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:75case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:76case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:77case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:78if (state->primitive_restart)79debug_printf("restart_index set with unsupported primitive topology %u\n", primitive_topology);80primitive_state.primitiveRestartEnable = VK_FALSE;81break;82default:83primitive_state.primitiveRestartEnable = state->primitive_restart ? VK_TRUE : VK_FALSE;84}8586VkPipelineColorBlendAttachmentState blend_att[PIPE_MAX_COLOR_BUFS];87VkPipelineColorBlendStateCreateInfo blend_state = {0};88blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;89if (state->void_alpha_attachments) {90for (unsigned i = 0; i < state->num_attachments; i++) {91blend_att[i] = state->blend_state->attachments[i];92if (state->void_alpha_attachments & BITFIELD_BIT(i)) {93blend_att[i].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;94blend_att[i].srcColorBlendFactor = clamp_void_blend_factor(blend_att[i].srcColorBlendFactor);95blend_att[i].dstColorBlendFactor = clamp_void_blend_factor(blend_att[i].dstColorBlendFactor);96}97}98blend_state.pAttachments = blend_att;99} else100blend_state.pAttachments = state->blend_state->attachments;101blend_state.attachmentCount = state->num_attachments;102blend_state.logicOpEnable = state->blend_state->logicop_enable;103blend_state.logicOp = state->blend_state->logicop_func;104105VkPipelineMultisampleStateCreateInfo ms_state = {0};106ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;107ms_state.rasterizationSamples = state->rast_samples;108ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage;109ms_state.alphaToOneEnable = state->blend_state->alpha_to_one;110ms_state.pSampleMask = state->sample_mask ? &state->sample_mask : NULL;111if (state->rast_state->force_persample_interp) {112ms_state.sampleShadingEnable = VK_TRUE;113ms_state.minSampleShading = 1.0;114}115116VkPipelineViewportStateCreateInfo viewport_state = {0};117viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;118viewport_state.viewportCount = state->num_viewports;119viewport_state.pViewports = NULL;120viewport_state.scissorCount = state->num_viewports;121viewport_state.pScissors = NULL;122123VkPipelineRasterizationStateCreateInfo rast_state = {0};124rast_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;125126rast_state.depthClampEnable = state->rast_state->depth_clamp;127rast_state.rasterizerDiscardEnable = state->rast_state->rasterizer_discard;128rast_state.polygonMode = state->rast_state->polygon_mode;129rast_state.cullMode = state->rast_state->cull_mode;130rast_state.frontFace = state->front_face;131132rast_state.depthBiasEnable = VK_TRUE;133rast_state.depthBiasConstantFactor = 0.0;134rast_state.depthBiasClamp = 0.0;135rast_state.depthBiasSlopeFactor = 0.0;136rast_state.lineWidth = 1.0f;137138VkPipelineRasterizationProvokingVertexStateCreateInfoEXT pv_state;139pv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT;140pv_state.provokingVertexMode = state->rast_state->pv_mode;141if (screen->info.have_EXT_provoking_vertex &&142state->rast_state->pv_mode == VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT) {143pv_state.pNext = rast_state.pNext;144rast_state.pNext = &pv_state;145}146147VkPipelineRasterizationLineStateCreateInfoEXT rast_line_state;148if (screen->info.have_EXT_line_rasterization) {149rast_line_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;150rast_line_state.pNext = rast_state.pNext;151rast_line_state.lineRasterizationMode = state->rast_state->line_mode;152153if (state->rast_state->line_stipple_pattern != UINT16_MAX) {154rast_line_state.stippledLineEnable = VK_TRUE;155rast_line_state.lineStippleFactor = state->rast_state->line_stipple_factor + 1;156rast_line_state.lineStipplePattern = state->rast_state->line_stipple_pattern;157} else {158rast_line_state.stippledLineEnable = VK_FALSE;159rast_line_state.lineStippleFactor = 0;160rast_line_state.lineStipplePattern = 0;161}162rast_state.pNext = &rast_line_state;163}164165VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {0};166depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;167depth_stencil_state.depthTestEnable = state->depth_stencil_alpha_state->depth_test;168depth_stencil_state.depthCompareOp = state->depth_stencil_alpha_state->depth_compare_op;169depth_stencil_state.depthBoundsTestEnable = state->depth_stencil_alpha_state->depth_bounds_test;170depth_stencil_state.minDepthBounds = state->depth_stencil_alpha_state->min_depth_bounds;171depth_stencil_state.maxDepthBounds = state->depth_stencil_alpha_state->max_depth_bounds;172depth_stencil_state.stencilTestEnable = state->depth_stencil_alpha_state->stencil_test;173depth_stencil_state.front = state->depth_stencil_alpha_state->stencil_front;174depth_stencil_state.back = state->depth_stencil_alpha_state->stencil_back;175depth_stencil_state.depthWriteEnable = state->depth_stencil_alpha_state->depth_write;176177VkDynamicState dynamicStateEnables[24] = {178VK_DYNAMIC_STATE_LINE_WIDTH,179VK_DYNAMIC_STATE_DEPTH_BIAS,180VK_DYNAMIC_STATE_BLEND_CONSTANTS,181VK_DYNAMIC_STATE_STENCIL_REFERENCE,182};183unsigned state_count = 4;184if (screen->info.have_EXT_extended_dynamic_state) {185dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT;186dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT;187dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS;188dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT;189dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT;190dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT;191dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT;192dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;193dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;194dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_OP_EXT;195dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT;196dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT;197dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_FRONT_FACE_EXT;198if (state->sample_locations_enabled)199dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT;200} else {201dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT;202dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR;203}204205VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};206pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;207pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;208pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;209210VkGraphicsPipelineCreateInfo pci = {0};211pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;212pci.layout = prog->base.layout;213pci.renderPass = state->render_pass->render_pass;214pci.pVertexInputState = &vertex_input_state;215pci.pInputAssemblyState = &primitive_state;216pci.pRasterizationState = &rast_state;217pci.pColorBlendState = &blend_state;218pci.pMultisampleState = &ms_state;219pci.pViewportState = &viewport_state;220pci.pDepthStencilState = &depth_stencil_state;221pci.pDynamicState = &pipelineDynamicStateCreateInfo;222223VkPipelineTessellationStateCreateInfo tci = {0};224VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0};225if (prog->shaders[PIPE_SHADER_TESS_CTRL] && prog->shaders[PIPE_SHADER_TESS_EVAL]) {226tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;227tci.patchControlPoints = state->vertices_per_patch;228pci.pTessellationState = &tci;229tci.pNext = &tdci;230tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;231tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;232}233234VkPipelineShaderStageCreateInfo shader_stages[ZINK_SHADER_COUNT];235uint32_t num_stages = 0;236for (int i = 0; i < ZINK_SHADER_COUNT; ++i) {237if (!prog->modules[i])238continue;239240VkPipelineShaderStageCreateInfo stage = {0};241stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;242stage.stage = zink_shader_stage(i);243stage.module = prog->modules[i]->shader;244stage.pName = "main";245shader_stages[num_stages++] = stage;246}247assert(num_stages > 0);248249pci.pStages = shader_stages;250pci.stageCount = num_stages;251252VkPipeline pipeline;253if (vkCreateGraphicsPipelines(screen->dev, prog->base.pipeline_cache, 1, &pci,254NULL, &pipeline) != VK_SUCCESS) {255debug_printf("vkCreateGraphicsPipelines failed\n");256return VK_NULL_HANDLE;257}258zink_screen_update_pipeline_cache(screen, &prog->base);259260return pipeline;261}262263VkPipeline264zink_create_compute_pipeline(struct zink_screen *screen, struct zink_compute_program *comp, struct zink_compute_pipeline_state *state)265{266VkComputePipelineCreateInfo pci = {0};267pci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;268pci.layout = comp->base.layout;269270VkPipelineShaderStageCreateInfo stage = {0};271stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;272stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;273stage.module = comp->module->shader;274stage.pName = "main";275276VkSpecializationInfo sinfo = {0};277VkSpecializationMapEntry me[3];278if (state->use_local_size) {279stage.pSpecializationInfo = &sinfo;280sinfo.mapEntryCount = 3;281sinfo.pMapEntries = &me[0];282sinfo.dataSize = sizeof(state->local_size);283sinfo.pData = &state->local_size[0];284uint32_t ids[] = {ZINK_WORKGROUP_SIZE_X, ZINK_WORKGROUP_SIZE_Y, ZINK_WORKGROUP_SIZE_Z};285for (int i = 0; i < 3; i++) {286me[i].size = sizeof(uint32_t);287me[i].constantID = ids[i];288me[i].offset = i * sizeof(uint32_t);289}290}291292pci.stage = stage;293294VkPipeline pipeline;295if (vkCreateComputePipelines(screen->dev, comp->base.pipeline_cache, 1, &pci,296NULL, &pipeline) != VK_SUCCESS) {297debug_printf("vkCreateComputePipelines failed\n");298return VK_NULL_HANDLE;299}300zink_screen_update_pipeline_cache(screen, &comp->base);301302return pipeline;303}304305306