| /* |
| * Copyright (c) 2026 The Khronos Group Inc. |
| * Copyright (c) 2026 Valve Corporation |
| * Copyright (c) 2026 LunarG, Inc. |
| * Copyright (C) 2026 Qualcomm Technologies, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| */ |
| |
| #include "layer_validation_tests.h" |
| #include "pipeline_helper.h" |
| #include "shader_object_helper.h" |
| |
| class NegativeTileShading : public TileShadingTest {}; |
| |
| TEST_F(NegativeTileShading, EndPerTileExecutionWithNonTileShadingRenderPass) { |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitRenderTarget(); |
| |
| VkPerTileEndInfoQCOM per_tile_end_info = vku::InitStructHelper(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBeginRenderPass(m_command_buffer, &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdEndPerTileExecutionQCOM-None-10666"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdEndPerTileExecutionQCOM-None-10667"); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndRenderPass(m_command_buffer); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, BeginPerTileExecutionWithNonTileShadingRenderPass) { |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitRenderTarget(); |
| |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBeginRenderPass(m_command_buffer, &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBeginPerTileExecutionQCOM-None-10664"); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndRenderPass(m_command_buffer); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, BeginPerTileExecutionButTileShadingPerTileFeatureNotEnabled) { |
| TEST_DESCRIPTION("Try to launch per-tile execution model in a tile-shading render pass scope, " |
| "but tileShadingPerTileDispatch or tileShadingPerTileDraw feature is not enabled."); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_QCOM_TILE_SHADING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::tileShading); |
| RETURN_IF_SKIP(Init()); |
| |
| InitTileShadingRenderTarget(); |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea.offset = {0, 0}; |
| rp_begin_info.renderArea.extent = tile_shading_rp_config.rt_size; |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_value; |
| |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBeginRenderPass(m_command_buffer, &rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBeginPerTileExecutionQCOM-None-10665"); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndRenderPass(m_command_buffer); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, RenderPassButTileShadingFeatureNotEnabled) { |
| TEST_DESCRIPTION("Try to create a tile-shading render pass, but tileShading feature is not enabled."); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_QCOM_TILE_SHADING_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| VkAttachmentDescription attachment_desc{}; |
| attachment_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference color_ref{}; |
| color_ref.attachment = 0; |
| color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkSubpassDescription subpass_desc{}; |
| subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass_desc.colorAttachmentCount = 1; |
| subpass_desc.pColorAttachments = &color_ref; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {0, 0}; |
| |
| VkRenderPassCreateInfo rp_ci = vku::InitStructHelper(&tile_shading_ci); |
| rp_ci.attachmentCount = 1; |
| rp_ci.pAttachments = &attachment_desc; |
| rp_ci.subpassCount = 1; |
| rp_ci.pSubpasses = &subpass_desc; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassTileShadingCreateInfoQCOM-tileShading-10658"); |
| VkRenderPass rp = VK_NULL_HANDLE; |
| vk::CreateRenderPass(device(), &rp_ci, nullptr, &rp); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeTileShading, NonZeroTileApronSizeButTileShadingApronFeatureNotEnabled) { |
| TEST_DESCRIPTION("Try to use non-zero tile-apron size when creates a render pass, but " |
| "tileShadingApron feature is not enabled."); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_QCOM_TILE_SHADING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::tileShading); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceTileShadingPropertiesQCOM tile_shading_props = vku::InitStructHelper(); |
| VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&tile_shading_props); |
| vk::GetPhysicalDeviceProperties2(Gpu(), &props2); |
| |
| VkAttachmentDescription attachment_desc{}; |
| attachment_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference color_ref{}; |
| color_ref.attachment = 0; |
| color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkSubpassDescription subpass_desc{}; |
| subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass_desc.colorAttachmentCount = 1; |
| subpass_desc.pColorAttachments = &color_ref; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {tile_shading_props.maxApronSize, tile_shading_props.maxApronSize}; |
| |
| VkRenderPassCreateInfo rp_ci = vku::InitStructHelper(&tile_shading_ci); |
| rp_ci.attachmentCount = 1; |
| rp_ci.pAttachments = &attachment_desc; |
| rp_ci.subpassCount = 1; |
| rp_ci.pSubpasses = &subpass_desc; |
| |
| VkRenderPass tile_shading_render_pass = VK_NULL_HANDLE; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassTileShadingCreateInfoQCOM-flags-10659"); |
| vk::CreateRenderPass(device(), &rp_ci, nullptr, &tile_shading_render_pass); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyRenderPass(device(), tile_shading_render_pass, nullptr); |
| } |
| |
| TEST_F(NegativeTileShading, AnisotropicApronSizeButTileShadingAnisotropicApronFeatureNotEnabled) { |
| TEST_DESCRIPTION("Try to use anisotropic apron size when creates a render pass, but " |
| "tileShadingAnisotropicApron feature is not enabled."); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_QCOM_TILE_SHADING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::tileShading); |
| AddRequiredFeature(vkt::Feature::tileShadingApron); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceTileShadingPropertiesQCOM tile_shading_props = vku::InitStructHelper(); |
| VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&tile_shading_props); |
| vk::GetPhysicalDeviceProperties2(Gpu(), &props2); |
| |
| VkAttachmentDescription attachment_desc{}; |
| attachment_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference color_ref{}; |
| color_ref.attachment = 0; |
| color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkSubpassDescription subpass_desc{}; |
| subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass_desc.colorAttachmentCount = 1; |
| subpass_desc.pColorAttachments = &color_ref; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {tile_shading_props.maxApronSize, std::max(tile_shading_props.maxApronSize - 1, 1U)}; |
| |
| VkRenderPassCreateInfo rp_ci = vku::InitStructHelper(&tile_shading_ci); |
| rp_ci.attachmentCount = 1; |
| rp_ci.pAttachments = &attachment_desc; |
| rp_ci.subpassCount = 1; |
| rp_ci.pSubpasses = &subpass_desc; |
| |
| VkRenderPass tile_shading_render_pass = VK_NULL_HANDLE; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassTileShadingCreateInfoQCOM-tileShadingAnisotropicApron-10661"); |
| vk::CreateRenderPass(device(), &rp_ci, nullptr, &tile_shading_render_pass); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyRenderPass(device(), tile_shading_render_pass, nullptr); |
| } |
| |
| TEST_F(NegativeTileShading, LargerTileApronSize) { |
| TEST_DESCRIPTION("Try to use tile apron size larger than maxApronSize when creates a render pass."); |
| AddRequiredFeature(vkt::Feature::tileShadingApron); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| |
| VkPhysicalDeviceTileShadingPropertiesQCOM tile_shading_props = vku::InitStructHelper(); |
| VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&tile_shading_props); |
| vk::GetPhysicalDeviceProperties2(Gpu(), &props2); |
| |
| VkAttachmentDescription attachment_desc{}; |
| attachment_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference color_ref{}; |
| color_ref.attachment = 0; |
| color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkSubpassDescription subpass_desc{}; |
| subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass_desc.colorAttachmentCount = 1; |
| subpass_desc.pColorAttachments = &color_ref; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {tile_shading_props.maxApronSize + 1, tile_shading_props.maxApronSize + 1}; |
| |
| VkRenderPassCreateInfo rp_ci = vku::InitStructHelper(&tile_shading_ci); |
| rp_ci.attachmentCount = 1; |
| rp_ci.pAttachments = &attachment_desc; |
| rp_ci.subpassCount = 1; |
| rp_ci.pSubpasses = &subpass_desc; |
| |
| VkRenderPass tile_shading_render_pass = VK_NULL_HANDLE; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassTileShadingCreateInfoQCOM-tileApronSize-10662"); |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassTileShadingCreateInfoQCOM-tileApronSize-10663"); |
| vk::CreateRenderPass(device(), &rp_ci, nullptr, &tile_shading_render_pass); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyRenderPass(device(), tile_shading_render_pass, nullptr); |
| } |
| |
| TEST_F(NegativeTileShading, RenderPassWithPerTileExecutionBit) { |
| TEST_DESCRIPTION("Try to create a tile-shading render pass with per-tile-execution bit, but " |
| "tileShadingPerTileDispatch and tileShadingPerTileDraw features are not enabled."); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_QCOM_TILE_SHADING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::tileShading); |
| RETURN_IF_SKIP(Init()); |
| |
| { |
| VkAttachmentDescription attachment_desc{}; |
| attachment_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference color_ref{}; |
| color_ref.attachment = 0; |
| color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkSubpassDescription subpass_desc{}; |
| subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass_desc.colorAttachmentCount = 1; |
| subpass_desc.pColorAttachments = &color_ref; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM | VK_TILE_SHADING_RENDER_PASS_PER_TILE_EXECUTION_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {0, 0}; |
| |
| VkRenderPassCreateInfo rp_ci = vku::InitStructHelper(&tile_shading_ci); |
| rp_ci.attachmentCount = 1; |
| rp_ci.pAttachments = &attachment_desc; |
| rp_ci.subpassCount = 1; |
| rp_ci.pSubpasses = &subpass_desc; |
| |
| VkRenderPass tile_shading_render_pass = VK_NULL_HANDLE; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCreateRenderPass-flags-10646"); |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassTileShadingCreateInfoQCOM-flags-10660"); |
| vk::CreateRenderPass(device(), &rp_ci, nullptr, &tile_shading_render_pass); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyRenderPass(device(), tile_shading_render_pass, nullptr); |
| } |
| { |
| VkAttachmentDescription2 attachment_desc2 = vku::InitStructHelper(); |
| attachment_desc2.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attachment_desc2.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_desc2.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attachment_desc2.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attachment_desc2.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_desc2.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_desc2.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_desc2.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference2 color_ref2 = vku::InitStructHelper(); |
| color_ref2.attachment = 0; |
| color_ref2.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_ref2.aspectMask = 0; |
| |
| VkSubpassDescription2 subpass_desc2 = vku::InitStructHelper(); |
| subpass_desc2.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass_desc2.viewMask = 0; |
| subpass_desc2.inputAttachmentCount = 0; |
| subpass_desc2.colorAttachmentCount = 1; |
| subpass_desc2.pColorAttachments = &color_ref2; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM | VK_TILE_SHADING_RENDER_PASS_PER_TILE_EXECUTION_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {0, 0}; |
| |
| VkRenderPassCreateInfo2 rpci2 = vku::InitStructHelper(&tile_shading_ci); |
| rpci2.flags = 0; |
| rpci2.attachmentCount = 1; |
| rpci2.pAttachments = &attachment_desc2; |
| rpci2.subpassCount = 1; |
| rpci2.pSubpasses = &subpass_desc2; |
| |
| VkRenderPass tile_shading_render_pass = VK_NULL_HANDLE; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCreateRenderPass2-flags-10649"); |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassTileShadingCreateInfoQCOM-flags-10660"); |
| vk::CreateRenderPass2(device(), &rpci2, nullptr, &tile_shading_render_pass); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyRenderPass(device(), tile_shading_render_pass, nullptr); |
| } |
| } |
| |
| TEST_F(NegativeTileShading, DynamicRenderingButTileShadingFeatureNotEnabled) { |
| TEST_DESCRIPTION("Try to launch a tile-shading dynamic rendering, but tileShading feature isn't enabled."); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_QCOM_TILE_SHADING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| |
| constexpr uint32_t image_width = 64; |
| constexpr uint32_t image_height = 64; |
| vkt::Image color_image{*m_device, image_width, image_height, m_render_target_fmt, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT}; |
| vkt::ImageView color_view = color_image.CreateView(); |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageView = color_view; |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.resolveMode = VK_RESOLVE_MODE_NONE; |
| color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {0, 0}; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(&tile_shading_ci); |
| rendering_info.renderArea = {{0, 0}, {image_width, image_height}}; |
| rendering_info.layerCount = 1; |
| rendering_info.colorAttachmentCount = 1; |
| rendering_info.pColorAttachments = &color_attachment; |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassTileShadingCreateInfoQCOM-tileShading-10658"); |
| vk::CmdBeginRendering(m_command_buffer, &rendering_info); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, DynamicRenderingWithApronSizeButRequiredFeaturesNotEnabled) { |
| TEST_DESCRIPTION("Try to launch a tile-shading dynamic rendering with specified anisotropic apron size, " |
| "but tileShadingApron and tileShadingAnisotropicApron features aren't enabled."); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_QCOM_TILE_SHADING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::tileShading); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceTileShadingPropertiesQCOM tile_shading_props = vku::InitStructHelper(); |
| VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&tile_shading_props); |
| vk::GetPhysicalDeviceProperties2(Gpu(), &props2); |
| |
| constexpr uint32_t image_width = 64; |
| constexpr uint32_t image_height = 64; |
| vkt::Image color_image{*m_device, image_width, image_height, m_render_target_fmt, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT}; |
| vkt::ImageView color_view = color_image.CreateView(); |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageView = color_view; |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.resolveMode = VK_RESOLVE_MODE_NONE; |
| color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {tile_shading_props.maxApronSize, std::max(tile_shading_props.maxApronSize - 1, 1U)}; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(&tile_shading_ci); |
| rendering_info.renderArea = {{0, 0}, {image_width, image_height}}; |
| rendering_info.layerCount = 1; |
| rendering_info.colorAttachmentCount = 1; |
| rendering_info.pColorAttachments = &color_attachment; |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassTileShadingCreateInfoQCOM-flags-10659"); |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassTileShadingCreateInfoQCOM-tileShadingAnisotropicApron-10661"); |
| vk::CmdBeginRendering(m_command_buffer, &rendering_info); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, RenderPassWithUndefinedFormatResolveAttachment) { |
| TEST_DESCRIPTION("Try to create a tile-shading render pass, but provides a undefined format resolve attachment."); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| |
| { |
| std::array<VkAttachmentDescription, 2> attachment_descs{}; |
| attachment_descs[0].format = m_render_target_fmt; |
| attachment_descs[0].samples = VK_SAMPLE_COUNT_4_BIT; |
| attachment_descs[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attachment_descs[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attachment_descs[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descs[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descs[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descs[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| attachment_descs[1].format = VK_FORMAT_UNDEFINED; |
| attachment_descs[1].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descs[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descs[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descs[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descs[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descs[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descs[1].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference color_ref{}; |
| color_ref.attachment = 0; |
| color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference resolve_ref{}; |
| resolve_ref.attachment = 1; |
| resolve_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkSubpassDescription subpass_desc{}; |
| subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass_desc.colorAttachmentCount = 1; |
| subpass_desc.pColorAttachments = &color_ref; |
| subpass_desc.pResolveAttachments = &resolve_ref; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {0, 0}; |
| |
| VkRenderPassCreateInfo rp_ci = vku::InitStructHelper(&tile_shading_ci); |
| rp_ci.attachmentCount = attachment_descs.size(); |
| rp_ci.pAttachments = attachment_descs.data(); |
| rp_ci.subpassCount = 1; |
| rp_ci.pSubpasses = &subpass_desc; |
| |
| VkRenderPass tile_shading_render_pass = VK_NULL_HANDLE; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkAttachmentDescription-format-06698"); |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassCreateInfo-pResolveAttachments-10647"); |
| vk::CreateRenderPass(device(), &rp_ci, nullptr, &tile_shading_render_pass); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyRenderPass(device(), tile_shading_render_pass, nullptr); |
| } |
| { |
| std::array<VkAttachmentDescription2, 2> attachment_descs{}; |
| attachment_descs[0] = vku::InitStructHelper(); |
| attachment_descs[0].format = m_render_target_fmt; |
| attachment_descs[0].samples = VK_SAMPLE_COUNT_4_BIT; |
| attachment_descs[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attachment_descs[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attachment_descs[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descs[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descs[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descs[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| attachment_descs[1] = vku::InitStructHelper(); |
| attachment_descs[1].format = VK_FORMAT_UNDEFINED; |
| attachment_descs[1].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descs[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descs[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descs[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descs[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descs[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descs[1].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference2 color_ref = vku::InitStructHelper(); |
| color_ref.attachment = 0; |
| color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference2 resolve_ref = vku::InitStructHelper(); |
| resolve_ref.attachment = 1; |
| resolve_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkSubpassDescription2 subpass_desc = vku::InitStructHelper(); |
| subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass_desc.colorAttachmentCount = 1; |
| subpass_desc.pColorAttachments = &color_ref; |
| subpass_desc.pResolveAttachments = &resolve_ref; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {0, 0}; |
| |
| VkRenderPassCreateInfo2 rp_ci2 = vku::InitStructHelper(&tile_shading_ci); |
| rp_ci2.attachmentCount = attachment_descs.size(); |
| rp_ci2.pAttachments = attachment_descs.data(); |
| rp_ci2.subpassCount = 1; |
| rp_ci2.pSubpasses = &subpass_desc; |
| |
| VkRenderPass tile_shading_render_pass = VK_NULL_HANDLE; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassCreateInfo2-pResolveAttachments-10650"); |
| m_errorMonitor->SetDesiredError("VUID-VkAttachmentDescription2-format-09332"); |
| vk::CreateRenderPass2(device(), &rp_ci2, nullptr, &tile_shading_render_pass); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyRenderPass(device(), tile_shading_render_pass, nullptr); |
| } |
| } |
| |
| TEST_F(NegativeTileShading, RenderPassWithFragmentDensityMapAttachment) { |
| TEST_DESCRIPTION("Try to create a tile-shading render pass, but provides an available fragment-density-map attachment."); |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| |
| { |
| std::array<VkAttachmentDescription, 2> attachment_descs{}; |
| attachment_descs[0].format = m_render_target_fmt; |
| attachment_descs[0].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descs[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attachment_descs[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attachment_descs[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descs[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descs[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descs[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| attachment_descs[1].format = VK_FORMAT_R8G8_UNORM; |
| attachment_descs[1].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descs[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descs[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descs[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descs[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descs[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descs[1].finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentReference color_ref{}; |
| color_ref.attachment = 0; |
| color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkSubpassDescription subpass_desc{}; |
| subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass_desc.colorAttachmentCount = 1; |
| subpass_desc.pColorAttachments = &color_ref; |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fdm_ci = vku::InitStructHelper(); |
| fdm_ci.fragmentDensityMapAttachment.attachment = 1; |
| fdm_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(&fdm_ci); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {0, 0}; |
| |
| VkRenderPassCreateInfo rp_ci = vku::InitStructHelper(&tile_shading_ci); |
| rp_ci.attachmentCount = attachment_descs.size(); |
| rp_ci.pAttachments = attachment_descs.data(); |
| rp_ci.subpassCount = 1; |
| rp_ci.pSubpasses = &subpass_desc; |
| |
| VkRenderPass tile_shading_render_pass = VK_NULL_HANDLE; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassCreateInfo-fragmentDensityMapAttachment-10648"); |
| vk::CreateRenderPass(device(), &rp_ci, nullptr, &tile_shading_render_pass); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyRenderPass(device(), tile_shading_render_pass, nullptr); |
| } |
| { |
| std::array<VkAttachmentDescription2, 2> attachment_descs{}; |
| attachment_descs[0] = vku::InitStructHelper(); |
| attachment_descs[0].format = m_render_target_fmt; |
| attachment_descs[0].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descs[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attachment_descs[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attachment_descs[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descs[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descs[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descs[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| attachment_descs[1] = vku::InitStructHelper(); |
| attachment_descs[1].format = VK_FORMAT_R8G8_UNORM; |
| attachment_descs[1].samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_descs[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descs[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descs[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_descs[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_descs[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_descs[1].finalLayout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkAttachmentReference2 color_ref = vku::InitStructHelper(); |
| color_ref.attachment = 0; |
| color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkSubpassDescription2 subpass_desc = vku::InitStructHelper(); |
| subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass_desc.colorAttachmentCount = 1; |
| subpass_desc.pColorAttachments = &color_ref; |
| |
| VkRenderPassFragmentDensityMapCreateInfoEXT fdm_ci = vku::InitStructHelper(); |
| fdm_ci.fragmentDensityMapAttachment.attachment = 1; |
| fdm_ci.fragmentDensityMapAttachment.layout = VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(&fdm_ci); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {0, 0}; |
| |
| VkRenderPassCreateInfo2 rp_ci2 = vku::InitStructHelper(&tile_shading_ci); |
| rp_ci2.attachmentCount = attachment_descs.size(); |
| rp_ci2.pAttachments = attachment_descs.data(); |
| rp_ci2.subpassCount = 1; |
| rp_ci2.pSubpasses = &subpass_desc; |
| |
| VkRenderPass tile_shading_render_pass = VK_NULL_HANDLE; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkRenderPassCreateInfo2-fragmentDensityMapAttachment-10651"); |
| vk::CreateRenderPass2(device(), &rp_ci2, nullptr, &tile_shading_render_pass); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyRenderPass(device(), tile_shading_render_pass, nullptr); |
| } |
| } |
| |
| TEST_F(NegativeTileShading, DynamicRenderingInSimultaneousUseBitCommandBuffer) { |
| TEST_DESCRIPTION("Try to launch a dynamic rendering in a recorded command buffer " |
| "with simultaneous-use-bit used."); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| |
| constexpr uint32_t image_width = 32; |
| constexpr uint32_t image_height = 32; |
| vkt::Image color_image{*m_device, image_width, image_height, m_render_target_fmt, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT}; |
| vkt::ImageView color_view = color_image.CreateView(); |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageView = color_view; |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.resolveMode = VK_RESOLVE_MODE_NONE; |
| color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {0, 0}; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(&tile_shading_ci); |
| rendering_info.renderArea = {{0, 0}, {image_width, image_height}}; |
| rendering_info.layerCount = 1; |
| rendering_info.colorAttachmentCount = 1; |
| rendering_info.pColorAttachments = &color_attachment; |
| |
| m_command_buffer.Begin(VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBeginRendering-flags-10641"); |
| vk::CmdBeginRendering(m_command_buffer, &rendering_info); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, DynamicRenderingWithPerTileExecutionBit) { |
| TEST_DESCRIPTION("Try to launch a tile-shading dynamic rendering but per-tile-execution bit is used."); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| |
| constexpr uint32_t image_width = 32; |
| constexpr uint32_t image_height = 32; |
| vkt::Image color_image{*m_device, image_width, image_height, m_render_target_fmt, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT}; |
| vkt::ImageView color_view = color_image.CreateView(); |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageView = color_view; |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.resolveMode = VK_RESOLVE_MODE_NONE; |
| color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM | VK_TILE_SHADING_RENDER_PASS_PER_TILE_EXECUTION_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {0, 0}; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(&tile_shading_ci); |
| rendering_info.renderArea = {{0, 0}, {image_width, image_height}}; |
| rendering_info.layerCount = 1; |
| rendering_info.colorAttachmentCount = 1; |
| rendering_info.pColorAttachments = &color_attachment; |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBeginRendering-flags-10642"); |
| vk::CmdBeginRendering(m_command_buffer, &rendering_info); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, DynamicRenderingButPerTileExecutionModelEnabled) { |
| TEST_DESCRIPTION("Try to end a tile-shading dynamic rendering, but per-tile-execution model is still enabled."); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageView = m_color_view; |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.resolveMode = VK_RESOLVE_MODE_NONE; |
| color_attachment.resolveImageView = VK_NULL_HANDLE; |
| color_attachment.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| color_attachment.clearValue = clear_value; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = tile_shading_rp_config.tile_apron_size; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(&tile_shading_ci); |
| rendering_info.renderArea = {{0, 0}, tile_shading_rp_config.rt_size}; |
| rendering_info.layerCount = 1; |
| rendering_info.viewMask = 0; |
| rendering_info.colorAttachmentCount = 1; |
| rendering_info.pColorAttachments = &color_attachment; |
| |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| VkPerTileEndInfoQCOM per_tile_end_info = vku::InitStructHelper(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBeginRendering(m_command_buffer, &rendering_info); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdEndRendering-None-10645"); |
| vk::CmdEndRendering(m_command_buffer); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| vk::CmdEndRendering(m_command_buffer); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, RenderPassWithSimultaneousUseBit) { |
| TEST_DESCRIPTION("Try to launch a tile-shading render pass in a recorded command buffer " |
| "with simultaneous-use-bit used."); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| |
| tile_shading_rp_config.use_render_pass2 = true; |
| InitTileShadingRenderTarget(); |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea.offset = {0, 0}; |
| rp_begin_info.renderArea.extent = tile_shading_rp_config.rt_size; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_value; |
| |
| VkSubpassBeginInfo subpass_begin_info = vku::InitStructHelper(); |
| subpass_begin_info.contents = VK_SUBPASS_CONTENTS_INLINE; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBeginRenderPass2-flags-10652"); |
| m_command_buffer.Begin(VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT); |
| vk::CmdBeginRenderPass2(m_command_buffer, &rp_begin_info, &subpass_begin_info); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, RenderPassButPerTileExecutionModelEnabled) { |
| TEST_DESCRIPTION("Try to end a tile-shading render pass, but per-tile execution model is still enabled."); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea.offset = {0, 0}; |
| rp_begin_info.renderArea.extent = tile_shading_rp_config.rt_size; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_value; |
| |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| VkPerTileEndInfoQCOM per_tile_end_info = vku::InitStructHelper(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBeginRenderPass(m_command_buffer, &rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdEndRenderPass-None-10653"); |
| vk::CmdEndRenderPass(m_command_buffer); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| vk::CmdEndRenderPass(m_command_buffer); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, DynamicRenderingWithFragmentDensityMapAttachment) { |
| TEST_DESCRIPTION("Try to launch a dynamic rendering when tile-shading is enabled and fragment-density-map attachment is provided."); |
| AddRequiredExtensions(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMap); |
| AddRequiredFeature(vkt::Feature::fragmentDensityMapNonSubsampledImages); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| |
| vkt::Image color_image{*m_device, 32, 32, m_render_target_fmt, |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT}; |
| vkt::ImageView color_view = color_image.CreateView(); |
| vkt::Image fdm_image{*m_device, 32, 32, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT}; |
| vkt::ImageView fdm_view = fdm_image.CreateView(); |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageView = color_view; |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.resolveMode = VK_RESOLVE_MODE_NONE; |
| color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| |
| VkRenderingFragmentDensityMapAttachmentInfoEXT fdm_attachment = vku::InitStructHelper(); |
| fdm_attachment.imageView = fdm_view; |
| fdm_attachment.imageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(&fdm_attachment); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {0, 0}; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(&tile_shading_ci); |
| rendering_info.renderArea = {{0, 0}, {32, 32}}; |
| rendering_info.layerCount = 1; |
| rendering_info.colorAttachmentCount = 1; |
| rendering_info.pColorAttachments = &color_attachment; |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-VkRenderingInfo-imageView-10643"); |
| vk::CmdBeginRendering(m_command_buffer, &rendering_info); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, SubpassDescriptionWithZeroApronSize) { |
| TEST_DESCRIPTION("Try to create a tile-shading render pass, but provides a tile-shading-apron subpass " |
| "description with zero apron size."); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| |
| { |
| VkAttachmentDescription attachment_desc{}; |
| attachment_desc.flags = 0; |
| attachment_desc.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference color_ref{}; |
| color_ref.attachment = 0; |
| color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkSubpassDescription subpass_desc{}; |
| subpass_desc.flags = VK_SUBPASS_DESCRIPTION_TILE_SHADING_APRON_BIT_QCOM; |
| subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass_desc.inputAttachmentCount = 0; |
| subpass_desc.colorAttachmentCount = 1; |
| subpass_desc.pColorAttachments = &color_ref; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {0, 0}; |
| |
| VkRenderPassCreateInfo rp_ci = vku::InitStructHelper(&tile_shading_ci); |
| rp_ci.flags = 0; |
| rp_ci.attachmentCount = 1; |
| rp_ci.pAttachments = &attachment_desc; |
| rp_ci.subpassCount = 1; |
| rp_ci.pSubpasses = &subpass_desc; |
| |
| VkRenderPass rp = VK_NULL_HANDLE; |
| m_errorMonitor->SetDesiredError("VUID-VkSubpassDescription-flags-10683"); |
| vk::CreateRenderPass(device(), &rp_ci, nullptr, &rp); |
| m_errorMonitor->VerifyFound(); |
| } |
| { |
| VkAttachmentDescription2 attachment_desc2 = vku::InitStructHelper(); |
| attachment_desc2.flags = 0; |
| attachment_desc2.format = VK_FORMAT_R8G8B8A8_UNORM; |
| attachment_desc2.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_desc2.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_desc2.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_desc2.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_desc2.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_desc2.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_desc2.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference2 color_ref2 = vku::InitStructHelper(); |
| color_ref2.attachment = 0; |
| color_ref2.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_ref2.aspectMask = 0; |
| |
| VkSubpassDescription2 subpass_desc2 = vku::InitStructHelper(); |
| subpass_desc2.flags = VK_SUBPASS_DESCRIPTION_TILE_SHADING_APRON_BIT_QCOM; |
| subpass_desc2.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass_desc2.viewMask = 0; |
| subpass_desc2.inputAttachmentCount = 0; |
| subpass_desc2.colorAttachmentCount = 1; |
| subpass_desc2.pColorAttachments = &color_ref2; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {0, 0}; |
| |
| VkRenderPassCreateInfo2 rpci2 = vku::InitStructHelper(&tile_shading_ci); |
| rpci2.flags = 0; |
| rpci2.attachmentCount = 1; |
| rpci2.pAttachments = &attachment_desc2; |
| rpci2.subpassCount = 1; |
| rpci2.pSubpasses = &subpass_desc2; |
| |
| VkRenderPass rp = VK_NULL_HANDLE; |
| m_errorMonitor->SetDesiredError("VUID-VkSubpassDescription2-flags-10683"); |
| vk::CreateRenderPass2(device(), &rpci2, nullptr, &rp); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeTileShading, BeginNonTileShadingCommandBufferWithTileShadingRenderPass) { |
| TEST_DESCRIPTION("Begin a command buffer without tile-shading-enable bit, but a tile-shading render pass " |
| "is included in the inheritance information."); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| vkt::CommandBuffer secondary_command{*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY}; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.tileApronSize = tile_shading_rp_config.tile_apron_size; |
| tile_shading_ci.flags = 0; |
| |
| VkCommandBufferInheritanceInfo inheritance_info = vku::InitStructHelper(&tile_shading_ci); |
| inheritance_info.renderPass = m_tile_shading_render_pass; |
| inheritance_info.subpass = 0; |
| inheritance_info.framebuffer = m_tile_shading_framebuffer; |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| begin_info.pInheritanceInfo = &inheritance_info; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkCommandBufferBeginInfo-flags-10617"); |
| vk::BeginCommandBuffer(secondary_command, &begin_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeTileShading, BeginTileShadingCommandBufferWithNonTileShadingRenderPass) { |
| TEST_DESCRIPTION("Begin a command buffer with tile-shading-enable bit, but the inheritance information " |
| "includes a non-tile-shading render pass."); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitRenderTarget(); |
| |
| vkt::CommandBuffer secondary_command{*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY}; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.tileApronSize = {0, 0}; |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| |
| VkCommandBufferInheritanceInfo inheritance_info = vku::InitStructHelper(&tile_shading_ci); |
| inheritance_info.renderPass = RenderPass(); |
| inheritance_info.subpass = 0; |
| inheritance_info.framebuffer = Framebuffer(); |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| begin_info.flags = 0; |
| begin_info.pInheritanceInfo = &inheritance_info; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkCommandBufferBeginInfo-flags-10618"); |
| vk::BeginCommandBuffer(secondary_command, &begin_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeTileShading, BeginTileShadingCommandBufferButHasInconsistentApronSize) { |
| TEST_DESCRIPTION("Begin a command buffer with tile-shading-enable bit, but the inheritance information " |
| "has tileApronSize that isn't equal to that tileApronSize used to create render pass."); |
| AddRequiredFeature(vkt::Feature::tileShadingApron); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| VkPhysicalDeviceTileShadingPropertiesQCOM tile_shading_props = vku::InitStructHelper(); |
| VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&tile_shading_props); |
| vk::GetPhysicalDeviceProperties2(Gpu(), &props2); |
| |
| vkt::CommandBuffer secondary_command{*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY}; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.tileApronSize = {tile_shading_props.maxApronSize, tile_shading_props.maxApronSize}; |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| |
| VkCommandBufferInheritanceInfo inheritance_info = vku::InitStructHelper(&tile_shading_ci); |
| inheritance_info.renderPass = m_tile_shading_render_pass; |
| inheritance_info.subpass = 0; |
| inheritance_info.framebuffer = m_tile_shading_framebuffer; |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| begin_info.pInheritanceInfo = &inheritance_info; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkCommandBufferBeginInfo-flags-10619"); |
| vk::BeginCommandBuffer(secondary_command, &begin_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeTileShading, ExecuteTileShadingCommandWithoutTileShadingEnableBit) { |
| TEST_DESCRIPTION("Execute a secondary command inside a tile-shading render pass scope, but that secondary " |
| "command hasn't been recorded with tile-shading-enable bit."); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| vkt::CommandBuffer secondary_command{*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY}; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.tileApronSize = tile_shading_rp_config.tile_apron_size; |
| tile_shading_ci.flags = 0; |
| |
| VkCommandBufferInheritanceInfo inheritance_info = vku::InitStructHelper(&tile_shading_ci); |
| inheritance_info.renderPass = m_tile_shading_render_pass; |
| inheritance_info.subpass = 0; |
| inheritance_info.framebuffer = m_tile_shading_framebuffer; |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| begin_info.pInheritanceInfo = &inheritance_info; |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea.offset = {0, 0}; |
| rp_begin_info.renderArea.extent = tile_shading_rp_config.rt_size; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_value; |
| |
| m_errorMonitor->SetAllowedFailureMsg("VUID-VkCommandBufferBeginInfo-flags-10617"); |
| secondary_command.Begin(&begin_info); |
| secondary_command.End(); |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-10620"); |
| m_command_buffer.ExecuteCommands(secondary_command); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, ExecuteTileShadingCommandInPerTileExecutionModelScope) { |
| TEST_DESCRIPTION("Execute a secondary command inside the per-tile execution model scope, but that secondary " |
| "command only has been recorded with tile-shading-enable bit."); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| vkt::CommandBuffer secondary_command{*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY}; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.tileApronSize = tile_shading_rp_config.tile_apron_size; |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| |
| VkCommandBufferInheritanceInfo inheritance_info = vku::InitStructHelper(&tile_shading_ci); |
| inheritance_info.renderPass = m_tile_shading_render_pass; |
| inheritance_info.subpass = 0; |
| inheritance_info.framebuffer = m_tile_shading_framebuffer; |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| begin_info.pInheritanceInfo = &inheritance_info; |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea.offset = {0, 0}; |
| rp_begin_info.renderArea.extent = tile_shading_rp_config.rt_size; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_value; |
| |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| VkPerTileEndInfoQCOM per_tile_end_info = vku::InitStructHelper(); |
| |
| secondary_command.Begin(&begin_info); |
| secondary_command.End(); |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-10621"); |
| m_command_buffer.ExecuteCommands(secondary_command); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, ExecuteTileShadingCommandWithInconsistentTileApronSize) { |
| TEST_DESCRIPTION("Execute a secondary command inside a tile-shading render pass scope, but that secondary " |
| "command has been recorded with a tile-apron size inconsistent with that of the render pass."); |
| AddRequiredFeature(vkt::Feature::tileShadingApron); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| |
| VkPhysicalDeviceTileShadingPropertiesQCOM tile_shading_props = vku::InitStructHelper(); |
| VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&tile_shading_props); |
| vk::GetPhysicalDeviceProperties2(Gpu(), &props2); |
| |
| tile_shading_rp_config.tile_apron_size = {tile_shading_props.maxApronSize, tile_shading_props.maxApronSize}; |
| InitTileShadingRenderTarget(); |
| |
| VkAttachmentDescription attachment_desc{}; |
| attachment_desc.format = tile_shading_rp_config.format; |
| attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkAttachmentReference color_ref{}; |
| color_ref.attachment = 0; |
| color_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| |
| VkSubpassDescription subpass_desc{}; |
| subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass_desc.colorAttachmentCount = 1; |
| subpass_desc.pColorAttachments = &color_ref; |
| |
| VkSubpassDependency subpass_dependency{}; |
| subpass_dependency.srcSubpass = VK_SUBPASS_EXTERNAL; |
| subpass_dependency.dstSubpass = 0; |
| subpass_dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; |
| subpass_dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; |
| subpass_dependency.srcAccessMask = 0; |
| subpass_dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; |
| subpass_dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci_primary = vku::InitStructHelper(); |
| tile_shading_ci_primary.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci_primary.tileApronSize = {0, 0}; |
| |
| VkRenderPassCreateInfo rp_ci = vku::InitStructHelper(&tile_shading_ci_primary); |
| rp_ci.attachmentCount = 1; |
| rp_ci.pAttachments = &attachment_desc; |
| rp_ci.subpassCount = 1; |
| rp_ci.pSubpasses = &subpass_desc; |
| rp_ci.dependencyCount = 1; |
| rp_ci.pDependencies = &subpass_dependency; |
| |
| vkt::RenderPass zero_apron_rp{*m_device, rp_ci}; |
| |
| vkt::CommandBuffer secondary_command{*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY}; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.tileApronSize = {tile_shading_props.maxApronSize, tile_shading_props.maxApronSize}; |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| |
| VkCommandBufferInheritanceInfo inheritance_info = vku::InitStructHelper(&tile_shading_ci); |
| inheritance_info.renderPass = m_tile_shading_render_pass; |
| inheritance_info.subpass = 0; |
| inheritance_info.framebuffer = m_tile_shading_framebuffer; |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| begin_info.pInheritanceInfo = &inheritance_info; |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = zero_apron_rp; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea.offset = {0, 0}; |
| rp_begin_info.renderArea.extent = tile_shading_rp_config.rt_size; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_value; |
| |
| secondary_command.Begin(&begin_info); |
| secondary_command.End(); |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-tileApronSize-10622"); |
| m_command_buffer.ExecuteCommands(secondary_command); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, ExecuteTileShadingCommandInNonTileShadingRenderPass) { |
| TEST_DESCRIPTION("Execute a secondary command inside a non-tile-shading render pass scope, but that secondary " |
| "command has been recorded with tile-shading-enable bit."); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitRenderTarget(); |
| |
| vkt::CommandBuffer secondary_command{*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY}; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.tileApronSize = {0, 0}; |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| |
| VkCommandBufferInheritanceInfo inheritance_info = vku::InitStructHelper(&tile_shading_ci); |
| inheritance_info.renderPass = RenderPass(); |
| inheritance_info.subpass = 0; |
| inheritance_info.framebuffer = Framebuffer(); |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| begin_info.pInheritanceInfo = &inheritance_info; |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = RenderPass(); |
| rp_begin_info.framebuffer = Framebuffer(); |
| rp_begin_info.renderArea.offset = {0, 0}; |
| rp_begin_info.renderArea.extent = {m_width, m_height}; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_value; |
| |
| secondary_command.Begin(&begin_info); |
| secondary_command.End(); |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-10623"); |
| m_command_buffer.ExecuteCommands(secondary_command); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, ExecutePerTileExecutionCommandButPerTileExecutionModelNotEnabled) { |
| TEST_DESCRIPTION("Execute a secondary command that has been recorded with per-tile-execution bit, " |
| "but the per-tile execution model isn't enabled."); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| vkt::CommandBuffer secondary_command{*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY}; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.tileApronSize = tile_shading_rp_config.tile_apron_size; |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM | VK_TILE_SHADING_RENDER_PASS_PER_TILE_EXECUTION_BIT_QCOM; |
| |
| VkCommandBufferInheritanceInfo inheritance_info = vku::InitStructHelper(&tile_shading_ci); |
| inheritance_info.renderPass = m_tile_shading_render_pass; |
| inheritance_info.subpass = 0; |
| inheritance_info.framebuffer = m_tile_shading_framebuffer; |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| begin_info.pInheritanceInfo = &inheritance_info; |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea.offset = {0, 0}; |
| rp_begin_info.renderArea.extent = tile_shading_rp_config.rt_size; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_value; |
| |
| secondary_command.Begin(&begin_info); |
| secondary_command.End(); |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-10624"); |
| m_command_buffer.ExecuteCommands(secondary_command); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, ExecuteNonZeroTileSizeCommand) { |
| TEST_DESCRIPTION("Execute a secondary command without a render pass, but that secondary " |
| "command has been recorded with a non-zero tile-apron size."); |
| AddRequiredFeature(vkt::Feature::tileShadingApron); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| |
| VkPhysicalDeviceTileShadingPropertiesQCOM tile_shading_props = vku::InitStructHelper(); |
| VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&tile_shading_props); |
| vk::GetPhysicalDeviceProperties2(Gpu(), &props2); |
| |
| vkt::CommandBuffer secondary_command{*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY}; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.tileApronSize = {tile_shading_props.maxApronSize, tile_shading_props.maxApronSize}; |
| tile_shading_ci.flags = 0; |
| |
| VkCommandBufferInheritanceInfo inheritance_info = vku::InitStructHelper(&tile_shading_ci); |
| inheritance_info.renderPass = nullptr; |
| inheritance_info.subpass = 0; |
| inheritance_info.framebuffer = nullptr; |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| begin_info.flags = 0; |
| begin_info.pInheritanceInfo = &inheritance_info; |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| secondary_command.Begin(&begin_info); |
| secondary_command.End(); |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-tileApronSize-10625"); |
| m_command_buffer.ExecuteCommands(secondary_command); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, LaunchTileAttachmentMemoryBarrierButUseWrongStageMask) { |
| TEST_DESCRIPTION("Try to launch tile attachment memory barrier but provides a wrong stage mask."); |
| AddRequiredFeature(vkt::Feature::synchronization2); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| |
| m_command_buffer.Begin(); |
| { |
| VkMemoryBarrier2 barrier2 = vku::InitStructHelper(); |
| barrier2.srcStageMask = VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT; |
| barrier2.srcAccessMask = VK_ACCESS_2_SHADER_TILE_ATTACHMENT_READ_BIT_QCOM; |
| barrier2.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; |
| barrier2.dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkMemoryBarrier2-srcAccessMask-10670"); |
| m_command_buffer.Barrier(barrier2); |
| m_errorMonitor->VerifyFound(); |
| } |
| { |
| VkMemoryBarrier2 barrier2 = vku::InitStructHelper(); |
| barrier2.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; |
| barrier2.srcAccessMask = VK_ACCESS_2_SHADER_TILE_ATTACHMENT_WRITE_BIT_QCOM; |
| barrier2.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; |
| barrier2.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkMemoryBarrier2-srcAccessMask-10671"); |
| m_command_buffer.Barrier(barrier2); |
| m_errorMonitor->VerifyFound(); |
| } |
| { |
| VkMemoryBarrier2 barrier2 = vku::InitStructHelper(); |
| barrier2.srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; |
| barrier2.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT; |
| barrier2.dstStageMask = VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT; |
| barrier2.dstAccessMask = VK_ACCESS_2_SHADER_TILE_ATTACHMENT_READ_BIT_QCOM; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkMemoryBarrier2-dstAccessMask-10670"); |
| m_command_buffer.Barrier(barrier2); |
| m_errorMonitor->VerifyFound(); |
| } |
| { |
| VkMemoryBarrier2 barrier2 = vku::InitStructHelper(); |
| barrier2.srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; |
| barrier2.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT; |
| barrier2.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; |
| barrier2.dstAccessMask = VK_ACCESS_2_SHADER_TILE_ATTACHMENT_WRITE_BIT_QCOM; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkMemoryBarrier2-dstAccessMask-10671"); |
| m_command_buffer.Barrier(barrier2); |
| m_errorMonitor->VerifyFound(); |
| } |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, DebugMarkerInsidePerTileExecutionModelScope) { |
| TEST_DESCRIPTION("Try to begin or end debug marker inside the per-tile execution model scope."); |
| AddRequiredExtensions(VK_EXT_DEBUG_MARKER_EXTENSION_NAME); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea.offset = {0, 0}; |
| rp_begin_info.renderArea.extent = tile_shading_rp_config.rt_size; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_value; |
| |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| VkPerTileEndInfoQCOM per_tile_end_info = vku::InitStructHelper(); |
| |
| VkDebugMarkerMarkerInfoEXT marker_info = vku::InitStructHelper(); |
| marker_info.pMarkerName = "tile-shading-marker"; |
| marker_info.color[0] = 1.0f; |
| marker_info.color[1] = 0.0f; |
| marker_info.color[2] = 0.0f; |
| marker_info.color[3] = 1.0f; |
| |
| { |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDebugMarkerBeginEXT-None-10614"); |
| vk::CmdDebugMarkerBeginEXT(m_command_buffer, &marker_info); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| m_command_buffer.Reset(); |
| } |
| { |
| m_command_buffer.Begin(); |
| vk::CmdDebugMarkerBeginEXT(m_command_buffer, &marker_info); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDebugMarkerEndEXT-None-10615"); |
| vk::CmdDebugMarkerEndEXT(m_command_buffer); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRenderPass(); |
| vk::CmdDebugMarkerEndEXT(m_command_buffer); |
| m_command_buffer.End(); |
| } |
| } |
| |
| TEST_F(NegativeTileShading, ClearAttachmentInsidePerTileExecutionModelScope) { |
| TEST_DESCRIPTION("Try to clear attachment inside the per-tile execution model scope."); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea.offset = {0, 0}; |
| rp_begin_info.renderArea.extent = tile_shading_rp_config.rt_size; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_value; |
| |
| VkClearAttachment clear_attachment{}; |
| clear_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| clear_attachment.colorAttachment = 0; |
| clear_attachment.clearValue = clear_value; |
| |
| VkClearRect clear_rect{}; |
| clear_rect.rect.offset = {0, 0}; |
| clear_rect.rect.extent = tile_shading_rp_config.rt_size; |
| clear_rect.baseArrayLayer = 0; |
| clear_rect.layerCount = 1; |
| |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| VkPerTileEndInfoQCOM per_tile_end_info = vku::InitStructHelper(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-None-10616"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &clear_attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, WriteTimestampInsidePerTileExecutionModelScope) { |
| TEST_DESCRIPTION("Try to write timestamp inside the per-tile execution model scope."); |
| AddRequiredFeature(vkt::Feature::synchronization2); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| vkt::QueryPool query_pool{*m_device, VK_QUERY_TYPE_TIMESTAMP, 1}; |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea.offset = {0, 0}; |
| rp_begin_info.renderArea.extent = tile_shading_rp_config.rt_size; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_value; |
| |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| VkPerTileEndInfoQCOM per_tile_end_info = vku::InitStructHelper(); |
| |
| { |
| m_command_buffer.Begin(); |
| vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdWriteTimestamp-None-10640"); |
| vk::CmdWriteTimestamp(m_command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, query_pool, 0); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| m_command_buffer.Reset(); |
| } |
| { |
| m_command_buffer.Begin(); |
| vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdWriteTimestamp2-None-10639"); |
| vk::CmdWriteTimestamp2(m_command_buffer, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, query_pool, 0); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| } |
| |
| TEST_F(NegativeTileShading, WaitEventsInsidePerTileExecutionModelScope) { |
| TEST_DESCRIPTION("Try to wait events inside the per-tile execution model scope."); |
| AddRequiredFeature(vkt::Feature::synchronization2); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| vkt::Event event{*m_device}; |
| const VkEvent event_handle = event.handle(); |
| |
| VkClearValue clear_value = {}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea.offset = {0, 0}; |
| rp_begin_info.renderArea.extent = tile_shading_rp_config.rt_size; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_value; |
| |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| VkPerTileEndInfoQCOM per_tile_end_info = vku::InitStructHelper(); |
| |
| { |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdWaitEvents-None-10655"); |
| vk::CmdWaitEvents(m_command_buffer, |
| 1, &event_handle, |
| VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, |
| VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, |
| 0, nullptr, |
| 0, nullptr, |
| 0, nullptr); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| m_command_buffer.Reset(); |
| } |
| { |
| VkMemoryBarrier2 mem_barrier2 = vku::InitStructHelper(); |
| mem_barrier2.srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; |
| mem_barrier2.srcAccessMask = 0; |
| mem_barrier2.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT; |
| mem_barrier2.dstAccessMask = VK_ACCESS_2_SHADER_TILE_ATTACHMENT_READ_BIT_QCOM; |
| |
| VkDependencyInfo dependency_info = vku::InitStructHelper(); |
| dependency_info.memoryBarrierCount = 1; |
| dependency_info.pMemoryBarriers = &mem_barrier2; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdWaitEvents2-None-10654"); |
| vk::CmdWaitEvents2(m_command_buffer, 1, &event_handle, &dependency_info); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| } |
| |
| TEST_F(NegativeTileShading, TransformFeedbackInsidePerTileExecutionModelScope) { |
| TEST_DESCRIPTION("Try to begin or end transform feedback inside the per-tile execution model scope."); |
| AddRequiredExtensions(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::transformFeedback); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| const char *vs_source = R"glsl( |
| #version 460 |
| |
| layout(xfb_buffer = 0, xfb_stride = 16) out; |
| layout(location = 0, xfb_offset = 0) out vec4 xfb_out; |
| |
| vec2 positions[3] = vec2[3]( |
| vec2( 0.0, -0.5), |
| vec2( 0.5, 0.5), |
| vec2(-0.5, 0.5) |
| ); |
| |
| void main() { |
| vec4 out_position = vec4(positions[gl_VertexIndex], 0.0, 1.0); |
| xfb_out = out_position; |
| gl_Position = out_position; |
| } |
| )glsl"; |
| const char *fs_source = R"glsl( |
| #version 460 |
| |
| layout(location = 0) out vec4 out_color; |
| |
| void main() { |
| out_color = vec4(1.0); |
| } |
| )glsl"; |
| |
| VkShaderObj vs{*m_device, vs_source, VK_SHADER_STAGE_VERTEX_BIT, SPV_ENV_VULKAN_1_3}; |
| VkShaderObj fs{*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_3}; |
| |
| CreatePipelineHelper xfb_pipe{*this}; |
| xfb_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()}; |
| xfb_pipe.gp_ci_.renderPass = m_tile_shading_render_pass; |
| xfb_pipe.CreateGraphicsPipeline(); |
| |
| constexpr VkDeviceSize xfb_offset = 0; |
| constexpr VkDeviceSize xfb_size = 4096; |
| vkt::Buffer xfb_buffer{*m_device, xfb_size, |
| VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT, |
| VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT}; |
| VkBuffer xfb_handle = xfb_buffer.handle(); |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea.offset = {0, 0}; |
| rp_begin_info.renderArea.extent = tile_shading_rp_config.rt_size; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_value; |
| |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| VkPerTileEndInfoQCOM per_tile_end_info = vku::InitStructHelper(); |
| |
| { |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, xfb_pipe); |
| vk::CmdBindTransformFeedbackBuffersEXT(m_command_buffer, 0, 1, &xfb_handle, &xfb_offset, &xfb_size); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBeginTransformFeedbackEXT-None-10656"); |
| vk::CmdBeginTransformFeedbackEXT(m_command_buffer, 0, 0, nullptr, nullptr); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| m_command_buffer.Reset(); |
| } |
| { |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, xfb_pipe); |
| vk::CmdBindTransformFeedbackBuffersEXT(m_command_buffer, 0, 1, &xfb_handle, &xfb_offset, &xfb_size); |
| vk::CmdBeginTransformFeedbackEXT(m_command_buffer, 0, 0, nullptr, nullptr); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdEndTransformFeedbackEXT-None-10657"); |
| vk::CmdEndTransformFeedbackEXT(m_command_buffer, 0, 0, nullptr, nullptr); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| vk::CmdEndTransformFeedbackEXT(m_command_buffer, 0, 0, nullptr, nullptr); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| } |
| |
| TEST_F(NegativeTileShading, QueryInsidePerTileExecutionModelScope) { |
| TEST_DESCRIPTION("Try to begin or end query inside the per-tile execution model scope."); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| vkt::QueryPool query_pool{*m_device, VK_QUERY_TYPE_OCCLUSION, 1}; |
| |
| VkClearValue clear_value{}; |
| clear_value.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea.offset = {0, 0}; |
| rp_begin_info.renderArea.extent = tile_shading_rp_config.rt_size; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_value; |
| |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| VkPerTileEndInfoQCOM per_tile_end_info = vku::InitStructHelper(); |
| |
| { |
| m_command_buffer.Begin(); |
| vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-None-10681"); |
| vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| m_command_buffer.Reset(); |
| } |
| { |
| m_command_buffer.Begin(); |
| vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1); |
| vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdEndQuery-None-07007"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdEndQuery-None-10682"); |
| vk::CmdEndQuery(m_command_buffer, query_pool, 0); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRenderPass(); |
| vk::CmdEndQuery(m_command_buffer, query_pool, 0); |
| m_command_buffer.End(); |
| } |
| } |
| |
| TEST_F(NegativeTileShading, DispatchTileButPerTileExecutionModelNotEnabled) { |
| TEST_DESCRIPTION("Try to launch dispatch tile, but per-tile execution model isn't enabled."); |
| AddRequiredFeature(vkt::Feature::tileShadingDispatchTile); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| CreateComputePipelineHelper compute_pipe{*this}; |
| compute_pipe.CreateComputePipeline(); |
| |
| VkDispatchTileInfoQCOM dispatch_tile_info = vku::InitStructHelper(); |
| |
| VkClearValue clear_color{}; |
| clear_color.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea = {{0,0}, tile_shading_rp_config.rt_size}; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_color; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchTileQCOM-None-10672"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchTileQCOM-None-10668"); |
| vk::CmdDispatchTileQCOM(m_command_buffer, &dispatch_tile_info); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, DispatchTileButPerTileDispatchFeatureNotEnabled) { |
| TEST_DESCRIPTION("Try to launch dispatch tile, but tileShadingDispatchTile feature isn't enabled."); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| CreateComputePipelineHelper compute_pipe{*this}; |
| compute_pipe.CreateComputePipeline(); |
| |
| VkDispatchTileInfoQCOM dispatch_tile_info = vku::InitStructHelper(); |
| |
| VkClearValue clear_color{}; |
| clear_color.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea = {{0,0}, tile_shading_rp_config.rt_size}; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_color; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchTileQCOM-None-10669"); |
| vk::CmdDispatchTileQCOM(m_command_buffer, &dispatch_tile_info); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, DispatchInsidePerTileExecutionModelButPerTileDispatchFeatureNotEnabled) { |
| TEST_DESCRIPTION("Try to launch dispatch inside the per-tile execution model scope, " |
| "but tileShadingPerTileDispatch feature isn't enabled."); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_QCOM_TILE_SHADING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::tileShading); |
| AddRequiredFeature(vkt::Feature::tileShadingPerTileDraw); |
| AddRequiredFeature(vkt::Feature::tileShadingColorAttachments); |
| RETURN_IF_SKIP(Init()); |
| InitTileShadingRenderTarget(); |
| |
| CreateComputePipelineHelper compute_pipe{*this}; |
| compute_pipe.CreateComputePipeline(); |
| |
| VkClearValue clear_color{}; |
| clear_color.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea = {{0,0}, tile_shading_rp_config.rt_size}; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_color; |
| |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| VkPerTileEndInfoQCOM per_tile_end_info = vku::InitStructHelper(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatch-None-10674"); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, DrawInsidePerTileExecutionModelButPerTileDrawFeatureNotEnabled) { |
| TEST_DESCRIPTION("Try to launch draw inside the per-tile execution model scope, " |
| "but tileShadingPerTileDraw feature isn't enabled."); |
| SetTargetApiVersion(VK_API_VERSION_1_3); |
| AddRequiredExtensions(VK_QCOM_TILE_SHADING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::tileShading); |
| AddRequiredFeature(vkt::Feature::tileShadingPerTileDispatch); |
| AddRequiredFeature(vkt::Feature::tileShadingColorAttachments); |
| RETURN_IF_SKIP(Init()); |
| InitTileShadingRenderTarget(); |
| |
| CreatePipelineHelper graphics_pipe{*this}; |
| graphics_pipe.gp_ci_.renderPass = m_tile_shading_render_pass; |
| graphics_pipe.CreateGraphicsPipeline(); |
| |
| VkClearValue clear_color{}; |
| clear_color.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea = {{0,0}, tile_shading_rp_config.rt_size}; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_color; |
| |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| VkPerTileEndInfoQCOM per_tile_end_info = vku::InitStructHelper(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-10677"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, TileShadingDrawButHasActiveGeometryShader) { |
| TEST_DESCRIPTION("Try to launch a draw inside a tile-shading render pass scope, but the graphics pipeline " |
| "has an active geometry shader."); |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| VkShaderObj vs{*m_device, kVertexMinimalGlsl, VK_SHADER_STAGE_VERTEX_BIT, SPV_ENV_VULKAN_1_3}; |
| VkShaderObj gs{*m_device, kGeometryMinimalGlsl, VK_SHADER_STAGE_GEOMETRY_BIT, SPV_ENV_VULKAN_1_3}; |
| VkShaderObj fs{*m_device, kFragmentMinimalGlsl, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_3}; |
| |
| CreatePipelineHelper tile_shading_graphics_pipe{*this}; |
| tile_shading_graphics_pipe.shader_stages_ = {vs.GetStageCreateInfo(), gs.GetStageCreateInfo(), fs.GetStageCreateInfo()}; |
| tile_shading_graphics_pipe.gp_ci_.renderPass = m_tile_shading_render_pass; |
| tile_shading_graphics_pipe.CreateGraphicsPipeline(); |
| |
| VkClearValue clear_color{}; |
| clear_color.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = m_tile_shading_render_pass; |
| rp_begin_info.framebuffer = m_tile_shading_framebuffer; |
| rp_begin_info.renderArea = {{0,0}, tile_shading_rp_config.rt_size}; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_color; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, tile_shading_graphics_pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-10678"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, TileShadingDrawButHasActiveGeometryShaderObject) { |
| TEST_DESCRIPTION("Try to launch a draw inside a tile-shading render pass scope, but a geometry " |
| "shader object is bound."); |
| AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::shaderObject); |
| AddRequiredFeature(vkt::Feature::geometryShader); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| InitTileShadingRenderTarget(); |
| |
| const auto vert_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl); |
| const auto geom_spv = GLSLToSPV(VK_SHADER_STAGE_GEOMETRY_BIT, kGeometryMinimalGlsl); |
| const auto frag_spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl); |
| |
| auto vert_ci = ShaderCreateInfo(vert_spv, VK_SHADER_STAGE_VERTEX_BIT); |
| vert_ci.nextStage = VK_SHADER_STAGE_GEOMETRY_BIT; |
| vkt::Shader vert_shader{*m_device, vert_ci}; |
| vkt::Shader geom_shader{*m_device, ShaderCreateInfo(geom_spv, VK_SHADER_STAGE_GEOMETRY_BIT)}; |
| vkt::Shader frag_shader{*m_device, ShaderCreateInfoNoNextStage(frag_spv, VK_SHADER_STAGE_FRAGMENT_BIT)}; |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageView = m_color_view; |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
| color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| color_attachment.clearValue.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_info = vku::InitStructHelper(); |
| tile_info.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_info.tileApronSize = {0, 0}; |
| |
| VkRenderingInfo rendering_info = vku::InitStructHelper(&tile_info); |
| rendering_info.renderArea = {{0, 0}, tile_shading_rp_config.rt_size}; |
| rendering_info.layerCount = 1; |
| rendering_info.colorAttachmentCount = 1; |
| rendering_info.pColorAttachments = &color_attachment; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(rendering_info); |
| SetDefaultDynamicStatesExclude(); |
| m_command_buffer.BindShaders(vert_shader, geom_shader, frag_shader); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-10678"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, PerTileDrawButAccessImageWithFeedbackLoopLayout) { |
| TEST_DESCRIPTION("Try to launch a per-tile draw inside a tile-shading render pass scope, but accesses " |
| "an tile attachment with VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT."); |
| AddRequiredExtensions(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::attachmentFeedbackLoopLayout); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| |
| constexpr uint32_t width = 64; |
| constexpr uint32_t height = 64; |
| constexpr VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM; |
| |
| vkt::Image color_image{*m_device, width, height, color_format, |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT | |
| VK_IMAGE_USAGE_SAMPLED_BIT}; |
| vkt::ImageView color_view = color_image.CreateView(); |
| vkt::Sampler sampler{*m_device, SafeSaneSamplerCreateInfo()}; |
| |
| VkAttachmentDescription attachment_desc{}; |
| attachment_desc.format = color_format; |
| attachment_desc.samples = VK_SAMPLE_COUNT_1_BIT; |
| attachment_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; |
| attachment_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
| attachment_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; |
| attachment_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; |
| attachment_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| attachment_desc.finalLayout = VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT; |
| |
| VkAttachmentReference color_ref{}; |
| color_ref.attachment = 0; |
| color_ref.layout = VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT; |
| |
| VkSubpassDescription subpass_desc{}; |
| subpass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
| subpass_desc.colorAttachmentCount = 1; |
| subpass_desc.pColorAttachments = &color_ref; |
| |
| VkSubpassDependency subpass_dependency{}; |
| subpass_dependency.srcSubpass = VK_SUBPASS_EXTERNAL; |
| subpass_dependency.dstSubpass = 0; |
| subpass_dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; |
| subpass_dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; |
| subpass_dependency.srcAccessMask = 0; |
| subpass_dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; |
| subpass_dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT | VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_shading_ci = vku::InitStructHelper(); |
| tile_shading_ci.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_shading_ci.tileApronSize = {0, 0}; |
| |
| VkRenderPassCreateInfo rp_ci = vku::InitStructHelper(&tile_shading_ci); |
| rp_ci.attachmentCount = 1; |
| rp_ci.pAttachments = &attachment_desc; |
| rp_ci.subpassCount = 1; |
| rp_ci.pSubpasses = &subpass_desc; |
| rp_ci.dependencyCount = 1; |
| rp_ci.pDependencies = &subpass_dependency; |
| vkt::RenderPass tile_shading_render_pass{*m_device, rp_ci}; |
| |
| const VkImageView color_view_handle = color_view.handle(); |
| VkFramebufferCreateInfo framebuffer_ci = vku::InitStructHelper(); |
| framebuffer_ci.renderPass = tile_shading_render_pass; |
| framebuffer_ci.attachmentCount = 1; |
| framebuffer_ci.pAttachments = &color_view_handle; |
| framebuffer_ci.width = width; |
| framebuffer_ci.height = height; |
| framebuffer_ci.layers = 1; |
| vkt::Framebuffer tile_shading_framebuffer{*m_device, framebuffer_ci}; |
| |
| const char* vs_source = R"glsl( |
| #version 460 |
| |
| vec2 pos[3] = vec2[]( |
| vec2(-1.0, -1.0), |
| vec2( 3.0, -1.0), |
| vec2(-1.0, 3.0) |
| ); |
| |
| void main() { |
| gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0); |
| } |
| )glsl"; |
| |
| const char* fs_source = R"glsl( |
| #version 460 |
| |
| layout(set = 0, binding = 0) uniform sampler2D tile_img; |
| layout(location = 0) out vec4 out_color; |
| |
| void main() { |
| vec4 color = texture(tile_img, vec2(0.5, 0.5)); |
| out_color = color; |
| } |
| )glsl"; |
| |
| VkShaderObj vs{*m_device, vs_source, VK_SHADER_STAGE_VERTEX_BIT, SPV_ENV_VULKAN_1_3}; |
| VkShaderObj fs{*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_3}; |
| |
| CreatePipelineHelper tile_shading_graphics_pipe{*this}; |
| tile_shading_graphics_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()}; |
| tile_shading_graphics_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}}; |
| tile_shading_graphics_pipe.gp_ci_.renderPass = tile_shading_render_pass; |
| tile_shading_graphics_pipe.gp_ci_.flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; |
| tile_shading_graphics_pipe.CreateGraphicsPipeline(); |
| tile_shading_graphics_pipe.descriptor_set_->WriteDescriptorImageInfo(0, color_view, sampler, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, |
| VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT); |
| tile_shading_graphics_pipe.descriptor_set_->UpdateDescriptorSets(); |
| |
| VkClearValue clear_color{}; |
| clear_color.color = {{0.0f, 0.0f, 0.0f, 0.0f}}; |
| |
| VkRenderPassBeginInfo rp_begin_info = vku::InitStructHelper(); |
| rp_begin_info.renderPass = tile_shading_render_pass; |
| rp_begin_info.framebuffer = tile_shading_framebuffer; |
| rp_begin_info.renderArea = {{0,0}, {width, height}}; |
| rp_begin_info.clearValueCount = 1; |
| rp_begin_info.pClearValues = &clear_color; |
| |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| VkPerTileEndInfoQCOM per_tile_end_info = vku::InitStructHelper(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, tile_shading_graphics_pipe); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, |
| tile_shading_graphics_pipe.pipeline_layout_, 0, 1, |
| &tile_shading_graphics_pipe.descriptor_set_->set_, 0, nullptr); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-10679"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeTileShading, ImageDescriptorMismatchTileMemory) { |
| TEST_DESCRIPTION("Try to create tile memory storage buffer and use it within a dispatch tile invocation."); |
| AddRequiredExtensions(VK_QCOM_TILE_MEMORY_HEAP_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::tileMemoryHeap); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| AddRequiredFeature(vkt::Feature::tileShadingDispatchTile); |
| RETURN_IF_SKIP(InitBasicTileShading()); |
| |
| constexpr uint32_t width = 64; |
| constexpr uint32_t height = 64; |
| const auto image_ci = vkt::Image::ImageCreateInfo2D(width, height, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, |
| VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TILE_MEMORY_BIT_QCOM | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::Image image{*m_device, image_ci, vkt::no_mem}; |
| |
| VkImageMemoryRequirementsInfo2 image_info = vku::InitStructHelper(); |
| VkTileMemoryRequirementsQCOM tile_mem_reqs = vku::InitStructHelper(); |
| VkMemoryRequirements2 image_reqs = vku::InitStructHelper(&tile_mem_reqs); |
| image_info.image = image; |
| vk::GetImageMemoryRequirements2(device(), &image_info, &image_reqs); |
| |
| if (tile_mem_reqs.size == 0) { |
| GTEST_SKIP() << "Image not eligible for tile memory binding, skipping test."; |
| } |
| |
| VkMemoryAllocateInfo alloc_info = vku::InitStructHelper(); |
| alloc_info.memoryTypeIndex = 0; |
| alloc_info.allocationSize = tile_mem_reqs.size; |
| bool pass = m_device->Physical().SetMemoryType(image_reqs.memoryRequirements.memoryTypeBits, &alloc_info, |
| VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, VK_MEMORY_HEAP_TILE_MEMORY_BIT_QCOM); |
| |
| if (!pass) { |
| GTEST_SKIP() << "Failed to find an eligible tile memory type, skipping test."; |
| } |
| |
| vkt::DeviceMemory image_memory{*m_device, alloc_info}; |
| vk::BindImageMemory(device(), image, image_memory, 0); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| OneOffDescriptorSet descriptor_set{m_device, |
| {{0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr}}}; |
| descriptor_set.WriteDescriptorImageInfo(0, image_view, VK_NULL_HANDLE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, |
| VK_IMAGE_LAYOUT_GENERAL); |
| descriptor_set.UpdateDescriptorSets(); |
| |
| const char* cs_source = R"glsl( |
| #version 460 |
| |
| #extension GL_QCOM_tile_shading : require |
| |
| layout(set = 0, binding = 0, tile_attachmentQCOM, rgba8) uniform readonly image2D storage_image; |
| layout(shading_rate_xQCOM = 1, shading_rate_yQCOM = 1, shading_rate_zQCOM = 1) in; |
| |
| void main(){ |
| vec4 data = imageLoad(storage_image, ivec2(0)); |
| } |
| )glsl"; |
| |
| CreateComputePipelineHelper compute_pipe{*this}; |
| compute_pipe.cs_ = VkShaderObj{*m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT}; |
| compute_pipe.pipeline_layout_ = vkt::PipelineLayout{*m_device, {&descriptor_set.layout_}}; |
| compute_pipe.CreateComputePipeline(); |
| |
| VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper(); |
| color_attachment.imageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| color_attachment.imageView = image_view; |
| |
| VkRenderPassTileShadingCreateInfoQCOM tile_info = vku::InitStructHelper(); |
| tile_info.flags = VK_TILE_SHADING_RENDER_PASS_ENABLE_BIT_QCOM; |
| tile_info.tileApronSize = {0, 0}; |
| |
| VkRenderingInfo begin_rendering_info = vku::InitStructHelper(&tile_info); |
| begin_rendering_info.colorAttachmentCount = 1; |
| begin_rendering_info.pColorAttachments = &color_attachment; |
| begin_rendering_info.layerCount = 1; |
| begin_rendering_info.renderArea = {{0, 0}, {width, height}}; |
| |
| VkDispatchTileInfoQCOM dispatch_tile_info = vku::InitStructHelper(); |
| VkPerTileBeginInfoQCOM per_tile_begin_info = vku::InitStructHelper(); |
| VkPerTileEndInfoQCOM per_tile_end_info = vku::InitStructHelper(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(begin_rendering_info); |
| vk::CmdBeginPerTileExecutionQCOM(m_command_buffer, &per_tile_begin_info); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipe); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, |
| compute_pipe.pipeline_layout_, 0, 1, &descriptor_set.set_, |
| 0, nullptr); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchTileQCOM-commandBuffer-10746"); |
| vk::CmdDispatchTileQCOM(m_command_buffer, &dispatch_tile_info); |
| m_errorMonitor->VerifyFound(); |
| vk::CmdEndPerTileExecutionQCOM(m_command_buffer, &per_tile_end_info); |
| m_command_buffer.EndRendering(); |
| m_command_buffer.End(); |
| } |