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