diff --git a/src/panfrost/vulkan/panvk_pipeline.h b/src/panfrost/vulkan/panvk_pipeline.h index 08555b97f5f..9880ce09e65 100644 --- a/src/panfrost/vulkan/panvk_pipeline.h +++ b/src/panfrost/vulkan/panvk_pipeline.h @@ -25,6 +25,13 @@ #define MAX_RTS 8 +struct panvk_pipeline_shader { + mali_ptr code; + mali_ptr rsd; + struct pan_shader_info info; + bool has_img_access; +}; + enum panvk_pipeline_type { PANVK_PIPELINE_GRAPHICS, PANVK_PIPELINE_COMPUTE, @@ -38,15 +45,6 @@ struct panvk_pipeline { struct panvk_pool bin_pool; struct panvk_pool desc_pool; - - unsigned active_stages; - - uint64_t rsds[MESA_SHADER_STAGES]; - - /* shader stage bit is set of the stage accesses storage images */ - uint32_t img_access_mask; - - unsigned tls_size; }; VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_pipeline, base, VkPipeline, @@ -55,16 +53,13 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_pipeline, base, VkPipeline, struct panvk_graphics_pipeline { struct panvk_pipeline base; + struct panvk_pipeline_shader vs; + struct panvk_pipeline_shader fs; + struct panvk_varyings_info varyings; struct { struct { - bool writes_point_size; - } vs; - - struct { - uint64_t address; - struct pan_shader_info info; bool required; bool dynamic_rsd; uint8_t rt_mask; @@ -100,8 +95,9 @@ panvk_pipeline_to_graphics_pipeline(struct panvk_pipeline *pipeline) struct panvk_compute_pipeline { struct panvk_pipeline base; + struct panvk_pipeline_shader cs; + struct pan_compute_dim local_size; - unsigned wls_size; }; static struct panvk_compute_pipeline * diff --git a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c index 8956c30b9d1..ba4ed54f9a1 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c @@ -535,7 +535,7 @@ panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf, const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline; if (!pipeline->state.fs.dynamic_rsd) { - draw->fs_rsd = pipeline->base.rsds[MESA_SHADER_FRAGMENT]; + draw->fs_rsd = pipeline->fs.rsd; return; } @@ -708,7 +708,7 @@ panvk_draw_prepare_varyings(struct panvk_cmd_buffer *cmdbuf, const struct vk_input_assembly_state *ia = &cmdbuf->vk.dynamic_graphics_state.ia; bool writes_point_size = - pipeline->state.vs.writes_point_size && + pipeline->vs.info.vs.writes_point_size && ia->primitive_topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST; for (unsigned i = 0, buf_idx = 0; i < PANVK_VARY_BUF_MAX; i++) { @@ -806,7 +806,7 @@ panvk_prepare_img_attribs(struct panvk_cmd_buffer *cmdbuf, struct panvk_descriptor_state *desc_state, const struct panvk_pipeline *pipeline) { - if (desc_state->img.attribs || !pipeline->img_access_mask) + if (desc_state->img.attribs) return; unsigned attrib_count = pipeline->layout->num_imgs; @@ -925,9 +925,7 @@ panvk_draw_prepare_vs_attribs(struct panvk_cmd_buffer *cmdbuf, const struct vk_vertex_input_state *vi = cmdbuf->vk.dynamic_graphics_state.vi; unsigned num_imgs = - pipeline->base.img_access_mask & BITFIELD_BIT(MESA_SHADER_VERTEX) - ? pipeline->base.layout->num_imgs - : 0; + pipeline->vs.has_img_access ? pipeline->base.layout->num_imgs : 0; unsigned num_vs_attribs = util_last_bit(vi->attributes_valid); unsigned num_vbs = util_last_bit(vi->bindings_valid); unsigned attrib_count = @@ -1004,16 +1002,16 @@ panvk_draw_prepare_attributes(struct panvk_cmd_buffer *cmdbuf, struct panvk_descriptor_state *desc_state = &cmdbuf->state.gfx.desc_state; const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline; - for (unsigned i = 0; i < ARRAY_SIZE(draw->stages); i++) { - if (i == MESA_SHADER_VERTEX) { - panvk_draw_prepare_vs_attribs(cmdbuf, draw); - draw->stages[i].attributes = cmdbuf->state.gfx.vs.attribs; - draw->stages[i].attribute_bufs = cmdbuf->state.gfx.vs.attrib_bufs; - } else if (pipeline->base.img_access_mask & BITFIELD_BIT(i)) { - panvk_prepare_img_attribs(cmdbuf, desc_state, &pipeline->base); - draw->stages[i].attributes = desc_state->img.attribs; - draw->stages[i].attribute_bufs = desc_state->img.attrib_bufs; - } + panvk_draw_prepare_vs_attribs(cmdbuf, draw); + draw->stages[MESA_SHADER_VERTEX].attributes = cmdbuf->state.gfx.vs.attribs; + draw->stages[MESA_SHADER_VERTEX].attribute_bufs = + cmdbuf->state.gfx.vs.attrib_bufs; + + if (pipeline->fs.has_img_access) { + panvk_prepare_img_attribs(cmdbuf, desc_state, &pipeline->base); + draw->stages[MESA_SHADER_FRAGMENT].attributes = desc_state->img.attribs; + draw->stages[MESA_SHADER_FRAGMENT].attribute_bufs = + desc_state->img.attrib_bufs; } } @@ -1092,7 +1090,7 @@ panvk_draw_prepare_vertex_job(struct panvk_cmd_buffer *cmdbuf, } pan_section_pack(ptr.cpu, COMPUTE_JOB, DRAW, cfg) { - cfg.state = pipeline->base.rsds[MESA_SHADER_VERTEX]; + cfg.state = pipeline->vs.rsd; cfg.attributes = draw->stages[MESA_SHADER_VERTEX].attributes; cfg.attribute_buffers = draw->stages[MESA_SHADER_VERTEX].attribute_bufs; cfg.varyings = draw->stages[MESA_SHADER_VERTEX].varyings; @@ -1142,7 +1140,7 @@ panvk_emit_tiler_primitive(struct panvk_cmd_buffer *cmdbuf, const struct vk_input_assembly_state *ia = &cmdbuf->vk.dynamic_graphics_state.ia; bool writes_point_size = - pipeline->state.vs.writes_point_size && + pipeline->vs.info.vs.writes_point_size && ia->primitive_topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST; pan_pack(prim, PRIMITIVE, cfg) { @@ -1189,7 +1187,7 @@ panvk_emit_tiler_primitive_size(struct panvk_cmd_buffer *cmdbuf, const struct vk_input_assembly_state *ia = &cmdbuf->vk.dynamic_graphics_state.ia; bool writes_point_size = - pipeline->state.vs.writes_point_size && + pipeline->vs.info.vs.writes_point_size && ia->primitive_topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST; pan_pack(primsz, PRIMITIVE_SIZE, cfg) { @@ -1367,7 +1365,8 @@ panvk_cmd_draw(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) panvk_draw_prepare_vertex_job(cmdbuf, draw); panvk_draw_prepare_tiler_job(cmdbuf, draw); batch->tlsinfo.tls.size = - MAX2(pipeline->base.tls_size, batch->tlsinfo.tls.size); + MAX3(pipeline->vs.info.tls_size, pipeline->fs.info.tls_size, + batch->tlsinfo.tls.size); unsigned vjob_id = pan_jc_add_job(&cmdbuf->desc_pool.base, &batch->jc, MALI_JOB_TYPE_VERTEX, @@ -1779,7 +1778,10 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x, dispatch.tsd = batch->tls.gpu; panvk_cmd_prepare_push_sets(cmdbuf, desc_state, &pipeline->base); - panvk_prepare_img_attribs(cmdbuf, desc_state, &pipeline->base); + + if (pipeline->cs.has_img_access) + panvk_prepare_img_attribs(cmdbuf, desc_state, &pipeline->base); + dispatch.attributes = desc_state->img.attribs; dispatch.attribute_bufs = desc_state->img.attrib_bufs; @@ -1809,7 +1811,7 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x, } pan_section_pack(job.cpu, COMPUTE_JOB, DRAW, cfg) { - cfg.state = pipeline->base.rsds[MESA_SHADER_COMPUTE]; + cfg.state = pipeline->cs.rsd; cfg.attributes = dispatch.attributes; cfg.attribute_buffers = dispatch.attribute_bufs; cfg.thread_storage = dispatch.tsd; @@ -1822,8 +1824,8 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x, pan_jc_add_job(&cmdbuf->desc_pool.base, &batch->jc, MALI_JOB_TYPE_COMPUTE, false, false, 0, 0, &job, false); - batch->tlsinfo.tls.size = pipeline->base.tls_size; - batch->tlsinfo.wls.size = pipeline->wls_size; + batch->tlsinfo.tls.size = pipeline->cs.info.tls_size; + batch->tlsinfo.wls.size = pipeline->cs.info.wls_size; if (batch->tlsinfo.wls.size) { unsigned core_id_range; diff --git a/src/panfrost/vulkan/panvk_vX_pipeline.c b/src/panfrost/vulkan/panvk_vX_pipeline.c index 6d622a8c89e..07fa6bb1ed9 100644 --- a/src/panfrost/vulkan/panvk_vX_pipeline.c +++ b/src/panfrost/vulkan/panvk_vX_pipeline.c @@ -52,20 +52,6 @@ #include "pan_earlyzs.h" #include "pan_shader.h" -static void -release_shaders(struct panvk_pipeline *pipeline, struct panvk_shader **shaders, - const VkAllocationCallbacks *alloc) -{ - struct panvk_device *dev = to_panvk_device(pipeline->base.device); - - for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++) { - if (!shaders[i]) - continue; - - panvk_per_arch(shader_destroy)(dev, shaders[i], alloc); - } -} - static bool dyn_state_is_set(const struct panvk_graphics_pipeline *pipeline, uint32_t id) { @@ -75,72 +61,6 @@ dyn_state_is_set(const struct panvk_graphics_pipeline *pipeline, uint32_t id) return BITSET_TEST(pipeline->state.dynamic.set, id); } -static VkResult -compile_shaders(struct panvk_pipeline *pipeline, - const VkPipelineShaderStageCreateInfo *stages, - uint32_t stage_count, const VkAllocationCallbacks *alloc, - struct panvk_shader **shaders) -{ - struct panvk_device *dev = to_panvk_device(pipeline->base.device); - struct panvk_graphics_pipeline *gfx_pipeline = - panvk_pipeline_to_graphics_pipeline(pipeline); - const VkPipelineShaderStageCreateInfo *stage_infos[MESA_SHADER_STAGES] = { - NULL, - }; - - for (uint32_t i = 0; i < stage_count; i++) { - gl_shader_stage stage = vk_to_mesa_shader_stage(stages[i].stage); - stage_infos[stage] = &stages[i]; - } - - /* compile shaders in reverse order */ - for (gl_shader_stage stage = MESA_SHADER_STAGES - 1; - stage > MESA_SHADER_NONE; stage--) { - const VkPipelineShaderStageCreateInfo *stage_info = stage_infos[stage]; - if (!stage_info) - continue; - - struct panvk_shader *shader; - - shader = panvk_per_arch(shader_create)( - dev, stage_info, pipeline->layout, - gfx_pipeline ? &gfx_pipeline->state.blend.pstate : NULL, - dyn_state_is_set(gfx_pipeline, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS), - alloc); - if (!shader) - return VK_ERROR_OUT_OF_HOST_MEMORY; - - shaders[stage] = shader; - } - - return VK_SUCCESS; -} - -static mali_ptr -upload_shader(struct panvk_pipeline *pipeline, - const struct panvk_shader *shader) -{ - void *shader_data = util_dynarray_element(&shader->binary, uint8_t, 0); - unsigned shader_sz = util_dynarray_num_elements(&shader->binary, uint8_t); - - if (!shader_sz) - return 0; - - return pan_pool_upload_aligned(&pipeline->bin_pool.base, shader_data, - shader_sz, 128); -} - -static void -emit_non_fs_rsd(const struct pan_shader_info *shader_info, mali_ptr shader_ptr, - void *rsd) -{ - assert(shader_info->stage != MESA_SHADER_FRAGMENT); - - pan_pack(rsd, RENDERER_STATE, cfg) { - pan_shader_prepare_rsd(shader_info, shader_ptr, &cfg); - } -} - static bool writes_depth(const struct vk_depth_stencil_state *ds) { @@ -225,7 +145,7 @@ static void emit_base_fs_rsd(const struct panvk_graphics_pipeline *pipeline, const struct vk_graphics_pipeline_state *state, void *rsd) { - const struct pan_shader_info *info = &pipeline->state.fs.info; + const struct pan_shader_info *info = &pipeline->fs.info; const struct vk_rasterization_state *rs = state->rs; const struct vk_depth_stencil_state *ds = state->ds; const struct vk_multisample_state *ms = state->ms; @@ -238,13 +158,12 @@ emit_base_fs_rsd(const struct panvk_graphics_pipeline *pipeline, bool alpha_to_coverage = ms && ms->alpha_to_coverage_enable; if (pipeline->state.fs.required) { - pan_shader_prepare_rsd(info, pipeline->state.fs.address, &cfg); + pan_shader_prepare_rsd(info, pipeline->fs.code, &cfg); - uint8_t rt_written = - pipeline->state.fs.info.outputs_written >> FRAG_RESULT_DATA0; + uint8_t rt_written = info->outputs_written >> FRAG_RESULT_DATA0; uint8_t rt_mask = pipeline->state.fs.rt_mask; cfg.properties.allow_forward_pixel_to_kill = - pipeline->state.fs.info.fs.can_fpk && !(rt_mask & ~rt_written) && + pipeline->fs.info.fs.can_fpk && !(rt_mask & ~rt_written) && !alpha_to_coverage && !pipeline->state.blend.reads_dest; bool writes_zs = writes_z || writes_s; @@ -405,80 +324,11 @@ emit_blend(const struct panvk_graphics_pipeline *pipeline, unsigned rt, cfg.internal.fixed_function.conversion.memory_format = GENX(panfrost_dithered_format_from_pipe_format)(rts->format, dithered); cfg.internal.fixed_function.conversion.register_format = - blend_type_from_nir(pipeline->state.fs.info.bifrost.blend[rt].type); + blend_type_from_nir(pipeline->fs.info.bifrost.blend[rt].type); cfg.internal.fixed_function.rt = rt; } } -static void -init_shaders(struct panvk_pipeline *pipeline, - const VkGraphicsPipelineCreateInfo *gfx_create_info, - const struct vk_graphics_pipeline_state *gfx_state, - struct panvk_shader **shaders) -{ - struct panvk_graphics_pipeline *gfx_pipeline = - panvk_pipeline_to_graphics_pipeline(pipeline); - struct panvk_compute_pipeline *compute_pipeline = - panvk_pipeline_to_compute_pipeline(pipeline); - - for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++) { - const struct panvk_shader *shader = shaders[i]; - if (!shader) - continue; - - pipeline->tls_size = MAX2(pipeline->tls_size, shader->info.tls_size); - - if (shader->has_img_access) - pipeline->img_access_mask |= BITFIELD_BIT(i); - - if (i == MESA_SHADER_VERTEX) - gfx_pipeline->state.vs.writes_point_size = - shader->info.vs.writes_point_size; - - mali_ptr shader_ptr = i == MESA_SHADER_FRAGMENT - ? gfx_pipeline->state.fs.address - : upload_shader(pipeline, shader); - - if (i != MESA_SHADER_FRAGMENT) { - struct panfrost_ptr rsd = - pan_pool_alloc_desc(&pipeline->desc_pool.base, RENDERER_STATE); - - emit_non_fs_rsd(&shader->info, shader_ptr, rsd.cpu); - pipeline->rsds[i] = rsd.gpu; - } - - if (i == MESA_SHADER_COMPUTE) { - compute_pipeline->local_size = shader->local_size; - compute_pipeline->wls_size = shader->info.wls_size; - } - } - - if (gfx_create_info && !gfx_pipeline->state.fs.dynamic_rsd) { - unsigned bd_count = MAX2(gfx_pipeline->state.blend.pstate.rt_count, 1); - struct panfrost_ptr rsd = pan_pool_alloc_desc_aggregate( - &pipeline->desc_pool.base, PAN_DESC(RENDERER_STATE), - PAN_DESC_ARRAY(bd_count, BLEND)); - void *bd = rsd.cpu + pan_size(RENDERER_STATE); - - emit_base_fs_rsd(gfx_pipeline, gfx_state, rsd.cpu); - for (unsigned rt = 0; rt < gfx_pipeline->state.blend.pstate.rt_count; - rt++) { - emit_blend(gfx_pipeline, rt, bd); - bd += pan_size(BLEND); - } - - pipeline->rsds[MESA_SHADER_FRAGMENT] = rsd.gpu; - } else if (gfx_create_info) { - emit_base_fs_rsd(gfx_pipeline, gfx_state, - gfx_pipeline->state.fs.rsd_template.opaque); - for (unsigned rt = 0; - rt < MAX2(gfx_pipeline->state.blend.pstate.rt_count, 1); rt++) { - emit_blend(gfx_pipeline, rt, - &gfx_pipeline->state.blend.bd_template[rt].opaque); - } - } -} - #define is_dyn(__state, __name) \ BITSET_TEST((__state)->dynamic, MESA_VK_DYNAMIC_##__name) @@ -578,7 +428,7 @@ parse_color_blend(struct panvk_graphics_pipeline *pipeline, static bool fs_required(struct panvk_graphics_pipeline *pipeline) { - const struct pan_shader_info *info = &pipeline->state.fs.info; + const struct pan_shader_info *info = &pipeline->fs.info; /* If we generally have side effects */ if (info->fs.sidefx) @@ -598,21 +448,33 @@ fs_required(struct panvk_graphics_pipeline *pipeline) static void init_fs_state(struct panvk_graphics_pipeline *pipeline, - const struct vk_graphics_pipeline_state *state, - struct panvk_shader *shader) + const struct vk_graphics_pipeline_state *state) { - if (!shader) - return; - pipeline->state.fs.dynamic_rsd = is_dyn(state, RS_DEPTH_BIAS_FACTORS) || is_dyn(state, CB_BLEND_CONSTANTS) || is_dyn(state, DS_STENCIL_COMPARE_MASK) || is_dyn(state, DS_STENCIL_WRITE_MASK) || is_dyn(state, DS_STENCIL_REFERENCE); - pipeline->state.fs.address = upload_shader(&pipeline->base, shader); - pipeline->state.fs.info = shader->info; pipeline->state.fs.rt_mask = get_active_color_attachments(state); pipeline->state.fs.required = fs_required(pipeline); + + unsigned bd_count = MAX2(pipeline->state.blend.pstate.rt_count, 1); + struct mali_renderer_state_packed *rsd = &pipeline->state.fs.rsd_template; + struct mali_blend_packed *bds = pipeline->state.blend.bd_template; + + if (!pipeline->state.fs.dynamic_rsd) { + struct panfrost_ptr ptr = pan_pool_alloc_desc_aggregate( + &pipeline->base.desc_pool.base, PAN_DESC(RENDERER_STATE), + PAN_DESC_ARRAY(bd_count, BLEND)); + + rsd = ptr.cpu; + bds = ptr.cpu + pan_size(RENDERER_STATE); + pipeline->fs.rsd = ptr.gpu; + } + + emit_base_fs_rsd(pipeline, state, rsd); + for (unsigned i = 0; i < bd_count; i++) + emit_blend(pipeline, i, &bds[i]); } static void @@ -656,24 +518,19 @@ update_varying_slot(struct panvk_varyings_info *varyings, gl_shader_stage stage, } static void -collect_varyings(struct panvk_graphics_pipeline *pipeline, - struct panvk_shader **shaders) +collect_varyings(struct panvk_graphics_pipeline *pipeline) { - for (uint32_t s = 0; s < MESA_SHADER_STAGES; s++) { - if (!shaders[s]) - continue; + const struct pan_shader_info *vs_info = &pipeline->vs.info; + const struct pan_shader_info *fs_info = &pipeline->fs.info; - const struct pan_shader_info *info = &shaders[s]->info; + for (unsigned i = 0; i < vs_info->varyings.output_count; i++) { + update_varying_slot(&pipeline->varyings, MESA_SHADER_VERTEX, + &vs_info->varyings.output[i], false); + } - for (unsigned i = 0; i < info->varyings.input_count; i++) { - update_varying_slot(&pipeline->varyings, s, &info->varyings.input[i], - true); - } - - for (unsigned i = 0; i < info->varyings.output_count; i++) { - update_varying_slot(&pipeline->varyings, s, &info->varyings.output[i], - false); - } + for (unsigned i = 0; i < fs_info->varyings.input_count; i++) { + update_varying_slot(&pipeline->varyings, MESA_SHADER_FRAGMENT, + &fs_info->varyings.input[i], true); } /* TODO: Xfb */ @@ -693,6 +550,60 @@ collect_varyings(struct panvk_graphics_pipeline *pipeline, } } +static VkResult +init_pipeline_shader(struct panvk_pipeline *pipeline, + const VkPipelineShaderStageCreateInfo *stage_info, + const VkAllocationCallbacks *alloc, + struct panvk_pipeline_shader *pshader) +{ + struct panvk_device *dev = to_panvk_device(pipeline->base.device); + struct panvk_graphics_pipeline *gfx_pipeline = + panvk_pipeline_to_graphics_pipeline(pipeline); + struct panvk_shader *shader; + + shader = panvk_per_arch(shader_create)( + dev, stage_info, pipeline->layout, + gfx_pipeline ? &gfx_pipeline->state.blend.pstate : NULL, + dyn_state_is_set(gfx_pipeline, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS), + alloc); + if (!shader) + return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY); + + void *shader_data = util_dynarray_element(&shader->binary, uint8_t, 0); + unsigned shader_sz = util_dynarray_num_elements(&shader->binary, uint8_t); + + if (shader_sz) { + pshader->code = pan_pool_upload_aligned(&pipeline->bin_pool.base, + shader_data, shader_sz, 128); + } else { + pshader->code = 0; + } + + pshader->info = shader->info; + pshader->has_img_access = shader->has_img_access; + + if (stage_info->stage == VK_SHADER_STAGE_COMPUTE_BIT) { + struct panvk_compute_pipeline *compute_pipeline = + panvk_pipeline_to_compute_pipeline(pipeline); + + compute_pipeline->local_size = shader->local_size; + } + + if (stage_info->stage != VK_SHADER_STAGE_FRAGMENT_BIT) { + struct panfrost_ptr rsd = + pan_pool_alloc_desc(&pipeline->desc_pool.base, RENDERER_STATE); + + pan_pack(rsd.cpu, RENDERER_STATE, cfg) { + pan_shader_prepare_rsd(&pshader->info, pshader->code, &cfg); + } + + pshader->rsd = rsd.gpu; + } + + panvk_per_arch(shader_destroy)(dev, shader, alloc); + return VK_SUCCESS; +} + static VkResult panvk_graphics_pipeline_create(struct panvk_device *dev, struct vk_pipeline_cache *cache, @@ -730,16 +641,38 @@ panvk_graphics_pipeline_create(struct panvk_device *dev, panvk_pool_init(&gfx_pipeline->base.desc_pool, dev, NULL, 0, 4096, "Pipeline static state", false); - struct panvk_shader *shaders[MESA_SHADER_STAGES] = {NULL}; - parse_color_blend(gfx_pipeline, &state); - compile_shaders(&gfx_pipeline->base, create_info->pStages, - create_info->stageCount, alloc, shaders); - collect_varyings(gfx_pipeline, shaders); - init_fs_state(gfx_pipeline, &state, shaders[MESA_SHADER_FRAGMENT]); - init_shaders(&gfx_pipeline->base, create_info, &state, shaders); - release_shaders(&gfx_pipeline->base, shaders, alloc); + /* Make sure the stage info is correct even if no stage info is provided for + * this stage in pStages. + */ + gfx_pipeline->vs.info.stage = MESA_SHADER_VERTEX; + gfx_pipeline->fs.info.stage = MESA_SHADER_FRAGMENT; + + for (uint32_t i = 0; i < create_info->stageCount; i++) { + struct panvk_pipeline_shader *pshader = NULL; + switch (create_info->pStages[i].stage) { + case VK_SHADER_STAGE_VERTEX_BIT: + pshader = &gfx_pipeline->vs; + break; + + case VK_SHADER_STAGE_FRAGMENT_BIT: + pshader = &gfx_pipeline->fs; + break; + + default: + assert(!"Unsupported graphics pipeline stage"); + } + + VkResult result = init_pipeline_shader( + &gfx_pipeline->base, &create_info->pStages[i], alloc, pshader); + if (result != VK_SUCCESS) + return result; + } + + collect_varyings(gfx_pipeline); + init_fs_state(gfx_pipeline, &state); + return VK_SUCCESS; } @@ -796,13 +729,12 @@ panvk_compute_pipeline_create(struct panvk_device *dev, panvk_pool_init(&compute_pipeline->base.desc_pool, dev, NULL, 0, 4096, "Pipeline static state", false); - struct panvk_shader *shaders[MESA_SHADER_STAGES] = {NULL}; + VkResult result = + init_pipeline_shader(&compute_pipeline->base, &create_info->stage, alloc, + &compute_pipeline->cs); + if (result != VK_SUCCESS) + return result; - compile_shaders(&compute_pipeline->base, &create_info->stage, 1, alloc, - shaders); - init_shaders(&compute_pipeline->base, NULL, NULL, shaders); - - release_shaders(&compute_pipeline->base, shaders, alloc); return VK_SUCCESS; }