panvk: Implement CmdBindVertexBuffers2()

The vk runtime has a helper to help us with the strides, we just
need to use vi_binding_strides[] when emitting the attributes.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Olivia Lee <benjamin.lee@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34696>
This commit is contained in:
Boris Brezillon 2025-04-22 17:25:02 +02:00
parent 1d11872828
commit e3cbb2c131
3 changed files with 43 additions and 30 deletions

View file

@ -48,12 +48,14 @@ emit_vs_attrib(struct panvk_cmd_buffer *cmdbuf,
uint32_t attrib_idx, uint32_t vb_desc_offset,
struct mali_attribute_packed *desc)
{
const struct vk_vertex_input_state *vi =
cmdbuf->vk.dynamic_graphics_state.vi;
const struct vk_dynamic_graphics_state *dyns =
&cmdbuf->vk.dynamic_graphics_state;
const struct vk_vertex_input_state *vi = dyns->vi;
const struct vk_vertex_attribute_state *attrib_info =
&vi->attributes[attrib_idx];
const struct vk_vertex_binding_state *buf_info =
&vi->bindings[attrib_info->binding];
const uint32_t stride = dyns->vi_binding_strides[attrib_info->binding];
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 = vb_desc_offset + attrib_info->binding;
@ -61,15 +63,13 @@ emit_vs_attrib(struct panvk_cmd_buffer *cmdbuf,
pan_pack(desc, ATTRIBUTE, cfg) {
cfg.offset = attrib_info->offset;
if (per_instance) {
cfg.offset +=
cmdbuf->state.gfx.sysvals.vs.base_instance * buf_info->stride;
}
if (per_instance)
cfg.offset += cmdbuf->state.gfx.sysvals.vs.base_instance * stride;
cfg.format = GENX(panfrost_format_from_pipe_format)(f)->hw;
cfg.table = 0;
cfg.buffer_index = buf_idx;
cfg.stride = buf_info->stride;
cfg.stride = stride;
if (!per_instance) {
/* Per-vertex */
cfg.attribute_type = MALI_ATTRIBUTE_TYPE_1D;
@ -117,17 +117,19 @@ prepare_vs_driver_set(struct panvk_cmd_buffer *cmdbuf)
struct panvk_shader_desc_state *vs_desc_state = &cmdbuf->state.gfx.vs.desc;
const struct panvk_shader *vs = cmdbuf->state.gfx.vs.shader;
const struct vk_vertex_input_state *vi =
cmdbuf->vk.dynamic_graphics_state.vi;
const struct vk_dynamic_graphics_state *dyns =
&cmdbuf->vk.dynamic_graphics_state;
const struct vk_vertex_input_state *vi = dyns->vi;
uint32_t vb_count = 0;
cmdbuf->state.gfx.vi.attribs_changing_on_base_instance = 0;
u_foreach_bit(i, vi->attributes_valid) {
const struct vk_vertex_binding_state *binding =
&vi->bindings[vi->attributes[i].binding];
const uint32_t stride =
dyns->vi_binding_strides[vi->attributes[i].binding];
if (binding->input_rate == VK_VERTEX_INPUT_RATE_INSTANCE &&
binding->stride != 0) {
if (binding->input_rate == VK_VERTEX_INPUT_RATE_INSTANCE && stride != 0) {
cmdbuf->state.gfx.vi.attribs_changing_on_base_instance |=
BITFIELD_BIT(i);
}
@ -2250,8 +2252,9 @@ panvk_cmd_draw_indirect(struct panvk_cmd_buffer *cmdbuf,
if (patch_attribs != 0) {
struct panvk_shader_desc_state *vs_desc_state =
&cmdbuf->state.gfx.vs.desc;
const struct vk_vertex_input_state *vi =
cmdbuf->vk.dynamic_graphics_state.vi;
const struct vk_dynamic_graphics_state *dyns =
&cmdbuf->vk.dynamic_graphics_state;
const struct vk_vertex_input_state *vi = dyns->vi;
cs_move64_to(b, vs_drv_set, vs_desc_state->driver_set.dev_addr);
@ -2261,8 +2264,8 @@ panvk_cmd_draw_indirect(struct panvk_cmd_buffer *cmdbuf,
u_foreach_bit(i, patch_attribs) {
const struct vk_vertex_attribute_state *attrib_info =
&vi->attributes[i];
const struct vk_vertex_binding_state *binding =
&vi->bindings[attrib_info->binding];
const uint32_t stride =
dyns->vi_binding_strides[attrib_info->binding];
cs_load32_to(b, attrib_offset, vs_drv_set,
pan_size(ATTRIBUTE) * i + (2 * sizeof(uint32_t)));
@ -2273,7 +2276,7 @@ panvk_cmd_draw_indirect(struct panvk_cmd_buffer *cmdbuf,
* is present. This is sub-optimal, but it's simple :-). */
cs_add32(b, multiplicand, cs_sr_reg32(b, IDVS, INSTANCE_OFFSET), 0);
for (uint32_t i = 31; i > 0; i--) {
uint32_t add = binding->stride << i;
uint32_t add = stride << i;
/* bit31 is the sign bit, so we don't need to subtract to
* check the presence of the bit. */
@ -2292,7 +2295,7 @@ panvk_cmd_draw_indirect(struct panvk_cmd_buffer *cmdbuf,
}
cs_if(b, MALI_CS_CONDITION_NEQUAL, multiplicand)
cs_add32(b, attrib_offset, attrib_offset, binding->stride);
cs_add32(b, attrib_offset, attrib_offset, stride);
cs_store32(b, attrib_offset, vs_drv_set,
pan_size(ATTRIBUTE) * i + (2 * sizeof(uint32_t)));

View file

@ -489,6 +489,7 @@ panvk_draw_prepare_varyings(struct panvk_cmd_buffer *cmdbuf,
static void
panvk_draw_emit_attrib_buf(const struct panvk_draw_data *draw,
const struct vk_vertex_binding_state *buf_info,
uint32_t stride,
const struct panvk_attrib_buf *buf,
struct mali_attribute_buffer_packed *desc)
{
@ -502,7 +503,7 @@ panvk_draw_emit_attrib_buf(const struct panvk_draw_data *draw,
if (draw->info.instance.count <= 1) {
pan_pack(desc, ATTRIBUTE_BUFFER, cfg) {
cfg.type = MALI_ATTRIBUTE_TYPE_1D;
cfg.stride = per_instance ? 0 : buf_info->stride;
cfg.stride = per_instance ? 0 : stride;
cfg.pointer = addr;
cfg.size = size;
}
@ -510,7 +511,7 @@ panvk_draw_emit_attrib_buf(const struct panvk_draw_data *draw,
pan_pack(desc, ATTRIBUTE_BUFFER, cfg) {
cfg.type = MALI_ATTRIBUTE_TYPE_1D_MODULUS;
cfg.divisor = draw->padded_vertex_count;
cfg.stride = buf_info->stride;
cfg.stride = stride;
cfg.pointer = addr;
cfg.size = size;
}
@ -527,7 +528,7 @@ panvk_draw_emit_attrib_buf(const struct panvk_draw_data *draw,
} else if (util_is_power_of_two_or_zero(divisor)) {
pan_pack(desc, ATTRIBUTE_BUFFER, cfg) {
cfg.type = MALI_ATTRIBUTE_TYPE_1D_POT_DIVISOR;
cfg.stride = buf_info->stride;
cfg.stride = stride;
cfg.pointer = addr;
cfg.size = size;
cfg.divisor_r = __builtin_ctz(divisor);
@ -538,7 +539,7 @@ panvk_draw_emit_attrib_buf(const struct panvk_draw_data *draw,
panfrost_compute_magic_divisor(divisor, &divisor_r, &divisor_e);
pan_pack(desc, ATTRIBUTE_BUFFER, cfg) {
cfg.type = MALI_ATTRIBUTE_TYPE_1D_NPOT_DIVISOR;
cfg.stride = buf_info->stride;
cfg.stride = stride;
cfg.pointer = addr;
cfg.size = size;
cfg.divisor_r = divisor_r;
@ -586,8 +587,9 @@ panvk_draw_prepare_vs_attribs(struct panvk_cmd_buffer *cmdbuf,
struct panvk_draw_data *draw)
{
const struct panvk_shader *vs = cmdbuf->state.gfx.vs.shader;
const struct vk_vertex_input_state *vi =
cmdbuf->vk.dynamic_graphics_state.vi;
const struct vk_dynamic_graphics_state *dyns =
&cmdbuf->vk.dynamic_graphics_state;
const struct vk_vertex_input_state *vi = dyns->vi;
unsigned num_imgs = vs->desc_info.others.count[PANVK_BIFROST_DESC_TABLE_IMG];
unsigned num_vs_attribs = util_last_bit(vi->attributes_valid);
unsigned num_vbs = util_last_bit(vi->bindings_valid);
@ -617,6 +619,7 @@ panvk_draw_prepare_vs_attribs(struct panvk_cmd_buffer *cmdbuf,
for (unsigned i = 0; i < num_vbs; i++) {
if (vi->bindings_valid & BITFIELD_BIT(i)) {
panvk_draw_emit_attrib_buf(draw, &vi->bindings[i],
dyns->vi_binding_strides[i],
&cmdbuf->state.gfx.vb.bufs[i],
&attrib_buf_descs[i * 2]);
} else {

View file

@ -809,23 +809,30 @@ panvk_per_arch(cmd_prepare_draw_sysvals)(struct panvk_cmd_buffer *cmdbuf,
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdBindVertexBuffers)(VkCommandBuffer commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer *pBuffers,
const VkDeviceSize *pOffsets)
panvk_per_arch(CmdBindVertexBuffers2)(VkCommandBuffer commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer *pBuffers,
const VkDeviceSize *pOffsets,
const VkDeviceSize *pSizes,
const VkDeviceSize *pStrides)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
assert(firstBinding + bindingCount <= MAX_VBS);
if (pStrides) {
vk_cmd_set_vertex_binding_strides(&cmdbuf->vk, firstBinding,
bindingCount, pStrides);
}
for (uint32_t i = 0; i < bindingCount; i++) {
VK_FROM_HANDLE(panvk_buffer, buffer, pBuffers[i]);
cmdbuf->state.gfx.vb.bufs[firstBinding + i].address =
panvk_buffer_gpu_ptr(buffer, pOffsets[i]);
cmdbuf->state.gfx.vb.bufs[firstBinding + i].size =
panvk_buffer_range(buffer, pOffsets[i], VK_WHOLE_SIZE);
cmdbuf->state.gfx.vb.bufs[firstBinding + i].size = panvk_buffer_range(
buffer, pOffsets[i], pSizes ? pSizes[i] : VK_WHOLE_SIZE);
}
cmdbuf->state.gfx.vb.count =