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