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 <boris.brezillon@collabora.com>
Reviewed-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13077>
This commit is contained in:
Boris Brezillon 2021-09-16 12:51:46 +02:00 committed by Marge Bot
parent 5360e6240d
commit 20fe252664
3 changed files with 74 additions and 56 deletions

View file

@ -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

View file

@ -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);

View file

@ -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;
}