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