diff --git a/src/panfrost/vulkan/panvk_pipeline.h b/src/panfrost/vulkan/panvk_pipeline.h index 00cc5795f09..08555b97f5f 100644 --- a/src/panfrost/vulkan/panvk_pipeline.h +++ b/src/panfrost/vulkan/panvk_pipeline.h @@ -25,25 +25,6 @@ #define MAX_RTS 8 -struct panvk_attrib_info { - unsigned buf; - unsigned offset; - enum pipe_format format; -}; - -struct panvk_attrib_buf_info { - unsigned stride; - bool per_instance; - uint32_t instance_divisor; -}; - -struct panvk_attribs_info { - struct panvk_attrib_info attrib[PAN_MAX_ATTRIBUTE]; - unsigned attrib_count; - struct panvk_attrib_buf_info buf[PAN_MAX_ATTRIBUTE]; - unsigned buf_count; -}; - enum panvk_pipeline_type { PANVK_PIPELINE_GRAPHICS, PANVK_PIPELINE_COMPUTE, @@ -78,7 +59,6 @@ struct panvk_graphics_pipeline { struct { struct { - struct panvk_attribs_info attribs; bool writes_point_size; } vs; diff --git a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c index e2886dfd4cf..8956c30b9d1 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c @@ -825,23 +825,24 @@ panvk_prepare_img_attribs(struct panvk_cmd_buffer *cmdbuf, static void panvk_draw_emit_attrib_buf(const struct panvk_draw_info *draw, - const struct panvk_attrib_buf_info *buf_info, + const struct vk_vertex_binding_state *buf_info, const struct panvk_attrib_buf *buf, void *desc) { mali_ptr addr = buf->address & ~63ULL; unsigned size = buf->size + (buf->address & 63); - unsigned divisor = draw->padded_vertex_count * buf_info->instance_divisor; + unsigned divisor = draw->padded_vertex_count * buf_info->divisor; + bool per_instance = buf_info->input_rate == VK_VERTEX_INPUT_RATE_INSTANCE; void *buf_ext = desc + pan_size(ATTRIBUTE_BUFFER); /* TODO: support instanced arrays */ if (draw->instance_count <= 1) { pan_pack(desc, ATTRIBUTE_BUFFER, cfg) { cfg.type = MALI_ATTRIBUTE_TYPE_1D; - cfg.stride = buf_info->per_instance ? 0 : buf_info->stride; + cfg.stride = per_instance ? 0 : buf_info->stride; cfg.pointer = addr; cfg.size = size; } - } else if (!buf_info->per_instance) { + } else if (!per_instance) { pan_pack(desc, ATTRIBUTE_BUFFER, cfg) { cfg.type = MALI_ATTRIBUTE_TYPE_1D_MODULUS; cfg.divisor = draw->padded_vertex_count; @@ -882,7 +883,7 @@ panvk_draw_emit_attrib_buf(const struct panvk_draw_info *draw, pan_pack(buf_ext, ATTRIBUTE_BUFFER_CONTINUATION_NPOT, cfg) { cfg.divisor_numerator = divisor_num; - cfg.divisor = buf_info->instance_divisor; + cfg.divisor = buf_info->divisor; } buf_ext = NULL; @@ -895,19 +896,20 @@ panvk_draw_emit_attrib_buf(const struct panvk_draw_info *draw, static void panvk_draw_emit_attrib(const struct panvk_draw_info *draw, - const struct panvk_attrib_info *attrib_info, - const struct panvk_attrib_buf_info *buf_info, + const struct vk_vertex_attribute_state *attrib_info, + const struct vk_vertex_binding_state *buf_info, const struct panvk_attrib_buf *buf, void *desc) { - enum pipe_format f = attrib_info->format; - unsigned buf_idx = attrib_info->buf; + bool per_instance = buf_info->input_rate == VK_VERTEX_INPUT_RATE_INSTANCE; + enum pipe_format f = vk_format_to_pipe_format(attrib_info->format); + unsigned buf_idx = attrib_info->binding; pan_pack(desc, ATTRIBUTE, cfg) { cfg.buffer_index = buf_idx * 2; cfg.offset = attrib_info->offset + (buf->address & 63); cfg.offset_enable = true; - if (buf_info->per_instance) + if (per_instance) cfg.offset += draw->first_instance * buf_info->stride; cfg.format = GENX(panfrost_format_from_pipe_format)(f)->hw; @@ -920,18 +922,27 @@ panvk_draw_prepare_vs_attribs(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; + 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; - unsigned num_vs_attribs = pipeline->state.vs.attribs.attrib_count; + unsigned num_vs_attribs = util_last_bit(vi->attributes_valid); + unsigned num_vbs = util_last_bit(vi->bindings_valid); unsigned attrib_count = num_imgs ? MAX_VS_ATTRIBS + num_imgs : num_vs_attribs; + bool dirty = + is_dirty(cmdbuf, VI) || is_dirty(cmdbuf, VI_BINDINGS_VALID) || + is_dirty(cmdbuf, VI_BINDING_STRIDES) || + (num_imgs && !desc_state->img.attribs) || + (cmdbuf->state.gfx.vb.count && !cmdbuf->state.gfx.vs.attrib_bufs) || + (attrib_count && !cmdbuf->state.gfx.vs.attribs); - if (cmdbuf->state.gfx.vs.attribs || !attrib_count) + if (!dirty) return; - unsigned attrib_buf_count = pipeline->state.vs.attribs.buf_count * 2; + unsigned attrib_buf_count = (num_vbs + num_imgs) * 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; @@ -939,19 +950,25 @@ 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->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 < num_vbs; i++) { + if (vi->bindings_valid & BITFIELD_BIT(i)) { + panvk_draw_emit_attrib_buf(draw, &vi->bindings[i], + &cmdbuf->state.gfx.vb.bufs[i], + &attrib_buf_descs[i * 2]); + } else { + memset(&attrib_buf_descs[i * 2], 0, sizeof(*attrib_buf_descs) * 2); + } } for (unsigned i = 0; i < num_vs_attribs; i++) { - unsigned buf_idx = pipeline->state.vs.attribs.attrib[i].buf; - - 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 (vi->attributes_valid & BITFIELD_BIT(i)) { + unsigned buf_idx = vi->attributes[i].binding; + panvk_draw_emit_attrib( + draw, &vi->attributes[i], &vi->bindings[buf_idx], + &cmdbuf->state.gfx.vb.bufs[buf_idx], &attrib_descs[i]); + } else { + memset(&attrib_descs[i], 0, sizeof(attrib_descs[0])); + } } if (num_imgs) { @@ -960,16 +977,14 @@ panvk_draw_prepare_vs_attribs(struct panvk_cmd_buffer *cmdbuf, * attributes. Buffers are tightly packed since they don't interfere with * the vertex shader. */ - unsigned bufs_offset = - pipeline->state.vs.attribs.buf_count * pan_size(ATTRIBUTE_BUFFER) * 2; unsigned attribs_offset = MAX_VS_ATTRIBS * pan_size(ATTRIBUTE); + unsigned bufs_offset = num_vbs * pan_size(ATTRIBUTE_BUFFER) * 2; memset(attribs.cpu + num_vs_attribs * pan_size(ATTRIBUTE), 0, (MAX_VS_ATTRIBS - num_vs_attribs) * pan_size(ATTRIBUTE)); panvk_fill_img_attribs(cmdbuf, desc_state, &pipeline->base, bufs.cpu + bufs_offset, - attribs.cpu + attribs_offset, - pipeline->state.vs.attribs.buf_count * 2); + attribs.cpu + attribs_offset, num_vbs * 2); desc_state->img.attrib_bufs = bufs.gpu + bufs_offset; desc_state->img.attribs = attribs.gpu + attribs_offset; } @@ -1997,7 +2012,7 @@ panvk_per_arch(CmdBindVertexBuffers)(VkCommandBuffer commandBuffer, cmdbuf->state.gfx.vb.count = MAX2(cmdbuf->state.gfx.vb.count, firstBinding + bindingCount); - cmdbuf->state.gfx.vs.attrib_bufs = cmdbuf->state.gfx.vs.attribs = 0; + cmdbuf->state.gfx.vs.attrib_bufs = 0; } VKAPI_ATTR void VKAPI_CALL @@ -2136,8 +2151,6 @@ panvk_per_arch(CmdBindDescriptorSets)( descriptors_state->dyn_desc_ubo = 0; descriptors_state->img.attrib_bufs = 0; descriptors_state->img.attribs = 0; - cmdbuf->state.gfx.vs.attribs = 0; - cmdbuf->state.gfx.vs.attrib_bufs = 0; assert(dynoffset_idx == dynamicOffsetCount); } @@ -2259,8 +2272,6 @@ panvk_cmd_push_descriptors(struct panvk_cmd_buffer *cmdbuf, desc_state->samplers = 0; desc_state->img.attrib_bufs = 0; desc_state->img.attribs = 0; - cmdbuf->state.gfx.vs.attrib_bufs = 0; - cmdbuf->state.gfx.vs.attribs = 0; return desc_state->push_sets[set]; } diff --git a/src/panfrost/vulkan/panvk_vX_pipeline.c b/src/panfrost/vulkan/panvk_vX_pipeline.c index 93d20cb5ab3..d8094b1d886 100644 --- a/src/panfrost/vulkan/panvk_vX_pipeline.c +++ b/src/panfrost/vulkan/panvk_vX_pipeline.c @@ -693,40 +693,6 @@ collect_varyings(struct panvk_graphics_pipeline *pipeline, } } -static void -parse_vertex_input(struct panvk_graphics_pipeline *pipeline, - const struct vk_graphics_pipeline_state *state, - struct panvk_shader **shaders) -{ - struct panvk_attribs_info *attribs = &pipeline->state.vs.attribs; - const struct vk_vertex_input_state *vi = state->vi; - - attribs->buf_count = util_last_bit(vi->bindings_valid); - for (unsigned i = 0; i < attribs->buf_count; i++) { - if (!(vi->bindings_valid & BITFIELD_BIT(i))) - continue; - - const struct vk_vertex_binding_state *desc = &vi->bindings[i]; - - attribs->buf[i].stride = desc->stride; - attribs->buf[i].per_instance = - desc->input_rate == VK_VERTEX_INPUT_RATE_INSTANCE; - attribs->buf[i].instance_divisor = desc->divisor; - } - - attribs->attrib_count = util_last_bit(vi->attributes_valid); - for (unsigned i = 0; i < attribs->attrib_count; i++) { - if (!(vi->attributes_valid & BITFIELD_BIT(i))) - continue; - - const struct vk_vertex_attribute_state *desc = &vi->attributes[i]; - - attribs->attrib[i].buf = desc->binding; - attribs->attrib[i].format = vk_format_to_pipe_format(desc->format); - attribs->attrib[i].offset = desc->offset; - } -} - static VkResult panvk_graphics_pipeline_create(struct panvk_device *dev, struct vk_pipeline_cache *cache, @@ -770,7 +736,6 @@ panvk_graphics_pipeline_create(struct panvk_device *dev, compile_shaders(&gfx_pipeline->base, create_info->pStages, create_info->stageCount, alloc, shaders); collect_varyings(gfx_pipeline, shaders); - parse_vertex_input(gfx_pipeline, &state, shaders); init_fs_state(gfx_pipeline, &state, shaders[MESA_SHADER_FRAGMENT]); init_shaders(&gfx_pipeline->base, create_info, &state, shaders);