anv: fix push descriptor deferred surface state packing
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Sun, 21 May 2023 12:19:56 +0000 (15:19 +0300)
committerMarge Bot <emma+marge@anholt.net>
Mon, 22 May 2023 10:50:26 +0000 (10:50 +0000)
Yuzu is running into a segfault because it writes the push descriptor
twice with 2 different layouts, but without a draw/dispatch in
between.

First vkCmdPushDescriptorSetKHR() writes descriptor 0 & 1 with a
uniform buffer. We toggle the 2 first bits of
anv_descriptor_set::generate_surface_states.

Second vkCmdPushDescriptorSetKHR() writes descriptor 0 with uniform
buffer and descriptor 1 with an image view. The first bit of
anv_descriptor_set::generate_surface_states stays, but the second bit
was already set before and it should now be off.

When we finally flush the push descriptor, we try to generate a
surface state for descriptor 1, but there is no valid buffer view for
it, we access an invalid pointer and segfault.

This fix resets the anv_descriptor_set::generate_surface_states when
the descriptor layout changes.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: b49b18f0b7 ("anv: reduce BT emissions & surface state writes with push descriptors")
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23156>

src/intel/vulkan/anv_cmd_buffer.c

index 05efe15..eb75f0a 100644 (file)
@@ -927,6 +927,7 @@ anv_cmd_buffer_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
          anv_descriptor_set_layout_unref(cmd_buffer->device, set->layout);
       anv_descriptor_set_layout_ref(layout);
       set->layout = layout;
+      set->generate_surface_states = 0;
    }
    set->is_push = true;
    set->size = anv_descriptor_set_layout_size(layout, false /* host_only */, 0);