From eb867e786b65a0bfb73169175953da43edbe6655 Mon Sep 17 00:00:00 2001 From: Boris Zanin Date: Fri, 11 Jan 2019 14:08:43 +0100 Subject: [PATCH] Add tests for VK_KHR_imageless_framebuffer Implement imageless framebuffer extension tests. Add tests: * dEQP-VK.imageless_framebuffer.color * dEQP-VK.imageless_framebuffer.depth_stencil * dEQP-VK.imageless_framebuffer.color_resolve * dEQP-VK.imageless_framebuffer.depth_stencil_resolve * dEQP-VK.imageless_framebuffer.multisubpass Components: Vulkan VK-GL-CTS issue: 1477 Change-Id: I2baa0614369a98afe2c028788824f50505bb291b (cherry picked from commit 656826a55cb17850a0f33dacf671490715020efa) --- AndroidGen.mk | 2 + android/cts/master/vk-master.txt | 5 + .../vulkancts/framework/vulkan/vkBasicTypes.inl | 14 +- external/vulkancts/framework/vulkan/vkCmdUtil.cpp | 39 +- external/vulkancts/framework/vulkan/vkCmdUtil.hpp | 23 +- .../framework/vulkan/vkDeviceExtensions.inl | 1 + .../framework/vulkan/vkDeviceFeatures.inl | 17 +- .../vulkan/vkDeviceFeaturesForContextDecl.inl | 1 + .../vulkan/vkDeviceFeaturesForContextDefs.inl | 1 + .../vkDeviceFeaturesForDefaultDeviceDefs.inl | 1 + .../framework/vulkan/vkGetStructureTypeImpl.inl | 20 + external/vulkancts/framework/vulkan/vkStrUtil.inl | 6 +- .../vulkancts/framework/vulkan/vkStrUtilImpl.inl | 67 +- .../vulkancts/framework/vulkan/vkStructTypes.inl | 36 + external/vulkancts/framework/vulkan/vkVulkan_c.inl | 46 + external/vulkancts/modules/vulkan/CMakeLists.txt | 3 + .../vulkan/imageless_framebuffer/CMakeLists.txt | 16 + .../vktImagelessFramebufferTests.cpp | 2662 ++++++++++++++++++++ .../vktImagelessFramebufferTests.hpp | 39 + .../vulkancts/modules/vulkan/vktTestPackage.cpp | 2 + .../mustpass/master/vk-default-no-waivers.txt | 5 + external/vulkancts/mustpass/master/vk-default.txt | 5 + external/vulkancts/scripts/src/extensions_data.txt | 3 +- external/vulkancts/scripts/src/vulkan_core.h | 46 + 24 files changed, 3041 insertions(+), 19 deletions(-) create mode 100644 external/vulkancts/modules/vulkan/imageless_framebuffer/CMakeLists.txt create mode 100644 external/vulkancts/modules/vulkan/imageless_framebuffer/vktImagelessFramebufferTests.cpp create mode 100644 external/vulkancts/modules/vulkan/imageless_framebuffer/vktImagelessFramebufferTests.hpp diff --git a/AndroidGen.mk b/AndroidGen.mk index 1403c63..25443be 100644 --- a/AndroidGen.mk +++ b/AndroidGen.mk @@ -165,6 +165,7 @@ LOCAL_SRC_FILES := \ external/vulkancts/modules/vulkan/image/vktImageTestsUtil.cpp \ external/vulkancts/modules/vulkan/image/vktImageTexture.cpp \ external/vulkancts/modules/vulkan/image/vktImageTranscodingSupportTests.cpp \ + external/vulkancts/modules/vulkan/imageless_framebuffer/vktImagelessFramebufferTests.cpp \ external/vulkancts/modules/vulkan/memory/vktMemoryAllocationTests.cpp \ external/vulkancts/modules/vulkan/memory/vktMemoryBindingTests.cpp \ external/vulkancts/modules/vulkan/memory/vktMemoryExternalMemoryHostTests.cpp \ @@ -1107,6 +1108,7 @@ LOCAL_C_INCLUDES := \ $(deqp_dir)/external/vulkancts/modules/vulkan/fragment_ops \ $(deqp_dir)/external/vulkancts/modules/vulkan/geometry \ $(deqp_dir)/external/vulkancts/modules/vulkan/image \ + $(deqp_dir)/external/vulkancts/modules/vulkan/imageless_framebuffer \ $(deqp_dir)/external/vulkancts/modules/vulkan/memory \ $(deqp_dir)/external/vulkancts/modules/vulkan/memory_model \ $(deqp_dir)/external/vulkancts/modules/vulkan/multiview \ diff --git a/android/cts/master/vk-master.txt b/android/cts/master/vk-master.txt index 270b292..d92ea15 100644 --- a/android/cts/master/vk-master.txt +++ b/android/cts/master/vk-master.txt @@ -462703,3 +462703,8 @@ dEQP-VK.descriptor_indexing.uniform_buffer_in_loop dEQP-VK.descriptor_indexing.storage_buffer_dynamic_in_loop dEQP-VK.descriptor_indexing.uniform_buffer_dynamic_in_loop dEQP-VK.descriptor_indexing.input_attachment_in_loop +dEQP-VK.imageless_framebuffer.color +dEQP-VK.imageless_framebuffer.depth_stencil +dEQP-VK.imageless_framebuffer.color_resolve +dEQP-VK.imageless_framebuffer.depth_stencil_resolve +dEQP-VK.imageless_framebuffer.multisubpass diff --git a/external/vulkancts/framework/vulkan/vkBasicTypes.inl b/external/vulkancts/framework/vulkan/vkBasicTypes.inl index 95b812e..929cc3a 100644 --- a/external/vulkancts/framework/vulkan/vkBasicTypes.inl +++ b/external/vulkancts/framework/vulkan/vkBasicTypes.inl @@ -304,6 +304,10 @@ enum VkStructureType VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000, VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001, VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = 1000108000, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = 1000108001, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = 1000108002, + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = 1000108003, VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = 1000109000, VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = 1000109001, VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = 1000109002, @@ -2071,6 +2075,13 @@ enum VkDescriptorPoolCreateFlagBits }; typedef deUint32 VkDescriptorPoolCreateFlags; +enum VkFramebufferCreateFlagBits +{ + VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = 0x00000001, + VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF, +}; +typedef deUint32 VkFramebufferCreateFlags; + enum VkAttachmentDescriptionFlagBits { VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001, @@ -2554,8 +2565,6 @@ typedef deUint32 VkPipelineLayoutCreateFlags; typedef deUint32 VkDescriptorPoolResetFlags; -typedef deUint32 VkFramebufferCreateFlags; - typedef deUint32 VkRenderPassCreateFlags; typedef deUint32 VkCommandPoolTrimFlags; @@ -2671,6 +2680,7 @@ VK_DEFINE_PLATFORM_TYPE(CAMetalLayer, void*); #define VK_KHR_16BIT_STORAGE_SPEC_VERSION 1 #define VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION 1 #define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_SPEC_VERSION 1 +#define VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION 1 #define VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME "VK_KHR_create_renderpass2" #define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1 #define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_SPEC_VERSION 1 diff --git a/external/vulkancts/framework/vulkan/vkCmdUtil.cpp b/external/vulkancts/framework/vulkan/vkCmdUtil.cpp index 315feb5..20171b3 100644 --- a/external/vulkancts/framework/vulkan/vkCmdUtil.cpp +++ b/external/vulkancts/framework/vulkan/vkCmdUtil.cpp @@ -53,12 +53,13 @@ void beginRenderPass (const DeviceInterface& vk, const VkRect2D& renderArea, const deUint32 clearValueCount, const VkClearValue* clearValues, - const VkSubpassContents contents) + const VkSubpassContents contents, + const void* pNext) { const VkRenderPassBeginInfo renderPassBeginInfo = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; + pNext, // const void* pNext; renderPass, // VkRenderPass renderPass; framebuffer, // VkFramebuffer framebuffer; renderArea, // VkRect2D renderArea; @@ -98,6 +99,40 @@ void beginRenderPass (const DeviceInterface& vk, const VkRenderPass renderPass, const VkFramebuffer framebuffer, const VkRect2D& renderArea, + const tcu::Vec4& clearColor, + const void* pNext, + const VkSubpassContents contents) +{ + const VkClearValue clearValue = makeClearValueColor(clearColor); + + beginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea, 1u, &clearValue, contents, pNext); +} + +void beginRenderPass (const DeviceInterface& vk, + const VkCommandBuffer commandBuffer, + const VkRenderPass renderPass, + const VkFramebuffer framebuffer, + const VkRect2D& renderArea, + const tcu::Vec4& clearColor, + const float clearDepth, + const deUint32 clearStencil, + const void* pNext, + const VkSubpassContents contents) +{ + const VkClearValue clearValues[] = + { + makeClearValueColor(clearColor), // attachment 0 + makeClearValueDepthStencil(clearDepth, clearStencil), // attachment 1 + }; + + beginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea, DE_LENGTH_OF_ARRAY(clearValues), clearValues, contents, pNext); +} + +void beginRenderPass (const DeviceInterface& vk, + const VkCommandBuffer commandBuffer, + const VkRenderPass renderPass, + const VkFramebuffer framebuffer, + const VkRect2D& renderArea, const tcu::UVec4& clearColor, const VkSubpassContents contents) { diff --git a/external/vulkancts/framework/vulkan/vkCmdUtil.hpp b/external/vulkancts/framework/vulkan/vkCmdUtil.hpp index 5e8de80..91a7e42 100644 --- a/external/vulkancts/framework/vulkan/vkCmdUtil.hpp +++ b/external/vulkancts/framework/vulkan/vkCmdUtil.hpp @@ -43,7 +43,8 @@ void beginRenderPass (const DeviceInterface& vk, const VkRect2D& renderArea, const deUint32 clearValueCount, const VkClearValue* clearValues, - const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE); + const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE, + const void* pNext = DE_NULL); void beginRenderPass (const DeviceInterface& vk, const VkCommandBuffer commandBuffer, @@ -73,6 +74,26 @@ void beginRenderPass (const DeviceInterface& vk, const VkRenderPass renderPass, const VkFramebuffer framebuffer, const VkRect2D& renderArea, + const tcu::Vec4& clearColor, + const void* pNext, + const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE); + +void beginRenderPass (const DeviceInterface& vk, + const VkCommandBuffer commandBuffer, + const VkRenderPass renderPass, + const VkFramebuffer framebuffer, + const VkRect2D& renderArea, + const tcu::Vec4& clearColor, + const float clearDepth, + const deUint32 clearStencil, + const void* pNext, + const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE); + +void beginRenderPass (const DeviceInterface& vk, + const VkCommandBuffer commandBuffer, + const VkRenderPass renderPass, + const VkFramebuffer framebuffer, + const VkRect2D& renderArea, const tcu::UVec4& clearColor, const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE); diff --git a/external/vulkancts/framework/vulkan/vkDeviceExtensions.inl b/external/vulkancts/framework/vulkan/vkDeviceExtensions.inl index 8e6bbe2..5241e20 100644 --- a/external/vulkancts/framework/vulkan/vkDeviceExtensions.inl +++ b/external/vulkancts/framework/vulkan/vkDeviceExtensions.inl @@ -46,5 +46,6 @@ static const char* s_allowedDeviceKhrExtensions[] = "VK_KHR_shader_atomic_int64", "VK_KHR_vulkan_memory_model", "VK_KHR_uniform_buffer_standard_layout", + "VK_KHR_imageless_framebuffer", }; diff --git a/external/vulkancts/framework/vulkan/vkDeviceFeatures.inl b/external/vulkancts/framework/vulkan/vkDeviceFeatures.inl index 2f79135..f5502f2 100644 --- a/external/vulkancts/framework/vulkan/vkDeviceFeatures.inl +++ b/external/vulkancts/framework/vulkan/vkDeviceFeatures.inl @@ -12,6 +12,7 @@ namespace vk #define VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME "VK_EXT_conditional_rendering" #define VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME "VK_KHR_shader_float16_int8" #define VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME "VK_EXT_depth_clip_enable" +#define VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME "VK_KHR_imageless_framebuffer" #define VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME "VK_EXT_inline_uniform_block" #define VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME "VK_EXT_blend_operation_advanced" #define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing" @@ -42,13 +43,14 @@ namespace vk #define VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME "VK_KHR_sampler_ycbcr_conversion" -template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, DECL_PROTECTED_MEMORY_EXTENSION_NAME, 0, 35); } -template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION, 34); } -template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, VK_EXT_TRANSFORM_FEEDBACK_SPEC_VERSION, 33); } -template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV, VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME, VK_NV_CORNER_SAMPLED_IMAGE_SPEC_VERSION, 32); } -template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME, VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION, 31); } -template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION, 30); } -template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, VK_EXT_DEPTH_CLIP_ENABLE_SPEC_VERSION, 29); } +template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, DECL_PROTECTED_MEMORY_EXTENSION_NAME, 0, 36); } +template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION, 35); } +template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, VK_EXT_TRANSFORM_FEEDBACK_SPEC_VERSION, 34); } +template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV, VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME, VK_NV_CORNER_SAMPLED_IMAGE_SPEC_VERSION, 33); } +template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME, VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION, 32); } +template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION, 31); } +template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, VK_EXT_DEPTH_CLIP_ENABLE_SPEC_VERSION, 30); } +template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR, VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME, VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION, 29); } template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT, VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME, VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION, 28); } template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT, VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, VK_EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION, 27); } template<> FeatureDesc makeFeatureDesc(void) { return FeatureDesc(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION, 26); } @@ -88,6 +90,7 @@ static const FeatureStructMapItem featureStructCreatorMap[] = { createFeatureStructWrapper, VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME, VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION }, { createFeatureStructWrapper, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION }, { createFeatureStructWrapper, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, VK_EXT_DEPTH_CLIP_ENABLE_SPEC_VERSION }, + { createFeatureStructWrapper, VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME, VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION }, { createFeatureStructWrapper, VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME, VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION }, { createFeatureStructWrapper, VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, VK_EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION }, { createFeatureStructWrapper, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION }, diff --git a/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDecl.inl b/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDecl.inl index 1ddd0b8..3792d5e 100644 --- a/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDecl.inl +++ b/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDecl.inl @@ -8,6 +8,7 @@ const vk::VkPhysicalDeviceCornerSampledImageFeaturesNV& getCornerSampledImag const vk::VkPhysicalDeviceConditionalRenderingFeaturesEXT& getConditionalRenderingFeatures (void) const; const vk::VkPhysicalDeviceFloat16Int8FeaturesKHR& getFloat16Int8Features (void) const; const vk::VkPhysicalDeviceDepthClipEnableFeaturesEXT& getDepthClipEnableFeatures (void) const; +const vk::VkPhysicalDeviceImagelessFramebufferFeaturesKHR& getImagelessFramebufferFeatures (void) const; const vk::VkPhysicalDeviceInlineUniformBlockFeaturesEXT& getInlineUniformBlockFeatures (void) const; const vk::VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT& getBlendOperationAdvancedFeatures (void) const; const vk::VkPhysicalDeviceDescriptorIndexingFeaturesEXT& getDescriptorIndexingFeatures (void) const; diff --git a/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDefs.inl b/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDefs.inl index 95ae97f..8704239 100644 --- a/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDefs.inl +++ b/external/vulkancts/framework/vulkan/vkDeviceFeaturesForContextDefs.inl @@ -8,6 +8,7 @@ const vk::VkPhysicalDeviceCornerSampledImageFeaturesNV& Context::getCornerSa const vk::VkPhysicalDeviceConditionalRenderingFeaturesEXT& Context::getConditionalRenderingFeatures (void) const { return m_device->getConditionalRenderingFeatures(); } const vk::VkPhysicalDeviceFloat16Int8FeaturesKHR& Context::getFloat16Int8Features (void) const { return m_device->getFloat16Int8Features(); } const vk::VkPhysicalDeviceDepthClipEnableFeaturesEXT& Context::getDepthClipEnableFeatures (void) const { return m_device->getDepthClipEnableFeatures(); } +const vk::VkPhysicalDeviceImagelessFramebufferFeaturesKHR& Context::getImagelessFramebufferFeatures (void) const { return m_device->getImagelessFramebufferFeatures(); } const vk::VkPhysicalDeviceInlineUniformBlockFeaturesEXT& Context::getInlineUniformBlockFeatures (void) const { return m_device->getInlineUniformBlockFeatures(); } const vk::VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT& Context::getBlendOperationAdvancedFeatures (void) const { return m_device->getBlendOperationAdvancedFeatures(); } const vk::VkPhysicalDeviceDescriptorIndexingFeaturesEXT& Context::getDescriptorIndexingFeatures (void) const { return m_device->getDescriptorIndexingFeatures(); } diff --git a/external/vulkancts/framework/vulkan/vkDeviceFeaturesForDefaultDeviceDefs.inl b/external/vulkancts/framework/vulkan/vkDeviceFeaturesForDefaultDeviceDefs.inl index 894a756..97430fa 100644 --- a/external/vulkancts/framework/vulkan/vkDeviceFeaturesForDefaultDeviceDefs.inl +++ b/external/vulkancts/framework/vulkan/vkDeviceFeaturesForDefaultDeviceDefs.inl @@ -8,6 +8,7 @@ const VkPhysicalDeviceCornerSampledImageFeaturesNV& getCornerSampledImageFea const VkPhysicalDeviceConditionalRenderingFeaturesEXT& getConditionalRenderingFeatures (void) const { return m_deviceFeatures.getFeatureType(); } const VkPhysicalDeviceFloat16Int8FeaturesKHR& getFloat16Int8Features (void) const { return m_deviceFeatures.getFeatureType(); } const VkPhysicalDeviceDepthClipEnableFeaturesEXT& getDepthClipEnableFeatures (void) const { return m_deviceFeatures.getFeatureType(); } +const VkPhysicalDeviceImagelessFramebufferFeaturesKHR& getImagelessFramebufferFeatures (void) const { return m_deviceFeatures.getFeatureType(); } const VkPhysicalDeviceInlineUniformBlockFeaturesEXT& getInlineUniformBlockFeatures (void) const { return m_deviceFeatures.getFeatureType(); } const VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT& getBlendOperationAdvancedFeatures (void) const { return m_deviceFeatures.getFeatureType(); } const VkPhysicalDeviceDescriptorIndexingFeaturesEXT& getDescriptorIndexingFeatures (void) const { return m_deviceFeatures.getFeatureType(); } diff --git a/external/vulkancts/framework/vulkan/vkGetStructureTypeImpl.inl b/external/vulkancts/framework/vulkan/vkGetStructureTypeImpl.inl index 7eecbaa..d59f9d9 100644 --- a/external/vulkancts/framework/vulkan/vkGetStructureTypeImpl.inl +++ b/external/vulkancts/framework/vulkan/vkGetStructureTypeImpl.inl @@ -656,6 +656,26 @@ template<> VkStructureType getStructureType (void) return VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR; } +template<> VkStructureType getStructureType (void) +{ + return VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR; +} + +template<> VkStructureType getStructureType (void) +{ + return VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR; +} + +template<> VkStructureType getStructureType (void) +{ + return VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR; +} + +template<> VkStructureType getStructureType (void) +{ + return VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR; +} + template<> VkStructureType getStructureType (void) { return VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR; diff --git a/external/vulkancts/framework/vulkan/vkStrUtil.inl b/external/vulkancts/framework/vulkan/vkStrUtil.inl index d578e9f..bea100e 100644 --- a/external/vulkancts/framework/vulkan/vkStrUtil.inl +++ b/external/vulkancts/framework/vulkan/vkStrUtil.inl @@ -263,6 +263,7 @@ tcu::Format::Bitfield<32> getColorComponentFlagsStr (VkColorComponentFla tcu::Format::Bitfield<32> getSamplerCreateFlagsStr (VkSamplerCreateFlags value); tcu::Format::Bitfield<32> getDescriptorSetLayoutCreateFlagsStr (VkDescriptorSetLayoutCreateFlags value); tcu::Format::Bitfield<32> getDescriptorPoolCreateFlagsStr (VkDescriptorPoolCreateFlags value); +tcu::Format::Bitfield<32> getFramebufferCreateFlagsStr (VkFramebufferCreateFlags value); tcu::Format::Bitfield<32> getAttachmentDescriptionFlagsStr (VkAttachmentDescriptionFlags value); tcu::Format::Bitfield<32> getSubpassDescriptionFlagsStr (VkSubpassDescriptionFlags value); tcu::Format::Bitfield<32> getAccessFlagsStr (VkAccessFlags value); @@ -325,7 +326,6 @@ tcu::Format::Bitfield<32> getPipelineColorBlendStateCreateFlagsStr (VkPipeli tcu::Format::Bitfield<32> getPipelineDynamicStateCreateFlagsStr (VkPipelineDynamicStateCreateFlags value); tcu::Format::Bitfield<32> getPipelineLayoutCreateFlagsStr (VkPipelineLayoutCreateFlags value); tcu::Format::Bitfield<32> getDescriptorPoolResetFlagsStr (VkDescriptorPoolResetFlags value); -tcu::Format::Bitfield<32> getFramebufferCreateFlagsStr (VkFramebufferCreateFlags value); tcu::Format::Bitfield<32> getRenderPassCreateFlagsStr (VkRenderPassCreateFlags value); tcu::Format::Bitfield<32> getCommandPoolTrimFlagsStr (VkCommandPoolTrimFlags value); tcu::Format::Bitfield<32> getDescriptorUpdateTemplateCreateFlagsStr (VkDescriptorUpdateTemplateCreateFlags value); @@ -560,6 +560,10 @@ std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceFloat16Int8Feat std::ostream& operator<< (std::ostream& s, const VkRectLayerKHR& value); std::ostream& operator<< (std::ostream& s, const VkPresentRegionKHR& value); std::ostream& operator<< (std::ostream& s, const VkPresentRegionsKHR& value); +std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceImagelessFramebufferFeaturesKHR& value); +std::ostream& operator<< (std::ostream& s, const VkFramebufferAttachmentImageInfoKHR& value); +std::ostream& operator<< (std::ostream& s, const VkFramebufferAttachmentsCreateInfoKHR& value); +std::ostream& operator<< (std::ostream& s, const VkRenderPassAttachmentBeginInfoKHR& value); std::ostream& operator<< (std::ostream& s, const VkAttachmentDescription2KHR& value); std::ostream& operator<< (std::ostream& s, const VkAttachmentReference2KHR& value); std::ostream& operator<< (std::ostream& s, const VkSubpassDescription2KHR& value); diff --git a/external/vulkancts/framework/vulkan/vkStrUtilImpl.inl b/external/vulkancts/framework/vulkan/vkStrUtilImpl.inl index 495915f..9f5e83a 100644 --- a/external/vulkancts/framework/vulkan/vkStrUtilImpl.inl +++ b/external/vulkancts/framework/vulkan/vkStrUtilImpl.inl @@ -316,6 +316,10 @@ const char* getStructureTypeName (VkStructureType value) case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT"; case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: return "VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT"; case VK_STRUCTURE_TYPE_HDR_METADATA_EXT: return "VK_STRUCTURE_TYPE_HDR_METADATA_EXT"; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR: return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR"; + case VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR: return "VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR"; + case VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR: return "VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR"; + case VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR: return "VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR"; case VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR: return "VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR"; case VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR: return "VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR"; case VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR: return "VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR"; @@ -2275,6 +2279,16 @@ tcu::Format::Bitfield<32> getDescriptorPoolCreateFlagsStr (VkDescriptorPoolCreat return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc)); } +tcu::Format::Bitfield<32> getFramebufferCreateFlagsStr (VkFramebufferCreateFlags value) +{ + static const tcu::Format::BitDesc s_desc[] = + { + tcu::Format::BitDesc(VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR, "VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR"), + tcu::Format::BitDesc(VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM, "VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM"), + }; + return tcu::Format::Bitfield<32>(value, DE_ARRAY_BEGIN(s_desc), DE_ARRAY_END(s_desc)); +} + tcu::Format::Bitfield<32> getAttachmentDescriptionFlagsStr (VkAttachmentDescriptionFlags value) { static const tcu::Format::BitDesc s_desc[] = @@ -2944,11 +2958,6 @@ tcu::Format::Bitfield<32> getDescriptorPoolResetFlagsStr (VkDescriptorPoolResetF return tcu::Format::Bitfield<32>(value, DE_NULL, DE_NULL); } -tcu::Format::Bitfield<32> getFramebufferCreateFlagsStr (VkFramebufferCreateFlags value) -{ - return tcu::Format::Bitfield<32>(value, DE_NULL, DE_NULL); -} - tcu::Format::Bitfield<32> getRenderPassCreateFlagsStr (VkRenderPassCreateFlags value) { return tcu::Format::Bitfield<32>(value, DE_NULL, DE_NULL); @@ -5704,6 +5713,54 @@ std::ostream& operator<< (std::ostream& s, const VkPresentRegionsKHR& value) return s; } +std::ostream& operator<< (std::ostream& s, const VkPhysicalDeviceImagelessFramebufferFeaturesKHR& value) +{ + s << "VkPhysicalDeviceImagelessFramebufferFeaturesKHR = {\n"; + s << "\tsType = " << value.sType << '\n'; + s << "\tpNext = " << value.pNext << '\n'; + s << "\timagelessFramebuffer = " << value.imagelessFramebuffer << '\n'; + s << '}'; + return s; +} + +std::ostream& operator<< (std::ostream& s, const VkFramebufferAttachmentImageInfoKHR& value) +{ + s << "VkFramebufferAttachmentImageInfoKHR = {\n"; + s << "\tsType = " << value.sType << '\n'; + s << "\tpNext = " << value.pNext << '\n'; + s << "\tflags = " << getImageCreateFlagsStr(value.flags) << '\n'; + s << "\tusage = " << getImageUsageFlagsStr(value.usage) << '\n'; + s << "\twidth = " << value.width << '\n'; + s << "\theight = " << value.height << '\n'; + s << "\tlayerCount = " << value.layerCount << '\n'; + s << "\tviewFormatCount = " << value.viewFormatCount << '\n'; + s << "\tpViewFormats = " << value.pViewFormats << '\n'; + s << '}'; + return s; +} + +std::ostream& operator<< (std::ostream& s, const VkFramebufferAttachmentsCreateInfoKHR& value) +{ + s << "VkFramebufferAttachmentsCreateInfoKHR = {\n"; + s << "\tsType = " << value.sType << '\n'; + s << "\tpNext = " << value.pNext << '\n'; + s << "\tattachmentImageInfoCount = " << value.attachmentImageInfoCount << '\n'; + s << "\tpAttachmentImageInfos = " << value.pAttachmentImageInfos << '\n'; + s << '}'; + return s; +} + +std::ostream& operator<< (std::ostream& s, const VkRenderPassAttachmentBeginInfoKHR& value) +{ + s << "VkRenderPassAttachmentBeginInfoKHR = {\n"; + s << "\tsType = " << value.sType << '\n'; + s << "\tpNext = " << value.pNext << '\n'; + s << "\tattachmentCount = " << value.attachmentCount << '\n'; + s << "\tpAttachments = " << value.pAttachments << '\n'; + s << '}'; + return s; +} + std::ostream& operator<< (std::ostream& s, const VkAttachmentDescription2KHR& value) { s << "VkAttachmentDescription2KHR = {\n"; diff --git a/external/vulkancts/framework/vulkan/vkStructTypes.inl b/external/vulkancts/framework/vulkan/vkStructTypes.inl index d559c8a..ea2e3bc 100644 --- a/external/vulkancts/framework/vulkan/vkStructTypes.inl +++ b/external/vulkancts/framework/vulkan/vkStructTypes.inl @@ -2001,6 +2001,42 @@ struct VkPresentRegionsKHR const VkPresentRegionKHR* pRegions; }; +struct VkPhysicalDeviceImagelessFramebufferFeaturesKHR +{ + VkStructureType sType; + void* pNext; + VkBool32 imagelessFramebuffer; +}; + +struct VkFramebufferAttachmentImageInfoKHR +{ + VkStructureType sType; + const void* pNext; + VkImageCreateFlags flags; + VkImageUsageFlags usage; + deUint32 width; + deUint32 height; + deUint32 layerCount; + deUint32 viewFormatCount; + const VkFormat* pViewFormats; +}; + +struct VkFramebufferAttachmentsCreateInfoKHR +{ + VkStructureType sType; + const void* pNext; + deUint32 attachmentImageInfoCount; + const VkFramebufferAttachmentImageInfoKHR* pAttachmentImageInfos; +}; + +struct VkRenderPassAttachmentBeginInfoKHR +{ + VkStructureType sType; + const void* pNext; + deUint32 attachmentCount; + const VkImageView* pAttachments; +}; + struct VkAttachmentDescription2KHR { VkStructureType sType; diff --git a/external/vulkancts/framework/vulkan/vkVulkan_c.inl b/external/vulkancts/framework/vulkan/vkVulkan_c.inl index d6e01a3..59f285c 100644 --- a/external/vulkancts/framework/vulkan/vkVulkan_c.inl +++ b/external/vulkancts/framework/vulkan/vkVulkan_c.inl @@ -354,6 +354,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000, VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001, VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = 1000108000, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = 1000108001, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = 1000108002, + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = 1000108003, VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = 1000109000, VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = 1000109001, VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = 1000109002, @@ -1698,6 +1702,11 @@ typedef enum VkDescriptorPoolCreateFlagBits { } VkDescriptorPoolCreateFlagBits; typedef VkFlags VkDescriptorPoolCreateFlags; typedef VkFlags VkDescriptorPoolResetFlags; + +typedef enum VkFramebufferCreateFlagBits { + VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = 0x00000001, + VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkFramebufferCreateFlagBits; typedef VkFlags VkFramebufferCreateFlags; typedef VkFlags VkRenderPassCreateFlags; @@ -5590,6 +5599,43 @@ VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplateKHR( const void* pData); #endif +#define VK_KHR_imageless_framebuffer 1 +#define VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION 1 +#define VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME "VK_KHR_imageless_framebuffer" + +typedef struct VkPhysicalDeviceImagelessFramebufferFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 imagelessFramebuffer; +} VkPhysicalDeviceImagelessFramebufferFeaturesKHR; + +typedef struct VkFramebufferAttachmentImageInfoKHR { + VkStructureType sType; + const void* pNext; + VkImageCreateFlags flags; + VkImageUsageFlags usage; + deUint32 width; + deUint32 height; + deUint32 layerCount; + deUint32 viewFormatCount; + const VkFormat* pViewFormats; +} VkFramebufferAttachmentImageInfoKHR; + +typedef struct VkFramebufferAttachmentsCreateInfoKHR { + VkStructureType sType; + const void* pNext; + deUint32 attachmentImageInfoCount; + const VkFramebufferAttachmentImageInfoKHR* pAttachmentImageInfos; +} VkFramebufferAttachmentsCreateInfoKHR; + +typedef struct VkRenderPassAttachmentBeginInfoKHR { + VkStructureType sType; + const void* pNext; + deUint32 attachmentCount; + const VkImageView* pAttachments; +} VkRenderPassAttachmentBeginInfoKHR; + + #define VK_KHR_create_renderpass2 1 #define VK_KHR_CREATE_RENDERPASS_2_SPEC_VERSION 1 diff --git a/external/vulkancts/modules/vulkan/CMakeLists.txt b/external/vulkancts/modules/vulkan/CMakeLists.txt index c39bcff..56f8bec 100644 --- a/external/vulkancts/modules/vulkan/CMakeLists.txt +++ b/external/vulkancts/modules/vulkan/CMakeLists.txt @@ -36,6 +36,7 @@ add_subdirectory(transform_feedback) add_subdirectory(util) add_subdirectory(amber) add_subdirectory(descriptor_indexing) +add_subdirectory(imageless_framebuffer) include_directories( api @@ -74,6 +75,7 @@ include_directories( util amber descriptor_indexing + imageless_framebuffer ) set(DEQP_VK_SRCS @@ -131,6 +133,7 @@ set(DEQP_VK_LIBS deqp-vk-amber deqp-vk-transform-feedback deqp-vk-descriptor-indexing + deqp-vk-imageless-framebuffer ) if (DE_COMPILER_IS_MSC AND (DE_PTR_SIZE EQUAL 4)) diff --git a/external/vulkancts/modules/vulkan/imageless_framebuffer/CMakeLists.txt b/external/vulkancts/modules/vulkan/imageless_framebuffer/CMakeLists.txt new file mode 100644 index 0000000..46f5954 --- /dev/null +++ b/external/vulkancts/modules/vulkan/imageless_framebuffer/CMakeLists.txt @@ -0,0 +1,16 @@ +include_directories(..) + +set(DEQP_VK_IMAGELESS_FRAMEBUFFER_SRCS + vktImagelessFramebufferTests.hpp + vktImagelessFramebufferTests.cpp +) + +set(DEQP_VK_IMAGELESS_FRAMEBUFFER_LIBS + tcutil + vkutil +) + +PCH(DEQP_VK_IMAGELESS_FRAMEBUFFER_SRCS ../pch.cpp) + +add_library(deqp-vk-imageless-framebuffer STATIC ${DEQP_VK_IMAGELESS_FRAMEBUFFER_SRCS}) +target_link_libraries(deqp-vk-imageless-framebuffer ${DEQP_VK_IMAGELESS_FRAMEBUFFER_LIBS}) diff --git a/external/vulkancts/modules/vulkan/imageless_framebuffer/vktImagelessFramebufferTests.cpp b/external/vulkancts/modules/vulkan/imageless_framebuffer/vktImagelessFramebufferTests.cpp new file mode 100644 index 0000000..6207c6e --- /dev/null +++ b/external/vulkancts/modules/vulkan/imageless_framebuffer/vktImagelessFramebufferTests.cpp @@ -0,0 +1,2662 @@ +/*------------------------------------------------------------------------ + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2019 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *//*! + * \file + * \brief Vulkan Imageless Framebuffer Tests + *//*--------------------------------------------------------------------*/ + +#include "vktImagelessFramebufferTests.hpp" +#include "vktTestGroupUtil.hpp" +#include "vktTestCase.hpp" + +#include "deUniquePtr.hpp" +#include "deRandom.hpp" + +#include "tcuTextureUtil.hpp" +#include "tcuVectorUtil.hpp" +#include "tcuImageCompare.hpp" +#include "tcuRGBA.hpp" + +#include "vkCmdUtil.hpp" +#include "vkImageUtil.hpp" +#include "vkObjUtil.hpp" +#include "vkQueryUtil.hpp" +#include "vkRefUtil.hpp" +#include "vkTypeUtil.hpp" +#include "vkBuilderUtil.hpp" + +#include + +namespace vkt +{ +namespace imageless +{ + +namespace +{ +using namespace vk; +using de::MovePtr; +using de::UniquePtr; +using de::SharedPtr; + +typedef SharedPtr > SharedPtrVkPipeline; + +enum TestType +{ + TEST_TYPE_COLOR = 0, + TEST_TYPE_DEPTH_STENCIL, + TEST_TYPE_COLOR_RESOLVE, + TEST_TYPE_DEPTH_STENCIL_RESOLVE, + TEST_TYPE_MULTISUBPASS, + TEST_TYPE_LAST +}; + +enum AspectFlagBits +{ + ASPECT_NONE = 0, + ASPECT_COLOR = (1<<0), + ASPECT_DEPTH = (1<<1), + ASPECT_STENCIL = (1<<2), + ASPECT_DEPTH_STENCIL = ASPECT_DEPTH | ASPECT_STENCIL, +}; +typedef deUint32 AspectFlags; + +const deUint32 NO_SAMPLE = static_cast(-1); +const deUint32 NO_SUBPASS = static_cast(-1); + +struct TestParameters +{ + TestType testType; + VkFormat colorFormat; + VkFormat dsFormat; +}; + +template +inline SharedPtr > makeSharedPtr (Move move) +{ + return SharedPtr >(new Unique(move)); +} + +VkSampleCountFlagBits sampleCountBitFromSampleCount (deUint32 count) +{ + switch (count) + { + case 1: return VK_SAMPLE_COUNT_1_BIT; + case 2: return VK_SAMPLE_COUNT_2_BIT; + case 4: return VK_SAMPLE_COUNT_4_BIT; + case 8: return VK_SAMPLE_COUNT_8_BIT; + case 16: return VK_SAMPLE_COUNT_16_BIT; + case 32: return VK_SAMPLE_COUNT_32_BIT; + case 64: return VK_SAMPLE_COUNT_64_BIT; + + default: + DE_FATAL("Invalid sample count"); + return (VkSampleCountFlagBits)0x0; + } +} + +VkAttachmentReference2KHR convertAttachmentReference (const VkAttachmentReference& attachmentReference, const VkImageAspectFlags aspectMask) +{ + const VkAttachmentReference2KHR attachmentReference2 = + { + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + attachmentReference.attachment, // deUint32 attachment; + attachmentReference.layout, // VkImageLayout layout; + aspectMask // VkImageAspectFlags aspectMask; + }; + + return attachmentReference2; +} + +std::vector convertAttachmentDescriptions (const std::vector& attachmentDescriptions) +{ + std::vector attachmentDescriptions2; + + attachmentDescriptions2.reserve(attachmentDescriptions.size()); + + for (size_t adNdx = 0; adNdx < attachmentDescriptions.size(); ++adNdx) + { + const VkAttachmentDescription& attachmentDescription = attachmentDescriptions[adNdx]; + const VkAttachmentDescription2KHR attachmentDescription2 = + { + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + attachmentDescription.flags, // VkAttachmentDescriptionFlags flags; + attachmentDescription.format, // VkFormat format; + attachmentDescription.samples, // VkSampleCountFlagBits samples; + attachmentDescription.loadOp, // VkAttachmentLoadOp loadOp; + attachmentDescription.storeOp, // VkAttachmentStoreOp storeOp; + attachmentDescription.stencilLoadOp, // VkAttachmentLoadOp stencilLoadOp; + attachmentDescription.stencilStoreOp, // VkAttachmentStoreOp stencilStoreOp; + attachmentDescription.initialLayout, // VkImageLayout initialLayout; + attachmentDescription.finalLayout, // VkImageLayout finalLayout; + }; + + attachmentDescriptions2.push_back(attachmentDescription2); + } + + return attachmentDescriptions2; +} + +Move makeGraphicsPipeline (const DeviceInterface& vk, + const VkDevice device, + const VkPipelineLayout pipelineLayout, + const VkRenderPass renderPass, + const VkShaderModule vertexModule, + const VkShaderModule fragmendModule, + const VkExtent2D renderSize, + const AspectFlags depthStencilAspects = ASPECT_NONE, + const VkSampleCountFlagBits sampleCountBits = VK_SAMPLE_COUNT_1_BIT, + const deUint32 subpass = 0) +{ + const bool useDepth = (depthStencilAspects & ASPECT_DEPTH) != 0; + const bool useStencil = (depthStencilAspects & ASPECT_STENCIL) != 0; + const std::vector viewports (1, makeViewport(renderSize)); + const std::vector scissors (1, makeRect2D(renderSize)); + const VkStencilOpState stencilOpState = + { + VK_STENCIL_OP_KEEP, // VkStencilOp failOp; + VK_STENCIL_OP_INCREMENT_AND_CLAMP, // VkStencilOp passOp; + VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; + VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp; + ~0u, // deUint32 compareMask; + ~0u, // deUint32 writeMask; + 0u // deUint32 reference; + }; + const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = + { + VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags; + useDepth ? VK_TRUE : VK_FALSE, // VkBool32 depthTestEnable; + useDepth ? VK_TRUE : VK_FALSE, // VkBool32 depthWriteEnable; + VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; + VK_FALSE, // VkBool32 depthBoundsTestEnable; + useStencil ? VK_TRUE : VK_FALSE, // VkBool32 stencilTestEnable; + stencilOpState, // VkStencilOpState front; + stencilOpState, // VkStencilOpState back; + 0.0f, // float minDepthBounds; + 1.0f // float maxDepthBounds; + }; + const VkPipelineMultisampleStateCreateInfo multisampleState = + { + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags flags; + sampleCountBits, // VkSampleCountFlagBits rasterizationSamples; + VK_FALSE, // VkBool32 sampleShadingEnable; + 0.0f, // float minSampleShading; + DE_NULL, // const VkSampleMask* pSampleMask; + VK_FALSE, // VkBool32 alphaToCoverageEnable; + VK_FALSE, // VkBool32 alphaToOneEnable; + }; + + return makeGraphicsPipeline(vk, // const DeviceInterface& vk + device, // const VkDevice device + pipelineLayout, // const VkPipelineLayout pipelineLayout + vertexModule, // const VkShaderModule vertexShaderModule + DE_NULL, // const VkShaderModule tessellationControlModule + DE_NULL, // const VkShaderModule tessellationEvalModule + DE_NULL, // const VkShaderModule geometryShaderModule + fragmendModule, // const VkShaderModule fragmentShaderModule + renderPass, // const VkRenderPass renderPass + viewports, // const std::vector& viewports + scissors, // const std::vector& scissors + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,// const VkPrimitiveTopology topology + subpass, // const deUint32 subpass + 0u, // const deUint32 patchControlPoints + DE_NULL, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo + DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo + &multisampleState, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo + &pipelineDepthStencilStateInfo); // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo +} + +Move makeRenderPass (const DeviceInterface& vk, + const VkDevice device, + const VkFormat colorFormat, + const VkFormat depthStencilFormat, + const VkSampleCountFlagBits colorSamples, + const VkSampleCountFlagBits depthStencilSamples = VK_SAMPLE_COUNT_1_BIT, + const VkAttachmentLoadOp loadOperation = VK_ATTACHMENT_LOAD_OP_CLEAR, + const VkImageLayout finalLayoutColor = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + const VkImageLayout finalLayoutDepthStencil = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + const VkImageLayout subpassLayoutColor = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + const VkImageLayout subpassLayoutDepthStencil = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + const VkAllocationCallbacks* const allocationCallbacks = DE_NULL) +{ + const bool hasColor = colorFormat != VK_FORMAT_UNDEFINED; + const bool hasDepthStencil = depthStencilFormat != VK_FORMAT_UNDEFINED; + const bool hasColorResolve = hasColor && (colorSamples != VK_SAMPLE_COUNT_1_BIT); + const bool hasDepthStencilResolve = hasDepthStencil && (depthStencilSamples != VK_SAMPLE_COUNT_1_BIT); + const VkImageLayout initialLayoutColor = loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED; + const VkImageLayout initialLayoutDepthStencil = loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED; + const VkAttachmentDescription colorAttachmentDescription = + { + (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; + colorFormat, // VkFormat format; + colorSamples, // VkSampleCountFlagBits samples; + loadOperation, // VkAttachmentLoadOp loadOp; + VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; + VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; + VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; + initialLayoutColor, // VkImageLayout initialLayout; + finalLayoutColor // VkImageLayout finalLayout; + }; + const VkAttachmentDescription depthStencilAttachmentDescription = + { + (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; + depthStencilFormat, // VkFormat format; + depthStencilSamples, // VkSampleCountFlagBits samples; + loadOperation, // VkAttachmentLoadOp loadOp; + VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; + loadOperation, // VkAttachmentLoadOp stencilLoadOp; + VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp; + initialLayoutDepthStencil, // VkImageLayout initialLayout; + finalLayoutDepthStencil // VkImageLayout finalLayout; + }; + const VkAttachmentDescription colorResolveAttachmentDescription = + { + (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; + colorFormat, // VkFormat format; + VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; + VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp; + VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; + VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; + VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; + initialLayoutColor, // VkImageLayout initialLayout; + finalLayoutColor // VkImageLayout finalLayout; + }; + const VkAttachmentDescription depthStencilResolveAttachmentDescription = + { + (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; + depthStencilFormat, // VkFormat format; + VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; + VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp; + VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; + VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp stencilLoadOp; + VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp; + initialLayoutDepthStencil, // VkImageLayout initialLayout; + finalLayoutDepthStencil // VkImageLayout finalLayout; + }; + std::vector attachmentDescriptions; + + if (hasColor) + attachmentDescriptions.push_back(colorAttachmentDescription); + if (hasDepthStencil) + attachmentDescriptions.push_back(depthStencilAttachmentDescription); + if (hasColorResolve) + attachmentDescriptions.push_back(colorResolveAttachmentDescription); + if (hasDepthStencilResolve) + attachmentDescriptions.push_back(depthStencilResolveAttachmentDescription); + + deUint32 attachmentCounter = 0; + const VkAttachmentReference colorAttachmentRef = + { + hasColor ? attachmentCounter++ : 0u, // deUint32 attachment; + subpassLayoutColor // VkImageLayout layout; + }; + const VkAttachmentReference depthStencilAttachmentRef = + { + hasDepthStencil ? attachmentCounter++ : 0u, // deUint32 attachment; + subpassLayoutDepthStencil // VkImageLayout layout; + }; + const VkAttachmentReference colorResolveAttachmentRef = + { + hasColorResolve ? attachmentCounter++ : 0u, // deUint32 attachment; + subpassLayoutColor // VkImageLayout layout; + }; + + if (hasDepthStencilResolve) + { + const VkImageAspectFlags colorAspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + const VkImageAspectFlags depthStencilAspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + const VkAttachmentReference2KHR colorAttachmentRef2 = convertAttachmentReference(colorAttachmentRef, colorAspectMask); + const VkAttachmentReference2KHR depthStencilAttachmentRef2 = convertAttachmentReference(depthStencilAttachmentRef, depthStencilAspectMask); + const VkAttachmentReference2KHR colorResolveAttachmentRef2 = convertAttachmentReference(colorResolveAttachmentRef, colorAspectMask); + const VkAttachmentReference2KHR depthStencilResolveAttachmentRef2 = + { + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + hasDepthStencilResolve ? attachmentCounter++ : 0u, // deUint32 attachment; + subpassLayoutDepthStencil, // VkImageLayout layout; + depthStencilAspectMask // VkImageAspectFlags aspectMask; + }; + const VkSubpassDescriptionDepthStencilResolveKHR subpassDescriptionDepthStencilResolve = + { + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + VK_RESOLVE_MODE_AVERAGE_BIT_KHR, // VkResolveModeFlagBitsKHR depthResolveMode; + VK_RESOLVE_MODE_MAX_BIT_KHR, // VkResolveModeFlagBitsKHR stencilResolveMode; + &depthStencilResolveAttachmentRef2 // const VkAttachmentReference2KHR* pDepthStencilResolveAttachment; + }; + const VkSubpassDescription2KHR subpassDescription2 = + { + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR, // VkStructureType sType; + &subpassDescriptionDepthStencilResolve, // const void* pNext; + (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; + VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; + 0u, // deUint32 viewMask; + 0u, // deUint32 inputAttachmentCount; + DE_NULL, // const VkAttachmentReference2KHR* pInputAttachments; + hasColor ? 1u : 0u, // deUint32 colorAttachmentCount; + hasColor ? &colorAttachmentRef2 : DE_NULL, // const VkAttachmentReference2KHR* pColorAttachments; + hasColorResolve ? &colorResolveAttachmentRef2 : DE_NULL, // const VkAttachmentReference2KHR* pResolveAttachments; + hasDepthStencil ? &depthStencilAttachmentRef2 : DE_NULL, // const VkAttachmentReference2KHR* pDepthStencilAttachment; + 0u, // deUint32 preserveAttachmentCount; + DE_NULL // const deUint32* pPreserveAttachments; + }; + const std::vector attachmentDescriptions2 = convertAttachmentDescriptions(attachmentDescriptions); + const VkRenderPassCreateInfo2KHR renderPassInfo = + { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; + (deUint32)attachmentDescriptions2.size(), // deUint32 attachmentCount; + &attachmentDescriptions2[0], // const VkAttachmentDescription2KHR* pAttachments; + 1u, // deUint32 subpassCount; + &subpassDescription2, // const VkSubpassDescription2KHR* pSubpasses; + 0u, // deUint32 dependencyCount; + DE_NULL, // const VkSubpassDependency2KHR* pDependencies; + 0u, // deUint32 correlatedViewMaskCount; + DE_NULL // const deUint32* pCorrelatedViewMasks; + }; + + return createRenderPass2KHR(vk, device, &renderPassInfo, allocationCallbacks); + } + else + { + const VkSubpassDescription subpassDescription = + { + (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; + VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; + 0u, // deUint32 inputAttachmentCount; + DE_NULL, // const VkAttachmentReference* pInputAttachments; + hasColor ? 1u : 0u, // deUint32 colorAttachmentCount; + hasColor ? &colorAttachmentRef : DE_NULL, // const VkAttachmentReference* pColorAttachments; + hasColorResolve ? &colorResolveAttachmentRef : DE_NULL, // const VkAttachmentReference* pResolveAttachments; + hasDepthStencil ? &depthStencilAttachmentRef : DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; + 0u, // deUint32 preserveAttachmentCount; + DE_NULL // const deUint32* pPreserveAttachments; + }; + const VkRenderPassCreateInfo renderPassInfo = + { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; + (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount; + &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments; + 1u, // deUint32 subpassCount; + &subpassDescription, // const VkSubpassDescription* pSubpasses; + 0u, // deUint32 dependencyCount; + DE_NULL // const VkSubpassDependency* pDependencies; + }; + + return createRenderPass(vk, device, &renderPassInfo, allocationCallbacks); + } +} + +Move makeRenderPass (const DeviceInterface& vk, + const VkDevice device, + const VkFormat colorFormat, + const VkAllocationCallbacks* const allocationCallbacks) +{ + const VkAttachmentDescription attachmentDescriptions[] = + { + { + (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; + colorFormat, // VkFormat format; + VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; + VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; + VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; + VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; + VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; + VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; + VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout; + }, + { + (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; + colorFormat, // VkFormat format; + VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; + VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp; + VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; + VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; + VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; + VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; + VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout; + }, + }; + const VkAttachmentReference colorAttachmentRef0 = + { + 0u, // deUint32 attachment; + VK_IMAGE_LAYOUT_GENERAL // VkImageLayout layout; + }; + const deUint32 preserveAttachment = 1u; + const VkAttachmentReference inputAttachmentRef1 = + { + 0u, // deUint32 attachment; + VK_IMAGE_LAYOUT_GENERAL // VkImageLayout layout; + }; + const VkAttachmentReference colorAttachmentRef1 = + { + 1u, // deUint32 attachment; + VK_IMAGE_LAYOUT_GENERAL // VkImageLayout layout; + }; + const VkSubpassDescription subpassDescriptions[] = + { + { + (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; + VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; + 0u, // deUint32 inputAttachmentCount; + DE_NULL, // const VkAttachmentReference* pInputAttachments; + 1u, // deUint32 colorAttachmentCount; + &colorAttachmentRef0, // const VkAttachmentReference* pColorAttachments; + DE_NULL, // const VkAttachmentReference* pResolveAttachments; + DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; + 1u, // deUint32 preserveAttachmentCount; + &preserveAttachment // const deUint32* pPreserveAttachments; + }, + { + (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; + VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; + 1u, // deUint32 inputAttachmentCount; + &inputAttachmentRef1, // const VkAttachmentReference* pInputAttachments; + 1u, // deUint32 colorAttachmentCount; + &colorAttachmentRef1, // const VkAttachmentReference* pColorAttachments; + DE_NULL, // const VkAttachmentReference* pResolveAttachments; + DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; + 0u, // deUint32 preserveAttachmentCount; + DE_NULL // const deUint32* pPreserveAttachments; + }, + }; + const VkSubpassDependency subpassDependency = + { + 0, // deUint32 srcSubpass; + 1u, // deUint32 dstSubpass; + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask; + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask; + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; + VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask; + VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR, // VkDependencyFlags dependencyFlags; + }; + const VkRenderPassCreateInfo renderPassInfo = + { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; + DE_LENGTH_OF_ARRAY(attachmentDescriptions), // deUint32 attachmentCount; + &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments; + DE_LENGTH_OF_ARRAY(subpassDescriptions), // deUint32 subpassCount; + &subpassDescriptions[0], // const VkSubpassDescription* pSubpasses; + 1u, // deUint32 dependencyCount; + &subpassDependency // const VkSubpassDependency* pDependencies; + }; + + return createRenderPass(vk, device, &renderPassInfo, allocationCallbacks); +} + +VkImageCreateInfo makeImageCreateInfo (const VkFormat format, const VkExtent2D size, const VkImageUsageFlags usage, VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT) +{ + const VkExtent3D extent = { size.width, size.height, 1u }; + const VkImageCreateInfo imageParams = + { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkImageCreateFlags flags; + VK_IMAGE_TYPE_2D, // VkImageType imageType; + format, // VkFormat format; + extent, // VkExtent3D extent; + 1u, // deUint32 mipLevels; + 1u, // deUint32 arrayLayers; + samples, // VkSampleCountFlagBits samples; + VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; + usage, // VkImageUsageFlags usage; + VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; + 0u, // deUint32 queueFamilyIndexCount; + DE_NULL, // const deUint32* pQueueFamilyIndices; + VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; + }; + return imageParams; +} + +std::vector makeFramebufferAttachmentImageInfos (const VkExtent2D& renderSize, + const VkFormat colorFormat, + const VkImageUsageFlags colorUsage, + const VkFormat dsFormat, + const VkImageUsageFlags dsUsage, + const AspectFlags resolveAspects, + const deUint32 inputAttachmentCount) +{ + const bool colorResolve = (resolveAspects & ASPECT_COLOR) != 0; + const bool depthStencilResolve = (resolveAspects & ASPECT_DEPTH_STENCIL) != 0; + std::vector framebufferAttachmentImageInfos; + + if (colorFormat != VK_FORMAT_UNDEFINED) + { + const VkFramebufferAttachmentImageInfoKHR framebufferAttachmentImageInfo = + { + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkImageCreateFlags)0u, // VkImageCreateFlags flags; + colorUsage, // VkImageUsageFlags usage; + renderSize.width, // deUint32 width; + renderSize.height, // deUint32 height; + 1u, // deUint32 layerCount; + 1u, // deUint32 viewFormatCount; + &colorFormat // const VkFormat* pViewFormats; + }; + + framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo); + } + + if (dsFormat != VK_FORMAT_UNDEFINED) + { + const VkFramebufferAttachmentImageInfoKHR framebufferAttachmentImageInfo = + { + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkImageCreateFlags)0u, // VkImageCreateFlags flags; + dsUsage, // VkImageUsageFlags usage; + renderSize.width, // deUint32 width; + renderSize.height, // deUint32 height; + 1u, // deUint32 layerCount; + 1u, // deUint32 viewFormatCount; + &dsFormat // const VkFormat* pViewFormats; + }; + + framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo); + } + + if (colorResolve) + { + const VkFramebufferAttachmentImageInfoKHR framebufferAttachmentImageInfo = + { + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkImageCreateFlags)0u, // VkImageCreateFlags flags; + colorUsage, // VkImageUsageFlags usage; + renderSize.width, // deUint32 width; + renderSize.height, // deUint32 height; + 1u, // deUint32 layerCount; + 1u, // deUint32 viewFormatCount; + &colorFormat // const VkFormat* pViewFormats; + }; + + DE_ASSERT(colorFormat != VK_FORMAT_UNDEFINED); + + framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo); + } + + if (depthStencilResolve) + { + const VkFramebufferAttachmentImageInfoKHR framebufferAttachmentImageInfo = + { + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkImageCreateFlags)0u, // VkImageCreateFlags flags; + dsUsage, // VkImageUsageFlags usage; + renderSize.width, // deUint32 width; + renderSize.height, // deUint32 height; + 1u, // deUint32 layerCount; + 1u, // deUint32 viewFormatCount; + &dsFormat // const VkFormat* pViewFormats; + }; + + DE_ASSERT(dsFormat != VK_FORMAT_UNDEFINED); + + framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo); + } + + for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < inputAttachmentCount; ++inputAttachmentNdx) + { + const VkFramebufferAttachmentImageInfoKHR framebufferAttachmentImageInfo = + { + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkImageCreateFlags)0u, // VkImageCreateFlags flags; + colorUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, // VkImageUsageFlags usage; + renderSize.width, // deUint32 width; + renderSize.height, // deUint32 height; + 1u, // deUint32 layerCount; + 1u, // deUint32 viewFormatCount; + &colorFormat // const VkFormat* pViewFormats; + }; + + framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo); + } + + return framebufferAttachmentImageInfos; +} + +Move makeFramebuffer (const DeviceInterface& vk, + const VkDevice device, + const VkRenderPass renderPass, + const VkExtent2D& renderSize, + const VkFormat colorFormat, + const VkImageUsageFlags colorUsage, + const VkFormat dsFormat = VK_FORMAT_UNDEFINED, + const VkImageUsageFlags dsUsage = static_cast(0), + const AspectFlags resolveAspects = ASPECT_NONE, + const deUint32 inputAttachmentCount = 0) +{ + const std::vector framebufferAttachmentImageInfos = makeFramebufferAttachmentImageInfos(renderSize, colorFormat, colorUsage, dsFormat, dsUsage, resolveAspects, inputAttachmentCount); + const deUint32 attachmentCount = static_cast(framebufferAttachmentImageInfos.size()); + const VkFramebufferAttachmentsCreateInfoKHR framebufferAttachmentsCreateInfo = + { + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + attachmentCount, // deUint32 attachmentImageInfoCount; + &framebufferAttachmentImageInfos[0] // const VkFramebufferAttachmentImageInfoKHR* pAttachmentImageInfos; + }; + const VkFramebufferCreateInfo framebufferInfo = + { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; + &framebufferAttachmentsCreateInfo, // const void* pNext; + VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR, // VkFramebufferCreateFlags flags; + renderPass, // VkRenderPass renderPass; + attachmentCount, // deUint32 attachmentCount; + DE_NULL, // const VkImageView* pAttachments; + renderSize.width, // deUint32 width; + renderSize.height, // deUint32 height; + 1u, // deUint32 layers; + }; + + return createFramebuffer(vk, device, &framebufferInfo); +} + +Move makeVerifyFramebuffer (const DeviceInterface& vk, + const VkDevice device, + const VkRenderPass renderPass, + const VkImageView colorAttachment, + const VkExtent2D& renderSize, + const deUint32 layers = 1u) +{ + const VkFramebufferCreateInfo framebufferInfo = { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags; + renderPass, // VkRenderPass renderPass; + 1u, // deUint32 attachmentCount; + &colorAttachment, // const VkImageView* pAttachments; + renderSize.width, // deUint32 width; + renderSize.height, // deUint32 height; + layers, // deUint32 layers; + }; + + return createFramebuffer(vk, device, &framebufferInfo); +} + +Move makeVerifyPipelineLayout (const DeviceInterface& vk, + const VkDevice device, + const VkDescriptorSetLayout descriptorSetLayout) +{ + const VkPushConstantRange pushConstantRanges = + { + VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; + 0u, // deUint32 offset; + sizeof(deUint32) // deUint32 size; + }; + const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = + { + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags; + 1u, // deUint32 setLayoutCount; + &descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; + 1u, // deUint32 pushConstantRangeCount; + &pushConstantRanges, // const VkPushConstantRange* pPushConstantRanges; + }; + return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo); +} + +Move makeVerifyRenderPass (const DeviceInterface& vk, + const VkDevice device, + const VkFormat colorFormat) +{ + return makeRenderPass(vk, device, colorFormat); +} + +VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask, + const VkAccessFlags dstAccessMask, + const VkImageLayout oldLayout, + const VkImageLayout newLayout, + const VkImage image, + const VkImageSubresourceRange subresourceRange) +{ + const VkImageMemoryBarrier barrier = + { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; + DE_NULL, // const void* pNext; + srcAccessMask, // VkAccessFlags outputMask; + dstAccessMask, // VkAccessFlags inputMask; + oldLayout, // VkImageLayout oldLayout; + newLayout, // VkImageLayout newLayout; + VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; + VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; + image, // VkImage image; + subresourceRange, // VkImageSubresourceRange subresourceRange; + }; + return barrier; +} + +VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags srcAccessMask, + const VkAccessFlags dstAccessMask, + const VkBuffer buffer, + const VkDeviceSize offset, + const VkDeviceSize bufferSizeBytes) +{ + const VkBufferMemoryBarrier barrier = + { + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; + DE_NULL, // const void* pNext; + srcAccessMask, // VkAccessFlags srcAccessMask; + dstAccessMask, // VkAccessFlags dstAccessMask; + VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; + VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; + buffer, // VkBuffer buffer; + offset, // VkDeviceSize offset; + bufferSizeBytes, // VkDeviceSize size; + }; + return barrier; +} + +VkBufferImageCopy makeBufferImageCopy (const VkExtent3D extent, + const VkImageSubresourceLayers subresourceLayers) +{ + const VkBufferImageCopy copyParams = + { + 0ull, // VkDeviceSize bufferOffset; + 0u, // deUint32 bufferRowLength; + 0u, // deUint32 bufferImageHeight; + subresourceLayers, // VkImageSubresourceLayers imageSubresource; + makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; + extent, // VkExtent3D imageExtent; + }; + return copyParams; +} + +inline Move makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkBufferCreateInfo& createInfo) +{ + return createBuffer(vk, device, &createInfo); +} + +inline Move makeImage (const DeviceInterface& vk, const VkDevice device, const VkImageCreateInfo& createInfo) +{ + return createImage(vk, device, &createInfo); +} + +MovePtr bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement) +{ + MovePtr alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement); + VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset())); + return alloc; +} + +MovePtr bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement) +{ + MovePtr alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement)); + VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset())); + return alloc; +} + +Move makeSampler (const DeviceInterface& vk, const VkDevice& device) +{ + const VkSamplerCreateInfo createInfo = + { + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkSamplerCreateFlags flags; + VK_FILTER_NEAREST, // VkFilter magFilter; + VK_FILTER_NEAREST, // VkFilter minFilter; + VK_SAMPLER_MIPMAP_MODE_LINEAR, // VkSamplerMipmapMode mipmapMode; + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU; + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV; + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW; + 0.0f, // float mipLodBias; + VK_FALSE, // VkBool32 anisotropyEnable; + 1.0f, // float maxAnisotropy; + VK_FALSE, // VkBool32 compareEnable; + VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp; + 0.0f, // float minLod; + 0.0f, // float maxLod; + VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor; + VK_FALSE // VkBool32 unnormalizedCoordinates; + }; + + return createSampler(vk, device, &createInfo); +} + +void fillBuffer (const DeviceInterface& vk, const VkDevice device, Allocation& bufferAlloc, const void* data, const VkDeviceSize dataSize) +{ + const VkMappedMemoryRange memRange = + { + VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType; + DE_NULL, // const void* pNext; + bufferAlloc.getMemory(), // VkDeviceMemory memory; + bufferAlloc.getOffset(), // VkDeviceSize offset; + VK_WHOLE_SIZE // VkDeviceSize size; + }; + const deUint32 dataSize32 = static_cast(dataSize); + + deMemcpy(bufferAlloc.getHostPtr(), data, dataSize32); + VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &memRange)); +} + +std::vector getFullQuadVertices (void) +{ + const float verticesData[] = + { + -1.0f, -1.0f, 0.0f, 1.0f, + -1.0f, +1.0f, 0.0f, 1.0f, + +1.0f, -1.0f, 0.0f, 1.0f, + -1.0f, +1.0f, 0.0f, 1.0f, + +1.0f, -1.0f, 0.0f, 1.0f, + +1.0f, +1.0f, 0.0f, 1.0f, + }; + const std::vector vertices (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData)); + + return vertices; +} + +void checkImageFormatProperties (const InstanceInterface& vki, + const VkPhysicalDevice& physDevice, + const VkFormat format, + const VkImageUsageFlags imageUsageFlags, + const VkExtent2D& requiredSize2D) +{ + const VkImageType imageType = VK_IMAGE_TYPE_2D; + const VkImageTiling imageTiling = VK_IMAGE_TILING_OPTIMAL; + const VkImageCreateFlags imageCreateFlags = static_cast(0u); + const deUint32 requiredLayers = 1u; + const VkExtent3D requiredSize = makeExtent3D(requiredSize2D.height, requiredSize2D.width, 1u); + + VkImageFormatProperties imageFormatProperties; + VkResult result; + + deMemset(&imageFormatProperties, 0, sizeof(imageFormatProperties)); + + result = vki.getPhysicalDeviceImageFormatProperties(physDevice, format, imageType, imageTiling, imageUsageFlags, imageCreateFlags, &imageFormatProperties); + + if (result != VK_SUCCESS || + imageFormatProperties.maxArrayLayers < requiredLayers || + imageFormatProperties.maxExtent.height < requiredSize.height || + imageFormatProperties.maxExtent.width < requiredSize.width || + imageFormatProperties.maxExtent.depth < requiredSize.depth) + { + TCU_THROW(NotSupportedError, "Depth/stencil format is not supported"); + } +} + +VkFormat getStencilBufferFormat(VkFormat depthStencilImageFormat) +{ + const tcu::TextureFormat tcuFormat = mapVkFormat(depthStencilImageFormat); + const VkFormat result = (tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS) ? VK_FORMAT_S8_UINT : VK_FORMAT_UNDEFINED; + + DE_ASSERT(result != VK_FORMAT_UNDEFINED); + + return result; +} + +static MovePtr convertDepthToColor (const tcu::TextureFormat& dataFormat, const int width, const int height, const void* data, const tcu::TextureFormat& targetFormat) +{ + const tcu::ConstPixelBufferAccess srcImage (dataFormat, width, height, 1u, data); + MovePtr dstImage (new tcu::TextureLevel(targetFormat, width, height, 1u)); + tcu::PixelBufferAccess dstAccess (dstImage->getAccess()); + + for (int y = 0; y < height; y++) + for (int x = 0; x < width; x++) + { + const float depth = srcImage.getPixDepth(x, y); + const tcu::Vec4 color = tcu::Vec4(depth, depth, depth, 1.0f); + + dstAccess.setPixel(color, x, y); + } + + return dstImage; +} + +static MovePtr convertStencilToColor (const tcu::TextureFormat& dataFormat, const int width, const int height, const void* data, const tcu::TextureFormat& targetFormat) +{ + const int maxValue (4); + const tcu::ConstPixelBufferAccess srcImage (dataFormat, width, height, 1u, data); + MovePtr dstImage (new tcu::TextureLevel(targetFormat, width, height, 1u)); + tcu::PixelBufferAccess dstAccess (dstImage->getAccess()); + + for (int y = 0; y < height; y++) + for (int x = 0; x < width; x++) + { + const int stencilInt = srcImage.getPixStencil(x, y); + const float stencil = (stencilInt < maxValue) ? float(stencilInt) / float(maxValue) : 1.0f; + const tcu::Vec4 color = tcu::Vec4(stencil, stencil, stencil, 1.0f); + + dstAccess.setPixel(color, x, y); + } + + return dstImage; +} + +class ColorImagelessTestInstance : public TestInstance +{ +public: + ColorImagelessTestInstance (Context& context, const TestParameters& parameters); +protected: + virtual tcu::TestStatus iterate (void); + + virtual std::vector getVertices (void); + void readOneSampleFromMultisampleImage (const VkFormat srcFormat, + const Unique& srcImage, + const deUint32 sampleID, + const VkFormat dstFormat, + const Unique& dstImage, + const Unique& dstBuffer, + const AspectFlags aspect); + virtual MovePtr generateReferenceImage (const tcu::TextureFormat& textureFormat, + const AspectFlags aspectFlags, + const deUint32 sample, + const deUint32 subpass); + virtual bool verifyBuffer (const UniquePtr& bufAlloc, + const VkFormat bufferFormat, + const std::string& name, + const AspectFlags aspectFlags, + const deUint32 sample = NO_SAMPLE, + const deUint32 subpass = NO_SUBPASS); + virtual bool verifyBufferInternal (const void* resultData, + const tcu::TextureFormat& textureFormat, + const tcu::TextureLevel& referenceImage, + const std::string& name); + + const bool m_extensions; + const VkExtent2D m_imageExtent2D; + const TestParameters m_parameters; + VkImageUsageFlags m_colorImageUsage; +}; + +ColorImagelessTestInstance::ColorImagelessTestInstance (Context& context, const TestParameters& parameters) + : TestInstance (context) + , m_extensions (context.requireDeviceExtension("VK_KHR_imageless_framebuffer")) + , m_imageExtent2D (makeExtent2D(32u, 32u)) + , m_parameters (parameters) + , m_colorImageUsage (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT) +{ + const InstanceInterface& vki = m_context.getInstanceInterface(); + const VkPhysicalDevice physDevice = m_context.getPhysicalDevice(); + const VkPhysicalDeviceImagelessFramebufferFeaturesKHR& imagelessFramebufferFeatures (context.getImagelessFramebufferFeatures()); + + if (imagelessFramebufferFeatures.imagelessFramebuffer == DE_FALSE) + TCU_THROW(NotSupportedError, "Imageless framebuffer is not supported"); + + checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D); +} + +void ColorImagelessTestInstance::readOneSampleFromMultisampleImage (const VkFormat srcFormat, + const Unique& srcImage, + const deUint32 sampleID, + const VkFormat dstFormat, + const Unique& dstImage, + const Unique& dstBuffer, + const AspectFlags aspect) +{ + const DeviceInterface& vk = m_context.getDeviceInterface(); + const VkDevice device = m_context.getDevice(); + const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); + const VkQueue queue = m_context.getUniversalQueue(); + Allocator& allocator = m_context.getDefaultAllocator(); + + const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); + const bool color = ((aspect & ASPECT_COLOR) != 0); + const bool depth = ((aspect & ASPECT_DEPTH) != 0); + const bool stencil = ((aspect & ASPECT_STENCIL) != 0); + const VkImageAspectFlags srcAspect = color ? VK_IMAGE_ASPECT_COLOR_BIT + : depth ? VK_IMAGE_ASPECT_DEPTH_BIT + : VK_IMAGE_ASPECT_STENCIL_BIT; + const VkImageSubresourceRange srcSubresRange = makeImageSubresourceRange(srcAspect, 0u, 1u, 0u, 1u); + const Unique srcImageView (makeImageView (vk, device, *srcImage, VK_IMAGE_VIEW_TYPE_2D, srcFormat, srcSubresRange)); + + const VkImageAspectFlags dstAspect = VK_IMAGE_ASPECT_COLOR_BIT; + const VkImageSubresourceRange dstSubresRange = makeImageSubresourceRange(dstAspect, 0u, 1u, 0u, 1u); + const Unique dstAttachment (makeImageView (vk, device, *dstImage, VK_IMAGE_VIEW_TYPE_2D, dstFormat, dstSubresRange)); + + const std::string fragModuleInfix = color ? "-color" + : depth ? "-depth" + : stencil ? "-stencil" + : ""; + const Unique vertModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("demultisample-vert"), 0u)); + const Unique fragModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("demultisample" + fragModuleInfix + "-frag"), 0u)); + const Unique renderPass (makeVerifyRenderPass (vk, device, dstFormat)); + const Unique framebuffer (makeVerifyFramebuffer (vk, device, *renderPass, *dstAttachment, m_imageExtent2D)); + + const VkDescriptorType samplerDescType (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); + const Unique sampler (makeSampler(vk, device)); + const Unique descriptorSetLayout (DescriptorSetLayoutBuilder() + .addSingleSamplerBinding(samplerDescType, VK_SHADER_STAGE_FRAGMENT_BIT, &sampler.get()) + .build(vk, device)); + const Unique descriptorPool (DescriptorPoolBuilder() + .addType(samplerDescType) + .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); + const Unique descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); + const VkDescriptorImageInfo imageDescriptorInfo (makeDescriptorImageInfo(DE_NULL, *srcImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)); + + DescriptorSetUpdateBuilder() + .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), samplerDescType, &imageDescriptorInfo) + .update(vk, device); + + const Unique pipelineLayout (makeVerifyPipelineLayout (vk, device, *descriptorSetLayout)); + const Unique pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D)); + const Unique cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); + const Unique cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); + + const std::vector vertexArray (getFullQuadVertices()); + const deUint32 vertexCount (static_cast(vertexArray.size() / 4u)); + const VkDeviceSize vertexArraySize (vertexArray.size() * sizeof(vertexArray[0])); + const Unique vertexBuffer (makeBuffer (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))); + const UniquePtr vertexBufferAlloc (bindBuffer (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible)); + const VkDeviceSize vertexBufferOffset (0u); + + fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize); + + beginCommandBuffer(vk, *cmdBuffer); + { + if (sampleID == 0) + { + if (color) + { + const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + *srcImage, srcSubresRange); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier); + } + else if (depth) + { + const VkImageSubresourceRange preCopySubresRange = makeImageSubresourceRange (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u); + const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + *srcImage, preCopySubresRange); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier); + } + } + + beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor); + { + vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); + + vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); + + vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset); + + vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(sampleID), &sampleID); + + vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u); + } + endRenderPass(vk, *cmdBuffer); + + // Image copy + { + const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + *dstImage, dstSubresRange); + const VkBufferImageCopy region = makeBufferImageCopy (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u), + makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u)); + const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *dstBuffer, 0ull, VK_WHOLE_SIZE); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier); + vk.cmdCopyImageToBuffer(*cmdBuffer, *dstImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dstBuffer, 1u, ®ion); + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u); + } + } + endCommandBuffer(vk, *cmdBuffer); + submitCommandsAndWait(vk, device, queue, *cmdBuffer); +} + +bool ColorImagelessTestInstance::verifyBufferInternal (const void* resultData, const tcu::TextureFormat& textureFormat, const tcu::TextureLevel& referenceImage, const std::string& name) +{ + const int dataSize (m_imageExtent2D.width * m_imageExtent2D.height * textureFormat.getPixelSize()); + const tcu::ConstPixelBufferAccess referenceAccess (referenceImage.getAccess()); + + if (deMemCmp(resultData, referenceAccess.getDataPtr(), dataSize) != 0) + { + const tcu::ConstPixelBufferAccess resultImage (textureFormat, m_imageExtent2D.width, m_imageExtent2D.height, 1u, resultData); + bool ok; + + ok = tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), "", referenceAccess, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT); + + return ok; + } + + return true; +} + +bool ColorImagelessTestInstance::verifyBuffer (const UniquePtr& bufAlloc, const VkFormat bufferFormat, const std::string& name, const AspectFlags aspectFlags, const deUint32 sample, const deUint32 subpass) +{ + invalidateMappedMemoryRange(m_context.getDeviceInterface(), m_context.getDevice(), bufAlloc->getMemory(), bufAlloc->getOffset(), VK_WHOLE_SIZE); + + const tcu::TextureFormat bufferTextureFormat (mapVkFormat(bufferFormat)); + const bool multisampled (sample != NO_SAMPLE); + const bool depth ((aspectFlags & ASPECT_DEPTH) != 0); + const bool stencil ((aspectFlags & ASPECT_STENCIL) != 0); + const bool convertRequired ((depth || stencil) && !multisampled); + const tcu::TextureFormat convertTextureFormat (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNORM_INT8)); + const tcu::TextureFormat referenceTextureFormat (convertRequired ? convertTextureFormat : bufferTextureFormat); + const MovePtr referenceImage (generateReferenceImage(referenceTextureFormat, aspectFlags, sample, subpass)); + + if (!multisampled && depth) + { + MovePtr convertedImage (convertDepthToColor(bufferTextureFormat, m_imageExtent2D.width, m_imageExtent2D.height, bufAlloc->getHostPtr(), convertTextureFormat)); + tcu::ConstPixelBufferAccess convertedAccess (convertedImage->getAccess()); + + return verifyBufferInternal(convertedAccess.getDataPtr(), convertTextureFormat, *referenceImage, name); + } + else if (!multisampled && stencil) + { + MovePtr convertedImage (convertStencilToColor(bufferTextureFormat, m_imageExtent2D.width, m_imageExtent2D.height, bufAlloc->getHostPtr(), convertTextureFormat)); + tcu::ConstPixelBufferAccess convertedAccess (convertedImage->getAccess()); + + return verifyBufferInternal(convertedAccess.getDataPtr(), convertTextureFormat, *referenceImage, name); + } + else + { + const void* resultData (bufAlloc->getHostPtr()); + + return verifyBufferInternal(resultData, bufferTextureFormat, *referenceImage, name); + } +} + +MovePtr ColorImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat& textureFormat, + const AspectFlags aspectFlags, + const deUint32 sample, + const deUint32 subpass) +{ + const int width = m_imageExtent2D.width; + const int height = m_imageExtent2D.height; + const int componentValue (static_cast(0.75f * 0x100)); + const tcu::RGBA colorDrawRGBA (tcu::RGBA(componentValue, componentValue, componentValue, 0xFF)); + const tcu::Vec4 colorDraw (colorDrawRGBA.toVec()); + const tcu::Vec4 colorFill (tcu::RGBA::black().toVec()); + MovePtr image (new tcu::TextureLevel(textureFormat, width, height)); + tcu::PixelBufferAccess access (image->getAccess()); + + DE_UNREF(aspectFlags); + DE_ASSERT(aspectFlags == ASPECT_COLOR); + DE_UNREF(sample); + DE_ASSERT(sample == NO_SAMPLE); + DE_UNREF(subpass); + DE_ASSERT(subpass == NO_SUBPASS); + + for (int y = 0; y < height; ++y) + { + const tcu::Vec4& validColor = (y < height / 2) ? colorFill : colorDraw; + + for (int x = 0; x < width; ++x) + access.setPixel(validColor, x, y); + } + + return image; +} + +std::vector ColorImagelessTestInstance::getVertices (void) +{ + const float verticesData[] = + { + -1.0f, 0.0f, 0.0f, 1.0f, + -1.0f, +1.0f, 0.0f, 1.0f, + +1.0f, 0.0f, 0.0f, 1.0f, + -1.0f, +1.0f, 0.0f, 1.0f, + +1.0f, 0.0f, 0.0f, 1.0f, + +1.0f, +1.0f, 0.0f, 1.0f, + }; + const std::vector vertices (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData)); + + return vertices; +} + +tcu::TestStatus ColorImagelessTestInstance::iterate (void) +{ + const DeviceInterface& vk = m_context.getDeviceInterface(); + const VkDevice device = m_context.getDevice(); + const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); + const VkQueue queue = m_context.getUniversalQueue(); + Allocator& allocator = m_context.getDefaultAllocator(); + + const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); + const VkFormat colorFormat = m_parameters.colorFormat; + const VkDeviceSize colorBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat)); + const VkImageSubresourceRange colorSubresRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); + + const Unique colorImage (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage))); + const UniquePtr colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any)); + const Unique colorAttachment (makeImageView (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange)); + const Unique colorBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT))); + const UniquePtr colorBufferAlloc (bindBuffer (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible)); + + const Unique vertModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u)); + const Unique fragModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("frag"), 0u)); + const Unique renderPass (makeRenderPass (vk, device, colorFormat, m_parameters.dsFormat)); + const Unique framebuffer (makeFramebuffer (vk, device, *renderPass, m_imageExtent2D, colorFormat, m_colorImageUsage, m_parameters.dsFormat)); + const Unique pipelineLayout (makePipelineLayout (vk, device)); + const Unique pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D)); + const Unique cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); + const Unique cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); + + const std::vector vertexArray (getVertices()); + const deUint32 vertexCount (static_cast(vertexArray.size() / 4u)); + const VkDeviceSize vertexArraySize (vertexArray.size() * sizeof(vertexArray[0])); + const Unique vertexBuffer (makeBuffer (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))); + const UniquePtr vertexBufferAlloc (bindBuffer (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible)); + const VkDeviceSize vertexBufferOffset (0u); + + fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize); + + beginCommandBuffer(vk, *cmdBuffer); + { + const VkRenderPassAttachmentBeginInfoKHR renderPassAttachmentBeginInfo = + { + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + 1u, // deUint32 attachmentCount; + &*colorAttachment // const VkImageView* pAttachments; + }; + + beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, &renderPassAttachmentBeginInfo); + { + vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); + + vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset); + + vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u); + } + endRenderPass(vk, *cmdBuffer); + + // Color image copy + { + const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + *colorImage, colorSubresRange); + const VkBufferImageCopy region = makeBufferImageCopy (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u), + makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u)); + const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier); + vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ®ion); + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u); + } + } + endCommandBuffer(vk, *cmdBuffer); + submitCommandsAndWait(vk, device, queue, *cmdBuffer); + + if (verifyBuffer(colorBufferAlloc, colorFormat, "Color", ASPECT_COLOR)) + return tcu::TestStatus::pass("Pass"); + else + return tcu::TestStatus::fail("Fail"); +} + +class DepthImagelessTestInstance : public ColorImagelessTestInstance +{ +public: + DepthImagelessTestInstance (Context& context, const TestParameters& parameters); + +protected: + virtual tcu::TestStatus iterate (void); + + virtual std::vector getVertices (void); + + virtual MovePtr generateReferenceImage (const tcu::TextureFormat& textureFormat, + const AspectFlags aspectFlags, + const deUint32 sample, + const deUint32 subpass); + + VkImageUsageFlags m_dsImageUsage; +}; + +DepthImagelessTestInstance::DepthImagelessTestInstance (Context& context, const TestParameters& parameters) + : ColorImagelessTestInstance (context, parameters) + , m_dsImageUsage (VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT) +{ + const InstanceInterface& vki = m_context.getInstanceInterface(); + const VkPhysicalDevice physDevice = m_context.getPhysicalDevice(); + + checkImageFormatProperties(vki, physDevice, m_parameters.dsFormat, m_dsImageUsage, m_imageExtent2D); +} + +MovePtr DepthImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat& textureFormat, + const AspectFlags aspectFlags, + const deUint32 sample, + const deUint32 subpass) +{ + const bool color = ((aspectFlags & ASPECT_COLOR) != 0); + const bool depth = ((aspectFlags & ASPECT_DEPTH) != 0); + const bool stencil = ((aspectFlags & ASPECT_STENCIL) != 0); + const int width = m_imageExtent2D.width; + const int height = m_imageExtent2D.height; + MovePtr image (new tcu::TextureLevel(textureFormat, width, height)); + tcu::PixelBufferAccess access (image->getAccess()); + + DE_ASSERT(dePop32(aspectFlags) == 1); + DE_UNREF(sample); + DE_ASSERT(sample == NO_SAMPLE); + DE_UNREF(subpass); + DE_ASSERT(subpass == NO_SUBPASS); + + if (color) + { + const int componentValue (static_cast(0.75f * 0x100)); + const tcu::RGBA colorDrawRGBA (tcu::RGBA(componentValue, componentValue, componentValue, 0xFF)); + const tcu::Vec4 colorDraw (colorDrawRGBA.toVec()); + const tcu::Vec4 colorDrawTop (tcu::RGBA::white().toVec()); + const tcu::Vec4 colorFill (tcu::RGBA::black().toVec()); + + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) + { + const tcu::Vec4& validColor = (y < height / 2) ? colorFill + : (x < width / 2) ? colorDraw + : colorDrawTop; + + access.setPixel(validColor, x, y); + } + } + + if (depth) + { + const int colorFillValue (static_cast(1.00f * 0x100)); + const int colorDrawValue (static_cast(0.50f * 0x100)); + const int colorTopValue (static_cast(0.25f * 0x100)); + const tcu::IVec4 colorFill (colorFillValue, 0, 0, 0xFF); + const tcu::IVec4 colorDraw (colorDrawValue, 0, 0, 0xFF); + const tcu::IVec4 colorTop (colorTopValue, 0, 0, 0xFF); + + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) + { + const tcu::IVec4& validColor = (y < height / 2) ? colorFill + : (x < width / 2) ? colorDraw + : colorTop; + + access.setPixel(validColor, x, y); + } + } + + if (stencil) + { + const int colorFillValue (static_cast(0.00f * 0x100)); + const int colorDrawValue (static_cast(0.25f * 0x100)); + const int colorTopValue (static_cast(0.50f * 0x100)); + const tcu::IVec4 colorFill (colorFillValue, 0, 0, 0xFF); + const tcu::IVec4 colorDraw (colorDrawValue, 0, 0, 0xFF); + const tcu::IVec4 colorTop (colorTopValue, 0, 0, 0xFF); + + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) + { + const tcu::IVec4& validColor = (y < height / 2) ? colorFill + : (x < width / 2) ? colorDraw + : colorTop; + + access.setPixel(validColor, x, y); + } + } + + return image; +} + +std::vector DepthImagelessTestInstance::getVertices (void) +{ + const float verticesData[] = + { + -1.0f, 0.0f, 0.50f, 1.0f, + -1.0f, +1.0f, 0.50f, 1.0f, + +1.0f, 0.0f, 0.50f, 1.0f, + -1.0f, +1.0f, 0.50f, 1.0f, + +1.0f, 0.0f, 0.50f, 1.0f, + +1.0f, +1.0f, 0.50f, 1.0f, + + 0.0f, 0.0f, 0.25f, 1.0f, + 0.0f, +1.0f, 0.25f, 1.0f, + +1.0f, 0.0f, 0.25f, 1.0f, + 0.0f, +1.0f, 0.25f, 1.0f, + +1.0f, 0.0f, 0.25f, 1.0f, + +1.0f, +1.0f, 0.25f, 1.0f, + }; + const std::vector vertices (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData)); + + return vertices; +} + +tcu::TestStatus DepthImagelessTestInstance::iterate (void) +{ + const DeviceInterface& vk = m_context.getDeviceInterface(); + const VkDevice device = m_context.getDevice(); + const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); + const VkQueue queue = m_context.getUniversalQueue(); + Allocator& allocator = m_context.getDefaultAllocator(); + + const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); + const VkFormat colorFormat = m_parameters.colorFormat; + const VkDeviceSize colorBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat)); + const VkImageSubresourceRange colorSubresRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); + + const Unique colorImage (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage))); + const UniquePtr colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any)); + const Unique colorAttachment (makeImageView (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange)); + const Unique colorBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT))); + const UniquePtr colorBufferAlloc (bindBuffer (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible)); + + const float clearDepth = 1.0f; + const deUint32 clearStencil = 0u; + const VkFormat dsFormat = m_parameters.dsFormat; + const deUint32 dsImagePixelSize = static_cast(tcu::getPixelSize(mapVkFormat(dsFormat))); + const VkImageAspectFlags dsAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + const VkImageSubresourceRange dsSubresRange = makeImageSubresourceRange(dsAspectFlags, 0u, 1u, 0u, 1u); + + const VkDeviceSize depthBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * dsImagePixelSize; + const VkFormat stencilBufferFormat = getStencilBufferFormat(dsFormat); + const deUint32 stencilPixelSize = static_cast(tcu::getPixelSize(mapVkFormat(stencilBufferFormat))); + const VkDeviceSize stencilBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * stencilPixelSize; + + const Unique dsImage (makeImage (vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage))); + const UniquePtr dsImageAlloc (bindImage (vk, device, allocator, *dsImage, MemoryRequirement::Any)); + const Unique dsAttachment (makeImageView (vk, device, *dsImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange)); + const Unique depthBuffer (makeBuffer (vk, device, makeBufferCreateInfo(depthBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT))); + const UniquePtr depthBufferAlloc (bindBuffer (vk, device, allocator, *depthBuffer, MemoryRequirement::HostVisible)); + const Unique stencilBuffer (makeBuffer (vk, device, makeBufferCreateInfo(stencilBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT))); + const UniquePtr stencilBufferAlloc (bindBuffer (vk, device, allocator, *stencilBuffer, MemoryRequirement::HostVisible)); + + const Unique vertModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u)); + const Unique fragModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("frag"), 0u)); + const Unique renderPass (makeRenderPass (vk, device, colorFormat, dsFormat)); + const Unique framebuffer (makeFramebuffer (vk, device, *renderPass, m_imageExtent2D, colorFormat, m_colorImageUsage, dsFormat, m_dsImageUsage)); + const Unique pipelineLayout (makePipelineLayout (vk, device)); + const Unique pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D, ASPECT_DEPTH_STENCIL)); + const Unique cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); + const Unique cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); + + const std::vector vertexArray (getVertices()); + const deUint32 vertexCount (static_cast(vertexArray.size() / 4u)); + const VkDeviceSize vertexArraySize (vertexArray.size() * sizeof(vertexArray[0])); + const Unique vertexBuffer (makeBuffer (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))); + const UniquePtr vertexBufferAlloc (bindBuffer (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible)); + const VkDeviceSize vertexBufferOffset (0u); + + fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize); + + beginCommandBuffer(vk, *cmdBuffer); + { + const VkImageView attachments[] = { *colorAttachment, *dsAttachment }; + const VkRenderPassAttachmentBeginInfoKHR renderPassAttachmentBeginInfo = + { + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + DE_LENGTH_OF_ARRAY(attachments), // deUint32 attachmentCount; + attachments // const VkImageView* pAttachments; + }; + + beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, clearDepth, clearStencil, &renderPassAttachmentBeginInfo); + { + vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); + + vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset); + + vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u); + } + endRenderPass(vk, *cmdBuffer); + + // Color image copy + { + const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + *colorImage, colorSubresRange); + const VkBufferImageCopy region = makeBufferImageCopy (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u), + makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u)); + const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier); + vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ®ion); + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u); + } + + // Depth/Stencil image copy + { + const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dsImage, dsSubresRange); + const VkBufferImageCopy depthCopyRegion = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u), + makeImageSubresourceLayers(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u)); + const VkBufferImageCopy stencilCopyRegion = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u), + makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u)); + const VkBufferMemoryBarrier postCopyBarriers[] = + { + makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *depthBuffer, 0ull, VK_WHOLE_SIZE), + makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *stencilBuffer, 0ull, VK_WHOLE_SIZE), + }; + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier); + vk.cmdCopyImageToBuffer(*cmdBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *depthBuffer, 1u, &depthCopyRegion); + vk.cmdCopyImageToBuffer(*cmdBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *stencilBuffer, 1u, &stencilCopyRegion); + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBarriers), postCopyBarriers, DE_NULL, 0u); + } + } + endCommandBuffer(vk, *cmdBuffer); + submitCommandsAndWait(vk, device, queue, *cmdBuffer); + + { + std::string result; + + if (!verifyBuffer(colorBufferAlloc, colorFormat, "Color", ASPECT_COLOR)) + result += " Color"; + + if (!verifyBuffer(depthBufferAlloc, dsFormat, "Depth", ASPECT_DEPTH)) + result += " Depth"; + + if (!verifyBuffer(stencilBufferAlloc, stencilBufferFormat, "Stencil", ASPECT_STENCIL)) + result += " Stencil"; + + if (result.empty()) + return tcu::TestStatus::pass("Pass"); + else + return tcu::TestStatus::fail("Following parts of image are incorrect:" + result); + } +} + +class ColorResolveImagelessTestInstance : public ColorImagelessTestInstance +{ +public: + ColorResolveImagelessTestInstance (Context& context, const TestParameters& parameters); +protected: + virtual tcu::TestStatus iterate (void); + + virtual MovePtr generateReferenceImage (const tcu::TextureFormat& textureFormat, + const AspectFlags aspectFlags, + const deUint32 sample, + const deUint32 subpass); + + virtual std::vector getVertices (void); +}; + +ColorResolveImagelessTestInstance::ColorResolveImagelessTestInstance (Context& context, const TestParameters& parameters) + : ColorImagelessTestInstance (context, parameters) +{ + const InstanceInterface& vki = m_context.getInstanceInterface(); + const VkPhysicalDevice physDevice = m_context.getPhysicalDevice(); + + // To validate per-sample image image must also be sampled + m_colorImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT; + + checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D); +} + +MovePtr ColorResolveImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat& textureFormat, + const AspectFlags aspectFlags, + const deUint32 sample, + const deUint32 subpass) +{ + const int width = m_imageExtent2D.width; + const int height = m_imageExtent2D.height; + MovePtr image (new tcu::TextureLevel(textureFormat, width, height)); + tcu::PixelBufferAccess access (image->getAccess()); + const int componentValue (static_cast(0.75f * 0x100)); + const tcu::RGBA colorDrawRGBA (tcu::RGBA(componentValue, componentValue, componentValue, 0xFF)); + const tcu::Vec4 colorDraw (colorDrawRGBA.toVec()); + const tcu::Vec4 colorFill (tcu::RGBA::black().toVec()); + const tcu::Vec4 colorEdge0 (colorFill); + const tcu::Vec4 colorEdge1 (colorDraw); + const tcu::Vec4 colorEdgeR ((colorDraw.x() + colorFill.x()) / 2, (colorDraw.y() + colorFill.y()) / 2, (colorDraw.z() + colorFill.z()) / 2, colorDraw.w()); + const tcu::Vec4& colorEdge = sample == 0 ? colorEdge0 + : sample == 1 ? colorEdge1 + : colorEdgeR; + + DE_UNREF(aspectFlags); + DE_ASSERT(dePop32(aspectFlags) == 1); + DE_ASSERT(aspectFlags == ASPECT_COLOR); + DE_UNREF(subpass); + DE_ASSERT(subpass == NO_SUBPASS); + + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) + { + const int mx = width - 1 - x; + const tcu::Vec4& validColor = (y == mx) ? colorEdge + : (y > mx) ? colorFill + : colorDraw; + + access.setPixel(validColor, x, y); + } + + return image; +} + +std::vector ColorResolveImagelessTestInstance::getVertices (void) +{ + const float verticesData[] = + { + -1.0f, -1.0f, 0.0f, 1.0f, + -1.0f, +1.0f, 0.0f, 1.0f, + +1.0f, -1.0f, 0.0f, 1.0f, + }; + const std::vector vertices (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData)); + + return vertices; +} + +tcu::TestStatus ColorResolveImagelessTestInstance::iterate (void) +{ + const DeviceInterface& vk = m_context.getDeviceInterface(); + const VkDevice device = m_context.getDevice(); + const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); + const VkQueue queue = m_context.getUniversalQueue(); + Allocator& allocator = m_context.getDefaultAllocator(); + + const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_2_BIT; + const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); + const VkFormat colorFormat = m_parameters.colorFormat; + const VkDeviceSize colorBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat)); + const VkImageSubresourceRange colorSubresRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); + + const Unique colorImage (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage, sampleCount))); + const UniquePtr colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any)); + const Unique colorAttachment (makeImageView (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange)); + + const Unique colorResolveImage (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage))); + const UniquePtr colorResolveImageAlloc (bindImage (vk, device, allocator, *colorResolveImage, MemoryRequirement::Any)); + const Unique colorResolveAttachment (makeImageView (vk, device, *colorResolveImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange)); + const Unique colorResolveBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT))); + const UniquePtr colorResolveBufferAlloc (bindBuffer (vk, device, allocator, *colorResolveBuffer, MemoryRequirement::HostVisible)); + + const Unique vertModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u)); + const Unique fragModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("frag"), 0u)); + const Unique renderPass (makeRenderPass (vk, device, colorFormat, m_parameters.dsFormat, sampleCount)); + const Unique framebuffer (makeFramebuffer (vk, device, *renderPass, m_imageExtent2D, colorFormat, m_colorImageUsage, m_parameters.dsFormat, 0u, ASPECT_COLOR)); + const Unique pipelineLayout (makePipelineLayout (vk, device)); + const Unique pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D, ASPECT_NONE, sampleCount)); + const Unique cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); + const Unique cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); + + const std::vector vertexArray (getVertices()); + const deUint32 vertexCount (static_cast(vertexArray.size() / 4u)); + const VkDeviceSize vertexArraySize (vertexArray.size() * sizeof(vertexArray[0])); + const Unique vertexBuffer (makeBuffer (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))); + const UniquePtr vertexBufferAlloc (bindBuffer (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible)); + const VkDeviceSize vertexBufferOffset (0u); + + fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize); + + beginCommandBuffer(vk, *cmdBuffer); + { + const VkImageView attachments[] = { *colorAttachment, *colorResolveAttachment }; + const VkRenderPassAttachmentBeginInfoKHR renderPassAttachmentBeginInfo = + { + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + DE_LENGTH_OF_ARRAY(attachments), // deUint32 attachmentCount; + attachments // const VkImageView* pAttachments; + }; + + beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, &renderPassAttachmentBeginInfo); + { + vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); + + vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset); + + vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u); + } + endRenderPass(vk, *cmdBuffer); + + // Color image copy + { + const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + *colorResolveImage, colorSubresRange); + const VkBufferImageCopy region = makeBufferImageCopy (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u), + makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u)); + const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorResolveBuffer, 0ull, VK_WHOLE_SIZE); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier); + vk.cmdCopyImageToBuffer(*cmdBuffer, *colorResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorResolveBuffer, 1u, ®ion); + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u); + } + } + endCommandBuffer(vk, *cmdBuffer); + submitCommandsAndWait(vk, device, queue, *cmdBuffer); + + { + std::string result; + + if (!verifyBuffer(colorResolveBufferAlloc, colorFormat, "ResolveColor", ASPECT_COLOR)) + result += " ResolveColor"; + + // Parse color aspect of separate samples of multisample image + for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx) + { + const std::string name ("Color" + de::toString(sampleNdx)); + const Unique imageSample (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage))); + const UniquePtr imageSampleAlloc (bindImage (vk, device, allocator, *imageSample, MemoryRequirement::Any)); + const Unique imageBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT))); + const UniquePtr imageBufferAlloc (bindBuffer (vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible)); + + readOneSampleFromMultisampleImage(colorFormat, colorImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_COLOR); + + if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_COLOR, sampleNdx)) + result += " " + name; + } + + + if (result.empty()) + return tcu::TestStatus::pass("Pass"); + else + return tcu::TestStatus::fail("Fail"); + } +} + +class DepthResolveImagelessTestInstance : public DepthImagelessTestInstance +{ +public: + DepthResolveImagelessTestInstance (Context& context, const TestParameters& parameters); + +protected: + virtual tcu::TestStatus iterate (void); + + virtual MovePtr generateReferenceImage (const tcu::TextureFormat& textureFormat, + const AspectFlags aspectFlags, + const deUint32 sample, + const deUint32 subpass); + + virtual std::vector getVertices (void); +}; + +DepthResolveImagelessTestInstance::DepthResolveImagelessTestInstance (Context& context, const TestParameters& parameters) + : DepthImagelessTestInstance (context, parameters) +{ + context.requireDeviceExtension("VK_KHR_depth_stencil_resolve"); + + const InstanceInterface& vki = m_context.getInstanceInterface(); + const VkPhysicalDevice physDevice = m_context.getPhysicalDevice(); + VkPhysicalDeviceProperties2 deviceProperties; + VkPhysicalDeviceDepthStencilResolvePropertiesKHR dsResolveProperties; + + deMemset(&deviceProperties, 0, sizeof(deviceProperties)); + deMemset(&dsResolveProperties, 0, sizeof(dsResolveProperties)); + + deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + deviceProperties.pNext = &dsResolveProperties; + + dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR; + dsResolveProperties.pNext = DE_NULL; + + vki.getPhysicalDeviceProperties2(physDevice, &deviceProperties); + + if ((dsResolveProperties.supportedDepthResolveModes & VK_RESOLVE_MODE_AVERAGE_BIT_KHR) == 0) + TCU_THROW(NotSupportedError, "Depth resolve does not support required VK_RESOLVE_MODE_AVERAGE_BIT_KHR"); + + if ((dsResolveProperties.supportedStencilResolveModes & VK_RESOLVE_MODE_MAX_BIT_KHR) == 0) + TCU_THROW(NotSupportedError, "Stencil resolve does not support required VK_RESOLVE_MODE_MAX_BIT_KHR"); + + m_colorImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT; + + checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D); + + m_dsImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT; + + checkImageFormatProperties(vki, physDevice, m_parameters.dsFormat, m_dsImageUsage, m_imageExtent2D); +} + +MovePtr DepthResolveImagelessTestInstance::generateReferenceImage (const tcu::TextureFormat& textureFormat, + const AspectFlags aspectFlags, + const deUint32 sample, + const deUint32 subpass) +{ + const bool color = ((aspectFlags & ASPECT_COLOR) != 0); + const bool depth = ((aspectFlags & ASPECT_DEPTH) != 0); + const bool stencil = ((aspectFlags & ASPECT_STENCIL) != 0); + const int width = m_imageExtent2D.width; + const int height = m_imageExtent2D.height; + MovePtr image (new tcu::TextureLevel(textureFormat, width, height)); + tcu::PixelBufferAccess access (image->getAccess()); + + DE_ASSERT(dePop32(aspectFlags) == 1); + DE_UNREF(subpass); + + if (color) + { + const tcu::Vec4 colorDraw (tcu::RGBA::blue().toVec()); + const tcu::Vec4 colorFill (tcu::RGBA::black().toVec()); + const tcu::Vec4 colorEdge0 (colorFill); + const tcu::Vec4 colorEdge1 (colorDraw); + const tcu::Vec4 colorEdgeR ((colorDraw.x() + colorFill.x()) / 2, (colorDraw.y() + colorFill.y()) / 2, (colorDraw.z() + colorFill.z()) / 2, colorDraw.w()); + const tcu::Vec4& colorEdge = sample == 0 ? colorEdge0 + : sample == 1 ? colorEdge1 + : colorEdgeR; + + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) + { + const int mx = width - 1 - x; + const tcu::Vec4& validColor = (y == mx) ? colorEdge + : (y > mx) ? colorFill + : colorDraw; + + access.setPixel(validColor, x, y); + } + } + + if (depth) + { + const int colorFillValue (static_cast(1.00f * 0x100)); + const int colorDrawValue (static_cast(0.00f * 0x100)); + const int colorEdgeValue (static_cast(0.50f * 0x100)); + const tcu::IVec4 colorFill (colorFillValue, colorFillValue, colorFillValue, 0xFF); + const tcu::IVec4 colorDraw (colorDrawValue, colorDrawValue, colorDrawValue, 0xFF); + const tcu::IVec4 colorEdge0 (colorFill); + const tcu::IVec4 colorEdge1 (colorDraw); + const tcu::IVec4 colorEdgeR (colorEdgeValue, colorEdgeValue, colorEdgeValue, 0xFF); + const tcu::IVec4& colorEdge = sample == 0 ? colorEdge0 + : sample == 1 ? colorEdge1 + : colorEdgeR; + + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) + { + const int mx = width - 1 - x; + const tcu::IVec4& validColor = (y == mx) ? colorEdge + : (y > mx) ? colorFill + : colorDraw; + + access.setPixel(validColor, x, y); + } + } + + if (stencil) + { + const int colorFillValue ((0 * 0x100) / 4); + const int colorDrawValue ((1 * 0x100) / 4); + const int colorEdgeValue ((1 * 0x100) / 4); + const tcu::IVec4 colorFill (colorFillValue, colorFillValue, colorFillValue, 0xFF); + const tcu::IVec4 colorDraw (colorDrawValue, colorDrawValue, colorDrawValue, 0xFF); + const tcu::IVec4 colorEdge0 (colorFill); + const tcu::IVec4 colorEdge1 (colorDraw); + const tcu::IVec4 colorEdgeR (colorEdgeValue, colorEdgeValue, colorEdgeValue, 0xFF); + const tcu::IVec4& colorEdge = sample == 0 ? colorEdge0 + : sample == 1 ? colorEdge1 + : colorEdgeR; + + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) + { + const int mx = width - 1 - x; + const tcu::IVec4& validColor = (y == mx) ? colorEdge + : (y > mx) ? colorFill + : colorDraw; + + access.setPixel(validColor, x, y); + } + } + + return image; +} + +std::vector DepthResolveImagelessTestInstance::getVertices (void) +{ + const float verticesData[] = + { + -1.0f, -1.0f, 0.0f, 1.0f, + -1.0f, +1.0f, 0.0f, 1.0f, + +1.0f, -1.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 0.5f, 1.0f, + -1.0f, +1.0f, 0.5f, 1.0f, + +1.0f, -1.0f, 0.5f, 1.0f, + }; + const std::vector vertices (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData)); + + return vertices; +} + +tcu::TestStatus DepthResolveImagelessTestInstance::iterate (void) +{ + const DeviceInterface& vk = m_context.getDeviceInterface(); + const VkDevice device = m_context.getDevice(); + const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); + const VkQueue queue = m_context.getUniversalQueue(); + Allocator& allocator = m_context.getDefaultAllocator(); + + const deUint32 sampleCount = 2u; + const VkSampleCountFlagBits sampleCountFlag = sampleCountBitFromSampleCount(sampleCount); + const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); + const VkFormat colorFormat = m_parameters.colorFormat; + const VkDeviceSize colorBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat)); + const VkImageSubresourceRange colorSubresRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); + + const Unique colorImage (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage, sampleCountFlag))); + const UniquePtr colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any)); + const Unique colorAttachment (makeImageView (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange)); + + const Unique colorResolveImage (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage))); + const UniquePtr colorResolveImageAlloc (bindImage (vk, device, allocator, *colorResolveImage, MemoryRequirement::Any)); + const Unique colorResolveAttachment (makeImageView (vk, device, *colorResolveImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange)); + const Unique colorResolveBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT))); + const UniquePtr colorResolveBufferAlloc (bindBuffer (vk, device, allocator, *colorResolveBuffer, MemoryRequirement::HostVisible)); + + const float clearDepth = 1.0f; + const deUint32 clearStencil = 0u; + const VkFormat dsFormat = m_parameters.dsFormat; + const deUint32 dsImagePixelSize = static_cast(tcu::getPixelSize(mapVkFormat(dsFormat))); + const VkImageAspectFlags dsAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + const VkImageSubresourceRange dsSubresRange = makeImageSubresourceRange(dsAspectFlags, 0u, 1u, 0u, 1u); + + const VkDeviceSize depthBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * dsImagePixelSize; + const VkFormat stencilBufferFormat = getStencilBufferFormat(dsFormat); + const deUint32 stencilPixelSize = static_cast(tcu::getPixelSize(mapVkFormat(stencilBufferFormat))); + const VkDeviceSize stencilBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * stencilPixelSize; + + const Unique dsImage (makeImage (vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage, sampleCountFlag))); + const UniquePtr dsImageAlloc (bindImage (vk, device, allocator, *dsImage, MemoryRequirement::Any)); + const Unique dsAttachment (makeImageView (vk, device, *dsImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange)); + + const Unique dsResolveImage (makeImage (vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage))); + const UniquePtr dsResolveImageAlloc (bindImage (vk, device, allocator, *dsResolveImage, MemoryRequirement::Any)); + const Unique dsResolveAttachment (makeImageView (vk, device, *dsResolveImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange)); + const Unique depthResolveBuffer (makeBuffer (vk, device, makeBufferCreateInfo(depthBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT))); + const UniquePtr depthResolveBufferAlloc (bindBuffer (vk, device, allocator, *depthResolveBuffer, MemoryRequirement::HostVisible)); + const Unique stencilResolveBuffer (makeBuffer (vk, device, makeBufferCreateInfo(stencilBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT))); + const UniquePtr stencilResolveBufferAlloc (bindBuffer (vk, device, allocator, *stencilResolveBuffer, MemoryRequirement::HostVisible)); + + const Unique vertModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u)); + const Unique fragModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("frag"), 0u)); + const Unique renderPass (makeRenderPass (vk, device, colorFormat, m_parameters.dsFormat, sampleCountFlag, sampleCountFlag)); + const Unique framebuffer (makeFramebuffer (vk, device, *renderPass, m_imageExtent2D, colorFormat, m_colorImageUsage, m_parameters.dsFormat, m_dsImageUsage, ASPECT_COLOR|ASPECT_DEPTH_STENCIL)); + const Unique pipelineLayout (makePipelineLayout (vk, device)); + const Unique pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D, ASPECT_DEPTH_STENCIL, sampleCountFlag)); + const Unique cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); + const Unique cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); + + const std::vector vertexArray (getVertices()); + const deUint32 vertexCount (static_cast(vertexArray.size() / 4u)); + const VkDeviceSize vertexArraySize (vertexArray.size() * sizeof(vertexArray[0])); + const Unique vertexBuffer (makeBuffer (vk, device, makeBufferCreateInfo(vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))); + const UniquePtr vertexBufferAlloc (bindBuffer (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible)); + const VkDeviceSize vertexBufferOffset (0u); + + fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize); + + beginCommandBuffer(vk, *cmdBuffer); + { + const VkImageView attachments[] = { *colorAttachment, *dsAttachment, *colorResolveAttachment, *dsResolveAttachment }; + const VkRenderPassAttachmentBeginInfoKHR renderPassAttachmentBeginInfo = + { + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + DE_LENGTH_OF_ARRAY(attachments), // deUint32 attachmentCount; + attachments // const VkImageView* pAttachments; + }; + + beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, clearDepth, clearStencil, &renderPassAttachmentBeginInfo); + { + vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); + + vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset); + + vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u); + } + endRenderPass(vk, *cmdBuffer); + + // Color resolve image copy + { + const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + *colorResolveImage, colorSubresRange); + const VkBufferImageCopy region = makeBufferImageCopy (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u), + makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u)); + const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorResolveBuffer, 0ull, VK_WHOLE_SIZE); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier); + vk.cmdCopyImageToBuffer(*cmdBuffer, *colorResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorResolveBuffer, 1u, ®ion); + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u); + } + + // Depth/Stencil resolve image copy + { + const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + *dsResolveImage, dsSubresRange); + const VkBufferImageCopy depthCopyRegion = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u), + makeImageSubresourceLayers(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u)); + const VkBufferImageCopy stencilCopyRegion = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u), + makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u)); + const VkBufferMemoryBarrier postCopyBarriers[] = + { + makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *depthResolveBuffer, 0ull, VK_WHOLE_SIZE), + makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *stencilResolveBuffer, 0ull, VK_WHOLE_SIZE), + }; + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier); + vk.cmdCopyImageToBuffer(*cmdBuffer, *dsResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *depthResolveBuffer, 1u, &depthCopyRegion); + vk.cmdCopyImageToBuffer(*cmdBuffer, *dsResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *stencilResolveBuffer, 1u, &stencilCopyRegion); + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBarriers), postCopyBarriers, DE_NULL, 0u); + } + } + endCommandBuffer(vk, *cmdBuffer); + submitCommandsAndWait(vk, device, queue, *cmdBuffer); + + { + std::string result; + + if (!verifyBuffer(colorResolveBufferAlloc, colorFormat, "ResolveColor", ASPECT_COLOR)) + result += " ResolveColor"; + + if (!verifyBuffer(depthResolveBufferAlloc, dsFormat, "ResolveDepth", ASPECT_DEPTH)) + result += " ResolveDepth"; + + if (!verifyBuffer(stencilResolveBufferAlloc, stencilBufferFormat, "ResolveStencil", ASPECT_STENCIL)) + result += " ResolveStencil"; + + // Parse color aspect of separate samples of multisample image + for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx) + { + const std::string name ("Color" + de::toString(sampleNdx)); + const Unique imageSample (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage))); + const UniquePtr imageSampleAlloc (bindImage (vk, device, allocator, *imageSample, MemoryRequirement::Any)); + const Unique imageBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT))); + const UniquePtr imageBufferAlloc (bindBuffer (vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible)); + + readOneSampleFromMultisampleImage(colorFormat, colorImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_COLOR); + + if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_COLOR, sampleNdx)) + result += " " + name; + } + + // Parse depth aspect of separate samples of multisample image + for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx) + { + const std::string name ("Depth" + de::toString(sampleNdx)); + const Unique imageSample (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage))); + const UniquePtr imageSampleAlloc (bindImage (vk, device, allocator, *imageSample, MemoryRequirement::Any)); + const Unique imageBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT))); + const UniquePtr imageBufferAlloc (bindBuffer (vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible)); + + readOneSampleFromMultisampleImage(dsFormat, dsImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_DEPTH); + + if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_DEPTH, sampleNdx)) + result += " " + name; + } + + // Parse stencil aspect of separate samples of multisample image + for (deUint32 sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx) + { + const std::string name ("Stencil" + de::toString(sampleNdx)); + const Unique imageSample (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage))); + const UniquePtr imageSampleAlloc (bindImage (vk, device, allocator, *imageSample, MemoryRequirement::Any)); + const Unique imageBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT))); + const UniquePtr imageBufferAlloc (bindBuffer (vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible)); + + readOneSampleFromMultisampleImage(dsFormat, dsImage, sampleNdx, colorFormat, imageSample, imageBuffer, ASPECT_STENCIL); + + if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_STENCIL, sampleNdx)) + result += " " + name; + } + + if (result.empty()) + return tcu::TestStatus::pass("Pass"); + else + return tcu::TestStatus::fail("Following parts of image are incorrect:" + result); + } +} + +class MultisubpassTestInstance : public ColorImagelessTestInstance +{ +public: + MultisubpassTestInstance (Context& context, const TestParameters& parameters); + +protected: + virtual tcu::TestStatus iterate (void); + + virtual std::vector getVertices (void); + + virtual MovePtr generateReferenceImage (const tcu::TextureFormat& textureFormat, + const AspectFlags aspectFlags, + const deUint32 sample, + const deUint32 subpass); +}; + +MultisubpassTestInstance::MultisubpassTestInstance (Context& context, const TestParameters& parameters) + : ColorImagelessTestInstance (context, parameters) +{ +} + +std::vector MultisubpassTestInstance::getVertices (void) +{ + const float verticesData[] = + { + -1.0f, 0.0f, 0.0f, 1.0f, + -1.0f, +1.0f, 0.0f, 1.0f, + +1.0f, 0.0f, 0.0f, 1.0f, + -1.0f, +1.0f, 0.0f, 1.0f, + +1.0f, 0.0f, 0.0f, 1.0f, + +1.0f, +1.0f, 0.0f, 1.0f, + }; + const std::vector vertices (verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData)); + + return vertices; +} + +MovePtr MultisubpassTestInstance::generateReferenceImage (const tcu::TextureFormat& textureFormat, + const AspectFlags aspectFlags, + const deUint32 sample, + const deUint32 subpass) +{ + const int width = m_imageExtent2D.width; + const int height = m_imageExtent2D.height; + const tcu::Vec4 colorDraw0 (0.0f, 0.0f, 1.0f, 1.0f); + const tcu::Vec4 colorFill0 (tcu::RGBA::black().toVec()); + const tcu::Vec4 colorDraw1 (colorDraw0.x(), 1.0f, colorDraw0.z(), 1.0f); + const tcu::Vec4 colorFill1 (colorFill0.x(), 1.0f, colorFill0.z(), 1.0f); + const tcu::Vec4& colorDraw ((subpass == 0) ? colorDraw0 : colorDraw1); + const tcu::Vec4& colorFill ((subpass == 0) ? colorFill0 : colorFill1); + MovePtr image (new tcu::TextureLevel(textureFormat, width, height)); + tcu::PixelBufferAccess access (image->getAccess()); + + DE_UNREF(aspectFlags); + DE_ASSERT(aspectFlags == ASPECT_COLOR); + DE_UNREF(sample); + DE_ASSERT(sample == NO_SAMPLE); + DE_ASSERT(subpass != NO_SUBPASS); + + for (int y = 0; y < height; ++y) + { + const tcu::Vec4& validColor = (y < height / 2) ? colorFill : colorDraw; + + for (int x = 0; x < width; ++x) + access.setPixel(validColor, x, y); + } + + return image; +} + +tcu::TestStatus MultisubpassTestInstance::iterate (void) +{ + const DeviceInterface& vk = m_context.getDeviceInterface(); + const VkDevice device = m_context.getDevice(); + const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); + const VkQueue queue = m_context.getUniversalQueue(); + Allocator& allocator = m_context.getDefaultAllocator(); + + const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); + const VkFormat colorFormat = m_parameters.colorFormat; + const VkDeviceSize colorBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat)); + const VkImageSubresourceRange colorSubresRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); + + const Unique color0Image (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))); + const UniquePtr color0ImageAlloc (bindImage (vk, device, allocator, *color0Image, MemoryRequirement::Any)); + const Unique color0Attachment (makeImageView (vk, device, *color0Image, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange)); + const Unique color0Buffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT))); + const UniquePtr color0BufferAlloc (bindBuffer (vk, device, allocator, *color0Buffer, MemoryRequirement::HostVisible)); + + const Unique color1Image (makeImage (vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))); + const UniquePtr color1ImageAlloc (bindImage (vk, device, allocator, *color1Image, MemoryRequirement::Any)); + const Unique color1Attachment (makeImageView (vk, device, *color1Image, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange)); + const Unique color1Buffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT))); + const UniquePtr color1BufferAlloc (bindBuffer (vk, device, allocator, *color1Buffer, MemoryRequirement::HostVisible)); + + const VkDescriptorType descriptorType (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT); + const Unique descriptorSetLayout (DescriptorSetLayoutBuilder() + .addSingleBinding(descriptorType, VK_SHADER_STAGE_FRAGMENT_BIT) + .build(vk, device)); + const Unique descriptorPool (DescriptorPoolBuilder() + .addType(descriptorType) + .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); + const Unique descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); + const VkDescriptorImageInfo imageDescriptorInfo (makeDescriptorImageInfo(DE_NULL, *color0Attachment, VK_IMAGE_LAYOUT_GENERAL)); + + DescriptorSetUpdateBuilder() + .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageDescriptorInfo) + .update(vk, device); + + const Unique renderPass (makeRenderPass (vk, device, colorFormat, DE_NULL)); + const Unique framebuffer (makeFramebuffer (vk, device, *renderPass, m_imageExtent2D, colorFormat, m_colorImageUsage, VK_FORMAT_UNDEFINED, 0u, ASPECT_NONE, 1u)); + const Unique cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); + const Unique cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); + + const Unique vertModule0 (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u)); + const Unique fragModule0 (createShaderModule (vk, device, m_context.getBinaryCollection().get("frag"), 0u)); + const Unique pipelineLayout0 (makePipelineLayout (vk, device)); + const Unique pipeline0 (makeGraphicsPipeline (vk, device, *pipelineLayout0, *renderPass, *vertModule0, *fragModule0, m_imageExtent2D)); + + const Unique vertModule1 (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert1"), 0u)); + const Unique fragModule1 (createShaderModule (vk, device, m_context.getBinaryCollection().get("frag1"), 0u)); + const Unique pipelineLayout1 (makePipelineLayout (vk, device, 1u, &*descriptorSetLayout)); + const Unique pipeline1 (makeGraphicsPipeline (vk, device, *pipelineLayout1, *renderPass, *vertModule1, *fragModule1, m_imageExtent2D, 0u, VK_SAMPLE_COUNT_1_BIT, 1u)); + + const std::vector vertex0Array (getVertices()); + const deUint32 vertex0Count (static_cast(vertex0Array.size() / 4u)); + const VkDeviceSize vertex0ArraySize (vertex0Array.size() * sizeof(vertex0Array[0])); + const Unique vertex0Buffer (makeBuffer (vk, device, makeBufferCreateInfo(vertex0ArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))); + const UniquePtr vertex0BufferAlloc (bindBuffer (vk, device, allocator, *vertex0Buffer, MemoryRequirement::HostVisible)); + const VkDeviceSize vertex0BufferOffset (0u); + + const std::vector vertex1Array (getFullQuadVertices()); + const deUint32 vertex1Count (static_cast(vertex1Array.size() / 4u)); + const VkDeviceSize vertex1ArraySize (vertex1Array.size() * sizeof(vertex1Array[0])); + const Unique vertex1Buffer (makeBuffer (vk, device, makeBufferCreateInfo(vertex1ArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))); + const UniquePtr vertex1BufferAlloc (bindBuffer (vk, device, allocator, *vertex1Buffer, MemoryRequirement::HostVisible)); + const VkDeviceSize vertex1BufferOffset (0u); + + fillBuffer(vk, device, *vertex0BufferAlloc, &vertex0Array[0], vertex0ArraySize); + fillBuffer(vk, device, *vertex1BufferAlloc, &vertex1Array[0], vertex1ArraySize); + + beginCommandBuffer(vk, *cmdBuffer); + { + const VkImageView attachments[] = { *color0Attachment, *color1Attachment }; + const VkRenderPassAttachmentBeginInfoKHR renderPassAttachmentBeginInfo = + { + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + DE_LENGTH_OF_ARRAY(attachments), // deUint32 attachmentCount; + &attachments[0] // const VkImageView* pAttachments; + }; + + beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, &renderPassAttachmentBeginInfo); + { + { + vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline0); + + vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertex0Buffer, &vertex0BufferOffset); + + vk.cmdDraw(*cmdBuffer, vertex0Count, 1u, 0u, 0u); + } + + vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); + + { + vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1); + + vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertex1Buffer, &vertex1BufferOffset); + + vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout1, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); + + vk.cmdDraw(*cmdBuffer, vertex1Count, 1u, 0u, 0u); + } + } + endRenderPass(vk, *cmdBuffer); + + // Subpass0 color image copy + { + const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + *color0Image, colorSubresRange); + const VkBufferImageCopy region = makeBufferImageCopy (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u), + makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u)); + const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *color0Buffer, 0ull, VK_WHOLE_SIZE); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier); + vk.cmdCopyImageToBuffer(*cmdBuffer, *color0Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color0Buffer, 1u, ®ion); + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u); + } + + // Subpass1 color image copy + { + const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier (VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + *color1Image, colorSubresRange); + const VkBufferImageCopy region = makeBufferImageCopy (makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u), + makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u)); + const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier (VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *color1Buffer, 0ull, VK_WHOLE_SIZE); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier); + vk.cmdCopyImageToBuffer(*cmdBuffer, *color1Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color1Buffer, 1u, ®ion); + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u); + } + } + endCommandBuffer(vk, *cmdBuffer); + submitCommandsAndWait(vk, device, queue, *cmdBuffer); + + { + std::string result; + + if (!verifyBuffer(color0BufferAlloc, colorFormat, "ColorSubpass0", ASPECT_COLOR, NO_SAMPLE, 0u)) + result += " ColorSubpass0"; + + if (!verifyBuffer(color1BufferAlloc, colorFormat, "ColorSubpass1", ASPECT_COLOR, NO_SAMPLE, 1u)) + result += " ColorSubpass1"; + + if (result.empty()) + return tcu::TestStatus::pass("Pass"); + else + return tcu::TestStatus::fail("Following parts of image are incorrect:" + result); + } +} + +class BaseTestCase : public TestCase +{ +public: + BaseTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, const TestParameters& parameters); + virtual ~BaseTestCase (void); + +protected: + virtual void initPrograms (SourceCollections& programCollection) const; + virtual TestInstance* createInstance (Context& context) const; + + const TestParameters m_parameters; +}; + +BaseTestCase::BaseTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, const TestParameters& parameters) + : TestCase (context, name, description) + , m_parameters (parameters) +{ +} + +BaseTestCase::~BaseTestCase () +{ +} + +void BaseTestCase::initPrograms (SourceCollections& programCollection) const +{ + // Vertex shader + { + std::ostringstream src; + + if (m_parameters.testType == TEST_TYPE_COLOR || m_parameters.testType == TEST_TYPE_COLOR_RESOLVE || m_parameters.testType == TEST_TYPE_DEPTH_STENCIL) + { + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" + << "\n" + << "layout(location = 0) in highp vec4 a_position;\n" + << "layout(location = 0) out highp vec4 a_color;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " gl_Position = a_position;\n" + << " if (gl_VertexIndex < 6)\n" + << " a_color = vec4(0.75f, 0.75f, 0.75f, 1.0f);\n" + << " else\n" + << " a_color = vec4(1.00f, 1.00f, 1.00f, 1.0f);\n" + << "}\n"; + } + + if (m_parameters.testType == TEST_TYPE_DEPTH_STENCIL_RESOLVE) + { + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" + << "\n" + << "layout(location = 0) in highp vec4 a_position;\n" + << "layout(location = 0) out highp vec4 a_color;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " gl_Position = a_position;\n" + << " if (gl_VertexIndex < 3)\n" + << " a_color = vec4(0.00f, 0.00f, 1.00f, 1.0f);\n" + << " else\n" + << " a_color = vec4(0.00f, 1.00f, 0.00f, 1.0f);\n" + << "}\n"; + } + + if (m_parameters.testType == TEST_TYPE_MULTISUBPASS) + { + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" + << "\n" + << "layout(location = 0) in highp vec4 a_position;\n" + << "layout(location = 0) out highp vec4 a_color;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " gl_Position = a_position;\n" + << " a_color = vec4(0.0f, 0.0f, 1.0f, 1.0f);\n" + << "}\n"; + } + + programCollection.glslSources.add("vert") << glu::VertexSource(src.str()); + } + + // Fragment shader + { + std::ostringstream src; + + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" + << "\n" + << "layout(location = 0) in highp vec4 a_color;\n" + << "layout(location = 0) out highp vec4 o_color;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " o_color = a_color;\n" + << "}\n"; + + programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()); + } + + // Additional shaders + if (m_parameters.testType == TEST_TYPE_COLOR_RESOLVE || m_parameters.testType == TEST_TYPE_DEPTH_STENCIL_RESOLVE) + { + // Vertex shader + { + std::ostringstream src; + + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" + << "\n" + << "layout(location = 0) in highp vec4 a_position;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " gl_Position = a_position;\n" + << "}\n"; + + programCollection.glslSources.add("demultisample-vert") << glu::VertexSource(src.str()); + } + + // Fragment shader + { + // Color + { + std::ostringstream src; + + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" + << "\n" + << "layout(set = 0, binding = 0) uniform sampler2DMS u_ms_image_sampler;\n" + << "layout(push_constant) uniform PushConstantsBlock {\n" + << " highp int sampleID;\n" + << "} pushConstants;\n" + << "layout(location = 0) out highp vec4 o_color;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " o_color = texelFetch(u_ms_image_sampler, ivec2(gl_FragCoord.xy), pushConstants.sampleID);\n" + << "}\n"; + + programCollection.glslSources.add("demultisample-color-frag") << glu::FragmentSource(src.str()); + } + + // Depth + { + std::ostringstream src; + + // Depth-component textures are treated as one-component floating-point textures. + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" + << "\n" + << "layout(binding = 0) uniform sampler2DMS u_ms_image_sampler;\n" + << "layout(push_constant) uniform PushConstantsBlock {\n" + << " highp int sampleID;\n" + << "} pushConstants;\n" + << "layout(location = 0) out highp vec4 o_color;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " vec4 val = texelFetch(u_ms_image_sampler, ivec2(gl_FragCoord.xy), pushConstants.sampleID);\n" + << " o_color = vec4(val.x, val.x, val.x, 1.0);\n" + << "}\n"; + + programCollection.glslSources.add("demultisample-depth-frag") << glu::FragmentSource(src.str()); + } + + // Stencil + { + std::ostringstream src; + + // Stencil-component textures are treated as one-component unsigned integer textures. + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" + << "\n" + << "layout(binding = 0) uniform usampler2DMS u_ms_image_sampler;\n" + << "layout(push_constant) uniform PushConstantsBlock {\n" + << " highp int sampleID;\n" + << "} pushConstants;\n" + << "layout(location = 0) out highp vec4 o_color;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " uvec4 uVal = texelFetch(u_ms_image_sampler, ivec2(gl_FragCoord.xy), pushConstants.sampleID);\n" + << " float val = float(uVal.x) / 4.0f;\n" + << " o_color = vec4(val, val, val, 1.0);\n" + << "}\n"; + + programCollection.glslSources.add("demultisample-stencil-frag") << glu::FragmentSource(src.str()); + } + } + } + + if (m_parameters.testType == TEST_TYPE_MULTISUBPASS) + { + // Vertex shader + { + std::ostringstream src; + + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" + << "\n" + << "layout(location = 0) in highp vec4 a_position;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " gl_Position = a_position;\n" + << "}\n"; + + programCollection.glslSources.add("vert1") << glu::VertexSource(src.str()); + } + + // Fragment shader + { + std::ostringstream src; + + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" + << "\n" + << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput u_colors;\n" + << "layout(location = 0) out highp vec4 o_color;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " o_color = subpassLoad(u_colors);\n" + << " o_color.g = 1.0f;\n" + << " o_color.a = 1.0f;\n" + << "}\n"; + + programCollection.glslSources.add("frag1") << glu::FragmentSource(src.str()); + } + } + + + return; +} + +TestInstance* BaseTestCase::createInstance (Context& context) const +{ + if (m_parameters.testType == TEST_TYPE_COLOR) + return new ColorImagelessTestInstance(context, m_parameters); + + if (m_parameters.testType == TEST_TYPE_DEPTH_STENCIL) + return new DepthImagelessTestInstance(context, m_parameters); + + if (m_parameters.testType == TEST_TYPE_COLOR_RESOLVE) + return new ColorResolveImagelessTestInstance(context, m_parameters); + + if (m_parameters.testType == TEST_TYPE_DEPTH_STENCIL_RESOLVE) + return new DepthResolveImagelessTestInstance(context, m_parameters); + + if (m_parameters.testType == TEST_TYPE_MULTISUBPASS) + return new MultisubpassTestInstance(context, m_parameters); + + TCU_THROW(InternalError, "Unknown test type specified"); +} + +tcu::TestNode* imagelessColorTests (tcu::TestContext& testCtx) +{ + TestParameters parameters = + { + TEST_TYPE_COLOR, // TestType testType; + VK_FORMAT_R8G8B8A8_UNORM, // VkFormat colorFormat; + VK_FORMAT_UNDEFINED, // VkFormat dsFormat; + }; + + return new BaseTestCase(testCtx, "color", "Imageless color attachment test", parameters); +} + +tcu::TestNode* imagelessDepthStencilTests (tcu::TestContext& testCtx) +{ + TestParameters parameters = + { + TEST_TYPE_DEPTH_STENCIL, // TestType testType; + VK_FORMAT_R8G8B8A8_UNORM, // VkFormat colorFormat; + VK_FORMAT_D24_UNORM_S8_UINT, // VkFormat dsFormat; + }; + + return new BaseTestCase(testCtx, "depth_stencil", "Imageless depth/stencil attachment test", parameters); +} + +tcu::TestNode* imagelessColorResolveTests (tcu::TestContext& testCtx) +{ + TestParameters parameters = + { + TEST_TYPE_COLOR_RESOLVE, // TestType testType; + VK_FORMAT_R8G8B8A8_UNORM, // VkFormat colorFormat; + VK_FORMAT_UNDEFINED, // VkFormat dsFormat; + }; + + return new BaseTestCase(testCtx, "color_resolve", "Imageless color attachment resolve test", parameters); +} + +tcu::TestNode* imagelessDepthStencilResolveTests (tcu::TestContext& testCtx) +{ + TestParameters parameters = + { + TEST_TYPE_DEPTH_STENCIL_RESOLVE, // TestType testType; + VK_FORMAT_R8G8B8A8_UNORM, // VkFormat colorFormat; + VK_FORMAT_D24_UNORM_S8_UINT, // VkFormat dsFormat; + }; + + return new BaseTestCase(testCtx, "depth_stencil_resolve", "Imageless color and depth/stencil attachment resolve test", parameters); +} + +tcu::TestNode* imagelessMultisubpass (tcu::TestContext& testCtx) +{ + TestParameters parameters = + { + TEST_TYPE_MULTISUBPASS, // TestType testType; + VK_FORMAT_R8G8B8A8_UNORM, // VkFormat colorFormat; + VK_FORMAT_D24_UNORM_S8_UINT, // VkFormat dsFormat; + }; + + return new BaseTestCase(testCtx, "multisubpass", "Multi-subpass test", parameters); +} + +} // anonymous + +tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx) +{ + de::MovePtr imagelessFramebufferGroup (new tcu::TestCaseGroup(testCtx, "imageless_framebuffer", "Imageless Framebuffer tests")); + + imagelessFramebufferGroup->addChild(imagelessColorTests(testCtx)); // Color only test + imagelessFramebufferGroup->addChild(imagelessDepthStencilTests(testCtx)); // Color and depth/stencil test + imagelessFramebufferGroup->addChild(imagelessColorResolveTests(testCtx)); // Color and color resolve test + imagelessFramebufferGroup->addChild(imagelessDepthStencilResolveTests(testCtx)); // Color, depth and depth resolve test (interaction with VK_KHR_depth_stencil_resolve) + imagelessFramebufferGroup->addChild(imagelessMultisubpass(testCtx)); // Multi-subpass test + + return imagelessFramebufferGroup.release(); +} + +} // imageless +} // vkt diff --git a/external/vulkancts/modules/vulkan/imageless_framebuffer/vktImagelessFramebufferTests.hpp b/external/vulkancts/modules/vulkan/imageless_framebuffer/vktImagelessFramebufferTests.hpp new file mode 100644 index 0000000..e5afd67 --- /dev/null +++ b/external/vulkancts/modules/vulkan/imageless_framebuffer/vktImagelessFramebufferTests.hpp @@ -0,0 +1,39 @@ +#ifndef _VKTIMAGELESSFRAMEBUFFERTESTS_HPP +#define _VKTIMAGELESSFRAMEBUFFERTESTS_HPP +/*------------------------------------------------------------------------ + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2019 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *//*! + * \file + * \brief Vulkan Imageless Framebuffer Tests + *//*--------------------------------------------------------------------*/ + +#include "tcuDefs.hpp" +#include "tcuTestCase.hpp" + +namespace vkt +{ +namespace imageless +{ + +tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx); + +} // imageless +} // vkt + +#endif // _VKTIMAGELESSFRAMEBUFFERTESTS_HPP diff --git a/external/vulkancts/modules/vulkan/vktTestPackage.cpp b/external/vulkancts/modules/vulkan/vktTestPackage.cpp index 499df26..6cbe18b 100644 --- a/external/vulkancts/modules/vulkan/vktTestPackage.cpp +++ b/external/vulkancts/modules/vulkan/vktTestPackage.cpp @@ -92,6 +92,7 @@ #include "vktAmberGraphicsFuzzTests.hpp" #include "vktTransformFeedbackTests.hpp" #include "vktDescriptorIndexingTests.hpp" +#include "vktImagelessFramebufferTests.hpp" #include #include @@ -506,6 +507,7 @@ void TestPackage::init (void) addChild(cts_amber::createGraphicsFuzzTests (m_testCtx)); addChild(TransformFeedback::createTests (m_testCtx)); addChild(DescriptorIndexing::createTests (m_testCtx)); + addChild(imageless::createTests (m_testCtx)); } } // vkt diff --git a/external/vulkancts/mustpass/master/vk-default-no-waivers.txt b/external/vulkancts/mustpass/master/vk-default-no-waivers.txt index 164650d..16f6547 100644 --- a/external/vulkancts/mustpass/master/vk-default-no-waivers.txt +++ b/external/vulkancts/mustpass/master/vk-default-no-waivers.txt @@ -464969,3 +464969,8 @@ dEQP-VK.descriptor_indexing.uniform_buffer_in_loop dEQP-VK.descriptor_indexing.storage_buffer_dynamic_in_loop dEQP-VK.descriptor_indexing.uniform_buffer_dynamic_in_loop dEQP-VK.descriptor_indexing.input_attachment_in_loop +dEQP-VK.imageless_framebuffer.color +dEQP-VK.imageless_framebuffer.depth_stencil +dEQP-VK.imageless_framebuffer.color_resolve +dEQP-VK.imageless_framebuffer.depth_stencil_resolve +dEQP-VK.imageless_framebuffer.multisubpass diff --git a/external/vulkancts/mustpass/master/vk-default.txt b/external/vulkancts/mustpass/master/vk-default.txt index e56bcbe..401ba3c 100644 --- a/external/vulkancts/mustpass/master/vk-default.txt +++ b/external/vulkancts/mustpass/master/vk-default.txt @@ -464816,3 +464816,8 @@ dEQP-VK.descriptor_indexing.uniform_buffer_in_loop dEQP-VK.descriptor_indexing.storage_buffer_dynamic_in_loop dEQP-VK.descriptor_indexing.uniform_buffer_dynamic_in_loop dEQP-VK.descriptor_indexing.input_attachment_in_loop +dEQP-VK.imageless_framebuffer.color +dEQP-VK.imageless_framebuffer.depth_stencil +dEQP-VK.imageless_framebuffer.color_resolve +dEQP-VK.imageless_framebuffer.depth_stencil_resolve +dEQP-VK.imageless_framebuffer.multisubpass diff --git a/external/vulkancts/scripts/src/extensions_data.txt b/external/vulkancts/scripts/src/extensions_data.txt index 84297e3..9105ec6 100644 --- a/external/vulkancts/scripts/src/extensions_data.txt +++ b/external/vulkancts/scripts/src/extensions_data.txt @@ -64,4 +64,5 @@ VK_KHR_depth_stencil_resolve DEVICE VK_KHR_draw_indirect_count DEVICE VK_KHR_shader_atomic_int64 DEVICE VK_KHR_vulkan_memory_model DEVICE -VK_KHR_uniform_buffer_standard_layout DEVICE \ No newline at end of file +VK_KHR_uniform_buffer_standard_layout DEVICE +VK_KHR_imageless_framebuffer DEVICE \ No newline at end of file diff --git a/external/vulkancts/scripts/src/vulkan_core.h b/external/vulkancts/scripts/src/vulkan_core.h index 5ea1893..ec69163 100755 --- a/external/vulkancts/scripts/src/vulkan_core.h +++ b/external/vulkancts/scripts/src/vulkan_core.h @@ -351,6 +351,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000, VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001, VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = 1000108000, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = 1000108001, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = 1000108002, + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = 1000108003, VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = 1000109000, VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = 1000109001, VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = 1000109002, @@ -1695,6 +1699,11 @@ typedef enum VkDescriptorPoolCreateFlagBits { } VkDescriptorPoolCreateFlagBits; typedef VkFlags VkDescriptorPoolCreateFlags; typedef VkFlags VkDescriptorPoolResetFlags; + +typedef enum VkFramebufferCreateFlagBits { + VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = 0x00000001, + VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkFramebufferCreateFlagBits; typedef VkFlags VkFramebufferCreateFlags; typedef VkFlags VkRenderPassCreateFlags; @@ -5587,6 +5596,43 @@ VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplateKHR( const void* pData); #endif +#define VK_KHR_imageless_framebuffer 1 +#define VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION 1 +#define VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME "VK_KHR_imageless_framebuffer" + +typedef struct VkPhysicalDeviceImagelessFramebufferFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 imagelessFramebuffer; +} VkPhysicalDeviceImagelessFramebufferFeaturesKHR; + +typedef struct VkFramebufferAttachmentImageInfoKHR { + VkStructureType sType; + const void* pNext; + VkImageCreateFlags flags; + VkImageUsageFlags usage; + uint32_t width; + uint32_t height; + uint32_t layerCount; + uint32_t viewFormatCount; + const VkFormat* pViewFormats; +} VkFramebufferAttachmentImageInfoKHR; + +typedef struct VkFramebufferAttachmentsCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t attachmentImageInfoCount; + const VkFramebufferAttachmentImageInfoKHR* pAttachmentImageInfos; +} VkFramebufferAttachmentsCreateInfoKHR; + +typedef struct VkRenderPassAttachmentBeginInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t attachmentCount; + const VkImageView* pAttachments; +} VkRenderPassAttachmentBeginInfoKHR; + + #define VK_KHR_create_renderpass2 1 #define VK_KHR_CREATE_RENDERPASS_2_SPEC_VERSION 1 -- 2.7.4