tests: Test sample locations
diff --git a/tests/unit/pipeline_positive.cpp b/tests/unit/pipeline_positive.cpp
index d2385dc..60dee7d 100644
--- a/tests/unit/pipeline_positive.cpp
+++ b/tests/unit/pipeline_positive.cpp
@@ -1951,3 +1951,105 @@
pipe.Destroy();
}
}
+
+TEST_F(PositivePipeline, SampleLocations) {
+ SetTargetApiVersion(VK_API_VERSION_1_1);
+ AddRequiredExtensions(VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME);
+ RETURN_IF_SKIP(Init());
+
+ VkMultisamplePropertiesEXT multisample_prop = vku::InitStructHelper();
+ vk::GetPhysicalDeviceMultisamplePropertiesEXT(Gpu(), VK_SAMPLE_COUNT_4_BIT, &multisample_prop);
+
+ if (multisample_prop.maxSampleLocationGridSize.width == 0 || multisample_prop.maxSampleLocationGridSize.height == 0) {
+ GTEST_SKIP() << "multisample properties are not supported";
+ }
+
+ VkImageCreateInfo image_ci = vku::InitStructHelper();
+ image_ci.imageType = VK_IMAGE_TYPE_2D;
+ image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
+ image_ci.extent = {32u, 32u, 1u};
+ image_ci.mipLevels = 1u;
+ image_ci.arrayLayers = 1u;
+ image_ci.samples = VK_SAMPLE_COUNT_4_BIT;
+ image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
+ image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+ image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ vkt::Image ms_image(*m_device, image_ci);
+ vkt::ImageView ms_image_view = ms_image.CreateView();
+
+ image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
+ vkt::Image resolve_image(*m_device, image_ci);
+ vkt::ImageView resolve_image_view = resolve_image.CreateView();
+
+ VkClearValue clear_value = {m_clear_color};
+
+ RenderPassSingleSubpass render_pass(*this);
+ render_pass.AddAttachmentDescription(VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_4_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ render_pass.AddAttachmentDescription(VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ render_pass.AddAttachmentReference({0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL});
+ render_pass.AddAttachmentReference({1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL});
+ render_pass.AddColorAttachment(0);
+ render_pass.AddResolveAttachment(1);
+ render_pass.CreateRenderPass();
+
+ VkImageView image_views[2] = {ms_image_view.handle(), resolve_image_view.handle()};
+ vkt::Framebuffer framebuffer(*m_device, render_pass, 2u, image_views);
+
+ std::vector<VkSampleLocationEXT> sample_location(4u, {0.5f, 0.5f});
+ VkSampleLocationsInfoEXT sample_locations_info = vku::InitStructHelper();
+ sample_locations_info.sampleLocationsPerPixel = VK_SAMPLE_COUNT_4_BIT;
+ sample_locations_info.sampleLocationGridSize = {1u, 1u};
+ sample_locations_info.sampleLocationsCount = 4u;
+ sample_locations_info.pSampleLocations = sample_location.data();
+
+ VkPipelineSampleLocationsStateCreateInfoEXT sample_locations_state = vku::InitStructHelper();
+ sample_locations_state.sampleLocationsEnable = VK_TRUE;
+ sample_locations_state.sampleLocationsInfo = sample_locations_info;
+
+ VkPipelineMultisampleStateCreateInfo multi_sample_state = vku::InitStructHelper(&sample_locations_state);
+ multi_sample_state.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
+ multi_sample_state.sampleShadingEnable = VK_FALSE;
+ multi_sample_state.minSampleShading = 1.0f;
+
+ VkPipelineRenderingCreateInfo pipeline_rendering_ci = vku::InitStructHelper();
+ pipeline_rendering_ci.colorAttachmentCount = 1u;
+ pipeline_rendering_ci.pColorAttachmentFormats = &image_ci.format;
+
+ CreatePipelineHelper pipe(*this, &pipeline_rendering_ci);
+ pipe.gp_ci_.pMultisampleState = &multi_sample_state;
+ pipe.gp_ci_.renderPass = render_pass;
+ pipe.CreateGraphicsPipeline();
+
+ VkAttachmentSampleLocationsEXT initial_location;
+ initial_location.attachmentIndex = 0u;
+ initial_location.sampleLocationsInfo = sample_locations_info;
+
+ VkSubpassSampleLocationsEXT subpass_sample_locations;
+ subpass_sample_locations.subpassIndex = 0u;
+ subpass_sample_locations.sampleLocationsInfo = sample_locations_info;
+
+ m_command_buffer.Begin();
+
+ VkRenderPassSampleLocationsBeginInfoEXT sample_locations_begin_info = vku::InitStructHelper();
+ sample_locations_begin_info.attachmentInitialSampleLocationsCount = 1u;
+ sample_locations_begin_info.pAttachmentInitialSampleLocations = &initial_location;
+ sample_locations_begin_info.postSubpassSampleLocationsCount = 1u;
+ sample_locations_begin_info.pPostSubpassSampleLocations = &subpass_sample_locations;
+
+ VkRenderPassBeginInfo render_pass_begin_info = vku::InitStructHelper(&sample_locations_begin_info);
+ render_pass_begin_info.renderPass = render_pass;
+ render_pass_begin_info.framebuffer = framebuffer;
+ render_pass_begin_info.renderArea = {{0, 0}, {32u, 32u}};
+ render_pass_begin_info.clearValueCount = 1u;
+ render_pass_begin_info.pClearValues = &clear_value;
+
+ vk::CmdBeginRenderPass(m_command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);
+ sample_locations_begin_info = {};
+
+ vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
+ vk::CmdDraw(m_command_buffer, 4u, 1u, 0u, 0u);
+ vk::CmdEndRenderPass(m_command_buffer);
+ m_command_buffer.End();
+}