From b4b7b4764f75ab0c1446a317947cb56b85f001ef Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Date: Thu, 24 Oct 2024 11:01:28 +0300 Subject: [PATCH 1/2] framework: add a way to enable descriptor_indexing Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> --- include/tapi/t_def.h | 2 ++ src/framework/test/t_phase_setup.c | 49 ++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/include/tapi/t_def.h b/include/tapi/t_def.h index bcba61df..4d37bb1d 100644 --- a/include/tapi/t_def.h +++ b/include/tapi/t_def.h @@ -93,6 +93,8 @@ struct test_def { const bool robust_image_access; + const bool descriptor_indexing; + /// \brief Private data for the test framework. /// /// Test authors shouldn't touch this struct. diff --git a/src/framework/test/t_phase_setup.c b/src/framework/test/t_phase_setup.c index ba54f8ab..95233dd9 100644 --- a/src/framework/test/t_phase_setup.c +++ b/src/framework/test/t_phase_setup.c @@ -317,7 +317,9 @@ t_setup_descriptor_pool(void) const VkDescriptorPoolCreateInfo create_info = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .pNext = NULL, - .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, + .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT | + (t->def->descriptor_indexing ? + VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT : 0), .maxSets = 8, .poolSizeCount = ARRAY_LENGTH(pool_sizes), .pPoolSizes = pool_sizes @@ -365,6 +367,15 @@ static VkBool32 debug_cb(VkDebugReportFlagsEXT flags, return false; } +static void +add_pnext(void *_prev, void *_next) +{ + VkBaseInStructure *prev = _prev, *next = _next; + while (prev->pNext != NULL) + prev = (VkBaseInStructure *) prev->pNext; + prev->pNext = next; +} + void t_setup_vulkan(void) { @@ -589,9 +600,13 @@ t_setup_vulkan(void) VkPhysicalDeviceRobustness2FeaturesEXT pdr2f = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT, }; + VkPhysicalDeviceDescriptorIndexingFeatures pddif = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, + .pNext = &pdr2f, + }; VkPhysicalDeviceFeatures2 pdf2 = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, - .pNext = &pdr2f, + .pNext = &pddif, }; vkGetPhysicalDeviceFeatures2(t->vk.physical_dev, &pdf2); @@ -599,19 +614,29 @@ t_setup_vulkan(void) t_skipf("Test requested robust image access, " "but implementation does not support robustImageAccess2"); + pdr2f.robustImageAccess2 = pdr2f.robustImageAccess2 && t->def->robust_image_access; - res = vkCreateDevice(t->vk.physical_dev, - &(VkDeviceCreateInfo) { - .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .queueCreateInfoCount = t->vk.queue_family_count, - .pQueueCreateInfos = qci, - .enabledExtensionCount = t->vk.device_extension_count, - .ppEnabledExtensionNames = ext_names, - .pEnabledFeatures = &pdf, - .pNext = t->def->robust_image_access ? &pdr2f : NULL, - }, NULL, &t->vk.device); + VkDeviceCreateInfo dci = { + .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .queueCreateInfoCount = t->vk.queue_family_count, + .pQueueCreateInfos = qci, + .enabledExtensionCount = t->vk.device_extension_count, + .ppEnabledExtensionNames = ext_names, + .pEnabledFeatures = &pdf, + }; + + if (t->def->robust_image_access) { + pdr2f.pNext = NULL; + add_pnext(&dci, &pdr2f); + } + if (t->def->descriptor_indexing) { + pddif.pNext = NULL; + add_pnext(&dci, &pddif); + } + + res = vkCreateDevice(t->vk.physical_dev, &dci, NULL, &t->vk.device); free(qci); free(ext_names); free(priorities); -- GitLab From 38d1afc18e3ee8423551c585433559ece466534d Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Date: Thu, 24 Oct 2024 10:31:08 +0300 Subject: [PATCH 2/2] Add test for gitlab issue 12058 Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> --- src/tests/bug/gitlab-12058.c | 229 +++++++++++++++++++++++++++++++++++ src/tests/meson.build | 1 + 2 files changed, 230 insertions(+) create mode 100644 src/tests/bug/gitlab-12058.c diff --git a/src/tests/bug/gitlab-12058.c b/src/tests/bug/gitlab-12058.c new file mode 100644 index 00000000..bcdc5f9e --- /dev/null +++ b/src/tests/bug/gitlab-12058.c @@ -0,0 +1,229 @@ +// Copyright 2024 Intel Corporation +// SPDX-License-Identifier: MIT + +/* This is a test for https://gitlab.freedesktop.org/mesa/mesa/-/issues/12058 + * + * The issue is rather involved and only reproduces on DG2+. + * + * Push constants buffers allocated internally in the driver are bounded + * (lowest offset, highest offset) using the shader usage. Between 2 pipelines + * bound with different push constant layouts, if there is no push constant + * update (or other events updating the push constant buffer like descriptor + * binding, base workgroup offset, etc...), the push constant buffer is not + * reallocated missing that a new pipeline has been bound with a different + * push constant layout that would require a new reallocation to adjust for + * the new lowest offset access. + * + * Here we force the UPDATE_AFTER_BIND_BIT to ensure the driver access a part + * of the push constant buffers for descriptors and we have 2 pipelines with + * no push constant access and the other with push constant accesses. We bind + * the first pipeline so that the computed push constant buffer bounds are + * smaller than what the second pipeline will need. + */ + +#include "tapi/t.h" + +#include "src/tests/bug/gitlab-12058-spirv.h" + +static void +test(void) +{ + t_require_ext("VK_EXT_descriptor_indexing"); + + VkDescriptorBindingFlags binding_flags = + VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT; + VkDescriptorSetLayoutBindingFlagsCreateInfo binding_flags_info = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, + .bindingCount = 1, + .pBindingFlags = &binding_flags, + }; + + VkDescriptorSetLayout set_layout; + + set_layout = qoCreateDescriptorSetLayout( + t_device, + .pNext = &binding_flags_info, + .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, + .bindingCount = 1, + .pBindings = (VkDescriptorSetLayoutBinding[]) { + { + .binding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, + .pImmutableSamplers = NULL, + }, + }); + + VkPipelineLayout pipeline_layout = qoCreatePipelineLayout( + t_device, + .setLayoutCount = 1, + .pSetLayouts = &set_layout, + .pushConstantRangeCount = 1, + .pPushConstantRanges = &(VkPushConstantRange) { + .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, + .offset = 0, + .size = 128, + }); + + VkShaderModule cs1 = qoCreateShaderModuleGLSL( + t_device, COMPUTE, + + layout(push_constant) uniform Push { + uint data0; + }; + layout(set = 0, binding = 0) buffer Storage { + uint storage[]; + }; + + void main() + { + storage[0] = 42; + } + ); + VkShaderModule cs2 = qoCreateShaderModuleGLSL( + t_device, COMPUTE, + + layout(push_constant) uniform Push { + uint data0; + } push; + layout(set = 0, binding = 0) buffer Storage { + uint storage[]; + }; + + void main() + { + storage[1] = push.data0; + } + ); + + VkPipeline pipeline1; + VkResult result = vkCreateComputePipelines(t_device, t_pipeline_cache, 1, + &(VkComputePipelineCreateInfo) { + .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, + .pNext = NULL, + .stage = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_COMPUTE_BIT, + .module = cs1, + .pName = "main", + }, + .flags = 0, + .layout = pipeline_layout + }, NULL, &pipeline1); + t_assert(result == VK_SUCCESS); + t_cleanup_push_vk_pipeline(t_device, pipeline1); + + VkPipeline pipeline2; + result = vkCreateComputePipelines(t_device, t_pipeline_cache, 1, + &(VkComputePipelineCreateInfo) { + .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, + .pNext = NULL, + .stage = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_COMPUTE_BIT, + .module = cs2, + .pName = "main", + }, + .flags = 0, + .layout = pipeline_layout + }, NULL, &pipeline2); + t_assert(result == VK_SUCCESS); + t_cleanup_push_vk_pipeline(t_device, pipeline2); + + VkDescriptorSet set = + qoAllocateDescriptorSet(t_device, + .descriptorPool = t_descriptor_pool, + .pSetLayouts = &set_layout); + + VkBuffer buffer = qoCreateBuffer(t_device, + .size = 1024, + .usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + + VkDeviceMemory mem = qoAllocBufferMemory(t_device, buffer, + .properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + t_cleanup_push_vk_device_memory(t_device, mem); + + qoBindBufferMemory(t_device, buffer, mem, 0); + + vkUpdateDescriptorSets(t_device, + /*writeCount*/ 1, + (VkWriteDescriptorSet[]) { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = set, + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .pBufferInfo = &(VkDescriptorBufferInfo) { + .buffer = buffer, + .offset = 0, + .range = VK_WHOLE_SIZE, + }, + }, + }, 0, NULL); + + uint32_t data; + + data = 43; + vkCmdPushConstants(t_cmd_buffer, pipeline_layout, + VK_SHADER_STAGE_COMPUTE_BIT, + 0, sizeof(data), &data); + + vkCmdBindDescriptorSets(t_cmd_buffer, + VK_PIPELINE_BIND_POINT_COMPUTE, + pipeline_layout, 0, 1, + &set, 0, NULL); + + vkCmdPipelineBarrier(t_cmd_buffer, + VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + 0, 0, NULL, + 1, &(VkBufferMemoryBarrier) { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .srcAccessMask = 0, + .dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT, + .buffer = buffer, + .offset = 0, + .size = VK_WHOLE_SIZE, + }, + 0, NULL); + + vkCmdBindPipeline(t_cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline1); + vkCmdDispatch(t_cmd_buffer, 1, 1, 1); + vkCmdBindPipeline(t_cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline2); + vkCmdDispatch(t_cmd_buffer, 1, 1, 1); + + vkCmdPipelineBarrier(t_cmd_buffer, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_HOST_BIT, + 0, 0, NULL, + 1, &(VkBufferMemoryBarrier) { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_HOST_READ_BIT, + .buffer = buffer, + .offset = 0, + .size = VK_WHOLE_SIZE, + }, + 0, NULL); + + qoEndCommandBuffer(t_cmd_buffer); + qoQueueSubmit(t_queue, 1, &t_cmd_buffer, VK_NULL_HANDLE); + + qoQueueWaitIdle(t_queue); + + uint32_t *ssbo_data = qoMapMemory(t_device, mem, 0, VK_WHOLE_SIZE, 0); + + t_assert(ssbo_data[0] == 42); + t_assert(ssbo_data[1] == 43); +} + +test_define { + .name = "bug.gitlab-12058", + .start = test, + .no_image = true, + .queue_setup = QUEUE_SETUP_COMPUTE, + .descriptor_indexing = true, +}; diff --git a/src/tests/meson.build b/src/tests/meson.build index 5196d4e1..8299c0c7 100644 --- a/src/tests/meson.build +++ b/src/tests/meson.build @@ -55,6 +55,7 @@ test_sources_with_spirv = [ 'bug/gitlab-6680.c', 'bug/gitlab-9013.c', 'bug/gitlab-11800.c', + 'bug/gitlab-12058.c', 'func/4-vertex-buffers.c', 'func/depthstencil/basic.c', 'func/depthstencil/arrayed-clear.c', -- GitLab