diff --git a/src/panfrost/vulkan/panvk_cmd_buffer.h b/src/panfrost/vulkan/panvk_cmd_buffer.h index 8f7ef22277d..8b09290fa81 100644 --- a/src/panfrost/vulkan/panvk_cmd_buffer.h +++ b/src/panfrost/vulkan/panvk_cmd_buffer.h @@ -111,7 +111,7 @@ struct panvk_attrib_buf { struct panvk_cmd_graphics_state { struct panvk_descriptor_state desc_state; - const struct panvk_pipeline *pipeline; + const struct panvk_graphics_pipeline *pipeline; uint32_t dirty; @@ -168,7 +168,7 @@ struct panvk_cmd_graphics_state { struct panvk_cmd_compute_state { struct panvk_descriptor_state desc_state; - const struct panvk_pipeline *pipeline; + const struct panvk_compute_pipeline *pipeline; struct panvk_compute_sysvals sysvals; }; @@ -198,10 +198,10 @@ panvk_cmd_get_pipeline(const struct panvk_cmd_buffer *cmdbuf, { switch (bindpoint) { case VK_PIPELINE_BIND_POINT_GRAPHICS: - return cmdbuf->state.gfx.pipeline; + return &cmdbuf->state.gfx.pipeline->base; case VK_PIPELINE_BIND_POINT_COMPUTE: - return cmdbuf->state.compute.pipeline; + return &cmdbuf->state.compute.pipeline->base; default: assert(!"Unsupported bind point"); diff --git a/src/panfrost/vulkan/panvk_pipeline.h b/src/panfrost/vulkan/panvk_pipeline.h index 5b353f0e412..25d39b1a95f 100644 --- a/src/panfrost/vulkan/panvk_pipeline.h +++ b/src/panfrost/vulkan/panvk_pipeline.h @@ -43,103 +43,140 @@ struct panvk_attribs_info { unsigned buf_count; }; +enum panvk_pipeline_type { + PANVK_PIPELINE_GRAPHICS, + PANVK_PIPELINE_COMPUTE, +}; + struct panvk_pipeline { struct vk_object_base base; - - struct panvk_varyings_info varyings; - struct panvk_attribs_info attribs; + enum panvk_pipeline_type type; const struct panvk_pipeline_layout *layout; - unsigned active_stages; - - uint32_t dynamic_state_mask; - struct panvk_priv_bo *binary_bo; struct panvk_priv_bo *state_bo; - uint64_t vpd; + 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; - unsigned wls_size; - - struct { - uint64_t address; - struct pan_shader_info info; - struct mali_renderer_state_packed rsd_template; - bool required; - bool dynamic_rsd; - uint8_t rt_mask; - } fs; - - struct { - struct pan_compute_dim local_size; - } cs; - - struct { - unsigned topology; - bool writes_point_size; - bool primitive_restart; - } ia; - - struct { - bool clamp_depth; - float line_width; - struct { - bool enable; - float constant_factor; - float clamp; - float slope_factor; - } depth_bias; - bool front_ccw; - bool cull_front_face; - bool cull_back_face; - bool enable; - } rast; - - struct { - bool z_test; - bool z_write; - unsigned z_compare_func; - bool s_test; - struct { - unsigned fail_op; - unsigned pass_op; - unsigned z_fail_op; - unsigned compare_func; - uint8_t compare_mask; - uint8_t write_mask; - uint8_t ref; - } s_front, s_back; - } zs; - - struct { - uint8_t rast_samples; - uint8_t min_samples; - uint16_t sample_mask; - bool alpha_to_coverage; - bool alpha_to_one; - } ms; - - struct { - struct pan_blend_state state; - struct mali_blend_packed bd_template[8]; - struct { - uint8_t index; - uint16_t bifrost_factor; - } constant[8]; - bool reads_dest; - } blend; - - VkViewport viewport; - VkRect2D scissor; }; VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_pipeline, base, VkPipeline, VK_OBJECT_TYPE_PIPELINE) +struct panvk_graphics_pipeline { + struct panvk_pipeline base; + + struct panvk_varyings_info varyings; + + struct { + uint32_t dynamic_mask; + + struct { + struct panvk_attribs_info attribs; + } vs; + + struct { + uint64_t address; + struct pan_shader_info info; + bool required; + bool dynamic_rsd; + uint8_t rt_mask; + struct mali_renderer_state_packed rsd_template; + } fs; + + struct { + unsigned topology; + bool writes_point_size; + bool primitive_restart; + } ia; + + struct { + bool clamp_depth; + float line_width; + struct { + bool enable; + float constant_factor; + float clamp; + float slope_factor; + } depth_bias; + bool front_ccw; + bool cull_front_face; + bool cull_back_face; + bool enable; + } rast; + + struct { + bool z_test; + bool z_write; + unsigned z_compare_func; + bool s_test; + struct { + unsigned fail_op; + unsigned pass_op; + unsigned z_fail_op; + unsigned compare_func; + uint8_t compare_mask; + uint8_t write_mask; + uint8_t ref; + } s_front, s_back; + } zs; + + struct { + uint8_t rast_samples; + uint8_t min_samples; + uint16_t sample_mask; + bool alpha_to_coverage; + bool alpha_to_one; + } ms; + + struct { + struct pan_blend_state pstate; + struct { + uint8_t index; + uint16_t bifrost_factor; + } constant[8]; + struct mali_blend_packed bd_template[8]; + bool reads_dest; + } blend; + + struct { + uint64_t vpd; + VkViewport viewport; + VkRect2D scissor; + } vp; + } state; +}; + +static struct panvk_graphics_pipeline * +panvk_pipeline_to_graphics_pipeline(struct panvk_pipeline *pipeline) +{ + if (pipeline->type != PANVK_PIPELINE_GRAPHICS) + return NULL; + + return container_of(pipeline, struct panvk_graphics_pipeline, base); +} + +struct panvk_compute_pipeline { + struct panvk_pipeline base; + + struct pan_compute_dim local_size; + unsigned wls_size; +}; + +static struct panvk_compute_pipeline * +panvk_pipeline_to_compute_pipeline(struct panvk_pipeline *pipeline) +{ + if (pipeline->type != PANVK_PIPELINE_COMPUTE) + return NULL; + + return container_of(pipeline, struct panvk_compute_pipeline, base); +} + #endif diff --git a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c index 09129aa82bc..ae7593fb323 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c @@ -522,10 +522,10 @@ static void panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { - const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline; + const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline; - if (!pipeline->fs.dynamic_rsd) { - draw->fs_rsd = pipeline->rsds[MESA_SHADER_FRAGMENT]; + if (!pipeline->state.fs.dynamic_rsd) { + draw->fs_rsd = pipeline->base.rsds[MESA_SHADER_FRAGMENT]; return; } @@ -533,29 +533,27 @@ panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf, const struct panvk_cmd_graphics_state *state = &cmdbuf->state.gfx; struct panfrost_ptr rsd = pan_pool_alloc_desc_aggregate( &cmdbuf->desc_pool.base, PAN_DESC(RENDERER_STATE), - PAN_DESC_ARRAY(pipeline->blend.state.rt_count, BLEND)); + PAN_DESC_ARRAY(pipeline->state.blend.pstate.rt_count, BLEND)); struct mali_renderer_state_packed rsd_dyn; - struct mali_renderer_state_packed *rsd_templ = - (struct mali_renderer_state_packed *)&pipeline->fs.rsd_template; - - STATIC_ASSERT(sizeof(pipeline->fs.rsd_template) >= sizeof(*rsd_templ)); + const struct mali_renderer_state_packed *rsd_templ = + &pipeline->state.fs.rsd_template; pan_pack(&rsd_dyn, RENDERER_STATE, cfg) { - if (pipeline->dynamic_state_mask & + if (pipeline->state.dynamic_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BIAS)) { cfg.depth_units = state->rast.depth_bias.constant_factor * 2.0f; cfg.depth_factor = state->rast.depth_bias.slope_factor; cfg.depth_bias_clamp = state->rast.depth_bias.clamp; } - if (pipeline->dynamic_state_mask & + if (pipeline->state.dynamic_mask & (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK)) { cfg.stencil_front.mask = state->zs.s_front.compare_mask; cfg.stencil_back.mask = state->zs.s_back.compare_mask; } - if (pipeline->dynamic_state_mask & + if (pipeline->state.dynamic_mask & (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) { cfg.stencil_mask_misc.stencil_mask_front = state->zs.s_front.write_mask; @@ -563,7 +561,7 @@ panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf, state->zs.s_back.write_mask; } - if (pipeline->dynamic_state_mask & + if (pipeline->state.dynamic_mask & (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE)) { cfg.stencil_front.reference_value = state->zs.s_front.ref; cfg.stencil_back.reference_value = state->zs.s_back.ref; @@ -574,15 +572,14 @@ panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf, memcpy(rsd.cpu, &rsd_dyn, sizeof(rsd_dyn)); void *bd = rsd.cpu + pan_size(RENDERER_STATE); - for (unsigned i = 0; i < pipeline->blend.state.rt_count; i++) { - if (pipeline->blend.constant[i].index != (uint8_t)~0) { + for (unsigned i = 0; i < pipeline->state.blend.pstate.rt_count; i++) { + if (pipeline->state.blend.constant[i].index != (uint8_t)~0) { struct mali_blend_packed bd_dyn; - struct mali_blend_packed *bd_templ = - (struct mali_blend_packed *)&pipeline->blend.bd_template[i]; - - float constant = cmdbuf->state.gfx.blend - .constants[pipeline->blend.constant[i].index] * - pipeline->blend.constant[i].bifrost_factor; + const struct mali_blend_packed *bd_templ = + &pipeline->state.blend.bd_template[i]; + unsigned constant_idx = pipeline->state.blend.constant[i].index; + float constant = cmdbuf->state.gfx.blend.constants[constant_idx] * + pipeline->state.blend.constant[i].bifrost_factor; pan_pack(&bd_dyn, BLEND, cfg) { cfg.enable = false; @@ -691,7 +688,7 @@ static void panvk_draw_prepare_varyings(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { - const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline; + const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline; struct panvk_varyings_info *varyings = &cmdbuf->state.gfx.varyings; panvk_varyings_alloc(varyings, &cmdbuf->varying_pool.base, @@ -726,16 +723,16 @@ panvk_draw_prepare_varyings(struct panvk_cmd_buffer *cmdbuf, varyings->varying[VARYING_SLOT_POS].offset; } - if (pipeline->ia.writes_point_size) { + if (pipeline->state.ia.writes_point_size) { draw->psiz = varyings->buf[varyings->varying[VARYING_SLOT_PSIZ].buf].address + varyings->varying[VARYING_SLOT_POS].offset; - } else if (pipeline->ia.topology == MALI_DRAW_MODE_LINES || - pipeline->ia.topology == MALI_DRAW_MODE_LINE_STRIP || - pipeline->ia.topology == MALI_DRAW_MODE_LINE_LOOP) { - draw->line_width = pipeline->dynamic_state_mask & PANVK_DYNAMIC_LINE_WIDTH + } else if (pipeline->state.ia.topology == MALI_DRAW_MODE_LINES || + pipeline->state.ia.topology == MALI_DRAW_MODE_LINE_STRIP || + pipeline->state.ia.topology == MALI_DRAW_MODE_LINE_LOOP) { + draw->line_width = pipeline->state.dynamic_mask & PANVK_DYNAMIC_LINE_WIDTH ? cmdbuf->state.gfx.rast.line_width - : pipeline->rast.line_width; + : pipeline->state.rast.line_width; } else { draw->line_width = 1.0f; } @@ -907,24 +904,24 @@ panvk_draw_prepare_vs_attribs(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { struct panvk_descriptor_state *desc_state = &cmdbuf->state.gfx.desc_state; - const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline; + const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline; unsigned num_imgs = - pipeline->img_access_mask & BITFIELD_BIT(MESA_SHADER_VERTEX) - ? pipeline->layout->num_imgs + pipeline->base.img_access_mask & BITFIELD_BIT(MESA_SHADER_VERTEX) + ? pipeline->base.layout->num_imgs : 0; - unsigned attrib_count = pipeline->attribs.attrib_count + num_imgs; + unsigned attrib_count = pipeline->state.vs.attribs.attrib_count + num_imgs; if (desc_state->vs_attribs || !attrib_count) return; - if (!pipeline->attribs.buf_count) { - panvk_prepare_non_vs_attribs(cmdbuf, desc_state, pipeline); + if (!pipeline->state.vs.attribs.buf_count) { + panvk_prepare_non_vs_attribs(cmdbuf, desc_state, &pipeline->base); desc_state->vs_attrib_bufs = desc_state->non_vs_attrib_bufs; desc_state->vs_attribs = desc_state->non_vs_attribs; return; } - unsigned attrib_buf_count = pipeline->attribs.buf_count * 2; + unsigned attrib_buf_count = pipeline->state.vs.attribs.buf_count * 2; struct panfrost_ptr bufs = pan_pool_alloc_desc_array( &cmdbuf->desc_pool.base, attrib_buf_count + 1, ATTRIBUTE_BUFFER); struct mali_attribute_buffer_packed *attrib_buf_descs = bufs.cpu; @@ -932,29 +929,31 @@ panvk_draw_prepare_vs_attribs(struct panvk_cmd_buffer *cmdbuf, &cmdbuf->desc_pool.base, attrib_count, ATTRIBUTE); struct mali_attribute_packed *attrib_descs = attribs.cpu; - for (unsigned i = 0; i < pipeline->attribs.buf_count; i++) { - panvk_draw_emit_attrib_buf(draw, &pipeline->attribs.buf[i], + for (unsigned i = 0; i < pipeline->state.vs.attribs.buf_count; i++) { + panvk_draw_emit_attrib_buf(draw, &pipeline->state.vs.attribs.buf[i], &cmdbuf->state.gfx.vb.bufs[i], &attrib_buf_descs[i * 2]); } - for (unsigned i = 0; i < pipeline->attribs.attrib_count; i++) { - unsigned buf_idx = pipeline->attribs.attrib[i].buf; + for (unsigned i = 0; i < pipeline->state.vs.attribs.attrib_count; i++) { + unsigned buf_idx = pipeline->state.vs.attribs.attrib[i].buf; - panvk_draw_emit_attrib( - draw, &pipeline->attribs.attrib[i], &pipeline->attribs.buf[buf_idx], - &cmdbuf->state.gfx.vb.bufs[buf_idx], &attrib_descs[i]); + panvk_draw_emit_attrib(draw, &pipeline->state.vs.attribs.attrib[i], + &pipeline->state.vs.attribs.buf[buf_idx], + &cmdbuf->state.gfx.vb.bufs[buf_idx], + &attrib_descs[i]); } - if (attrib_count > pipeline->attribs.attrib_count) { + if (num_imgs) { unsigned bufs_offset = - pipeline->attribs.buf_count * pan_size(ATTRIBUTE_BUFFER) * 2; + pipeline->state.vs.attribs.buf_count * pan_size(ATTRIBUTE_BUFFER) * 2; unsigned attribs_offset = - pipeline->attribs.buf_count * pan_size(ATTRIBUTE); + pipeline->state.vs.attribs.buf_count * pan_size(ATTRIBUTE); - panvk_fill_non_vs_attribs( - cmdbuf, desc_state, pipeline, bufs.cpu + bufs_offset, - attribs.cpu + attribs_offset, pipeline->attribs.buf_count * 2); + panvk_fill_non_vs_attribs(cmdbuf, desc_state, &pipeline->base, + bufs.cpu + bufs_offset, + attribs.cpu + attribs_offset, + pipeline->state.vs.attribs.buf_count * 2); } /* A NULL entry is needed to stop prefecting on Bifrost */ @@ -970,15 +969,15 @@ panvk_draw_prepare_attributes(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { struct panvk_descriptor_state *desc_state = &cmdbuf->state.gfx.desc_state; - const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline; + 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 = desc_state->vs_attribs; draw->stages[i].attribute_bufs = desc_state->vs_attrib_bufs; - } else if (pipeline->img_access_mask & BITFIELD_BIT(i)) { - panvk_prepare_non_vs_attribs(cmdbuf, desc_state, pipeline); + } else if (pipeline->base.img_access_mask & BITFIELD_BIT(i)) { + panvk_prepare_non_vs_attribs(cmdbuf, desc_state, &pipeline->base); draw->stages[i].attributes = desc_state->non_vs_attribs; draw->stages[i].attribute_bufs = desc_state->non_vs_attrib_bufs; } @@ -1025,10 +1024,10 @@ static void panvk_draw_prepare_viewport(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { - const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline; + const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline; - if (pipeline->vpd) { - draw->viewport = pipeline->vpd; + if (pipeline->state.vp.vpd) { + draw->viewport = pipeline->state.vp.vpd; } else if (cmdbuf->state.gfx.vpd) { draw->viewport = cmdbuf->state.gfx.vpd; } else { @@ -1036,13 +1035,13 @@ panvk_draw_prepare_viewport(struct panvk_cmd_buffer *cmdbuf, pan_pool_alloc_desc(&cmdbuf->desc_pool.base, VIEWPORT); const VkViewport *viewport = - pipeline->dynamic_state_mask & PANVK_DYNAMIC_VIEWPORT + pipeline->state.dynamic_mask & PANVK_DYNAMIC_VIEWPORT ? &cmdbuf->state.gfx.viewport - : &pipeline->viewport; + : &pipeline->state.vp.viewport; const VkRect2D *scissor = - pipeline->dynamic_state_mask & PANVK_DYNAMIC_SCISSOR + pipeline->state.dynamic_mask & PANVK_DYNAMIC_SCISSOR ? &cmdbuf->state.gfx.scissor - : &pipeline->scissor; + : &pipeline->state.vp.scissor; panvk_per_arch(emit_viewport)(viewport, scissor, vp.cpu); draw->viewport = cmdbuf->state.gfx.vpd = vp.gpu; @@ -1053,7 +1052,7 @@ static void panvk_draw_prepare_vertex_job(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { - const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline; + const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline; struct panvk_batch *batch = cmdbuf->cur_batch; struct panfrost_ptr ptr = pan_pool_alloc_desc(&cmdbuf->desc_pool.base, COMPUTE_JOB); @@ -1069,7 +1068,7 @@ panvk_draw_prepare_vertex_job(struct panvk_cmd_buffer *cmdbuf, } pan_section_pack(ptr.cpu, COMPUTE_JOB, DRAW, cfg) { - cfg.state = pipeline->rsds[MESA_SHADER_VERTEX]; + cfg.state = pipeline->base.rsds[MESA_SHADER_VERTEX]; 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; @@ -1086,16 +1085,16 @@ panvk_draw_prepare_vertex_job(struct panvk_cmd_buffer *cmdbuf, } static void -panvk_emit_tiler_primitive(const struct panvk_pipeline *pipeline, +panvk_emit_tiler_primitive(const struct panvk_graphics_pipeline *pipeline, const struct panvk_draw_info *draw, void *prim) { pan_pack(prim, PRIMITIVE, cfg) { - cfg.draw_mode = pipeline->ia.topology; - if (pipeline->ia.writes_point_size) + cfg.draw_mode = pipeline->state.ia.topology; + if (pipeline->state.ia.writes_point_size) cfg.point_size_array_format = MALI_POINT_SIZE_ARRAY_FORMAT_FP16; cfg.first_provoking_vertex = true; - if (pipeline->ia.primitive_restart) + if (pipeline->state.ia.primitive_restart) cfg.primitive_restart = MALI_PRIMITIVE_RESTART_IMPLICIT; cfg.job_task_split = 6; @@ -1125,12 +1124,12 @@ panvk_emit_tiler_primitive(const struct panvk_pipeline *pipeline, } static void -panvk_emit_tiler_primitive_size(const struct panvk_pipeline *pipeline, +panvk_emit_tiler_primitive_size(const struct panvk_graphics_pipeline *pipeline, const struct panvk_draw_info *draw, void *primsz) { pan_pack(primsz, PRIMITIVE_SIZE, cfg) { - if (pipeline->ia.writes_point_size) { + if (pipeline->state.ia.writes_point_size) { cfg.size_array = draw->psiz; } else { cfg.constant = draw->line_width; @@ -1139,13 +1138,13 @@ panvk_emit_tiler_primitive_size(const struct panvk_pipeline *pipeline, } static void -panvk_emit_tiler_dcd(const struct panvk_pipeline *pipeline, +panvk_emit_tiler_dcd(const struct panvk_graphics_pipeline *pipeline, const struct panvk_draw_info *draw, void *dcd) { pan_pack(dcd, DRAW, cfg) { - cfg.front_face_ccw = pipeline->rast.front_ccw; - cfg.cull_front_face = pipeline->rast.cull_front_face; - cfg.cull_back_face = pipeline->rast.cull_back_face; + cfg.front_face_ccw = pipeline->state.rast.front_ccw; + cfg.cull_front_face = pipeline->state.rast.cull_front_face; + cfg.cull_back_face = pipeline->state.rast.cull_back_face; cfg.position = draw->position; cfg.state = draw->fs_rsd; cfg.attributes = draw->stages[MESA_SHADER_FRAGMENT].attributes; @@ -1159,9 +1158,9 @@ panvk_emit_tiler_dcd(const struct panvk_pipeline *pipeline, * be set to 0 and the provoking vertex is selected with the * PRIMITIVE.first_provoking_vertex field. */ - if (pipeline->ia.topology == MALI_DRAW_MODE_LINES || - pipeline->ia.topology == MALI_DRAW_MODE_LINE_STRIP || - pipeline->ia.topology == MALI_DRAW_MODE_LINE_LOOP) { + if (pipeline->state.ia.topology == MALI_DRAW_MODE_LINES || + pipeline->state.ia.topology == MALI_DRAW_MODE_LINE_STRIP || + pipeline->state.ia.topology == MALI_DRAW_MODE_LINE_LOOP) { cfg.flat_shading_vertex = true; } @@ -1181,7 +1180,7 @@ static void panvk_draw_prepare_tiler_job(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { - const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline; + const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline; struct panvk_batch *batch = cmdbuf->cur_batch; struct panfrost_ptr ptr = pan_pool_alloc_desc(&cmdbuf->desc_pool.base, TILER_JOB); @@ -1255,7 +1254,7 @@ panvk_cmd_draw(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { struct panvk_batch *batch = cmdbuf->cur_batch; struct panvk_descriptor_state *desc_state = &cmdbuf->state.gfx.desc_state; - const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline; + const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline; /* There are only 16 bits in the descriptor for the job ID, make sure all * the 3 (2 in Bifrost) jobs in this draw are in the same batch. @@ -1266,19 +1265,19 @@ panvk_cmd_draw(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) batch = panvk_per_arch(cmd_open_batch)(cmdbuf); } - if (pipeline->rast.enable) + if (pipeline->state.rast.enable) panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf); panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, true); panvk_cmd_prepare_draw_sysvals(cmdbuf, draw); - panvk_cmd_prepare_push_sets(cmdbuf, desc_state, pipeline); + panvk_cmd_prepare_push_sets(cmdbuf, desc_state, &pipeline->base); panvk_cmd_prepare_push_uniforms(cmdbuf, desc_state, &cmdbuf->state.gfx.sysvals, sizeof(cmdbuf->state.gfx.sysvals)); - panvk_cmd_prepare_ubos(cmdbuf, desc_state, pipeline); - panvk_cmd_prepare_textures(cmdbuf, desc_state, pipeline); - panvk_cmd_prepare_samplers(cmdbuf, desc_state, pipeline); + panvk_cmd_prepare_ubos(cmdbuf, desc_state, &pipeline->base); + panvk_cmd_prepare_textures(cmdbuf, desc_state, &pipeline->base); + panvk_cmd_prepare_samplers(cmdbuf, desc_state, &pipeline->base); /* TODO: indexed draws */ draw->tls = batch->tls.gpu; @@ -1299,14 +1298,14 @@ panvk_cmd_draw(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) panvk_draw_prepare_tiler_context(cmdbuf, draw); panvk_draw_prepare_vertex_job(cmdbuf, draw); panvk_draw_prepare_tiler_job(cmdbuf, draw); - batch->tlsinfo.tls.size = MAX2(pipeline->tls_size, batch->tlsinfo.tls.size); - assert(!pipeline->wls_size); + batch->tlsinfo.tls.size = + MAX2(pipeline->base.tls_size, batch->tlsinfo.tls.size); unsigned vjob_id = pan_jc_add_job(&cmdbuf->desc_pool.base, &batch->jc, MALI_JOB_TYPE_VERTEX, false, false, 0, 0, &draw->jobs.vertex, false); - if (pipeline->rast.enable && draw->position) { + if (pipeline->state.rast.enable && draw->position) { pan_jc_add_job(&cmdbuf->desc_pool.base, &batch->jc, MALI_JOB_TYPE_TILER, false, false, vjob_id, 0, &draw->jobs.tiler, false); } @@ -1402,8 +1401,8 @@ panvk_per_arch(CmdDrawIndexed)(VkCommandBuffer commandBuffer, if (instanceCount == 0 || indexCount == 0) return; - const struct panvk_pipeline *pipeline = cmdbuf->state.gfx.pipeline; - bool primitive_restart = pipeline->ia.primitive_restart; + const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline; + bool primitive_restart = pipeline->state.ia.primitive_restart; panvk_index_minmax_search(cmdbuf, firstIndex, indexCount, primitive_restart, &min_vertex, &max_vertex); @@ -1689,7 +1688,8 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x, struct panvk_descriptor_state *desc_state = &cmdbuf->state.compute.desc_state; - const struct panvk_pipeline *pipeline = cmdbuf->state.compute.pipeline; + const struct panvk_compute_pipeline *pipeline = + cmdbuf->state.compute.pipeline; struct panfrost_ptr job = pan_pool_alloc_desc(&cmdbuf->desc_pool.base, COMPUTE_JOB); @@ -1697,20 +1697,20 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x, sysvals->num_work_groups.x = x; sysvals->num_work_groups.y = y; sysvals->num_work_groups.z = z; - sysvals->local_group_size.x = pipeline->cs.local_size.x; - sysvals->local_group_size.y = pipeline->cs.local_size.y; - sysvals->local_group_size.z = pipeline->cs.local_size.z; + sysvals->local_group_size.x = pipeline->local_size.x; + sysvals->local_group_size.y = pipeline->local_size.y; + sysvals->local_group_size.z = pipeline->local_size.z; desc_state->push_uniforms = 0; panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, false); dispatch.tsd = batch->tls.gpu; - panvk_cmd_prepare_push_sets(cmdbuf, desc_state, pipeline); - panvk_prepare_non_vs_attribs(cmdbuf, desc_state, pipeline); + panvk_cmd_prepare_push_sets(cmdbuf, desc_state, &pipeline->base); + panvk_prepare_non_vs_attribs(cmdbuf, desc_state, &pipeline->base); dispatch.attributes = desc_state->non_vs_attribs; dispatch.attribute_bufs = desc_state->non_vs_attrib_bufs; - panvk_cmd_prepare_ubos(cmdbuf, desc_state, pipeline); + panvk_cmd_prepare_ubos(cmdbuf, desc_state, &pipeline->base); dispatch.ubos = desc_state->ubos; panvk_cmd_prepare_push_uniforms(cmdbuf, desc_state, @@ -1718,25 +1718,25 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x, sizeof(cmdbuf->state.compute.sysvals)); dispatch.push_uniforms = desc_state->push_uniforms; - panvk_cmd_prepare_textures(cmdbuf, desc_state, pipeline); + panvk_cmd_prepare_textures(cmdbuf, desc_state, &pipeline->base); dispatch.textures = desc_state->textures; - panvk_cmd_prepare_samplers(cmdbuf, desc_state, pipeline); + panvk_cmd_prepare_samplers(cmdbuf, desc_state, &pipeline->base); dispatch.samplers = desc_state->samplers; panfrost_pack_work_groups_compute( pan_section_ptr(job.cpu, COMPUTE_JOB, INVOCATION), dispatch.wg_count.x, - dispatch.wg_count.y, dispatch.wg_count.z, pipeline->cs.local_size.x, - pipeline->cs.local_size.y, pipeline->cs.local_size.z, false, false); + dispatch.wg_count.y, dispatch.wg_count.z, pipeline->local_size.x, + pipeline->local_size.y, pipeline->local_size.z, false, false); pan_section_pack(job.cpu, COMPUTE_JOB, PARAMETERS, cfg) { - cfg.job_task_split = util_logbase2_ceil(pipeline->cs.local_size.x + 1) + - util_logbase2_ceil(pipeline->cs.local_size.y + 1) + - util_logbase2_ceil(pipeline->cs.local_size.z + 1); + cfg.job_task_split = util_logbase2_ceil(pipeline->local_size.x + 1) + + util_logbase2_ceil(pipeline->local_size.y + 1) + + util_logbase2_ceil(pipeline->local_size.z + 1); } pan_section_pack(job.cpu, COMPUTE_JOB, DRAW, cfg) { - cfg.state = pipeline->rsds[MESA_SHADER_COMPUTE]; + cfg.state = pipeline->base.rsds[MESA_SHADER_COMPUTE]; cfg.attributes = dispatch.attributes; cfg.attribute_buffers = dispatch.attribute_bufs; cfg.thread_storage = dispatch.tsd; @@ -1749,7 +1749,7 @@ 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->tls_size; + batch->tlsinfo.tls.size = pipeline->base.tls_size; batch->tlsinfo.wls.size = pipeline->wls_size; if (batch->tlsinfo.wls.size) { unsigned core_id_range; @@ -2118,25 +2118,31 @@ panvk_per_arch(CmdBindPipeline)(VkCommandBuffer commandBuffer, VK_FROM_HANDLE(panvk_pipeline, pipeline, _pipeline); switch (pipelineBindPoint) { - case VK_PIPELINE_BIND_POINT_GRAPHICS: - cmdbuf->state.gfx.fs_rsd = 0; - cmdbuf->state.gfx.varyings = pipeline->varyings; + case VK_PIPELINE_BIND_POINT_GRAPHICS: { + struct panvk_graphics_pipeline *gfx_pipeline = + panvk_pipeline_to_graphics_pipeline(pipeline); - if (!(pipeline->dynamic_state_mask & + cmdbuf->state.gfx.fs_rsd = 0; + cmdbuf->state.gfx.varyings = gfx_pipeline->varyings; + + if (!(gfx_pipeline->state.dynamic_mask & BITFIELD_BIT(VK_DYNAMIC_STATE_VIEWPORT))) { - cmdbuf->state.gfx.viewport = pipeline->viewport; + cmdbuf->state.gfx.viewport = gfx_pipeline->state.vp.viewport; cmdbuf->state.gfx.dirty |= PANVK_DYNAMIC_VIEWPORT; } - if (!(pipeline->dynamic_state_mask & + if (!(gfx_pipeline->state.dynamic_mask & BITFIELD_BIT(VK_DYNAMIC_STATE_SCISSOR))) { - cmdbuf->state.gfx.scissor = pipeline->scissor; + cmdbuf->state.gfx.scissor = gfx_pipeline->state.vp.scissor; cmdbuf->state.gfx.dirty |= PANVK_DYNAMIC_SCISSOR; } - cmdbuf->state.gfx.pipeline = pipeline; + + cmdbuf->state.gfx.pipeline = gfx_pipeline; break; + } case VK_PIPELINE_BIND_POINT_COMPUTE: - cmdbuf->state.compute.pipeline = pipeline; + cmdbuf->state.compute.pipeline = + panvk_pipeline_to_compute_pipeline(pipeline); break; default: diff --git a/src/panfrost/vulkan/panvk_vX_pipeline.c b/src/panfrost/vulkan/panvk_vX_pipeline.c index d965c63f0bc..fc117a6edfc 100644 --- a/src/panfrost/vulkan/panvk_vX_pipeline.c +++ b/src/panfrost/vulkan/panvk_vX_pipeline.c @@ -80,22 +80,6 @@ struct panvk_pipeline_builder { enum pipe_format color_attachment_formats[MAX_RTS]; }; -static VkResult -panvk_pipeline_builder_create_pipeline(struct panvk_pipeline_builder *builder, - struct panvk_pipeline **out_pipeline) -{ - struct panvk_device *dev = builder->device; - - struct panvk_pipeline *pipeline = vk_object_zalloc( - &dev->vk, builder->alloc, sizeof(*pipeline), VK_OBJECT_TYPE_PIPELINE); - if (!pipeline) - return VK_ERROR_OUT_OF_HOST_MEMORY; - - pipeline->layout = builder->layout; - *out_pipeline = pipeline; - return VK_SUCCESS; -} - static void panvk_pipeline_builder_finish(struct panvk_pipeline_builder *builder) { @@ -109,15 +93,21 @@ panvk_pipeline_builder_finish(struct panvk_pipeline_builder *builder) } static bool -panvk_pipeline_static_state(struct panvk_pipeline *pipeline, uint32_t id) +panvk_graphics_pipeline_static_state( + const struct panvk_graphics_pipeline *pipeline, uint32_t id) { - return !(pipeline->dynamic_state_mask & (1 << id)); + if (!pipeline) + return false; + + return !(pipeline->state.dynamic_mask & (1 << id)); } static VkResult panvk_pipeline_builder_compile_shaders(struct panvk_pipeline_builder *builder, struct panvk_pipeline *pipeline) { + struct panvk_graphics_pipeline *gfx_pipeline = + panvk_pipeline_to_graphics_pipeline(pipeline); const VkPipelineShaderStageCreateInfo *stage_infos[MESA_SHADER_STAGES] = { NULL}; const VkPipelineShaderStageCreateInfo *stages = @@ -142,9 +132,9 @@ panvk_pipeline_builder_compile_shaders(struct panvk_pipeline_builder *builder, shader = panvk_per_arch(shader_create)( builder->device, stage, stage_info, builder->layout, - &pipeline->blend.state, - panvk_pipeline_static_state(pipeline, - VK_DYNAMIC_STATE_BLEND_CONSTANTS), + gfx_pipeline ? &gfx_pipeline->state.blend.pstate : NULL, + panvk_graphics_pipeline_static_state(gfx_pipeline, + VK_DYNAMIC_STATE_BLEND_CONSTANTS), builder->alloc); if (!shader) return VK_ERROR_OUT_OF_HOST_MEMORY; @@ -192,6 +182,8 @@ static void panvk_pipeline_builder_alloc_static_state_bo( struct panvk_pipeline_builder *builder, struct panvk_pipeline *pipeline) { + struct panvk_graphics_pipeline *gfx_pipeline = + panvk_pipeline_to_graphics_pipeline(pipeline); unsigned bo_size = 0; for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++) { @@ -199,19 +191,23 @@ panvk_pipeline_builder_alloc_static_state_bo( if (!shader && i != MESA_SHADER_FRAGMENT) continue; - if (pipeline->fs.dynamic_rsd && i == MESA_SHADER_FRAGMENT) + assert(gfx_pipeline); + if (gfx_pipeline->state.fs.dynamic_rsd && i == MESA_SHADER_FRAGMENT) continue; bo_size = ALIGN_POT(bo_size, pan_alignment(RENDERER_STATE)); builder->stages[i].rsd_offset = bo_size; bo_size += pan_size(RENDERER_STATE); if (i == MESA_SHADER_FRAGMENT) - bo_size += pan_size(BLEND) * MAX2(pipeline->blend.state.rt_count, 1); + bo_size += pan_size(BLEND) * + MAX2(gfx_pipeline->state.blend.pstate.rt_count, 1); } if (builder->create_info.gfx && - panvk_pipeline_static_state(pipeline, VK_DYNAMIC_STATE_VIEWPORT) && - panvk_pipeline_static_state(pipeline, VK_DYNAMIC_STATE_SCISSOR)) { + panvk_graphics_pipeline_static_state(gfx_pipeline, + VK_DYNAMIC_STATE_VIEWPORT) && + panvk_graphics_pipeline_static_state(gfx_pipeline, + VK_DYNAMIC_STATE_SCISSOR)) { bo_size = ALIGN_POT(bo_size, pan_alignment(VIEWPORT)); builder->vpd_offset = bo_size; bo_size += pan_size(VIEWPORT); @@ -235,29 +231,32 @@ panvk_pipeline_builder_emit_non_fs_rsd( } static void -panvk_pipeline_builder_emit_base_fs_rsd(const struct panvk_pipeline *pipeline, - void *rsd) +panvk_pipeline_builder_emit_base_fs_rsd( + const struct panvk_graphics_pipeline *pipeline, void *rsd) { - const struct pan_shader_info *info = &pipeline->fs.info; + const struct pan_shader_info *info = &pipeline->state.fs.info; pan_pack(rsd, RENDERER_STATE, cfg) { - if (pipeline->fs.required) { - pan_shader_prepare_rsd(info, pipeline->fs.address, &cfg); + if (pipeline->state.fs.required) { + pan_shader_prepare_rsd(info, pipeline->state.fs.address, &cfg); uint8_t rt_written = - pipeline->fs.info.outputs_written >> FRAG_RESULT_DATA0; - uint8_t rt_mask = pipeline->fs.rt_mask; + pipeline->state.fs.info.outputs_written >> FRAG_RESULT_DATA0; + uint8_t rt_mask = pipeline->state.fs.rt_mask; cfg.properties.allow_forward_pixel_to_kill = - pipeline->fs.info.fs.can_fpk && !(rt_mask & ~rt_written) && - !pipeline->ms.alpha_to_coverage && !pipeline->blend.reads_dest; + pipeline->state.fs.info.fs.can_fpk && !(rt_mask & ~rt_written) && + !pipeline->state.ms.alpha_to_coverage && + !pipeline->state.blend.reads_dest; - bool writes_zs = pipeline->zs.z_write || pipeline->zs.s_test; - bool zs_always_passes = !pipeline->zs.z_test && !pipeline->zs.s_test; + bool writes_zs = + pipeline->state.zs.z_write || pipeline->state.zs.s_test; + bool zs_always_passes = + !pipeline->state.zs.z_test && !pipeline->state.zs.s_test; bool oq = false; /* TODO: Occlusion queries */ - struct pan_earlyzs_state earlyzs = - pan_earlyzs_get(pan_earlyzs_analyze(info), writes_zs || oq, - pipeline->ms.alpha_to_coverage, zs_always_passes); + struct pan_earlyzs_state earlyzs = pan_earlyzs_get( + pan_earlyzs_analyze(info), writes_zs || oq, + pipeline->state.ms.alpha_to_coverage, zs_always_passes); cfg.properties.pixel_kill_operation = earlyzs.kill; cfg.properties.zs_update_operation = earlyzs.update; @@ -268,66 +267,71 @@ panvk_pipeline_builder_emit_base_fs_rsd(const struct panvk_pipeline *pipeline, cfg.properties.zs_update_operation = MALI_PIXEL_KILL_STRONG_EARLY; } - bool msaa = pipeline->ms.rast_samples > 1; + bool msaa = pipeline->state.ms.rast_samples > 1; cfg.multisample_misc.multisample_enable = msaa; cfg.multisample_misc.sample_mask = - msaa ? pipeline->ms.sample_mask : UINT16_MAX; + msaa ? pipeline->state.ms.sample_mask : UINT16_MAX; cfg.multisample_misc.depth_function = - pipeline->zs.z_test ? pipeline->zs.z_compare_func : MALI_FUNC_ALWAYS; + pipeline->state.zs.z_test ? pipeline->state.zs.z_compare_func + : MALI_FUNC_ALWAYS; - cfg.multisample_misc.depth_write_mask = pipeline->zs.z_write; + cfg.multisample_misc.depth_write_mask = pipeline->state.zs.z_write; cfg.multisample_misc.fixed_function_near_discard = - !pipeline->rast.clamp_depth; + !pipeline->state.rast.clamp_depth; cfg.multisample_misc.fixed_function_far_discard = - !pipeline->rast.clamp_depth; + !pipeline->state.rast.clamp_depth; cfg.multisample_misc.shader_depth_range_fixed = true; - cfg.stencil_mask_misc.stencil_enable = pipeline->zs.s_test; - cfg.stencil_mask_misc.alpha_to_coverage = pipeline->ms.alpha_to_coverage; + cfg.stencil_mask_misc.stencil_enable = pipeline->state.zs.s_test; + cfg.stencil_mask_misc.alpha_to_coverage = + pipeline->state.ms.alpha_to_coverage; cfg.stencil_mask_misc.alpha_test_compare_function = MALI_FUNC_ALWAYS; cfg.stencil_mask_misc.front_facing_depth_bias = - pipeline->rast.depth_bias.enable; + pipeline->state.rast.depth_bias.enable; cfg.stencil_mask_misc.back_facing_depth_bias = - pipeline->rast.depth_bias.enable; + pipeline->state.rast.depth_bias.enable; cfg.stencil_mask_misc.single_sampled_lines = - pipeline->ms.rast_samples <= 1; + pipeline->state.ms.rast_samples <= 1; - if (!(pipeline->dynamic_state_mask & - (1 << VK_DYNAMIC_STATE_DEPTH_BIAS))) { - cfg.depth_units = pipeline->rast.depth_bias.constant_factor * 2.0f; - cfg.depth_factor = pipeline->rast.depth_bias.slope_factor; - cfg.depth_bias_clamp = pipeline->rast.depth_bias.clamp; + if (panvk_graphics_pipeline_static_state(pipeline, + VK_DYNAMIC_STATE_DEPTH_BIAS)) { + cfg.depth_units = + pipeline->state.rast.depth_bias.constant_factor * 2.0f; + cfg.depth_factor = pipeline->state.rast.depth_bias.slope_factor; + cfg.depth_bias_clamp = pipeline->state.rast.depth_bias.clamp; } - if (!(pipeline->dynamic_state_mask & - (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK))) { - cfg.stencil_front.mask = pipeline->zs.s_front.compare_mask; - cfg.stencil_back.mask = pipeline->zs.s_back.compare_mask; + if (panvk_graphics_pipeline_static_state( + pipeline, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK)) { + cfg.stencil_front.mask = pipeline->state.zs.s_front.compare_mask; + cfg.stencil_back.mask = pipeline->state.zs.s_back.compare_mask; } - if (!(pipeline->dynamic_state_mask & - (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK))) { + if (panvk_graphics_pipeline_static_state( + pipeline, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) { cfg.stencil_mask_misc.stencil_mask_front = - pipeline->zs.s_front.write_mask; + pipeline->state.zs.s_front.write_mask; cfg.stencil_mask_misc.stencil_mask_back = - pipeline->zs.s_back.write_mask; + pipeline->state.zs.s_back.write_mask; } - if (!(pipeline->dynamic_state_mask & - (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE))) { - cfg.stencil_front.reference_value = pipeline->zs.s_front.ref; - cfg.stencil_back.reference_value = pipeline->zs.s_back.ref; + if (panvk_graphics_pipeline_static_state( + pipeline, VK_DYNAMIC_STATE_STENCIL_REFERENCE)) { + cfg.stencil_front.reference_value = pipeline->state.zs.s_front.ref; + cfg.stencil_back.reference_value = pipeline->state.zs.s_back.ref; } - cfg.stencil_front.compare_function = pipeline->zs.s_front.compare_func; - cfg.stencil_front.stencil_fail = pipeline->zs.s_front.fail_op; - cfg.stencil_front.depth_fail = pipeline->zs.s_front.z_fail_op; - cfg.stencil_front.depth_pass = pipeline->zs.s_front.pass_op; - cfg.stencil_back.compare_function = pipeline->zs.s_back.compare_func; - cfg.stencil_back.stencil_fail = pipeline->zs.s_back.fail_op; - cfg.stencil_back.depth_fail = pipeline->zs.s_back.z_fail_op; - cfg.stencil_back.depth_pass = pipeline->zs.s_back.pass_op; + cfg.stencil_front.compare_function = + pipeline->state.zs.s_front.compare_func; + cfg.stencil_front.stencil_fail = pipeline->state.zs.s_front.fail_op; + cfg.stencil_front.depth_fail = pipeline->state.zs.s_front.z_fail_op; + cfg.stencil_front.depth_pass = pipeline->state.zs.s_front.pass_op; + cfg.stencil_back.compare_function = + pipeline->state.zs.s_back.compare_func; + cfg.stencil_back.stencil_fail = pipeline->state.zs.s_back.fail_op; + cfg.stencil_back.depth_fail = pipeline->state.zs.s_back.z_fail_op; + cfg.stencil_back.depth_pass = pipeline->state.zs.s_back.pass_op; } } @@ -355,10 +359,10 @@ blend_type_from_nir(nir_alu_type nir_type) } static void -panvk_pipeline_builder_emit_blend(const struct panvk_pipeline *pipeline, - unsigned rt, void *bd) +panvk_pipeline_builder_emit_blend( + const struct panvk_graphics_pipeline *pipeline, unsigned rt, void *bd) { - const struct pan_blend_state *blend = &pipeline->blend.state; + const struct pan_blend_state *blend = &pipeline->state.blend.pstate; const struct pan_blend_rt_state *rts = &blend->rts[rt]; bool dithered = false; @@ -407,7 +411,7 @@ panvk_pipeline_builder_emit_blend(const struct panvk_pipeline *pipeline, 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->fs.info.bifrost.blend[rt].type); + blend_type_from_nir(pipeline->state.fs.info.bifrost.blend[rt].type); cfg.internal.fixed_function.rt = rt; } } @@ -416,13 +420,17 @@ static void panvk_pipeline_builder_init_shaders(struct panvk_pipeline_builder *builder, struct panvk_pipeline *pipeline) { + 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 = builder->shaders[i]; if (!shader) continue; pipeline->tls_size = MAX2(pipeline->tls_size, shader->info.tls_size); - pipeline->wls_size = MAX2(pipeline->wls_size, shader->info.wls_size); if (shader->has_img_access) pipeline->img_access_mask |= BITFIELD_BIT(i); @@ -436,7 +444,7 @@ panvk_pipeline_builder_init_shaders(struct panvk_pipeline_builder *builder, * pipeline to write point size when we're actually drawing points. * Otherwise the point size write would conflict with wide lines. */ - pipeline->ia.writes_point_size = points; + gfx_pipeline->state.ia.writes_point_size = points; } mali_ptr shader_ptr = 0; @@ -457,38 +465,42 @@ panvk_pipeline_builder_init_shaders(struct panvk_pipeline_builder *builder, pipeline->rsds[i] = gpu_rsd; } - if (i == MESA_SHADER_COMPUTE) - pipeline->cs.local_size = shader->local_size; + if (i == MESA_SHADER_COMPUTE) { + compute_pipeline->local_size = shader->local_size; + compute_pipeline->wls_size = shader->info.wls_size; + } } - if (builder->create_info.gfx && !pipeline->fs.dynamic_rsd) { + if (builder->create_info.gfx && !gfx_pipeline->state.fs.dynamic_rsd) { void *rsd = pipeline->state_bo->addr.host + builder->stages[MESA_SHADER_FRAGMENT].rsd_offset; mali_ptr gpu_rsd = pipeline->state_bo->addr.dev + builder->stages[MESA_SHADER_FRAGMENT].rsd_offset; void *bd = rsd + pan_size(RENDERER_STATE); - panvk_pipeline_builder_emit_base_fs_rsd(pipeline, rsd); - for (unsigned rt = 0; rt < pipeline->blend.state.rt_count; rt++) { - panvk_pipeline_builder_emit_blend(pipeline, rt, bd); + panvk_pipeline_builder_emit_base_fs_rsd(gfx_pipeline, rsd); + for (unsigned rt = 0; rt < gfx_pipeline->state.blend.pstate.rt_count; + rt++) { + panvk_pipeline_builder_emit_blend(gfx_pipeline, rt, bd); bd += pan_size(BLEND); } pipeline->rsds[MESA_SHADER_FRAGMENT] = gpu_rsd; } else if (builder->create_info.gfx) { - panvk_pipeline_builder_emit_base_fs_rsd(pipeline, - &pipeline->fs.rsd_template); - for (unsigned rt = 0; rt < MAX2(pipeline->blend.state.rt_count, 1); - rt++) { - panvk_pipeline_builder_emit_blend(pipeline, rt, - &pipeline->blend.bd_template[rt]); + panvk_pipeline_builder_emit_base_fs_rsd( + gfx_pipeline, gfx_pipeline->state.fs.rsd_template.opaque); + for (unsigned rt = 0; + rt < MAX2(gfx_pipeline->state.blend.pstate.rt_count, 1); rt++) { + panvk_pipeline_builder_emit_blend( + gfx_pipeline, rt, + &gfx_pipeline->state.blend.bd_template[rt].opaque); } } } static void panvk_pipeline_builder_parse_viewport(struct panvk_pipeline_builder *builder, - struct panvk_pipeline *pipeline) + struct panvk_graphics_pipeline *pipeline) { /* The spec says: * @@ -497,28 +509,34 @@ panvk_pipeline_builder_parse_viewport(struct panvk_pipeline_builder *builder, * pipeline has rasterization disabled. */ if (!builder->rasterizer_discard && - panvk_pipeline_static_state(pipeline, VK_DYNAMIC_STATE_VIEWPORT) && - panvk_pipeline_static_state(pipeline, VK_DYNAMIC_STATE_SCISSOR)) { - void *vpd = pipeline->state_bo->addr.host + builder->vpd_offset; + panvk_graphics_pipeline_static_state(pipeline, + VK_DYNAMIC_STATE_VIEWPORT) && + panvk_graphics_pipeline_static_state(pipeline, + VK_DYNAMIC_STATE_SCISSOR)) { + void *vpd = pipeline->base.state_bo->addr.host + builder->vpd_offset; panvk_per_arch(emit_viewport)( builder->create_info.gfx->pViewportState->pViewports, builder->create_info.gfx->pViewportState->pScissors, vpd); - pipeline->vpd = pipeline->state_bo->addr.dev + builder->vpd_offset; + pipeline->state.vp.vpd = + pipeline->base.state_bo->addr.dev + builder->vpd_offset; } - if (panvk_pipeline_static_state(pipeline, VK_DYNAMIC_STATE_VIEWPORT) && + + if (panvk_graphics_pipeline_static_state(pipeline, + VK_DYNAMIC_STATE_VIEWPORT) && builder->create_info.gfx->pViewportState) - pipeline->viewport = + pipeline->state.vp.viewport = builder->create_info.gfx->pViewportState->pViewports[0]; - if (panvk_pipeline_static_state(pipeline, VK_DYNAMIC_STATE_SCISSOR) && + if (panvk_graphics_pipeline_static_state(pipeline, + VK_DYNAMIC_STATE_SCISSOR) && builder->create_info.gfx->pViewportState) - pipeline->scissor = + pipeline->state.vp.scissor = builder->create_info.gfx->pViewportState->pScissors[0]; } static void panvk_pipeline_builder_parse_dynamic(struct panvk_pipeline_builder *builder, - struct panvk_pipeline *pipeline) + struct panvk_graphics_pipeline *pipeline) { const VkPipelineDynamicStateCreateInfo *dynamic_info = builder->create_info.gfx->pDynamicState; @@ -530,7 +548,7 @@ panvk_pipeline_builder_parse_dynamic(struct panvk_pipeline_builder *builder, VkDynamicState state = dynamic_info->pDynamicStates[i]; switch (state) { case VK_DYNAMIC_STATE_VIEWPORT ... VK_DYNAMIC_STATE_STENCIL_REFERENCE: - pipeline->dynamic_state_mask |= 1 << state; + pipeline->state.dynamic_mask |= 1 << state; break; default: unreachable("unsupported dynamic state"); @@ -566,35 +584,37 @@ translate_prim_topology(VkPrimitiveTopology in) static void panvk_pipeline_builder_parse_input_assembly( - struct panvk_pipeline_builder *builder, struct panvk_pipeline *pipeline) + struct panvk_pipeline_builder *builder, + struct panvk_graphics_pipeline *pipeline) { - pipeline->ia.primitive_restart = + pipeline->state.ia.primitive_restart = builder->create_info.gfx->pInputAssemblyState->primitiveRestartEnable; - pipeline->ia.topology = translate_prim_topology( + pipeline->state.ia.topology = translate_prim_topology( builder->create_info.gfx->pInputAssemblyState->topology); } static void -panvk_pipeline_builder_parse_color_blend(struct panvk_pipeline_builder *builder, - struct panvk_pipeline *pipeline) +panvk_pipeline_builder_parse_color_blend( + struct panvk_pipeline_builder *builder, + struct panvk_graphics_pipeline *pipeline) { if (!builder->create_info.gfx->pColorBlendState) return; - pipeline->blend.state.logicop_enable = + pipeline->state.blend.pstate.logicop_enable = builder->create_info.gfx->pColorBlendState->logicOpEnable; - pipeline->blend.state.logicop_func = + pipeline->state.blend.pstate.logicop_func = vk_logic_op_to_pipe(builder->create_info.gfx->pColorBlendState->logicOp); - pipeline->blend.state.rt_count = + pipeline->state.blend.pstate.rt_count = util_last_bit(builder->active_color_attachments); - memcpy(pipeline->blend.state.constants, + memcpy(pipeline->state.blend.pstate.constants, builder->create_info.gfx->pColorBlendState->blendConstants, - sizeof(pipeline->blend.state.constants)); + sizeof(pipeline->state.blend.pstate.constants)); - for (unsigned i = 0; i < pipeline->blend.state.rt_count; i++) { + for (unsigned i = 0; i < pipeline->state.blend.pstate.rt_count; i++) { const VkPipelineColorBlendAttachmentState *in = &builder->create_info.gfx->pColorBlendState->pAttachments[i]; - struct pan_blend_rt_state *out = &pipeline->blend.state.rts[i]; + struct pan_blend_rt_state *out = &pipeline->state.blend.pstate.rts[i]; out->format = builder->color_attachment_formats[i]; @@ -627,13 +647,14 @@ panvk_pipeline_builder_parse_color_blend(struct panvk_pipeline_builder *builder, util_blend_dst_alpha_to_one(out->equation.alpha_dst_factor); } - pipeline->blend.reads_dest |= pan_blend_reads_dest(out->equation); + pipeline->state.blend.reads_dest |= pan_blend_reads_dest(out->equation); - unsigned constant_mask = panvk_per_arch(blend_needs_lowering)( - builder->device, &pipeline->blend.state, i) - ? 0 - : pan_blend_constant_mask(out->equation); - pipeline->blend.constant[i].index = ffs(constant_mask) - 1; + unsigned constant_mask = + panvk_per_arch(blend_needs_lowering)(builder->device, + &pipeline->state.blend.pstate, i) + ? 0 + : pan_blend_constant_mask(out->equation); + pipeline->state.blend.constant[i].index = ffs(constant_mask) - 1; if (constant_mask) { /* On Bifrost, the blend constant is expressed with a UNORM of the * size of the target format. The value is then shifted such that @@ -647,26 +668,27 @@ panvk_pipeline_builder_parse_color_blend(struct panvk_pipeline_builder *builder, unsigned chan_size = 0; for (unsigned c = 0; c < format_desc->nr_channels; c++) chan_size = MAX2(format_desc->channel[c].size, chan_size); - pipeline->blend.constant[i].bifrost_factor = ((1 << chan_size) - 1) - << (16 - chan_size); + pipeline->state.blend.constant[i].bifrost_factor = + ((1 << chan_size) - 1) << (16 - chan_size); } } } static void -panvk_pipeline_builder_parse_multisample(struct panvk_pipeline_builder *builder, - struct panvk_pipeline *pipeline) +panvk_pipeline_builder_parse_multisample( + struct panvk_pipeline_builder *builder, + struct panvk_graphics_pipeline *pipeline) { unsigned nr_samples = MAX2( builder->create_info.gfx->pMultisampleState->rasterizationSamples, 1); - pipeline->ms.rast_samples = + pipeline->state.ms.rast_samples = builder->create_info.gfx->pMultisampleState->rasterizationSamples; - pipeline->ms.sample_mask = + pipeline->state.ms.sample_mask = builder->create_info.gfx->pMultisampleState->pSampleMask ? builder->create_info.gfx->pMultisampleState->pSampleMask[0] : UINT16_MAX; - pipeline->ms.min_samples = + pipeline->state.ms.min_samples = MAX2(builder->create_info.gfx->pMultisampleState->minSampleShading * nr_samples, 1); @@ -715,12 +737,12 @@ translate_compare_func(VkCompareOp comp) static void panvk_pipeline_builder_parse_zs(struct panvk_pipeline_builder *builder, - struct panvk_pipeline *pipeline) + struct panvk_graphics_pipeline *pipeline) { if (!builder->use_depth_stencil_attachment) return; - pipeline->zs.z_test = + pipeline->state.zs.z_test = builder->create_info.gfx->pDepthStencilState->depthTestEnable; /* The Vulkan spec says: @@ -732,84 +754,84 @@ panvk_pipeline_builder_parse_zs(struct panvk_pipeline_builder *builder, * The hardware does not make this distinction, though, so we AND in the * condition ourselves. */ - pipeline->zs.z_write = - pipeline->zs.z_test && + pipeline->state.zs.z_write = + pipeline->state.zs.z_test && builder->create_info.gfx->pDepthStencilState->depthWriteEnable; - pipeline->zs.z_compare_func = translate_compare_func( + pipeline->state.zs.z_compare_func = translate_compare_func( builder->create_info.gfx->pDepthStencilState->depthCompareOp); - pipeline->zs.s_test = + pipeline->state.zs.s_test = builder->create_info.gfx->pDepthStencilState->stencilTestEnable; - pipeline->zs.s_front.fail_op = translate_stencil_op( + pipeline->state.zs.s_front.fail_op = translate_stencil_op( builder->create_info.gfx->pDepthStencilState->front.failOp); - pipeline->zs.s_front.pass_op = translate_stencil_op( + pipeline->state.zs.s_front.pass_op = translate_stencil_op( builder->create_info.gfx->pDepthStencilState->front.passOp); - pipeline->zs.s_front.z_fail_op = translate_stencil_op( + pipeline->state.zs.s_front.z_fail_op = translate_stencil_op( builder->create_info.gfx->pDepthStencilState->front.depthFailOp); - pipeline->zs.s_front.compare_func = translate_compare_func( + pipeline->state.zs.s_front.compare_func = translate_compare_func( builder->create_info.gfx->pDepthStencilState->front.compareOp); - pipeline->zs.s_front.compare_mask = + pipeline->state.zs.s_front.compare_mask = builder->create_info.gfx->pDepthStencilState->front.compareMask; - pipeline->zs.s_front.write_mask = + pipeline->state.zs.s_front.write_mask = builder->create_info.gfx->pDepthStencilState->front.writeMask; - pipeline->zs.s_front.ref = + pipeline->state.zs.s_front.ref = builder->create_info.gfx->pDepthStencilState->front.reference; - pipeline->zs.s_back.fail_op = translate_stencil_op( + pipeline->state.zs.s_back.fail_op = translate_stencil_op( builder->create_info.gfx->pDepthStencilState->back.failOp); - pipeline->zs.s_back.pass_op = translate_stencil_op( + pipeline->state.zs.s_back.pass_op = translate_stencil_op( builder->create_info.gfx->pDepthStencilState->back.passOp); - pipeline->zs.s_back.z_fail_op = translate_stencil_op( + pipeline->state.zs.s_back.z_fail_op = translate_stencil_op( builder->create_info.gfx->pDepthStencilState->back.depthFailOp); - pipeline->zs.s_back.compare_func = translate_compare_func( + pipeline->state.zs.s_back.compare_func = translate_compare_func( builder->create_info.gfx->pDepthStencilState->back.compareOp); - pipeline->zs.s_back.compare_mask = + pipeline->state.zs.s_back.compare_mask = builder->create_info.gfx->pDepthStencilState->back.compareMask; - pipeline->zs.s_back.write_mask = + pipeline->state.zs.s_back.write_mask = builder->create_info.gfx->pDepthStencilState->back.writeMask; - pipeline->zs.s_back.ref = + pipeline->state.zs.s_back.ref = builder->create_info.gfx->pDepthStencilState->back.reference; } static void panvk_pipeline_builder_parse_rast(struct panvk_pipeline_builder *builder, - struct panvk_pipeline *pipeline) + struct panvk_graphics_pipeline *pipeline) { - pipeline->rast.clamp_depth = + pipeline->state.rast.clamp_depth = builder->create_info.gfx->pRasterizationState->depthClampEnable; - pipeline->rast.depth_bias.enable = + pipeline->state.rast.depth_bias.enable = builder->create_info.gfx->pRasterizationState->depthBiasEnable; - pipeline->rast.depth_bias.constant_factor = + pipeline->state.rast.depth_bias.constant_factor = builder->create_info.gfx->pRasterizationState->depthBiasConstantFactor; - pipeline->rast.depth_bias.clamp = + pipeline->state.rast.depth_bias.clamp = builder->create_info.gfx->pRasterizationState->depthBiasClamp; - pipeline->rast.depth_bias.slope_factor = + pipeline->state.rast.depth_bias.slope_factor = builder->create_info.gfx->pRasterizationState->depthBiasSlopeFactor; - pipeline->rast.front_ccw = + pipeline->state.rast.front_ccw = builder->create_info.gfx->pRasterizationState->frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE; - pipeline->rast.cull_front_face = + pipeline->state.rast.cull_front_face = builder->create_info.gfx->pRasterizationState->cullMode & VK_CULL_MODE_FRONT_BIT; - pipeline->rast.cull_back_face = + pipeline->state.rast.cull_back_face = builder->create_info.gfx->pRasterizationState->cullMode & VK_CULL_MODE_BACK_BIT; - pipeline->rast.line_width = + pipeline->state.rast.line_width = builder->create_info.gfx->pRasterizationState->lineWidth; - pipeline->rast.enable = + pipeline->state.rast.enable = !builder->create_info.gfx->pRasterizationState->rasterizerDiscardEnable; } static bool -panvk_fs_required(struct panvk_pipeline *pipeline) +panvk_fs_required(struct panvk_graphics_pipeline *pipeline) { - const struct pan_shader_info *info = &pipeline->fs.info; + const struct pan_shader_info *info = &pipeline->state.fs.info; /* If we generally have side effects */ if (info->fs.sidefx) return true; /* If colour is written we need to execute */ - const struct pan_blend_state *blend = &pipeline->blend.state; + const struct pan_blend_state *blend = &pipeline->state.blend.pstate; for (unsigned i = 0; i < blend->rt_count; ++i) { if (blend->rts[i].equation.color_mask) return true; @@ -829,18 +851,19 @@ panvk_fs_required(struct panvk_pipeline *pipeline) static void panvk_pipeline_builder_init_fs_state(struct panvk_pipeline_builder *builder, - struct panvk_pipeline *pipeline) + struct panvk_graphics_pipeline *pipeline) { if (!builder->shaders[MESA_SHADER_FRAGMENT]) return; - pipeline->fs.dynamic_rsd = - pipeline->dynamic_state_mask & PANVK_DYNAMIC_FS_RSD_MASK; - pipeline->fs.address = pipeline->binary_bo->addr.dev + - builder->stages[MESA_SHADER_FRAGMENT].shader_offset; - pipeline->fs.info = builder->shaders[MESA_SHADER_FRAGMENT]->info; - pipeline->fs.rt_mask = builder->active_color_attachments; - pipeline->fs.required = panvk_fs_required(pipeline); + pipeline->state.fs.dynamic_rsd = + pipeline->state.dynamic_mask & PANVK_DYNAMIC_FS_RSD_MASK; + pipeline->state.fs.address = + pipeline->base.binary_bo->addr.dev + + builder->stages[MESA_SHADER_FRAGMENT].shader_offset; + pipeline->state.fs.info = builder->shaders[MESA_SHADER_FRAGMENT]->info; + pipeline->state.fs.rt_mask = builder->active_color_attachments; + pipeline->state.fs.required = panvk_fs_required(pipeline); } static void @@ -887,7 +910,7 @@ panvk_pipeline_update_varying_slot(struct panvk_varyings_info *varyings, static void panvk_pipeline_builder_collect_varyings(struct panvk_pipeline_builder *builder, - struct panvk_pipeline *pipeline) + struct panvk_graphics_pipeline *pipeline) { for (uint32_t s = 0; s < MESA_SHADER_STAGES; s++) { if (!builder->shaders[s]) @@ -925,9 +948,10 @@ panvk_pipeline_builder_collect_varyings(struct panvk_pipeline_builder *builder, static void panvk_pipeline_builder_parse_vertex_input( - struct panvk_pipeline_builder *builder, struct panvk_pipeline *pipeline) + struct panvk_pipeline_builder *builder, + struct panvk_graphics_pipeline *pipeline) { - struct panvk_attribs_info *attribs = &pipeline->attribs; + struct panvk_attribs_info *attribs = &pipeline->state.vs.attribs; const VkPipelineVertexInputStateCreateInfo *info = builder->create_info.gfx->pVertexInputState; @@ -976,27 +1000,45 @@ static VkResult panvk_pipeline_builder_build(struct panvk_pipeline_builder *builder, struct panvk_pipeline **pipeline) { - VkResult result = panvk_pipeline_builder_create_pipeline(builder, pipeline); - if (result != VK_SUCCESS) - return result; + struct panvk_device *dev = builder->device; /* TODO: make those functions return a result and handle errors */ if (builder->create_info.gfx) { - panvk_pipeline_builder_parse_dynamic(builder, *pipeline); - panvk_pipeline_builder_parse_color_blend(builder, *pipeline); + struct panvk_graphics_pipeline *gfx_pipeline = + vk_object_zalloc(&dev->vk, builder->alloc, sizeof(*gfx_pipeline), + VK_OBJECT_TYPE_PIPELINE); + if (!gfx_pipeline) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + *pipeline = &gfx_pipeline->base; + gfx_pipeline->base.layout = builder->layout; + gfx_pipeline->base.type = PANVK_PIPELINE_GRAPHICS; + + panvk_pipeline_builder_parse_dynamic(builder, gfx_pipeline); + panvk_pipeline_builder_parse_color_blend(builder, gfx_pipeline); panvk_pipeline_builder_compile_shaders(builder, *pipeline); - panvk_pipeline_builder_collect_varyings(builder, *pipeline); - panvk_pipeline_builder_parse_input_assembly(builder, *pipeline); - panvk_pipeline_builder_parse_multisample(builder, *pipeline); - panvk_pipeline_builder_parse_zs(builder, *pipeline); - panvk_pipeline_builder_parse_rast(builder, *pipeline); - panvk_pipeline_builder_parse_vertex_input(builder, *pipeline); + panvk_pipeline_builder_collect_varyings(builder, gfx_pipeline); + panvk_pipeline_builder_parse_input_assembly(builder, gfx_pipeline); + panvk_pipeline_builder_parse_multisample(builder, gfx_pipeline); + panvk_pipeline_builder_parse_zs(builder, gfx_pipeline); + panvk_pipeline_builder_parse_rast(builder, gfx_pipeline); + panvk_pipeline_builder_parse_vertex_input(builder, gfx_pipeline); panvk_pipeline_builder_upload_shaders(builder, *pipeline); - panvk_pipeline_builder_init_fs_state(builder, *pipeline); + panvk_pipeline_builder_init_fs_state(builder, gfx_pipeline); panvk_pipeline_builder_alloc_static_state_bo(builder, *pipeline); panvk_pipeline_builder_init_shaders(builder, *pipeline); - panvk_pipeline_builder_parse_viewport(builder, *pipeline); + panvk_pipeline_builder_parse_viewport(builder, gfx_pipeline); } else { + struct panvk_compute_pipeline *compute_pipeline = + vk_object_zalloc(&dev->vk, builder->alloc, sizeof(*compute_pipeline), + VK_OBJECT_TYPE_PIPELINE); + if (!compute_pipeline) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + *pipeline = &compute_pipeline->base; + compute_pipeline->base.layout = builder->layout; + compute_pipeline->base.type = PANVK_PIPELINE_COMPUTE; + panvk_pipeline_builder_compile_shaders(builder, *pipeline); panvk_pipeline_builder_upload_shaders(builder, *pipeline); panvk_pipeline_builder_alloc_static_state_bo(builder, *pipeline);