• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 The Khronos Group Inc.
6  * Copyright (c) 2019 The Android Open Source Project
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Cube image with misaligned baseArrayLayer tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktImageMisalignedCubeTests.hpp"
26 #include "vktTestCaseUtil.hpp"
27 #include "vktImageTestsUtil.hpp"
28 #include "vktImageTexture.hpp"
29 
30 #include "vkDefs.hpp"
31 #include "vkRef.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkPlatform.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vkBarrierUtil.hpp"
37 #include "vkBuilderUtil.hpp"
38 #include "vkImageUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41 #include "vkTypeUtil.hpp"
42 #include "vkBufferWithMemory.hpp"
43 
44 #include "deUniquePtr.hpp"
45 #include "deStringUtil.hpp"
46 #include "deMath.h"
47 
48 #include <string>
49 
50 using namespace vk;
51 
52 namespace vkt
53 {
54 namespace image
55 {
56 namespace
57 {
58 
makeImageCreateInfo(const tcu::IVec3 & size,const VkFormat format)59 inline VkImageCreateInfo makeImageCreateInfo (const tcu::IVec3& size, const VkFormat format)
60 {
61 	const VkImageUsageFlags	usage		= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
62 	const VkImageCreateInfo	imageParams	=
63 	{
64 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//  VkStructureType			sType;
65 		DE_NULL,								//  const void*				pNext;
66 		VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,	//  VkImageCreateFlags		flags;
67 		VK_IMAGE_TYPE_2D,						//  VkImageType				imageType;
68 		format,									//  VkFormat				format;
69 		makeExtent3D(size.x(), size.y(), 1u),	//  VkExtent3D				extent;
70 		1u,										//  deUint32				mipLevels;
71 		(deUint32)size.z(),						//  deUint32				arrayLayers;
72 		VK_SAMPLE_COUNT_1_BIT,					//  VkSampleCountFlagBits	samples;
73 		VK_IMAGE_TILING_OPTIMAL,				//  VkImageTiling			tiling;
74 		usage,									//  VkImageUsageFlags		usage;
75 		VK_SHARING_MODE_EXCLUSIVE,				//  VkSharingMode			sharingMode;
76 		0u,										//  deUint32				queueFamilyIndexCount;
77 		DE_NULL,								//  const deUint32*			pQueueFamilyIndices;
78 		VK_IMAGE_LAYOUT_UNDEFINED,				//  VkImageLayout			initialLayout;
79 	};
80 
81 	return imageParams;
82 }
83 
fillBuffer(const DeviceInterface & vk,const VkDevice device,const Allocation & alloc,const VkDeviceSize offset,const VkDeviceSize size,const VkFormat format,const tcu::Vec4 & color)84 void fillBuffer (const DeviceInterface& vk, const VkDevice device, const Allocation& alloc, const VkDeviceSize offset, const VkDeviceSize size, const VkFormat format, const tcu::Vec4& color)
85 {
86 	const tcu::TextureFormat	textureFormat		= mapVkFormat(format);
87 	const deUint32				colorPixelSize		= static_cast<deUint32>(tcu::getPixelSize(textureFormat));
88 	tcu::TextureLevel			colorPixelBuffer	(textureFormat, 1, 1);
89 	tcu::PixelBufferAccess		colorPixel			(colorPixelBuffer);
90 
91 	colorPixel.setPixel(color, 0, 0);
92 
93 	const deUint8*	src		= static_cast<deUint8*>(colorPixel.getDataPtr());
94 	deUint8*		dstBase	= static_cast<deUint8*>(alloc.getHostPtr());
95 	deUint8*		dst		= &dstBase[offset];
96 
97 	for (deUint32 pixelPos = 0; pixelPos < size; pixelPos += colorPixelSize)
98 		deMemcpy(&dst[pixelPos], src, colorPixelSize);
99 
100 	flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset() + offset, size);
101 }
102 
makeBufferImageCopy(const vk::VkDeviceSize & bufferOffset,const vk::VkImageSubresourceLayers & imageSubresource,const vk::VkOffset3D & imageOffset,const vk::VkExtent3D & imageExtent)103 VkBufferImageCopy makeBufferImageCopy (const vk::VkDeviceSize&				bufferOffset,
104 									   const vk::VkImageSubresourceLayers&	imageSubresource,
105 									   const vk::VkOffset3D&				imageOffset,
106 									   const vk::VkExtent3D&				imageExtent)
107 {
108 	const VkBufferImageCopy copyParams =
109 	{
110 		bufferOffset,								//	VkDeviceSize				bufferOffset;
111 		0u,											//	deUint32					bufferRowLength;
112 		0u,											//	deUint32					bufferImageHeight;
113 		imageSubresource,							//	VkImageSubresourceLayers	imageSubresource;
114 		imageOffset,								//	VkOffset3D					imageOffset;
115 		imageExtent,								//	VkExtent3D					imageExtent;
116 	};
117 	return copyParams;
118 }
119 
120 //! Interpret the memory as IVec4
readVec4(const void * const data,const deUint32 ndx)121 inline tcu::Vec4 readVec4 (const void* const data, const deUint32 ndx)
122 {
123 	const float* const	p	= reinterpret_cast<const float*>(data);
124 	const deUint32		ofs	= 4 * ndx;
125 
126 	return tcu::Vec4(p[ofs+0], p[ofs+1], p[ofs+2], p[ofs+3]);
127 }
128 
129 class MisalignedCubeTestInstance : public TestInstance
130 {
131 public:
132 					MisalignedCubeTestInstance	(Context&			context,
133 												 const tcu::IVec3&	size,
134 												 const VkFormat		format);
135 	tcu::TestStatus	iterate						(void);
136 
137 private:
138 	const tcu::IVec3&	m_size;
139 	const VkFormat		m_format;
140 };
141 
MisalignedCubeTestInstance(Context & context,const tcu::IVec3 & size,const VkFormat format)142 MisalignedCubeTestInstance::MisalignedCubeTestInstance (Context& context, const tcu::IVec3& size, const VkFormat format)
143 	: TestInstance	(context)
144 	, m_size		(size)
145 	, m_format		(format)
146 {
147 }
148 
iterate(void)149 tcu::TestStatus MisalignedCubeTestInstance::iterate (void)
150 {
151 	DE_ASSERT(de::inRange(m_size.z(), 6, 16));
152 	DE_ASSERT(m_format == VK_FORMAT_R8G8B8A8_UNORM);
153 
154 	const DeviceInterface&			vk						= m_context.getDeviceInterface();
155 	const VkDevice					device					= m_context.getDevice();
156 	Allocator&						allocator				= m_context.getDefaultAllocator();
157 	const VkQueue					queue					= m_context.getUniversalQueue();
158 	const deUint32					queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
159 	const deUint32					numLayers				= m_size.z();
160 	const deUint32					cube0LayerStart			= 0;
161 	const deUint32					cube1LayerStart			= numLayers - 6u;
162 	const VkDeviceSize				resultBufferSizeBytes	= 2 * 6 * 4 * sizeof(float);	// vec4[6] in shader
163 	const VkExtent3D				imageExtent				= makeExtent3D(m_size.x(), m_size.y(), 1u);
164 	const deUint32					pixelSize				= static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(m_format)));
165 	const deUint32					layerSize				= imageExtent.width * imageExtent.height * pixelSize;
166 	const float						eps						= 1.0f / float(2 * 256);
167 
168 	const VkBufferCreateInfo		resultBufferCreateInfo	= makeBufferCreateInfo(resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
169 	de::MovePtr<BufferWithMemory>	resultBuffer			= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
170 	const Allocation&				resultBufferAlloc		= resultBuffer->getAllocation();
171 	const VkImageCreateInfo			imageCreateInfo			= makeImageCreateInfo(m_size, m_format);
172 	de::MovePtr<Image>				image					= de::MovePtr<Image>(new Image(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
173 	const VkImageSubresourceRange	imageSubresourceRange0	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, cube0LayerStart, 6u);
174 	Move<VkImageView>				imageView0				= makeImageView(vk, device, image->get(), VK_IMAGE_VIEW_TYPE_CUBE, m_format, imageSubresourceRange0);
175 	const VkImageSubresourceRange	imageSubresourceRange1	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, cube1LayerStart, 6u);
176 	Move<VkImageView>				imageView1				= makeImageView(vk, device, image->get(), VK_IMAGE_VIEW_TYPE_CUBE, m_format, imageSubresourceRange1);
177 
178 	Move<VkDescriptorSetLayout>		descriptorSetLayout		= DescriptorSetLayoutBuilder()
179 																.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
180 																.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
181 																.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
182 																.build(vk, device);
183 	Move<VkDescriptorPool>			descriptorPool			= DescriptorPoolBuilder()
184 																.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
185 																.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
186 																.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
187 																.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
188 	Move<VkDescriptorSet>			descriptorSet			= makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
189 	const VkDescriptorImageInfo		descriptorImageInfo0	= makeDescriptorImageInfo(DE_NULL, *imageView0, VK_IMAGE_LAYOUT_GENERAL);
190 	const VkDescriptorImageInfo		descriptorImageInfo1	= makeDescriptorImageInfo(DE_NULL, *imageView1, VK_IMAGE_LAYOUT_GENERAL);
191 	const VkDescriptorBufferInfo	descriptorBufferInfo	= makeDescriptorBufferInfo(resultBuffer->get(), 0ull, resultBufferSizeBytes);
192 
193 	const Move<VkShaderModule>		shaderModule			= createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0);
194 	const Move<VkPipelineLayout>	pipelineLayout			= makePipelineLayout(vk, device, *descriptorSetLayout);
195 	const Move<VkPipeline>			pipeline				= makeComputePipeline(vk, device, *pipelineLayout, *shaderModule);
196 	const Move<VkCommandPool>		cmdPool					= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
197 	const Move<VkCommandBuffer>		cmdBuffer				= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
198 
199 	const VkDeviceSize				clearBufferSize			= layerSize * numLayers;
200 	const Move<VkBuffer>			clearBuffer				= makeBuffer(vk, device, clearBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
201 	const de::MovePtr<Allocation>	clearBufferAlloc		= bindBuffer(vk, device, allocator, *clearBuffer, MemoryRequirement::HostVisible);
202 	const VkImageSubresourceRange	clearSubresRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, numLayers);
203 	const VkImageMemoryBarrier		clearBarrier			= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
204 																					 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
205 																					 image->get(), clearSubresRange);
206 	const VkImageMemoryBarrier		preShaderImageBarrier	= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
207 																					 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
208 																					 image->get(), clearSubresRange);
209 	const VkBufferMemoryBarrier		postShaderBarrier		= makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
210 																					  resultBuffer->get(), 0ull, VK_WHOLE_SIZE);
211 	bool							result					= true;
212 
213 	DescriptorSetUpdateBuilder()
214 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo0)
215 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo1)
216 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo)
217 		.update(vk, device);
218 
219 	beginCommandBuffer(vk, *cmdBuffer);
220 
221 	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
222 	vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
223 
224 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &clearBarrier);
225 
226 	// Clear layers with predefined values
227 	for (deUint32 layerNdx = 0; layerNdx < numLayers; ++layerNdx)
228 	{
229 		const float						componentValue			= float(16 * layerNdx) / 255.0f;
230 		const tcu::Vec4					clearColor				= tcu::Vec4(componentValue, componentValue, componentValue, 1.0f);
231 		const VkDeviceSize				bufferOffset			= layerNdx * layerSize;
232 		const VkImageSubresourceLayers	imageSubresource		= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, layerNdx, 1u);
233 		const VkBufferImageCopy			bufferImageCopyRegion	= makeBufferImageCopy(bufferOffset, imageSubresource, makeOffset3D(0u, 0u, 0u), imageExtent);
234 
235 		fillBuffer(vk, device, *clearBufferAlloc, bufferOffset, layerSize, m_format, clearColor);
236 
237 		vk.cmdCopyBufferToImage(*cmdBuffer, *clearBuffer, image->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopyRegion);
238 	}
239 
240 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preShaderImageBarrier);
241 
242 	vk.cmdDispatch(*cmdBuffer, 1, 1, 1);
243 
244 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, DE_NULL, 1, &postShaderBarrier, 0, DE_NULL);
245 
246 	endCommandBuffer(vk, *cmdBuffer);
247 
248 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
249 
250 	invalidateAlloc(vk, device, resultBufferAlloc);
251 
252 	// Check cube 0
253 	for (deUint32 layerNdx = 0; layerNdx < 6; ++layerNdx)
254 	{
255 		const deUint32	layerUsed		= cube0LayerStart + layerNdx;
256 		const float		componentValue	= float(16 * layerUsed) / 255.0f;
257 		const tcu::Vec4	expectedColor	= tcu::Vec4(componentValue, componentValue, componentValue, 1.0f);
258 		const tcu::Vec4	resultColor		= readVec4(resultBufferAlloc.getHostPtr(), layerNdx);
259 		const tcu::Vec4	delta			= expectedColor - resultColor;
260 
261 		if (deFloatAbs(delta.x()) > eps || deFloatAbs(delta.y()) > eps || deFloatAbs(delta.z()) > eps || deFloatAbs(delta.w()) > eps)
262 			result = false;
263 	}
264 
265 	// Check cube 1
266 	for (deUint32 layerNdx = 0; layerNdx < 6; ++layerNdx)
267 	{
268 		const deUint32	layerUsed		= cube1LayerStart + layerNdx;
269 		const float		componentValue	= float(16 * layerUsed) / 255.0f;
270 		const tcu::Vec4	expectedColor	= tcu::Vec4(componentValue, componentValue, componentValue, 1.0f);
271 		const tcu::Vec4 resultColor		= readVec4(resultBufferAlloc.getHostPtr(), layerNdx + 6u);
272 		const tcu::Vec4	delta			= expectedColor - resultColor;
273 
274 		if (deFloatAbs(delta.x()) > eps || deFloatAbs(delta.y()) > eps || deFloatAbs(delta.z()) > eps || deFloatAbs(delta.w()) > eps)
275 			result = false;
276 	}
277 
278 	if (result)
279 		return tcu::TestStatus::pass("pass");
280 	else
281 		return tcu::TestStatus::fail("fail");
282 }
283 
284 class MisalignedCubeTest : public TestCase
285 {
286 public:
287 						MisalignedCubeTest	(tcu::TestContext&	testCtx,
288 											 const std::string&	name,
289 											 const std::string&	description,
290 											 const tcu::IVec3&	size,
291 											 const VkFormat		format);
292 
293 	void				initPrograms		(SourceCollections& programCollection) const;
294 	TestInstance*		createInstance		(Context&			context) const;
295 
296 private:
297 	const tcu::IVec3	m_size;
298 	const VkFormat		m_format;
299 };
300 
MisalignedCubeTest(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const tcu::IVec3 & size,const VkFormat format)301 MisalignedCubeTest::MisalignedCubeTest (tcu::TestContext&	testCtx,
302 										const std::string&	name,
303 										const std::string&	description,
304 										const tcu::IVec3&	size,
305 										const VkFormat		format)
306 	: TestCase	(testCtx, name, description)
307 	, m_size	(size)
308 	, m_format	(format)
309 {
310 }
311 
initPrograms(SourceCollections & programCollection) const312 void MisalignedCubeTest::initPrograms (SourceCollections& programCollection) const
313 {
314 	const std::string formatQualifierStr = getShaderImageFormatQualifier(mapVkFormat(m_format));
315 
316 	std::ostringstream src;
317 	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
318 		<< "\n"
319 		<< "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
320 		<< "layout (binding = 0, " << formatQualifierStr << ") " << "readonly uniform highp imageCube u_cubeImage0;\n"
321 		<< "layout (binding = 1, " << formatQualifierStr << ") " << "readonly uniform highp imageCube u_cubeImage1;\n"
322 		<< "layout (binding = 2) writeonly buffer Output\n"
323 		<< "{\n"
324 		<< "    vec4 cube0_color0;\n"
325 		<< "    vec4 cube0_color1;\n"
326 		<< "    vec4 cube0_color2;\n"
327 		<< "    vec4 cube0_color3;\n"
328 		<< "    vec4 cube0_color4;\n"
329 		<< "    vec4 cube0_color5;\n"
330 		<< "    vec4 cube1_color0;\n"
331 		<< "    vec4 cube1_color1;\n"
332 		<< "    vec4 cube1_color2;\n"
333 		<< "    vec4 cube1_color3;\n"
334 		<< "    vec4 cube1_color4;\n"
335 		<< "    vec4 cube1_color5;\n"
336 		<< "} sb_out;\n"
337 		<< "\n"
338 		<< "void main (void)\n"
339 		<< "{\n"
340 		<< "    sb_out.cube0_color0 = imageLoad(u_cubeImage0, ivec3(1, 1, 0));\n"
341 		<< "    sb_out.cube0_color1 = imageLoad(u_cubeImage0, ivec3(1, 1, 1));\n"
342 		<< "    sb_out.cube0_color2 = imageLoad(u_cubeImage0, ivec3(1, 1, 2));\n"
343 		<< "    sb_out.cube0_color3 = imageLoad(u_cubeImage0, ivec3(1, 1, 3));\n"
344 		<< "    sb_out.cube0_color4 = imageLoad(u_cubeImage0, ivec3(1, 1, 4));\n"
345 		<< "    sb_out.cube0_color5 = imageLoad(u_cubeImage0, ivec3(1, 1, 5));\n"
346 		<< "    sb_out.cube1_color0 = imageLoad(u_cubeImage1, ivec3(1, 1, 0));\n"
347 		<< "    sb_out.cube1_color1 = imageLoad(u_cubeImage1, ivec3(1, 1, 1));\n"
348 		<< "    sb_out.cube1_color2 = imageLoad(u_cubeImage1, ivec3(1, 1, 2));\n"
349 		<< "    sb_out.cube1_color3 = imageLoad(u_cubeImage1, ivec3(1, 1, 3));\n"
350 		<< "    sb_out.cube1_color4 = imageLoad(u_cubeImage1, ivec3(1, 1, 4));\n"
351 		<< "    sb_out.cube1_color5 = imageLoad(u_cubeImage1, ivec3(1, 1, 5));\n"
352 		<< "}\n";
353 
354 	programCollection.glslSources.add("comp") << glu::ComputeSource(src.str());
355 }
356 
createInstance(Context & context) const357 TestInstance* MisalignedCubeTest::createInstance (Context& context) const
358 {
359 	return new MisalignedCubeTestInstance(context, m_size, m_format);
360 }
361 
362 //! Base sizes used to generate actual imager sizes in the test.
363 static const tcu::IVec3 s_baseImageSizes[] =
364 {
365 	tcu::IVec3(16, 16,  7),
366 	tcu::IVec3(16, 16,  8),
367 	tcu::IVec3(16, 16,  9),
368 	tcu::IVec3(16, 16, 10),
369 	tcu::IVec3(16, 16, 11),
370 };
371 
372 } // anonymous ns
373 
createMisalignedCubeTests(tcu::TestContext & testCtx)374 tcu::TestCaseGroup* createMisalignedCubeTests (tcu::TestContext& testCtx)
375 {
376 	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "misaligned_cube", "Cube image with misaligned baseArrayLayer test cases"));
377 
378 	const VkFormat	format	= VK_FORMAT_R8G8B8A8_UNORM;
379 
380 	for (int imageSizeNdx = 0; imageSizeNdx < DE_LENGTH_OF_ARRAY(s_baseImageSizes); ++imageSizeNdx)
381 	{
382 		const tcu::IVec3	size	= s_baseImageSizes[imageSizeNdx];
383 
384 		testGroup->addChild(new MisalignedCubeTest(testCtx, de::toString(size.z()), "", size, format));
385 	}
386 
387 	return testGroup.release();
388 }
389 
390 } // image
391 } // vkt
392