1029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch/*------------------------------------------------------------------------
2e7a343938a2845ba12fed436ebdec31785c144f0Pyry Haulos * Vulkan Conformance Tests
3e7a343938a2845ba12fed436ebdec31785c144f0Pyry Haulos * ------------------------
4e7a343938a2845ba12fed436ebdec31785c144f0Pyry Haulos *
5e7a343938a2845ba12fed436ebdec31785c144f0Pyry Haulos * Copyright (c) 2016 The Khronos Group Inc.
6e7a343938a2845ba12fed436ebdec31785c144f0Pyry Haulos *
7978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License");
8978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * you may not use this file except in compliance with the License.
9978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * You may obtain a copy of the License at
10e7a343938a2845ba12fed436ebdec31785c144f0Pyry Haulos *
11978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos *      http://www.apache.org/licenses/LICENSE-2.0
12e7a343938a2845ba12fed436ebdec31785c144f0Pyry Haulos *
13978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * Unless required by applicable law or agreed to in writing, software
14978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS,
15978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * See the License for the specific language governing permissions and
17978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * limitations under the License.
18e7a343938a2845ba12fed436ebdec31785c144f0Pyry Haulos *
19e7a343938a2845ba12fed436ebdec31785c144f0Pyry Haulos *//*!
20e7a343938a2845ba12fed436ebdec31785c144f0Pyry Haulos * \file  vktSparseResourcesImageSparseResidency.cpp
21e7a343938a2845ba12fed436ebdec31785c144f0Pyry Haulos * \brief Sparse partially resident images tests
22e7a343938a2845ba12fed436ebdec31785c144f0Pyry Haulos *//*--------------------------------------------------------------------*/
23029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
24029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "vktSparseResourcesBufferSparseBinding.hpp"
25029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "vktSparseResourcesTestsUtil.hpp"
26029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "vktSparseResourcesBase.hpp"
27029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "vktTestCaseUtil.hpp"
28029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
29029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "vkDefs.hpp"
30029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "vkRef.hpp"
31029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "vkRefUtil.hpp"
32029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "vkPlatform.hpp"
33029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "vkPrograms.hpp"
34029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "vkMemUtil.hpp"
35029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "vkBuilderUtil.hpp"
36029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "vkImageUtil.hpp"
37029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "vkQueryUtil.hpp"
38029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "vkTypeUtil.hpp"
39029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
40029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "deUniquePtr.hpp"
41029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include "deStringUtil.hpp"
42029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
43029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include <string>
44029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch#include <vector>
45029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
46029550532951eec8a34b752f1ea6957a4f1c69d9Kantochusing namespace vk;
47029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
48029550532951eec8a34b752f1ea6957a4f1c69d9Kantochnamespace vkt
49029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
50029550532951eec8a34b752f1ea6957a4f1c69d9Kantochnamespace sparse
51029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
52029550532951eec8a34b752f1ea6957a4f1c69d9Kantochnamespace
53029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
54029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
55029550532951eec8a34b752f1ea6957a4f1c69d9Kantochconst std::string getCoordStr  (const ImageType		imageType,
56029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch								const std::string&	x,
57029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch								const std::string&	y,
58029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch								const std::string&	z)
59029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
60029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	switch (imageType)
61029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
62029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case IMAGE_TYPE_1D:
63029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case IMAGE_TYPE_BUFFER:
64029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			return x;
65029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
66029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case IMAGE_TYPE_1D_ARRAY:
67029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case IMAGE_TYPE_2D:
68029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			return "ivec2(" + x + "," + y + ")";
69029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
70029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case IMAGE_TYPE_2D_ARRAY:
71029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case IMAGE_TYPE_3D:
72029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case IMAGE_TYPE_CUBE:
73029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case IMAGE_TYPE_CUBE_ARRAY:
74029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			return "ivec3(" + x + "," + y + "," + z + ")";
75029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
76029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		default:
77029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			DE_ASSERT(false);
78029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			return "";
79029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
80029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch}
81029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
82029550532951eec8a34b752f1ea6957a4f1c69d9KantochdeUint32 getNumUsedChannels (const tcu::TextureFormat& format)
83029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
84029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	switch (format.order)
85029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
86029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::R:			return 1;
87029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::A:			return 1;
88029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::I:			return 1;
89029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::L:			return 1;
90029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::LA:		return 2;
91029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::RG:		return 2;
92029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::RA:		return 2;
93029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::RGB:		return 3;
94029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::RGBA:		return 4;
95029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::ARGB:		return 4;
96029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::BGR:		return 3;
97029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::BGRA:		return 4;
98029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::sR:		return 1;
99029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::sRG:		return 2;
100029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::sRGB:		return 3;
101029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::sRGBA:		return 4;
102029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::sBGR:		return 3;
103029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::sBGRA:		return 4;
104029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::D:			return 1;
105029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::S:			return 1;
106029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case tcu::TextureFormat::DS:		return 2;
107029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		default:
108029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			DE_ASSERT(DE_FALSE);
109029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			return 0;
110029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
111029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch}
112029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
113029550532951eec8a34b752f1ea6957a4f1c69d9Kantochtcu::UVec3 alignedDivide (const VkExtent3D& extent, const VkExtent3D& divisor)
114029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
115029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	tcu::UVec3 result;
116029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
117029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	result.x() = extent.width  / divisor.width  + ((extent.width  % divisor.width)  ? 1u : 0u);
118029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	result.y() = extent.height / divisor.height + ((extent.height % divisor.height) ? 1u : 0u);
119029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	result.z() = extent.depth  / divisor.depth  + ((extent.depth  % divisor.depth)  ? 1u : 0u);
120029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
121029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	return result;
122029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch}
123029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
124029550532951eec8a34b752f1ea6957a4f1c69d9Kantochtcu::UVec3 computeWorkGroupSize (const tcu::UVec3& gridSize)
125029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
126029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const deUint32		maxComputeWorkGroupInvocations	= 128u;
127029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const tcu::UVec3	maxComputeWorkGroupSize			= tcu::UVec3(128u, 128u, 64u);
128029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
129029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const deUint32 xWorkGroupSize = std::min(std::min(gridSize.x(), maxComputeWorkGroupSize.x()), maxComputeWorkGroupInvocations);
130029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const deUint32 yWorkGroupSize = std::min(std::min(gridSize.y(), maxComputeWorkGroupSize.y()), maxComputeWorkGroupInvocations /  xWorkGroupSize);
131029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const deUint32 zWorkGroupSize = std::min(std::min(gridSize.z(), maxComputeWorkGroupSize.z()), maxComputeWorkGroupInvocations / (xWorkGroupSize*yWorkGroupSize));
132029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
133029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	return tcu::UVec3(xWorkGroupSize, yWorkGroupSize, zWorkGroupSize);
134029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch}
135029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
136029550532951eec8a34b752f1ea6957a4f1c69d9Kantochclass ImageSparseResidencyCase : public TestCase
137029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
138029550532951eec8a34b752f1ea6957a4f1c69d9Kantochpublic:
139029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					ImageSparseResidencyCase	(tcu::TestContext&			testCtx,
140029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch												 const std::string&			name,
141029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch												 const std::string&			description,
142029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch												 const ImageType			imageType,
143029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch												 const tcu::UVec3&			imageSize,
144029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch												 const tcu::TextureFormat&	format,
145029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch												 const glu::GLSLVersion		glslVersion);
146029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
147029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	void			initPrograms				(SourceCollections&			sourceCollections) const;
148029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	TestInstance*	createInstance				(Context&					context) const;
149029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
150029550532951eec8a34b752f1ea6957a4f1c69d9Kantochprivate:
151029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const ImageType				m_imageType;
152029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const tcu::UVec3			m_imageSize;
153029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const tcu::TextureFormat	m_format;
154029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const glu::GLSLVersion		m_glslVersion;
155029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch};
156029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
157029550532951eec8a34b752f1ea6957a4f1c69d9KantochImageSparseResidencyCase::ImageSparseResidencyCase (tcu::TestContext&			testCtx,
158029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch													const std::string&			name,
159029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch													const std::string&			description,
160029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch													const ImageType				imageType,
161029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch													const tcu::UVec3&			imageSize,
162029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch													const tcu::TextureFormat&	format,
163029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch													const glu::GLSLVersion		glslVersion)
164029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	: TestCase				(testCtx, name, description)
165029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	, m_imageType			(imageType)
166029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	, m_imageSize			(imageSize)
167029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	, m_format				(format)
168029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	, m_glslVersion			(glslVersion)
169029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
170029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch}
171029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
172029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
173029550532951eec8a34b752f1ea6957a4f1c69d9Kantochvoid ImageSparseResidencyCase::initPrograms (SourceCollections&	sourceCollections) const
174029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
175029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Create compute program
176029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const char* const versionDecl			= glu::getGLSLVersionDeclaration(m_glslVersion);
177029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const std::string imageTypeStr			= getShaderImageType(m_format, m_imageType);
178029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const std::string formatQualifierStr	= getShaderImageFormatQualifier(m_format);
179029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const std::string formatDataStr			= getShaderImageDataType(m_format);
180029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const tcu::UVec3  gridSize				= getShaderGridSize(m_imageType, m_imageSize);
181029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const tcu::UVec3  workGroupSize			= computeWorkGroupSize(gridSize);
182029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
183029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	std::ostringstream src;
184029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	src << versionDecl << "\n"
185029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		<< "layout (local_size_x = " << workGroupSize.x() << ", local_size_y = " << workGroupSize.y() << ", local_size_z = " << workGroupSize.z() << ") in; \n"
186029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		<< "layout (binding = 0, " << formatQualifierStr << ") writeonly uniform highp " << imageTypeStr << " u_image;\n"
187029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		<< "void main (void)\n"
188029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		<< "{\n"
189029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		<< "	if( gl_GlobalInvocationID.x < " << gridSize.x() << " ) \n"
190029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		<< "	if( gl_GlobalInvocationID.y < " << gridSize.y() << " ) \n"
191029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		<< "	if( gl_GlobalInvocationID.z < " << gridSize.z() << " ) \n"
192029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		<< "	{\n"
193029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		<< "		imageStore(u_image, " << getCoordStr(m_imageType, "gl_GlobalInvocationID.x", "gl_GlobalInvocationID.y", "gl_GlobalInvocationID.z") << ","
194029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		<< formatDataStr << "( int(gl_GlobalInvocationID.x) % 127, int(gl_GlobalInvocationID.y) % 127, int(gl_GlobalInvocationID.z) % 127, 1));\n"
195029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		<< "	}\n"
196029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		<< "}\n";
197029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
198029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	sourceCollections.glslSources.add("comp") << glu::ComputeSource(src.str());
199029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch}
200029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
201029550532951eec8a34b752f1ea6957a4f1c69d9Kantochclass ImageSparseResidencyInstance : public SparseResourcesBaseInstance
202029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
203029550532951eec8a34b752f1ea6957a4f1c69d9Kantochpublic:
204029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					ImageSparseResidencyInstance(Context&									 context,
205029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch												 const ImageType							 imageType,
206029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch												 const tcu::UVec3&							 imageSize,
207029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch												 const tcu::TextureFormat&					 format);
208029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
209029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	tcu::TestStatus	iterate						(void);
210029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
211029550532951eec8a34b752f1ea6957a4f1c69d9Kantochprivate:
212029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const ImageType				m_imageType;
213029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const tcu::UVec3			m_imageSize;
214029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const tcu::TextureFormat	m_format;
215029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch};
216029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
217029550532951eec8a34b752f1ea6957a4f1c69d9KantochImageSparseResidencyInstance::ImageSparseResidencyInstance (Context&					context,
218029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch															const ImageType				imageType,
219029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch															const tcu::UVec3&			imageSize,
220029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch															const tcu::TextureFormat&	format)
221029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	: SparseResourcesBaseInstance	(context)
222029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	, m_imageType					(imageType)
223029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	, m_imageSize					(imageSize)
224029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	, m_format						(format)
225029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
226029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch}
227029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
228029550532951eec8a34b752f1ea6957a4f1c69d9Kantochtcu::TestStatus ImageSparseResidencyInstance::iterate (void)
229029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
230029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const InstanceInterface&			 instance		 = m_context.getInstanceInterface();
231029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const DeviceInterface&				 deviceInterface = m_context.getDeviceInterface();
232029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkPhysicalDevice				 physicalDevice	 = m_context.getPhysicalDevice();
233029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkPhysicalDeviceFeatures		 deviceFeatures	 = getPhysicalDeviceFeatures(instance, physicalDevice);
234029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
235029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	switch (mapImageType(m_imageType))
236029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
237029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case VK_IMAGE_TYPE_2D:
238029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		{
239029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			if (deviceFeatures.sparseResidencyImage2D == false)
240029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Sparse residency for 2D Image not supported");
241029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		}
242029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		break;
243029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		case VK_IMAGE_TYPE_3D:
244029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		{
245029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			if (deviceFeatures.sparseResidencyImage3D == false)
246029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Sparse residency for 3D Image not supported");
247029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
248029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		}
249029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		break;
250029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		default:
251029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported image type");
252029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	};
253029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
254029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Check if the image format supports sparse operations
255029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec =
256029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		getPhysicalDeviceSparseImageFormatProperties(instance, physicalDevice, mapTextureFormat(m_format), mapImageType(m_imageType),
257029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_TILING_OPTIMAL);
258029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
259029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	if (sparseImageFormatPropVec.size() == 0)
260029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
261029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "The image format does not support sparse operations");
262029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
263029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
264029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
265029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
266029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	if (isImageSizeSupported(m_imageType, m_imageSize, deviceProperties.limits) == false)
267029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
268029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Image size not supported for device");
269029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
270029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
271029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	QueueRequirementsVec queueRequirements;
272029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	queueRequirements.push_back(QueueRequirements(VK_QUEUE_SPARSE_BINDING_BIT, 1u));
273029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	queueRequirements.push_back(QueueRequirements(VK_QUEUE_COMPUTE_BIT, 1u));
274029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
275029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Create logical device supporting both sparse and compute queues
276029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	if (!createDeviceSupportingQueues(queueRequirements))
277029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
278029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Could not create device supporting sparse and compute queue");
279029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
280029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
281029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
282029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
283029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Create memory allocator for logical device
284029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const de::UniquePtr<Allocator> allocator(new SimpleAllocator(deviceInterface, *m_logicalDevice, deviceMemoryProperties));
285029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
286029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Create queue supporting sparse binding operations
287029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const Queue& sparseQueue = getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
288029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
289029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Create queue supporting compute and transfer operations
290029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const Queue& computeQueue = getQueue(VK_QUEUE_COMPUTE_BIT, 0);
291029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
292029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	VkImageCreateInfo imageCreateInfo;
293029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
294029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.sType					= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;					//VkStructureType		sType;
295029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.pNext					= DE_NULL;												//const void*			pNext;
296029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.flags					= VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;					//VkImageCreateFlags	flags;
297029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.imageType				= mapImageType(m_imageType);							//VkImageType			imageType;
298029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.format					= mapTextureFormat(m_format);							//VkFormat				format;
299029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.extent					= makeExtent3D(getLayerSize(m_imageType, m_imageSize));	//VkExtent3D			extent;
300029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.mipLevels				= 1u;													//deUint32				mipLevels;
301029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.arrayLayers				= getNumLayers(m_imageType, m_imageSize);				//deUint32				arrayLayers;
302029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.samples					= VK_SAMPLE_COUNT_1_BIT;								//VkSampleCountFlagBits	samples;
303029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.tiling					= VK_IMAGE_TILING_OPTIMAL;								//VkImageTiling			tiling;
304029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.initialLayout			= VK_IMAGE_LAYOUT_UNDEFINED;							//VkImageLayout			initialLayout;
305029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.usage					= VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
306029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch											  VK_IMAGE_USAGE_STORAGE_BIT;							//VkImageUsageFlags		usage;
307029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.sharingMode				= VK_SHARING_MODE_EXCLUSIVE;							//VkSharingMode			sharingMode;
308029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.queueFamilyIndexCount	= 0u;													//deUint32				queueFamilyIndexCount;
309029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	imageCreateInfo.pQueueFamilyIndices		= DE_NULL;												//const deUint32*		pQueueFamilyIndices;
310029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
311029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
312029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
313029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageCreateInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
314029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
315029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
316029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const deUint32 queueFamilyIndices[] = { sparseQueue.queueFamilyIndex, computeQueue.queueFamilyIndex };
317029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
318029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	if (sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex)
319029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
320029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageCreateInfo.sharingMode				= VK_SHARING_MODE_CONCURRENT;	//VkSharingMode			sharingMode;
321029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageCreateInfo.queueFamilyIndexCount	= 2u;							//deUint32				queueFamilyIndexCount;
322029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageCreateInfo.pQueueFamilyIndices		= queueFamilyIndices;			//const deUint32*		pQueueFamilyIndices;
323029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
324029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
325029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Create sparse image
326029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const Unique<VkImage> sparseImage(createImage(deviceInterface, *m_logicalDevice, &imageCreateInfo));
327029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
328029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Get image general memory requirements
329029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkMemoryRequirements imageMemoryRequirements = getImageMemoryRequirements(deviceInterface, *m_logicalDevice, *sparseImage);
330029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
331029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	if (imageMemoryRequirements.size > deviceProperties.limits.sparseAddressSpaceSize)
332029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
333029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Required memory size for sparse resource exceeds device limits");
334029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
335029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
336029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	DE_ASSERT((imageMemoryRequirements.size % imageMemoryRequirements.alignment) == 0);
337029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
338029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Get image sparse memory requirements
339029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	deUint32 sparseMemoryReqCount = 0;
340029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
341029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	deviceInterface.getImageSparseMemoryRequirements(*m_logicalDevice, *sparseImage, &sparseMemoryReqCount, DE_NULL);
342029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
343029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	DE_ASSERT(sparseMemoryReqCount != 0);
344029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
345029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	std::vector<VkSparseImageMemoryRequirements> sparseImageMemoryRequirements;
346029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	sparseImageMemoryRequirements.resize(sparseMemoryReqCount);
347029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
348029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	deviceInterface.getImageSparseMemoryRequirements(*m_logicalDevice, *sparseImage, &sparseMemoryReqCount, &sparseImageMemoryRequirements[0]);
349029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
350029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Make sure the image type includes color aspect
351029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	deUint32 colorAspectIndex = NO_MATCH_FOUND;
352029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
353029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	for (deUint32 memoryReqNdx = 0; memoryReqNdx < sparseMemoryReqCount; ++memoryReqNdx)
354029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
355029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		if (sparseImageMemoryRequirements[memoryReqNdx].formatProperties.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT)
356029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		{
357029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			colorAspectIndex = memoryReqNdx;
358029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			break;
359029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		}
360029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
361029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
362029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	if (colorAspectIndex == NO_MATCH_FOUND)
363029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
364029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported image aspect - the test supports currently only VK_IMAGE_ASPECT_COLOR_BIT");
365029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
366029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
367029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkSparseImageMemoryRequirements aspectRequirements	= sparseImageMemoryRequirements[colorAspectIndex];
368029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkImageAspectFlags			  aspectMask			= aspectRequirements.formatProperties.aspectMask;
369029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkExtent3D					  imageGranularity		= aspectRequirements.formatProperties.imageGranularity;
370029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
371029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	DE_ASSERT((aspectRequirements.imageMipTailSize % imageMemoryRequirements.alignment) == 0);
372029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
373029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	typedef de::SharedPtr< Unique<VkDeviceMemory> > DeviceMemoryUniquePtr;
374029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
375029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	std::vector<VkSparseImageMemoryBind> imageResidencyMemoryBinds;
376029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	std::vector<VkSparseMemoryBind>		 imageMipTailMemoryBinds;
377029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	std::vector<DeviceMemoryUniquePtr>	 deviceMemUniquePtrVec;
378029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const deUint32						 memoryType = findMatchingMemoryType(deviceMemoryProperties, imageMemoryRequirements, MemoryRequirement::Any);
379029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
380029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	if (memoryType == NO_MATCH_FOUND)
381029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
382029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		return tcu::TestStatus(QP_TEST_RESULT_FAIL, "No matching memory type found");
383029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
384029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
385029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Bind device memory for each aspect
386029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	for (deUint32 layerNdx = 0; layerNdx < imageCreateInfo.arrayLayers; ++layerNdx)
387029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
388029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		for (deUint32 mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx)
389029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		{
390029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			const VkExtent3D		 mipExtent			= mipLevelExtents(imageCreateInfo.extent, mipLevelNdx);
391029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			const tcu::UVec3		 numSparseBinds		= alignedDivide(mipExtent, imageGranularity);
392029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			const tcu::UVec3		 lastBlockExtent	= tcu::UVec3(mipExtent.width  % imageGranularity.width  ? mipExtent.width  % imageGranularity.width  : imageGranularity.width,
393029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch																	 mipExtent.height % imageGranularity.height ? mipExtent.height % imageGranularity.height : imageGranularity.height,
394029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch																	 mipExtent.depth  % imageGranularity.depth  ? mipExtent.depth  % imageGranularity.depth  : imageGranularity.depth );
395029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
396029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			for (deUint32 z = 0; z < numSparseBinds.z(); ++z)
397029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			for (deUint32 y = 0; y < numSparseBinds.y(); ++y)
398029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			for (deUint32 x = 0; x < numSparseBinds.x(); ++x)
399029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			{
400029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				const deUint32 linearIndex = x + y*numSparseBinds.x() + z*numSparseBinds.x()*numSparseBinds.y() + layerNdx*numSparseBinds.x()*numSparseBinds.y()*numSparseBinds.z();
401029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
402029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				if (linearIndex % 2 == 1)
403029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				{
404029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					continue;
405029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				}
406029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
407029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				const VkMemoryAllocateInfo allocInfo =
408029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				{
409029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType			sType;
410029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					DE_NULL,								//	const void*				pNext;
411029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					imageMemoryRequirements.alignment,		//	VkDeviceSize			allocationSize;
412029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					memoryType,								//	deUint32				memoryTypeIndex;
413029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				};
414029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
415029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				VkDeviceMemory deviceMemory = 0;
416029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				VK_CHECK(deviceInterface.allocateMemory(*m_logicalDevice, &allocInfo, DE_NULL, &deviceMemory));
417029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
418029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(deviceMemory), Deleter<VkDeviceMemory>(deviceInterface, *m_logicalDevice, DE_NULL))));
419029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
420029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				VkOffset3D offset;
421029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				offset.x = x*imageGranularity.width;
422029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				offset.y = y*imageGranularity.height;
423029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				offset.z = z*imageGranularity.depth;
424029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
425029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				VkExtent3D extent;
426029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				extent.width =  (x == numSparseBinds.x() - 1) ? lastBlockExtent.x() : imageGranularity.width;
427029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				extent.height = (y == numSparseBinds.y() - 1) ? lastBlockExtent.y() : imageGranularity.height;
428029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				extent.depth =  (z == numSparseBinds.z() - 1) ? lastBlockExtent.z() : imageGranularity.depth;
429029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
430029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				VkSparseImageMemoryBind imageMemoryBind;
431029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				imageMemoryBind.subresource.aspectMask	= aspectMask;
432029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				imageMemoryBind.subresource.mipLevel	= mipLevelNdx;
433029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				imageMemoryBind.subresource.arrayLayer	= layerNdx;
434029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				imageMemoryBind.memory					= deviceMemory;
435029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				imageMemoryBind.memoryOffset			= 0u;
436029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				imageMemoryBind.flags					= 0u;
437029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				imageMemoryBind.offset					= offset;
438029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				imageMemoryBind.extent					= extent;
439029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
440029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				imageResidencyMemoryBinds.push_back(imageMemoryBind);
441029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			}
442029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		}
443029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
444029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		if (!(aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && aspectRequirements.imageMipTailFirstLod < imageCreateInfo.mipLevels)
445029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		{
446029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			const VkMemoryAllocateInfo allocInfo =
447029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			{
448029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType	sType;
449029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				DE_NULL,								//	const void*		pNext;
450029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				aspectRequirements.imageMipTailSize,	//	VkDeviceSize	allocationSize;
451029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				memoryType,								//	deUint32		memoryTypeIndex;
452029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			};
453029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
454029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			VkDeviceMemory deviceMemory = 0;
455029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			VK_CHECK(deviceInterface.allocateMemory(*m_logicalDevice, &allocInfo, DE_NULL, &deviceMemory));
456029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
457029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(deviceMemory), Deleter<VkDeviceMemory>(deviceInterface, *m_logicalDevice, DE_NULL))));
458029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
459029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			VkSparseMemoryBind imageMipTailMemoryBind;
460029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
461029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			imageMipTailMemoryBind.resourceOffset	= aspectRequirements.imageMipTailOffset + layerNdx * aspectRequirements.imageMipTailStride;
462029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			imageMipTailMemoryBind.size				= aspectRequirements.imageMipTailSize;
463029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			imageMipTailMemoryBind.memory			= deviceMemory;
464029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			imageMipTailMemoryBind.memoryOffset		= 0u;
465029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			imageMipTailMemoryBind.flags			= 0u;
466029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
467029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
468029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		}
469029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
470029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
471029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	if ((aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) && aspectRequirements.imageMipTailFirstLod < imageCreateInfo.mipLevels)
472029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
473029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		const VkMemoryAllocateInfo allocInfo =
474029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		{
475029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType	sType;
476029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			DE_NULL,								//	const void*		pNext;
477029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			aspectRequirements.imageMipTailSize,	//	VkDeviceSize	allocationSize;
478029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			memoryType,								//	deUint32		memoryTypeIndex;
479029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		};
480029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
481029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		VkDeviceMemory deviceMemory = 0;
482029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		VK_CHECK(deviceInterface.allocateMemory(*m_logicalDevice, &allocInfo, DE_NULL, &deviceMemory));
483029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
484029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(deviceMemory), Deleter<VkDeviceMemory>(deviceInterface, *m_logicalDevice, DE_NULL))));
485029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
486029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		VkSparseMemoryBind imageMipTailMemoryBind;
487029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
488029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageMipTailMemoryBind.resourceOffset	= aspectRequirements.imageMipTailOffset;
489029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageMipTailMemoryBind.size				= aspectRequirements.imageMipTailSize;
490029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageMipTailMemoryBind.memory			= deviceMemory;
491029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageMipTailMemoryBind.memoryOffset		= 0u;
492029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageMipTailMemoryBind.flags			= 0u;
493029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
494029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageMipTailMemoryBinds.push_back(imageMipTailMemoryBind);
495029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
496029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
497029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const Unique<VkSemaphore> imageMemoryBindSemaphore(makeSemaphore(deviceInterface, *m_logicalDevice));
498029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
499029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	VkBindSparseInfo bindSparseInfo =
500029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
501029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,			//VkStructureType							sType;
502029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		DE_NULL,									//const void*								pNext;
503029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		0u,											//deUint32									waitSemaphoreCount;
504029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		DE_NULL,									//const VkSemaphore*						pWaitSemaphores;
505029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		0u,											//deUint32									bufferBindCount;
506029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		DE_NULL,									//const VkSparseBufferMemoryBindInfo*		pBufferBinds;
507029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		0u,											//deUint32									imageOpaqueBindCount;
508029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		DE_NULL,									//const VkSparseImageOpaqueMemoryBindInfo*	pImageOpaqueBinds;
509029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		0u,											//deUint32									imageBindCount;
510029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		DE_NULL,									//const VkSparseImageMemoryBindInfo*		pImageBinds;
511029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		1u,											//deUint32									signalSemaphoreCount;
512029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		&imageMemoryBindSemaphore.get()				//const VkSemaphore*						pSignalSemaphores;
513029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	};
514029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
515029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	VkSparseImageMemoryBindInfo		  imageResidencyBindInfo;
516029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	VkSparseImageOpaqueMemoryBindInfo imageMipTailBindInfo;
517029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
518029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	if (imageResidencyMemoryBinds.size() > 0)
519029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
520029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageResidencyBindInfo.image	 = *sparseImage;
521029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageResidencyBindInfo.bindCount = static_cast<deUint32>(imageResidencyMemoryBinds.size());
522029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageResidencyBindInfo.pBinds    = &imageResidencyMemoryBinds[0];
523029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
524029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		bindSparseInfo.imageBindCount	 = 1u;
525029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		bindSparseInfo.pImageBinds		 = &imageResidencyBindInfo;
526029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
527029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
528029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	if (imageMipTailMemoryBinds.size() > 0)
529029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
530029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageMipTailBindInfo.image			= *sparseImage;
531029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageMipTailBindInfo.bindCount		= static_cast<deUint32>(imageMipTailMemoryBinds.size());
532029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		imageMipTailBindInfo.pBinds			= &imageMipTailMemoryBinds[0];
533029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
534029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		bindSparseInfo.imageOpaqueBindCount = 1u;
535029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		bindSparseInfo.pImageOpaqueBinds	= &imageMipTailBindInfo;
536029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
537029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
538029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Submit sparse bind commands for execution
539029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	VK_CHECK(deviceInterface.queueBindSparse(sparseQueue.queueHandle, 1u, &bindSparseInfo, DE_NULL));
540029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
541029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Create command buffer for compute and transfer oparations
542029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const Unique<VkCommandPool>	  commandPool(makeCommandPool(deviceInterface, *m_logicalDevice, computeQueue.queueFamilyIndex));
543029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, *m_logicalDevice, *commandPool));
544029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
545029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Start recording commands
546029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	beginCommandBuffer(deviceInterface, *commandBuffer);
547029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
548029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Create descriptor set layout
549029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const Unique<VkDescriptorSetLayout> descriptorSetLayout(
550029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		DescriptorSetLayoutBuilder()
551029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
552029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		.build(deviceInterface, *m_logicalDevice));
553029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
554029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Create and bind compute pipeline
555029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const Unique<VkShaderModule>	shaderModule(createShaderModule(deviceInterface, *m_logicalDevice, m_context.getBinaryCollection().get("comp"), DE_NULL));
556029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const Unique<VkPipelineLayout>	pipelineLayout(makePipelineLayout(deviceInterface, *m_logicalDevice, *descriptorSetLayout));
557029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const Unique<VkPipeline>		computePipeline(makeComputePipeline(deviceInterface, *m_logicalDevice, *pipelineLayout, *shaderModule));
558029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
559029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
560029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
561029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Create and bind descriptor set
562029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const Unique<VkDescriptorPool> descriptorPool(
563029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		DescriptorPoolBuilder()
564029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1u)
565029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		.build(deviceInterface, *m_logicalDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
566029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
567029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const Unique<VkDescriptorSet>	descriptorSet(makeDescriptorSet(deviceInterface, *m_logicalDevice, *descriptorPool, *descriptorSetLayout));
568029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
569029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkImageSubresourceRange	subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, getNumLayers(m_imageType, m_imageSize));
570029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const Unique<VkImageView>		imageView(makeImageView(deviceInterface, *m_logicalDevice, *sparseImage, mapImageViewType(m_imageType), mapTextureFormat(m_format), subresourceRange));
571029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkDescriptorImageInfo		sparseImageInfo  = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
572029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
573029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	DescriptorSetUpdateBuilder()
574029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &sparseImageInfo)
575029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		.update(deviceInterface, *m_logicalDevice);
576029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
577029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	deviceInterface.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
578029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
579029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkImageMemoryBarrier sparseImageLayoutChangeBarrier
580029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		= makeImageMemoryBarrier(
581029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		0u, VK_ACCESS_SHADER_WRITE_BIT,
582029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
583029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		*sparseImage, subresourceRange);
584029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
585029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &sparseImageLayoutChangeBarrier);
586029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
587029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const tcu::UVec3  gridSize		= getShaderGridSize(m_imageType, m_imageSize);
588029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const tcu::UVec3  workGroupSize = computeWorkGroupSize(gridSize);
589029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
590029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const deUint32 xWorkGroupCount = gridSize.x() / workGroupSize.x() + (gridSize.x() % workGroupSize.x() ? 1u : 0u);
591029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const deUint32 yWorkGroupCount = gridSize.y() / workGroupSize.y() + (gridSize.y() % workGroupSize.y() ? 1u : 0u);
592029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const deUint32 zWorkGroupCount = gridSize.z() / workGroupSize.z() + (gridSize.z() % workGroupSize.z() ? 1u : 0u);
593029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
594029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const tcu::UVec3 maxComputeWorkGroupCount = tcu::UVec3(65535u, 65535u, 65535u);
595029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
596029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	if (maxComputeWorkGroupCount.x() < xWorkGroupCount ||
597029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		maxComputeWorkGroupCount.y() < yWorkGroupCount ||
598029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		maxComputeWorkGroupCount.z() < zWorkGroupCount)
599029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
600029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Image size is not supported");
601029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
602029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
603029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	deviceInterface.cmdDispatch(*commandBuffer, xWorkGroupCount, yWorkGroupCount, zWorkGroupCount);
604029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
605029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkImageMemoryBarrier sparseImageTrasferBarrier
606029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		= makeImageMemoryBarrier(
607029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
608029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
609029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		*sparseImage, subresourceRange);
610029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
611029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &sparseImageTrasferBarrier);
612029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
613029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const deUint32			 imageSizeInBytes		= getNumPixels(m_imageType, m_imageSize) * tcu::getPixelSize(m_format);
614029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkBufferCreateInfo outputBufferCreateInfo = makeBufferCreateInfo(imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
615029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
616029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const de::UniquePtr<Buffer>	outputBuffer(new Buffer(deviceInterface, *m_logicalDevice, *allocator, outputBufferCreateInfo, MemoryRequirement::HostVisible));
617029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
618029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkBufferImageCopy bufferImageCopy = makeBufferImageCopy(imageCreateInfo.extent, imageCreateInfo.arrayLayers);
619029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
620029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	deviceInterface.cmdCopyImageToBuffer(*commandBuffer, *sparseImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, outputBuffer->get(), 1u, &bufferImageCopy);
621029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
622029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkBufferMemoryBarrier outputBufferHostReadBarrier
623029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		= makeBufferMemoryBarrier(
624029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
625029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		outputBuffer->get(), 0u, imageSizeInBytes);
626029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
627029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &outputBufferHostReadBarrier, 0u, DE_NULL);
628029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
629029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// End recording commands
630029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	endCommandBuffer(deviceInterface, *commandBuffer);
631029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
632029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// The stage at which execution is going to wait for finish of sparse binding operations
633029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const VkPipelineStageFlags stageBits[] = { VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT };
634029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
635029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Submit commands for execution and wait for completion
636029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	submitCommandsAndWait(deviceInterface, *m_logicalDevice, computeQueue.queueHandle, *commandBuffer, 1u, &imageMemoryBindSemaphore.get(), stageBits);
637029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
638029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Retrieve data from buffer to host memory
639029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const Allocation& allocation = outputBuffer->getAllocation();
640029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
641029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	invalidateMappedMemoryRange(deviceInterface, *m_logicalDevice, allocation.getMemory(), allocation.getOffset(), imageSizeInBytes);
642029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
643029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const deUint8*	outputData = static_cast<const deUint8*>(allocation.getHostPtr());
644029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	tcu::TestStatus testStatus = tcu::TestStatus::pass("Passed");
645029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
646029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	const tcu::ConstPixelBufferAccess pixelBuffer = tcu::ConstPixelBufferAccess(m_format, gridSize.x(), gridSize.y(), gridSize.z(), outputData);
647029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
648029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Validate results
649029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	if( aspectRequirements.imageMipTailFirstLod > 0u )
650029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
651029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		const VkExtent3D		 mipExtent		 = mipLevelExtents(imageCreateInfo.extent, 0u);
652029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		const tcu::UVec3		 numSparseBinds  = alignedDivide(mipExtent, imageGranularity);
653029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		const tcu::UVec3		 lastBlockExtent = tcu::UVec3(	mipExtent.width  % imageGranularity.width  ? mipExtent.width  % imageGranularity.width  : imageGranularity.width,
654029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch																mipExtent.height % imageGranularity.height ? mipExtent.height % imageGranularity.height : imageGranularity.height,
655029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch																mipExtent.depth  % imageGranularity.depth  ? mipExtent.depth  % imageGranularity.depth  : imageGranularity.depth);
656029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
657029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		for (deUint32 layerNdx = 0; layerNdx < imageCreateInfo.arrayLayers; ++layerNdx)
658029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		{
659029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			for (deUint32 z = 0; z < numSparseBinds.z(); ++z)
660029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			for (deUint32 y = 0; y < numSparseBinds.y(); ++y)
661029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			for (deUint32 x = 0; x < numSparseBinds.x(); ++x)
662029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			{
663029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				VkExtent3D offset;
664029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				offset.width  = x*imageGranularity.width;
665029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				offset.height = y*imageGranularity.height;
666029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				offset.depth  = z*imageGranularity.depth + layerNdx*numSparseBinds.z()*imageGranularity.depth;
667029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
668029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				VkExtent3D extent;
669029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				extent.width  = (x == numSparseBinds.x() - 1) ? lastBlockExtent.x() : imageGranularity.width;
670029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				extent.height = (y == numSparseBinds.y() - 1) ? lastBlockExtent.y() : imageGranularity.height;
671029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				extent.depth  = (z == numSparseBinds.z() - 1) ? lastBlockExtent.z() : imageGranularity.depth;
672029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
673029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				const deUint32 linearIndex = x + y*numSparseBinds.x() + z*numSparseBinds.x()*numSparseBinds.y() + layerNdx*numSparseBinds.x()*numSparseBinds.y()*numSparseBinds.z();
674029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
675029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				if (linearIndex % 2 == 0)
676029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				{
677029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					for (deUint32 offsetZ = offset.depth;  offsetZ < offset.depth  + extent.depth;  ++offsetZ)
678029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					for (deUint32 offsetY = offset.height; offsetY < offset.height + extent.height; ++offsetY)
679029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					for (deUint32 offsetX = offset.width;  offsetX < offset.width  + extent.width;  ++offsetX)
680029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					{
681029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch						const tcu::UVec4 referenceValue = tcu::UVec4(offsetX % 127u, offsetY % 127u, offsetZ % 127u, 1u);
682029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch						const tcu::UVec4 outputValue	= pixelBuffer.getPixelUint(offsetX, offsetY, offsetZ);
683029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
684029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch						if (memcmp(&outputValue, &referenceValue, sizeof(deUint32) * getNumUsedChannels(m_format)))
685029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch						{
686029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch							testStatus = tcu::TestStatus::fail("Failed");
687029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch							goto verificationFinished;
688029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch						}
689029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					}
690029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				}
691029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				else
692029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				{
693029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					if (deviceProperties.sparseProperties.residencyNonResidentStrict)
694029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					{
695029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch						for (deUint32 offsetZ = offset.depth;  offsetZ < offset.depth  + extent.depth;  ++offsetZ)
696029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch						for (deUint32 offsetY = offset.height; offsetY < offset.height + extent.height; ++offsetY)
697029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch						for (deUint32 offsetX = offset.width;  offsetX < offset.width  + extent.width;  ++offsetX)
698029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch						{
699029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch							const tcu::UVec4 referenceValue = tcu::UVec4(0u, 0u, 0u, 0u);
700029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch							const tcu::UVec4 outputValue = pixelBuffer.getPixelUint(offsetX, offsetY, offsetZ);
701029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
702029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch							if (memcmp(&outputValue, &referenceValue, sizeof(deUint32) * getNumUsedChannels(m_format)))
703029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch							{
704029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch								testStatus = tcu::TestStatus::fail("Failed");
705029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch								goto verificationFinished;
706029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch							}
707029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch						}
708029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch					}
709029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				}
710029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			}
711029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		}
712029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
713029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	else
714029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
715029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		const VkExtent3D mipExtent = mipLevelExtents(imageCreateInfo.extent, 0u);
716029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
717029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		for (deUint32 offsetZ = 0u; offsetZ < mipExtent.depth * imageCreateInfo.arrayLayers; ++offsetZ)
718029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		for (deUint32 offsetY = 0u; offsetY < mipExtent.height; ++offsetY)
719029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		for (deUint32 offsetX = 0u; offsetX < mipExtent.width;  ++offsetX)
720029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		{
721029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			const tcu::UVec4 referenceValue = tcu::UVec4(offsetX % 127u, offsetY % 127u, offsetZ % 127u, 1u);
722029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			const tcu::UVec4 outputValue	= pixelBuffer.getPixelUint(offsetX, offsetY, offsetZ);
723029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
724029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			if (memcmp(&outputValue, &referenceValue, sizeof(deUint32) * getNumUsedChannels(m_format)))
725029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			{
726029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				testStatus = tcu::TestStatus::fail("Failed");
727029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				goto verificationFinished;
728029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			}
729029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		}
730029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
731029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
732029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	verificationFinished:
733029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
734029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	// Wait for sparse queue to become idle
735029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	deviceInterface.queueWaitIdle(sparseQueue.queueHandle);
736029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
737029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	return testStatus;
738029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch}
739029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
740029550532951eec8a34b752f1ea6957a4f1c69d9KantochTestInstance* ImageSparseResidencyCase::createInstance (Context& context) const
741029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
742029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	return new ImageSparseResidencyInstance(context, m_imageType, m_imageSize, m_format);
743029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch}
744029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
745029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch} // anonymous ns
746029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
747029550532951eec8a34b752f1ea6957a4f1c69d9Kantochtcu::TestCaseGroup* createImageSparseResidencyTests (tcu::TestContext& testCtx)
748029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch{
749029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "image_sparse_residency", "Buffer Sparse Residency"));
750029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
751029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	static const deUint32 sizeCountPerImageType = 3u;
752029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
753029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	struct ImageParameters
754029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
755029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		ImageType	imageType;
756029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		tcu::UVec3	imageSizes[sizeCountPerImageType];
757029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	};
758029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
759029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	static const ImageParameters imageParametersArray[] =
760029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
761029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		{ IMAGE_TYPE_2D,		 { tcu::UVec3(512u, 256u, 1u),  tcu::UVec3(1024u, 128u, 1u), tcu::UVec3(11u, 137u, 1u) } },
762029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		{ IMAGE_TYPE_2D_ARRAY,	 { tcu::UVec3(512u, 256u, 6u),	tcu::UVec3(1024u, 128u, 8u), tcu::UVec3(11u, 137u, 3u) } },
763029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		{ IMAGE_TYPE_CUBE,		 { tcu::UVec3(512u, 256u, 1u),	tcu::UVec3(1024u, 128u, 1u), tcu::UVec3(11u, 137u, 1u) } },
764029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		{ IMAGE_TYPE_CUBE_ARRAY, { tcu::UVec3(512u, 256u, 6u),	tcu::UVec3(1024u, 128u, 8u), tcu::UVec3(11u, 137u, 3u) } },
765029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		{ IMAGE_TYPE_3D,		 { tcu::UVec3(512u, 256u, 16u), tcu::UVec3(1024u, 128u, 8u), tcu::UVec3(11u, 137u, 3u) } }
766029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	};
767029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
768029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	static const tcu::TextureFormat formats[] =
769029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
770029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT32),
771029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT16),
772029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		tcu::TextureFormat(tcu::TextureFormat::R,	 tcu::TextureFormat::SIGNED_INT8),
773029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		tcu::TextureFormat(tcu::TextureFormat::RG,	 tcu::TextureFormat::SIGNED_INT32),
774029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		tcu::TextureFormat(tcu::TextureFormat::RG,   tcu::TextureFormat::SIGNED_INT16),
775029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		tcu::TextureFormat(tcu::TextureFormat::RG,   tcu::TextureFormat::SIGNED_INT8),
776029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32),
777029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT16),
778029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8)
779029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	};
780029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
781029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	for (deInt32 imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray); ++imageTypeNdx)
782029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	{
783029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		const ImageType					imageType = imageParametersArray[imageTypeNdx].imageType;
784029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));
785029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
786029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		for (deInt32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
787029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		{
788029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			const tcu::TextureFormat&		format = formats[formatNdx];
789029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, getShaderImageFormatQualifier(format).c_str(), ""));
790029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
791029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			for (deInt32 imageSizeNdx = 0; imageSizeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray[imageTypeNdx].imageSizes); ++imageSizeNdx)
792029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			{
793029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				const tcu::UVec3 imageSize = imageParametersArray[imageTypeNdx].imageSizes[imageSizeNdx];
794029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
795029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				std::ostringstream stream;
796029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				stream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
797029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
798029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch				formatGroup->addChild(new ImageSparseResidencyCase(testCtx, stream.str(), "", imageType, imageSize, format, glu::GLSL_VERSION_440));
799029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			}
800029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch			imageTypeGroup->addChild(formatGroup.release());
801029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		}
802029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch		testGroup->addChild(imageTypeGroup.release());
803029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	}
804029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
805029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch	return testGroup.release();
806029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch}
807029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch
808029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch} // sparse
809029550532951eec8a34b752f1ea6957a4f1c69d9Kantoch} // vkt
810