From da0a4e7d8856a859ebbdaa34bb25926f63bb2d08 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Fri, 13 Mar 2020 17:36:41 -0500 Subject: Add a targeted test for mesa/mesa#2623 https://gitlab.freedesktop.org/mesa/mesa/issues/2623 Reviewed-by: Lionel Landwerlin --- Makefile.am | 2 + src/tests/func/ubo/robust-push-ubo.c | 276 +++++++++++++++++++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100644 src/tests/func/ubo/robust-push-ubo.c diff --git a/Makefile.am b/Makefile.am index af16252..ec13108 100644 --- a/Makefile.am +++ b/Makefile.am @@ -122,6 +122,7 @@ bin_crucible_SOURCES = \ src/tests/func/ssbo/interleave.c \ src/tests/func/sync/semaphore-fd.c \ src/tests/func/renderpass/clear.c \ + src/tests/func/ubo/robust-push-ubo.c \ src/tests/stress/lots-of-surface-state.c \ src/tests/stress/buffer_limit.c \ src/tests/self/concurrent-output.c \ @@ -177,6 +178,7 @@ BUILT_SOURCES = \ src/tests/func/shader_group_vote/ext_shader_subgroup_vote-spirv.h \ src/tests/func/ssbo/interleave-spirv.h \ src/tests/func/sync/semaphore-fd-spirv.h \ + src/tests/func/ubo/robust-push-ubo-spirv.h \ src/tests/stress/lots-of-surface-state-spirv.h bin_crucible_LDADD = $(MESA_LDFLAGS) -lm -lvulkan -lpthread $(libpng_LIBS) \ diff --git a/src/tests/func/ubo/robust-push-ubo.c b/src/tests/func/ubo/robust-push-ubo.c new file mode 100644 index 0000000..f422339 --- /dev/null +++ b/src/tests/func/ubo/robust-push-ubo.c @@ -0,0 +1,276 @@ +// Copyright 2015 Intel Corporation +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice (including the next +// paragraph) shall be included in all copies or substantial portions of the +// Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "tapi/t.h" +#include "util/misc.h" + +#include "robust-push-ubo-spirv.h" + +#define UBO_PAD_SIZE (4 * 4 * 15) +#define UBO_BIND_SIZE (UBO_PAD_SIZE + 4 * 4) + +static VkPipeline +create_pipeline(VkDevice device, VkPipelineLayout pipeline_layout) +{ + VkShaderModule vs = qoCreateShaderModuleGLSL(t_device, VERTEX, + void main() + { + vec2 pos = vec2(float(gl_VertexIndex & 1), + float(gl_VertexIndex >> 1)); + gl_Position = vec4(vec2(-1) + 2 * pos, 0.0f, 1.0f); + } + ); + + VkShaderModule fs = qoCreateShaderModuleGLSL(t_device, FRAGMENT, + layout(location = 0) out vec4 f_color; + + layout(set = 0, binding = 0) uniform block1 { + // Ensure that the two colors are in different 32B blocks + vec4 pad[15]; + vec4 color1; + vec4 color2; + } u; + + void main() + { + f_color = u.color1 + u.color2; + } + ); + + VkPipelineVertexInputStateCreateInfo vi_create_info = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = 0, + .pVertexBindingDescriptions = NULL, + .vertexAttributeDescriptionCount = 0, + .pVertexAttributeDescriptions = NULL, + }; + + return qoCreateGraphicsPipeline(t_device, t_pipeline_cache, + &(QoExtraGraphicsPipelineCreateInfo) { + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + .vertexShader = vs, + .fragmentShader = fs, + .pNext = + &(VkGraphicsPipelineCreateInfo) { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .pVertexInputState = &vi_create_info, + .flags = 0, + .layout = pipeline_layout, + .renderPass = t_render_pass, + .subpass = 0, + }}); +} + +static VkBuffer +create_buffer(uint32_t bind_offset) +{ + const VkDeviceSize buffer_size = 4096; + const VkDeviceSize ubo_align = + t_physical_dev_props->limits.minUniformBufferOffsetAlignment; + assert(bind_offset % ubo_align == 0); + + VkBuffer buffer = qoCreateBuffer(t_device, .size = buffer_size); + + VkDeviceMemory mem = qoAllocBufferMemory(t_device, buffer, + .properties = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + + qoBindBufferMemory(t_device, buffer, mem, /*offset*/ 0); + + void *map = qoMapMemory(t_device, mem, /*offset*/ 0, + buffer_size, /*flags*/ 0); + + uint32_t offset = 0; + + assert(offset + bind_offset <= buffer_size); + memset(map + offset, 0, bind_offset); + offset += bind_offset; + + assert(offset + UBO_PAD_SIZE <= buffer_size); + memset(map + offset, 0, UBO_PAD_SIZE); + offset += UBO_PAD_SIZE; + + const float colors[8] = { + 0.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 0.0f, 1.0f, + }; + assert(offset + sizeof(colors) <= buffer_size); + memcpy(map + offset, colors, sizeof(colors)); + offset += sizeof(colors); + + return buffer; +} + +static void +test(void) +{ + const uint32_t bind_offset = 512; + + VkDescriptorSetLayout set_layout = qoCreateDescriptorSetLayout(t_device, + .bindingCount = 1, + .pBindings = (VkDescriptorSetLayoutBinding[]) { + { + .binding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + .pImmutableSamplers = NULL, + }, + }); + + VkPipelineLayout pipeline_layout = qoCreatePipelineLayout(t_device, + .setLayoutCount = 1, + .pSetLayouts = &set_layout); + + VkPipeline pipeline = create_pipeline(t_device, pipeline_layout); + + VkBuffer buffer = create_buffer(bind_offset); + + VkDescriptorSet set = qoAllocateDescriptorSet(t_device, + .descriptorPool = t_descriptor_pool, + .pSetLayouts = &set_layout); + + vkUpdateDescriptorSets(t_device, 1, /* writeCount */ + (VkWriteDescriptorSet[]) { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = set, + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .pBufferInfo = (VkDescriptorBufferInfo[]) { + { + .buffer = buffer, + .offset = bind_offset, + .range = UBO_BIND_SIZE, + } + }, + }, + }, 0, NULL); + + vkCmdBeginRenderPass(t_cmd_buffer, + &(VkRenderPassBeginInfo) { + .renderPass = t_render_pass, + .framebuffer = t_framebuffer, + .renderArea = { { 0, 0 }, { t_width, t_height } }, + .clearValueCount = 1, + .pClearValues = (VkClearValue[]) { + { .color = { .float32 = { 1.0, 0.0, 0.0, 1.0 } } }, + } + }, VK_SUBPASS_CONTENTS_INLINE); + + vkCmdBindPipeline(t_cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + vkCmdBindDescriptorSets(t_cmd_buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + pipeline_layout, 0, 1, + &set, 0, NULL); + vkCmdDraw(t_cmd_buffer, /*vertexCount*/ 4, /*instanceCount*/ 1, + /*firstVertex*/ 0, /*firstInstance*/ 0); + vkCmdEndRenderPass(t_cmd_buffer); + qoEndCommandBuffer(t_cmd_buffer); + qoQueueSubmit(t_queue, 1, &t_cmd_buffer, VK_NULL_HANDLE); +} + +test_define { + .name = "func.ubo.robust-push-ubo", + .start = test, + .image_filename = "32x32-green.ref.png", + .robust_buffer_access = true, +}; + +static void +test_dynamic(void) +{ + const uint32_t bind_offset = 512; + + VkDescriptorSetLayout set_layout = qoCreateDescriptorSetLayout(t_device, + .bindingCount = 1, + .pBindings = (VkDescriptorSetLayoutBinding[]) { + { + .binding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + .pImmutableSamplers = NULL, + }, + }); + + VkPipelineLayout pipeline_layout = qoCreatePipelineLayout(t_device, + .setLayoutCount = 1, + .pSetLayouts = &set_layout); + + VkPipeline pipeline = create_pipeline(t_device, pipeline_layout); + + VkBuffer buffer = create_buffer(bind_offset); + + VkDescriptorSet set = qoAllocateDescriptorSet(t_device, + .descriptorPool = t_descriptor_pool, + .pSetLayouts = &set_layout); + + vkUpdateDescriptorSets(t_device, 1, /* writeCount */ + (VkWriteDescriptorSet[]) { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = set, + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, + .pBufferInfo = (VkDescriptorBufferInfo[]) { + { + .buffer = buffer, + .offset = 0, + .range = UBO_BIND_SIZE, + } + }, + }, + }, 0, NULL); + + vkCmdBeginRenderPass(t_cmd_buffer, + &(VkRenderPassBeginInfo) { + .renderPass = t_render_pass, + .framebuffer = t_framebuffer, + .renderArea = { { 0, 0 }, { t_width, t_height } }, + .clearValueCount = 1, + .pClearValues = (VkClearValue[]) { + { .color = { .float32 = { 1.0, 0.0, 0.0, 1.0 } } }, + } + }, VK_SUBPASS_CONTENTS_INLINE); + + vkCmdBindPipeline(t_cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + vkCmdBindDescriptorSets(t_cmd_buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + pipeline_layout, 0, 1, + &set, 1, (uint32_t[]) { bind_offset }); + vkCmdDraw(t_cmd_buffer, /*vertexCount*/ 4, /*instanceCount*/ 1, + /*firstVertex*/ 0, /*firstInstance*/ 0); + vkCmdEndRenderPass(t_cmd_buffer); + qoEndCommandBuffer(t_cmd_buffer); + qoQueueSubmit(t_queue, 1, &t_cmd_buffer, VK_NULL_HANDLE); +} + +test_define { + .name = "func.ubo.robust-push-ubo-dynamic", + .start = test_dynamic, + .image_filename = "32x32-green.ref.png", + .robust_buffer_access = true, +}; -- cgit v1.2.3