1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------ 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2022 Google Inc. 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief YCbCr image offset tests 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "vktYCbCrImageOffsetTests.hpp" 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "vktTestCaseUtil.hpp" 27e5c31af7Sopenharmony_ci#include "vktTestGroupUtil.hpp" 28e5c31af7Sopenharmony_ci#include "vktYCbCrUtil.hpp" 29e5c31af7Sopenharmony_ci 30e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp" 31e5c31af7Sopenharmony_ci#include "vkRefUtil.hpp" 32e5c31af7Sopenharmony_ci#include "vkTypeUtil.hpp" 33e5c31af7Sopenharmony_ci 34e5c31af7Sopenharmony_ci#include <string> 35e5c31af7Sopenharmony_ci#include <vector> 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_ciusing tcu::UVec2; 38e5c31af7Sopenharmony_ciusing tcu::TestLog; 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ciusing std::string; 41e5c31af7Sopenharmony_ciusing std::vector; 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_ciusing namespace vk; 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_cinamespace vkt 46e5c31af7Sopenharmony_ci{ 47e5c31af7Sopenharmony_cinamespace ycbcr 48e5c31af7Sopenharmony_ci{ 49e5c31af7Sopenharmony_cinamespace 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_ci 52e5c31af7Sopenharmony_ci struct TestConfig 53e5c31af7Sopenharmony_ci { 54e5c31af7Sopenharmony_ci TestConfig (const vk::VkFormat format_) : format (format_) {} 55e5c31af7Sopenharmony_ci vk::VkFormat format; 56e5c31af7Sopenharmony_ci }; 57e5c31af7Sopenharmony_ci 58e5c31af7Sopenharmony_ci void checkSupport (Context& context, const TestConfig config) 59e5c31af7Sopenharmony_ci { 60e5c31af7Sopenharmony_ci const vk::VkFormatProperties properties = vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), 61e5c31af7Sopenharmony_ci context.getPhysicalDevice(), config.format); 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_ci if ((properties.linearTilingFeatures & vk::VK_FORMAT_FEATURE_DISJOINT_BIT) == 0) 64e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format doesn't support disjoint planes"); 65e5c31af7Sopenharmony_ci } 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_ci vk::Move<vk::VkImage> createImage (const vk::DeviceInterface& vkd, 68e5c31af7Sopenharmony_ci vk::VkDevice device, 69e5c31af7Sopenharmony_ci vk::VkFormat format, 70e5c31af7Sopenharmony_ci const UVec2& size) 71e5c31af7Sopenharmony_ci { 72e5c31af7Sopenharmony_ci const vk::VkImageCreateInfo createInfo = 73e5c31af7Sopenharmony_ci { 74e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 75e5c31af7Sopenharmony_ci DE_NULL, 76e5c31af7Sopenharmony_ci vk::VK_IMAGE_CREATE_DISJOINT_BIT, 77e5c31af7Sopenharmony_ci vk::VK_IMAGE_TYPE_2D, 78e5c31af7Sopenharmony_ci format, 79e5c31af7Sopenharmony_ci vk::makeExtent3D(size.x(), size.y(), 1u), 80e5c31af7Sopenharmony_ci 1u, 81e5c31af7Sopenharmony_ci 1u, 82e5c31af7Sopenharmony_ci vk::VK_SAMPLE_COUNT_1_BIT, 83e5c31af7Sopenharmony_ci vk::VK_IMAGE_TILING_LINEAR, 84e5c31af7Sopenharmony_ci vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 85e5c31af7Sopenharmony_ci vk::VK_SHARING_MODE_EXCLUSIVE, 86e5c31af7Sopenharmony_ci 0u, 87e5c31af7Sopenharmony_ci (const deUint32*)DE_NULL, 88e5c31af7Sopenharmony_ci vk::VK_IMAGE_LAYOUT_PREINITIALIZED 89e5c31af7Sopenharmony_ci }; 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci return vk::createImage(vkd, device, &createInfo); 92e5c31af7Sopenharmony_ci } 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_ci tcu::TestStatus imageOffsetTest (Context& context, const TestConfig config) 95e5c31af7Sopenharmony_ci { 96e5c31af7Sopenharmony_ci const vk::DeviceInterface& vkd (context.getDeviceInterface()); 97e5c31af7Sopenharmony_ci const vk::VkDevice device (context.getDevice()); 98e5c31af7Sopenharmony_ci 99e5c31af7Sopenharmony_ci const vk::Unique<vk::VkImage> srcImage (createImage(vkd, device, config.format, UVec2(8u, 8u))); 100e5c31af7Sopenharmony_ci const vk::MemoryRequirement srcMemoryRequirement (vk::MemoryRequirement::HostVisible); 101e5c31af7Sopenharmony_ci vector<AllocationSp> srcImageMemory; 102e5c31af7Sopenharmony_ci 103e5c31af7Sopenharmony_ci const deUint32 numPlanes = getPlaneCount(config.format); 104e5c31af7Sopenharmony_ci vector<vk::VkBindImageMemoryInfo> coreInfos; 105e5c31af7Sopenharmony_ci vector<vk::VkBindImagePlaneMemoryInfo> planeInfos; 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_ci coreInfos.reserve(numPlanes); 108e5c31af7Sopenharmony_ci planeInfos.reserve(numPlanes); 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ci for (deUint32 planeNdx = 0; planeNdx < numPlanes; ++planeNdx) 111e5c31af7Sopenharmony_ci { 112e5c31af7Sopenharmony_ci const vk::VkImageAspectFlagBits planeAspect = (vk::VkImageAspectFlagBits)(vk::VK_IMAGE_ASPECT_PLANE_0_BIT << planeNdx); 113e5c31af7Sopenharmony_ci vk::VkMemoryRequirements reqs = getImagePlaneMemoryRequirements(vkd, device, srcImage.get(), planeAspect); 114e5c31af7Sopenharmony_ci const VkDeviceSize offset = deAlign64(reqs.size, reqs.alignment); 115e5c31af7Sopenharmony_ci reqs.size *= 2; 116e5c31af7Sopenharmony_ci 117e5c31af7Sopenharmony_ci srcImageMemory.push_back(AllocationSp(context.getDefaultAllocator().allocate(reqs, srcMemoryRequirement).release())); 118e5c31af7Sopenharmony_ci 119e5c31af7Sopenharmony_ci vk::VkBindImagePlaneMemoryInfo planeInfo = 120e5c31af7Sopenharmony_ci { 121e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, 122e5c31af7Sopenharmony_ci DE_NULL, 123e5c31af7Sopenharmony_ci planeAspect 124e5c31af7Sopenharmony_ci }; 125e5c31af7Sopenharmony_ci planeInfos.push_back(planeInfo); 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_ci vk::VkBindImageMemoryInfo coreInfo = 128e5c31af7Sopenharmony_ci { 129e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, 130e5c31af7Sopenharmony_ci &planeInfos.back(), 131e5c31af7Sopenharmony_ci srcImage.get(), 132e5c31af7Sopenharmony_ci srcImageMemory.back()->getMemory(), 133e5c31af7Sopenharmony_ci offset, 134e5c31af7Sopenharmony_ci }; 135e5c31af7Sopenharmony_ci coreInfos.push_back(coreInfo); 136e5c31af7Sopenharmony_ci } 137e5c31af7Sopenharmony_ci 138e5c31af7Sopenharmony_ci VK_CHECK(vkd.bindImageMemory2(device, numPlanes, coreInfos.data())); 139e5c31af7Sopenharmony_ci 140e5c31af7Sopenharmony_ci vk::VkImageAspectFlags aspectMasks[3] = {vk::VK_IMAGE_ASPECT_PLANE_0_BIT, vk::VK_IMAGE_ASPECT_PLANE_1_BIT, 141e5c31af7Sopenharmony_ci vk::VK_IMAGE_ASPECT_PLANE_2_BIT}; 142e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < numPlanes; i++) 143e5c31af7Sopenharmony_ci { 144e5c31af7Sopenharmony_ci vk::VkSubresourceLayout subresourceLayout; 145e5c31af7Sopenharmony_ci auto subresource = vk::makeImageSubresource(aspectMasks[i], 0u, 0u); 146e5c31af7Sopenharmony_ci vkd.getImageSubresourceLayout(device, srcImage.get(), &subresource, &subresourceLayout); 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ci // VkSubresourceLayout::offset is the byte offset from the start of the image or the plane 149e5c31af7Sopenharmony_ci // where the image subresource begins. For disjoint images, it should be 0 since each plane 150e5c31af7Sopenharmony_ci // has been separately bound to memory. 151e5c31af7Sopenharmony_ci if (subresourceLayout.offset != 0) 152e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Failed, subresource layout offset != 0"); 153e5c31af7Sopenharmony_ci } 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("Pass"); 156e5c31af7Sopenharmony_ci } 157e5c31af7Sopenharmony_ci 158e5c31af7Sopenharmony_ci void initYcbcrImageOffsetTests (tcu::TestCaseGroup* testGroup) 159e5c31af7Sopenharmony_ci { 160e5c31af7Sopenharmony_ci const vk::VkFormat ycbcrFormats[] = 161e5c31af7Sopenharmony_ci { 162e5c31af7Sopenharmony_ci vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, 163e5c31af7Sopenharmony_ci vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, 164e5c31af7Sopenharmony_ci vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM, 165e5c31af7Sopenharmony_ci vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM, 166e5c31af7Sopenharmony_ci vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM, 167e5c31af7Sopenharmony_ci vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16, 168e5c31af7Sopenharmony_ci vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, 169e5c31af7Sopenharmony_ci vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16, 170e5c31af7Sopenharmony_ci vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16, 171e5c31af7Sopenharmony_ci vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16, 172e5c31af7Sopenharmony_ci vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16, 173e5c31af7Sopenharmony_ci vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16, 174e5c31af7Sopenharmony_ci vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16, 175e5c31af7Sopenharmony_ci vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16, 176e5c31af7Sopenharmony_ci vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16, 177e5c31af7Sopenharmony_ci vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, 178e5c31af7Sopenharmony_ci vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM, 179e5c31af7Sopenharmony_ci vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, 180e5c31af7Sopenharmony_ci vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, 181e5c31af7Sopenharmony_ci vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, 182e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 183e5c31af7Sopenharmony_ci vk::VK_FORMAT_G8_B8R8_2PLANE_444_UNORM, 184e5c31af7Sopenharmony_ci vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16, 185e5c31af7Sopenharmony_ci vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, 186e5c31af7Sopenharmony_ci vk::VK_FORMAT_G16_B16R16_2PLANE_444_UNORM, 187e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 188e5c31af7Sopenharmony_ci }; 189e5c31af7Sopenharmony_ci 190e5c31af7Sopenharmony_ci for (int i = 0; i < DE_LENGTH_OF_ARRAY(ycbcrFormats); i++) 191e5c31af7Sopenharmony_ci { 192e5c31af7Sopenharmony_ci const vk::VkFormat srcFormat (ycbcrFormats[i]); 193e5c31af7Sopenharmony_ci const string srcFormatName (de::toLower(std::string(getFormatName(srcFormat)).substr(10))); 194e5c31af7Sopenharmony_ci 195e5c31af7Sopenharmony_ci const TestConfig config (srcFormat); 196e5c31af7Sopenharmony_ci addFunctionCase(testGroup, srcFormatName.c_str(), checkSupport, imageOffsetTest, config); 197e5c31af7Sopenharmony_ci } 198e5c31af7Sopenharmony_ci } 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci} // anonymous 201e5c31af7Sopenharmony_ci 202e5c31af7Sopenharmony_citcu::TestCaseGroup* createImageOffsetTests (tcu::TestContext& testCtx) 203e5c31af7Sopenharmony_ci{ 204e5c31af7Sopenharmony_ci return createTestGroup(testCtx, "subresource_offset", initYcbcrImageOffsetTests); 205e5c31af7Sopenharmony_ci} 206e5c31af7Sopenharmony_ci 207e5c31af7Sopenharmony_ci} // ycbcr 208e5c31af7Sopenharmony_ci} // vkt 209