1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------ 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2019 Advanced Micro Devices, Inc. 6e5c31af7Sopenharmony_ci * Copyright (c) 2019 The Khronos Group Inc. 7e5c31af7Sopenharmony_ci * Copyright (c) 2023 LunarG, Inc. 8e5c31af7Sopenharmony_ci * Copyright (c) 2023 Nintendo 9e5c31af7Sopenharmony_ci * 10e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 11e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 12e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 13e5c31af7Sopenharmony_ci * 14e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 15e5c31af7Sopenharmony_ci * 16e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 17e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 18e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 20e5c31af7Sopenharmony_ci * limitations under the License. 21e5c31af7Sopenharmony_ci * 22e5c31af7Sopenharmony_ci *//*! 23e5c31af7Sopenharmony_ci * \file 24e5c31af7Sopenharmony_ci * \brief Tests for VK_AMD_shader_fragment_mask 25e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_ci#include "vktPipelineMultisampleShaderFragmentMaskTests.hpp" 28e5c31af7Sopenharmony_ci#include "vktPipelineMakeUtil.hpp" 29e5c31af7Sopenharmony_ci#include "vktTestCase.hpp" 30e5c31af7Sopenharmony_ci#include "vktTestCaseUtil.hpp" 31e5c31af7Sopenharmony_ci#include "vktTestGroupUtil.hpp" 32e5c31af7Sopenharmony_ci#include "vktCustomInstancesDevices.hpp" 33e5c31af7Sopenharmony_ci#include "tcuCommandLine.hpp" 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_ci#include "vkCmdUtil.hpp" 36e5c31af7Sopenharmony_ci#include "vkObjUtil.hpp" 37e5c31af7Sopenharmony_ci#include "vkPlatform.hpp" 38e5c31af7Sopenharmony_ci#include "vkMemUtil.hpp" 39e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp" 40e5c31af7Sopenharmony_ci#include "vkTypeUtil.hpp" 41e5c31af7Sopenharmony_ci#include "vkRefUtil.hpp" 42e5c31af7Sopenharmony_ci#include "vkBuilderUtil.hpp" 43e5c31af7Sopenharmony_ci#include "vkPrograms.hpp" 44e5c31af7Sopenharmony_ci#include "vkImageUtil.hpp" 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_ci#include "deUniquePtr.hpp" 47e5c31af7Sopenharmony_ci#include "deSharedPtr.hpp" 48e5c31af7Sopenharmony_ci#include "deRandom.hpp" 49e5c31af7Sopenharmony_ci 50e5c31af7Sopenharmony_ci#include "tcuVector.hpp" 51e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 52e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp" 53e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 54e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp" 55e5c31af7Sopenharmony_ci 56e5c31af7Sopenharmony_ci#include <string> 57e5c31af7Sopenharmony_ci#include <vector> 58e5c31af7Sopenharmony_ci#include <set> 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_cinamespace vkt 61e5c31af7Sopenharmony_ci{ 62e5c31af7Sopenharmony_cinamespace pipeline 63e5c31af7Sopenharmony_ci{ 64e5c31af7Sopenharmony_cinamespace 65e5c31af7Sopenharmony_ci{ 66e5c31af7Sopenharmony_ciusing namespace vk; 67e5c31af7Sopenharmony_ciusing de::MovePtr; 68e5c31af7Sopenharmony_ciusing de::SharedPtr; 69e5c31af7Sopenharmony_ciusing tcu::UVec2; 70e5c31af7Sopenharmony_ciusing tcu::UVec4; 71e5c31af7Sopenharmony_ciusing tcu::Vec2; 72e5c31af7Sopenharmony_ciusing tcu::Vec4; 73e5c31af7Sopenharmony_ci 74e5c31af7Sopenharmony_citypedef SharedPtr<Unique<VkImageView> > ImageViewSp; 75e5c31af7Sopenharmony_ci 76e5c31af7Sopenharmony_cistruct PositionColor 77e5c31af7Sopenharmony_ci{ 78e5c31af7Sopenharmony_ci tcu::Vec4 position; 79e5c31af7Sopenharmony_ci VkClearColorValue color; 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_ci PositionColor (const tcu::Vec4& pos, const tcu::UVec4& col) : position(pos) 82e5c31af7Sopenharmony_ci { 83e5c31af7Sopenharmony_ci deMemcpy(color.uint32, col.getPtr(), sizeof(color.uint32)); 84e5c31af7Sopenharmony_ci } 85e5c31af7Sopenharmony_ci 86e5c31af7Sopenharmony_ci PositionColor (const tcu::Vec4& pos, const tcu::Vec4& col) : position(pos) 87e5c31af7Sopenharmony_ci { 88e5c31af7Sopenharmony_ci deMemcpy(color.float32, col.getPtr(), sizeof(color.float32)); 89e5c31af7Sopenharmony_ci } 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci PositionColor (const PositionColor& rhs) 92e5c31af7Sopenharmony_ci : position (rhs.position) 93e5c31af7Sopenharmony_ci , color (rhs.color) 94e5c31af7Sopenharmony_ci { 95e5c31af7Sopenharmony_ci } 96e5c31af7Sopenharmony_ci}; 97e5c31af7Sopenharmony_ci 98e5c31af7Sopenharmony_ci//! Make a (unused) sampler. 99e5c31af7Sopenharmony_ciMove<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice device) 100e5c31af7Sopenharmony_ci{ 101e5c31af7Sopenharmony_ci const VkSamplerCreateInfo samplerParams = 102e5c31af7Sopenharmony_ci { 103e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType; 104e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 105e5c31af7Sopenharmony_ci (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags; 106e5c31af7Sopenharmony_ci VK_FILTER_NEAREST, // VkFilter magFilter; 107e5c31af7Sopenharmony_ci VK_FILTER_NEAREST, // VkFilter minFilter; 108e5c31af7Sopenharmony_ci VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode; 109e5c31af7Sopenharmony_ci VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU; 110e5c31af7Sopenharmony_ci VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV; 111e5c31af7Sopenharmony_ci VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW; 112e5c31af7Sopenharmony_ci 0.0f, // float mipLodBias; 113e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 anisotropyEnable; 114e5c31af7Sopenharmony_ci 1.0f, // float maxAnisotropy; 115e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 compareEnable; 116e5c31af7Sopenharmony_ci VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp; 117e5c31af7Sopenharmony_ci 0.0f, // float minLod; 118e5c31af7Sopenharmony_ci 0.0f, // float maxLod; 119e5c31af7Sopenharmony_ci VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor; 120e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 unnormalizedCoordinates; 121e5c31af7Sopenharmony_ci }; 122e5c31af7Sopenharmony_ci return createSampler(vk, device, &samplerParams); 123e5c31af7Sopenharmony_ci} 124e5c31af7Sopenharmony_ci 125e5c31af7Sopenharmony_ciMove<VkImage> makeImage (const DeviceInterface& vk, 126e5c31af7Sopenharmony_ci const VkDevice device, 127e5c31af7Sopenharmony_ci const VkFormat format, 128e5c31af7Sopenharmony_ci const UVec2& size, 129e5c31af7Sopenharmony_ci const deUint32 layers, 130e5c31af7Sopenharmony_ci const VkSampleCountFlagBits samples, 131e5c31af7Sopenharmony_ci const VkImageUsageFlags usage) 132e5c31af7Sopenharmony_ci{ 133e5c31af7Sopenharmony_ci const VkImageCreateInfo imageParams = 134e5c31af7Sopenharmony_ci { 135e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 136e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 137e5c31af7Sopenharmony_ci (VkImageCreateFlags)0, // VkImageCreateFlags flags; 138e5c31af7Sopenharmony_ci VK_IMAGE_TYPE_2D, // VkImageType imageType; 139e5c31af7Sopenharmony_ci format, // VkFormat format; 140e5c31af7Sopenharmony_ci makeExtent3D(size.x(), size.y(), 1), // VkExtent3D extent; 141e5c31af7Sopenharmony_ci 1u, // deUint32 mipLevels; 142e5c31af7Sopenharmony_ci layers, // deUint32 arrayLayers; 143e5c31af7Sopenharmony_ci samples, // VkSampleCountFlagBits samples; 144e5c31af7Sopenharmony_ci VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 145e5c31af7Sopenharmony_ci usage, // VkImageUsageFlags usage; 146e5c31af7Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 147e5c31af7Sopenharmony_ci 0u, // deUint32 queueFamilyIndexCount; 148e5c31af7Sopenharmony_ci DE_NULL, // const deUint32* pQueueFamilyIndices; 149e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 150e5c31af7Sopenharmony_ci }; 151e5c31af7Sopenharmony_ci return createImage(vk, device, &imageParams); 152e5c31af7Sopenharmony_ci} 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_cistd::vector<PositionColor> genShapes (const VkFormat colorFormat) 155e5c31af7Sopenharmony_ci{ 156e5c31af7Sopenharmony_ci std::vector<PositionColor> vertices; 157e5c31af7Sopenharmony_ci 158e5c31af7Sopenharmony_ci if (colorFormat == VK_FORMAT_R8G8B8A8_UNORM) 159e5c31af7Sopenharmony_ci { 160e5c31af7Sopenharmony_ci vertices.push_back(PositionColor(Vec4( 0.0f, -0.75f, 0.0f, 1.0f), Vec4(0.5f, 0.5f, 0.5f, 1.0f))); 161e5c31af7Sopenharmony_ci vertices.push_back(PositionColor(Vec4(-0.75f, 0.75f, 0.0f, 1.0f), Vec4(1.0f, 0.5f, 0.5f, 1.0f))); 162e5c31af7Sopenharmony_ci vertices.push_back(PositionColor(Vec4( 0.75f, 0.65f, 0.0f, 1.0f), Vec4(0.0f, 0.5f, 1.0f, 1.0f))); 163e5c31af7Sopenharmony_ci } 164e5c31af7Sopenharmony_ci else 165e5c31af7Sopenharmony_ci { 166e5c31af7Sopenharmony_ci vertices.push_back(PositionColor(Vec4( 0.0f, -0.75f, 0.0f, 1.0f), UVec4(0xabcdu, 0u, 0u, 0u))); 167e5c31af7Sopenharmony_ci vertices.push_back(PositionColor(Vec4(-0.75f, 0.75f, 0.0f, 1.0f), UVec4(0xbcdeu, 0u, 0u, 0u))); 168e5c31af7Sopenharmony_ci vertices.push_back(PositionColor(Vec4( 0.75f, 0.65f, 0.0f, 1.0f), UVec4(0xcdefu, 0u, 0u, 0u))); 169e5c31af7Sopenharmony_ci } 170e5c31af7Sopenharmony_ci 171e5c31af7Sopenharmony_ci return vertices; 172e5c31af7Sopenharmony_ci} 173e5c31af7Sopenharmony_ci 174e5c31af7Sopenharmony_ci//! Map color image format to a convenient format used in vertex attributes 175e5c31af7Sopenharmony_ciVkFormat getVertexInputColorFormat (const VkFormat colorImageFormat) 176e5c31af7Sopenharmony_ci{ 177e5c31af7Sopenharmony_ci switch (tcu::getTextureChannelClass(mapVkFormat(colorImageFormat).type)) 178e5c31af7Sopenharmony_ci { 179e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 180e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 181e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 182e5c31af7Sopenharmony_ci return VK_FORMAT_R32G32B32A32_SFLOAT; 183e5c31af7Sopenharmony_ci 184e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 185e5c31af7Sopenharmony_ci return VK_FORMAT_R32G32B32A32_SINT; 186e5c31af7Sopenharmony_ci 187e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 188e5c31af7Sopenharmony_ci return VK_FORMAT_R32G32B32A32_UINT; 189e5c31af7Sopenharmony_ci 190e5c31af7Sopenharmony_ci default: 191e5c31af7Sopenharmony_ci DE_ASSERT(0); 192e5c31af7Sopenharmony_ci return VK_FORMAT_UNDEFINED; 193e5c31af7Sopenharmony_ci } 194e5c31af7Sopenharmony_ci} 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_cienum SampleSource 197e5c31af7Sopenharmony_ci{ 198e5c31af7Sopenharmony_ci SAMPLE_SOURCE_IMAGE, //!< texel fetch from an image 199e5c31af7Sopenharmony_ci SAMPLE_SOURCE_SUBPASS_INPUT, //!< texel fetch from an input attachment 200e5c31af7Sopenharmony_ci}; 201e5c31af7Sopenharmony_ci 202e5c31af7Sopenharmony_ci// Class to wrap a singleton device for use in fragment mask tests, 203e5c31af7Sopenharmony_ci// which require the VK_AMD_shader_fragment extension. 204e5c31af7Sopenharmony_ciclass SingletonDevice 205e5c31af7Sopenharmony_ci{ 206e5c31af7Sopenharmony_ci SingletonDevice(Context& context) 207e5c31af7Sopenharmony_ci : m_context(context) 208e5c31af7Sopenharmony_ci , m_logicalDevice() 209e5c31af7Sopenharmony_ci { 210e5c31af7Sopenharmony_ci const float queuePriority = 1.0; 211e5c31af7Sopenharmony_ci const VkDeviceQueueCreateInfo queues[] = 212e5c31af7Sopenharmony_ci { 213e5c31af7Sopenharmony_ci { 214e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, 215e5c31af7Sopenharmony_ci DE_NULL, 216e5c31af7Sopenharmony_ci (VkDeviceQueueCreateFlags)0, 217e5c31af7Sopenharmony_ci m_context.getUniversalQueueFamilyIndex(), 218e5c31af7Sopenharmony_ci 1u, // queueCount 219e5c31af7Sopenharmony_ci &queuePriority, // pQueuePriorities 220e5c31af7Sopenharmony_ci } 221e5c31af7Sopenharmony_ci }; 222e5c31af7Sopenharmony_ci 223e5c31af7Sopenharmony_ci const auto& vkp = m_context.getPlatformInterface(); 224e5c31af7Sopenharmony_ci const auto& vki = m_context.getInstanceInterface(); 225e5c31af7Sopenharmony_ci const auto instance = m_context.getInstance(); 226e5c31af7Sopenharmony_ci const auto physicalDevice = m_context.getPhysicalDevice(); 227e5c31af7Sopenharmony_ci std::vector<const char*> creationExtensions = m_context.getDeviceCreationExtensions(); 228e5c31af7Sopenharmony_ci 229e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures2 features2 = initVulkanStructure(); 230e5c31af7Sopenharmony_ci VkPhysicalDeviceDescriptorBufferFeaturesEXT descriptorBufferFeatures = initVulkanStructure(); 231e5c31af7Sopenharmony_ci VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT graphicsPipelineLibraryFeatures = initVulkanStructure(); 232e5c31af7Sopenharmony_ci VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamicRenderingFeatures = initVulkanStructure(); 233e5c31af7Sopenharmony_ci VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeatures = initVulkanStructure(&dynamicRenderingFeatures); 234e5c31af7Sopenharmony_ci 235e5c31af7Sopenharmony_ci m_context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2"); 236e5c31af7Sopenharmony_ci const auto addFeatures = makeStructChainAdder(&features2); 237e5c31af7Sopenharmony_ci 238e5c31af7Sopenharmony_ci if (m_context.isDeviceFunctionalitySupported("VK_EXT_descriptor_buffer")) 239e5c31af7Sopenharmony_ci addFeatures(&descriptorBufferFeatures); 240e5c31af7Sopenharmony_ci 241e5c31af7Sopenharmony_ci if (m_context.isDeviceFunctionalitySupported("VK_EXT_graphics_pipeline_library")) 242e5c31af7Sopenharmony_ci addFeatures(&graphicsPipelineLibraryFeatures); 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci if (m_context.isDeviceFunctionalitySupported("VK_EXT_shader_object")) 245e5c31af7Sopenharmony_ci addFeatures(&shaderObjectFeatures); 246e5c31af7Sopenharmony_ci 247e5c31af7Sopenharmony_ci vki.getPhysicalDeviceFeatures2(physicalDevice, &features2); 248e5c31af7Sopenharmony_ci descriptorBufferFeatures.descriptorBuffer = VK_FALSE; 249e5c31af7Sopenharmony_ci features2.features.robustBufferAccess = VK_FALSE; // Disable robustness features. 250e5c31af7Sopenharmony_ci creationExtensions.push_back("VK_AMD_shader_fragment_mask"); 251e5c31af7Sopenharmony_ci 252e5c31af7Sopenharmony_ci VkDeviceCreateInfo createInfo = initVulkanStructure(&features2); 253e5c31af7Sopenharmony_ci createInfo.flags = 0u; 254e5c31af7Sopenharmony_ci createInfo.queueCreateInfoCount = de::arrayLength(queues); 255e5c31af7Sopenharmony_ci createInfo.pQueueCreateInfos = queues; 256e5c31af7Sopenharmony_ci createInfo.enabledLayerCount = 0u; 257e5c31af7Sopenharmony_ci createInfo.ppEnabledLayerNames = nullptr; 258e5c31af7Sopenharmony_ci createInfo.enabledExtensionCount = de::sizeU32(creationExtensions); 259e5c31af7Sopenharmony_ci createInfo.ppEnabledExtensionNames = de::dataOrNull(creationExtensions); 260e5c31af7Sopenharmony_ci createInfo.pEnabledFeatures = nullptr; 261e5c31af7Sopenharmony_ci 262e5c31af7Sopenharmony_ci m_logicalDevice = createCustomDevice( 263e5c31af7Sopenharmony_ci m_context.getTestContext().getCommandLine().isValidationEnabled(), 264e5c31af7Sopenharmony_ci vkp, 265e5c31af7Sopenharmony_ci instance, 266e5c31af7Sopenharmony_ci vki, 267e5c31af7Sopenharmony_ci physicalDevice, 268e5c31af7Sopenharmony_ci &createInfo, 269e5c31af7Sopenharmony_ci nullptr); 270e5c31af7Sopenharmony_ci 271e5c31af7Sopenharmony_ci m_deviceDriver = de::MovePtr<DeviceDriver>(new DeviceDriver(vkp, instance, *m_logicalDevice, m_context.getUsedApiVersion())); 272e5c31af7Sopenharmony_ci } 273e5c31af7Sopenharmony_ci 274e5c31af7Sopenharmony_cipublic: 275e5c31af7Sopenharmony_ci ~SingletonDevice() 276e5c31af7Sopenharmony_ci { 277e5c31af7Sopenharmony_ci } 278e5c31af7Sopenharmony_ci 279e5c31af7Sopenharmony_ci static VkDevice getDevice(Context& context) 280e5c31af7Sopenharmony_ci { 281e5c31af7Sopenharmony_ci if (!m_singletonDevice) 282e5c31af7Sopenharmony_ci m_singletonDevice = SharedPtr<SingletonDevice>(new SingletonDevice(context)); 283e5c31af7Sopenharmony_ci DE_ASSERT(m_singletonDevice); 284e5c31af7Sopenharmony_ci return m_singletonDevice->m_logicalDevice.get(); 285e5c31af7Sopenharmony_ci } 286e5c31af7Sopenharmony_ci 287e5c31af7Sopenharmony_ci static VkQueue getUniversalQueue(Context& context) 288e5c31af7Sopenharmony_ci { 289e5c31af7Sopenharmony_ci return getDeviceQueue(getDeviceInterface(context), getDevice(context), context.getUniversalQueueFamilyIndex(), 0); 290e5c31af7Sopenharmony_ci } 291e5c31af7Sopenharmony_ci 292e5c31af7Sopenharmony_ci static const DeviceInterface& getDeviceInterface(Context& context) 293e5c31af7Sopenharmony_ci { 294e5c31af7Sopenharmony_ci if (!m_singletonDevice) 295e5c31af7Sopenharmony_ci m_singletonDevice = SharedPtr<SingletonDevice>(new SingletonDevice(context)); 296e5c31af7Sopenharmony_ci DE_ASSERT(m_singletonDevice); 297e5c31af7Sopenharmony_ci return *(m_singletonDevice->m_deviceDriver.get()); 298e5c31af7Sopenharmony_ci } 299e5c31af7Sopenharmony_ci 300e5c31af7Sopenharmony_ci static void destroy() 301e5c31af7Sopenharmony_ci { 302e5c31af7Sopenharmony_ci m_singletonDevice.clear(); 303e5c31af7Sopenharmony_ci } 304e5c31af7Sopenharmony_ci 305e5c31af7Sopenharmony_ciprivate: 306e5c31af7Sopenharmony_ci const Context& m_context; 307e5c31af7Sopenharmony_ci Move<vk::VkDevice> m_logicalDevice; 308e5c31af7Sopenharmony_ci de::MovePtr<vk::DeviceDriver> m_deviceDriver; 309e5c31af7Sopenharmony_ci static SharedPtr<SingletonDevice> m_singletonDevice; 310e5c31af7Sopenharmony_ci}; 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_ciSharedPtr<SingletonDevice> SingletonDevice::m_singletonDevice; 313e5c31af7Sopenharmony_ci 314e5c31af7Sopenharmony_ci//! The parameters that define a test case 315e5c31af7Sopenharmony_cistruct TestParams 316e5c31af7Sopenharmony_ci{ 317e5c31af7Sopenharmony_ci PipelineConstructionType pipelineConstructionType; 318e5c31af7Sopenharmony_ci UVec2 renderSize; 319e5c31af7Sopenharmony_ci deUint32 numLayers; //!< 1 or N for layered image 320e5c31af7Sopenharmony_ci SampleSource sampleSource; //!< source of texel fetch 321e5c31af7Sopenharmony_ci VkSampleCountFlagBits numColorSamples; 322e5c31af7Sopenharmony_ci VkFormat colorFormat; //!< Color attachment format 323e5c31af7Sopenharmony_ci 324e5c31af7Sopenharmony_ci TestParams (void) 325e5c31af7Sopenharmony_ci : numLayers () 326e5c31af7Sopenharmony_ci , sampleSource (SAMPLE_SOURCE_IMAGE) 327e5c31af7Sopenharmony_ci , numColorSamples () 328e5c31af7Sopenharmony_ci , colorFormat () 329e5c31af7Sopenharmony_ci { 330e5c31af7Sopenharmony_ci } 331e5c31af7Sopenharmony_ci}; 332e5c31af7Sopenharmony_ci 333e5c31af7Sopenharmony_civoid checkRequirements (Context& context, TestParams params) 334e5c31af7Sopenharmony_ci{ 335e5c31af7Sopenharmony_ci const auto& vki = context.getInstanceInterface(); 336e5c31af7Sopenharmony_ci const auto physicalDevice = context.getPhysicalDevice(); 337e5c31af7Sopenharmony_ci 338e5c31af7Sopenharmony_ci const auto& supportedExtensions = enumerateCachedDeviceExtensionProperties(vki, physicalDevice); 339e5c31af7Sopenharmony_ci if (!isExtensionStructSupported(supportedExtensions, RequiredExtension("VK_AMD_shader_fragment_mask"))) 340e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "VK_AMD_shader_fragment_mask not supported"); 341e5c31af7Sopenharmony_ci 342e5c31af7Sopenharmony_ci const auto& limits = context.getDeviceProperties().limits; 343e5c31af7Sopenharmony_ci 344e5c31af7Sopenharmony_ci if ((limits.framebufferColorSampleCounts & params.numColorSamples) == 0u) 345e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "framebufferColorSampleCounts: sample count not supported"); 346e5c31af7Sopenharmony_ci 347e5c31af7Sopenharmony_ci if ((isIntFormat(params.colorFormat) || isUintFormat(params.colorFormat))) 348e5c31af7Sopenharmony_ci { 349e5c31af7Sopenharmony_ci if ((limits.sampledImageIntegerSampleCounts & params.numColorSamples) == 0u) 350e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "sampledImageIntegerSampleCounts: sample count not supported"); 351e5c31af7Sopenharmony_ci } 352e5c31af7Sopenharmony_ci else 353e5c31af7Sopenharmony_ci { 354e5c31af7Sopenharmony_ci if ((limits.sampledImageColorSampleCounts & params.numColorSamples) == 0u) 355e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "sampledImageColorSampleCounts: sample count not supported"); 356e5c31af7Sopenharmony_ci } 357e5c31af7Sopenharmony_ci 358e5c31af7Sopenharmony_ci // In the subpass input case we have to store fetch results into a buffer for subsequent verification in a compute shader. 359e5c31af7Sopenharmony_ci const bool requireFragmentStores = (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT); 360e5c31af7Sopenharmony_ci 361e5c31af7Sopenharmony_ci if (requireFragmentStores) 362e5c31af7Sopenharmony_ci { 363e5c31af7Sopenharmony_ci if (!context.getDeviceFeatures().fragmentStoresAndAtomics) 364e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics: feature not supported"); 365e5c31af7Sopenharmony_ci } 366e5c31af7Sopenharmony_ci 367e5c31af7Sopenharmony_ci checkPipelineConstructionRequirements(vki, physicalDevice, params.pipelineConstructionType); 368e5c31af7Sopenharmony_ci} 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_ci//! Common data used by the test 371e5c31af7Sopenharmony_cistruct WorkingData 372e5c31af7Sopenharmony_ci{ 373e5c31af7Sopenharmony_ci deUint32 numVertices; //!< Number of vertices defined in the vertex buffer 374e5c31af7Sopenharmony_ci Move<VkBuffer> vertexBuffer; 375e5c31af7Sopenharmony_ci MovePtr<Allocation> vertexBufferAlloc; 376e5c31af7Sopenharmony_ci Move<VkImage> colorImage; //!< Color image 377e5c31af7Sopenharmony_ci MovePtr<Allocation> colorImageAlloc; 378e5c31af7Sopenharmony_ci Move<VkImageView> colorImageView; //!< Color image view spanning all layers 379e5c31af7Sopenharmony_ci Move<VkBuffer> colorBuffer; //!< Buffer used to copy image data 380e5c31af7Sopenharmony_ci MovePtr<Allocation> colorBufferAlloc; 381e5c31af7Sopenharmony_ci VkDeviceSize colorBufferSize; 382e5c31af7Sopenharmony_ci Move<VkSampler> defaultSampler; //!< Unused sampler, we are using texel fetches 383e5c31af7Sopenharmony_ci 384e5c31af7Sopenharmony_ci WorkingData (void) 385e5c31af7Sopenharmony_ci : numVertices () 386e5c31af7Sopenharmony_ci , colorBufferSize () 387e5c31af7Sopenharmony_ci { 388e5c31af7Sopenharmony_ci } 389e5c31af7Sopenharmony_ci}; 390e5c31af7Sopenharmony_ci 391e5c31af7Sopenharmony_civoid initPrograms (SourceCollections& programCollection, const TestParams params) 392e5c31af7Sopenharmony_ci{ 393e5c31af7Sopenharmony_ci std::string colorType; //!< color pixel type used by image functions 394e5c31af7Sopenharmony_ci std::string colorBufferType; //!< packed pixel type as stored in a ssbo 395e5c31af7Sopenharmony_ci std::string colorBufferPack; //!< a cast or a function call when writing back color format to the ssbo 396e5c31af7Sopenharmony_ci std::string colorFragInQualifier; //!< fragment shader color input qualifier 397e5c31af7Sopenharmony_ci std::string samplerPrefix; //!< u, i, or empty 398e5c31af7Sopenharmony_ci 399e5c31af7Sopenharmony_ci switch (params.colorFormat) 400e5c31af7Sopenharmony_ci { 401e5c31af7Sopenharmony_ci case VK_FORMAT_R8G8B8A8_UNORM: 402e5c31af7Sopenharmony_ci colorType = "vec4"; 403e5c31af7Sopenharmony_ci colorBufferType = "uint"; 404e5c31af7Sopenharmony_ci colorBufferPack = "packUnorm4x8"; 405e5c31af7Sopenharmony_ci break; 406e5c31af7Sopenharmony_ci 407e5c31af7Sopenharmony_ci case VK_FORMAT_R32_UINT: 408e5c31af7Sopenharmony_ci colorType = "uint"; 409e5c31af7Sopenharmony_ci colorBufferType = "uint"; 410e5c31af7Sopenharmony_ci colorBufferPack = colorBufferType; 411e5c31af7Sopenharmony_ci colorFragInQualifier = "flat"; 412e5c31af7Sopenharmony_ci samplerPrefix = "u"; 413e5c31af7Sopenharmony_ci break; 414e5c31af7Sopenharmony_ci 415e5c31af7Sopenharmony_ci case VK_FORMAT_R32_SINT: 416e5c31af7Sopenharmony_ci colorType = "int"; 417e5c31af7Sopenharmony_ci colorBufferType = "int"; 418e5c31af7Sopenharmony_ci colorBufferPack = colorBufferType; 419e5c31af7Sopenharmony_ci colorFragInQualifier = "flat"; 420e5c31af7Sopenharmony_ci samplerPrefix = "i"; 421e5c31af7Sopenharmony_ci break; 422e5c31af7Sopenharmony_ci 423e5c31af7Sopenharmony_ci default: 424e5c31af7Sopenharmony_ci DE_FATAL("initPrograms not handled for this color format"); 425e5c31af7Sopenharmony_ci break; 426e5c31af7Sopenharmony_ci } 427e5c31af7Sopenharmony_ci 428e5c31af7Sopenharmony_ci // Vertex shader - position and color 429e5c31af7Sopenharmony_ci { 430e5c31af7Sopenharmony_ci std::ostringstream src; 431e5c31af7Sopenharmony_ci src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 432e5c31af7Sopenharmony_ci << "\n" 433e5c31af7Sopenharmony_ci << "layout(location = 0) in vec4 in_position;\n" 434e5c31af7Sopenharmony_ci << "layout(location = 1) in " << colorType << " in_color;\n" 435e5c31af7Sopenharmony_ci << "layout(location = 0) out " << colorType << " o_color;\n" 436e5c31af7Sopenharmony_ci << "\n" 437e5c31af7Sopenharmony_ci << "out gl_PerVertex {\n" 438e5c31af7Sopenharmony_ci << " vec4 gl_Position;\n" 439e5c31af7Sopenharmony_ci << "};\n" 440e5c31af7Sopenharmony_ci << "\n" 441e5c31af7Sopenharmony_ci << "void main(void)\n" 442e5c31af7Sopenharmony_ci << "{\n" 443e5c31af7Sopenharmony_ci // Introduce a variance in geometry per instance index which maps to the image layer 444e5c31af7Sopenharmony_ci << " float a = 0.25 * float(gl_InstanceIndex);\n" 445e5c31af7Sopenharmony_ci << " mat3 rm = mat3( cos(a), sin(a), 0.0,\n" 446e5c31af7Sopenharmony_ci << " -sin(a), cos(a), 0.0,\n" 447e5c31af7Sopenharmony_ci << " 0.0, 0.0, 1.0);\n" 448e5c31af7Sopenharmony_ci << " vec2 rpos = (rm * vec3(in_position.xy, 1.0)).xy;\n" 449e5c31af7Sopenharmony_ci << "\n" 450e5c31af7Sopenharmony_ci << " gl_Position = vec4(rpos, in_position.zw);\n" 451e5c31af7Sopenharmony_ci << " o_color = in_color;\n" 452e5c31af7Sopenharmony_ci << "}\n"; 453e5c31af7Sopenharmony_ci 454e5c31af7Sopenharmony_ci programCollection.glslSources.add("vert") << glu::VertexSource(src.str()); 455e5c31af7Sopenharmony_ci } 456e5c31af7Sopenharmony_ci 457e5c31af7Sopenharmony_ci // Vertex shader - no vertex data, fill viewport with one primitive 458e5c31af7Sopenharmony_ci { 459e5c31af7Sopenharmony_ci std::ostringstream src; 460e5c31af7Sopenharmony_ci src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 461e5c31af7Sopenharmony_ci << "\n" 462e5c31af7Sopenharmony_ci << "out gl_PerVertex {\n" 463e5c31af7Sopenharmony_ci << " vec4 gl_Position;\n" 464e5c31af7Sopenharmony_ci << "};\n" 465e5c31af7Sopenharmony_ci << "\n" 466e5c31af7Sopenharmony_ci << "void main(void)\n" 467e5c31af7Sopenharmony_ci << "{\n" 468e5c31af7Sopenharmony_ci // Specify an oversized triangle covering the whole viewport. 469e5c31af7Sopenharmony_ci << " switch (gl_VertexIndex)\n" 470e5c31af7Sopenharmony_ci << " {\n" 471e5c31af7Sopenharmony_ci << " case 0:\n" 472e5c31af7Sopenharmony_ci << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 473e5c31af7Sopenharmony_ci << " break;\n" 474e5c31af7Sopenharmony_ci << " case 1:\n" 475e5c31af7Sopenharmony_ci << " gl_Position = vec4(-1.0, 3.0, 0.0, 1.0);\n" 476e5c31af7Sopenharmony_ci << " break;\n" 477e5c31af7Sopenharmony_ci << " case 2:\n" 478e5c31af7Sopenharmony_ci << " gl_Position = vec4( 3.0, -1.0, 0.0, 1.0);\n" 479e5c31af7Sopenharmony_ci << " break;\n" 480e5c31af7Sopenharmony_ci << " }\n" 481e5c31af7Sopenharmony_ci << "}\n"; 482e5c31af7Sopenharmony_ci 483e5c31af7Sopenharmony_ci programCollection.glslSources.add("vert_full") << glu::VertexSource(src.str()); 484e5c31af7Sopenharmony_ci } 485e5c31af7Sopenharmony_ci 486e5c31af7Sopenharmony_ci // Fragment shader - output color from VS 487e5c31af7Sopenharmony_ci { 488e5c31af7Sopenharmony_ci std::ostringstream src; 489e5c31af7Sopenharmony_ci src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 490e5c31af7Sopenharmony_ci << "\n" 491e5c31af7Sopenharmony_ci << "layout(location = 0) in " << colorFragInQualifier << " " << colorType << " in_color;\n" 492e5c31af7Sopenharmony_ci << "layout(location = 0) out " << colorType << " o_color;\n" 493e5c31af7Sopenharmony_ci << "\n" 494e5c31af7Sopenharmony_ci << "void main(void)\n" 495e5c31af7Sopenharmony_ci << "{\n" 496e5c31af7Sopenharmony_ci << " o_color = in_color;\n" 497e5c31af7Sopenharmony_ci << "}\n"; 498e5c31af7Sopenharmony_ci 499e5c31af7Sopenharmony_ci programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()); 500e5c31af7Sopenharmony_ci } 501e5c31af7Sopenharmony_ci 502e5c31af7Sopenharmony_ci // Fragment shader - FMASK fetch from an input attachment 503e5c31af7Sopenharmony_ci if (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT) 504e5c31af7Sopenharmony_ci { 505e5c31af7Sopenharmony_ci std::ostringstream src; 506e5c31af7Sopenharmony_ci src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 507e5c31af7Sopenharmony_ci << "#extension GL_AMD_shader_fragment_mask : enable\n" 508e5c31af7Sopenharmony_ci << "\n" 509e5c31af7Sopenharmony_ci << "layout(set = 0, binding = 0) uniform " << samplerPrefix << "sampler2DMS" << (params.numLayers > 1 ? "Array" : "") << " u_image;\n" 510e5c31af7Sopenharmony_ci << "layout(set = 0, binding = 1, std430) writeonly buffer ColorOutput {\n" 511e5c31af7Sopenharmony_ci << " " << colorBufferType << " color[];\n" 512e5c31af7Sopenharmony_ci << "} sb_out;\n" 513e5c31af7Sopenharmony_ci << "layout(input_attachment_index = 0, set = 0, binding = 2) uniform " << samplerPrefix << "subpassInputMS" << " input_attach;\n" 514e5c31af7Sopenharmony_ci << "\n" 515e5c31af7Sopenharmony_ci << "void main(void)\n" 516e5c31af7Sopenharmony_ci << "{\n" 517e5c31af7Sopenharmony_ci << " ivec2 p = ivec2(gl_FragCoord.xy);\n" 518e5c31af7Sopenharmony_ci << " int width = " << params.renderSize.x() << ";\n" 519e5c31af7Sopenharmony_ci << " int numSamples = " << static_cast<deUint32>(params.numColorSamples) << ";\n" 520e5c31af7Sopenharmony_ci << " int colorOutNdx = numSamples * (p.x + width * p.y);\n" 521e5c31af7Sopenharmony_ci << "\n" 522e5c31af7Sopenharmony_ci << " uint mask = fragmentMaskFetchAMD(input_attach);\n" 523e5c31af7Sopenharmony_ci << " for (int sampleNdx = 0; sampleNdx < numSamples; ++sampleNdx)\n" 524e5c31af7Sopenharmony_ci << " {\n" 525e5c31af7Sopenharmony_ci << " int fragNdx = int((mask >> (4 * sampleNdx)) & 0xf);\n" 526e5c31af7Sopenharmony_ci << " " << samplerPrefix << "vec4 color = fragmentFetchAMD(input_attach, fragNdx);\n" 527e5c31af7Sopenharmony_ci << " sb_out.color[colorOutNdx + sampleNdx] = " << colorBufferPack << "(color);\n" 528e5c31af7Sopenharmony_ci << " }\n" 529e5c31af7Sopenharmony_ci << "}\n"; 530e5c31af7Sopenharmony_ci 531e5c31af7Sopenharmony_ci programCollection.glslSources.add("frag_fmask_fetch") << glu::FragmentSource(src.str()); 532e5c31af7Sopenharmony_ci } 533e5c31af7Sopenharmony_ci 534e5c31af7Sopenharmony_ci // Generate compute shaders 535e5c31af7Sopenharmony_ci const struct ComputeShaderParams 536e5c31af7Sopenharmony_ci { 537e5c31af7Sopenharmony_ci const char* name; 538e5c31af7Sopenharmony_ci bool isFmaskFetch; 539e5c31af7Sopenharmony_ci bool enabled; 540e5c31af7Sopenharmony_ci } computeShaders[] = 541e5c31af7Sopenharmony_ci { 542e5c31af7Sopenharmony_ci // name // FMASK? // enabled? 543e5c31af7Sopenharmony_ci { "comp_fetch", false, true, }, 544e5c31af7Sopenharmony_ci { "comp_fmask_fetch", true, (params.sampleSource != SAMPLE_SOURCE_SUBPASS_INPUT) }, 545e5c31af7Sopenharmony_ci }; 546e5c31af7Sopenharmony_ci 547e5c31af7Sopenharmony_ci for (const ComputeShaderParams* pShaderParams = computeShaders; pShaderParams != DE_ARRAY_END(computeShaders); ++pShaderParams) 548e5c31af7Sopenharmony_ci if (pShaderParams->enabled) 549e5c31af7Sopenharmony_ci { 550e5c31af7Sopenharmony_ci const std::string samplingPos = (params.numLayers == 1 ? "ivec2(gl_WorkGroupID.xy)" 551e5c31af7Sopenharmony_ci : "ivec3(gl_WorkGroupID)"); 552e5c31af7Sopenharmony_ci std::ostringstream src; 553e5c31af7Sopenharmony_ci src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 554e5c31af7Sopenharmony_ci << (pShaderParams->isFmaskFetch ? "#extension GL_AMD_shader_fragment_mask : enable\n" : "") 555e5c31af7Sopenharmony_ci << "#define NUM_SAMPLES " << static_cast<deUint32>(params.numColorSamples) << "\n" 556e5c31af7Sopenharmony_ci << "\n" 557e5c31af7Sopenharmony_ci << "layout(local_size_x = NUM_SAMPLES) in;\n" // one work group per pixel, each sample gets a local invocation 558e5c31af7Sopenharmony_ci << "\n" 559e5c31af7Sopenharmony_ci << "layout(set = 0, binding = 0) uniform " << samplerPrefix << "sampler2DMS" << (params.numLayers > 1 ? "Array" : "") << " u_image;\n" 560e5c31af7Sopenharmony_ci << "layout(set = 0, binding = 1, std430) writeonly buffer ColorOutput {\n" 561e5c31af7Sopenharmony_ci << " " << colorBufferType << " color[];\n" 562e5c31af7Sopenharmony_ci << "} sb_out;\n" 563e5c31af7Sopenharmony_ci << "\n" 564e5c31af7Sopenharmony_ci << "void main(void)\n" 565e5c31af7Sopenharmony_ci << "{\n" 566e5c31af7Sopenharmony_ci << " int sampleNdx = int(gl_LocalInvocationID.x);\n" 567e5c31af7Sopenharmony_ci << " int colorOutNdx = NUM_SAMPLES * int(gl_WorkGroupID.x +\n" 568e5c31af7Sopenharmony_ci << " gl_WorkGroupID.y * gl_NumWorkGroups.x +\n" 569e5c31af7Sopenharmony_ci << " gl_WorkGroupID.z * gl_NumWorkGroups.x * gl_NumWorkGroups.y);\n" 570e5c31af7Sopenharmony_ci << "\n"; 571e5c31af7Sopenharmony_ci if (pShaderParams->isFmaskFetch) 572e5c31af7Sopenharmony_ci { 573e5c31af7Sopenharmony_ci src << " uint mask = fragmentMaskFetchAMD(u_image, " << samplingPos << ");\n" 574e5c31af7Sopenharmony_ci << " int fragNdx = int((mask >> (4 * sampleNdx)) & 0xf);\n" 575e5c31af7Sopenharmony_ci << " " << samplerPrefix << "vec4 color = fragmentFetchAMD(u_image, " << samplingPos << ", fragNdx);\n" 576e5c31af7Sopenharmony_ci << " sb_out.color[colorOutNdx + sampleNdx] = " << colorBufferPack << "(color);\n"; 577e5c31af7Sopenharmony_ci } 578e5c31af7Sopenharmony_ci else 579e5c31af7Sopenharmony_ci { 580e5c31af7Sopenharmony_ci src << " " << samplerPrefix << "vec4 color = texelFetch(u_image, " << samplingPos << ", sampleNdx);\n" 581e5c31af7Sopenharmony_ci << " sb_out.color[colorOutNdx + sampleNdx] = " << colorBufferPack << "(color);\n"; 582e5c31af7Sopenharmony_ci } 583e5c31af7Sopenharmony_ci src << "}\n"; 584e5c31af7Sopenharmony_ci 585e5c31af7Sopenharmony_ci programCollection.glslSources.add(pShaderParams->name) << glu::ComputeSource(src.str()); 586e5c31af7Sopenharmony_ci } 587e5c31af7Sopenharmony_ci} 588e5c31af7Sopenharmony_ci 589e5c31af7Sopenharmony_cistd::vector<VkClearValue> genClearValues (const VkFormat format, const deUint32 count) 590e5c31af7Sopenharmony_ci{ 591e5c31af7Sopenharmony_ci std::vector<VkClearValue> clearValues; 592e5c31af7Sopenharmony_ci de::Random rng (332); 593e5c31af7Sopenharmony_ci 594e5c31af7Sopenharmony_ci switch (format) 595e5c31af7Sopenharmony_ci { 596e5c31af7Sopenharmony_ci case VK_FORMAT_R8G8B8A8_UNORM: 597e5c31af7Sopenharmony_ci for (deUint32 i = 0u; i < count; ++i) 598e5c31af7Sopenharmony_ci clearValues.push_back(makeClearValueColorF32(rng.getFloat(), rng.getFloat(), rng.getFloat(), 1.0f)); 599e5c31af7Sopenharmony_ci break; 600e5c31af7Sopenharmony_ci 601e5c31af7Sopenharmony_ci case VK_FORMAT_R32_UINT: 602e5c31af7Sopenharmony_ci case VK_FORMAT_R32_SINT: 603e5c31af7Sopenharmony_ci for (deUint32 i = 0u; i < count; ++i) 604e5c31af7Sopenharmony_ci clearValues.push_back(makeClearValueColorU32(rng.getUint32(), 0u, 0u, 0u)); 605e5c31af7Sopenharmony_ci break; 606e5c31af7Sopenharmony_ci 607e5c31af7Sopenharmony_ci default: 608e5c31af7Sopenharmony_ci DE_FATAL("Clear color not defined for this format"); 609e5c31af7Sopenharmony_ci break; 610e5c31af7Sopenharmony_ci } 611e5c31af7Sopenharmony_ci 612e5c31af7Sopenharmony_ci return clearValues; 613e5c31af7Sopenharmony_ci} 614e5c31af7Sopenharmony_ci 615e5c31af7Sopenharmony_ci//! For subpass load case draw and fetch must happen within the same render pass. 616e5c31af7Sopenharmony_civoid drawAndSampleInputAttachment (Context& context, const TestParams& params, WorkingData& wd) 617e5c31af7Sopenharmony_ci{ 618e5c31af7Sopenharmony_ci DE_ASSERT(params.numLayers == 1u); // subpass load with single-layer image 619e5c31af7Sopenharmony_ci 620e5c31af7Sopenharmony_ci const InstanceInterface& vki = context.getInstanceInterface(); 621e5c31af7Sopenharmony_ci const DeviceInterface& vk = SingletonDevice::getDeviceInterface(context); 622e5c31af7Sopenharmony_ci const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 623e5c31af7Sopenharmony_ci const VkDevice device = SingletonDevice::getDevice(context); 624e5c31af7Sopenharmony_ci 625e5c31af7Sopenharmony_ci RenderPassWrapper renderPass; 626e5c31af7Sopenharmony_ci 627e5c31af7Sopenharmony_ci // Create descriptor set 628e5c31af7Sopenharmony_ci const Unique<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder() 629e5c31af7Sopenharmony_ci .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &wd.defaultSampler.get()) 630e5c31af7Sopenharmony_ci .addSingleBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT) 631e5c31af7Sopenharmony_ci .addSingleBinding (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT) 632e5c31af7Sopenharmony_ci .build(vk, device)); 633e5c31af7Sopenharmony_ci 634e5c31af7Sopenharmony_ci const Unique<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder() 635e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 636e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) 637e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) 638e5c31af7Sopenharmony_ci .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); 639e5c31af7Sopenharmony_ci 640e5c31af7Sopenharmony_ci const Unique<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); 641e5c31af7Sopenharmony_ci 642e5c31af7Sopenharmony_ci { 643e5c31af7Sopenharmony_ci const VkDescriptorImageInfo colorImageInfo = makeDescriptorImageInfo(DE_NULL, *wd.colorImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 644e5c31af7Sopenharmony_ci const VkDescriptorBufferInfo bufferInfo = makeDescriptorBufferInfo(*wd.colorBuffer, 0u, wd.colorBufferSize); 645e5c31af7Sopenharmony_ci 646e5c31af7Sopenharmony_ci DescriptorSetUpdateBuilder builder; 647e5c31af7Sopenharmony_ci 648e5c31af7Sopenharmony_ci builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &colorImageInfo); 649e5c31af7Sopenharmony_ci builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo); 650e5c31af7Sopenharmony_ci 651e5c31af7Sopenharmony_ci if (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT) 652e5c31af7Sopenharmony_ci builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &colorImageInfo); 653e5c31af7Sopenharmony_ci 654e5c31af7Sopenharmony_ci builder.update(vk, device); 655e5c31af7Sopenharmony_ci } 656e5c31af7Sopenharmony_ci 657e5c31af7Sopenharmony_ci // Create a render pass and a framebuffer 658e5c31af7Sopenharmony_ci { 659e5c31af7Sopenharmony_ci std::vector<VkSubpassDescription> subpasses; 660e5c31af7Sopenharmony_ci std::vector<VkSubpassDependency> subpassDependencies; 661e5c31af7Sopenharmony_ci std::vector<VkImage> images; 662e5c31af7Sopenharmony_ci std::vector<VkImageView> attachments; 663e5c31af7Sopenharmony_ci std::vector<VkAttachmentDescription> attachmentDescriptions; 664e5c31af7Sopenharmony_ci std::vector<VkAttachmentReference> attachmentReferences; 665e5c31af7Sopenharmony_ci 666e5c31af7Sopenharmony_ci // Reserve capacity to avoid invalidating pointers to elements 667e5c31af7Sopenharmony_ci attachmentReferences.reserve(2); // color image + input attachment 668e5c31af7Sopenharmony_ci 669e5c31af7Sopenharmony_ci // Create a MS draw subpass 670e5c31af7Sopenharmony_ci { 671e5c31af7Sopenharmony_ci images.push_back(*wd.colorImage); 672e5c31af7Sopenharmony_ci attachments.push_back(*wd.colorImageView); 673e5c31af7Sopenharmony_ci 674e5c31af7Sopenharmony_ci attachmentDescriptions.push_back(makeAttachmentDescription( 675e5c31af7Sopenharmony_ci (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 676e5c31af7Sopenharmony_ci params.colorFormat, // VkFormat format; 677e5c31af7Sopenharmony_ci params.numColorSamples, // VkSampleCountFlagBits samples; 678e5c31af7Sopenharmony_ci VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 679e5c31af7Sopenharmony_ci VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 680e5c31af7Sopenharmony_ci VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 681e5c31af7Sopenharmony_ci VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 682e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 683e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout; 684e5c31af7Sopenharmony_ci )); 685e5c31af7Sopenharmony_ci 686e5c31af7Sopenharmony_ci attachmentReferences.push_back(makeAttachmentReference(static_cast<deUint32>(attachmentReferences.size()), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 687e5c31af7Sopenharmony_ci const VkAttachmentReference* colorRef = &attachmentReferences.back(); 688e5c31af7Sopenharmony_ci 689e5c31af7Sopenharmony_ci const VkSubpassDescription subpassDescription = 690e5c31af7Sopenharmony_ci { 691e5c31af7Sopenharmony_ci (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; 692e5c31af7Sopenharmony_ci VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 693e5c31af7Sopenharmony_ci 0u, // uint32_t inputAttachmentCount; 694e5c31af7Sopenharmony_ci DE_NULL, // const VkAttachmentReference* pInputAttachments; 695e5c31af7Sopenharmony_ci 1u, // uint32_t colorAttachmentCount; 696e5c31af7Sopenharmony_ci colorRef, // const VkAttachmentReference* pColorAttachments; 697e5c31af7Sopenharmony_ci DE_NULL, // const VkAttachmentReference* pResolveAttachments; 698e5c31af7Sopenharmony_ci DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 699e5c31af7Sopenharmony_ci 0u, // uint32_t preserveAttachmentCount; 700e5c31af7Sopenharmony_ci DE_NULL, // const uint32_t* pPreserveAttachments; 701e5c31af7Sopenharmony_ci }; 702e5c31af7Sopenharmony_ci 703e5c31af7Sopenharmony_ci subpasses.push_back(subpassDescription); 704e5c31af7Sopenharmony_ci } 705e5c31af7Sopenharmony_ci 706e5c31af7Sopenharmony_ci // Create a sampling subpass 707e5c31af7Sopenharmony_ci { 708e5c31af7Sopenharmony_ci attachmentReferences.push_back(makeAttachmentReference(0u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)); 709e5c31af7Sopenharmony_ci const VkAttachmentReference* inputRef = &attachmentReferences.back(); 710e5c31af7Sopenharmony_ci 711e5c31af7Sopenharmony_ci // No color attachment, side effects only 712e5c31af7Sopenharmony_ci VkSubpassDescription subpassDescription = 713e5c31af7Sopenharmony_ci { 714e5c31af7Sopenharmony_ci (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; 715e5c31af7Sopenharmony_ci VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 716e5c31af7Sopenharmony_ci 1u, // uint32_t inputAttachmentCount; 717e5c31af7Sopenharmony_ci inputRef, // const VkAttachmentReference* pInputAttachments; 718e5c31af7Sopenharmony_ci 0u, // uint32_t colorAttachmentCount; 719e5c31af7Sopenharmony_ci DE_NULL, // const VkAttachmentReference* pColorAttachments; 720e5c31af7Sopenharmony_ci DE_NULL, // const VkAttachmentReference* pResolveAttachments; 721e5c31af7Sopenharmony_ci DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 722e5c31af7Sopenharmony_ci 0u, // uint32_t preserveAttachmentCount; 723e5c31af7Sopenharmony_ci DE_NULL, // const uint32_t* pPreserveAttachments; 724e5c31af7Sopenharmony_ci }; 725e5c31af7Sopenharmony_ci 726e5c31af7Sopenharmony_ci subpasses.push_back(subpassDescription); 727e5c31af7Sopenharmony_ci } 728e5c31af7Sopenharmony_ci 729e5c31af7Sopenharmony_ci // Serialize the subpasses 730e5c31af7Sopenharmony_ci { 731e5c31af7Sopenharmony_ci const VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT 732e5c31af7Sopenharmony_ci | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT 733e5c31af7Sopenharmony_ci | VK_ACCESS_SHADER_WRITE_BIT; 734e5c31af7Sopenharmony_ci const VkSubpassDependency dependency = 735e5c31af7Sopenharmony_ci { 736e5c31af7Sopenharmony_ci 0u, // uint32_t srcSubpass; 737e5c31af7Sopenharmony_ci 1u, // uint32_t dstSubpass; 738e5c31af7Sopenharmony_ci VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask; 739e5c31af7Sopenharmony_ci VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags dstStageMask; 740e5c31af7Sopenharmony_ci VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; 741e5c31af7Sopenharmony_ci dstAccessMask, // VkAccessFlags dstAccessMask; 742e5c31af7Sopenharmony_ci VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags; 743e5c31af7Sopenharmony_ci }; 744e5c31af7Sopenharmony_ci subpassDependencies.push_back(dependency); 745e5c31af7Sopenharmony_ci } 746e5c31af7Sopenharmony_ci 747e5c31af7Sopenharmony_ci VkRenderPassCreateInfo renderPassInfo = 748e5c31af7Sopenharmony_ci { 749e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 750e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 751e5c31af7Sopenharmony_ci (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; 752e5c31af7Sopenharmony_ci static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount; 753e5c31af7Sopenharmony_ci dataOrNullPtr(attachmentDescriptions), // const VkAttachmentDescription* pAttachments; 754e5c31af7Sopenharmony_ci static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount; 755e5c31af7Sopenharmony_ci dataOrNullPtr(subpasses), // const VkSubpassDescription* pSubpasses; 756e5c31af7Sopenharmony_ci static_cast<deUint32>(subpassDependencies.size()), // deUint32 dependencyCount; 757e5c31af7Sopenharmony_ci dataOrNullPtr(subpassDependencies), // const VkSubpassDependency* pDependencies; 758e5c31af7Sopenharmony_ci }; 759e5c31af7Sopenharmony_ci 760e5c31af7Sopenharmony_ci renderPass = RenderPassWrapper(params.pipelineConstructionType, vk, device, &renderPassInfo); 761e5c31af7Sopenharmony_ci renderPass.createFramebuffer(vk, device, static_cast<deUint32>(attachments.size()), dataOrNullPtr(images), dataOrNullPtr(attachments), params.renderSize.x(), params.renderSize.y()); 762e5c31af7Sopenharmony_ci } 763e5c31af7Sopenharmony_ci 764e5c31af7Sopenharmony_ci const std::vector<VkViewport> viewports { makeViewport(params.renderSize) }; 765e5c31af7Sopenharmony_ci const std::vector<VkRect2D> scissors { makeRect2D(params.renderSize) }; 766e5c31af7Sopenharmony_ci 767e5c31af7Sopenharmony_ci VkPipelineMultisampleStateCreateInfo multisampleStateInfo 768e5c31af7Sopenharmony_ci { 769e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 770e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 771e5c31af7Sopenharmony_ci (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags; 772e5c31af7Sopenharmony_ci params.numColorSamples, // VkSampleCountFlagBits rasterizationSamples; 773e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 sampleShadingEnable; 774e5c31af7Sopenharmony_ci 1.0f, // float minSampleShading; 775e5c31af7Sopenharmony_ci DE_NULL, // const VkSampleMask* pSampleMask; 776e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 alphaToCoverageEnable; 777e5c31af7Sopenharmony_ci VK_FALSE // VkBool32 alphaToOneEnable; 778e5c31af7Sopenharmony_ci }; 779e5c31af7Sopenharmony_ci 780e5c31af7Sopenharmony_ci const VkPipelineColorBlendAttachmentState defaultBlendAttachmentState 781e5c31af7Sopenharmony_ci { 782e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 blendEnable; 783e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 784e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 785e5c31af7Sopenharmony_ci VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 786e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 787e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 788e5c31af7Sopenharmony_ci VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 789e5c31af7Sopenharmony_ci 0xf, // VkColorComponentFlags colorWriteMask; 790e5c31af7Sopenharmony_ci }; 791e5c31af7Sopenharmony_ci 792e5c31af7Sopenharmony_ci VkPipelineColorBlendStateCreateInfo colorBlendStateInfo 793e5c31af7Sopenharmony_ci { 794e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 795e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 796e5c31af7Sopenharmony_ci (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; 797e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 logicOpEnable; 798e5c31af7Sopenharmony_ci VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 799e5c31af7Sopenharmony_ci 1u, // deUint32 attachmentCount; 800e5c31af7Sopenharmony_ci &defaultBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 801e5c31af7Sopenharmony_ci { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 802e5c31af7Sopenharmony_ci }; 803e5c31af7Sopenharmony_ci 804e5c31af7Sopenharmony_ci const ShaderWrapper vertexModuleDraw (ShaderWrapper(vk, device, context.getBinaryCollection().get("vert"), 0u)); 805e5c31af7Sopenharmony_ci const ShaderWrapper fragmentModuleDraw (ShaderWrapper(vk, device, context.getBinaryCollection().get("frag"), 0u)); 806e5c31af7Sopenharmony_ci 807e5c31af7Sopenharmony_ci // Create pipelines for MS draw 808e5c31af7Sopenharmony_ci const PipelineLayoutWrapper pipelineLayout (params.pipelineConstructionType, vk, device, *descriptorSetLayout); 809e5c31af7Sopenharmony_ci GraphicsPipelineWrapper pipelineDraw (vki, vk, physicalDevice, device, context.getDeviceExtensions(), params.pipelineConstructionType); 810e5c31af7Sopenharmony_ci { 811e5c31af7Sopenharmony_ci // Vertex attributes: position and color 812e5c31af7Sopenharmony_ci VkVertexInputBindingDescription vertexInputBindingDescriptions = makeVertexInputBindingDescription(0u, sizeof(PositionColor), VK_VERTEX_INPUT_RATE_VERTEX); 813e5c31af7Sopenharmony_ci std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescriptions 814e5c31af7Sopenharmony_ci { 815e5c31af7Sopenharmony_ci makeVertexInputAttributeDescription(0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, 0u), 816e5c31af7Sopenharmony_ci makeVertexInputAttributeDescription(1u, 0u, getVertexInputColorFormat(params.colorFormat), sizeof(Vec4)) 817e5c31af7Sopenharmony_ci }; 818e5c31af7Sopenharmony_ci 819e5c31af7Sopenharmony_ci const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo 820e5c31af7Sopenharmony_ci { 821e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 822e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 823e5c31af7Sopenharmony_ci (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 824e5c31af7Sopenharmony_ci 1u, // uint32_t vertexBindingDescriptionCount; 825e5c31af7Sopenharmony_ci &vertexInputBindingDescriptions, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 826e5c31af7Sopenharmony_ci static_cast<deUint32>(vertexInputAttributeDescriptions.size()), // uint32_t vertexAttributeDescriptionCount; 827e5c31af7Sopenharmony_ci vertexInputAttributeDescriptions.data(), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 828e5c31af7Sopenharmony_ci }; 829e5c31af7Sopenharmony_ci 830e5c31af7Sopenharmony_ci pipelineDraw.setDefaultRasterizationState() 831e5c31af7Sopenharmony_ci .setDefaultDepthStencilState() 832e5c31af7Sopenharmony_ci .setupVertexInputState(&vertexInputStateInfo) 833e5c31af7Sopenharmony_ci .setupPreRasterizationShaderState(viewports, 834e5c31af7Sopenharmony_ci scissors, 835e5c31af7Sopenharmony_ci pipelineLayout, 836e5c31af7Sopenharmony_ci *renderPass, 837e5c31af7Sopenharmony_ci 0u, 838e5c31af7Sopenharmony_ci vertexModuleDraw) 839e5c31af7Sopenharmony_ci .setupFragmentShaderState(pipelineLayout, *renderPass, 0u, fragmentModuleDraw, DE_NULL, &multisampleStateInfo) 840e5c31af7Sopenharmony_ci .setupFragmentOutputState(*renderPass, 0u, &colorBlendStateInfo, &multisampleStateInfo) 841e5c31af7Sopenharmony_ci .setMonolithicPipelineLayout(pipelineLayout) 842e5c31af7Sopenharmony_ci .buildPipeline(); 843e5c31af7Sopenharmony_ci } 844e5c31af7Sopenharmony_ci 845e5c31af7Sopenharmony_ci // Sampling pass is single-sampled, output to storage buffer 846e5c31af7Sopenharmony_ci const ShaderWrapper vertexModuleSample (ShaderWrapper(vk, device, context.getBinaryCollection().get("vert_full"), 0u)); 847e5c31af7Sopenharmony_ci const ShaderWrapper fragmentModuleSample (ShaderWrapper(vk, device, context.getBinaryCollection().get("frag_fmask_fetch"), 0u)); 848e5c31af7Sopenharmony_ci 849e5c31af7Sopenharmony_ci // Sampling pipeline 850e5c31af7Sopenharmony_ci GraphicsPipelineWrapper pipelineSample(vki, vk, physicalDevice, device, context.getDeviceExtensions(), params.pipelineConstructionType); 851e5c31af7Sopenharmony_ci { 852e5c31af7Sopenharmony_ci VkPipelineVertexInputStateCreateInfo vertexInputStateInfo; 853e5c31af7Sopenharmony_ci deMemset(&vertexInputStateInfo, 0, sizeof(vertexInputStateInfo)); 854e5c31af7Sopenharmony_ci vertexInputStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 855e5c31af7Sopenharmony_ci 856e5c31af7Sopenharmony_ci multisampleStateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 857e5c31af7Sopenharmony_ci colorBlendStateInfo.attachmentCount = 0u; 858e5c31af7Sopenharmony_ci 859e5c31af7Sopenharmony_ci pipelineSample.setDefaultRasterizationState() 860e5c31af7Sopenharmony_ci .setDefaultDepthStencilState() 861e5c31af7Sopenharmony_ci .setupVertexInputState(&vertexInputStateInfo) 862e5c31af7Sopenharmony_ci .setupPreRasterizationShaderState(viewports, 863e5c31af7Sopenharmony_ci scissors, 864e5c31af7Sopenharmony_ci pipelineLayout, 865e5c31af7Sopenharmony_ci *renderPass, 866e5c31af7Sopenharmony_ci 1u, 867e5c31af7Sopenharmony_ci vertexModuleSample) 868e5c31af7Sopenharmony_ci .setupFragmentShaderState(pipelineLayout, *renderPass, 1u, fragmentModuleSample, DE_NULL, &multisampleStateInfo) 869e5c31af7Sopenharmony_ci .setupFragmentOutputState(*renderPass, 1u, &colorBlendStateInfo, &multisampleStateInfo) 870e5c31af7Sopenharmony_ci .setMonolithicPipelineLayout(pipelineLayout) 871e5c31af7Sopenharmony_ci .buildPipeline(); 872e5c31af7Sopenharmony_ci } 873e5c31af7Sopenharmony_ci 874e5c31af7Sopenharmony_ci const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex())); 875e5c31af7Sopenharmony_ci const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); 876e5c31af7Sopenharmony_ci 877e5c31af7Sopenharmony_ci beginCommandBuffer(vk, *cmdBuffer); 878e5c31af7Sopenharmony_ci 879e5c31af7Sopenharmony_ci { 880e5c31af7Sopenharmony_ci // Generate clear values 881e5c31af7Sopenharmony_ci std::vector<VkClearValue> clearValues = genClearValues(params.colorFormat, params.numLayers); 882e5c31af7Sopenharmony_ci 883e5c31af7Sopenharmony_ci const VkRect2D renderArea = 884e5c31af7Sopenharmony_ci { 885e5c31af7Sopenharmony_ci { 0u, 0u }, 886e5c31af7Sopenharmony_ci { params.renderSize.x(), params.renderSize.y() } 887e5c31af7Sopenharmony_ci }; 888e5c31af7Sopenharmony_ci renderPass.begin(vk, *cmdBuffer, renderArea, static_cast<deUint32>(clearValues.size()), dataOrNullPtr(clearValues)); 889e5c31af7Sopenharmony_ci } 890e5c31af7Sopenharmony_ci 891e5c31af7Sopenharmony_ci vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); 892e5c31af7Sopenharmony_ci 893e5c31af7Sopenharmony_ci { 894e5c31af7Sopenharmony_ci const VkDeviceSize vertexBufferOffset = 0ull; 895e5c31af7Sopenharmony_ci vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &wd.vertexBuffer.get(), &vertexBufferOffset); 896e5c31af7Sopenharmony_ci } 897e5c31af7Sopenharmony_ci 898e5c31af7Sopenharmony_ci pipelineDraw.bind(*cmdBuffer); 899e5c31af7Sopenharmony_ci vk.cmdDraw(*cmdBuffer, wd.numVertices, 1u, 0u, 0u); 900e5c31af7Sopenharmony_ci 901e5c31af7Sopenharmony_ci renderPass.nextSubpass(vk, *cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); 902e5c31af7Sopenharmony_ci 903e5c31af7Sopenharmony_ci pipelineSample.bind(*cmdBuffer); 904e5c31af7Sopenharmony_ci vk.cmdDraw(*cmdBuffer, 3u, 1u, 0u, 0u); // fill the framebuffer, geometry defined in the VS 905e5c31af7Sopenharmony_ci 906e5c31af7Sopenharmony_ci renderPass.end(vk, *cmdBuffer); 907e5c31af7Sopenharmony_ci 908e5c31af7Sopenharmony_ci // Buffer write barrier 909e5c31af7Sopenharmony_ci { 910e5c31af7Sopenharmony_ci const VkBufferMemoryBarrier barrier = 911e5c31af7Sopenharmony_ci { 912e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 913e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 914e5c31af7Sopenharmony_ci VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask; 915e5c31af7Sopenharmony_ci VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 916e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 917e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 918e5c31af7Sopenharmony_ci *wd.colorBuffer, // VkBuffer buffer; 919e5c31af7Sopenharmony_ci 0ull, // VkDeviceSize offset; 920e5c31af7Sopenharmony_ci VK_WHOLE_SIZE, // VkDeviceSize size; 921e5c31af7Sopenharmony_ci }; 922e5c31af7Sopenharmony_ci 923e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, DE_NULL, 1u, &barrier, DE_NULL, 0u); 924e5c31af7Sopenharmony_ci } 925e5c31af7Sopenharmony_ci 926e5c31af7Sopenharmony_ci VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 927e5c31af7Sopenharmony_ci submitCommandsAndWait(vk, device, SingletonDevice::getUniversalQueue(context), *cmdBuffer); 928e5c31af7Sopenharmony_ci 929e5c31af7Sopenharmony_ci invalidateMappedMemoryRange(vk, device, wd.colorBufferAlloc->getMemory(), wd.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE); 930e5c31af7Sopenharmony_ci} 931e5c31af7Sopenharmony_ci 932e5c31af7Sopenharmony_ci//! Only draw a multisampled image 933e5c31af7Sopenharmony_civoid draw (Context& context, const TestParams& params, WorkingData& wd) 934e5c31af7Sopenharmony_ci{ 935e5c31af7Sopenharmony_ci const InstanceInterface & vki = context.getInstanceInterface(); 936e5c31af7Sopenharmony_ci const DeviceInterface& vk = SingletonDevice::getDeviceInterface(context); 937e5c31af7Sopenharmony_ci const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 938e5c31af7Sopenharmony_ci const VkDevice device = SingletonDevice::getDevice(context); 939e5c31af7Sopenharmony_ci 940e5c31af7Sopenharmony_ci std::vector<ImageViewSp> imageViews; 941e5c31af7Sopenharmony_ci RenderPassWrapper renderPass; 942e5c31af7Sopenharmony_ci 943e5c31af7Sopenharmony_ci // Create color attachments 944e5c31af7Sopenharmony_ci for (deUint32 layerNdx = 0u; layerNdx < params.numLayers; ++layerNdx) 945e5c31af7Sopenharmony_ci { 946e5c31af7Sopenharmony_ci imageViews.push_back(ImageViewSp(new Unique<VkImageView>( 947e5c31af7Sopenharmony_ci makeImageView(vk, device, *wd.colorImage, VK_IMAGE_VIEW_TYPE_2D, params.colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, layerNdx, 1u))))); 948e5c31af7Sopenharmony_ci } 949e5c31af7Sopenharmony_ci 950e5c31af7Sopenharmony_ci // Create a render pass and a framebuffer 951e5c31af7Sopenharmony_ci { 952e5c31af7Sopenharmony_ci std::vector<VkSubpassDescription> subpasses; 953e5c31af7Sopenharmony_ci std::vector<VkImage> images; 954e5c31af7Sopenharmony_ci std::vector<VkImageView> attachments; 955e5c31af7Sopenharmony_ci std::vector<VkAttachmentDescription> attachmentDescriptions; 956e5c31af7Sopenharmony_ci std::vector<VkAttachmentReference> attachmentReferences; 957e5c31af7Sopenharmony_ci 958e5c31af7Sopenharmony_ci // Reserve capacity to avoid invalidating pointers to elements 959e5c31af7Sopenharmony_ci attachmentReferences.reserve(params.numLayers); 960e5c31af7Sopenharmony_ci 961e5c31af7Sopenharmony_ci // Create MS draw subpasses 962e5c31af7Sopenharmony_ci for (deUint32 layerNdx = 0u; layerNdx < params.numLayers; ++layerNdx) 963e5c31af7Sopenharmony_ci { 964e5c31af7Sopenharmony_ci images.push_back(*wd.colorImage); 965e5c31af7Sopenharmony_ci attachments.push_back(**imageViews[layerNdx]); 966e5c31af7Sopenharmony_ci 967e5c31af7Sopenharmony_ci attachmentDescriptions.push_back(makeAttachmentDescription( 968e5c31af7Sopenharmony_ci (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 969e5c31af7Sopenharmony_ci params.colorFormat, // VkFormat format; 970e5c31af7Sopenharmony_ci params.numColorSamples, // VkSampleCountFlagBits samples; 971e5c31af7Sopenharmony_ci VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 972e5c31af7Sopenharmony_ci VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 973e5c31af7Sopenharmony_ci VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 974e5c31af7Sopenharmony_ci VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 975e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 976e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout; 977e5c31af7Sopenharmony_ci )); 978e5c31af7Sopenharmony_ci 979e5c31af7Sopenharmony_ci attachmentReferences.push_back(makeAttachmentReference(static_cast<deUint32>(attachmentReferences.size()), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); 980e5c31af7Sopenharmony_ci const VkAttachmentReference* colorRef = &attachmentReferences.back(); 981e5c31af7Sopenharmony_ci 982e5c31af7Sopenharmony_ci const VkSubpassDescription subpassDescription = 983e5c31af7Sopenharmony_ci { 984e5c31af7Sopenharmony_ci (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; 985e5c31af7Sopenharmony_ci VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 986e5c31af7Sopenharmony_ci 0u, // uint32_t inputAttachmentCount; 987e5c31af7Sopenharmony_ci DE_NULL, // const VkAttachmentReference* pInputAttachments; 988e5c31af7Sopenharmony_ci 1u, // uint32_t colorAttachmentCount; 989e5c31af7Sopenharmony_ci colorRef, // const VkAttachmentReference* pColorAttachments; 990e5c31af7Sopenharmony_ci DE_NULL, // const VkAttachmentReference* pResolveAttachments; 991e5c31af7Sopenharmony_ci DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 992e5c31af7Sopenharmony_ci 0u, // uint32_t preserveAttachmentCount; 993e5c31af7Sopenharmony_ci DE_NULL, // const uint32_t* pPreserveAttachments; 994e5c31af7Sopenharmony_ci }; 995e5c31af7Sopenharmony_ci 996e5c31af7Sopenharmony_ci subpasses.push_back(subpassDescription); 997e5c31af7Sopenharmony_ci } 998e5c31af7Sopenharmony_ci 999e5c31af7Sopenharmony_ci // All MS image drawing subpasses are independent 1000e5c31af7Sopenharmony_ci VkRenderPassCreateInfo renderPassInfo = 1001e5c31af7Sopenharmony_ci { 1002e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 1003e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1004e5c31af7Sopenharmony_ci (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; 1005e5c31af7Sopenharmony_ci static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount; 1006e5c31af7Sopenharmony_ci dataOrNullPtr(attachmentDescriptions), // const VkAttachmentDescription* pAttachments; 1007e5c31af7Sopenharmony_ci static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount; 1008e5c31af7Sopenharmony_ci dataOrNullPtr(subpasses), // const VkSubpassDescription* pSubpasses; 1009e5c31af7Sopenharmony_ci 0u, // deUint32 dependencyCount; 1010e5c31af7Sopenharmony_ci DE_NULL, // const VkSubpassDependency* pDependencies; 1011e5c31af7Sopenharmony_ci }; 1012e5c31af7Sopenharmony_ci 1013e5c31af7Sopenharmony_ci renderPass = RenderPassWrapper(params.pipelineConstructionType, vk, device, &renderPassInfo); 1014e5c31af7Sopenharmony_ci renderPass.createFramebuffer(vk, device, static_cast<deUint32>(attachments.size()), dataOrNullPtr(images), dataOrNullPtr(attachments), params.renderSize.x(), params.renderSize.y()); 1015e5c31af7Sopenharmony_ci } 1016e5c31af7Sopenharmony_ci 1017e5c31af7Sopenharmony_ci const PipelineLayoutWrapper pipelineLayout (params.pipelineConstructionType, vk, device); 1018e5c31af7Sopenharmony_ci const ShaderWrapper vertexModuleDraw (ShaderWrapper(vk, device, context.getBinaryCollection().get("vert"), 0u)); 1019e5c31af7Sopenharmony_ci const ShaderWrapper fragmentModuleDraw (ShaderWrapper(vk, device, context.getBinaryCollection().get("frag"), 0u)); 1020e5c31af7Sopenharmony_ci 1021e5c31af7Sopenharmony_ci // Vertex attributes: position and color 1022e5c31af7Sopenharmony_ci VkVertexInputBindingDescription vertexInputBindingDescriptions = makeVertexInputBindingDescription(0u, sizeof(PositionColor), VK_VERTEX_INPUT_RATE_VERTEX); 1023e5c31af7Sopenharmony_ci std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescriptions 1024e5c31af7Sopenharmony_ci { 1025e5c31af7Sopenharmony_ci makeVertexInputAttributeDescription(0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, 0u), 1026e5c31af7Sopenharmony_ci makeVertexInputAttributeDescription(1u, 0u, getVertexInputColorFormat(params.colorFormat), sizeof(Vec4)) 1027e5c31af7Sopenharmony_ci }; 1028e5c31af7Sopenharmony_ci 1029e5c31af7Sopenharmony_ci const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo 1030e5c31af7Sopenharmony_ci { 1031e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 1032e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1033e5c31af7Sopenharmony_ci (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 1034e5c31af7Sopenharmony_ci 1u, // uint32_t vertexBindingDescriptionCount; 1035e5c31af7Sopenharmony_ci &vertexInputBindingDescriptions, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 1036e5c31af7Sopenharmony_ci static_cast<deUint32>(vertexInputAttributeDescriptions.size()), // uint32_t vertexAttributeDescriptionCount; 1037e5c31af7Sopenharmony_ci vertexInputAttributeDescriptions.data(), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 1038e5c31af7Sopenharmony_ci }; 1039e5c31af7Sopenharmony_ci 1040e5c31af7Sopenharmony_ci const std::vector<VkViewport> viewports { makeViewport(params.renderSize) }; 1041e5c31af7Sopenharmony_ci const std::vector<VkRect2D> scissors { makeRect2D(params.renderSize) }; 1042e5c31af7Sopenharmony_ci 1043e5c31af7Sopenharmony_ci const VkPipelineMultisampleStateCreateInfo multisampleStateInfo 1044e5c31af7Sopenharmony_ci { 1045e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1046e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1047e5c31af7Sopenharmony_ci (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags; 1048e5c31af7Sopenharmony_ci params.numColorSamples, // VkSampleCountFlagBits rasterizationSamples; 1049e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 sampleShadingEnable; 1050e5c31af7Sopenharmony_ci 1.0f, // float minSampleShading; 1051e5c31af7Sopenharmony_ci DE_NULL, // const VkSampleMask* pSampleMask; 1052e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 alphaToCoverageEnable; 1053e5c31af7Sopenharmony_ci VK_FALSE // VkBool32 alphaToOneEnable; 1054e5c31af7Sopenharmony_ci }; 1055e5c31af7Sopenharmony_ci 1056e5c31af7Sopenharmony_ci const VkPipelineColorBlendAttachmentState defaultBlendAttachmentState 1057e5c31af7Sopenharmony_ci { 1058e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 blendEnable; 1059e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 1060e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 1061e5c31af7Sopenharmony_ci VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 1062e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 1063e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 1064e5c31af7Sopenharmony_ci VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 1065e5c31af7Sopenharmony_ci 0xf, // VkColorComponentFlags colorWriteMask; 1066e5c31af7Sopenharmony_ci }; 1067e5c31af7Sopenharmony_ci 1068e5c31af7Sopenharmony_ci VkPipelineColorBlendStateCreateInfo colorBlendStateInfo 1069e5c31af7Sopenharmony_ci { 1070e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 1071e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1072e5c31af7Sopenharmony_ci (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; 1073e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 logicOpEnable; 1074e5c31af7Sopenharmony_ci VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 1075e5c31af7Sopenharmony_ci 1u, // deUint32 attachmentCount; 1076e5c31af7Sopenharmony_ci &defaultBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 1077e5c31af7Sopenharmony_ci { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 1078e5c31af7Sopenharmony_ci }; 1079e5c31af7Sopenharmony_ci 1080e5c31af7Sopenharmony_ci // Create pipelines for MS draw 1081e5c31af7Sopenharmony_ci std::vector<GraphicsPipelineWrapper> pipelines; 1082e5c31af7Sopenharmony_ci pipelines.reserve(params.numLayers); 1083e5c31af7Sopenharmony_ci for (deUint32 layerNdx = 0u; layerNdx < params.numLayers; ++layerNdx) 1084e5c31af7Sopenharmony_ci { 1085e5c31af7Sopenharmony_ci pipelines.emplace_back(vki, vk, physicalDevice, device, context.getDeviceExtensions(), params.pipelineConstructionType); 1086e5c31af7Sopenharmony_ci pipelines.back().setDefaultRasterizationState() 1087e5c31af7Sopenharmony_ci .setDefaultColorBlendState() 1088e5c31af7Sopenharmony_ci .setDefaultDepthStencilState() 1089e5c31af7Sopenharmony_ci .setupVertexInputState(&vertexInputStateInfo) 1090e5c31af7Sopenharmony_ci .setupPreRasterizationShaderState(viewports, 1091e5c31af7Sopenharmony_ci scissors, 1092e5c31af7Sopenharmony_ci pipelineLayout, 1093e5c31af7Sopenharmony_ci *renderPass, 1094e5c31af7Sopenharmony_ci layerNdx, 1095e5c31af7Sopenharmony_ci vertexModuleDraw) 1096e5c31af7Sopenharmony_ci .setupFragmentShaderState(pipelineLayout, *renderPass, layerNdx, fragmentModuleDraw, DE_NULL, &multisampleStateInfo) 1097e5c31af7Sopenharmony_ci .setupFragmentOutputState(*renderPass, layerNdx, &colorBlendStateInfo, &multisampleStateInfo) 1098e5c31af7Sopenharmony_ci .setMonolithicPipelineLayout(pipelineLayout) 1099e5c31af7Sopenharmony_ci .buildPipeline(); 1100e5c31af7Sopenharmony_ci } 1101e5c31af7Sopenharmony_ci 1102e5c31af7Sopenharmony_ci const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex())); 1103e5c31af7Sopenharmony_ci const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); 1104e5c31af7Sopenharmony_ci 1105e5c31af7Sopenharmony_ci beginCommandBuffer(vk, *cmdBuffer); 1106e5c31af7Sopenharmony_ci 1107e5c31af7Sopenharmony_ci { 1108e5c31af7Sopenharmony_ci // Generate clear values 1109e5c31af7Sopenharmony_ci std::vector<VkClearValue> clearValues = genClearValues(params.colorFormat, params.numLayers); 1110e5c31af7Sopenharmony_ci 1111e5c31af7Sopenharmony_ci const VkRect2D renderArea = 1112e5c31af7Sopenharmony_ci { 1113e5c31af7Sopenharmony_ci { 0u, 0u }, 1114e5c31af7Sopenharmony_ci { params.renderSize.x(), params.renderSize.y() } 1115e5c31af7Sopenharmony_ci }; 1116e5c31af7Sopenharmony_ci 1117e5c31af7Sopenharmony_ci renderPass.begin(vk, *cmdBuffer, renderArea, static_cast<deUint32>(clearValues.size()), dataOrNullPtr(clearValues)); 1118e5c31af7Sopenharmony_ci } 1119e5c31af7Sopenharmony_ci 1120e5c31af7Sopenharmony_ci { 1121e5c31af7Sopenharmony_ci const VkDeviceSize vertexBufferOffset = 0ull; 1122e5c31af7Sopenharmony_ci vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &wd.vertexBuffer.get(), &vertexBufferOffset); 1123e5c31af7Sopenharmony_ci } 1124e5c31af7Sopenharmony_ci 1125e5c31af7Sopenharmony_ci for (deUint32 layerNdx = 0u; layerNdx < params.numLayers; ++layerNdx) 1126e5c31af7Sopenharmony_ci { 1127e5c31af7Sopenharmony_ci if (layerNdx != 0u) 1128e5c31af7Sopenharmony_ci renderPass.nextSubpass(vk, *cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); 1129e5c31af7Sopenharmony_ci 1130e5c31af7Sopenharmony_ci pipelines[layerNdx].bind(*cmdBuffer); 1131e5c31af7Sopenharmony_ci vk.cmdDraw(*cmdBuffer, wd.numVertices, 1u, 0u, layerNdx); // pass instance index to slightly change geometry per layer 1132e5c31af7Sopenharmony_ci } 1133e5c31af7Sopenharmony_ci 1134e5c31af7Sopenharmony_ci renderPass.end(vk, *cmdBuffer); 1135e5c31af7Sopenharmony_ci 1136e5c31af7Sopenharmony_ci VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1137e5c31af7Sopenharmony_ci submitCommandsAndWait(vk, device, SingletonDevice::getUniversalQueue(context), *cmdBuffer); 1138e5c31af7Sopenharmony_ci} 1139e5c31af7Sopenharmony_ci 1140e5c31af7Sopenharmony_ci//! Sample from an image in a compute shader, storing the result in a color buffer 1141e5c31af7Sopenharmony_civoid dispatchSampleImage (Context& context, const TestParams& params, WorkingData& wd, const std::string& shaderName) 1142e5c31af7Sopenharmony_ci{ 1143e5c31af7Sopenharmony_ci const DeviceInterface& vk = SingletonDevice::getDeviceInterface(context); 1144e5c31af7Sopenharmony_ci const VkDevice device = SingletonDevice::getDevice(context); 1145e5c31af7Sopenharmony_ci 1146e5c31af7Sopenharmony_ci // Create descriptor set 1147e5c31af7Sopenharmony_ci 1148e5c31af7Sopenharmony_ci const Unique<VkDescriptorSetLayout> descriptorSetLayout( 1149e5c31af7Sopenharmony_ci DescriptorSetLayoutBuilder() 1150e5c31af7Sopenharmony_ci .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT, &wd.defaultSampler.get()) 1151e5c31af7Sopenharmony_ci .addSingleBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) 1152e5c31af7Sopenharmony_ci .build(vk, device)); 1153e5c31af7Sopenharmony_ci 1154e5c31af7Sopenharmony_ci const Unique<VkDescriptorPool> descriptorPool( 1155e5c31af7Sopenharmony_ci DescriptorPoolBuilder() 1156e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 1157e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) 1158e5c31af7Sopenharmony_ci .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); 1159e5c31af7Sopenharmony_ci 1160e5c31af7Sopenharmony_ci const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); 1161e5c31af7Sopenharmony_ci 1162e5c31af7Sopenharmony_ci { 1163e5c31af7Sopenharmony_ci const VkDescriptorImageInfo colorImageInfo = makeDescriptorImageInfo(DE_NULL, *wd.colorImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 1164e5c31af7Sopenharmony_ci const VkDescriptorBufferInfo resultBufferInfo = makeDescriptorBufferInfo(*wd.colorBuffer, 0ull, wd.colorBufferSize); 1165e5c31af7Sopenharmony_ci 1166e5c31af7Sopenharmony_ci DescriptorSetUpdateBuilder builder; 1167e5c31af7Sopenharmony_ci 1168e5c31af7Sopenharmony_ci builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &colorImageInfo); 1169e5c31af7Sopenharmony_ci builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferInfo); 1170e5c31af7Sopenharmony_ci 1171e5c31af7Sopenharmony_ci builder.update(vk, device); 1172e5c31af7Sopenharmony_ci } 1173e5c31af7Sopenharmony_ci 1174e5c31af7Sopenharmony_ci // Pipeline 1175e5c31af7Sopenharmony_ci 1176e5c31af7Sopenharmony_ci const Unique<VkShaderModule> shaderModule (createShaderModule(vk, device, context.getBinaryCollection().get(shaderName), 0u)); 1177e5c31af7Sopenharmony_ci const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout)); 1178e5c31af7Sopenharmony_ci const Unique<VkPipeline> pipeline (makeComputePipeline(vk, device, *pipelineLayout, *shaderModule)); 1179e5c31af7Sopenharmony_ci 1180e5c31af7Sopenharmony_ci const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex())); 1181e5c31af7Sopenharmony_ci const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); 1182e5c31af7Sopenharmony_ci 1183e5c31af7Sopenharmony_ci beginCommandBuffer(vk, *cmdBuffer); 1184e5c31af7Sopenharmony_ci 1185e5c31af7Sopenharmony_ci vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline); 1186e5c31af7Sopenharmony_ci vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); 1187e5c31af7Sopenharmony_ci 1188e5c31af7Sopenharmony_ci vk.cmdDispatch(*cmdBuffer, params.renderSize.x(), params.renderSize.y(), params.numLayers); 1189e5c31af7Sopenharmony_ci 1190e5c31af7Sopenharmony_ci { 1191e5c31af7Sopenharmony_ci const VkBufferMemoryBarrier barrier = 1192e5c31af7Sopenharmony_ci { 1193e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1194e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1195e5c31af7Sopenharmony_ci VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1196e5c31af7Sopenharmony_ci VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 1197e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 1198e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 1199e5c31af7Sopenharmony_ci *wd.colorBuffer, // VkBuffer buffer; 1200e5c31af7Sopenharmony_ci 0ull, // VkDeviceSize offset; 1201e5c31af7Sopenharmony_ci VK_WHOLE_SIZE, // VkDeviceSize size; 1202e5c31af7Sopenharmony_ci }; 1203e5c31af7Sopenharmony_ci 1204e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, 1205e5c31af7Sopenharmony_ci (const VkMemoryBarrier*)DE_NULL, 1u, &barrier, 0u, (const VkImageMemoryBarrier*)DE_NULL); 1206e5c31af7Sopenharmony_ci } 1207e5c31af7Sopenharmony_ci 1208e5c31af7Sopenharmony_ci VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1209e5c31af7Sopenharmony_ci submitCommandsAndWait(vk, device, SingletonDevice::getUniversalQueue(context), *cmdBuffer); 1210e5c31af7Sopenharmony_ci 1211e5c31af7Sopenharmony_ci invalidateMappedMemoryRange(vk, device, wd.colorBufferAlloc->getMemory(), wd.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE); 1212e5c31af7Sopenharmony_ci} 1213e5c31af7Sopenharmony_ci 1214e5c31af7Sopenharmony_ci//! Get a single-sampled image access from a multisampled color buffer with samples packed per pixel 1215e5c31af7Sopenharmony_citcu::ConstPixelBufferAccess getSingleSampledAccess (const void* const imageData, const TestParams& params, const deUint32 sampleNdx, const deUint32 layerNdx) 1216e5c31af7Sopenharmony_ci{ 1217e5c31af7Sopenharmony_ci const deUint32 numSamples = static_cast<deUint32>(params.numColorSamples); 1218e5c31af7Sopenharmony_ci const deUint32 pixelSize = tcu::getPixelSize(mapVkFormat(params.colorFormat)); 1219e5c31af7Sopenharmony_ci const deUint32 rowSize = pixelSize * params.renderSize.x(); 1220e5c31af7Sopenharmony_ci const deUint32 layerSize = rowSize * params.renderSize.y(); 1221e5c31af7Sopenharmony_ci const deUint8* src = static_cast<const deUint8*>(imageData) 1222e5c31af7Sopenharmony_ci + (layerNdx * numSamples * layerSize) 1223e5c31af7Sopenharmony_ci + (sampleNdx * pixelSize); 1224e5c31af7Sopenharmony_ci const tcu::IVec3 size (params.renderSize.x(), params.renderSize.y(), 1); 1225e5c31af7Sopenharmony_ci const tcu::IVec3 pitch (numSamples * pixelSize, 1226e5c31af7Sopenharmony_ci numSamples * rowSize, 1227e5c31af7Sopenharmony_ci numSamples * layerSize); 1228e5c31af7Sopenharmony_ci return tcu::ConstPixelBufferAccess(mapVkFormat(params.colorFormat), size, pitch, src); 1229e5c31af7Sopenharmony_ci} 1230e5c31af7Sopenharmony_ci 1231e5c31af7Sopenharmony_citcu::TestStatus test (Context& context, const TestParams params) 1232e5c31af7Sopenharmony_ci{ 1233e5c31af7Sopenharmony_ci WorkingData wd; 1234e5c31af7Sopenharmony_ci const DeviceInterface& vk = SingletonDevice::getDeviceInterface(context); 1235e5c31af7Sopenharmony_ci const VkDevice device = SingletonDevice::getDevice(context); 1236e5c31af7Sopenharmony_ci 1237e5c31af7Sopenharmony_ci MovePtr<Allocator> allocator = MovePtr<Allocator>(new SimpleAllocator(vk, device, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()))); 1238e5c31af7Sopenharmony_ci 1239e5c31af7Sopenharmony_ci // Initialize resources 1240e5c31af7Sopenharmony_ci { 1241e5c31af7Sopenharmony_ci const VkImageUsageFlags msImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT 1242e5c31af7Sopenharmony_ci | VK_IMAGE_USAGE_SAMPLED_BIT 1243e5c31af7Sopenharmony_ci | (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0); 1244e5c31af7Sopenharmony_ci wd.colorImage = makeImage(vk, device, params.colorFormat, params.renderSize, params.numLayers, params.numColorSamples, msImageUsage); 1245e5c31af7Sopenharmony_ci wd.colorImageAlloc = bindImage(vk, device, *allocator, *wd.colorImage, MemoryRequirement::Any); 1246e5c31af7Sopenharmony_ci wd.colorImageView = makeImageView(vk, device, *wd.colorImage, (params.numLayers == 1u ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY), params.colorFormat, 1247e5c31af7Sopenharmony_ci makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, params.numLayers)); 1248e5c31af7Sopenharmony_ci 1249e5c31af7Sopenharmony_ci wd.defaultSampler = makeSampler(vk, device); 1250e5c31af7Sopenharmony_ci 1251e5c31af7Sopenharmony_ci // Color buffer is meant to hold data for all layers and all samples of the image. 1252e5c31af7Sopenharmony_ci // Data is tightly packed layer by layer, for each pixel all samples are laid out together starting with sample 0. 1253e5c31af7Sopenharmony_ci // E.g.: pixel(0,0)sample(0)sample(1), pixel(1,0)sample(0)sample(1), ... 1254e5c31af7Sopenharmony_ci wd.colorBufferSize = static_cast<VkDeviceSize>(tcu::getPixelSize(mapVkFormat(params.colorFormat)) 1255e5c31af7Sopenharmony_ci * params.renderSize.x() * params.renderSize.y() * params.numLayers * static_cast<deUint32>(params.numColorSamples)); 1256e5c31af7Sopenharmony_ci wd.colorBuffer = makeBuffer(vk, device, wd.colorBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); 1257e5c31af7Sopenharmony_ci wd.colorBufferAlloc = bindBuffer(vk, device, *allocator, *wd.colorBuffer, MemoryRequirement::HostVisible); 1258e5c31af7Sopenharmony_ci 1259e5c31af7Sopenharmony_ci deMemset(wd.colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(wd.colorBufferSize)); 1260e5c31af7Sopenharmony_ci flushMappedMemoryRange(vk, device, wd.colorBufferAlloc->getMemory(), wd.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE); 1261e5c31af7Sopenharmony_ci 1262e5c31af7Sopenharmony_ci const std::vector<PositionColor> vertices = genShapes(params.colorFormat); 1263e5c31af7Sopenharmony_ci const VkDeviceSize vertexBufferSize = static_cast<VkDeviceSize>(sizeof(vertices[0]) * vertices.size()); 1264e5c31af7Sopenharmony_ci 1265e5c31af7Sopenharmony_ci wd.numVertices = static_cast<deUint32>(vertices.size()); 1266e5c31af7Sopenharmony_ci wd.vertexBuffer = makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); 1267e5c31af7Sopenharmony_ci wd.vertexBufferAlloc = bindBuffer(vk, device, *allocator, *wd.vertexBuffer, MemoryRequirement::HostVisible); 1268e5c31af7Sopenharmony_ci 1269e5c31af7Sopenharmony_ci deMemcpy(wd.vertexBufferAlloc->getHostPtr(), dataOrNullPtr(vertices), static_cast<std::size_t>(vertexBufferSize)); 1270e5c31af7Sopenharmony_ci flushMappedMemoryRange(vk, device, wd.vertexBufferAlloc->getMemory(), wd.vertexBufferAlloc->getOffset(), VK_WHOLE_SIZE); 1271e5c31af7Sopenharmony_ci } 1272e5c31af7Sopenharmony_ci 1273e5c31af7Sopenharmony_ci if (params.sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT) 1274e5c31af7Sopenharmony_ci { 1275e5c31af7Sopenharmony_ci // Create a multisample image and sample from it 1276e5c31af7Sopenharmony_ci drawAndSampleInputAttachment (context, params, wd); 1277e5c31af7Sopenharmony_ci } 1278e5c31af7Sopenharmony_ci else 1279e5c31af7Sopenharmony_ci { 1280e5c31af7Sopenharmony_ci // Draw the image, then sample from it in a CS 1281e5c31af7Sopenharmony_ci draw (context, params, wd); 1282e5c31af7Sopenharmony_ci dispatchSampleImage (context, params, wd, "comp_fmask_fetch"); 1283e5c31af7Sopenharmony_ci } 1284e5c31af7Sopenharmony_ci 1285e5c31af7Sopenharmony_ci // Copy the result 1286e5c31af7Sopenharmony_ci std::vector<deUint8> fmaskFetchColorBuffer (static_cast<deUint32>(wd.colorBufferSize)); 1287e5c31af7Sopenharmony_ci deMemcpy(&fmaskFetchColorBuffer[0], wd.colorBufferAlloc->getHostPtr(), static_cast<std::size_t>(wd.colorBufferSize)); 1288e5c31af7Sopenharmony_ci 1289e5c31af7Sopenharmony_ci // Clear the color buffer, just to be sure we're getting the new data 1290e5c31af7Sopenharmony_ci deMemset(wd.colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(wd.colorBufferSize)); 1291e5c31af7Sopenharmony_ci flushMappedMemoryRange(vk, device, wd.colorBufferAlloc->getMemory(), wd.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE); 1292e5c31af7Sopenharmony_ci 1293e5c31af7Sopenharmony_ci // Sample image using the standard texel fetch 1294e5c31af7Sopenharmony_ci dispatchSampleImage (context, params, wd, "comp_fetch"); 1295e5c31af7Sopenharmony_ci 1296e5c31af7Sopenharmony_ci // Verify the images 1297e5c31af7Sopenharmony_ci { 1298e5c31af7Sopenharmony_ci const void* const fmaskResult = dataOrNullPtr(fmaskFetchColorBuffer); 1299e5c31af7Sopenharmony_ci const void* const expectedResult = wd.colorBufferAlloc->getHostPtr(); 1300e5c31af7Sopenharmony_ci 1301e5c31af7Sopenharmony_ci DE_ASSERT(!isFloatFormat(params.colorFormat)); // we're using int compare 1302e5c31af7Sopenharmony_ci 1303e5c31af7Sopenharmony_ci // Mismatch, do image compare to pinpoint the failure 1304e5c31af7Sopenharmony_ci for (deUint32 layerNdx = 0u; layerNdx < params.numLayers; ++layerNdx) 1305e5c31af7Sopenharmony_ci for (deUint32 sampleNdx = 0u; sampleNdx < static_cast<deUint32>(params.numColorSamples); ++sampleNdx) 1306e5c31af7Sopenharmony_ci { 1307e5c31af7Sopenharmony_ci const std::string imageName = "layer_" + de::toString(layerNdx) + "_sample_" + de::toString(sampleNdx); 1308e5c31af7Sopenharmony_ci const std::string imageDesc = "Layer " + de::toString(layerNdx) + " Sample " + de::toString(sampleNdx); 1309e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess expected = getSingleSampledAccess(expectedResult, params, sampleNdx, layerNdx); 1310e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess actual = getSingleSampledAccess(fmaskResult, params, sampleNdx, layerNdx); 1311e5c31af7Sopenharmony_ci const UVec4 threshold (0); // should match exactly 1312e5c31af7Sopenharmony_ci 1313e5c31af7Sopenharmony_ci const bool ok = tcu::intThresholdCompare(context.getTestContext().getLog(), imageName.c_str(), imageDesc.c_str(), 1314e5c31af7Sopenharmony_ci expected, actual, threshold, tcu::COMPARE_LOG_RESULT); 1315e5c31af7Sopenharmony_ci 1316e5c31af7Sopenharmony_ci if (!ok) 1317e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Some texels were incorrect"); 1318e5c31af7Sopenharmony_ci } 1319e5c31af7Sopenharmony_ci } 1320e5c31af7Sopenharmony_ci 1321e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("Pass"); 1322e5c31af7Sopenharmony_ci} 1323e5c31af7Sopenharmony_ci 1324e5c31af7Sopenharmony_cistd::string getFormatShortString (const VkFormat format) 1325e5c31af7Sopenharmony_ci{ 1326e5c31af7Sopenharmony_ci std::string s(de::toLower(getFormatName(format))); 1327e5c31af7Sopenharmony_ci return s.substr(10); 1328e5c31af7Sopenharmony_ci} 1329e5c31af7Sopenharmony_ci 1330e5c31af7Sopenharmony_civoid createShaderFragmentMaskTestsInGroup (tcu::TestCaseGroup* rootGroup, PipelineConstructionType pipelineConstructionType) 1331e5c31af7Sopenharmony_ci{ 1332e5c31af7Sopenharmony_ci // Per spec, the following formats must support color attachment and sampled image 1333e5c31af7Sopenharmony_ci const VkFormat colorFormats[] = 1334e5c31af7Sopenharmony_ci { 1335e5c31af7Sopenharmony_ci VK_FORMAT_R8G8B8A8_UNORM, 1336e5c31af7Sopenharmony_ci VK_FORMAT_R32_UINT, 1337e5c31af7Sopenharmony_ci VK_FORMAT_R32_SINT, 1338e5c31af7Sopenharmony_ci }; 1339e5c31af7Sopenharmony_ci 1340e5c31af7Sopenharmony_ci const VkSampleCountFlagBits sampleCounts[] = 1341e5c31af7Sopenharmony_ci { 1342e5c31af7Sopenharmony_ci VK_SAMPLE_COUNT_2_BIT, 1343e5c31af7Sopenharmony_ci VK_SAMPLE_COUNT_4_BIT, 1344e5c31af7Sopenharmony_ci VK_SAMPLE_COUNT_8_BIT, 1345e5c31af7Sopenharmony_ci VK_SAMPLE_COUNT_16_BIT, 1346e5c31af7Sopenharmony_ci }; 1347e5c31af7Sopenharmony_ci 1348e5c31af7Sopenharmony_ci const struct SourceCase 1349e5c31af7Sopenharmony_ci { 1350e5c31af7Sopenharmony_ci const char* name; 1351e5c31af7Sopenharmony_ci deUint32 numLayers; 1352e5c31af7Sopenharmony_ci SampleSource sampleSource; 1353e5c31af7Sopenharmony_ci } sourceCases[] = 1354e5c31af7Sopenharmony_ci { 1355e5c31af7Sopenharmony_ci { "image_2d", 1u, SAMPLE_SOURCE_IMAGE }, 1356e5c31af7Sopenharmony_ci { "image_2d_array", 3u, SAMPLE_SOURCE_IMAGE }, 1357e5c31af7Sopenharmony_ci { "subpass_input", 1u, SAMPLE_SOURCE_SUBPASS_INPUT }, 1358e5c31af7Sopenharmony_ci }; 1359e5c31af7Sopenharmony_ci 1360e5c31af7Sopenharmony_ci // Test 1: Compare fragments fetched via FMASK and an ordinary texel fetch 1361e5c31af7Sopenharmony_ci { 1362e5c31af7Sopenharmony_ci for (const VkSampleCountFlagBits* pSampleCount = sampleCounts; pSampleCount != DE_ARRAY_END(sampleCounts); ++pSampleCount) 1363e5c31af7Sopenharmony_ci { 1364e5c31af7Sopenharmony_ci MovePtr<tcu::TestCaseGroup> sampleCountGroup (new tcu::TestCaseGroup(rootGroup->getTestContext(), ("samples_" + de::toString(*pSampleCount)).c_str())); 1365e5c31af7Sopenharmony_ci for (const SourceCase* pSourceCase = sourceCases; pSourceCase != DE_ARRAY_END(sourceCases); ++pSourceCase) 1366e5c31af7Sopenharmony_ci { 1367e5c31af7Sopenharmony_ci // Input attachments cannot be used with dynamic rendering. 1368e5c31af7Sopenharmony_ci if (pSourceCase->sampleSource == SAMPLE_SOURCE_SUBPASS_INPUT && isConstructionTypeShaderObject(pipelineConstructionType)) 1369e5c31af7Sopenharmony_ci continue; 1370e5c31af7Sopenharmony_ci 1371e5c31af7Sopenharmony_ci MovePtr<tcu::TestCaseGroup> sourceGroup (new tcu::TestCaseGroup(rootGroup->getTestContext(), pSourceCase->name)); 1372e5c31af7Sopenharmony_ci for (const VkFormat* pColorFormat = colorFormats; pColorFormat != DE_ARRAY_END(colorFormats); ++pColorFormat) 1373e5c31af7Sopenharmony_ci { 1374e5c31af7Sopenharmony_ci TestParams params; 1375e5c31af7Sopenharmony_ci params.pipelineConstructionType = pipelineConstructionType; 1376e5c31af7Sopenharmony_ci params.renderSize = UVec2(32, 32); 1377e5c31af7Sopenharmony_ci params.colorFormat = *pColorFormat; 1378e5c31af7Sopenharmony_ci params.numColorSamples = *pSampleCount; 1379e5c31af7Sopenharmony_ci params.numLayers = pSourceCase->numLayers; 1380e5c31af7Sopenharmony_ci params.sampleSource = pSourceCase->sampleSource; 1381e5c31af7Sopenharmony_ci 1382e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms(sourceGroup.get(), getFormatShortString(*pColorFormat), checkRequirements, initPrograms, test, params); 1383e5c31af7Sopenharmony_ci } 1384e5c31af7Sopenharmony_ci sampleCountGroup->addChild(sourceGroup.release()); 1385e5c31af7Sopenharmony_ci } 1386e5c31af7Sopenharmony_ci rootGroup->addChild(sampleCountGroup.release()); 1387e5c31af7Sopenharmony_ci } 1388e5c31af7Sopenharmony_ci } 1389e5c31af7Sopenharmony_ci} 1390e5c31af7Sopenharmony_ci 1391e5c31af7Sopenharmony_ci} // anonymous ns 1392e5c31af7Sopenharmony_ci 1393e5c31af7Sopenharmony_citcu::TestCaseGroup* createMultisampleShaderFragmentMaskTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType) 1394e5c31af7Sopenharmony_ci{ 1395e5c31af7Sopenharmony_ci const auto cleanGroup = [](tcu::TestCaseGroup*, PipelineConstructionType) { SingletonDevice::destroy(); }; 1396e5c31af7Sopenharmony_ci const char* groupName = "shader_fragment_mask"; 1397e5c31af7Sopenharmony_ci 1398e5c31af7Sopenharmony_ci // Access raw texel values in a compressed MSAA surface 1399e5c31af7Sopenharmony_ci return createTestGroup(testCtx, groupName, createShaderFragmentMaskTestsInGroup, pipelineConstructionType, cleanGroup); 1400e5c31af7Sopenharmony_ci} 1401e5c31af7Sopenharmony_ci 1402e5c31af7Sopenharmony_ci} // pipeline 1403e5c31af7Sopenharmony_ci} // vkt 1404