| /* |
| * Copyright (c) 2015-2025 The Khronos Group Inc. |
| * Copyright (c) 2015-2025 Valve Corporation |
| * Copyright (c) 2015-2025 LunarG, Inc. |
| * Copyright (c) 2015-2025 Google, Inc. |
| * Modifications Copyright (C) 2022 Advanced Micro Devices, Inc. All rights reserved. |
| * |
| * 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 <cmath> |
| #include "generated/vk_function_pointers.h" |
| #include "utils/cast_utils.h" |
| #include "../framework/layer_validation_tests.h" |
| #include "../framework/pipeline_helper.h" |
| #include "../framework/descriptor_helper.h" |
| #include "../framework/render_pass_helper.h" |
| |
| class NegativeCommand : public VkLayerTest {}; |
| |
| TEST_F(NegativeCommand, CommandPoolConsistency) { |
| TEST_DESCRIPTION("Allocate command buffers from one command pool and attempt to delete them from another."); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkFreeCommandBuffers-pCommandBuffers-parent"); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| VkCommandPoolCreateInfo pool_create_info = vku::InitStructHelper(); |
| pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_; |
| pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; |
| |
| vkt::CommandPool command_pool_1(*m_device, pool_create_info); |
| vkt::CommandPool command_pool_2(*m_device, pool_create_info); |
| |
| VkCommandBuffer cb; |
| VkCommandBufferAllocateInfo command_buffer_allocate_info = vku::InitStructHelper(); |
| command_buffer_allocate_info.commandPool = command_pool_1; |
| command_buffer_allocate_info.commandBufferCount = 1; |
| command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; |
| vk::AllocateCommandBuffers(device(), &command_buffer_allocate_info, &cb); |
| |
| vk::FreeCommandBuffers(device(), command_pool_2, 1, &cb); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, IndexBufferNotBound) { |
| TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound."); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-None-07312"); |
| // Use DrawIndexed w/o an index buffer bound |
| vk::CmdDrawIndexed(m_command_buffer, 3, 1, 0, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, IndexBufferNotBoundMaintenance6) { |
| TEST_DESCRIPTION("Just setting feature is not enough, need to set to null"); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_6_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance6); |
| AddRequiredFeature(vkt::Feature::nullDescriptor); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-None-07312"); |
| vk::CmdDrawIndexed(m_command_buffer, 0, 1, 0, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, IndexBufferDestroyed) { |
| TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound."); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| vkt::Buffer index_buffer(*m_device, 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| vk::CmdBindIndexBuffer(m_command_buffer, index_buffer, 0, VK_INDEX_TYPE_UINT32); |
| index_buffer.Destroy(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-commandBuffer-recording"); |
| // Use DrawIndexed w/o an index buffer bound |
| vk::CmdDrawIndexed(m_command_buffer, 3, 1, 0, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, IndexBufferSizeOffset) { |
| TEST_DESCRIPTION("Run bind index buffer with an offset greater than the size of the index buffer."); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| vkt::Buffer index_buffer(*m_device, 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindIndexBuffer(m_command_buffer, index_buffer, 512, VK_INDEX_TYPE_UINT16); |
| |
| // draw one past the end of the buffer |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-robustBufferAccess2-08798"); |
| vk::CmdDrawIndexed(m_command_buffer, 256, 1, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| // draw one too many indices |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-robustBufferAccess2-08798"); |
| vk::CmdDrawIndexed(m_command_buffer, 257, 1, 0, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| vk::CmdBindIndexBuffer(m_command_buffer, index_buffer, 0, VK_INDEX_TYPE_UINT16); |
| |
| // draw one too many indices |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-robustBufferAccess2-08798"); |
| vk::CmdDrawIndexed(m_command_buffer, 513, 1, 0, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| // draw one past the end of the buffer using the offset |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-robustBufferAccess2-08798"); |
| vk::CmdDrawIndexed(m_command_buffer, 512, 1, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, MissingClearAttachment) { |
| TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment structure passed to vkCmdClearAttachments"); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| |
| VkClearAttachment color_attachment = {VK_IMAGE_ASPECT_COLOR_BIT, 2, VkClearValue{}}; |
| VkClearRect clear_rect = {{{0, 0}, {m_width, m_height}}, 0, 1}; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-aspectMask-07271"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &color_attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| |
| color_attachment.colorAttachment = VK_ATTACHMENT_UNUSED; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-aspectMask-07271"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &color_attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, MissingClearAttachment2) { |
| TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment structure passed to vkCmdClearAttachments"); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| |
| VkClearAttachment color_attachment = {VK_IMAGE_ASPECT_COLOR_BIT, 1, VkClearValue{}}; |
| VkClearRect clear_rect = {{{0, 0}, {m_width, m_height}}, 0, 1}; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-aspectMask-07271"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &color_attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ClearAttachment64Bit) { |
| TEST_DESCRIPTION("Clear with a 64-bit format"); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_R64G64B64A64_SFLOAT, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) { |
| GTEST_SKIP() << "VK_FORMAT_R64G64B64A64_SFLOAT format not supported"; |
| } |
| vkt::Image image(*m_device, 32, 32, VK_FORMAT_R64G64B64A64_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| RenderPassSingleSubpass rp(*this); |
| rp.AddAttachmentDescription(VK_FORMAT_R64G64B64A64_SFLOAT); |
| rp.AddAttachmentReference({0, VK_IMAGE_LAYOUT_GENERAL}); |
| rp.AddColorAttachment(0); |
| rp.CreateRenderPass(); |
| vkt::Framebuffer fb(*m_device, rp, 1, &image_view.handle()); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp, fb); |
| |
| VkClearAttachment attachment; |
| attachment.colorAttachment = 0; |
| VkClearRect clear_rect = {}; |
| clear_rect.rect.offset = {0, 0}; |
| clear_rect.rect.extent = {1, 1}; |
| clear_rect.baseArrayLayer = 0; |
| clear_rect.layerCount = 1; |
| |
| attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-None-09679"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, CommandBufferTwoSubmits) { |
| m_errorMonitor->SetDesiredError("UNASSIGNED-DrawState-CommandBufferSingleSubmitViolation"); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| m_command_buffer.Begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); |
| m_command_buffer.End(); |
| |
| // Bypass framework since it does the waits automatically |
| m_default_queue->Submit(m_command_buffer); |
| m_default_queue->Wait(); |
| |
| // Cause validation error by re-submitting cmd buffer that should only be |
| // submitted once |
| m_default_queue->Submit(m_command_buffer); |
| m_default_queue->Wait(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, Sync2CommandBufferTwoSubmits) { |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::synchronization2); |
| RETURN_IF_SKIP(Init()); |
| |
| m_errorMonitor->SetDesiredError("UNASSIGNED-DrawState-CommandBufferSingleSubmitViolation"); |
| InitRenderTarget(); |
| |
| m_command_buffer.Begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); |
| m_command_buffer.End(); |
| |
| // Bypass framework since it does the waits automatically |
| VkCommandBufferSubmitInfo cb_info = vku::InitStructHelper(); |
| cb_info.commandBuffer = m_command_buffer; |
| |
| VkSubmitInfo2 submit_info = vku::InitStructHelper(); |
| submit_info.commandBufferInfoCount = 1; |
| submit_info.pCommandBufferInfos = &cb_info; |
| |
| vk::QueueSubmit2KHR(m_default_queue->handle(), 1, &submit_info, VK_NULL_HANDLE); |
| m_default_queue->Wait(); |
| |
| // Cause validation error by re-submitting cmd buffer that should only be |
| // submitted once |
| vk::QueueSubmit2KHR(m_default_queue->handle(), 1, &submit_info, VK_NULL_HANDLE); |
| m_default_queue->Wait(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, PushConstants) { |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkPipelineLayout pipeline_layout; |
| VkPushConstantRange pc_range = {}; |
| VkPipelineLayoutCreateInfo pipeline_layout_ci = vku::InitStructHelper(); |
| pipeline_layout_ci.pushConstantRangeCount = 1; |
| pipeline_layout_ci.pPushConstantRanges = &pc_range; |
| |
| // Check for invalid push constant ranges in pipeline layouts. |
| struct PipelineLayoutTestCase { |
| VkPushConstantRange const range; |
| const char *msg; |
| }; |
| |
| const uint32_t too_big = m_device->Physical().limits_.maxPushConstantsSize + 0x4; |
| const std::array<PipelineLayoutTestCase, 10> range_tests = {{ |
| {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, "VUID-VkPushConstantRange-size-00296"}, |
| {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1}, "VUID-VkPushConstantRange-size-00297"}, |
| {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1}, "VUID-VkPushConstantRange-size-00297"}, |
| {{VK_SHADER_STAGE_VERTEX_BIT, 4, 0}, "VUID-VkPushConstantRange-size-00296"}, |
| {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4}, "VUID-VkPushConstantRange-offset-00295"}, |
| {{VK_SHADER_STAGE_VERTEX_BIT, 0, too_big}, "VUID-VkPushConstantRange-size-00298"}, |
| {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big}, "VUID-VkPushConstantRange-offset-00294"}, |
| {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 4}, "VUID-VkPushConstantRange-offset-00294"}, |
| {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020}, "VUID-VkPushConstantRange-offset-00294"}, |
| {{VK_SHADER_STAGE_VERTEX_BIT, 0x00000020, 0xFFFFFFF0}, "VUID-VkPushConstantRange-size-00298"}, |
| }}; |
| |
| // Check for invalid offset and size |
| for (const auto &iter : range_tests) { |
| pc_range = iter.range; |
| m_errorMonitor->SetDesiredError(iter.msg); |
| vk::CreatePipelineLayout(device(), &pipeline_layout_ci, NULL, &pipeline_layout); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Check for invalid stage flag |
| pc_range.offset = 0; |
| pc_range.size = 16; |
| pc_range.stageFlags = 0; |
| m_errorMonitor->SetDesiredError("VUID-VkPushConstantRange-stageFlags-requiredbitmask"); |
| vk::CreatePipelineLayout(device(), &pipeline_layout_ci, NULL, &pipeline_layout); |
| m_errorMonitor->VerifyFound(); |
| |
| // Check for duplicate stage flags in a list of push constant ranges. |
| // A shader can only have one push constant block and that block is mapped |
| // to the push constant range that has that shader's stage flag set. |
| // The shader's stage flag can only appear once in all the ranges, so the |
| // implementation can find the one and only range to map it to. |
| const uint32_t ranges_per_test = 5; |
| struct DuplicateStageFlagsTestCase { |
| VkPushConstantRange const ranges[ranges_per_test]; |
| std::vector<const char *> const msg; |
| }; |
| // Overlapping ranges are OK, but a stage flag can appear only once. |
| const std::array<DuplicateStageFlagsTestCase, 3> duplicate_stage_flags_tests = { |
| { |
| {{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, |
| {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, |
| {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, |
| {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, |
| {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}}, |
| { |
| "VUID-VkPipelineLayoutCreateInfo-pPushConstantRanges-00292", |
| "VUID-VkPipelineLayoutCreateInfo-pPushConstantRanges-00292", |
| "VUID-VkPipelineLayoutCreateInfo-pPushConstantRanges-00292", |
| "VUID-VkPipelineLayoutCreateInfo-pPushConstantRanges-00292", |
| }}, |
| {{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, |
| {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}, |
| {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4}, |
| {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, |
| {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}}, |
| { |
| "VUID-VkPipelineLayoutCreateInfo-pPushConstantRanges-00292", |
| "VUID-VkPipelineLayoutCreateInfo-pPushConstantRanges-00292", |
| }}, |
| {{{VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4}, |
| {VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 4}, |
| {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, |
| {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, |
| {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}}, |
| { |
| "VUID-VkPipelineLayoutCreateInfo-pPushConstantRanges-00292", |
| }}, |
| }, |
| }; |
| |
| for (const auto &iter : duplicate_stage_flags_tests) { |
| pipeline_layout_ci.pPushConstantRanges = iter.ranges; |
| pipeline_layout_ci.pushConstantRangeCount = ranges_per_test; |
| for (const auto &vuid : iter.msg) { |
| m_errorMonitor->SetDesiredError(vuid); |
| } |
| vk::CreatePipelineLayout(device(), &pipeline_layout_ci, NULL, &pipeline_layout); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // |
| // CmdPushConstants tests |
| // |
| |
| // Setup a pipeline layout with ranges: [0,32) [16,80) |
| const std::vector<VkPushConstantRange> pc_range2 = {{VK_SHADER_STAGE_VERTEX_BIT, 16, 64}, |
| {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 32}}; |
| const vkt::PipelineLayout pipeline_layout_obj(*m_device, {}, pc_range2); |
| |
| const uint8_t dummy_values[100] = {}; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| // Check for invalid stage flag |
| // Note that VU 07790 isn't reached due to parameter validation |
| m_errorMonitor->SetDesiredError("VUID-vkCmdPushConstants-stageFlags-requiredbitmask"); |
| vk::CmdPushConstants(m_command_buffer, pipeline_layout_obj, 0, 0, 16, dummy_values); |
| m_errorMonitor->VerifyFound(); |
| |
| // Positive tests for the overlapping ranges |
| vk::CmdPushConstants(m_command_buffer, pipeline_layout_obj, VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, dummy_values); |
| vk::CmdPushConstants(m_command_buffer, pipeline_layout_obj, VK_SHADER_STAGE_VERTEX_BIT, 32, 48, dummy_values); |
| vk::CmdPushConstants(m_command_buffer, pipeline_layout_obj, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 16, 16, |
| dummy_values); |
| |
| // Wrong cmd stages for extant range |
| // No range for all cmd stages -- "VUID-vkCmdPushConstants-offset-01795" VUID-vkCmdPushConstants-offset-01795 |
| m_errorMonitor->SetDesiredError("VUID-vkCmdPushConstants-offset-01795"); |
| // Missing cmd stages for found overlapping range -- "VUID-vkCmdPushConstants-offset-01796" VUID-vkCmdPushConstants-offset-01796 |
| m_errorMonitor->SetDesiredError("VUID-vkCmdPushConstants-offset-01796"); |
| vk::CmdPushConstants(m_command_buffer, pipeline_layout_obj, VK_SHADER_STAGE_GEOMETRY_BIT, 0, 16, dummy_values); |
| m_errorMonitor->VerifyFound(); |
| |
| // Wrong no extant range |
| m_errorMonitor->SetDesiredError("VUID-vkCmdPushConstants-offset-01795"); |
| vk::CmdPushConstants(m_command_buffer, pipeline_layout_obj, VK_SHADER_STAGE_FRAGMENT_BIT, 80, 4, dummy_values); |
| m_errorMonitor->VerifyFound(); |
| |
| // Wrong overlapping extent |
| m_errorMonitor->SetDesiredError("VUID-vkCmdPushConstants-offset-01795"); |
| vk::CmdPushConstants(m_command_buffer, pipeline_layout_obj, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 20, |
| dummy_values); |
| m_errorMonitor->VerifyFound(); |
| |
| // Wrong stage flags for valid overlapping range |
| m_errorMonitor->SetDesiredError("VUID-vkCmdPushConstants-offset-01796"); |
| vk::CmdPushConstants(m_command_buffer, pipeline_layout_obj, VK_SHADER_STAGE_VERTEX_BIT, 16, 16, dummy_values); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, PushConstant2PipelineLayoutCreateInfo) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_6_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance6); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| const float data[16] = {}; |
| VkPushConstantsInfo pc_info = vku::InitStructHelper(); |
| pc_info.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; |
| pc_info.offset = 32; |
| pc_info.size = 16; |
| pc_info.pValues = data; |
| pc_info.layout = VK_NULL_HANDLE; |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-VkPushConstantsInfo-None-09495"); |
| vk::CmdPushConstants2KHR(m_command_buffer, &pc_info); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, NoBeginCommandBuffer) { |
| RETURN_IF_SKIP(Init()); |
| m_errorMonitor->SetDesiredError("VUID-vkEndCommandBuffer-commandBuffer-00059"); |
| vk::EndCommandBuffer(m_command_buffer); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, CommandBufferReset) { |
| // Cause error due to Begin while recording CB |
| // Then cause 2 errors for attempting to reset CB w/o having |
| // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set for the pool from |
| // which CBs were allocated. Note that this bit is off by default. |
| m_errorMonitor->SetDesiredError("VUID-vkBeginCommandBuffer-commandBuffer-00049"); |
| |
| RETURN_IF_SKIP(InitFramework()); |
| RETURN_IF_SKIP(InitState(nullptr, nullptr, 0)); |
| |
| // Force the failure by setting the Renderpass and Framebuffer fields with (fake) data |
| VkCommandBufferInheritanceInfo cmd_buf_hinfo = vku::InitStructHelper(); |
| VkCommandBufferBeginInfo cmd_buf_info = vku::InitStructHelper(); |
| cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; |
| cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo; |
| |
| // Begin CB to transition to recording state |
| vk::BeginCommandBuffer(m_command_buffer, &cmd_buf_info); |
| // Can't re-begin. This should trigger error |
| vk::BeginCommandBuffer(m_command_buffer, &cmd_buf_info); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkResetCommandBuffer-commandBuffer-00046"); |
| VkCommandBufferResetFlags flags = 0; // Don't care about flags for this test |
| // Reset attempt will trigger error due to incorrect CommandPool state |
| vk::ResetCommandBuffer(m_command_buffer, flags); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkBeginCommandBuffer-commandBuffer-00050"); |
| // Transition CB to RECORDED state |
| vk::EndCommandBuffer(m_command_buffer); |
| // Now attempting to Begin will implicitly reset, which triggers error |
| vk::BeginCommandBuffer(m_command_buffer, &cmd_buf_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, CommandBufferPrimaryFlags) { |
| RETURN_IF_SKIP(Init()); |
| VkCommandBufferBeginInfo cmd_buf_info = vku::InitStructHelper(); |
| cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; |
| m_errorMonitor->SetDesiredError("VUID-vkBeginCommandBuffer-commandBuffer-02840"); |
| vk::BeginCommandBuffer(m_command_buffer, &cmd_buf_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ClearColorAttachmentsOutsideRenderPass) { |
| // Call CmdClearAttachmentss outside of an active RenderPass |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-renderpass"); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| // Start no RenderPass |
| m_command_buffer.Begin(); |
| |
| VkClearAttachment color_attachment; |
| color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| color_attachment.clearValue.color.float32[0] = 0; |
| color_attachment.clearValue.color.float32[1] = 0; |
| color_attachment.clearValue.color.float32[2] = 0; |
| color_attachment.clearValue.color.float32[3] = 0; |
| color_attachment.colorAttachment = 0; |
| VkClearRect clear_rect = {{{0, 0}, {32, 32}}, 0, 1}; |
| vk::CmdClearAttachments(m_command_buffer, 1, &color_attachment, 1, &clear_rect); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ClearColorAttachmentsZeroLayercount) { |
| TEST_DESCRIPTION("Call CmdClearAttachments with a pRect having a layerCount of zero."); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-layerCount-01934"); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBeginRenderPass(m_command_buffer, &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); |
| |
| VkClearAttachment color_attachment; |
| color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| color_attachment.clearValue.color.float32[0] = 0; |
| color_attachment.clearValue.color.float32[1] = 0; |
| color_attachment.clearValue.color.float32[2] = 0; |
| color_attachment.clearValue.color.float32[3] = 0; |
| color_attachment.colorAttachment = 0; |
| VkClearRect clear_rect = {{{0, 0}, {32, 32}}}; |
| vk::CmdClearAttachments(m_command_buffer, 1, &color_attachment, 1, &clear_rect); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ClearColorAttachmentsZeroExtent) { |
| TEST_DESCRIPTION("Call CmdClearAttachments with a pRect having a rect2D extent of zero."); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBeginRenderPass(m_command_buffer, &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); |
| |
| VkClearAttachment color_attachment; |
| color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| color_attachment.clearValue.color.float32[0] = 0; |
| color_attachment.clearValue.color.float32[1] = 0; |
| color_attachment.clearValue.color.float32[2] = 0; |
| color_attachment.clearValue.color.float32[3] = 0; |
| color_attachment.colorAttachment = 0; |
| VkClearRect clear_rect = {}; |
| clear_rect.rect.offset = {0, 0}; |
| clear_rect.baseArrayLayer = 0; |
| clear_rect.layerCount = 1; |
| |
| clear_rect.rect.extent = {0, 1}; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-rect-02682"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &color_attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| |
| clear_rect.rect.extent = {1, 0}; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-rect-02683"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &color_attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ClearAttachmentsAspectMasks) { |
| TEST_DESCRIPTION("Check VkClearAttachment invalid aspect masks."); |
| AddRequiredExtensions(VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBeginRenderPass(m_command_buffer, &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); |
| |
| VkClearAttachment attachment; |
| attachment.clearValue.color.float32[0] = 0; |
| attachment.clearValue.color.float32[1] = 0; |
| attachment.clearValue.color.float32[2] = 0; |
| attachment.clearValue.color.float32[3] = 0; |
| attachment.colorAttachment = 0; |
| VkClearRect clear_rect = {}; |
| clear_rect.rect.offset = {0, 0}; |
| clear_rect.rect.extent = {1, 1}; |
| clear_rect.baseArrayLayer = 0; |
| clear_rect.layerCount = 1; |
| |
| attachment.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT; |
| m_errorMonitor->SetDesiredError("VUID-VkClearAttachment-aspectMask-00020"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| |
| attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_METADATA_BIT; |
| m_errorMonitor->SetDesiredError("VUID-VkClearAttachment-aspectMask-00020"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| |
| attachment.aspectMask = VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT; |
| m_errorMonitor->SetDesiredError("VUID-VkClearAttachment-aspectMask-02246"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| |
| attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT; |
| m_errorMonitor->SetDesiredError("VUID-VkClearAttachment-aspectMask-02246"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ClearAttachmentsImplicitCheck) { |
| TEST_DESCRIPTION("Check VkClearAttachment implicit VUs."); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBeginRenderPass(m_command_buffer, &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); |
| |
| VkClearAttachment color_attachment; |
| color_attachment.clearValue.color.float32[0] = 0; |
| color_attachment.clearValue.color.float32[1] = 0; |
| color_attachment.clearValue.color.float32[2] = 0; |
| color_attachment.clearValue.color.float32[3] = 0; |
| color_attachment.colorAttachment = 0; |
| VkClearRect clear_rect = {}; |
| clear_rect.rect.offset = {0, 0}; |
| clear_rect.rect.extent = {1, 1}; |
| clear_rect.baseArrayLayer = 0; |
| clear_rect.layerCount = 1; |
| |
| color_attachment.aspectMask = 0; |
| m_errorMonitor->SetDesiredError("VUID-VkClearAttachment-aspectMask-requiredbitmask"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &color_attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| |
| color_attachment.aspectMask = 0xffffffff; |
| m_errorMonitor->SetDesiredError("VUID-VkClearAttachment-aspectMask-parameter"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &color_attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ClearAttachmentsDepth) { |
| TEST_DESCRIPTION("Call CmdClearAttachments with invalid depth aspect masks."); |
| |
| RETURN_IF_SKIP(Init()); |
| m_depth_stencil_fmt = FindSupportedStencilOnlyFormat(Gpu()); |
| if (m_depth_stencil_fmt == VK_FORMAT_UNDEFINED) { |
| GTEST_SKIP() << "Couldn't find a stencil only image format"; |
| } |
| |
| m_depthStencil->Init(*m_device, m_width, m_height, 1, m_depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); |
| vkt::ImageView depth_image_view = m_depthStencil->CreateView(VK_IMAGE_ASPECT_STENCIL_BIT); |
| InitRenderTarget(&depth_image_view.handle()); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBeginRenderPass(m_command_buffer, &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); |
| |
| VkClearAttachment attachment; |
| attachment.colorAttachment = 0; |
| VkClearRect clear_rect = {}; |
| clear_rect.rect.offset = {0, 0}; |
| clear_rect.rect.extent = {1, 1}; |
| clear_rect.baseArrayLayer = 0; |
| clear_rect.layerCount = 1; |
| |
| attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| vk::CmdClearAttachments(m_command_buffer, 1, &attachment, 1, &clear_rect); |
| |
| attachment.clearValue.depthStencil.depth = 0.0f; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-aspectMask-07884"); |
| attachment.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; |
| vk::CmdClearAttachments(m_command_buffer, 1, &attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ClearAttachmentsStencil) { |
| TEST_DESCRIPTION("Call CmdClearAttachments with invalid stencil aspect masks."); |
| |
| RETURN_IF_SKIP(Init()); |
| m_depth_stencil_fmt = FindSupportedDepthOnlyFormat(Gpu()); |
| m_depthStencil->Init(*m_device, m_width, m_height, 1, m_depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); |
| vkt::ImageView depth_image_view = m_depthStencil->CreateView(VK_IMAGE_ASPECT_DEPTH_BIT); |
| InitRenderTarget(&depth_image_view.handle()); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBeginRenderPass(m_command_buffer, &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); |
| |
| VkClearAttachment attachment; |
| attachment.colorAttachment = 0; |
| VkClearRect clear_rect = {}; |
| clear_rect.rect.offset = {0, 0}; |
| clear_rect.rect.extent = {1, 1}; |
| clear_rect.baseArrayLayer = 0; |
| clear_rect.layerCount = 1; |
| |
| attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| vk::CmdClearAttachments(m_command_buffer, 1, &attachment, 1, &clear_rect); |
| |
| attachment.clearValue.depthStencil.depth = 0.0f; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-aspectMask-07885"); |
| attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; |
| vk::CmdClearAttachments(m_command_buffer, 1, &attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ClearAttachmentsOutsideRenderPass) { |
| TEST_DESCRIPTION("Call CmdClearAttachments outside renderpass"); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| m_command_buffer.Begin(); |
| VkClearAttachment attachment; |
| attachment.colorAttachment = 0; |
| VkClearRect clear_rect = {}; |
| clear_rect.rect.offset = {0, 0}; |
| clear_rect.rect.extent = {1, 1}; |
| clear_rect.baseArrayLayer = 0; |
| clear_rect.layerCount = 1; |
| attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-renderpass"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, DrawOutsideRenderPass) { |
| TEST_DESCRIPTION("call vkCmdDraw without renderpass"); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-renderpass"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, DispatchInsideRenderPass) { |
| TEST_DESCRIPTION("Only allowed with VK_QCOM_tile_shading"); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| CreateComputePipelineHelper pipe(*this); |
| pipe.CreateComputePipeline(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatch-None-10672"); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, MultiDrawDrawOutsideRenderPass) { |
| AddRequiredExtensions(VK_EXT_MULTI_DRAW_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::multiDraw); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkMultiDrawInfoEXT multi_draws[3] = {}; |
| multi_draws[0].vertexCount = multi_draws[1].vertexCount = multi_draws[2].vertexCount = 3; |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiEXT-renderpass"); |
| vk::CmdDrawMultiEXT(m_command_buffer, 3, multi_draws, 1, 0, sizeof(VkMultiDrawInfoEXT)); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ExecuteCommandsPrimaryCB) { |
| TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a primary command buffer (should only be secondary)"); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| // An empty primary command buffer |
| vkt::CommandBuffer cb(*m_device, m_command_pool); |
| cb.Begin(); |
| cb.End(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBeginRenderPass(m_command_buffer, &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| VkCommandBuffer handle = cb; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-00088"); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &handle); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetUnexpectedError("All elements of pCommandBuffers must not be in the pending state"); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, SimultaneousUseOneShot) { |
| TEST_DESCRIPTION("Submit the same command buffer twice in one submit looking for simultaneous use and one time submit errors"); |
| const char *simultaneous_use_message = "is already in use and is not marked for simultaneous use"; |
| RETURN_IF_SKIP(Init()); |
| |
| VkCommandBuffer cmd_bufs[2]; |
| VkCommandBufferAllocateInfo alloc_info = vku::InitStructHelper(); |
| alloc_info.commandBufferCount = 2; |
| alloc_info.commandPool = m_command_pool; |
| alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; |
| vk::AllocateCommandBuffers(device(), &alloc_info, cmd_bufs); |
| |
| VkCommandBufferBeginInfo cb_binfo = vku::InitStructHelper(); |
| cb_binfo.pInheritanceInfo = VK_NULL_HANDLE; |
| cb_binfo.flags = 0; |
| vk::BeginCommandBuffer(cmd_bufs[0], &cb_binfo); |
| VkViewport viewport = {0, 0, 16, 16, 0, 1}; |
| vk::CmdSetViewport(cmd_bufs[0], 0, 1, &viewport); |
| vk::EndCommandBuffer(cmd_bufs[0]); |
| VkCommandBuffer duplicates[2] = {cmd_bufs[0], cmd_bufs[0]}; |
| |
| VkSubmitInfo submit_info = vku::InitStructHelper(); |
| submit_info.commandBufferCount = 2; |
| submit_info.pCommandBuffers = duplicates; |
| m_errorMonitor->SetDesiredError(simultaneous_use_message); |
| vk::QueueSubmit(m_default_queue->handle(), 1, &submit_info, VK_NULL_HANDLE); |
| m_errorMonitor->VerifyFound(); |
| m_default_queue->Wait(); |
| |
| // Set one time use and now look for one time submit |
| duplicates[0] = duplicates[1] = cmd_bufs[1]; |
| cb_binfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; |
| vk::BeginCommandBuffer(cmd_bufs[1], &cb_binfo); |
| vk::CmdSetViewport(cmd_bufs[1], 0, 1, &viewport); |
| vk::EndCommandBuffer(cmd_bufs[1]); |
| m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00071"); |
| m_errorMonitor->SetDesiredError("UNASSIGNED-DrawState-CommandBufferSingleSubmitViolation"); |
| vk::QueueSubmit(m_default_queue->handle(), 1, &submit_info, VK_NULL_HANDLE); |
| m_errorMonitor->VerifyFound(); |
| m_default_queue->Wait(); |
| } |
| |
| TEST_F(NegativeCommand, DrawTimeImageViewTypeMismatchWithPipeline) { |
| TEST_DESCRIPTION( |
| "Test that an error is produced when an image view type does not match the dimensionality declared in the shader"); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| const char *fs_source = R"glsl( |
| #version 450 |
| layout(set=0, binding=0) uniform sampler3D s; |
| layout(location=0) out vec4 color; |
| void main() { |
| color = texture(s, vec3(0)); |
| } |
| )glsl"; |
| VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT); |
| |
| vkt::Image image(*m_device, 16, 16, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT); |
| vkt::ImageView image_view = image.CreateView(); |
| vkt::Sampler sampler(*m_device, SafeSaneSamplerCreateInfo()); |
| |
| OneOffDescriptorSet descriptor_set(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}, |
| }); |
| vkt::PipelineLayout pipeline_layout(*m_device, {&descriptor_set.layout_}); |
| |
| descriptor_set.WriteDescriptorImageInfo(0, image_view, sampler); |
| descriptor_set.UpdateDescriptorSets(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()}; |
| pipe.gp_ci_.layout = pipeline_layout; |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &descriptor_set.set_, 0, |
| nullptr); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-viewType-07752"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, DrawTimeImageViewTypeMismatchWithPipelineFunction) { |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| const char *fs_source = R"glsl( |
| #version 450 |
| layout(set=0, binding=0) uniform sampler3D s; |
| layout(location=0) out vec4 color; |
| |
| vec4 foo(sampler3D func_sampler) { |
| return texture(func_sampler, vec3(0)); |
| } |
| |
| void main() { |
| color = foo(s); |
| } |
| )glsl"; |
| VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT); |
| |
| vkt::Image image(*m_device, 16, 16, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT); |
| vkt::ImageView image_view = image.CreateView(); |
| vkt::Sampler sampler(*m_device, SafeSaneSamplerCreateInfo()); |
| |
| OneOffDescriptorSet descriptor_set(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}, |
| }); |
| vkt::PipelineLayout pipeline_layout(*m_device, {&descriptor_set.layout_}); |
| |
| descriptor_set.WriteDescriptorImageInfo(0, image_view, sampler); |
| descriptor_set.UpdateDescriptorSets(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()}; |
| pipe.gp_ci_.layout = pipeline_layout; |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &descriptor_set.set_, 0, |
| nullptr); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-viewType-07752"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, DrawTimeImageComponentTypeMismatchWithPipeline) { |
| TEST_DESCRIPTION( |
| "Test that an error is produced when the component type of an imageview disagrees with the type in the shader."); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| const char *fs_source = R"glsl( |
| #version 450 |
| layout(set=0, binding=0) uniform isampler2D s; |
| layout(location=0) out vec4 color; |
| void main() { |
| color = texelFetch(s, ivec2(0), 0); |
| } |
| )glsl"; |
| VkShaderObj fs(*m_device, fs_source, VK_SHADER_STAGE_FRAGMENT_BIT); |
| |
| vkt::Image image(*m_device, 16, 16, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT); |
| vkt::ImageView image_view = image.CreateView(); |
| vkt::Sampler sampler(*m_device, SafeSaneSamplerCreateInfo()); |
| |
| OneOffDescriptorSet descriptor_set(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}, |
| }); |
| vkt::PipelineLayout pipeline_layout(*m_device, {&descriptor_set.layout_}); |
| |
| descriptor_set.WriteDescriptorImageInfo(0, image_view, sampler); |
| descriptor_set.UpdateDescriptorSets(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()}; |
| pipe.gp_ci_.layout = pipeline_layout; |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &descriptor_set.set_, 0, |
| nullptr); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-format-07753"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImageLowSampleCount) { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcImage-00257"); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Required formats/features not supported"; |
| } |
| |
| // Create two images of sample count 1 and try to Resolve between them |
| VkImageCreateInfo image_create_info = vkt::Image::ImageCreateInfo2D( |
| 32, 1, 1, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| vkt::Image src_image(*m_device, image_create_info, vkt::set_layout); |
| vkt::Image dst_image(*m_device, image_create_info, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| VkImageResolve resolve_region; |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| vk::CmdResolveImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_command_buffer.End(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImageHighSampleCount) { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-dstImage-00259"); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Required formats/features not supported"; |
| } |
| |
| // Create two images of sample count 4 and try to Resolve between them |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; |
| image_create_info.extent = {32, 32, 1}; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 1; |
| image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| // Note: Some implementations expect color attachment usage for any |
| // multisample surface |
| image_create_info.usage = |
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_create_info.flags = 0; |
| |
| vkt::Image src_image(*m_device, image_create_info, vkt::set_layout); |
| vkt::Image dst_image(*m_device, image_create_info, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest? |
| // VK_IMAGE_LAYOUT_UNDEFINED = 0, |
| // VK_IMAGE_LAYOUT_GENERAL = 1, |
| VkImageResolve resolve_region; |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| vk::CmdResolveImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_command_buffer.End(); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImageFormatMismatch) { |
| RETURN_IF_SKIP(Init()); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Required formats/features not supported"; |
| } |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; |
| image_create_info.extent = {32, 1, 1}; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 1; |
| image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; // guarantee support from sampledImageColorSampleCounts |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| // Note: Some implementations expect color attachment usage for any |
| // multisample surface |
| image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_create_info.flags = 0; |
| vkt::Image src_image(*m_device, image_create_info, vkt::set_layout); |
| |
| // Set format to something other than source image |
| image_create_info.format = VK_FORMAT_R32_SFLOAT; |
| // Note: Some implementations expect color attachment usage for any |
| // multisample surface |
| image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_image(*m_device, image_create_info, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest? |
| // VK_IMAGE_LAYOUT_UNDEFINED = 0, |
| // VK_IMAGE_LAYOUT_GENERAL = 1, |
| VkImageResolve resolve_region; |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcImage-01386"); |
| vk::CmdResolveImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImageLayoutMismatch) { |
| RETURN_IF_SKIP(Init()); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Required formats/features not supported"; |
| } |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; |
| image_create_info.extent = {32, 32, 1}; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 1; |
| image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; // guarantee support from sampledImageColorSampleCounts |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = |
| VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| // Note: Some implementations expect color attachment usage for any |
| // multisample surface |
| image_create_info.flags = 0; |
| vkt::Image src_image(*m_device, image_create_info); |
| |
| // Note: Some implementations expect color attachment usage for any |
| // multisample surface |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_image(*m_device, image_create_info); |
| |
| m_command_buffer.Begin(); |
| // source image must have valid contents before resolve |
| VkClearColorValue clear_color = {{0, 0, 0, 0}}; |
| VkImageSubresourceRange subresource = {}; |
| subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| subresource.layerCount = 1; |
| subresource.levelCount = 1; |
| src_image.SetLayout(m_command_buffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); |
| vk::CmdClearColorImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource); |
| src_image.TransitionLayout(m_command_buffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); |
| dst_image.SetLayout(m_command_buffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); |
| |
| VkImageResolve resolve_region; |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| // source image layout mismatch |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcImageLayout-00260"); |
| vk::CmdResolveImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| // dst image layout mismatch |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-dstImageLayout-00262"); |
| vk::CmdResolveImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveInvalidSubresource) { |
| AddOptionalExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| const bool copy_commands2 = IsExtensionsEnabled(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Required formats/features not supported"; |
| } |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; |
| image_create_info.extent = {32, 32, 1}; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 1; |
| image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; // guarantee support from sampledImageColorSampleCounts |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = |
| VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| // Note: Some implementations expect color attachment usage for any |
| // multisample surface |
| image_create_info.flags = 0; |
| vkt::Image src_image(*m_device, image_create_info); |
| |
| // Note: Some implementations expect color attachment usage for any |
| // multisample surface |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dstImage(*m_device, image_create_info); |
| |
| m_command_buffer.Begin(); |
| // source image must have valid contents before resolve |
| VkClearColorValue clear_color = {{0, 0, 0, 0}}; |
| VkImageSubresourceRange subresource = {}; |
| subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| subresource.layerCount = 1; |
| subresource.levelCount = 1; |
| src_image.SetLayout(m_command_buffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); |
| vk::CmdClearColorImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource); |
| src_image.TransitionLayout(m_command_buffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); |
| dstImage.SetLayout(m_command_buffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); |
| |
| VkImageResolve resolve_region; |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| // invalid source mip level |
| resolve_region.srcSubresource.mipLevel = image_create_info.mipLevels; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcSubresource-01709"); |
| vk::CmdResolveImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| |
| // Equivalent test using KHR_copy_commands2 |
| if (copy_commands2) { |
| const VkImageResolve2 resolve_region2 = {VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2, |
| NULL, |
| resolve_region.srcSubresource, |
| resolve_region.srcOffset, |
| resolve_region.dstSubresource, |
| resolve_region.dstOffset, |
| resolve_region.extent}; |
| const VkResolveImageInfo2 resolve_image_info2 = { |
| VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2, NULL, src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve_region2}; |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcSubresource-01709"); |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_image_info2); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| resolve_region.srcSubresource.mipLevel = 0; |
| // invalid dest mip level |
| resolve_region.dstSubresource.mipLevel = image_create_info.mipLevels; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-dstSubresource-01710"); |
| vk::CmdResolveImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| |
| // Equivalent test using KHR_copy_commands2 |
| if (copy_commands2) { |
| const VkImageResolve2 resolve_region2 = {VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2, |
| NULL, |
| resolve_region.srcSubresource, |
| resolve_region.srcOffset, |
| resolve_region.dstSubresource, |
| resolve_region.dstOffset, |
| resolve_region.extent}; |
| const VkResolveImageInfo2 resolve_image_info2 = { |
| VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2, NULL, src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve_region2}; |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-dstSubresource-01710"); |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_image_info2); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| resolve_region.dstSubresource.mipLevel = 0; |
| // invalid source array layer range |
| resolve_region.srcSubresource.baseArrayLayer = image_create_info.arrayLayers; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcSubresource-01711"); |
| vk::CmdResolveImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| |
| // Equivalent test using KHR_copy_commands2 |
| if (copy_commands2) { |
| const VkImageResolve2 resolve_region2 = {VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2, |
| NULL, |
| resolve_region.srcSubresource, |
| resolve_region.srcOffset, |
| resolve_region.dstSubresource, |
| resolve_region.dstOffset, |
| resolve_region.extent}; |
| const VkResolveImageInfo2 resolve_image_info2 = { |
| VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2, NULL, src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve_region2}; |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcSubresource-01711"); |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_image_info2); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| resolve_region.srcSubresource.baseArrayLayer = 0; |
| // invalid dest array layer range |
| resolve_region.dstSubresource.baseArrayLayer = image_create_info.arrayLayers; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-dstSubresource-01712"); |
| vk::CmdResolveImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| |
| // Equivalent test using KHR_copy_commands2 |
| if (copy_commands2) { |
| const VkImageResolve2 resolve_region2 = {VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2, |
| NULL, |
| resolve_region.srcSubresource, |
| resolve_region.srcOffset, |
| resolve_region.dstSubresource, |
| resolve_region.dstOffset, |
| resolve_region.extent}; |
| const VkResolveImageInfo2 resolve_image_info2 = { |
| VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2, NULL, src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve_region2}; |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-dstSubresource-01712"); |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_image_info2); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| resolve_region.dstSubresource.baseArrayLayer = 0; |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImageImageType) { |
| RETURN_IF_SKIP(Init()); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Required formats/features not supported"; |
| } |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; |
| image_create_info.extent = {32, 1, 1}; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 4; // more than 1 to not trip other validation |
| image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; // guarantee support from sampledImageColorSampleCounts |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = |
| VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| // Note: Some implementations expect color attachment usage for any |
| // multisample surface |
| image_create_info.flags = 0; |
| |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| vkt::Image src_image2D(*m_device, image_create_info, vkt::set_layout); |
| |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.imageType = VK_IMAGE_TYPE_1D; |
| vkt::Image dst_image1D(*m_device, image_create_info, vkt::set_layout); |
| |
| image_create_info.imageType = VK_IMAGE_TYPE_3D; |
| image_create_info.extent.height = 16; |
| image_create_info.extent.depth = 16; |
| image_create_info.arrayLayers = 1; |
| vkt::Image dst_image3D(*m_device, image_create_info, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve resolve_region; |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| // layerCount is not 1 |
| resolve_region.srcSubresource.layerCount = 2; |
| m_errorMonitor->SetDesiredError("VUID-VkImageResolve-layerCount-08803"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcImage-04446"); |
| vk::CmdResolveImage(m_command_buffer, src_image2D, VK_IMAGE_LAYOUT_GENERAL, dst_image3D, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| resolve_region.srcSubresource.layerCount = 1; |
| |
| // Set height with 1D dstImage |
| resolve_region.extent.height = 2; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-dstImage-00276"); |
| // Also exceed height of both images |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcOffset-00270"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-dstOffset-00275"); |
| vk::CmdResolveImage(m_command_buffer, src_image2D, VK_IMAGE_LAYOUT_GENERAL, dst_image1D, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| resolve_region.extent.height = 1; |
| |
| // Set depth with 1D dstImage and 2D srcImage |
| resolve_region.extent.depth = 2; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-dstImage-00278"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcImage-00273"); |
| vk::CmdResolveImage(m_command_buffer, src_image2D, VK_IMAGE_LAYOUT_GENERAL, dst_image1D, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| resolve_region.extent.depth = 1; |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImageSizeExceeded) { |
| TEST_DESCRIPTION("Resolve Image with subresource region greater than size of src/dst image"); |
| RETURN_IF_SKIP(Init()); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Required formats/features not supported"; |
| } |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM; |
| image_create_info.extent = {32, 32, 1}; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 1; |
| image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = |
| VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| // Note: Some implementations expect color attachment usage for any |
| // multisample surface |
| image_create_info.flags = 0; |
| |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| vkt::Image src_image2D(*m_device, image_create_info, vkt::set_layout); |
| |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dstImage2D(*m_device, image_create_info, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve resolve_region = {}; |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {32, 32, 1}; |
| |
| vk::CmdResolveImage(m_command_buffer, src_image2D, VK_IMAGE_LAYOUT_GENERAL, dstImage2D, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| |
| // srcImage exceeded in x-dim |
| resolve_region.srcOffset.x = 4; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcOffset-00269"); |
| vk::CmdResolveImage(m_command_buffer, src_image2D, VK_IMAGE_LAYOUT_GENERAL, dstImage2D, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| resolve_region.srcOffset.x = 0; |
| |
| // dstImage exceeded in x-dim |
| resolve_region.dstOffset.x = 4; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-dstOffset-00274"); |
| vk::CmdResolveImage(m_command_buffer, src_image2D, VK_IMAGE_LAYOUT_GENERAL, dstImage2D, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| resolve_region.dstOffset.x = 0; |
| |
| // both image exceeded in y-dim |
| resolve_region.srcOffset.y = 32; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcOffset-00270"); |
| vk::CmdResolveImage(m_command_buffer, src_image2D, VK_IMAGE_LAYOUT_GENERAL, dstImage2D, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| resolve_region.srcOffset.y = 0; |
| |
| resolve_region.dstOffset.y = 32; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-dstOffset-00275"); |
| vk::CmdResolveImage(m_command_buffer, src_image2D, VK_IMAGE_LAYOUT_GENERAL, dstImage2D, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| resolve_region.dstOffset.y = 0; |
| |
| // srcImage exceeded in z-dim |
| resolve_region.srcOffset.z = 1; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcOffset-00272"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcImage-00273"); // because it's a 2d image |
| vk::CmdResolveImage(m_command_buffer, src_image2D, VK_IMAGE_LAYOUT_GENERAL, dstImage2D, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| resolve_region.srcOffset.z = 0; |
| |
| // dstImage exceeded in z-dim |
| resolve_region.dstOffset.z = 1; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-dstOffset-00277"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-dstImage-00278"); // because it's a 2d image |
| vk::CmdResolveImage(m_command_buffer, src_image2D, VK_IMAGE_LAYOUT_GENERAL, dstImage2D, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| resolve_region.dstOffset.z = 0; |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ClearImage) { |
| TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and ClearDepthStencilImage with a color image."); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| m_command_buffer.Begin(); |
| |
| // Color image |
| VkClearColorValue clear_color; |
| memset(clear_color.uint32, 0, sizeof(uint32_t) * 4); |
| |
| auto image_ci = vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT); |
| vkt::Image color_image_no_transfer(*m_device, image_ci); |
| |
| image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
| vkt::Image color_image(*m_device, image_ci); |
| |
| const VkImageSubresourceRange color_range{VK_IMAGE_ASPECT_COLOR_BIT, 0, image_ci.mipLevels, 0, image_ci.arrayLayers}; |
| |
| // Depth/Stencil image |
| VkClearDepthStencilValue clear_value = {0}; |
| image_ci.format = VK_FORMAT_D16_UNORM; |
| image_ci.extent = {64, 64, 1}; |
| image_ci.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
| vkt::Image ds_image(*m_device, image_ci); |
| |
| const VkImageSubresourceRange ds_range{VK_IMAGE_ASPECT_DEPTH_BIT, 0, image_ci.mipLevels, 0, image_ci.arrayLayers}; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-image-00007"); |
| |
| vk::CmdClearColorImage(m_command_buffer, ds_image, VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &color_range); |
| |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-image-00002"); |
| |
| vk::CmdClearColorImage(m_command_buffer, color_image_no_transfer, VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &color_range); |
| |
| m_errorMonitor->VerifyFound(); |
| |
| // Call CmdClearDepthStencilImage with color image |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-image-00014"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-image-02826"); |
| |
| vk::CmdClearDepthStencilImage(m_command_buffer, color_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value, 1, &ds_range); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ClearColor64Bit) { |
| TEST_DESCRIPTION("Clear with a 64-bit format"); |
| RETURN_IF_SKIP(Init()); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_R64G64B64A64_SFLOAT, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "VK_FORMAT_R64G64B64A64_SFLOAT format not supported"; |
| } |
| vkt::Image image(*m_device, 32, 32, VK_FORMAT_R64G64B64A64_SFLOAT, VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| |
| m_command_buffer.Begin(); |
| const VkClearColorValue clear_color = {{0.0f, 0.0f, 0.0f, 1.0f}}; |
| VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-image-09678"); |
| vk::CmdClearColorImage(m_command_buffer, image, VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, CommandQueueFlags) { |
| TEST_DESCRIPTION( |
| "Allocate a command buffer on a queue that does not support graphics and try to issue a graphics-only command"); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| const std::optional<uint32_t> queue_family_index = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT); |
| if (!queue_family_index) { |
| GTEST_SKIP() << "Non-graphics queue family not found"; |
| } |
| |
| // Create command pool on a non-graphics queue |
| vkt::CommandPool command_pool(*m_device, queue_family_index.value()); |
| |
| // Setup command buffer on pool |
| vkt::CommandBuffer command_buffer(*m_device, command_pool); |
| command_buffer.Begin(); |
| |
| // Issue a graphics only command |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetViewport-commandBuffer-cmdpool"); |
| VkViewport viewport = {0, 0, 16, 16, 0, 1}; |
| vk::CmdSetViewport(command_buffer, 0, 1, &viewport); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, MultiDraw) { |
| TEST_DESCRIPTION("Test validation of multi_draw extension"); |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_EXT_MULTI_DRAW_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::multiDraw); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceMultiDrawPropertiesEXT multi_draw_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(multi_draw_properties); |
| InitRenderTarget(); |
| |
| VkMultiDrawInfoEXT multi_draws[3] = {}; |
| multi_draws[0].vertexCount = multi_draws[1].vertexCount = multi_draws[2].vertexCount = 3; |
| |
| VkMultiDrawIndexedInfoEXT multi_draw_indices[3] = {}; |
| multi_draw_indices[0].indexCount = multi_draw_indices[1].indexCount = multi_draw_indices[2].indexCount = 1; |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| // Try existing VUID checks |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_, 0, 1, |
| &pipe.descriptor_set_->set_, 0, NULL); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiEXT-None-08606"); |
| vk::CmdDrawMultiEXT(m_command_buffer, 3, multi_draws, 1, 0, sizeof(VkMultiDrawInfoEXT)); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiIndexedEXT-None-07312"); // missing index buffer |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiIndexedEXT-None-08606"); |
| vk::CmdDrawMultiIndexedEXT(m_command_buffer, 3, multi_draw_indices, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), 0); |
| m_errorMonitor->VerifyFound(); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| |
| // New VUIDs added with multi_draw (also see GPU-AV) |
| vkt::Buffer buffer(*m_device, 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| multi_draw_indices[2].indexCount = 511; |
| vk::CmdBindIndexBuffer(m_command_buffer, buffer, 2, VK_INDEX_TYPE_UINT16); |
| // This first should be fine |
| vk::CmdDrawMultiIndexedEXT(m_command_buffer, 3, multi_draw_indices, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), 0); |
| // Fail with index offset |
| multi_draw_indices[2].firstIndex = 1; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiIndexedEXT-robustBufferAccess2-08798"); |
| // Fail with index count |
| multi_draw_indices[2].firstIndex = 0; |
| multi_draw_indices[2].indexCount = 512; |
| vk::CmdDrawMultiIndexedEXT(m_command_buffer, 3, multi_draw_indices, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), 0); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiIndexedEXT-robustBufferAccess2-08798"); |
| vk::CmdDrawMultiIndexedEXT(m_command_buffer, 3, multi_draw_indices, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), 0); |
| m_errorMonitor->VerifyFound(); |
| multi_draw_indices[2].indexCount = 1; |
| |
| vk::CmdBindIndexBuffer(m_command_buffer, buffer, 0, VK_INDEX_TYPE_UINT16); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiEXT-drawCount-09628"); |
| vk::CmdDrawMultiEXT(m_command_buffer, 3, multi_draws, 1, 0, sizeof(VkMultiDrawInfoEXT) + 1); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiIndexedEXT-drawCount-09629"); |
| vk::CmdDrawMultiIndexedEXT(m_command_buffer, 3, multi_draw_indices, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT) + 1, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiEXT-drawCount-04935"); |
| vk::CmdDrawMultiEXT(m_command_buffer, 3, nullptr, 1, 0, sizeof(VkMultiDrawInfoEXT)); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiIndexedEXT-drawCount-04940"); |
| vk::CmdDrawMultiIndexedEXT(m_command_buffer, 3, nullptr, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), 0); |
| m_errorMonitor->VerifyFound(); |
| |
| if (multi_draw_properties.maxMultiDrawCount < vvl::kU32Max) { |
| uint32_t draw_count = multi_draw_properties.maxMultiDrawCount + 1; |
| std::vector<VkMultiDrawInfoEXT> max_multi_draws(draw_count); |
| std::vector<VkMultiDrawIndexedInfoEXT> max_multi_indexed_draws(draw_count); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiEXT-drawCount-04934"); |
| vk::CmdDrawMultiEXT(m_command_buffer, draw_count, max_multi_draws.data(), 1, 0, sizeof(VkMultiDrawInfoEXT)); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiIndexedEXT-drawCount-04939"); |
| vk::CmdDrawMultiIndexedEXT(m_command_buffer, draw_count, max_multi_indexed_draws.data(), 1, 0, |
| sizeof(VkMultiDrawIndexedInfoEXT), 0); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeCommand, MultiDrawMaintenance5) { |
| TEST_DESCRIPTION("Test validation of multi_draw extension with VK_KHR_maintenance5"); |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_EXT_MULTI_DRAW_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance5); |
| AddRequiredFeature(vkt::Feature::multiDraw); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| // Try existing VUID checks |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_, 0, 1, |
| &pipe.descriptor_set_->set_, 0, NULL); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| |
| // Use non-power-of-2 size to |
| vkt::Buffer buffer(*m_device, 2048, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| |
| VkMultiDrawIndexedInfoEXT multi_draw_indices = {0, 514, 0}; // overflow |
| |
| // same as calling vkCmdBindIndexBuffer (size of the buffer creation) |
| vk::CmdBindIndexBuffer2KHR(m_command_buffer, buffer, 2, 1024, VK_INDEX_TYPE_UINT16); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiIndexedEXT-robustBufferAccess2-08798"); |
| vk::CmdDrawMultiIndexedEXT(m_command_buffer, 1, &multi_draw_indices, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), 0); |
| m_errorMonitor->VerifyFound(); |
| |
| multi_draw_indices.indexCount = 256; // only uses [0 - 512] |
| vk::CmdBindIndexBuffer2KHR(m_command_buffer, buffer, 2, 508, VK_INDEX_TYPE_UINT16); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiIndexedEXT-robustBufferAccess2-08798"); |
| vk::CmdDrawMultiIndexedEXT(m_command_buffer, 1, &multi_draw_indices, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), 0); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, MultiDrawWholeSizeMaintenance5) { |
| TEST_DESCRIPTION("Test validation of multi_draw extension with VK_KHR_maintenance5"); |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_EXT_MULTI_DRAW_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance5); |
| AddRequiredFeature(vkt::Feature::multiDraw); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| // Try existing VUID checks |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_, 0, 1, |
| &pipe.descriptor_set_->set_, 0, NULL); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| |
| // Use non-power-of-2 size to |
| vkt::Buffer buffer(*m_device, 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| |
| VkMultiDrawIndexedInfoEXT multi_draw_indices = {0, 514, 0}; // overflow |
| |
| // VK_WHOLE_SIZE also full size of the buffer |
| vk::CmdBindIndexBuffer2KHR(m_command_buffer, buffer, 2, VK_WHOLE_SIZE, VK_INDEX_TYPE_UINT16); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiIndexedEXT-robustBufferAccess2-08798"); |
| vk::CmdDrawMultiIndexedEXT(m_command_buffer, 1, &multi_draw_indices, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), 0); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, MultiDrawMaintenance5Mixed) { |
| TEST_DESCRIPTION("Test vkCmdBindIndexBuffer2KHR with vkCmdBindIndexBuffer"); |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_EXT_MULTI_DRAW_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance5); |
| AddRequiredFeature(vkt::Feature::multiDraw); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| // Try existing VUID checks |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_, 0, 1, |
| &pipe.descriptor_set_->set_, 0, NULL); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| |
| // New VUIDs added with multi_draw (also see GPU-AV) |
| vkt::Buffer buffer(*m_device, 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| VkMultiDrawIndexedInfoEXT multi_draw_indices = {0, 511, 0}; |
| |
| // valid |
| vk::CmdBindIndexBuffer(m_command_buffer, buffer, 0, VK_INDEX_TYPE_UINT16); |
| // should be overwritten with smaller size |
| vk::CmdBindIndexBuffer2KHR(m_command_buffer, buffer, 0, 1000, VK_INDEX_TYPE_UINT16); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiIndexedEXT-robustBufferAccess2-08798"); |
| vk::CmdDrawMultiIndexedEXT(m_command_buffer, 1, &multi_draw_indices, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), 0); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, MultiDrawFeatures) { |
| TEST_DESCRIPTION("Test validation of multi draw feature enabled"); |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_EXT_MULTI_DRAW_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkMultiDrawInfoEXT multi_draws[3] = {}; |
| multi_draws[0].vertexCount = multi_draws[1].vertexCount = multi_draws[2].vertexCount = 3; |
| |
| VkMultiDrawIndexedInfoEXT multi_draw_indices[3] = {}; |
| multi_draw_indices[0].indexCount = multi_draw_indices[1].indexCount = multi_draw_indices[2].indexCount = 1; |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiEXT-None-04933"); |
| vk::CmdDrawMultiEXT(m_command_buffer, 3, multi_draws, 1, 0, sizeof(VkMultiDrawInfoEXT)); |
| m_errorMonitor->VerifyFound(); |
| vkt::Buffer buffer(*m_device, 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| vk::CmdBindIndexBuffer(m_command_buffer, buffer, 0, VK_INDEX_TYPE_UINT16); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawMultiIndexedEXT-None-04937"); |
| vk::CmdDrawMultiIndexedEXT(m_command_buffer, 3, multi_draw_indices, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), 0); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, IndirectDraw) { |
| TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirect and vkCmdDrawIndexedIndirect"); |
| |
| AddRequiredFeature(vkt::Feature::multiDrawIndirect); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_, 0, 1, |
| &pipe.descriptor_set_->set_, 0, NULL); |
| |
| vkt::Buffer draw_buffer(*m_device, sizeof(VkDrawIndirectCommand), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); |
| vkt::Buffer draw_buffer_correct(*m_device, sizeof(VkDrawIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT); |
| vkt::Buffer draw_buffer_large(*m_device, sizeof(VkDrawIndirectCommand) * 16u, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT); |
| vkt::Buffer index_buffer(*m_device, sizeof(uint32_t), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| vk::CmdBindIndexBuffer(m_command_buffer, index_buffer, 0, VK_INDEX_TYPE_UINT32); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirect-buffer-02709"); |
| vk::CmdDrawIndirect(m_command_buffer, draw_buffer, 0, 1, sizeof(VkDrawIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirect-drawCount-00488"); |
| vk::CmdDrawIndirect(m_command_buffer, draw_buffer_correct, 0, 2, sizeof(VkDrawIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirect-drawCount-00540"); |
| vk::CmdDrawIndexedIndirect(m_command_buffer, draw_buffer_correct, 0, 2, sizeof(VkDrawIndexedIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirect-offset-02710"); |
| vk::CmdDrawIndexedIndirect(m_command_buffer, draw_buffer_large, 2, 1, sizeof(VkDrawIndexedIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, MultiDrawIndirectFeature) { |
| TEST_DESCRIPTION("use vkCmdDrawIndexedIndirect without MultiDrawIndirect"); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| if (m_device->Physical().limits_.maxDrawIndirectCount < 2) { |
| GTEST_SKIP() << "maxDrawIndirectCount is too low"; |
| } |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| vkt::Buffer draw_buffer(*m_device, sizeof(VkDrawIndirectCommand) * 3, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, |
| VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| |
| vkt::Buffer index_buffer(*m_device, sizeof(uint32_t), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| vk::CmdBindIndexBuffer(m_command_buffer, index_buffer, 0, VK_INDEX_TYPE_UINT32); |
| |
| vk::CmdDrawIndexedIndirect(m_command_buffer, draw_buffer, 0, 0, sizeof(VkDrawIndexedIndirectCommand)); |
| vk::CmdDrawIndexedIndirect(m_command_buffer, draw_buffer, 0, 1, sizeof(VkDrawIndexedIndirectCommand)); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirect-drawCount-02718"); |
| vk::CmdDrawIndexedIndirect(m_command_buffer, draw_buffer, 0, 2, sizeof(VkDrawIndexedIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, StrideMultiDrawIndirect) { |
| TEST_DESCRIPTION("Validate Stride parameter."); |
| AddRequiredFeature(vkt::Feature::multiDrawIndirect); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| const uint32_t buffer_size = 128; |
| vkt::Buffer buffer(*m_device, buffer_size, |
| VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT); |
| |
| CreatePipelineHelper helper(*this); |
| helper.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| |
| auto buf_memory_barrier = buffer.BufferMemoryBarrier( |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INDIRECT_COMMAND_READ_BIT | VK_ACCESS_INDEX_READ_BIT, 0, VK_WHOLE_SIZE); |
| vk::CmdPipelineBarrier(m_command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, |
| VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 0, nullptr, 1, |
| &buf_memory_barrier, 0, nullptr); |
| |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, helper.Handle()); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirect-drawCount-00476"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirect-drawCount-00488"); |
| vk::CmdDrawIndirect(m_command_buffer, buffer, 0, 100, 2); |
| m_errorMonitor->VerifyFound(); |
| |
| vk::CmdDrawIndirect(m_command_buffer, buffer, 0, 2, 24); |
| |
| vk::CmdBindIndexBuffer(m_command_buffer, buffer, 0, VK_INDEX_TYPE_UINT16); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirect-drawCount-00528"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirect-drawCount-00540"); |
| vk::CmdDrawIndexedIndirect(m_command_buffer, buffer, 0, 100, 2); |
| m_errorMonitor->VerifyFound(); |
| |
| auto draw_count = m_device->Physical().limits_.maxDrawIndirectCount; |
| if (draw_count != vvl::kU32Max) { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirect-drawCount-02719"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirect-drawCount-00476"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirect-drawCount-00488"); |
| vk::CmdDrawIndirect(m_command_buffer, buffer, 0, draw_count + 1, 2); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirect-drawCount-00487"); |
| vk::CmdDrawIndirect(m_command_buffer, buffer, buffer_size, 1, 2); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirect-drawCount-00539"); |
| vk::CmdDrawIndexedIndirect(m_command_buffer, buffer, buffer_size, 1, 2); |
| m_errorMonitor->VerifyFound(); |
| |
| vk::CmdDrawIndexedIndirect(m_command_buffer, buffer, 0, 2, 24); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, DrawIndirectCountKHR) { |
| TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirectCountKHR"); |
| |
| AddRequiredExtensions(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_, 0, 1, |
| &pipe.descriptor_set_->set_, 0, NULL); |
| |
| VkBufferCreateInfo buffer_create_info = vku::InitStructHelper(); |
| buffer_create_info.size = sizeof(VkDrawIndirectCommand); |
| buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; |
| vkt::Buffer draw_buffer(*m_device, buffer_create_info, vkt::no_mem); |
| |
| VkDeviceSize count_buffer_size = 128; |
| VkBufferCreateInfo count_buffer_create_info = vku::InitStructHelper(); |
| count_buffer_create_info.size = count_buffer_size; |
| count_buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; |
| vkt::Buffer count_buffer(*m_device, count_buffer_create_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirectCount-buffer-02708"); |
| vk::CmdDrawIndirectCountKHR(m_command_buffer, draw_buffer, 0, count_buffer, 0, 1, sizeof(VkDrawIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| draw_buffer.AllocateAndBindMemory(*m_device); |
| |
| vkt::Buffer count_buffer_unbound(*m_device, count_buffer_create_info, vkt::no_mem); |
| |
| count_buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; |
| vkt::Buffer count_buffer_wrong(*m_device, count_buffer_create_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirectCount-countBuffer-02714"); |
| vk::CmdDrawIndirectCountKHR(m_command_buffer, draw_buffer, 0, count_buffer_unbound, 0, 1, sizeof(VkDrawIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirectCount-countBuffer-02715"); |
| vk::CmdDrawIndirectCountKHR(m_command_buffer, draw_buffer, 0, count_buffer_wrong, 0, 1, sizeof(VkDrawIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirectCount-offset-02710"); |
| vk::CmdDrawIndirectCountKHR(m_command_buffer, draw_buffer, 1, count_buffer, 0, 1, sizeof(VkDrawIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirectCount-countBufferOffset-02716"); |
| vk::CmdDrawIndirectCountKHR(m_command_buffer, draw_buffer, 0, count_buffer, 1, 1, sizeof(VkDrawIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirectCount-countBufferOffset-04129"); |
| vk::CmdDrawIndirectCountKHR(m_command_buffer, draw_buffer, 0, count_buffer, count_buffer_size, 1, |
| sizeof(VkDrawIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirectCount-stride-03110"); |
| vk::CmdDrawIndirectCountKHR(m_command_buffer, draw_buffer, 0, count_buffer, 0, 1, 1); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, DrawIndexedIndirectCountKHR) { |
| TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndexedIndirectCountKHR"); |
| |
| AddRequiredExtensions(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_, 0, 1, |
| &pipe.descriptor_set_->set_, 0, NULL); |
| |
| VkBufferCreateInfo buffer_create_info = vku::InitStructHelper(); |
| buffer_create_info.size = sizeof(VkDrawIndexedIndirectCommand); |
| buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; |
| vkt::Buffer draw_buffer(*m_device, buffer_create_info); |
| |
| VkDeviceSize count_buffer_size = 128; |
| VkBufferCreateInfo count_buffer_create_info = vku::InitStructHelper(); |
| count_buffer_create_info.size = count_buffer_size; |
| count_buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; |
| vkt::Buffer count_buffer(*m_device, count_buffer_create_info); |
| |
| VkBufferCreateInfo index_buffer_create_info = vku::InitStructHelper(); |
| index_buffer_create_info.size = sizeof(uint32_t); |
| index_buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; |
| vkt::Buffer index_buffer(*m_device, index_buffer_create_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirectCount-None-07312"); |
| vk::CmdDrawIndexedIndirectCountKHR(m_command_buffer, draw_buffer, 0, count_buffer, 0, 1, sizeof(VkDrawIndexedIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| vk::CmdBindIndexBuffer(m_command_buffer, index_buffer, 0, VK_INDEX_TYPE_UINT32); |
| |
| vkt::Buffer draw_buffer_unbound(*m_device, count_buffer_create_info, vkt::no_mem); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirectCount-buffer-02708"); |
| vk::CmdDrawIndexedIndirectCountKHR(m_command_buffer, draw_buffer_unbound, 0, count_buffer, 0, 1, |
| sizeof(VkDrawIndexedIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| vkt::Buffer count_buffer_unbound(*m_device, count_buffer_create_info, vkt::no_mem); |
| |
| count_buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; |
| vkt::Buffer count_buffer_wrong(*m_device, count_buffer_create_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirectCount-countBuffer-02714"); |
| vk::CmdDrawIndexedIndirectCountKHR(m_command_buffer, draw_buffer, 0, count_buffer_unbound, 0, 1, |
| sizeof(VkDrawIndexedIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirectCount-countBuffer-02715"); |
| vk::CmdDrawIndexedIndirectCountKHR(m_command_buffer, draw_buffer, 0, count_buffer_wrong, 0, 1, |
| sizeof(VkDrawIndexedIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirectCount-offset-02710"); |
| vk::CmdDrawIndexedIndirectCountKHR(m_command_buffer, draw_buffer, 1, count_buffer, 0, 1, sizeof(VkDrawIndexedIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirectCount-countBufferOffset-02716"); |
| vk::CmdDrawIndexedIndirectCountKHR(m_command_buffer, draw_buffer, 0, count_buffer, 1, 1, sizeof(VkDrawIndexedIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirectCount-countBufferOffset-04129"); |
| vk::CmdDrawIndexedIndirectCountKHR(m_command_buffer, draw_buffer, 0, count_buffer, count_buffer_size, 1, |
| sizeof(VkDrawIndexedIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirectCount-stride-03142"); |
| vk::CmdDrawIndexedIndirectCountKHR(m_command_buffer, draw_buffer, 0, count_buffer, 0, 1, 1); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, DrawIndirectCountFeature) { |
| TEST_DESCRIPTION("Test covered valid usage for the 1.2 drawIndirectCount feature"); |
| |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| vkt::Buffer indirect_buffer(*m_device, sizeof(VkDrawIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, |
| VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| |
| vkt::Buffer indexed_indirect_buffer(*m_device, sizeof(VkDrawIndexedIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, |
| VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| |
| vkt::Buffer count_buffer(*m_device, sizeof(uint32_t), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| |
| vkt::Buffer index_buffer(*m_device, sizeof(uint32_t), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| // Make calls to valid commands but without the drawIndirectCount feature set |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirectCount-None-04445"); |
| vk::CmdDrawIndirectCount(m_command_buffer, indirect_buffer, 0, count_buffer, 0, 1, sizeof(VkDrawIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| vk::CmdBindIndexBuffer(m_command_buffer, index_buffer, 0, VK_INDEX_TYPE_UINT32); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirectCount-None-04445"); |
| vk::CmdDrawIndexedIndirectCount(m_command_buffer, indexed_indirect_buffer, 0, count_buffer, 0, 1, |
| sizeof(VkDrawIndexedIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ExclusiveScissorNV) { |
| TEST_DESCRIPTION("Test VK_NV_scissor_exclusive with multiViewport disabled."); |
| |
| AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME); |
| |
| AddRequiredFeature(vkt::Feature::exclusiveScissor); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| if (m_device->Physical().limits_.maxViewports <= 1) { |
| GTEST_SKIP() << "Device doesn't support multiple viewports"; |
| } |
| |
| // Based on PSOViewportStateTests |
| { |
| VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f}; |
| VkViewport viewports[] = {viewport, viewport}; |
| VkRect2D scissor = {{0, 0}, {64, 64}}; |
| VkRect2D scissors[100] = {scissor, scissor}; |
| |
| struct TestCase { |
| uint32_t viewport_count; |
| VkViewport *viewports; |
| uint32_t scissor_count; |
| VkRect2D *scissors; |
| uint32_t exclusive_scissor_count; |
| VkRect2D *exclusive_scissors; |
| |
| std::vector<std::string> vuids; |
| }; |
| |
| std::vector<TestCase> test_cases = { |
| {1, |
| viewports, |
| 1, |
| scissors, |
| 2, |
| scissors, |
| {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027", |
| "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029"}}, |
| {1, |
| viewports, |
| 1, |
| scissors, |
| 100, |
| scissors, |
| {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027", |
| "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02028", |
| "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029"}}, |
| {1, viewports, 1, scissors, 1, nullptr, {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04056"}}, |
| }; |
| |
| for (const auto &test_case : test_cases) { |
| VkPipelineViewportExclusiveScissorStateCreateInfoNV exc = |
| vku::InitStructHelper(); |
| |
| const auto break_vp = [&test_case, &exc](CreatePipelineHelper &helper) { |
| helper.vp_state_ci_.viewportCount = test_case.viewport_count; |
| helper.vp_state_ci_.pViewports = test_case.viewports; |
| helper.vp_state_ci_.scissorCount = test_case.scissor_count; |
| helper.vp_state_ci_.pScissors = test_case.scissors; |
| helper.vp_state_ci_.pNext = &exc; |
| |
| exc.exclusiveScissorCount = test_case.exclusive_scissor_count; |
| exc.pExclusiveScissors = test_case.exclusive_scissors; |
| }; |
| CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit, test_case.vuids); |
| } |
| } |
| |
| // Based on SetDynScissorParamTests |
| { |
| const VkRect2D scissor = {{0, 0}, {16, 16}}; |
| const VkRect2D scissors[] = {scissor, scissor}; |
| |
| m_command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035"); |
| vk::CmdSetExclusiveScissorNV(m_command_buffer, 1, 1, scissors); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-arraylength"); |
| vk::CmdSetExclusiveScissorNV(m_command_buffer, 0, 0, nullptr); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036"); |
| vk::CmdSetExclusiveScissorNV(m_command_buffer, 0, 2, scissors); |
| m_errorMonitor->VerifyFound(); |
| |
| // This VU gets triggered before VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035 |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-arraylength"); |
| vk::CmdSetExclusiveScissorNV(m_command_buffer, 1, 0, scissors); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036"); |
| vk::CmdSetExclusiveScissorNV(m_command_buffer, 1, 2, scissors); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetExclusiveScissorNV-pExclusiveScissors-parameter"); |
| vk::CmdSetExclusiveScissorNV(m_command_buffer, 0, 1, nullptr); |
| m_errorMonitor->VerifyFound(); |
| |
| struct TestCase { |
| VkRect2D scissor; |
| std::string vuid; |
| }; |
| |
| std::vector<TestCase> test_cases = { |
| {{{-1, 0}, {16, 16}}, "VUID-vkCmdSetExclusiveScissorNV-x-02037"}, |
| {{{0, -1}, {16, 16}}, "VUID-vkCmdSetExclusiveScissorNV-x-02037"}, |
| {{{1, 0}, {vvl::kI32Max, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"}, |
| {{{vvl::kI32Max, 0}, {1, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"}, |
| {{{0, 0}, {uint32_t{vvl::kI32Max} + 1, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"}, |
| {{{0, 1}, {16, vvl::kI32Max}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"}, |
| {{{0, vvl::kI32Max}, {16, 1}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"}, |
| {{{0, 0}, {16, uint32_t{vvl::kI32Max} + 1}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"}}; |
| |
| for (const auto &test_case : test_cases) { |
| m_errorMonitor->SetDesiredError(test_case.vuid.c_str()); |
| vk::CmdSetExclusiveScissorNV(m_command_buffer, 0, 1, &test_case.scissor); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| m_command_buffer.End(); |
| } |
| } |
| |
| TEST_F(NegativeCommand, ViewportWScalingNV) { |
| TEST_DESCRIPTION("Verify VK_NV_clip_space_w_scaling"); |
| |
| AddRequiredExtensions(VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::multiViewport); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| const char vs_src[] = R"glsl( |
| #version 450 |
| const vec2 positions[] = { vec2(-1.0f, 1.0f), |
| vec2( 1.0f, 1.0f), |
| vec2(-1.0f, -1.0f), |
| vec2( 1.0f, -1.0f) }; |
| out gl_PerVertex { |
| vec4 gl_Position; |
| }; |
| |
| void main() { |
| gl_Position = vec4(positions[gl_VertexIndex % 4], 0.0f, 1.0f); |
| } |
| )glsl"; |
| |
| const char fs_src[] = R"glsl( |
| #version 450 |
| layout(location = 0) out vec4 outColor; |
| |
| void main() { |
| outColor = vec4(0.0f, 1.0f, 0.0f, 1.0f); |
| } |
| )glsl"; |
| |
| const std::vector<VkViewport> vp = { |
| {0.0f, 0.0f, 64.0f, 64.0f}, {0.0f, 0.0f, 64.0f, 64.0f}, {0.0f, 0.0f, 64.0f, 64.0f}, {0.0f, 0.0f, 64.0f, 64.0f}}; |
| const std::vector<VkRect2D> sc = {{{0, 0}, {32, 32}}, {{32, 0}, {32, 32}}, {{0, 32}, {32, 32}}, {{32, 32}, {32, 32}}}; |
| constexpr std::array scale = {VkViewportWScalingNV{-0.2f, -0.2f}, VkViewportWScalingNV{0.2f, -0.2f}, |
| VkViewportWScalingNV{-0.2f, 0.2f}, VkViewportWScalingNV{0.2f, 0.2f}}; |
| |
| const uint32_t vp_count = static_cast<uint32_t>(vp.size()); |
| |
| VkPipelineViewportWScalingStateCreateInfoNV vpsi = vku::InitStructHelper(); |
| vpsi.viewportWScalingEnable = VK_TRUE; |
| vpsi.viewportCount = vp_count; |
| vpsi.pViewportWScalings = scale.data(); |
| |
| VkPipelineViewportStateCreateInfo vpci = vku::InitStructHelper(&vpsi); |
| vpci.viewportCount = vp_count; |
| vpci.pViewports = vp.data(); |
| vpci.scissorCount = vp_count; |
| vpci.pScissors = sc.data(); |
| |
| const auto set_vpci = [&vpci](CreatePipelineHelper &helper) { helper.vp_state_ci_ = vpci; }; |
| |
| // Make sure no errors show up when creating the pipeline with w-scaling enabled |
| CreatePipelineHelper::OneshotTest(*this, set_vpci, kErrorBit); |
| |
| // Create pipeline with w-scaling enabled but without a valid scaling array |
| vpsi.pViewportWScalings = nullptr; |
| CreatePipelineHelper::OneshotTest(*this, set_vpci, kErrorBit, |
| std::vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-01715"})); |
| |
| vpsi.pViewportWScalings = scale.data(); |
| |
| // Create pipeline with w-scaling enabled but without matching viewport counts |
| vpsi.viewportCount = 1; |
| CreatePipelineHelper::OneshotTest( |
| *this, set_vpci, kErrorBit, |
| std::vector<std::string>({"VUID-VkPipelineViewportStateCreateInfo-viewportWScalingEnable-01726"})); |
| |
| VkShaderObj vs(*m_device, vs_src, VK_SHADER_STAGE_VERTEX_BIT); |
| VkShaderObj fs(*m_device, fs_src, VK_SHADER_STAGE_FRAGMENT_BIT); |
| |
| vpsi.viewportCount = vp_count; |
| CreatePipelineHelper pipe(*this); |
| pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()}; |
| pipe.vp_state_ci_ = vpci; |
| pipe.CreateGraphicsPipeline(); |
| |
| CreatePipelineHelper pipe_dynamic(*this); |
| pipe_dynamic.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()}; |
| pipe_dynamic.vp_state_ci_ = vpci; |
| pipe_dynamic.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV); |
| pipe_dynamic.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| |
| // Bind pipeline without dynamic w scaling enabled |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| |
| // Bind pipeline that has dynamic w-scaling enabled |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_dynamic); |
| |
| const auto max_vps = m_device->Physical().limits_.maxViewports; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetViewportWScalingNV-firstViewport-01324"); |
| vk::CmdSetViewportWScalingNV(m_command_buffer, 1, max_vps, scale.data()); |
| m_errorMonitor->VerifyFound(); |
| |
| vk::CmdSetViewportWScalingNV(m_command_buffer, 0, vp_count, scale.data()); |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, FilterCubicSamplerInCmdDraw) { |
| TEST_DESCRIPTION("Verify if sampler is filter cubic, image view needs to support it."); |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_EXT_FILTER_CUBIC_EXTENSION_NAME); |
| AddRequiredExtensions(VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; |
| VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; |
| |
| VkFormatProperties format_props; |
| vk::GetPhysicalDeviceFormatProperties(m_device->Physical(), format, &format_props); |
| if ((format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT) == 0) { |
| GTEST_SKIP() << "SAMPLED_IMAGE_FILTER_CUBIC_BIT for format is not supported."; |
| } |
| |
| auto image_ci = vkt::Image::ImageCreateInfo2D(128, 128, 1, 1, format, usage); |
| |
| VkPhysicalDeviceImageViewImageFormatInfoEXT imageview_format_info = vku::InitStructHelper(); |
| imageview_format_info.imageViewType = VK_IMAGE_VIEW_TYPE_2D; |
| VkPhysicalDeviceImageFormatInfo2 image_format_info = vku::InitStructHelper(&imageview_format_info); |
| image_format_info.type = image_ci.imageType; |
| image_format_info.format = image_ci.format; |
| image_format_info.tiling = image_ci.tiling; |
| image_format_info.usage = image_ci.usage; |
| image_format_info.flags = image_ci.flags; |
| |
| VkFilterCubicImageViewImageFormatPropertiesEXT filter_cubic_props = vku::InitStructHelper(); |
| VkImageFormatProperties2 image_format_properties = vku::InitStructHelper(&filter_cubic_props); |
| |
| vk::GetPhysicalDeviceImageFormatProperties2(Gpu(), &image_format_info, &image_format_properties); |
| |
| if (filter_cubic_props.filterCubic || filter_cubic_props.filterCubicMinmax) { |
| GTEST_SKIP() << "Image and ImageView supports filter cubic ; skipped."; |
| } |
| |
| vkt::Image image(*m_device, image_ci, vkt::set_layout); |
| vkt::ImageView image_view = image.CreateView(); |
| |
| VkSamplerCreateInfo sampler_ci = vku::InitStructHelper(); |
| sampler_ci.minFilter = VK_FILTER_CUBIC_EXT; |
| sampler_ci.magFilter = VK_FILTER_CUBIC_EXT; |
| vkt::Sampler sampler(*m_device, sampler_ci); |
| ASSERT_TRUE(sampler.initialized()); |
| |
| VkSamplerReductionModeCreateInfo reduction_mode_ci = vku::InitStructHelper(); |
| reduction_mode_ci.reductionMode = VK_SAMPLER_REDUCTION_MODE_MIN; |
| sampler_ci.pNext = &reduction_mode_ci; |
| vkt::Sampler sampler_reduction(*m_device, sampler_ci); |
| |
| VkShaderObj fs(*m_device, kFragmentSamplerGlsl, VK_SHADER_STAGE_FRAGMENT_BIT); |
| |
| CreatePipelineHelper g_pipe(*this); |
| g_pipe.shader_stages_ = {g_pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()}; |
| g_pipe.dsl_bindings_[0] = {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}; |
| g_pipe.CreateGraphicsPipeline(); |
| |
| g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, image_view, sampler_reduction); |
| g_pipe.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_, 0, 1, |
| &g_pipe.descriptor_set_->set_, 0, nullptr); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-filterCubicMinmax-02695"); |
| vk::CmdDraw(m_command_buffer, 1, 0, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| m_command_buffer.Reset(); |
| |
| g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, image_view, sampler); |
| g_pipe.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_, 0, 1, |
| &g_pipe.descriptor_set_->set_, 0, nullptr); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-filterCubic-02694"); |
| vk::CmdDraw(m_command_buffer, 1, 0, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ImageFilterCubicSamplerInCmdDraw) { |
| TEST_DESCRIPTION("Verify if sampler is filter cubic with the VK_IMG_filter cubic extension that it's a valid ImageViewType."); |
| |
| AddRequiredExtensions(VK_IMG_FILTER_CUBIC_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT)) { |
| GTEST_SKIP() << "Required formats/features not supported"; |
| } |
| |
| VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; |
| VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; |
| auto image_ci = vkt::Image::ImageCreateInfo2D(128, 128, 1, 1, format, usage); |
| image_ci.imageType = VK_IMAGE_TYPE_3D; |
| vkt::Image image(*m_device, image_ci, vkt::set_layout); |
| |
| vkt::ImageView image_view = image.CreateView(VK_IMAGE_VIEW_TYPE_3D); |
| |
| VkSamplerCreateInfo sampler_ci = vku::InitStructHelper(); |
| sampler_ci.minFilter = VK_FILTER_CUBIC_EXT; |
| sampler_ci.magFilter = VK_FILTER_CUBIC_EXT; |
| vkt::Sampler sampler(*m_device, sampler_ci); |
| ASSERT_TRUE(sampler.initialized()); |
| |
| const char fs_src[] = R"glsl( |
| #version 450 |
| layout(set=0, binding=0) uniform sampler3D s; |
| layout(location=0) out vec4 x; |
| void main(){ |
| x = texture(s, vec3(1)); |
| } |
| )glsl"; |
| VkShaderObj fs(*m_device, fs_src, VK_SHADER_STAGE_FRAGMENT_BIT); |
| |
| CreatePipelineHelper g_pipe(*this); |
| g_pipe.shader_stages_ = {g_pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()}; |
| g_pipe.dsl_bindings_[0] = {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}; |
| g_pipe.CreateGraphicsPipeline(); |
| |
| g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, image_view, sampler); |
| g_pipe.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_, 0, 1, |
| &g_pipe.descriptor_set_->set_, 0, nullptr); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-02693"); |
| vk::CmdDraw(m_command_buffer, 1, 0, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, CmdUpdateBufferSize) { |
| TEST_DESCRIPTION("Update buffer with invalid dataSize"); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| uint32_t update_data[4] = {0, 0, 0, 0}; |
| VkDeviceSize data_size = sizeof(uint32_t) * 4; |
| vkt::Buffer buffer(*m_device, data_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdUpdateBuffer-dataSize-00033"); |
| m_command_buffer.Begin(); |
| vk::CmdUpdateBuffer(m_command_buffer, buffer, sizeof(uint32_t), data_size, (void *)update_data); |
| m_command_buffer.End(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, CmdUpdateBufferDstOffset) { |
| TEST_DESCRIPTION("Update buffer with invalid dst offset"); |
| RETURN_IF_SKIP(Init()); |
| |
| uint32_t update_data[4] = {0, 0, 0, 0}; |
| VkDeviceSize data_size = sizeof(uint32_t) * 4; |
| vkt::Buffer buffer(*m_device, data_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdUpdateBuffer-dstOffset-00032"); |
| m_command_buffer.Begin(); |
| vk::CmdUpdateBuffer(m_command_buffer, buffer, sizeof(uint32_t) * 8, data_size, (void *)update_data); |
| m_command_buffer.End(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, DescriptorSetPipelineBindPoint) { |
| TEST_DESCRIPTION( |
| "Attempt to bind descriptor set to a bind point not supported by command pool the command buffer was allocated from"); |
| RETURN_IF_SKIP(Init()); |
| |
| const std::optional<uint32_t> compute_qfi = m_device->ComputeOnlyQueueFamily(); |
| if (!compute_qfi) { |
| GTEST_SKIP() << "No compute-only queue family, skipping bindpoint and queue tests."; |
| } |
| |
| OneOffDescriptorSet descriptor_set(m_device, { |
| {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, |
| }); |
| |
| const vkt::PipelineLayout pipeline_layout(*m_device, {&descriptor_set.layout_}); |
| |
| vkt::CommandPool command_pool(*m_device, compute_qfi.value()); |
| vkt::CommandBuffer command_buffer(*m_device, command_pool); |
| command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindDescriptorSets-pipelineBindPoint-00361"); |
| vk::CmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &descriptor_set.set_, 0, |
| nullptr); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, DescriptorSetPipelineBindPointMaintenance6) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_6_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance6); |
| RETURN_IF_SKIP(Init()); |
| |
| const std::optional<uint32_t> compute_qfi = m_device->ComputeOnlyQueueFamily(); |
| if (!compute_qfi) { |
| GTEST_SKIP() << "No compute-only queue family, skipping bindpoint and queue tests."; |
| } |
| |
| OneOffDescriptorSet descriptor_set(m_device, { |
| {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, |
| }); |
| |
| const vkt::PipelineLayout pipeline_layout(*m_device, {&descriptor_set.layout_}); |
| |
| vkt::CommandPool command_pool(*m_device, compute_qfi.value()); |
| vkt::CommandBuffer command_buffer(*m_device, command_pool); |
| command_buffer.Begin(); |
| |
| VkBindDescriptorSetsInfo bind_ds_info = vku::InitStructHelper(); |
| bind_ds_info.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; |
| bind_ds_info.layout = pipeline_layout; |
| bind_ds_info.firstSet = 0; |
| bind_ds_info.descriptorSetCount = 1; |
| bind_ds_info.pDescriptorSets = &descriptor_set.set_; |
| bind_ds_info.dynamicOffsetCount = 0; |
| bind_ds_info.pDynamicOffsets = nullptr; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindDescriptorSets2-pBindDescriptorSetsInfo-09467"); |
| vk::CmdBindDescriptorSets2KHR(command_buffer, &bind_ds_info); |
| m_errorMonitor->VerifyFound(); |
| |
| bind_ds_info.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; |
| bind_ds_info.descriptorSetCount = 0; |
| m_errorMonitor->SetDesiredError("VUID-VkBindDescriptorSetsInfo-descriptorSetCount-arraylength"); |
| vk::CmdBindDescriptorSets2KHR(command_buffer, &bind_ds_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, CmdClearColorImageNullColor) { |
| TEST_DESCRIPTION("Test invalid null entries for clear color"); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Image image(*m_device, 32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| |
| VkImageSubresourceRange isr = {}; |
| isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| isr.baseArrayLayer = 0; |
| isr.baseMipLevel = 0; |
| isr.layerCount = 1; |
| isr.levelCount = 1; |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-pColor-04961"); |
| vk::CmdClearColorImage(m_command_buffer, image, VK_IMAGE_LAYOUT_GENERAL, nullptr, 1, &isr); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, EndCommandBufferWithConditionalRendering) { |
| TEST_DESCRIPTION("Call EndCommandBuffer when conditional rendering is active"); |
| AddRequiredExtensions(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Buffer buffer(*m_device, 32, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT); |
| |
| VkConditionalRenderingBeginInfoEXT conditional_rendering_begin = vku::InitStructHelper(); |
| conditional_rendering_begin.buffer = buffer; |
| |
| VkCommandBufferBeginInfo command_buffer_begin = vku::InitStructHelper(); |
| |
| vk::BeginCommandBuffer(m_command_buffer, &command_buffer_begin); |
| vk::CmdBeginConditionalRenderingEXT(m_command_buffer, &conditional_rendering_begin); |
| m_errorMonitor->SetDesiredError("VUID-vkEndCommandBuffer-None-01978"); |
| vk::EndCommandBuffer(m_command_buffer); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, DrawBlendEnabledFormatFeatures) { |
| TEST_DESCRIPTION("Test pipeline blend enabled with missing image views format features"); |
| AddRequiredExtensions(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::extendedDynamicState3ColorBlendEnable); |
| RETURN_IF_SKIP(Init()); |
| |
| PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr; |
| PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr; |
| if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) { |
| GTEST_SKIP() << "Failed to load device profile layer."; |
| } |
| |
| const VkFormat render_format = GetRenderTargetFormat(); |
| |
| // Set format features from being found |
| VkFormatProperties formatProps; |
| fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(Gpu(), render_format, &formatProps); |
| if ((formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0) { |
| GTEST_SKIP() << "Required linear tiling features not supported"; |
| } |
| // Gets pass pipeline creation but not the actual tiling used |
| formatProps.optimalTilingFeatures |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT; |
| // will be caught at draw time that feature for optimal image is not set |
| // InitRenderTarget() should be setting color attachment as VK_IMAGE_TILING_LINEAR |
| formatProps.linearTilingFeatures &= ~VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT; |
| fpvkSetPhysicalDeviceFormatPropertiesEXT(Gpu(), render_format, formatProps); |
| |
| InitRenderTarget(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.cb_attachments_.blendEnable = VK_TRUE; |
| pipe.CreateGraphicsPipeline(); |
| |
| CreatePipelineHelper pipe2(*this); |
| pipe2.AddDynamicState(VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT); |
| pipe2.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-blendEnable-04727"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| VkBool32 color_blend_enable = VK_TRUE; |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe2); |
| vk::CmdSetColorBlendEnableEXT(m_command_buffer, 0, 1u, &color_blend_enable); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-blendEnable-04727"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| color_blend_enable = VK_FALSE; |
| vk::CmdSetColorBlendEnableEXT(m_command_buffer, 0, 1u, &color_blend_enable); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, EndConditionalRendering) { |
| TEST_DESCRIPTION("Invalid calls to vkCmdEndConditionalRenderingEXT."); |
| |
| AddRequiredExtensions(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| VkAttachmentDescription attach[] = { |
| {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, |
| VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, |
| VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, |
| }; |
| VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; |
| VkSubpassDescription subpasses[] = { |
| {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, |
| {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr}, |
| }; |
| |
| VkSubpassDependency dep = {0, |
| 1, |
| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, |
| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, |
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
| VK_DEPENDENCY_BY_REGION_BIT}; |
| |
| VkRenderPassCreateInfo rpci = vku::InitStructHelper(); |
| rpci.attachmentCount = 1; |
| rpci.pAttachments = attach; |
| rpci.subpassCount = 2; |
| rpci.pSubpasses = subpasses; |
| rpci.dependencyCount = 1; |
| rpci.pDependencies = &dep; |
| |
| vkt::RenderPass render_pass(*m_device, rpci); |
| |
| vkt::Image image(*m_device, 32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); |
| vkt::ImageView imageView = image.CreateView(); |
| |
| vkt::Framebuffer framebuffer(*m_device, render_pass, 1, &imageView.handle()); |
| |
| VkBufferCreateInfo buffer_create_info = vku::InitStructHelper(); |
| buffer_create_info.size = 32; |
| buffer_create_info.usage = VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT; |
| vkt::Buffer buffer(*m_device, buffer_create_info); |
| |
| VkConditionalRenderingBeginInfoEXT conditional_rendering_begin = vku::InitStructHelper(); |
| conditional_rendering_begin.buffer = buffer; |
| |
| VkClearValue clear_value; |
| clear_value.color = m_clear_color; |
| |
| VkRenderPassBeginInfo rpbi = vku::InitStructHelper(); |
| rpbi.renderPass = render_pass; |
| rpbi.framebuffer = framebuffer; |
| rpbi.renderArea = {{0, 0}, {32, 32}}; |
| rpbi.clearValueCount = 1; |
| rpbi.pClearValues = &clear_value; |
| |
| m_command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdEndConditionalRenderingEXT-None-01985"); |
| vk::CmdEndConditionalRenderingEXT(m_command_buffer); |
| m_errorMonitor->VerifyFound(); |
| |
| vk::CmdBeginConditionalRenderingEXT(m_command_buffer, &conditional_rendering_begin); |
| vk::CmdBeginRenderPass(m_command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdEndConditionalRenderingEXT-None-01986"); |
| vk::CmdEndConditionalRenderingEXT(m_command_buffer); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.NextSubpass(); |
| m_command_buffer.EndRenderPass(); |
| vk::CmdEndConditionalRenderingEXT(m_command_buffer); |
| |
| m_command_buffer.FullMemoryBarrier(); |
| vk::CmdBeginRenderPass(m_command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE); |
| vk::CmdBeginConditionalRenderingEXT(m_command_buffer, &conditional_rendering_begin); |
| m_command_buffer.NextSubpass(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdEndConditionalRenderingEXT-None-01987"); |
| vk::CmdEndConditionalRenderingEXT(m_command_buffer); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveUsage) { |
| TEST_DESCRIPTION("Resolve image with missing usage flags."); |
| |
| RETURN_IF_SKIP(Init()); |
| const VkPhysicalDeviceLimits &dev_limits = m_device->Physical().limits_; |
| if ((dev_limits.sampledImageColorSampleCounts & VK_SAMPLE_COUNT_2_BIT) == 0) { |
| GTEST_SKIP() << "Required VkSampleCountFlagBits are not supported; skipping"; |
| } |
| |
| PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr; |
| PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr; |
| if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) { |
| GTEST_SKIP() << "Failed to load device profile layer."; |
| } |
| |
| VkFormat src_format = VK_FORMAT_R8_UNORM; |
| VkFormat dst_format = VK_FORMAT_R8_SNORM; |
| |
| VkFormatProperties formatProps; |
| fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(Gpu(), src_format, &formatProps); |
| formatProps.optimalTilingFeatures &= ~VK_FORMAT_FEATURE_TRANSFER_SRC_BIT; |
| fpvkSetPhysicalDeviceFormatPropertiesEXT(Gpu(), src_format, formatProps); |
| fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(Gpu(), dst_format, &formatProps); |
| formatProps.optimalTilingFeatures &= ~VK_FORMAT_FEATURE_TRANSFER_DST_BIT; |
| fpvkSetPhysicalDeviceFormatPropertiesEXT(Gpu(), dst_format, formatProps); |
| |
| VkImageCreateInfo image_create_info = vku::InitStructHelper(); |
| image_create_info.imageType = VK_IMAGE_TYPE_2D; |
| image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; |
| image_create_info.extent = {32, 1, 1}; |
| image_create_info.mipLevels = 1; |
| image_create_info.arrayLayers = 1; |
| image_create_info.samples = VK_SAMPLE_COUNT_2_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| image_create_info.flags = 0; |
| vkt::Image src_image(*m_device, image_create_info, vkt::set_layout); |
| |
| image_create_info.format = dst_format; |
| |
| // Some implementations don't support multisampling, check that image format is valid |
| VkImageFormatProperties image_format_props{}; |
| VkResult result = GetImageFormatProps(Gpu(), image_create_info, image_format_props); |
| bool src_image_2_tests_valid = false; |
| vkt::Image src_image2; |
| if ((result == VK_SUCCESS) && (image_format_props.sampleCounts & VK_SAMPLE_COUNT_4_BIT) != 0) { |
| src_image2.Init(*m_device, image_create_info); |
| src_image_2_tests_valid = true; |
| } |
| |
| image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; |
| image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
| vkt::Image invalidSrcImage(*m_device, image_create_info, vkt::set_layout); |
| |
| image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| image_create_info.format = src_format; |
| vkt::Image invalidSrcImage2(*m_device, image_create_info, vkt::set_layout); |
| |
| image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; |
| image_create_info.samples = VK_SAMPLE_COUNT_1_BIT; |
| image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
| image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; |
| vkt::Image dstImage(*m_device, image_create_info, vkt::set_layout); |
| |
| image_create_info.format = src_format; |
| vkt::Image dstImage2(*m_device, image_create_info, vkt::set_layout); |
| |
| image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM; |
| image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| vkt::Image invalidDstImage(*m_device, image_create_info, vkt::set_layout); |
| |
| image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
| image_create_info.format = dst_format; |
| vkt::Image invalidDstImage2(*m_device, image_create_info, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| VkImageResolve resolve_region; |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcImage-06762"); |
| vk::CmdResolveImage(m_command_buffer, invalidSrcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-dstImage-06764"); |
| vk::CmdResolveImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_GENERAL, invalidDstImage, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcImage-06763"); |
| vk::CmdResolveImage(m_command_buffer, invalidSrcImage2, VK_IMAGE_LAYOUT_GENERAL, dstImage2, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| |
| if (src_image_2_tests_valid) { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-dstImage-06765"); |
| vk::CmdResolveImage(m_command_buffer, src_image2, VK_IMAGE_LAYOUT_GENERAL, invalidDstImage2, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, DepthStencilStateForReadOnlyLayout) { |
| TEST_DESCRIPTION("invalid depth stencil state for subpass that uses read only image layout."); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| const VkFormat ds_format = FindSupportedDepthStencilFormat(Gpu()); |
| vkt::Image ds_image(*m_device, 32, 32, ds_format, |
| VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); |
| |
| vkt::ImageView image_view = ds_image.CreateView(VK_IMAGE_ASPECT_DEPTH_BIT); |
| |
| RenderPassSingleSubpass rp(*this); |
| rp.AddAttachmentDescription(ds_format, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, |
| VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL); |
| rp.AddAttachmentReference({0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL}); |
| rp.AddDepthStencilAttachment(0); |
| rp.CreateRenderPass(); |
| |
| VkPipelineDepthStencilStateCreateInfo depth_state_info = vku::InitStructHelper(); |
| depth_state_info.depthTestEnable = VK_TRUE; |
| depth_state_info.depthWriteEnable = VK_TRUE; |
| |
| VkPipelineDepthStencilStateCreateInfo stencil_state_info = vku::InitStructHelper(); |
| stencil_state_info.front.failOp = VK_STENCIL_OP_ZERO; |
| stencil_state_info.front.writeMask = 1; |
| stencil_state_info.back.writeMask = 1; |
| stencil_state_info.stencilTestEnable = VK_TRUE; |
| |
| VkPipelineDepthStencilStateCreateInfo stencil_disabled_state_info = vku::InitStructHelper(); |
| stencil_disabled_state_info.front.failOp = VK_STENCIL_OP_ZERO; |
| stencil_disabled_state_info.front.writeMask = 1; |
| stencil_disabled_state_info.back.writeMask = 0; |
| stencil_disabled_state_info.stencilTestEnable = VK_TRUE; |
| |
| CreatePipelineHelper depth_pipe(*this); |
| depth_pipe.LateBindPipelineInfo(); |
| depth_pipe.gp_ci_.renderPass = rp; |
| depth_pipe.gp_ci_.pDepthStencilState = &depth_state_info; |
| depth_pipe.CreateGraphicsPipeline(false); |
| |
| CreatePipelineHelper stencil_pipe(*this); |
| stencil_pipe.LateBindPipelineInfo(); |
| stencil_pipe.gp_ci_.renderPass = rp; |
| stencil_pipe.gp_ci_.pDepthStencilState = &stencil_state_info; |
| stencil_pipe.CreateGraphicsPipeline(false); |
| |
| CreatePipelineHelper stencil_disabled_pipe(*this); |
| stencil_disabled_pipe.LateBindPipelineInfo(); |
| stencil_disabled_pipe.gp_ci_.renderPass = rp; |
| stencil_disabled_pipe.gp_ci_.pDepthStencilState = &stencil_disabled_state_info; |
| stencil_disabled_pipe.CreateGraphicsPipeline(false); |
| |
| CreatePipelineHelper stencil_dynamic_pipe(*this); |
| stencil_dynamic_pipe.AddDynamicState(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK); |
| stencil_dynamic_pipe.LateBindPipelineInfo(); |
| stencil_dynamic_pipe.gp_ci_.renderPass = rp; |
| stencil_dynamic_pipe.gp_ci_.pDepthStencilState = &stencil_state_info; |
| stencil_dynamic_pipe.CreateGraphicsPipeline(false); |
| |
| vkt::Framebuffer framebuffer(*m_device, rp, 1, &image_view.handle()); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp, framebuffer, 32, 32); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, depth_pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-06886"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, stencil_pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-06887"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| // valid since writeMask is set to zero |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, stencil_disabled_pipe); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, stencil_dynamic_pipe); |
| vk::CmdSetStencilWriteMask(m_command_buffer, VK_STENCIL_FACE_FRONT_AND_BACK, 1); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-06887"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| // valid since writeMask is set to zero |
| vk::CmdSetStencilWriteMask(m_command_buffer, VK_STENCIL_FACE_FRONT_BIT, 0); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, DepthStencilStateForReadOnlyLayoutDynamicRendering) { |
| SetTargetApiVersion(VK_API_VERSION_1_2); |
| AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::dynamicRendering); |
| RETURN_IF_SKIP(Init()); |
| |
| auto depth_format = FindSupportedDepthOnlyFormat(Gpu()); |
| auto stencil_format = FindSupportedStencilOnlyFormat(Gpu()); |
| if (stencil_format == VK_FORMAT_UNDEFINED) { |
| GTEST_SKIP() << "Couldn't find a stencil only image format"; |
| } |
| vkt::Image depth_image(*m_device, 32, 32, depth_format, |
| VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); |
| vkt::Image stencil_image(*m_device, 32, 32, stencil_format, |
| VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); |
| |
| vkt::ImageView depth_image_view = depth_image.CreateView(VK_IMAGE_ASPECT_DEPTH_BIT); |
| vkt::ImageView stencil_image_view = stencil_image.CreateView(VK_IMAGE_ASPECT_STENCIL_BIT); |
| |
| VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper(); |
| pipeline_rendering_info.colorAttachmentCount = 0; |
| pipeline_rendering_info.depthAttachmentFormat = depth_format; |
| pipeline_rendering_info.stencilAttachmentFormat = VK_FORMAT_UNDEFINED; |
| |
| VkPipelineDepthStencilStateCreateInfo depth_state_info = vku::InitStructHelper(); |
| depth_state_info.depthTestEnable = VK_TRUE; |
| depth_state_info.depthWriteEnable = VK_TRUE; |
| |
| CreatePipelineHelper depth_pipe(*this, &pipeline_rendering_info); |
| depth_pipe.gp_ci_.pDepthStencilState = &depth_state_info; |
| depth_pipe.CreateGraphicsPipeline(); |
| |
| pipeline_rendering_info.depthAttachmentFormat = VK_FORMAT_UNDEFINED; |
| pipeline_rendering_info.stencilAttachmentFormat = stencil_format; |
| |
| VkPipelineDepthStencilStateCreateInfo stencil_state_info = vku::InitStructHelper(); |
| stencil_state_info.front.failOp = VK_STENCIL_OP_ZERO; |
| stencil_state_info.front.writeMask = 1; |
| stencil_state_info.back.writeMask = 1; |
| stencil_state_info.stencilTestEnable = VK_TRUE; |
| |
| CreatePipelineHelper stencil_pipe(*this, &pipeline_rendering_info); |
| stencil_pipe.gp_ci_.pDepthStencilState = &stencil_state_info; |
| stencil_pipe.CreateGraphicsPipeline(); |
| |
| VkRenderingInfo begin_rendering_info = vku::InitStructHelper(); |
| begin_rendering_info.layerCount = 1; |
| begin_rendering_info.renderArea = {{0, 0}, {1, 1}}; |
| |
| { |
| VkRenderingAttachmentInfo depth_attachment = vku::InitStructHelper(); |
| depth_attachment.imageView = depth_image_view; |
| depth_attachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL; |
| begin_rendering_info.pDepthAttachment = &depth_attachment; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRendering(begin_rendering_info); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, depth_pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-06886"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRendering(); |
| } |
| { |
| VkRenderingAttachmentInfo stencil_attachment = vku::InitStructHelper(); |
| stencil_attachment.imageView = stencil_image_view; |
| stencil_attachment.imageLayout = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL; |
| begin_rendering_info.pStencilAttachment = &stencil_attachment; |
| begin_rendering_info.pDepthAttachment = nullptr; |
| |
| m_command_buffer.BeginRendering(begin_rendering_info); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, stencil_pipe); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-06887"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRendering(); |
| } |
| } |
| |
| TEST_F(NegativeCommand, ClearColorImageWithRange) { |
| TEST_DESCRIPTION("Record clear color with an invalid VkImageSubresourceRange"); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| vkt::Image image(*m_device, 32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| |
| const VkClearColorValue clear_color = {{0.0f, 0.0f, 0.0f, 1.0f}}; |
| |
| m_command_buffer.Begin(); |
| |
| // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS |
| { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-baseMipLevel-01470"); |
| const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, VK_REMAINING_MIP_LEVELS, 0, 1}; |
| vk::CmdClearColorImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS |
| { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-baseMipLevel-01470"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-pRanges-01692"); |
| const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 1, 1, 0, 1}; |
| vk::CmdClearColorImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Try levelCount = 0 |
| { |
| m_errorMonitor->SetDesiredError("VUID-VkImageSubresourceRange-levelCount-01720"); |
| const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 0, 1}; |
| vk::CmdClearColorImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Try baseMipLevel + levelCount > image.mipLevels |
| { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-pRanges-01692"); |
| const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 2, 0, 1}; |
| vk::CmdClearColorImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS |
| { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-baseArrayLayer-01472"); |
| const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS}; |
| vk::CmdClearColorImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS |
| { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-baseArrayLayer-01472"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-pRanges-01693"); |
| const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, 1}; |
| vk::CmdClearColorImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Try layerCount = 0 |
| { |
| m_errorMonitor->SetDesiredError("VUID-VkImageSubresourceRange-layerCount-01721"); |
| const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 0}; |
| vk::CmdClearColorImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Try baseArrayLayer + layerCount > image.arrayLayers |
| { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-pRanges-01693"); |
| const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2}; |
| vk::CmdClearColorImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeCommand, ClearDepthStencilWithAspect) { |
| TEST_DESCRIPTION("Verify ClearDepth with an invalid VkImageAspectFlags."); |
| RETURN_IF_SKIP(Init()); |
| const auto depth_format = FindSupportedDepthStencilFormat(Gpu()); |
| |
| const VkClearDepthStencilValue clear_value = {}; |
| VkImageSubresourceRange range = {VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0, 1, 0, 1}; |
| |
| vkt::Image image(*m_device, 64, 64, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); |
| |
| m_command_buffer.Begin(); |
| |
| // Element of pRanges.aspect includes VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_USAGE_TRANSFER_DST_BIT not included in the |
| // VkImageCreateInfo::usage used to create image |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-pRanges-02659"); |
| // Element of pRanges.aspect includes VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_USAGE_TRANSFER_DST_BIT not included in the |
| // VkImageCreateInfo::usage used to create image |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-pRanges-02660"); |
| // ... since VK_IMAGE_USAGE_TRANSFER_DST_BIT not included in the VkImageCreateInfo::usage used to create image |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-pRanges-02659"); |
| vk::CmdClearDepthStencilImage(m_command_buffer, image, VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| |
| // Using stencil aspect when format only have depth |
| const VkFormat depth_only_format = FindSupportedDepthOnlyFormat(Gpu()); |
| if (depth_only_format != VK_FORMAT_UNDEFINED) { |
| vkt::Image depth_image(*m_device, 64, 64, depth_only_format, |
| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-image-02825"); |
| vk::CmdClearDepthStencilImage(m_command_buffer, depth_image, VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ClearDepthStencilWithAspectSeparate) { |
| TEST_DESCRIPTION("Verify ClearDepth with an invalid VkImageAspectFlags."); |
| AddRequiredExtensions(VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| const auto depth_format = FindSupportedDepthStencilFormat(Gpu()); |
| |
| const VkClearDepthStencilValue clear_value = {}; |
| VkImageSubresourceRange range = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 1, 0, 1}; |
| |
| m_command_buffer.Begin(); |
| |
| VkImageStencilUsageCreateInfo image_stencil_create_info = vku::InitStructHelper(); |
| image_stencil_create_info.stencilUsage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; // not VK_IMAGE_USAGE_TRANSFER_DST_BIT |
| |
| auto image_ci = vkt::Image::ImageCreateInfo2D(64, 64, 1, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); |
| image_ci.pNext = &image_stencil_create_info; |
| vkt::Image image(*m_device, image_ci); |
| |
| // Element of pRanges.aspect includes VK_IMAGE_ASPECT_STENCIL_BIT, and image was created with separate stencil usage, |
| // VK_IMAGE_USAGE_TRANSFER_DST_BIT not included in the VkImageStencilUsageCreateInfo::stencilUsage used to create image |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-pRanges-02658"); |
| // ... since VK_IMAGE_USAGE_TRANSFER_DST_BIT not included in the VkImageCreateInfo::usage used to create image |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-pRanges-02659"); |
| vk::CmdClearDepthStencilImage(m_command_buffer, image, VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ClearDepthStencilWithRange) { |
| TEST_DESCRIPTION("Record clear depth with an invalid VkImageSubresourceRange"); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| const auto depth_format = FindSupportedDepthStencilFormat(Gpu()); |
| vkt::Image image(*m_device, 32, 32, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; |
| |
| const VkClearDepthStencilValue clear_value = {}; |
| |
| m_command_buffer.Begin(); |
| |
| // Try baseMipLevel >= image.mipLevels with VK_REMAINING_MIP_LEVELS |
| { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-baseMipLevel-01474"); |
| const VkImageSubresourceRange range = {ds_aspect, 1, VK_REMAINING_MIP_LEVELS, 0, 1}; |
| vk::CmdClearDepthStencilImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Try baseMipLevel >= image.mipLevels without VK_REMAINING_MIP_LEVELS |
| { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-baseMipLevel-01474"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-pRanges-01694"); |
| const VkImageSubresourceRange range = {ds_aspect, 1, 1, 0, 1}; |
| vk::CmdClearDepthStencilImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Try levelCount = 0 |
| { |
| m_errorMonitor->SetDesiredError("VUID-VkImageSubresourceRange-levelCount-01720"); |
| const VkImageSubresourceRange range = {ds_aspect, 0, 0, 0, 1}; |
| vk::CmdClearDepthStencilImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Try baseMipLevel + levelCount > image.mipLevels |
| { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-pRanges-01694"); |
| const VkImageSubresourceRange range = {ds_aspect, 0, 2, 0, 1}; |
| vk::CmdClearDepthStencilImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Try baseArrayLayer >= image.arrayLayers with VK_REMAINING_ARRAY_LAYERS |
| { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-baseArrayLayer-01476"); |
| const VkImageSubresourceRange range = {ds_aspect, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS}; |
| vk::CmdClearDepthStencilImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Try baseArrayLayer >= image.arrayLayers without VK_REMAINING_ARRAY_LAYERS |
| { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-baseArrayLayer-01476"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-pRanges-01695"); |
| const VkImageSubresourceRange range = {ds_aspect, 0, 1, 1, 1}; |
| vk::CmdClearDepthStencilImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Try layerCount = 0 |
| { |
| m_errorMonitor->SetDesiredError("VUID-VkImageSubresourceRange-layerCount-01721"); |
| const VkImageSubresourceRange range = {ds_aspect, 0, 1, 0, 0}; |
| vk::CmdClearDepthStencilImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // Try baseArrayLayer + layerCount > image.arrayLayers |
| { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-pRanges-01695"); |
| const VkImageSubresourceRange range = {ds_aspect, 0, 1, 0, 2}; |
| vk::CmdClearDepthStencilImage(m_command_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeCommand, ClearColorImageWithinRenderPass) { |
| // Call CmdClearColorImage within an active RenderPass |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-renderpass"); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| VkClearColorValue clear_color; |
| memset(clear_color.uint32, 0, sizeof(uint32_t) * 4); |
| |
| auto image_ci = vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, VK_FORMAT_B8G8R8A8_UNORM, |
| VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| vkt::Image dst_image(*m_device, image_ci, vkt::set_layout); |
| |
| const VkImageSubresourceRange range{VK_IMAGE_ASPECT_COLOR_BIT, 0, image_ci.mipLevels, 0, image_ci.arrayLayers}; |
| |
| vk::CmdClearColorImage(m_command_buffer, dst_image, VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range); |
| |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ClearDepthStencilImage) { |
| // Hit errors related to vk::CmdClearDepthStencilImage() |
| // 1. Use an image that doesn't have VK_IMAGE_USAGE_TRANSFER_DST_BIT set |
| // 2. Call CmdClearDepthStencilImage within an active RenderPass |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| auto depth_format = FindSupportedDepthStencilFormat(Gpu()); |
| |
| VkClearDepthStencilValue clear_value = {0}; |
| // Error here is that VK_IMAGE_USAGE_TRANSFER_DST_BIT is excluded for DS image that we'll call Clear on below |
| VkImageCreateInfo image_create_info = |
| vkt::Image::ImageCreateInfo2D(64, 64, 1, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); |
| vkt::Image dst_image_bad_usage(*m_device, image_create_info, vkt::set_layout); |
| const VkImageSubresourceRange range{VK_IMAGE_ASPECT_DEPTH_BIT, 0, image_create_info.mipLevels, 0, |
| image_create_info.arrayLayers}; |
| |
| m_command_buffer.Begin(); |
| // need to handle since an element of pRanges includes VK_IMAGE_ASPECT_DEPTH_BIT without VkImageCreateInfo::usage having |
| // VK_IMAGE_USAGE_TRANSFER_DST_BIT being set |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-pRanges-02660"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-pRanges-02659"); |
| vk::CmdClearDepthStencilImage(m_command_buffer, dst_image_bad_usage, VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| |
| // Fix usage for next test case |
| image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
| vkt::Image dst_image(*m_device, image_create_info, vkt::set_layout); |
| |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-renderpass"); |
| vk::CmdClearDepthStencilImage(m_command_buffer, dst_image, VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ClearDepthImage) { |
| TEST_DESCRIPTION("Test clearing without VK_EXT_depth_range_unrestricted"); |
| // Extension doesn't have feature bit, so not enabling extension invokes restrictions |
| RETURN_IF_SKIP(Init()); |
| |
| // Need to set format framework uses for InitRenderTarget |
| m_depth_stencil_fmt = FindSupportedDepthStencilFormat(Gpu()); |
| |
| int depth_attachment_index = 1; |
| m_depthStencil->Init(*m_device, m_width, m_height, 1, m_depth_stencil_fmt, |
| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| vkt::ImageView depth_image_view = m_depthStencil->CreateView(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); |
| InitRenderTarget(&depth_image_view.handle()); |
| |
| m_command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkClearDepthStencilValue-depth-00022"); |
| const VkImageSubresourceRange range = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1}; |
| const VkClearDepthStencilValue bad_clear_value = {1.5f, 0}; |
| vk::CmdClearDepthStencilImage(m_command_buffer, m_depthStencil->handle(), VK_IMAGE_LAYOUT_GENERAL, &bad_clear_value, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| |
| m_renderPassClearValues[depth_attachment_index].depthStencil.depth = 1.5f; |
| m_errorMonitor->SetDesiredError("VUID-VkClearDepthStencilValue-depth-00022"); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| m_errorMonitor->VerifyFound(); |
| |
| // set back to normal |
| m_renderPassClearValues[depth_attachment_index].depthStencil.depth = 1.0f; |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkClearDepthStencilValue-depth-00022"); |
| VkClearAttachment clear_attachment; |
| clear_attachment.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; |
| clear_attachment.clearValue.depthStencil.depth = 1.5f; |
| clear_attachment.clearValue.depthStencil.stencil = 0; |
| VkClearRect clear_rect = {{{0, 0}, {32, 32}}, 0, 1}; |
| vk::CmdClearAttachments(m_command_buffer, 1, &clear_attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ClearDepthImageWithNAN) { |
| TEST_DESCRIPTION("Clear depth image when depth clear value is NAN"); |
| RETURN_IF_SKIP(Init()); |
| |
| VkFormat depth_stencil_format = FindSupportedDepthStencilFormat(Gpu()); |
| vkt::Image depth_image(*m_device, 32, 32, depth_stencil_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| |
| const VkImageSubresourceRange subresource = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1}; |
| const VkClearDepthStencilValue nan_depth_clear_value = {std::numeric_limits<float>::quiet_NaN(), 0}; |
| assert(std::isnan(nan_depth_clear_value.depth)); |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-VkClearDepthStencilValue-depth-00022"); |
| vk::CmdClearDepthStencilImage(m_command_buffer, depth_image, VK_IMAGE_LAYOUT_GENERAL, &nan_depth_clear_value, 1, &subresource); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ClearColorImageImageLayout) { |
| TEST_DESCRIPTION("Check ClearImage layouts with SHARED_PRESENTABLE_IMAGE extension active."); |
| AddRequiredExtensions(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| auto image_ci = vkt::Image::ImageCreateInfo2D(32, 32, 1, 4, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| vkt::Image dst_image(*m_device, image_ci, vkt::set_layout); |
| m_command_buffer.Begin(); |
| |
| VkClearColorValue color_clear_value = {}; |
| VkImageSubresourceRange clear_range; |
| clear_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| clear_range.baseMipLevel = 0; |
| clear_range.baseArrayLayer = 0; |
| clear_range.layerCount = 1; |
| clear_range.levelCount = 1; |
| |
| // Fail by using bad layout for color clear (GENERAL, SHARED_PRESENT or TRANSFER_DST are permitted). |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-imageLayout-01394"); |
| vk::CmdClearColorImage(m_command_buffer, dst_image, VK_IMAGE_LAYOUT_UNDEFINED, &color_clear_value, 1, &clear_range); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, CmdClearAttachmentTests) { |
| TEST_DESCRIPTION("Various tests for validating usage of vkCmdClearAttachments"); |
| |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| VkImageFormatProperties image_format_properties{}; |
| ASSERT_EQ(VK_SUCCESS, vk::GetPhysicalDeviceImageFormatProperties(m_device->Physical(), m_renderTargets[0]->Format(), |
| VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, |
| m_renderTargets[0]->Usage(), 0, &image_format_properties)); |
| if (image_format_properties.maxArrayLayers < 4) { |
| GTEST_SKIP() << "Test needs to create image 2D array of 4 image view, but VkImageFormatProperties::maxArrayLayers is < 4. " |
| "Skipping test."; |
| } |
| |
| // Create frame buffer with 2 layers, and image view with 4 layers, |
| // to make sure that considered layer count is the one coming from frame buffer |
| // (test would not fail if layer count used to do validation was 4) |
| assert(!m_renderTargets.empty()); |
| const auto render_target_ci = vkt::Image::ImageCreateInfo2D(m_renderTargets[0]->Width(), m_renderTargets[0]->Height(), |
| m_renderTargets[0]->CreateInfo().mipLevels, 4, |
| m_renderTargets[0]->Format(), m_renderTargets[0]->Usage()); |
| vkt::Image render_target(*m_device, render_target_ci, vkt::set_layout); |
| vkt::ImageView render_target_view = |
| render_target.CreateView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, 0, 1, 0, render_target_ci.arrayLayers); |
| VkFramebufferCreateInfo fb_info = vku::InitStructHelper(); |
| fb_info.renderPass = RenderPass(); |
| fb_info.layers = 2; |
| fb_info.attachmentCount = 1; |
| fb_info.pAttachments = &render_target_view.handle(); |
| fb_info.width = m_width; |
| fb_info.height = m_height; |
| vkt::Framebuffer framebuffer(*m_device, fb_info); |
| m_renderPassBeginInfo.framebuffer = framebuffer; |
| |
| // Create secondary command buffer |
| VkCommandBufferAllocateInfo secondary_cmd_buffer_alloc_info = vku::InitStructHelper(); |
| secondary_cmd_buffer_alloc_info.commandPool = m_command_pool; |
| secondary_cmd_buffer_alloc_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; |
| secondary_cmd_buffer_alloc_info.commandBufferCount = 1; |
| |
| vkt::CommandBuffer secondary_cmd_buffer(*m_device, secondary_cmd_buffer_alloc_info); |
| VkCommandBufferInheritanceInfo secondary_cmd_buffer_inheritance_info = vku::InitStructHelper(); |
| secondary_cmd_buffer_inheritance_info.renderPass = m_renderPass; |
| secondary_cmd_buffer_inheritance_info.framebuffer = framebuffer; |
| |
| VkCommandBufferBeginInfo secondary_cmd_buffer_begin_info = vku::InitStructHelper(); |
| secondary_cmd_buffer_begin_info.flags = |
| VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| secondary_cmd_buffer_begin_info.pInheritanceInfo = &secondary_cmd_buffer_inheritance_info; |
| |
| // Create clear rect |
| VkClearAttachment color_attachment; |
| color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| color_attachment.clearValue.color.float32[0] = 1.0; |
| color_attachment.clearValue.color.float32[1] = 1.0; |
| color_attachment.clearValue.color.float32[2] = 1.0; |
| color_attachment.clearValue.color.float32[3] = 1.0; |
| color_attachment.colorAttachment = 0; |
| VkClearRect clear_rect = {{{0, 0}, {m_width, m_height}}, 0, 1}; |
| |
| auto clear_cmds = [this, &color_attachment](VkCommandBuffer cmd_buffer, VkClearRect clear_rect) { |
| // extent too wide |
| VkClearRect clear_rect_too_large = clear_rect; |
| clear_rect_too_large.rect.extent.width = m_renderPassBeginInfo.renderArea.extent.width + 4; |
| clear_rect_too_large.rect.extent.height = clear_rect_too_large.rect.extent.height / 2; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-pRects-00016"); |
| vk::CmdClearAttachments(cmd_buffer, 1, &color_attachment, 1, &clear_rect_too_large); |
| |
| // baseLayer < render pass instance layer count |
| clear_rect.baseArrayLayer = 1; |
| clear_rect.layerCount = 1; |
| vk::CmdClearAttachments(cmd_buffer, 1, &color_attachment, 1, &clear_rect); |
| |
| // baseLayer + layerCount <= render pass instance layer count |
| clear_rect.baseArrayLayer = 0; |
| clear_rect.layerCount = 2; |
| vk::CmdClearAttachments(cmd_buffer, 1, &color_attachment, 1, &clear_rect); |
| |
| // baseLayer >= render pass instance layer count |
| clear_rect.baseArrayLayer = 2; |
| clear_rect.layerCount = 1; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-pRects-06937"); |
| vk::CmdClearAttachments(cmd_buffer, 1, &color_attachment, 1, &clear_rect); |
| |
| // baseLayer + layerCount > render pass instance layer count |
| clear_rect.baseArrayLayer = 0; |
| clear_rect.layerCount = 4; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-pRects-06937"); |
| vk::CmdClearAttachments(cmd_buffer, 1, &color_attachment, 1, &clear_rect); |
| }; |
| |
| // Register clear commands to secondary command buffer |
| secondary_cmd_buffer.Begin(&secondary_cmd_buffer_begin_info); |
| clear_cmds(secondary_cmd_buffer, clear_rect); |
| secondary_cmd_buffer.End(); |
| |
| m_command_buffer.Begin(); |
| |
| // Execute secondary command buffer |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| vk::CmdExecuteCommands(m_command_buffer, 1, &secondary_cmd_buffer.handle()); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| |
| // Execute same commands as previously, but in a primary command buffer |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| clear_cmds(m_command_buffer, clear_rect); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, BindVertexIndexBufferUsage) { |
| TEST_DESCRIPTION("Bad usage flags for binding the Vertex and Index buffer"); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::Buffer buffer(*m_device, 64, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| |
| m_command_buffer.Begin(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindIndexBuffer-buffer-08784"); |
| vk::CmdBindIndexBuffer(m_command_buffer, buffer, 0, VK_INDEX_TYPE_UINT32); |
| m_errorMonitor->VerifyFound(); |
| |
| VkDeviceSize offsets = 0; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindVertexBuffers-pBuffers-00627"); |
| vk::CmdBindVertexBuffers(m_command_buffer, 0, 1, &buffer.handle(), &offsets); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, BindIndexBufferHandles) { |
| TEST_DESCRIPTION("call vkCmdBindIndexBuffer with bad Handles"); |
| RETURN_IF_SKIP(Init()); |
| vkt::Buffer buffer(*m_device, 64, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| m_command_buffer.Begin(); |
| VkBuffer bad_buffer = CastToHandle<VkBuffer, uintptr_t>(0xbaadbeef); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindIndexBuffer-buffer-parameter"); |
| vk::CmdBindIndexBuffer(m_command_buffer, bad_buffer, 0, VK_INDEX_TYPE_UINT32); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ClearImageAspectMask) { |
| TEST_DESCRIPTION("Need to use VK_IMAGE_ASPECT_COLOR_BIT."); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| VkClearColorValue clear_color; |
| memset(clear_color.uint32, 0, sizeof(uint32_t) * 4); |
| const VkImageSubresourceRange color_range = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1}; |
| |
| vkt::Image image(*m_device, 32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-aspectMask-02498"); |
| vk::CmdClearColorImage(m_command_buffer, image, VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &color_range); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, RenderPassContinueNotSupportedByCommandPool) { |
| TEST_DESCRIPTION("Use render pass continue bit with unsupported command pool."); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| const std::optional<uint32_t> non_graphics_queue_family_index = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT); |
| |
| if (!non_graphics_queue_family_index) { |
| GTEST_SKIP() << "No suitable queue found."; |
| } |
| |
| vkt::CommandPool command_pool(*m_device, non_graphics_queue_family_index.value()); |
| vkt::CommandBuffer command_buffer(*m_device, command_pool); |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkCommandBufferBeginInfo-flags-09123"); |
| vk::BeginCommandBuffer(command_buffer, &begin_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ClearDepthStencilImageWithInvalidAspect) { |
| TEST_DESCRIPTION("Use vkCmdClearDepthStencilImage with invalid image aspect."); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| VkFormat format = FindSupportedDepthStencilFormat(m_device->Physical()); |
| vkt::Image image(*m_device, 32, 32, format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| |
| VkClearDepthStencilValue clear_value = {0}; |
| VkImageSubresourceRange range = {}; |
| range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| range.baseMipLevel = 0u; |
| range.layerCount = 1u; |
| range.baseArrayLayer = 0u; |
| range.levelCount = 1u; |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearDepthStencilImage-aspectMask-02824"); |
| vk::CmdClearDepthStencilImage(m_command_buffer, image, VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1u, &range); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ClearColorImageWithMissingFeature) { |
| TEST_DESCRIPTION("Use vkCmdClearColorImage with image format that doesnt have VK_FORMAT_FEATURE_TRANSFER_DST_BIT."); |
| |
| AddRequiredExtensions(VK_KHR_MAINTENANCE1_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr; |
| PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr; |
| if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) { |
| GTEST_SKIP() << "Failed to load device profile layer."; |
| } |
| |
| VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; |
| |
| VkFormatProperties formatProps; |
| fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(Gpu(), format, &formatProps); |
| formatProps.optimalTilingFeatures &= ~VK_FORMAT_FEATURE_TRANSFER_DST_BIT; |
| fpvkSetPhysicalDeviceFormatPropertiesEXT(Gpu(), format, formatProps); |
| |
| vkt::Image image(*m_device, 32, 32, format, VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| |
| VkImageSubresourceRange range = {}; |
| range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| range.baseMipLevel = 0u; |
| range.layerCount = 1u; |
| range.baseArrayLayer = 0u; |
| range.levelCount = 1u; |
| |
| VkClearColorValue clear_value = {{0, 0, 0, 0}}; |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-image-01993"); |
| vk::CmdClearColorImage(m_command_buffer, image, VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1u, &range); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ClearDsImageWithInvalidAspect) { |
| TEST_DESCRIPTION("Attempt to clear color aspect of depth/stencil image."); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| for (uint32_t i = 0; i < 2; ++i) { |
| bool missing_depth = i == 0; |
| auto format = missing_depth ? FindSupportedStencilOnlyFormat(m_device->Physical()) |
| : FindSupportedDepthOnlyFormat(m_device->Physical()); |
| if (format == VK_FORMAT_UNDEFINED) { |
| continue; |
| } |
| VkImageAspectFlags image_aspect = missing_depth ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; |
| VkImageAspectFlags clear_aspect = missing_depth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT; |
| |
| vkt::Image image(*m_device, 32, 32, format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); |
| vkt::ImageView image_view = image.CreateView(image_aspect); |
| |
| RenderPassSingleSubpass rp(*this); |
| rp.AddAttachmentDescription(format, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); |
| rp.AddAttachmentReference({0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}); |
| rp.AddDepthStencilAttachment(0); |
| rp.CreateRenderPass(); |
| |
| vkt::Framebuffer framebuffer(*m_device, rp, 1, &image_view.handle()); |
| |
| VkClearValue clear_value = {}; |
| clear_value.depthStencil = {0}; |
| |
| VkClearAttachment clear_attachment = {}; |
| clear_attachment.aspectMask = clear_aspect; |
| clear_attachment.colorAttachment = 0u; |
| clear_attachment.clearValue.depthStencil.depth = 0.0f; |
| VkClearRect clear_rect; |
| clear_rect.rect = {{0, 0}, {32u, 32u}}; |
| clear_rect.baseArrayLayer = 0u; |
| clear_rect.layerCount = 1u; |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(rp, framebuffer, 32, 32, 1, &clear_value); |
| if (missing_depth) { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-aspectMask-07884"); |
| } else { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-aspectMask-07885"); |
| } |
| vk::CmdClearAttachments(m_command_buffer, 1u, &clear_attachment, 1u, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| } |
| |
| TEST_F(NegativeCommand, InvalidCommandBufferInheritanceInfo) { |
| TEST_DESCRIPTION("Test VkCommandBufferInheritanceInfo using disabled featuers."); |
| |
| AddRequiredExtensions(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::CommandBuffer secondary_cb(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| VkCommandBufferInheritanceConditionalRenderingInfoEXT inheritance_conditional_rendering_info = vku::InitStructHelper(); |
| inheritance_conditional_rendering_info.conditionalRenderingEnable = VK_TRUE; |
| |
| VkCommandBufferInheritanceInfo inheritance_info = vku::InitStructHelper(&inheritance_conditional_rendering_info); |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| begin_info.pInheritanceInfo = &inheritance_info; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkCommandBufferInheritanceConditionalRenderingInfoEXT-conditionalRenderingEnable-01977"); |
| vk::BeginCommandBuffer(secondary_cb, &begin_info); |
| m_errorMonitor->VerifyFound(); |
| |
| inheritance_info.pNext = nullptr; |
| inheritance_info.occlusionQueryEnable = VK_TRUE; |
| m_errorMonitor->SetDesiredError("VUID-VkCommandBufferInheritanceInfo-occlusionQueryEnable-00056"); |
| vk::BeginCommandBuffer(secondary_cb, &begin_info); |
| m_errorMonitor->VerifyFound(); |
| |
| inheritance_info.occlusionQueryEnable = VK_FALSE; |
| inheritance_info.pipelineStatistics = VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT; |
| m_errorMonitor->SetDesiredError("VUID-VkCommandBufferInheritanceInfo-pipelineStatistics-00058"); |
| vk::BeginCommandBuffer(secondary_cb, &begin_info); |
| m_errorMonitor->VerifyFound(); |
| |
| inheritance_info.pipelineStatistics = 0u; |
| inheritance_info.queryFlags = VK_QUERY_CONTROL_PRECISE_BIT; |
| m_errorMonitor->SetDesiredError("VUID-VkCommandBufferInheritanceInfo-queryFlags-02788"); |
| vk::BeginCommandBuffer(secondary_cb, &begin_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, PipelineStatisticsInvalidFlags) { |
| TEST_DESCRIPTION("Use invalid pipelineStatistics flags."); |
| |
| AddRequiredFeature(vkt::Feature::pipelineStatisticsQuery); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::CommandBuffer secondary_cb(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| VkCommandBufferInheritanceInfo inheritance_info = vku::InitStructHelper(); |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| begin_info.pInheritanceInfo = &inheritance_info; |
| |
| inheritance_info.pipelineStatistics = VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM; // Invalid |
| m_errorMonitor->SetDesiredError("VUID-VkCommandBufferInheritanceInfo-pipelineStatistics-02789"); |
| vk::BeginCommandBuffer(secondary_cb, &begin_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, QueryControlInvalidFlags) { |
| TEST_DESCRIPTION("Use invalid query control flags."); |
| |
| AddRequiredFeature(vkt::Feature::inheritedQueries); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::CommandBuffer secondary_cb(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY); |
| |
| VkCommandBufferInheritanceInfo inheritance_info = vku::InitStructHelper(); |
| |
| VkCommandBufferBeginInfo begin_info = vku::InitStructHelper(); |
| begin_info.pInheritanceInfo = &inheritance_info; |
| |
| inheritance_info.queryFlags = VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM; // Invalid |
| m_errorMonitor->SetDesiredError("VUID-VkCommandBufferInheritanceInfo-queryFlags-00057"); |
| vk::BeginCommandBuffer(secondary_cb, &begin_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, CommandBufferRecording) { |
| TEST_DESCRIPTION("Test core functions for commandBuffer-recording VUs."); |
| RETURN_IF_SKIP(Init()); |
| RETURN_IF_SKIP(InitRenderTarget()); |
| |
| { |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetViewport-commandBuffer-recording"); |
| const VkViewport viewport = {0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f}; |
| vk::CmdSetViewport(m_command_buffer, 0, 1, &viewport); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetScissor-commandBuffer-recording"); |
| const VkRect2D scissor = {{0, 0}, {0, 0}}; |
| vk::CmdSetScissor(m_command_buffer, 0, 1, &scissor); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetLineWidth-commandBuffer-recording"); |
| vk::CmdSetLineWidth(m_command_buffer, 1.0f); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetDepthBias-commandBuffer-recording"); |
| vk::CmdSetDepthBias(m_command_buffer, 0.0f, 0.0f, 0.0f); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetBlendConstants-commandBuffer-recording"); |
| float blends[4] = {1.0f, 1.0f, 1.0f, 1.0f}; |
| vk::CmdSetBlendConstants(m_command_buffer, blends); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetDepthBounds-commandBuffer-recording"); |
| vk::CmdSetDepthBounds(m_command_buffer, 1.0f, 1.0f); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetStencilCompareMask-commandBuffer-recording"); |
| vk::CmdSetStencilCompareMask(m_command_buffer, VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetStencilWriteMask-commandBuffer-recording"); |
| vk::CmdSetStencilWriteMask(m_command_buffer, VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetStencilReference-commandBuffer-recording"); |
| vk::CmdSetStencilReference(m_command_buffer, VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindPipeline-commandBuffer-recording"); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBeginRenderPass-commandBuffer-recording"); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| vkt::Buffer indirect_buffer(*m_device, 32, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-renderpass"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-commandBuffer-recording"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-None-08606"); |
| vk::CmdDraw(m_command_buffer, 3, 1, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-renderpass"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-commandBuffer-recording"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-None-07312"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexed-None-08606"); |
| vk::CmdDrawIndexed(m_command_buffer, 0, 1, 0, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirect-renderpass"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirect-commandBuffer-recording"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndirect-None-08606"); |
| vk::CmdDrawIndirect(m_command_buffer, indirect_buffer, 0, 1, 32); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirect-renderpass"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirect-None-07312"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirect-commandBuffer-recording"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirect-None-08606"); |
| vk::CmdDrawIndexedIndirect(m_command_buffer, indirect_buffer, 0, 1, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatch-commandBuffer-recording"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatch-None-08606"); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchIndirect-commandBuffer-recording"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchIndirect-None-08606"); |
| vk::CmdDispatchIndirect(m_command_buffer, indirect_buffer, 0); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| vkt::Image image(*m_device, 16, 16, VK_FORMAT_R8G8B8A8_UINT, |
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); |
| vkt::Buffer buffer(*m_device, 1024, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); |
| |
| VkImageCopy copy_region; |
| copy_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| copy_region.srcOffset = {0, 0, 0}; |
| copy_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| copy_region.dstOffset = {1, 1, 0}; |
| copy_region.extent = {1, 1, 1}; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdCopyImage-commandBuffer-recording"); |
| vk::CmdCopyImage(m_command_buffer, image, VK_IMAGE_LAYOUT_GENERAL, image, VK_IMAGE_LAYOUT_GENERAL, 1, ©_region); |
| m_errorMonitor->VerifyFound(); |
| |
| VkBufferImageCopy buffer_region = {}; |
| buffer_region.bufferRowLength = 0; |
| buffer_region.bufferImageHeight = 0; |
| buffer_region.imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| buffer_region.imageOffset = {0, 0, 0}; |
| buffer_region.imageExtent = {1, 1, 1}; |
| buffer_region.bufferOffset = 0; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdCopyBufferToImage-commandBuffer-recording"); |
| vk::CmdCopyBufferToImage(m_command_buffer, buffer, image, VK_IMAGE_LAYOUT_GENERAL, 1, &buffer_region); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdCopyImageToBuffer-commandBuffer-recording"); |
| vk::CmdCopyImageToBuffer(m_command_buffer, image, VK_IMAGE_LAYOUT_GENERAL, buffer, 1, &buffer_region); |
| m_errorMonitor->VerifyFound(); |
| |
| VkBufferCopy buffer_copy = {0, 64, 64}; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdCopyBuffer-commandBuffer-recording"); |
| vk::CmdCopyBuffer(m_command_buffer, buffer, buffer, 1, &buffer_copy); |
| m_errorMonitor->VerifyFound(); |
| |
| VkImageBlit blit_region; |
| blit_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u}; |
| blit_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u}; |
| blit_region.srcOffsets[0] = {0, 0, 0}; |
| blit_region.srcOffsets[1] = {1, 1, 1}; |
| blit_region.dstOffsets[0] = {1, 1, 0}; |
| blit_region.dstOffsets[1] = {2, 2, 1}; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBlitImage-commandBuffer-recording"); |
| vk::CmdBlitImage(m_command_buffer, image, VK_IMAGE_LAYOUT_GENERAL, image, VK_IMAGE_LAYOUT_GENERAL, 1u, &blit_region, |
| VK_FILTER_NEAREST); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdFillBuffer-commandBuffer-recording"); |
| vk::CmdFillBuffer(m_command_buffer, buffer, 0, 4, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| uint32_t data = 0; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdUpdateBuffer-commandBuffer-recording"); |
| vk::CmdUpdateBuffer(m_command_buffer, buffer, 0, 4, &data); |
| m_errorMonitor->VerifyFound(); |
| |
| VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; |
| VkClearColorValue clear_color = {{0.0f, 0.0f, 0.0f, 1.0f}}; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-commandBuffer-recording"); |
| vk::CmdClearColorImage(m_command_buffer, image, VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range); |
| m_errorMonitor->VerifyFound(); |
| |
| VkClearAttachment clear_attachment; |
| clear_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| clear_attachment.colorAttachment = 0; |
| VkClearRect clear_rect = {{{0, 0}, {m_width, m_height}}, 0, 1}; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-commandBuffer-recording"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdClearAttachments-renderpass"); |
| vk::CmdClearAttachments(m_command_buffer, 1, &clear_attachment, 1, &clear_rect); |
| m_errorMonitor->VerifyFound(); |
| |
| VkImageMemoryBarrier image_barrier = image.ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, range); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdPipelineBarrier-commandBuffer-recording"); |
| vk::CmdPipelineBarrier(m_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, |
| nullptr, 0, nullptr, 1, &image_barrier); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| vkt::Buffer index_buffer(*m_device, 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); |
| vkt::Buffer vertex_buffer(*m_device, 1024, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindIndexBuffer-commandBuffer-recording"); |
| vk::CmdBindIndexBuffer(m_command_buffer, index_buffer, 0, VK_INDEX_TYPE_UINT32); |
| m_errorMonitor->VerifyFound(); |
| VkDeviceSize offsets = 0; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindVertexBuffers-commandBuffer-recording"); |
| vk::CmdBindVertexBuffers(m_command_buffer, 0, 1, &vertex_buffer.handle(), &offsets); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| vkt::Event event(*m_device); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdSetEvent-commandBuffer-recording"); |
| vk::CmdSetEvent(m_command_buffer, event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdWaitEvents-commandBuffer-recording"); |
| vk::CmdWaitEvents(m_command_buffer, 1, &event.handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, |
| VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, nullptr, 0, nullptr, 0, nullptr); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResetEvent-commandBuffer-recording"); |
| vk::CmdResetEvent(m_command_buffer, event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResetQueryPool-commandBuffer-recording"); |
| vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-commandBuffer-recording"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-queryType-02804"); |
| vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0); |
| m_errorMonitor->VerifyFound(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdEndQuery-commandBuffer-recording"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdEndQuery-None-01923"); |
| vk::CmdEndQuery(m_command_buffer, query_pool, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdWriteTimestamp-commandBuffer-recording"); |
| vk::CmdWriteTimestamp(m_command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, query_pool, 0); |
| m_errorMonitor->VerifyFound(); |
| |
| vkt::Buffer buffer(*m_device, 16, VK_BUFFER_USAGE_TRANSFER_DST_BIT); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-commandBuffer-recording"); |
| vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0, 1, buffer, 0, 4, VK_QUERY_RESULT_WAIT_BIT); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| { |
| OneOffDescriptorSet descriptor_set(m_device, {{0, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}}); |
| VkPushConstantRange pc_range = {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}; |
| vkt::PipelineLayout pipeline_layout(*m_device, {&descriptor_set.layout_}, {pc_range}); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindDescriptorSets-commandBuffer-recording"); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &descriptor_set.set_, 0, |
| nullptr); |
| m_errorMonitor->VerifyFound(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdPushConstants-commandBuffer-recording"); |
| uint32_t data = 0; |
| vk::CmdPushConstants(m_command_buffer, pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 4, &data); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeCommand, ManyInvalidatedObjects) { |
| RETURN_IF_SKIP(Init()); |
| |
| const char *cs_source = R"glsl( |
| #version 450 |
| layout(set = 0, binding = 0) buffer SSBO_0 { |
| vec4 a; |
| }; |
| |
| layout(set = 0, binding = 1) uniform sampler2D s; |
| |
| void main() { |
| a = texture(s, vec2(0)); |
| } |
| )glsl"; |
| |
| vkt::Buffer buffer1(*m_device, 32, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); |
| vkt::Buffer buffer2(*m_device, 32, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); |
| vkt::Image image(*m_device, 16, 16, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT); |
| vkt::ImageView image_view = image.CreateView(); |
| vkt::Sampler sampler(*m_device, SafeSaneSamplerCreateInfo()); |
| |
| OneOffDescriptorSet descriptor_set(m_device, |
| { |
| {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr}, |
| {1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}, |
| }); |
| vkt::PipelineLayout pipeline_layout(*m_device, {&descriptor_set.layout_}); |
| descriptor_set.WriteDescriptorBufferInfo(0, buffer1, 0, VK_WHOLE_SIZE, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); |
| descriptor_set.WriteDescriptorImageInfo(1, image_view, sampler); |
| descriptor_set.UpdateDescriptorSets(); |
| |
| CreateComputePipelineHelper pipe(*this); |
| pipe.cp_ci_.layout = pipeline_layout; |
| pipe.cs_ = VkShaderObj(*m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT); |
| pipe.CreateComputePipeline(); |
| |
| CreateComputePipelineHelper pipe2(*this); |
| pipe2.CreateComputePipeline(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipe); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout, 0, 1, &descriptor_set.set_, 0, |
| nullptr); |
| vk::CmdDispatch(m_command_buffer, 1, 1, 1); |
| |
| uint32_t data = 0; |
| vk::CmdUpdateBuffer(m_command_buffer, buffer2, 0, sizeof(uint32_t), &data); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipe2); |
| |
| image.Destroy(); |
| buffer2.Destroy(); |
| pipe2.Destroy(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkEndCommandBuffer-commandBuffer-00059"); |
| vk::EndCommandBuffer(m_command_buffer); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImageFormat) { |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_10_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance10); |
| RETURN_IF_SKIP(Init()); |
| |
| if (!IsPlatformMockICD()) { |
| GTEST_SKIP() << "Too hard to find unsupported format that works on real driver."; |
| } |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| image_ci.format = VK_FORMAT_B8G8R8A8_UINT; |
| image_ci.extent = {32, 32, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_ci.flags = 0; |
| |
| vkt::Image src_image(*m_device, image_ci, vkt::set_layout); |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| VkImageResolve resolve_region; |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-maintenance10-11799"); |
| vk::CmdResolveImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImageAspectMask) { |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::samplerYcbcrConversion); |
| RETURN_IF_SKIP(Init()); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Required formats/features not supported"; |
| } |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = VK_FORMAT_R8G8B8A8_UNORM; |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 4; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| |
| image_ci.flags = 0; |
| |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| vkt::Image src_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve resolve_region; |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| resolve_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_PLANE_0_BIT; |
| resolve_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_PLANE_0_BIT; |
| m_errorMonitor->SetDesiredError("VUID-VkImageResolve-aspectMask-10981"); |
| m_errorMonitor->SetDesiredError("VUID-VkImageResolve-aspectMask-10981"); |
| vk::CmdResolveImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| m_errorMonitor->VerifyFound(); |
| |
| resolve_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; |
| m_errorMonitor->SetDesiredError("VUID-VkImageResolve-aspectMask-10981"); |
| m_errorMonitor->SetDesiredError("VUID-VkImageResolve-aspectMask-10981"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcSubresource-11802"); |
| vk::CmdResolveImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, |
| &resolve_region); |
| |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImage2ColorImageAspectMask) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_10_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::samplerYcbcrConversion); |
| AddRequiredFeature(vkt::Feature::maintenance10); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceMaintenance10PropertiesKHR maintenance10_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(maintenance10_props); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_R8G8B8A8_UINT, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Required formats/features not supported"; |
| } |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = VK_FORMAT_R8G8B8A8_UINT; |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| |
| vkt::Image src_color_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_color_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve2KHR resolve_region = vku::InitStructHelper(); |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| resolve_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| resolve_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; |
| |
| VkResolveImageModeInfoKHR resolve_mode = vku::InitStructHelper(); |
| resolve_mode.flags = VK_RESOLVE_IMAGE_SKIP_TRANSFER_FUNCTION_BIT_KHR; |
| resolve_mode.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| resolve_mode.stencilResolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| VkResolveImageInfo2KHR resolve_info = vku::InitStructHelper(&resolve_mode); |
| resolve_info.srcImage = src_color_image; |
| resolve_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.dstImage = dst_color_image; |
| resolve_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.regionCount = 1; |
| resolve_info.pRegions = &resolve_region; |
| |
| if (!maintenance10_props.resolveSrgbFormatSupportsTransferFunctionControl) { |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageModeInfoKHR-flags-10996"); |
| } else { |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-pNext-10982"); |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-pNext-10982"); |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10985"); |
| } |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImage2ColorImageResolveModeNone) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_10_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::samplerYcbcrConversion); |
| AddRequiredFeature(vkt::Feature::maintenance10); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceMaintenance10PropertiesKHR maintenance10_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(maintenance10_props); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_R8G8B8A8_UINT, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Required formats/features not supported"; |
| } |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = VK_FORMAT_R8G8B8A8_UINT; |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| |
| vkt::Image src_color_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_color_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve2KHR resolve_region = vku::InitStructHelper(); |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| VkResolveImageModeInfoKHR resolve_mode = vku::InitStructHelper(); |
| resolve_mode.resolveMode = VK_RESOLVE_MODE_NONE; |
| resolve_mode.stencilResolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| VkResolveImageInfo2KHR resolve_info = vku::InitStructHelper(&resolve_mode); |
| resolve_info.srcImage = src_color_image; |
| resolve_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.dstImage = dst_color_image; |
| resolve_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.regionCount = 1; |
| resolve_info.pRegions = &resolve_region; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10985"); |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10983"); |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImage2DepthImageAspectMask) { |
| AddRequiredExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_10_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::samplerYcbcrConversion); |
| AddRequiredFeature(vkt::Feature::maintenance10); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = VK_FORMAT_D16_UNORM; |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Multisample depth images not supported"; |
| } |
| |
| vkt::Image src_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve2KHR resolve_region = vku::InitStructHelper(); |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| VkResolveImageModeInfoKHR resolve_mode = vku::InitStructHelper(); |
| resolve_mode.flags = 0; |
| resolve_mode.resolveMode = VK_RESOLVE_MODE_MIN_BIT; |
| resolve_mode.stencilResolveMode = VK_RESOLVE_MODE_MIN_BIT; |
| VkResolveImageInfo2KHR resolve_info = vku::InitStructHelper(&resolve_mode); |
| resolve_info.srcImage = src_depth_image; |
| resolve_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.dstImage = dst_depth_image; |
| resolve_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.regionCount = 1; |
| resolve_info.pRegions = &resolve_region; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-srcSubresource-11800"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdResolveImage-dstSubresource-11801"); |
| |
| resolve_info.srcImage = src_depth_image; |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImage2DepthImageIllegalAspectMaskValues) { |
| AddRequiredExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_10_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::samplerYcbcrConversion); |
| AddRequiredFeature(vkt::Feature::maintenance10); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = VK_FORMAT_D16_UNORM; |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Multisample depth images not supported"; |
| } |
| |
| vkt::Image src_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve2KHR resolve_region = vku::InitStructHelper(); |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_PLANE_0_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_PLANE_0_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| VkResolveImageModeInfoKHR resolve_mode = vku::InitStructHelper(); |
| resolve_mode.flags = 0; |
| resolve_mode.resolveMode = VK_RESOLVE_MODE_MIN_BIT; |
| resolve_mode.stencilResolveMode = VK_RESOLVE_MODE_MIN_BIT; |
| VkResolveImageInfo2KHR resolve_info = vku::InitStructHelper(&resolve_mode); |
| resolve_info.srcImage = src_depth_image; |
| resolve_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.dstImage = dst_depth_image; |
| resolve_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.regionCount = 1; |
| resolve_info.pRegions = &resolve_region; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkImageResolve2-aspectMask-10993"); |
| m_errorMonitor->SetDesiredError("VUID-VkImageResolve2-aspectMask-10993"); |
| resolve_info.srcImage = src_depth_image; |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImage2DepthImageSrcAndDstAspectMasksDifferent) { |
| AddRequiredExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_10_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::samplerYcbcrConversion); |
| AddRequiredFeature(vkt::Feature::maintenance10); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = VK_FORMAT_D16_UNORM; |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Multisample depth images not supported"; |
| } |
| vkt::Image src_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve2KHR resolve_region = vku::InitStructHelper(); |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| VkResolveImageModeInfoKHR resolve_mode = vku::InitStructHelper(); |
| resolve_mode.flags = 0; |
| resolve_mode.resolveMode = VK_RESOLVE_MODE_MIN_BIT; |
| resolve_mode.stencilResolveMode = VK_RESOLVE_MODE_MIN_BIT; |
| VkResolveImageInfo2KHR resolve_info = vku::InitStructHelper(&resolve_mode); |
| resolve_info.srcImage = src_depth_image; |
| resolve_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.dstImage = dst_depth_image; |
| resolve_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.regionCount = 1; |
| resolve_info.pRegions = &resolve_region; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcSubresource-11802"); |
| resolve_info.srcImage = src_depth_image; |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImage2DepthImageResolveModeNone) { |
| AddRequiredExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_10_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::samplerYcbcrConversion); |
| AddRequiredFeature(vkt::Feature::maintenance10); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(depth_stencil_resolve_props); |
| const bool has_depth_resolve_mode_sample_zero = |
| (depth_stencil_resolve_props.supportedDepthResolveModes & VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) != 0; |
| if (has_depth_resolve_mode_sample_zero) { |
| GTEST_SKIP() << "depth resolve mode supports VK_RESOLVE_MODE_SAMPLE_ZERO_BIT"; |
| } |
| const bool has_stencil_resolve_mode_sample_average = |
| (depth_stencil_resolve_props.supportedStencilResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT) != 0; |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = VK_FORMAT_D16_UNORM; |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Multisample depth images not supported"; |
| } |
| |
| vkt::Image src_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve2KHR resolve_region = vku::InitStructHelper(); |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| VkResolveImageModeInfoKHR resolve_mode = vku::InitStructHelper(); |
| resolve_mode.flags = 0; |
| resolve_mode.resolveMode = VK_RESOLVE_MODE_NONE; |
| resolve_mode.stencilResolveMode = VK_RESOLVE_MODE_NONE; |
| VkResolveImageInfo2KHR resolve_info = vku::InitStructHelper(&resolve_mode); |
| resolve_info.srcImage = src_depth_image; |
| resolve_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.dstImage = dst_depth_image; |
| resolve_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.regionCount = 1; |
| resolve_info.pRegions = &resolve_region; |
| |
| resolve_info.srcImage = src_depth_image; |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10987"); |
| if (!has_stencil_resolve_mode_sample_average) { |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10990"); |
| } |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImage2DepthImageResolveMode) { |
| AddRequiredExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_10_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::samplerYcbcrConversion); |
| AddRequiredFeature(vkt::Feature::maintenance10); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(depth_stencil_resolve_props); |
| const bool has_depth_resolve_mode_sample_zero = |
| (depth_stencil_resolve_props.supportedDepthResolveModes & VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) != 0; |
| if (has_depth_resolve_mode_sample_zero) { |
| GTEST_SKIP() << "depth resolve mode supports VK_RESOLVE_MODE_SAMPLE_ZERO_BIT"; |
| } |
| const bool has_stencil_resolve_mode_sample_average = |
| (depth_stencil_resolve_props.supportedStencilResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT) != 0; |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = VK_FORMAT_D16_UNORM; |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Multisample depth images not supported"; |
| } |
| |
| vkt::Image src_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve2KHR resolve_region = vku::InitStructHelper(); |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| VkResolveImageModeInfoKHR resolve_mode = vku::InitStructHelper(); |
| resolve_mode.flags = 0; |
| resolve_mode.resolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; |
| resolve_mode.stencilResolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| VkResolveImageInfo2KHR resolve_info = vku::InitStructHelper(&resolve_mode); |
| resolve_info.srcImage = src_depth_image; |
| resolve_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.dstImage = dst_depth_image; |
| resolve_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.regionCount = 1; |
| resolve_info.pRegions = &resolve_region; |
| |
| resolve_info.srcImage = src_depth_image; |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10989"); |
| if (!has_stencil_resolve_mode_sample_average) { |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10990"); |
| } |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImage2StencilImageResolveMode) { |
| AddRequiredExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_10_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::samplerYcbcrConversion); |
| AddRequiredFeature(vkt::Feature::maintenance10); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(depth_stencil_resolve_props); |
| const bool has_stencil_resolve_mode_sample_average = |
| (depth_stencil_resolve_props.supportedStencilResolveModes & VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) != 0; |
| if (has_stencil_resolve_mode_sample_average) { |
| GTEST_SKIP() << "stencil resolve mode supports VK_RESOLVE_MODE_SAMPLE_ZERO_BIT"; |
| } |
| const bool has_depth_resolve_mode_sample_average = |
| (depth_stencil_resolve_props.supportedDepthResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT) != 0; |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = FindSupportedDepthStencilFormat(Gpu()); |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Multisample depth/stencil images not supported"; |
| } |
| |
| vkt::Image src_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve2KHR resolve_region = vku::InitStructHelper(); |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| VkResolveImageModeInfoKHR resolve_mode = vku::InitStructHelper(); |
| resolve_mode.flags = 0; |
| resolve_mode.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| resolve_mode.stencilResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; |
| VkResolveImageInfo2KHR resolve_info = vku::InitStructHelper(&resolve_mode); |
| resolve_info.srcImage = src_depth_image; |
| resolve_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.dstImage = dst_depth_image; |
| resolve_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.regionCount = 1; |
| resolve_info.pRegions = &resolve_region; |
| |
| resolve_info.srcImage = src_depth_image; |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10990"); |
| if (!has_depth_resolve_mode_sample_average) { |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10989"); |
| } |
| |
| if (!depth_stencil_resolve_props.independentResolve) { |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10991"); |
| } |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImage2DepthStencilImageResolveMode) { |
| AddRequiredExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_10_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::samplerYcbcrConversion); |
| AddRequiredFeature(vkt::Feature::maintenance10); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(depth_stencil_resolve_props); |
| const bool has_stencil_resolve_mode_sample_average = |
| (depth_stencil_resolve_props.supportedStencilResolveModes & VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) != 0; |
| if (has_stencil_resolve_mode_sample_average) { |
| GTEST_SKIP() << "stencil resolve mode supports VK_RESOLVE_MODE_SAMPLE_ZERO_BIT"; |
| } |
| const bool has_depth_resolve_mode_sample_average = |
| (depth_stencil_resolve_props.supportedDepthResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT) != 0; |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = FindSupportedDepthStencilFormat(Gpu()); |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Multisample depth/stencil images not supported"; |
| } |
| |
| vkt::Image src_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| std::array<VkImageResolve2KHR, 2> resolve_regions; |
| resolve_regions[0] = vku::InitStructHelper(); |
| resolve_regions[0].srcSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}; |
| resolve_regions[0].srcOffset = {0, 0, 0}; |
| resolve_regions[0].dstSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}; |
| resolve_regions[0].dstOffset = {0, 0, 0}; |
| resolve_regions[0].extent = {1, 1, 1}; |
| resolve_regions[1] = resolve_regions[0]; |
| resolve_regions[1].srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; |
| resolve_regions[1].dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; |
| |
| VkResolveImageModeInfoKHR resolve_mode = vku::InitStructHelper(); |
| resolve_mode.flags = 0; |
| resolve_mode.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| resolve_mode.stencilResolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; |
| VkResolveImageInfo2KHR resolve_info = vku::InitStructHelper(&resolve_mode); |
| resolve_info.srcImage = src_depth_image; |
| resolve_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.dstImage = dst_depth_image; |
| resolve_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.regionCount = size32(resolve_regions); |
| resolve_info.pRegions = resolve_regions.data(); |
| |
| resolve_info.srcImage = src_depth_image; |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10990"); |
| if (!has_depth_resolve_mode_sample_average) { |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10989"); |
| } |
| if (!depth_stencil_resolve_props.independentResolve) { |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10991"); |
| } |
| if (!depth_stencil_resolve_props.independentResolveNone) { |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10992"); |
| } |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImage2DepthImageNoMaintenance10) { |
| AddRequiredExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::samplerYcbcrConversion); |
| RETURN_IF_SKIP(Init()); |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = VK_FORMAT_D16_UNORM; |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Multisample depth images not supported"; |
| } |
| |
| vkt::Image src_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve2KHR resolve_region = vku::InitStructHelper(); |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| VkResolveImageModeInfoKHR resolve_mode = vku::InitStructHelper(); |
| resolve_mode.flags = 0; |
| resolve_mode.resolveMode = VK_RESOLVE_MODE_MIN_BIT; |
| resolve_mode.stencilResolveMode = VK_RESOLVE_MODE_MIN_BIT; |
| VkResolveImageInfo2KHR resolve_info = vku::InitStructHelper(&resolve_mode); |
| resolve_info.srcImage = src_depth_image; |
| resolve_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.dstImage = dst_depth_image; |
| resolve_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.regionCount = 1; |
| resolve_info.pRegions = &resolve_region; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkImageResolve2-maintenance10-10994"); |
| m_errorMonitor->SetDesiredError("VUID-VkImageResolve2-maintenance10-10994"); |
| resolve_info.srcImage = src_depth_image; |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImage2DepthImageResolveImageModeInfoBothSkipAndEnableTransfer) { |
| AddRequiredExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_10_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::samplerYcbcrConversion); |
| AddRequiredFeature(vkt::Feature::maintenance10); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceMaintenance10PropertiesKHR maintenance_10_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(maintenance_10_props); |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = VK_FORMAT_D16_UNORM; |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Multisample depth images not supported"; |
| } |
| |
| vkt::Image src_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve2KHR resolve_region = vku::InitStructHelper(); |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| VkResolveImageModeInfoKHR resolve_mode = vku::InitStructHelper(); |
| resolve_mode.flags = VK_RESOLVE_IMAGE_SKIP_TRANSFER_FUNCTION_BIT_KHR | VK_RESOLVE_IMAGE_ENABLE_TRANSFER_FUNCTION_BIT_KHR; |
| resolve_mode.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| resolve_mode.stencilResolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| VkResolveImageInfo2KHR resolve_info = vku::InitStructHelper(&resolve_mode); |
| resolve_info.srcImage = src_depth_image; |
| resolve_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.dstImage = dst_depth_image; |
| resolve_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.regionCount = 1; |
| resolve_info.pRegions = &resolve_region; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageModeInfoKHR-flags-10995"); |
| if (!maintenance_10_props.resolveSrgbFormatSupportsTransferFunctionControl) { |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageModeInfoKHR-flags-10996"); |
| } |
| resolve_info.srcImage = src_depth_image; |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImage2DepthImageResolveImageModeInvalidMode) { |
| AddRequiredExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_10_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::samplerYcbcrConversion); |
| AddRequiredFeature(vkt::Feature::maintenance10); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceMaintenance10PropertiesKHR maintenance_10_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(maintenance_10_props); |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = VK_FORMAT_D16_UNORM; |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Multisample depth images not supported"; |
| } |
| |
| vkt::Image src_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve2KHR resolve_region = vku::InitStructHelper(); |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| VkResolveImageModeInfoKHR resolve_mode = vku::InitStructHelper(); |
| resolve_mode.flags = VK_RESOLVE_IMAGE_SKIP_TRANSFER_FUNCTION_BIT_KHR; |
| resolve_mode.resolveMode = VK_RESOLVE_MODE_MIN_BIT; |
| resolve_mode.stencilResolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| VkResolveImageInfo2KHR resolve_info = vku::InitStructHelper(&resolve_mode); |
| resolve_info.srcImage = src_depth_image; |
| resolve_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.dstImage = dst_depth_image; |
| resolve_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.regionCount = 1; |
| resolve_info.pRegions = &resolve_region; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageModeInfoKHR-flags-10997"); |
| if (!maintenance_10_props.resolveSrgbFormatSupportsTransferFunctionControl) { |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageModeInfoKHR-flags-10996"); |
| } |
| resolve_info.srcImage = src_depth_image; |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImage2ColorImageResolveModeSampleZero) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_10_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::samplerYcbcrConversion); |
| AddRequiredFeature(vkt::Feature::maintenance10); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceMaintenance10PropertiesKHR maintenance10_props = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(maintenance10_props); |
| |
| if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, |
| VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Required formats/features not supported"; |
| } |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = VK_FORMAT_R8G8B8A8_UNORM; |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| |
| vkt::Image src_color_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_color_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve2KHR resolve_region = vku::InitStructHelper(); |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| VkResolveImageModeInfoKHR resolve_mode = vku::InitStructHelper(); |
| resolve_mode.resolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; |
| resolve_mode.stencilResolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; |
| VkResolveImageInfo2KHR resolve_info = vku::InitStructHelper(&resolve_mode); |
| resolve_info.srcImage = src_color_image; |
| resolve_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.dstImage = dst_color_image; |
| resolve_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.regionCount = 1; |
| resolve_info.pRegions = &resolve_region; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10984"); |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_info); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeCommand, DrawIndexedIndirectOffset) { |
| AddRequiredFeature(vkt::Feature::multiDrawIndirect); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| CreatePipelineHelper pipe(*this); |
| pipe.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| m_command_buffer.BeginRenderPass(m_renderPassBeginInfo); |
| |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_, 0, 1, |
| &pipe.descriptor_set_->set_, 0, nullptr); |
| |
| vkt::Buffer draw_buffer_correct(*m_device, sizeof(VkDrawIndirectCommand) * 16u, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT); |
| vkt::Buffer index_buffer(*m_device, sizeof(uint32_t), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
| vk::CmdBindIndexBuffer(m_command_buffer, index_buffer, 0, VK_INDEX_TYPE_UINT32); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDrawIndexedIndirect-offset-02710"); |
| vk::CmdDrawIndexedIndirect(m_command_buffer, draw_buffer_correct, 3u, 2u, sizeof(VkDrawIndexedIndirectCommand)); |
| m_errorMonitor->VerifyFound(); |
| |
| m_command_buffer.EndRenderPass(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeCommand, ResolveImage2StencilResolveMode) { |
| SetTargetApiVersion(VK_API_VERSION_1_1); |
| AddRequiredExtensions(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_MAINTENANCE_10_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::maintenance10); |
| RETURN_IF_SKIP(Init()); |
| |
| VkFormat format = FindSupportedStencilOnlyFormat(gpu_); |
| |
| VkImageCreateInfo image_ci = vku::InitStructHelper(); |
| image_ci.format = format; |
| image_ci.extent = {32, 1, 1}; |
| image_ci.mipLevels = 1; |
| image_ci.arrayLayers = 1; |
| image_ci.samples = VK_SAMPLE_COUNT_4_BIT; |
| image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; |
| image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| image_ci.flags = 0; |
| image_ci.imageType = VK_IMAGE_TYPE_2D; |
| if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { |
| GTEST_SKIP() << "Multisample depth images not supported"; |
| } |
| |
| vkt::Image src_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| image_ci.samples = VK_SAMPLE_COUNT_1_BIT; |
| vkt::Image dst_depth_image(*m_device, image_ci, vkt::set_layout); |
| |
| m_command_buffer.Begin(); |
| |
| VkImageResolve2KHR resolve_region = vku::InitStructHelper(); |
| resolve_region.srcSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}; |
| resolve_region.srcOffset = {0, 0, 0}; |
| resolve_region.dstSubresource = {VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0, 1}; |
| resolve_region.dstOffset = {0, 0, 0}; |
| resolve_region.extent = {1, 1, 1}; |
| |
| VkResolveImageModeInfoKHR resolve_mode = vku::InitStructHelper(); |
| resolve_mode.flags = 0; |
| resolve_mode.resolveMode = VK_RESOLVE_MODE_NONE; |
| resolve_mode.stencilResolveMode = VK_RESOLVE_MODE_NONE; |
| VkResolveImageInfo2KHR resolve_info = vku::InitStructHelper(&resolve_mode); |
| resolve_info.srcImage = src_depth_image; |
| resolve_info.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.dstImage = dst_depth_image; |
| resolve_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; |
| resolve_info.regionCount = 1; |
| resolve_info.pRegions = &resolve_region; |
| |
| resolve_info.srcImage = src_depth_image; |
| m_errorMonitor->SetDesiredError("VUID-VkResolveImageInfo2-srcImage-10988"); |
| vk::CmdResolveImage2KHR(m_command_buffer, &resolve_info); |
| m_errorMonitor->VerifyFound(); |
| } |