• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 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 Image size Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktImageSizeTests.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 
42 #include "deUniquePtr.hpp"
43 #include "deStringUtil.hpp"
44 
45 #include <string>
46 
47 using namespace vk;
48 
49 namespace vkt
50 {
51 namespace image
52 {
53 namespace
54 {
55 
56 //! Get a texture based on image type and suggested size.
getTexture(const ImageType imageType,const tcu::IVec3 & size)57 Texture getTexture (const ImageType imageType, const tcu::IVec3& size)
58 {
59 	switch (imageType)
60 	{
61 		case IMAGE_TYPE_1D:
62 		case IMAGE_TYPE_BUFFER:
63 			return Texture(imageType, tcu::IVec3(size.x(), 1, 1), 1);
64 
65 		case IMAGE_TYPE_1D_ARRAY:
66 			return Texture(imageType, tcu::IVec3(size.x(), 1, 1), size.y());
67 
68 		case IMAGE_TYPE_2D:
69 			return Texture(imageType, tcu::IVec3(size.x(), size.y(), 1), 1);
70 
71 		case IMAGE_TYPE_2D_ARRAY:
72 			return Texture(imageType, tcu::IVec3(size.x(), size.y(), 1), size.z());
73 
74 		case IMAGE_TYPE_CUBE:
75 			return Texture(imageType, tcu::IVec3(size.x(), size.x(), 1), 6);
76 
77 		case IMAGE_TYPE_CUBE_ARRAY:
78 			return Texture(imageType, tcu::IVec3(size.x(), size.x(), 1), 2*6);
79 
80 		case IMAGE_TYPE_3D:
81 			return Texture(imageType, size, 1);
82 
83 		default:
84 			DE_FATAL("Internal error");
85 			return Texture(IMAGE_TYPE_LAST, tcu::IVec3(), 0);
86 	}
87 }
88 
makeImageCreateInfo(const Texture & texture,const VkFormat format)89 inline VkImageCreateInfo makeImageCreateInfo (const Texture& texture, const VkFormat format)
90 {
91 	const VkImageCreateInfo imageParams =
92 	{
93 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,												// VkStructureType			sType;
94 		DE_NULL,																			// const void*				pNext;
95 		(isCube(texture) ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0u),	// VkImageCreateFlags		flags;
96 		mapImageType(texture.type()),														// VkImageType				imageType;
97 		format,																				// VkFormat					format;
98 		makeExtent3D(texture.layerSize()),													// VkExtent3D				extent;
99 		1u,																					// deUint32					mipLevels;
100 		(deUint32)texture.numLayers(),														// deUint32					arrayLayers;
101 		VK_SAMPLE_COUNT_1_BIT,																// VkSampleCountFlagBits	samples;
102 		VK_IMAGE_TILING_OPTIMAL,															// VkImageTiling			tiling;
103 		VK_IMAGE_USAGE_STORAGE_BIT,															// VkImageUsageFlags		usage;
104 		VK_SHARING_MODE_EXCLUSIVE,															// VkSharingMode			sharingMode;
105 		0u,																					// deUint32					queueFamilyIndexCount;
106 		DE_NULL,																			// const deUint32*			pQueueFamilyIndices;
107 		VK_IMAGE_LAYOUT_UNDEFINED,															// VkImageLayout			initialLayout;
108 	};
109 	return imageParams;
110 }
111 
112 //! Interpret the memory as IVec3
readIVec3(const void * const data)113 inline tcu::IVec3 readIVec3 (const void* const data)
114 {
115 	const int* const p = reinterpret_cast<const int*>(data);
116 	return tcu::IVec3(p[0], p[1], p[2]);
117 }
118 
getExpectedImageSizeResult(const Texture & texture)119 tcu::IVec3 getExpectedImageSizeResult (const Texture& texture)
120 {
121 	// GLSL imageSize() function returns:
122 	// z = 0 for cubes
123 	// z = N for cube arrays, where N is the number of cubes
124 	// y or z = L where L is the number of layers for other array types (e.g. 1D array, 2D array)
125 	// z = D where D is the depth of 3d image
126 
127 	const tcu::IVec3 size = texture.size();
128 	const int numCubeFaces = 6;
129 
130 	switch (texture.type())
131 	{
132 		case IMAGE_TYPE_1D:
133 		case IMAGE_TYPE_BUFFER:
134 			return tcu::IVec3(size.x(), 0, 0);
135 
136 		case IMAGE_TYPE_1D_ARRAY:
137 		case IMAGE_TYPE_2D:
138 		case IMAGE_TYPE_CUBE:
139 			return tcu::IVec3(size.x(), size.y(), 0);
140 
141 		case IMAGE_TYPE_2D_ARRAY:
142 		case IMAGE_TYPE_3D:
143 			return size;
144 
145 		case IMAGE_TYPE_CUBE_ARRAY:
146 			return tcu::IVec3(size.x(), size.y(), size.z() / numCubeFaces);
147 
148 		default:
149 			DE_FATAL("Internal error");
150 			return tcu::IVec3();
151 	}
152 }
153 
154 class SizeTest : public TestCase
155 {
156 public:
157 	enum TestFlags
158 	{
159 		FLAG_READONLY_IMAGE		= 1u << 0,
160 		FLAG_WRITEONLY_IMAGE	= 1u << 1,
161 	};
162 
163 						SizeTest			(tcu::TestContext&	testCtx,
164 											 const std::string&	name,
165 											 const std::string&	description,
166 											 const Texture&		texture,
167 											 const VkFormat		format,
168 											 const deUint32		flags = 0);
169 
170 	void				initPrograms		(SourceCollections& programCollection) const;
171 	TestInstance*		createInstance		(Context&			context) const;
172 	virtual void		checkSupport		(Context&			context) const;
173 
174 private:
175 	const Texture		m_texture;
176 	const VkFormat		m_format;
177 	const bool			m_useReadonly;
178 	const bool			m_useWriteonly;
179 };
180 
SizeTest(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const Texture & texture,const VkFormat format,const deUint32 flags)181 SizeTest::SizeTest (tcu::TestContext&		testCtx,
182 					const std::string&		name,
183 					const std::string&		description,
184 					const Texture&			texture,
185 					const VkFormat			format,
186 					const deUint32			flags)
187 	: TestCase			(testCtx, name, description)
188 	, m_texture			(texture)
189 	, m_format			(format)
190 	, m_useReadonly		((flags & FLAG_READONLY_IMAGE) != 0)
191 	, m_useWriteonly	((flags & FLAG_WRITEONLY_IMAGE) != 0)
192 {
193 	// We expect at least one flag to be set.
194 	DE_ASSERT(m_useReadonly || m_useWriteonly);
195 }
196 
checkSupport(Context & context) const197 void SizeTest::checkSupport (Context& context) const
198 {
199 	if (m_texture.type() == IMAGE_TYPE_CUBE_ARRAY)
200 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY);
201 }
202 
initPrograms(SourceCollections & programCollection) const203 void SizeTest::initPrograms (SourceCollections& programCollection) const
204 {
205 	const std::string formatQualifierStr = getShaderImageFormatQualifier(mapVkFormat(m_format));
206 	const std::string imageTypeStr = getShaderImageType(mapVkFormat(m_format), m_texture.type());
207 	const int dimension = m_texture.dimension();
208 
209 	std::ostringstream accessQualifier;
210 	if (m_useReadonly)
211 		accessQualifier << " readonly";
212 	if (m_useWriteonly)
213 		accessQualifier << " writeonly";
214 
215 	std::ostringstream src;
216 	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
217 		<< "\n"
218 		<< "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
219 		<< "layout (binding = 0, " << formatQualifierStr << ")" << accessQualifier.str() << " uniform highp " << imageTypeStr << " u_image;\n"
220 		<< "layout (binding = 1) writeonly buffer Output {\n"
221 		<< "    ivec3 size;\n"
222 		<< "} sb_out;\n"
223 		<< "\n"
224 		<< "void main (void)\n"
225 		<< "{\n"
226 		<< (dimension == 1 ?
227 			"    sb_out.size = ivec3(imageSize(u_image), 0, 0);\n"
228 			: dimension == 2 || m_texture.type() == IMAGE_TYPE_CUBE ?		// cubes return ivec2
229 			"    sb_out.size = ivec3(imageSize(u_image), 0);\n"
230 			: dimension == 3 ?												// cube arrays return ivec3
231 			"    sb_out.size = imageSize(u_image);\n"
232 			: "")
233 		<< "}\n";
234 
235 	programCollection.glslSources.add("comp") << glu::ComputeSource(src.str());
236 }
237 
238 //! Build a case name, e.g. "readonly_writeonly_32x32"
getCaseName(const Texture & texture,const deUint32 flags)239 std::string getCaseName (const Texture& texture, const deUint32 flags)
240 {
241 	std::ostringstream str;
242 	str << ((flags & SizeTest::FLAG_READONLY_IMAGE) != 0 ? "readonly_" : "")
243 		<< ((flags & SizeTest::FLAG_WRITEONLY_IMAGE) != 0 ? "writeonly_" : "");
244 
245 	const int numComponents = texture.dimension();
246 	for (int i = 0; i < numComponents; ++i)
247 		str << (i == 0 ? "" : "x") << texture.size()[i];
248 
249 	return str.str();
250 }
251 
252 //! Base test instance for image and buffer tests
253 class SizeTestInstance : public TestInstance
254 {
255 public:
256 									SizeTestInstance			(Context&				context,
257 																 const Texture&			texture,
258 																 const VkFormat			format);
259 
260 	tcu::TestStatus                 iterate						(void);
~SizeTestInstance(void)261 	virtual							~SizeTestInstance			(void) {}
262 
263 protected:
264 	virtual VkDescriptorSetLayout	prepareDescriptors			(void) = 0;
265 	virtual VkDescriptorSet         getDescriptorSet			(void) const = 0;
266 	virtual void					commandBeforeCompute		(const VkCommandBuffer	cmdBuffer) = 0;
267 
268 	const Texture					m_texture;
269 	const VkFormat					m_format;
270 	const VkDeviceSize				m_resultBufferSizeBytes;
271 	de::MovePtr<Buffer>				m_resultBuffer;				//!< Shader writes the output here.
272 };
273 
SizeTestInstance(Context & context,const Texture & texture,const VkFormat format)274 SizeTestInstance::SizeTestInstance (Context& context, const Texture& texture, const VkFormat format)
275 	: TestInstance				(context)
276 	, m_texture					(texture)
277 	, m_format					(format)
278 	, m_resultBufferSizeBytes	(3 * sizeof(deUint32))	// ivec3 in shader
279 {
280 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
281 	const VkDevice			device		= m_context.getDevice();
282 	Allocator&				allocator	= m_context.getDefaultAllocator();
283 
284 	// Create an SSBO for shader output.
285 
286 	m_resultBuffer = de::MovePtr<Buffer>(new Buffer(
287 		vk, device, allocator,
288 		makeBufferCreateInfo(m_resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
289 		MemoryRequirement::HostVisible));
290 }
291 
iterate(void)292 tcu::TestStatus SizeTestInstance::iterate (void)
293 {
294 	const DeviceInterface&	vk					= m_context.getDeviceInterface();
295 	const VkDevice			device				= m_context.getDevice();
296 	const VkQueue			queue				= m_context.getUniversalQueue();
297 	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
298 
299 	// Create memory barriers.
300 
301 	const VkBufferMemoryBarrier shaderWriteBarrier = makeBufferMemoryBarrier(
302 		VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
303 		m_resultBuffer->get(), 0ull, m_resultBufferSizeBytes);
304 
305 	// Create the pipeline.
306 
307 	const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));
308 
309 	const VkDescriptorSetLayout descriptorSetLayout = prepareDescriptors();
310 	const VkDescriptorSet descriptorSet = getDescriptorSet();
311 
312 	const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, descriptorSetLayout));
313 	const Unique<VkPipeline> pipeline(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
314 
315 	const Unique<VkCommandPool> cmdPool(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
316 	const Unique<VkCommandBuffer> cmdBuffer(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
317 
318 	beginCommandBuffer(vk, *cmdBuffer);
319 
320 	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
321 	vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
322 
323 	commandBeforeCompute(*cmdBuffer);
324 	vk.cmdDispatch(*cmdBuffer, 1, 1, 1);
325 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &shaderWriteBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
326 
327 	endCommandBuffer(vk, *cmdBuffer);
328 
329 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
330 
331 	// Compare the result.
332 
333 	const Allocation& bufferAlloc = m_resultBuffer->getAllocation();
334 	invalidateAlloc(vk, device, bufferAlloc);
335 
336 	const tcu::IVec3 resultSize = readIVec3(bufferAlloc.getHostPtr());
337 	const tcu::IVec3 expectedSize = getExpectedImageSizeResult(m_texture);
338 
339 	if (resultSize != expectedSize)
340 		return tcu::TestStatus::fail("Incorrect imageSize(): expected " + de::toString(expectedSize) + " but got " + de::toString(resultSize));
341 	else
342 		return tcu::TestStatus::pass("Passed");
343 }
344 
345 class ImageSizeTestInstance : public SizeTestInstance
346 {
347 public:
348 									ImageSizeTestInstance		(Context&				context,
349 																 const Texture&			texture,
350 																 const VkFormat			format);
351 
352 protected:
353 	VkDescriptorSetLayout			prepareDescriptors			(void);
354 	void							commandBeforeCompute		(const VkCommandBuffer	cmdBuffer);
355 
getDescriptorSet(void) const356 	VkDescriptorSet                 getDescriptorSet			(void) const { return *m_descriptorSet; }
357 
358 	de::MovePtr<Image>				m_image;
359 	Move<VkImageView>				m_imageView;
360 	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
361 	Move<VkDescriptorPool>			m_descriptorPool;
362 	Move<VkDescriptorSet>			m_descriptorSet;
363 };
364 
ImageSizeTestInstance(Context & context,const Texture & texture,const VkFormat format)365 ImageSizeTestInstance::ImageSizeTestInstance (Context& context, const Texture& texture, const VkFormat format)
366 	: SizeTestInstance	(context, texture, format)
367 {
368 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
369 	const VkDevice			device		= m_context.getDevice();
370 	Allocator&				allocator	= m_context.getDefaultAllocator();
371 
372 	// Create an image. Its data be uninitialized, as we're not reading from it.
373 
374 	m_image = de::MovePtr<Image>(new Image(vk, device, allocator, makeImageCreateInfo(m_texture, m_format), MemoryRequirement::Any));
375 
376 	const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_texture.numLayers());
377 	m_imageView = makeImageView(vk, device, m_image->get(), mapImageViewType(m_texture.type()), m_format, subresourceRange);
378 }
379 
prepareDescriptors(void)380 VkDescriptorSetLayout ImageSizeTestInstance::prepareDescriptors (void)
381 {
382 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
383 	const VkDevice			device	= m_context.getDevice();
384 
385 	m_descriptorSetLayout = DescriptorSetLayoutBuilder()
386 		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
387 		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
388 		.build(vk, device);
389 
390 	m_descriptorPool = DescriptorPoolBuilder()
391 		.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
392 		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
393 		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
394 
395 	m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
396 
397 	const VkDescriptorImageInfo descriptorImageInfo = makeDescriptorImageInfo(DE_NULL, *m_imageView, VK_IMAGE_LAYOUT_GENERAL);
398 	const VkDescriptorBufferInfo descriptorBufferInfo = makeDescriptorBufferInfo(m_resultBuffer->get(), 0ull, m_resultBufferSizeBytes);
399 
400 	DescriptorSetUpdateBuilder()
401 		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
402 		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo)
403 		.update(vk, device);
404 
405 	return *m_descriptorSetLayout;
406 }
407 
commandBeforeCompute(const VkCommandBuffer cmdBuffer)408 void ImageSizeTestInstance::commandBeforeCompute (const VkCommandBuffer cmdBuffer)
409 {
410 	const DeviceInterface& vk = m_context.getDeviceInterface();
411 
412 	const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_texture.numLayers());
413 	const VkImageMemoryBarrier barrierSetImageLayout = makeImageMemoryBarrier(
414 		0u, VK_ACCESS_SHADER_READ_BIT,
415 		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
416 		m_image->get(), subresourceRange);
417 
418 	vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &barrierSetImageLayout);
419 }
420 
421 class BufferSizeTestInstance : public SizeTestInstance
422 {
423 public:
424 									BufferSizeTestInstance		(Context&				context,
425 																 const Texture&			texture,
426 																 const VkFormat			format);
427 
428 protected:
429 	VkDescriptorSetLayout			prepareDescriptors			(void);
430 
commandBeforeCompute(const VkCommandBuffer)431 	void							commandBeforeCompute		(const VkCommandBuffer) {}
getDescriptorSet(void) const432 	VkDescriptorSet					getDescriptorSet			(void) const { return *m_descriptorSet; }
433 
434 	de::MovePtr<Buffer>				m_imageBuffer;
435 	Move<VkBufferView>				m_bufferView;
436 	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
437 	Move<VkDescriptorPool>			m_descriptorPool;
438 	Move<VkDescriptorSet>			m_descriptorSet;
439 };
440 
BufferSizeTestInstance(Context & context,const Texture & texture,const VkFormat format)441 BufferSizeTestInstance::BufferSizeTestInstance (Context& context, const Texture& texture, const VkFormat format)
442 	: SizeTestInstance	(context, texture, format)
443 {
444 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
445 	const VkDevice			device		= m_context.getDevice();
446 	Allocator&				allocator	= m_context.getDefaultAllocator();
447 
448 	// Create a texel storage buffer. Its data be uninitialized, as we're not reading from it.
449 
450 	const VkDeviceSize imageSizeBytes = getImageSizeBytes(m_texture.size(), m_format);
451 	m_imageBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
452 		makeBufferCreateInfo(imageSizeBytes, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT), MemoryRequirement::Any));
453 
454 	m_bufferView = makeBufferView(vk, device, m_imageBuffer->get(), m_format, 0ull, imageSizeBytes);
455 }
456 
prepareDescriptors(void)457 VkDescriptorSetLayout BufferSizeTestInstance::prepareDescriptors (void)
458 {
459 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
460 	const VkDevice			device	= m_context.getDevice();
461 
462 	m_descriptorSetLayout = DescriptorSetLayoutBuilder()
463 		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
464 		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
465 		.build(vk, device);
466 
467 	m_descriptorPool = DescriptorPoolBuilder()
468 		.addType(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
469 		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
470 		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
471 
472 	m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
473 
474 	const VkDescriptorBufferInfo descriptorBufferInfo = makeDescriptorBufferInfo(m_resultBuffer->get(), 0ull, m_resultBufferSizeBytes);
475 
476 	DescriptorSetUpdateBuilder()
477 		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, &m_bufferView.get())
478 		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo)
479 		.update(vk, device);
480 
481 	return *m_descriptorSetLayout;
482 }
483 
createInstance(Context & context) const484 TestInstance* SizeTest::createInstance (Context& context) const
485 {
486 	if (m_texture.type() == IMAGE_TYPE_BUFFER)
487 		return new BufferSizeTestInstance(context, m_texture, m_format);
488 	else
489 		return new ImageSizeTestInstance(context, m_texture, m_format);
490 }
491 
492 static const ImageType s_imageTypes[] =
493 {
494 	IMAGE_TYPE_1D,
495 	IMAGE_TYPE_1D_ARRAY,
496 	IMAGE_TYPE_2D,
497 	IMAGE_TYPE_2D_ARRAY,
498 	IMAGE_TYPE_3D,
499 	IMAGE_TYPE_CUBE,
500 	IMAGE_TYPE_CUBE_ARRAY,
501 	IMAGE_TYPE_BUFFER,
502 };
503 
504 //! Base sizes used to generate actual image/buffer sizes in the test.
505 static const tcu::IVec3 s_baseImageSizes[] =
506 {
507 	tcu::IVec3(32, 32, 32),
508 	tcu::IVec3(12, 34, 56),
509 	tcu::IVec3(1,   1,  1),
510 	tcu::IVec3(7,   1,  1),
511 };
512 
513 static const deUint32 s_flags[] =
514 {
515 	SizeTest::FLAG_READONLY_IMAGE,
516 	SizeTest::FLAG_WRITEONLY_IMAGE,
517 	SizeTest::FLAG_READONLY_IMAGE | SizeTest::FLAG_WRITEONLY_IMAGE,
518 };
519 
520 } // anonymous ns
521 
createImageSizeTests(tcu::TestContext & testCtx)522 tcu::TestCaseGroup* createImageSizeTests (tcu::TestContext& testCtx)
523 {
524 	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "image_size", "imageSize() cases"));
525 
526 	const VkFormat format = VK_FORMAT_R32G32B32A32_SFLOAT;
527 
528 	for (int imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++imageTypeNdx)
529 	{
530 		de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(s_imageTypes[imageTypeNdx]).c_str(), ""));
531 
532 		for (int flagNdx = 0; flagNdx < DE_LENGTH_OF_ARRAY(s_flags); ++flagNdx)
533 		for (int imageSizeNdx = 0; imageSizeNdx < DE_LENGTH_OF_ARRAY(s_baseImageSizes); ++imageSizeNdx)
534 		{
535 			const Texture texture = getTexture(s_imageTypes[imageTypeNdx], s_baseImageSizes[imageSizeNdx]);
536 			imageGroup->addChild(new SizeTest(testCtx, getCaseName(texture, s_flags[flagNdx]), "", texture, format, s_flags[flagNdx]));
537 		}
538 
539 		testGroup->addChild(imageGroup.release());
540 	}
541 	return testGroup.release();
542 }
543 
544 } // image
545 } // vkt
546