From 20fe252664e1ee396ecabf35748b1298ce002d91 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 16 Sep 2021 12:51:46 +0200 Subject: [PATCH] panvk: Fix the pipeline binding logic Right now, only one pipeline can be bound at any given time, instead of one per bind-point. Fix the code so we can support compute operations. Signed-off-by: Boris Brezillon Reviewed-by: Tomeu Vizoso Part-of: --- src/panfrost/vulkan/panvk_cmd_buffer.c | 24 ++++--- src/panfrost/vulkan/panvk_private.h | 20 ++++-- src/panfrost/vulkan/panvk_vX_cmd_buffer.c | 86 ++++++++++++----------- 3 files changed, 74 insertions(+), 56 deletions(-) diff --git a/src/panfrost/vulkan/panvk_cmd_buffer.c b/src/panfrost/vulkan/panvk_cmd_buffer.c index 24d20fa93ef..40a9ed0663a 100644 --- a/src/panfrost/vulkan/panvk_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_cmd_buffer.c @@ -78,7 +78,7 @@ panvk_CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VK_FROM_HANDLE(panvk_pipeline_layout, layout, _layout); struct panvk_descriptor_state *descriptors_state = - &cmdbuf->descriptors[pipelineBindPoint]; + &cmdbuf->bind_points[pipelineBindPoint].desc_state; for (unsigned i = 0; i < descriptorSetCount; ++i) { unsigned idx = i + firstSet; @@ -133,23 +133,25 @@ panvk_CmdBindPipeline(VkCommandBuffer commandBuffer, VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); VK_FROM_HANDLE(panvk_pipeline, pipeline, _pipeline); - cmdbuf->state.bind_point = pipelineBindPoint; - cmdbuf->state.pipeline = pipeline; - cmdbuf->state.varyings = pipeline->varyings; + cmdbuf->bind_points[pipelineBindPoint].pipeline = pipeline; cmdbuf->state.fs_rsd = 0; - memset(cmdbuf->descriptors[pipelineBindPoint].sysvals, 0, - sizeof(cmdbuf->descriptors[pipelineBindPoint].sysvals)); + memset(cmdbuf->bind_points[pipelineBindPoint].desc_state.sysvals, 0, + sizeof(cmdbuf->bind_points[0].desc_state.sysvals)); - if (!(pipeline->dynamic_state_mask & BITFIELD_BIT(VK_DYNAMIC_STATE_VIEWPORT))) - cmdbuf->state.viewport = pipeline->viewport; - if (!(pipeline->dynamic_state_mask & BITFIELD_BIT(VK_DYNAMIC_STATE_SCISSOR))) - cmdbuf->state.scissor = pipeline->scissor; + if (pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS) { + cmdbuf->state.varyings = pipeline->varyings; + + if (!(pipeline->dynamic_state_mask & BITFIELD_BIT(VK_DYNAMIC_STATE_VIEWPORT))) + cmdbuf->state.viewport = pipeline->viewport; + if (!(pipeline->dynamic_state_mask & BITFIELD_BIT(VK_DYNAMIC_STATE_SCISSOR))) + cmdbuf->state.scissor = pipeline->scissor; + } /* Sysvals are passed through UBOs, we need dirty the UBO array if the * pipeline contain shaders using sysvals. */ if (pipeline->num_sysvals) - cmdbuf->descriptors[pipelineBindPoint].ubos = 0; + cmdbuf->bind_points[pipelineBindPoint].desc_state.ubos = 0; } void diff --git a/src/panfrost/vulkan/panvk_private.h b/src/panfrost/vulkan/panvk_private.h index 659f70581f0..cefae73d25a 100644 --- a/src/panfrost/vulkan/panvk_private.h +++ b/src/panfrost/vulkan/panvk_private.h @@ -572,10 +572,6 @@ struct panvk_attrib_buf { }; struct panvk_cmd_state { - VkPipelineBindPoint bind_point; - - struct panvk_pipeline *pipeline; - uint32_t dirty; struct panvk_varyings_info varyings; @@ -657,6 +653,11 @@ enum panvk_cmd_buffer_status { PANVK_CMD_BUFFER_STATUS_PENDING, }; +struct panvk_cmd_bind_point_state { + struct panvk_descriptor_state desc_state; + const struct panvk_pipeline *pipeline; +}; + struct panvk_cmd_buffer { struct vk_object_base base; @@ -680,11 +681,20 @@ struct panvk_cmd_buffer { VkShaderStageFlags push_constant_stages; struct panvk_descriptor_set meta_push_descriptors; - struct panvk_descriptor_state descriptors[MAX_BIND_POINTS]; + struct panvk_cmd_bind_point_state bind_points[MAX_BIND_POINTS]; VkResult record_result; }; +#define panvk_cmd_get_bind_point_state(cmdbuf, bindpoint) \ + &(cmdbuf)->bind_points[VK_PIPELINE_BIND_POINT_ ## bindpoint] + +#define panvk_cmd_get_pipeline(cmdbuf, bindpoint) \ + (cmdbuf)->bind_points[VK_PIPELINE_BIND_POINT_ ## bindpoint].pipeline + +#define panvk_cmd_get_desc_state(cmdbuf, bindpoint) \ + &(cmdbuf)->bind_points[VK_PIPELINE_BIND_POINT_ ## bindpoint].desc_state + struct panvk_batch * panvk_cmd_open_batch(struct panvk_cmd_buffer *cmdbuf); diff --git a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c index 05017dcd0cd..7ce34ff24ee 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c @@ -315,11 +315,11 @@ panvk_cmd_upload_sysval(struct panvk_cmd_buffer *cmdbuf, } static void -panvk_cmd_prepare_sysvals(struct panvk_cmd_buffer *cmdbuf) +panvk_cmd_prepare_sysvals(struct panvk_cmd_buffer *cmdbuf, + struct panvk_cmd_bind_point_state *bind_point_state) { - struct panvk_descriptor_state *desc_state = - &cmdbuf->descriptors[cmdbuf->state.bind_point]; - const struct panvk_pipeline *pipeline = cmdbuf->state.pipeline; + struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state; + const struct panvk_pipeline *pipeline = bind_point_state->pipeline; if (!pipeline->num_sysvals) return; @@ -345,17 +345,16 @@ panvk_cmd_prepare_sysvals(struct panvk_cmd_buffer *cmdbuf) } static void -panvk_cmd_prepare_ubos(struct panvk_cmd_buffer *cmdbuf) +panvk_cmd_prepare_ubos(struct panvk_cmd_buffer *cmdbuf, + struct panvk_cmd_bind_point_state *bind_point_state) { - struct panvk_descriptor_state *desc_state = - &cmdbuf->descriptors[cmdbuf->state.bind_point]; - const struct panvk_pipeline *pipeline = - cmdbuf->state.pipeline; + struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state; + const struct panvk_pipeline *pipeline = bind_point_state->pipeline; if (!pipeline->num_ubos || desc_state->ubos) return; - panvk_cmd_prepare_sysvals(cmdbuf); + panvk_cmd_prepare_sysvals(cmdbuf, bind_point_state); struct panfrost_ptr ubos = pan_pool_alloc_desc_array(&cmdbuf->desc_pool.base, @@ -368,11 +367,11 @@ panvk_cmd_prepare_ubos(struct panvk_cmd_buffer *cmdbuf) } static void -panvk_cmd_prepare_textures(struct panvk_cmd_buffer *cmdbuf) +panvk_cmd_prepare_textures(struct panvk_cmd_buffer *cmdbuf, + struct panvk_cmd_bind_point_state *bind_point_state) { - struct panvk_descriptor_state *desc_state = - &cmdbuf->descriptors[cmdbuf->state.bind_point]; - const struct panvk_pipeline *pipeline = cmdbuf->state.pipeline; + struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state; + const struct panvk_pipeline *pipeline = bind_point_state->pipeline; unsigned num_textures = pipeline->layout->num_textures; if (!num_textures || desc_state->textures) @@ -404,11 +403,11 @@ panvk_cmd_prepare_textures(struct panvk_cmd_buffer *cmdbuf) } static void -panvk_cmd_prepare_samplers(struct panvk_cmd_buffer *cmdbuf) +panvk_cmd_prepare_samplers(struct panvk_cmd_buffer *cmdbuf, + struct panvk_cmd_bind_point_state *bind_point_state) { - struct panvk_descriptor_state *desc_state = - &cmdbuf->descriptors[cmdbuf->state.bind_point]; - const struct panvk_pipeline *pipeline = cmdbuf->state.pipeline; + struct panvk_descriptor_state *desc_state = &bind_point_state->desc_state; + const struct panvk_pipeline *pipeline = bind_point_state->pipeline; unsigned num_samplers = pipeline->layout->num_samplers; if (!num_samplers || desc_state->samplers) @@ -439,7 +438,8 @@ static void panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { - const struct panvk_pipeline *pipeline = cmdbuf->state.pipeline; + const struct panvk_pipeline *pipeline = + panvk_cmd_get_pipeline(cmdbuf, GRAPHICS); if (!pipeline->fs.dynamic_rsd) { draw->fs_rsd = pipeline->rsds[MESA_SHADER_FRAGMENT]; @@ -546,7 +546,7 @@ static void panvk_draw_prepare_varyings(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { - const struct panvk_pipeline *pipeline = cmdbuf->state.pipeline; + const struct panvk_pipeline *pipeline = panvk_cmd_get_pipeline(cmdbuf, GRAPHICS); struct panvk_varyings_info *varyings = &cmdbuf->state.varyings; panvk_varyings_alloc(varyings, &cmdbuf->varying_pool.base, @@ -593,8 +593,10 @@ static void panvk_draw_prepare_attributes(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { + const struct panvk_pipeline *pipeline = panvk_cmd_get_pipeline(cmdbuf, GRAPHICS); + /* TODO: images */ - if (!cmdbuf->state.pipeline->attribs.buf_count) + if (!pipeline->attribs.buf_count) return; if (cmdbuf->state.vb.attribs) { @@ -603,13 +605,13 @@ panvk_draw_prepare_attributes(struct panvk_cmd_buffer *cmdbuf, return; } - unsigned buf_count = cmdbuf->state.pipeline->attribs.buf_count + + unsigned buf_count = pipeline->attribs.buf_count + (PAN_ARCH >= 6 ? 1 : 0); struct panfrost_ptr bufs = pan_pool_alloc_desc_array(&cmdbuf->desc_pool.base, buf_count * 2, ATTRIBUTE_BUFFER); - panvk_per_arch(emit_attrib_bufs)(&cmdbuf->state.pipeline->attribs, + panvk_per_arch(emit_attrib_bufs)(&pipeline->attribs, cmdbuf->state.vb.bufs, cmdbuf->state.vb.count, draw, bufs.cpu); @@ -617,10 +619,10 @@ panvk_draw_prepare_attributes(struct panvk_cmd_buffer *cmdbuf, struct panfrost_ptr attribs = pan_pool_alloc_desc_array(&cmdbuf->desc_pool.base, - cmdbuf->state.pipeline->attribs.attrib_count, + pipeline->attribs.attrib_count, ATTRIBUTE); - panvk_per_arch(emit_attribs)(cmdbuf->device, &cmdbuf->state.pipeline->attribs, + panvk_per_arch(emit_attribs)(cmdbuf->device, &pipeline->attribs, cmdbuf->state.vb.bufs, cmdbuf->state.vb.count, attribs.cpu); cmdbuf->state.vb.attribs = attribs.gpu; @@ -632,7 +634,7 @@ static void panvk_draw_prepare_viewport(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { - const struct panvk_pipeline *pipeline = cmdbuf->state.pipeline; + const struct panvk_pipeline *pipeline = panvk_cmd_get_pipeline(cmdbuf, GRAPHICS); if (pipeline->vpd) { draw->viewport = pipeline->vpd; @@ -658,29 +660,28 @@ static void panvk_draw_prepare_vertex_job(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { + const struct panvk_pipeline *pipeline = panvk_cmd_get_pipeline(cmdbuf, GRAPHICS); struct panvk_batch *batch = cmdbuf->state.batch; struct panfrost_ptr ptr = pan_pool_alloc_desc(&cmdbuf->desc_pool.base, COMPUTE_JOB); util_dynarray_append(&batch->jobs, void *, ptr.cpu); draw->jobs.vertex = ptr; - panvk_per_arch(emit_vertex_job)(cmdbuf->state.pipeline, - draw, ptr.cpu); - + panvk_per_arch(emit_vertex_job)(pipeline, draw, ptr.cpu); } static void panvk_draw_prepare_tiler_job(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { + const struct panvk_pipeline *pipeline = panvk_cmd_get_pipeline(cmdbuf, GRAPHICS); struct panvk_batch *batch = cmdbuf->state.batch; struct panfrost_ptr ptr = pan_pool_alloc_desc(&cmdbuf->desc_pool.base, TILER_JOB); util_dynarray_append(&batch->jobs, void *, ptr.cpu); draw->jobs.tiler = ptr; - panvk_per_arch(emit_tiler_job)(cmdbuf->state.pipeline, - draw, ptr.cpu); + panvk_per_arch(emit_tiler_job)(pipeline, draw, ptr.cpu); } void @@ -693,7 +694,10 @@ panvk_per_arch(CmdDraw)(VkCommandBuffer commandBuffer, VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); struct panvk_batch *batch = cmdbuf->state.batch; - const struct panvk_pipeline *pipeline = cmdbuf->state.pipeline; + struct panvk_cmd_bind_point_state *bind_point_state = + panvk_cmd_get_bind_point_state(cmdbuf, GRAPHICS); + const struct panvk_pipeline *pipeline = + panvk_cmd_get_pipeline(cmdbuf, GRAPHICS); /* 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. @@ -704,15 +708,17 @@ panvk_per_arch(CmdDraw)(VkCommandBuffer commandBuffer, batch = panvk_cmd_open_batch(cmdbuf); } - if (cmdbuf->state.pipeline->fs.required) + if (pipeline->fs.required) panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf); panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, true); - panvk_cmd_prepare_ubos(cmdbuf); - panvk_cmd_prepare_textures(cmdbuf); - panvk_cmd_prepare_samplers(cmdbuf); + panvk_cmd_prepare_ubos(cmdbuf, bind_point_state); + panvk_cmd_prepare_textures(cmdbuf, bind_point_state); + panvk_cmd_prepare_samplers(cmdbuf, bind_point_state); /* TODO: indexed draws */ + struct panvk_descriptor_state *desc_state = + panvk_cmd_get_desc_state(cmdbuf, GRAPHICS); struct panvk_draw_info draw = { .first_vertex = firstVertex, @@ -723,9 +729,9 @@ panvk_per_arch(CmdDraw)(VkCommandBuffer commandBuffer, .offset_start = firstVertex, .tls = batch->tls.gpu, .fb = batch->fb.desc.gpu, - .ubos = cmdbuf->descriptors[VK_PIPELINE_BIND_POINT_GRAPHICS].ubos, - .textures = cmdbuf->descriptors[VK_PIPELINE_BIND_POINT_GRAPHICS].textures, - .samplers = cmdbuf->descriptors[VK_PIPELINE_BIND_POINT_GRAPHICS].samplers, + .ubos = desc_state->ubos, + .textures = desc_state->textures, + .samplers = desc_state->samplers, }; STATIC_ASSERT(sizeof(draw.invocation) >= sizeof(struct mali_invocation_packed)); @@ -957,7 +963,7 @@ panvk_reset_cmdbuf(struct panvk_cmd_buffer *cmdbuf) cmdbuf->status = PANVK_CMD_BUFFER_STATUS_INITIAL; for (unsigned i = 0; i < MAX_BIND_POINTS; i++) - memset(&cmdbuf->descriptors[i].sets, 0, sizeof(cmdbuf->descriptors[i].sets)); + memset(&cmdbuf->bind_points[i].desc_state.sets, 0, sizeof(cmdbuf->bind_points[0].desc_state.sets)); return cmdbuf->record_result; }