• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*
20  * \file  vktSparseResourcesShaderIntrinsicsSampled.cpp
21  * \brief Sparse Resources Shader Intrinsics for sampled images
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSparseResourcesShaderIntrinsicsSampled.hpp"
25 
26 using namespace vk;
27 
28 namespace vkt
29 {
30 namespace sparse
31 {
32 namespace
33 {
34 
makeGraphicsPipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkRenderPass renderPass,const VkShaderModule vertexModule,const VkShaderModule fragmentModule,const VkShaderModule geometryModule)35 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&			vk,
36 									   const VkDevice					device,
37 									   const VkPipelineLayout			pipelineLayout,
38 									   const VkRenderPass				renderPass,
39 									   const VkShaderModule				vertexModule,
40 									   const VkShaderModule				fragmentModule,
41 									   const VkShaderModule				geometryModule)
42 {
43 	const VkFormat		vertexFormatPosition		= VK_FORMAT_R32G32_SFLOAT;
44 	const VkFormat		vertexFormatTexCoord		= VK_FORMAT_R32G32_SFLOAT;
45 	const deUint32		vertexSizePosition			= tcu::getPixelSize(mapVkFormat(vertexFormatPosition));
46 	const deUint32		vertexSizeTexCoord			= tcu::getPixelSize(mapVkFormat(vertexFormatTexCoord));
47 	const deUint32		vertexBufferOffsetPosition	= 0u;
48 	const deUint32		vertexBufferOffsetTexCoord	= vertexSizePosition;
49 	const deUint32		vertexDataStride			= vertexSizePosition + vertexSizeTexCoord;
50 
51 	const VkVertexInputBindingDescription vertexBinding =
52 	{
53 		0u,							// deUint32				binding;
54 		vertexDataStride,			// deUint32				stride;
55 		VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputRate	inputRate;
56 	};
57 
58 	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
59 	{
60 		// position
61 		{
62 			0u,							// deUint32	location;
63 			0u,							// deUint32	binding;
64 			vertexFormatPosition,		// VkFormat	format;
65 			vertexBufferOffsetPosition,	// deUint32	offset;
66 		},
67 		// texture coordinates
68 		{
69 			1u,							// deUint32	location;
70 			0u,							// deUint32	binding;
71 			vertexFormatTexCoord,		// VkFormat	format;
72 			vertexBufferOffsetTexCoord,	// deUint32	offset;
73 		},
74 	};
75 
76 	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
77 	{
78 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType                             sType;
79 		DE_NULL,														// const void*                                 pNext;
80 		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags       flags;
81 		1u,																// uint32_t                                    vertexBindingDescriptionCount;
82 		&vertexBinding,													// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
83 		DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),			// uint32_t                                    vertexAttributeDescriptionCount;
84 		vertexInputAttributeDescriptions,								// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
85 	};
86 
87 	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
88 	{
89 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
90 		DE_NULL,														// const void*                                 pNext;
91 		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags     flags;
92 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,							// VkPrimitiveTopology                         topology;
93 		VK_FALSE,														// VkBool32                                    primitiveRestartEnable;
94 	};
95 
96 	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
97 	{
98 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType                             sType;
99 		DE_NULL,														// const void*                                 pNext;
100 		(VkPipelineViewportStateCreateFlags)0,							// VkPipelineViewportStateCreateFlags          flags;
101 		1u,																// uint32_t                                    viewportCount;
102 		DE_NULL, // dynamic state										// const VkViewport*                           pViewports;
103 		1u,																// uint32_t                                    scissorCount;
104 		DE_NULL, // dynamic state										// const VkRect2D*                             pScissors;
105 	};
106 
107 	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
108 	{
109 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
110 		DE_NULL,														// const void*                              pNext;
111 		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
112 		VK_FALSE,														// VkBool32                                 depthClampEnable;
113 		VK_FALSE,														// VkBool32                                 rasterizerDiscardEnable;
114 		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
115 		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
116 		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
117 		VK_FALSE,														// VkBool32									depthBiasEnable;
118 		0.0f,															// float									depthBiasConstantFactor;
119 		0.0f,															// float									depthBiasClamp;
120 		0.0f,															// float									depthBiasSlopeFactor;
121 		1.0f,															// float									lineWidth;
122 	};
123 
124 	const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
125 	{
126 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType							sType;
127 		DE_NULL,														// const void*								pNext;
128 		(VkPipelineMultisampleStateCreateFlags)0,						// VkPipelineMultisampleStateCreateFlags	flags;
129 		VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits					rasterizationSamples;
130 		VK_FALSE,														// VkBool32									sampleShadingEnable;
131 		0.0f,															// float									minSampleShading;
132 		DE_NULL,														// const VkSampleMask*						pSampleMask;
133 		VK_FALSE,														// VkBool32									alphaToCoverageEnable;
134 		VK_FALSE														// VkBool32									alphaToOneEnable;
135 	};
136 
137 	const VkStencilOpState stencilOpState = makeStencilOpState(
138 		VK_STENCIL_OP_KEEP,				// stencil fail
139 		VK_STENCIL_OP_KEEP,				// depth & stencil pass
140 		VK_STENCIL_OP_KEEP,				// depth only fail
141 		VK_COMPARE_OP_ALWAYS,			// compare op
142 		0u,								// compare mask
143 		0u,								// write mask
144 		0u);							// reference
145 
146 	VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
147 	{
148 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,		// VkStructureType							sType;
149 		DE_NULL,														// const void*								pNext;
150 		(VkPipelineDepthStencilStateCreateFlags)0,						// VkPipelineDepthStencilStateCreateFlags	flags;
151 		VK_FALSE,														// VkBool32									depthTestEnable;
152 		VK_FALSE,														// VkBool32									depthWriteEnable;
153 		VK_COMPARE_OP_LESS,												// VkCompareOp								depthCompareOp;
154 		VK_FALSE,														// VkBool32									depthBoundsTestEnable;
155 		VK_FALSE,														// VkBool32									stencilTestEnable;
156 		stencilOpState,													// VkStencilOpState							front;
157 		stencilOpState,													// VkStencilOpState							back;
158 		0.0f,															// float									minDepthBounds;
159 		1.0f,															// float									maxDepthBounds;
160 	};
161 
162 	const VkColorComponentFlags					colorComponentsAll					= VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
163 	const VkPipelineColorBlendAttachmentState	defaultColorBlendAttachmentState	=
164 	{
165 		VK_FALSE,						// VkBool32					blendEnable;
166 		VK_BLEND_FACTOR_ONE,			// VkBlendFactor			srcColorBlendFactor;
167 		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstColorBlendFactor;
168 		VK_BLEND_OP_ADD,				// VkBlendOp				colorBlendOp;
169 		VK_BLEND_FACTOR_ONE,			// VkBlendFactor			srcAlphaBlendFactor;
170 		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstAlphaBlendFactor;
171 		VK_BLEND_OP_ADD,				// VkBlendOp				alphaBlendOp;
172 		colorComponentsAll,				// VkColorComponentFlags	colorWriteMask;
173 	};
174 
175 	const VkPipelineColorBlendAttachmentState	colorBlendAttachmentStates[] =
176 	{
177 		defaultColorBlendAttachmentState,
178 		defaultColorBlendAttachmentState,
179 	};
180 
181 	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
182 	{
183 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,		// VkStructureType								sType;
184 		DE_NULL,														// const void*									pNext;
185 		(VkPipelineColorBlendStateCreateFlags)0,						// VkPipelineColorBlendStateCreateFlags			flags;
186 		VK_FALSE,														// VkBool32										logicOpEnable;
187 		VK_LOGIC_OP_COPY,												// VkLogicOp									logicOp;
188 		DE_LENGTH_OF_ARRAY(colorBlendAttachmentStates),					// deUint32										attachmentCount;
189 		colorBlendAttachmentStates,										// const VkPipelineColorBlendAttachmentState*	pAttachments;
190 		{ 0.0f, 0.0f, 0.0f, 0.0f },										// float										blendConstants[4];
191 	};
192 
193 	const VkDynamicState dynamicStates[] =
194 	{
195 		VK_DYNAMIC_STATE_VIEWPORT,
196 		VK_DYNAMIC_STATE_SCISSOR,
197 	};
198 
199 	const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
200 	{
201 		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	// VkStructureType						sType;
202 		DE_NULL,												// const void*							pNext;
203 		(VkPipelineDynamicStateCreateFlags)0,					// VkPipelineDynamicStateCreateFlags	flags;
204 		DE_LENGTH_OF_ARRAY(dynamicStates),						// deUint32								dynamicStateCount;
205 		dynamicStates,											// const VkDynamicState*				pDynamicStates;
206 	};
207 
208 	const VkPipelineShaderStageCreateInfo pShaderStages[] =
209 	{
210 		{
211 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
212 			DE_NULL,													// const void*							pNext;
213 			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
214 			VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBits				stage;
215 			vertexModule,												// VkShaderModule						module;
216 			"main",														// const char*							pName;
217 			DE_NULL,													// const VkSpecializationInfo*			pSpecializationInfo;
218 		},
219 		{
220 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
221 			DE_NULL,													// const void*							pNext;
222 			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
223 			VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBits				stage;
224 			fragmentModule,												// VkShaderModule						module;
225 			"main",														// const char*							pName;
226 			DE_NULL,													// const VkSpecializationInfo*			pSpecializationInfo;
227 		},
228 		{
229 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
230 			DE_NULL,													// const void*							pNext;
231 			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
232 			VK_SHADER_STAGE_GEOMETRY_BIT,								// VkShaderStageFlagBits				stage;
233 			geometryModule,												// VkShaderModule						module;
234 			"main",														// const char*							pName;
235 			DE_NULL,													// const VkSpecializationInfo*			pSpecializationInfo;
236 		},
237 	};
238 
239 	const deUint32 numActiveShaderStages = DE_LENGTH_OF_ARRAY(pShaderStages) - (geometryModule == DE_NULL ? 1u : 0u);
240 
241 	const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
242 	{
243 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
244 		DE_NULL,											// const void*										pNext;
245 		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags							flags;
246 		numActiveShaderStages,								// deUint32											stageCount;
247 		pShaderStages,										// const VkPipelineShaderStageCreateInfo*			pStages;
248 		&vertexInputStateInfo,								// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
249 		&pipelineInputAssemblyStateInfo,					// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
250 		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
251 		&pipelineViewportStateInfo,							// const VkPipelineViewportStateCreateInfo*			pViewportState;
252 		&pipelineRasterizationStateInfo,					// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
253 		&pipelineMultisampleStateInfo,						// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
254 		&pipelineDepthStencilStateInfo,						// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
255 		&pipelineColorBlendStateInfo,						// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
256 		&dynamicStateCreateInfo,							// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
257 		pipelineLayout,										// VkPipelineLayout									layout;
258 		renderPass,											// VkRenderPass										renderPass;
259 		0u,													// deUint32											subpass;
260 		DE_NULL,											// VkPipeline										basePipelineHandle;
261 		0,													// deInt32											basePipelineIndex;
262 	};
263 
264 	return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
265 }
266 
267 } // anonymous
268 
initPrograms(vk::SourceCollections & programCollection) const269 void SparseShaderIntrinsicsCaseSampledBase::initPrograms (vk::SourceCollections& programCollection) const
270 {
271 	const deUint32		numLayers	= getNumLayers(m_imageType, m_imageSize);
272 	const std::string	coordString = getShaderImageCoordinates(m_imageType, "%local_texCoord_x", "%local_texCoord_xy", "%local_texCoord_xyz");
273 
274 	// Create vertex shader
275 	std::ostringstream vs;
276 
277 	vs	<< "#version 440\n"
278 		<< "layout(location = 0) in  highp vec2 vs_in_position;\n"
279 		<< "layout(location = 1) in  highp vec2 vs_in_texCoord;\n"
280 		<< "\n"
281 		<< "layout(location = 0) out highp vec3 vs_out_texCoord;\n"
282 		<< "\n"
283 		<< "out gl_PerVertex {\n"
284 		<< "	vec4  gl_Position;\n"
285 		<< "};\n"
286 		<< "void main (void)\n"
287 		<< "{\n"
288 		<< "	gl_Position		= vec4(vs_in_position, 0.0f, 1.0f);\n"
289 		<< "	vs_out_texCoord = vec3(vs_in_texCoord, 0.0f);\n"
290 		<< "}\n";
291 
292 	programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
293 
294 	if (numLayers > 1u)
295 	{
296 		const deInt32 maxVertices = 3u * numLayers;
297 
298 		// Create geometry shader
299 		std::ostringstream gs;
300 
301 		gs << "#version 440\n"
302 			<< "layout(triangles) in;\n"
303 			<< "layout(triangle_strip, max_vertices = " << static_cast<deInt32>(maxVertices) << ") out;\n"
304 			<< "\n"
305 			<< "in gl_PerVertex {\n"
306 			<< "	vec4  gl_Position;\n"
307 			<< "} gl_in[];\n"
308 			<< "out gl_PerVertex {\n"
309 			<< "	vec4  gl_Position;\n"
310 			<< "};\n"
311 			<< "layout(location = 0) in  highp vec3 gs_in_texCoord[];\n"
312 			<< "\n"
313 			<< "layout(location = 0) out highp vec3 gs_out_texCoord;\n"
314 			<< "\n"
315 			<< "void main (void)\n"
316 			<< "{\n"
317 			<< "    for (int layerNdx = 0; layerNdx < " << static_cast<deInt32>(numLayers) << "; ++layerNdx)\n"
318 			<< "    {\n"
319 			<< "		for (int vertexNdx = 0; vertexNdx < gl_in.length(); ++vertexNdx)\n"
320 			<< "		{\n"
321 			<< "			gl_Layer		= layerNdx;\n"
322 			<< "			gl_Position		= gl_in[vertexNdx].gl_Position;\n"
323 			<< "			gs_out_texCoord = vec3(gs_in_texCoord[vertexNdx].xy, float(layerNdx));\n"
324 			<< "			EmitVertex();\n"
325 			<< "		}\n"
326 			<< "		EndPrimitive();\n"
327 			<< "    }\n"
328 			<< "}\n";
329 
330 		programCollection.glslSources.add("geometry_shader") << glu::GeometrySource(gs.str());
331 	}
332 
333 	// Create fragment shader
334 	std::ostringstream fs;
335 
336 	const std::string	typeImgComp		= getImageComponentTypeName(m_format);
337 	const std::string	typeImgCompVec4	= getImageComponentVec4TypeName(m_format);
338 
339 	fs	<< "OpCapability Shader\n"
340 		<< "OpCapability SampledCubeArray\n"
341 		<< "OpCapability ImageCubeArray\n"
342 		<< "OpCapability SparseResidency\n"
343 		<< "OpCapability StorageImageExtendedFormats\n"
344 
345 		<< "%ext_import = OpExtInstImport \"GLSL.std.450\"\n"
346 		<< "OpMemoryModel Logical GLSL450\n"
347 		<< "OpEntryPoint Fragment %func_main \"main\" %varying_texCoord %output_texel %output_residency\n"
348 		<< "OpExecutionMode %func_main OriginUpperLeft\n"
349 		<< "OpSource GLSL 440\n"
350 
351 		<< "OpName %func_main \"main\"\n"
352 
353 		<< "OpName %varying_texCoord \"varying_texCoord\"\n"
354 
355 		<< "OpName %output_texel \"out_texel\"\n"
356 		<< "OpName %output_residency \"out_residency\"\n"
357 
358 		<< "OpName %type_uniformblock \"LodBlock\"\n"
359 		<< "OpMemberName %type_uniformblock 0 \"lod\"\n"
360 		<< "OpMemberName %type_uniformblock 1 \"size\"\n"
361 		<< "OpName %uniformblock_instance \"lodInstance\"\n"
362 
363 		<< "OpName %uniformconst_image_sparse \"u_imageSparse\"\n"
364 
365 		<< "OpDecorate %varying_texCoord Location 0\n"
366 
367 		<< "OpDecorate %output_texel	 Location 0\n"
368 		<< "OpDecorate %output_residency Location 1\n"
369 
370 		<< "OpDecorate		 %type_uniformblock Block\n"
371 		<< "OpMemberDecorate %type_uniformblock 0 Offset 0\n"
372 		<< "OpMemberDecorate %type_uniformblock 1 Offset 8\n"
373 
374 		<< "OpDecorate %uniformconst_image_sparse DescriptorSet 0\n"
375 		<< "OpDecorate %uniformconst_image_sparse Binding " << BINDING_IMAGE_SPARSE << "\n"
376 
377 		<< "%type_void = OpTypeVoid\n"
378 		<< "%type_void_func = OpTypeFunction %type_void\n"
379 
380 		<< "%type_bool							= OpTypeBool\n"
381 		<< "%type_int							= OpTypeInt 32 1\n"
382 		<< "%type_uint							= OpTypeInt 32 0\n"
383 		<< "%type_float							= OpTypeFloat 32\n"
384 		<< "%type_vec2							= OpTypeVector %type_float 2\n"
385 		<< "%type_vec3							= OpTypeVector %type_float 3\n"
386 		<< "%type_vec4							= OpTypeVector %type_float 4\n"
387 		<< "%type_ivec4						= OpTypeVector %type_int  4\n"
388 		<< "%type_uvec4						= OpTypeVector %type_uint 4\n"
389 		<< "%type_uniformblock					= OpTypeStruct %type_uint %type_vec2\n"
390 		<< "%type_struct_int_img_comp_vec4	= OpTypeStruct %type_int " << typeImgCompVec4 << "\n"
391 
392 		<< "%type_input_vec3					= OpTypePointer Input %type_vec3\n"
393 		<< "%type_input_float					= OpTypePointer Input %type_float\n"
394 
395 		<< "%type_output_img_comp_vec4			= OpTypePointer Output " << typeImgCompVec4 << "\n"
396 		<< "%type_output_uint					= OpTypePointer Output %type_uint\n"
397 
398 		<< "%type_function_int					= OpTypePointer Function %type_int\n"
399 		<< "%type_function_img_comp_vec4		= OpTypePointer Function " << typeImgCompVec4 << "\n"
400 		<< "%type_function_int_img_comp_vec4	= OpTypePointer Function %type_struct_int_img_comp_vec4\n"
401 
402 		<< "%type_pushconstant_uniformblock				= OpTypePointer PushConstant %type_uniformblock\n"
403 		<< "%type_pushconstant_uniformblock_member_lod  = OpTypePointer PushConstant %type_uint\n"
404 		<< "%type_pushconstant_uniformblock_member_size = OpTypePointer PushConstant %type_vec2\n"
405 
406 		<< "%type_image_sparse				= " << getOpTypeImageSparse(m_imageType, m_format, typeImgComp, true) << "\n"
407 		<< "%type_sampled_image_sparse		= OpTypeSampledImage %type_image_sparse\n"
408 		<< "%type_uniformconst_image_sparse = OpTypePointer UniformConstant %type_sampled_image_sparse\n"
409 
410 		<< "%varying_texCoord			= OpVariable %type_input_vec3 Input\n"
411 
412 		<< "%output_texel				= OpVariable %type_output_img_comp_vec4 Output\n"
413 		<< "%output_residency			= OpVariable %type_output_uint Output\n"
414 
415 		<< "%uniformconst_image_sparse	= OpVariable %type_uniformconst_image_sparse UniformConstant\n"
416 
417 		<< "%uniformblock_instance  = OpVariable %type_pushconstant_uniformblock PushConstant\n"
418 
419 		// Declare constants
420 		<< "%constant_uint_0				= OpConstant %type_uint 0\n"
421 		<< "%constant_uint_1				= OpConstant %type_uint 1\n"
422 		<< "%constant_uint_2				= OpConstant %type_uint 2\n"
423 		<< "%constant_uint_3				= OpConstant %type_uint 3\n"
424 		<< "%constant_int_0					= OpConstant %type_int  0\n"
425 		<< "%constant_int_1					= OpConstant %type_int  1\n"
426 		<< "%constant_int_2					= OpConstant %type_int  2\n"
427 		<< "%constant_int_3					= OpConstant %type_int  3\n"
428 		<< "%constant_float_0				= OpConstant %type_float 0.0\n"
429 		<< "%constant_float_half			= OpConstant %type_float 0.5\n"
430 		<< "%constant_texel_resident		= OpConstant %type_uint " << MEMORY_BLOCK_BOUND_VALUE << "\n"
431 		<< "%constant_texel_not_resident	= OpConstant %type_uint " << MEMORY_BLOCK_NOT_BOUND_VALUE << "\n"
432 
433 		// Call main function
434 		<< "%func_main		 = OpFunction %type_void None %type_void_func\n"
435 		<< "%label_func_main = OpLabel\n"
436 
437 		<< "%local_image_sparse = OpLoad %type_sampled_image_sparse %uniformconst_image_sparse\n"
438 
439 		<< "%texCoord = OpLoad %type_vec3 %varying_texCoord\n"
440 
441 		<< "%local_texCoord_x = OpCompositeExtract %type_float %texCoord 0\n"
442 		<< "%local_texCoord_y = OpCompositeExtract %type_float %texCoord 1\n"
443 		<< "%local_texCoord_z = OpCompositeExtract %type_float %texCoord 2\n"
444 
445 		<< "%local_texCoord_xy	= OpCompositeConstruct %type_vec2 %local_texCoord_x %local_texCoord_y\n"
446 		<< "%local_texCoord_xyz = OpCompositeConstruct %type_vec3 %local_texCoord_x %local_texCoord_y %local_texCoord_z\n"
447 
448 		<< "%access_uniformblock_member_uint_lod = OpAccessChain %type_pushconstant_uniformblock_member_lod %uniformblock_instance %constant_int_0\n"
449 		<< "%local_uniformblock_member_uint_lod  = OpLoad %type_uint %access_uniformblock_member_uint_lod\n"
450 		<< "%local_uniformblock_member_float_lod = OpConvertUToF %type_float %local_uniformblock_member_uint_lod\n"
451 		<< "%access_uniformblock_member_size	 = OpAccessChain %type_pushconstant_uniformblock_member_size %uniformblock_instance %constant_int_1\n"
452 		<< "%local_uniformblock_member_size		 = OpLoad %type_vec2 %access_uniformblock_member_size\n"
453 
454 		<< sparseImageOpString("%local_sparse_op_result", "%type_struct_int_img_comp_vec4", "%local_image_sparse", coordString, "%local_uniformblock_member_float_lod") << "\n"
455 
456 		// Load texel value
457 		<< "%local_img_comp_vec4 = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_op_result 1\n"
458 
459 		<< "OpStore %output_texel %local_img_comp_vec4\n"
460 
461 		// Load residency code
462 		<< "%local_residency_code = OpCompositeExtract %type_int %local_sparse_op_result 0\n"
463 
464 		// Check if loaded texel is placed in resident memory
465 		<< "%local_texel_resident = OpImageSparseTexelsResident %type_bool %local_residency_code\n"
466 		<< "OpSelectionMerge %branch_texel_resident None\n"
467 		<< "OpBranchConditional %local_texel_resident %label_texel_resident %label_texel_not_resident\n"
468 		<< "%label_texel_resident = OpLabel\n"
469 
470 		// Loaded texel is in resident memory
471 		<< "OpStore %output_residency %constant_texel_resident\n"
472 
473 		<< "OpBranch %branch_texel_resident\n"
474 		<< "%label_texel_not_resident = OpLabel\n"
475 
476 		// Loaded texel is not in resident memory
477 		<< "OpStore %output_residency %constant_texel_not_resident\n"
478 
479 		<< "OpBranch %branch_texel_resident\n"
480 		<< "%branch_texel_resident = OpLabel\n"
481 
482 		<< "OpReturn\n"
483 		<< "OpFunctionEnd\n";
484 
485 	programCollection.spirvAsmSources.add("fragment_shader") << fs.str();
486 }
487 
sparseImageOpString(const std::string & resultVariable,const std::string & resultType,const std::string & image,const std::string & coord,const std::string & miplevel) const488 std::string	SparseCaseOpImageSparseSampleExplicitLod::sparseImageOpString (const std::string& resultVariable,
489 																		   const std::string& resultType,
490 																		   const std::string& image,
491 																		   const std::string& coord,
492 																		   const std::string& miplevel) const
493 {
494 	std::ostringstream	src;
495 
496 	src << resultVariable << " = OpImageSparseSampleExplicitLod " << resultType << " " << image << " " << coord << " Lod " << miplevel << "\n";
497 
498 	return src.str();
499 }
500 
sparseImageOpString(const std::string & resultVariable,const std::string & resultType,const std::string & image,const std::string & coord,const std::string & miplevel) const501 std::string	SparseCaseOpImageSparseSampleImplicitLod::sparseImageOpString  (const std::string& resultVariable,
502 																			const std::string& resultType,
503 																			const std::string& image,
504 																			const std::string& coord,
505 																			const std::string& miplevel) const
506 {
507 	DE_UNREF(miplevel);
508 
509 	std::ostringstream	src;
510 
511 	src << resultVariable << " = OpImageSparseSampleImplicitLod " << resultType << " " << image << " " << coord << "\n";
512 
513 	return src.str();
514 }
515 
sparseImageOpString(const std::string & resultVariable,const std::string & resultType,const std::string & image,const std::string & coord,const std::string & miplevel) const516 std::string	SparseCaseOpImageSparseGather::sparseImageOpString (const std::string& resultVariable,
517 																const std::string& resultType,
518 																const std::string& image,
519 																const std::string& coord,
520 																const std::string& miplevel) const
521 {
522 	DE_UNREF(miplevel);
523 
524 	std::ostringstream	src;
525 
526 	const std::string	typeImgComp		= getImageComponentTypeName(m_format);
527 	const std::string	typeImgCompVec4	= getImageComponentVec4TypeName(m_format);
528 
529 	// Bias the coord value by half a texel, so we sample from center of 2x2 gather rectangle
530 
531 	src << "%local_image_width	= OpCompositeExtract %type_float %local_uniformblock_member_size 0\n";
532 	src << "%local_image_height	= OpCompositeExtract %type_float %local_uniformblock_member_size 1\n";
533 	src << "%local_coord_x_bias	= OpFDiv %type_float %constant_float_half %local_image_width\n";
534 	src << "%local_coord_y_bias	= OpFDiv %type_float %constant_float_half %local_image_height\n";
535 
536 	switch (m_imageType)
537 	{
538 		case IMAGE_TYPE_2D:
539 		{
540 			src << "%local_coord_bias	= OpCompositeConstruct %type_vec2 %local_coord_x_bias %local_coord_y_bias\n";
541 			src << "%local_coord_biased	= OpFAdd %type_vec2 " << coord << " %local_coord_bias\n";
542 
543 			break;
544 		}
545 
546 		case IMAGE_TYPE_2D_ARRAY:
547 		case IMAGE_TYPE_3D:
548 		{
549 			src << "%local_coord_bias	= OpCompositeConstruct %type_vec3 %local_coord_x_bias %local_coord_y_bias %constant_float_0\n";
550 			src << "%local_coord_biased	= OpFAdd %type_vec3 " << coord << " %local_coord_bias\n";
551 
552 			break;
553 		}
554 
555 		default:
556 		{
557 			/* This can't be happening. */
558 			DE_ASSERT(DE_FALSE);
559 		}
560 	}
561 
562 	src << "%local_sparse_gather_result_x = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_0\n";
563 	src << "%local_sparse_gather_result_y = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_1\n";
564 	src << "%local_sparse_gather_result_z = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_2\n";
565 	src << "%local_sparse_gather_result_w = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_3\n";
566 
567 	src << "%local_gather_residency_code = OpCompositeExtract %type_int %local_sparse_gather_result_x 0\n";
568 
569 	src << "%local_gather_texels_x = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_x 1\n";
570 	src << "%local_gather_texels_y = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_y 1\n";
571 	src << "%local_gather_texels_z = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_z 1\n";
572 	src << "%local_gather_texels_w = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_w 1\n";
573 
574 	src << "%local_gather_primary_texel_x = OpCompositeExtract " << typeImgComp << " %local_gather_texels_x 3\n";
575 	src << "%local_gather_primary_texel_y = OpCompositeExtract " << typeImgComp << " %local_gather_texels_y 3\n";
576 	src << "%local_gather_primary_texel_z = OpCompositeExtract " << typeImgComp << " %local_gather_texels_z 3\n";
577 	src << "%local_gather_primary_texel_w = OpCompositeExtract " << typeImgComp << " %local_gather_texels_w 3\n";
578 
579 	src << "%local_gather_primary_texel	= OpCompositeConstruct " << typeImgCompVec4 << " %local_gather_primary_texel_x %local_gather_primary_texel_y %local_gather_primary_texel_z %local_gather_primary_texel_w\n";
580 	src << resultVariable << " = OpCompositeConstruct " << resultType << " %local_gather_residency_code %local_gather_primary_texel\n";
581 
582 	return src.str();
583 }
584 
585 class SparseShaderIntrinsicsInstanceSampledBase : public SparseShaderIntrinsicsInstanceBase
586 {
587 public:
SparseShaderIntrinsicsInstanceSampledBase(Context & context,const SpirVFunction function,const ImageType imageType,const tcu::UVec3 & imageSize,const tcu::TextureFormat & format)588 	SparseShaderIntrinsicsInstanceSampledBase	(Context&					context,
589 												 const SpirVFunction		function,
590 												 const ImageType			imageType,
591 												 const tcu::UVec3&			imageSize,
592 												 const tcu::TextureFormat&	format)
593 	: SparseShaderIntrinsicsInstanceBase(context, function, imageType, imageSize, format) {}
594 
595 	VkImageUsageFlags		imageSparseUsageFlags	(void) const;
596 	VkImageUsageFlags		imageOutputUsageFlags	(void) const;
597 
598 	VkQueueFlags			getQueueFlags			(void) const;
599 
600 	void					recordCommands			(const VkCommandBuffer		commandBuffer,
601 													 const VkImageCreateInfo&	imageSparseInfo,
602 													 const VkImage				imageSparse,
603 													 const VkImage				imageTexels,
604 													 const VkImage				imageResidency);
605 
606 	virtual VkImageSubresourceRange	sampledImageRangeToBind(const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const = 0;
607 
608 private:
609 	typedef de::SharedPtr< vk::Unique<vk::VkFramebuffer> > VkFramebufferSp;
610 
611 	Move<VkBuffer>					m_vertexBuffer;
612 	de::MovePtr<Allocation>			m_vertexBufferAlloc;
613 	std::vector<VkFramebufferSp>	m_framebuffers;
614 	Move<VkRenderPass>				m_renderPass;
615 	Move<VkSampler>					m_sampler;
616 };
617 
imageSparseUsageFlags(void) const618 VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageSparseUsageFlags (void) const
619 {
620 	return VK_IMAGE_USAGE_SAMPLED_BIT;
621 }
622 
imageOutputUsageFlags(void) const623 VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageOutputUsageFlags (void) const
624 {
625 	return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
626 }
627 
getQueueFlags(void) const628 VkQueueFlags SparseShaderIntrinsicsInstanceSampledBase::getQueueFlags (void) const
629 {
630 	return VK_QUEUE_GRAPHICS_BIT;
631 }
632 
recordCommands(const VkCommandBuffer commandBuffer,const VkImageCreateInfo & imageSparseInfo,const VkImage imageSparse,const VkImage imageTexels,const VkImage imageResidency)633 void SparseShaderIntrinsicsInstanceSampledBase::recordCommands (const VkCommandBuffer		commandBuffer,
634 																const VkImageCreateInfo&	imageSparseInfo,
635 																const VkImage				imageSparse,
636 																const VkImage				imageTexels,
637 																const VkImage				imageResidency)
638 {
639 	const InstanceInterface&		 instance			= m_context.getInstanceInterface();
640 	const DeviceInterface&			 deviceInterface	= getDeviceInterface();
641 	const VkPhysicalDevice			 physicalDevice		= m_context.getPhysicalDevice();
642 	const VkPhysicalDeviceProperties deviceProperties	= getPhysicalDeviceProperties(instance, physicalDevice);
643 
644 	if (imageSparseInfo.extent.width  > deviceProperties.limits.maxFramebufferWidth  ||
645 		imageSparseInfo.extent.height > deviceProperties.limits.maxFramebufferHeight ||
646 		imageSparseInfo.arrayLayers   > deviceProperties.limits.maxFramebufferLayers)
647 	{
648 		TCU_THROW(NotSupportedError, "Image size exceeds allowed framebuffer dimensions");
649 	}
650 
651 	// Check if device supports image format for sampled images
652 	if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
653 		TCU_THROW(NotSupportedError, "Device does not support image format for sampled images");
654 
655 	// Check if device supports image format for color attachment
656 	if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
657 		TCU_THROW(NotSupportedError, "Device does not support image format for color attachment");
658 
659 	// Make sure device supports VK_FORMAT_R32_UINT format for color attachment
660 	if (!checkImageFormatFeatureSupport(instance, physicalDevice, mapTextureFormat(m_residencyFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
661 		TCU_THROW(TestError, "Device does not support VK_FORMAT_R32_UINT format for color attachment");
662 
663 	// Create buffer storing vertex data
664 	std::vector<tcu::Vec2> vertexData;
665 
666 	vertexData.push_back(tcu::Vec2(-1.0f,-1.0f));
667 	vertexData.push_back(tcu::Vec2( 0.0f, 0.0f));
668 
669 	vertexData.push_back(tcu::Vec2(-1.0f, 1.0f));
670 	vertexData.push_back(tcu::Vec2( 0.0f, 1.0f));
671 
672 	vertexData.push_back(tcu::Vec2( 1.0f,-1.0f));
673 	vertexData.push_back(tcu::Vec2( 1.0f, 0.0f));
674 
675 	vertexData.push_back(tcu::Vec2( 1.0f, 1.0f));
676 	vertexData.push_back(tcu::Vec2( 1.0f, 1.0f));
677 
678 	const VkDeviceSize			vertexDataSizeInBytes	= sizeInBytes(vertexData);
679 	const VkBufferCreateInfo	vertexBufferCreateInfo	= makeBufferCreateInfo(vertexDataSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
680 
681 	m_vertexBuffer		= createBuffer(deviceInterface, getDevice(), &vertexBufferCreateInfo);
682 	m_vertexBufferAlloc	= bindBuffer(deviceInterface, getDevice(), getAllocator(), *m_vertexBuffer, MemoryRequirement::HostVisible);
683 
684 	deMemcpy(m_vertexBufferAlloc->getHostPtr(), &vertexData[0], static_cast<std::size_t>(vertexDataSizeInBytes));
685 	flushMappedMemoryRange(deviceInterface, getDevice(), m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexDataSizeInBytes);
686 
687 	// Create render pass
688 	const VkAttachmentDescription texelsAttachmentDescription =
689 	{
690 		(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
691 		imageSparseInfo.format,								// VkFormat							format;
692 		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
693 		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
694 		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
695 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
696 		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
697 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
698 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
699 	};
700 
701 	const VkAttachmentDescription residencyAttachmentDescription =
702 	{
703 		(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
704 		mapTextureFormat(m_residencyFormat),				// VkFormat							format;
705 		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
706 		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
707 		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
708 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
709 		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
710 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
711 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
712 	};
713 
714 	const VkAttachmentDescription colorAttachmentsDescription[] = { texelsAttachmentDescription, residencyAttachmentDescription };
715 
716 	const VkAttachmentReference texelsAttachmentReference =
717 	{
718 		0u,													// deUint32			attachment;
719 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
720 	};
721 
722 	const VkAttachmentReference residencyAttachmentReference =
723 	{
724 		1u,													// deUint32			attachment;
725 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
726 	};
727 
728 	const VkAttachmentReference colorAttachmentsReference[] = { texelsAttachmentReference, residencyAttachmentReference };
729 
730 	const VkAttachmentReference depthAttachmentReference =
731 	{
732 		VK_ATTACHMENT_UNUSED,								// deUint32			attachment;
733 		VK_IMAGE_LAYOUT_UNDEFINED							// VkImageLayout	layout;
734 	};
735 
736 	const VkSubpassDescription subpassDescription =
737 	{
738 		(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags;
739 		VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
740 		0u,													// deUint32							inputAttachmentCount;
741 		DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
742 		2u,													// deUint32							colorAttachmentCount;
743 		colorAttachmentsReference,							// const VkAttachmentReference*		pColorAttachments;
744 		DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
745 		&depthAttachmentReference,							// const VkAttachmentReference*		pDepthStencilAttachment;
746 		0u,													// deUint32							preserveAttachmentCount;
747 		DE_NULL												// const deUint32*					pPreserveAttachments;
748 	};
749 
750 	const VkRenderPassCreateInfo renderPassInfo =
751 	{
752 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
753 		DE_NULL,											// const void*						pNext;
754 		(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags;
755 		2u,													// deUint32							attachmentCount;
756 		colorAttachmentsDescription,						// const VkAttachmentDescription*	pAttachments;
757 		1u,													// deUint32							subpassCount;
758 		&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
759 		0u,													// deUint32							dependencyCount;
760 		DE_NULL												// const VkSubpassDependency*		pDependencies;
761 	};
762 
763 	m_renderPass = createRenderPass(deviceInterface, getDevice(), &renderPassInfo);
764 
765 	// Create descriptor set layout
766 	DescriptorSetLayoutBuilder descriptorLayerBuilder;
767 
768 	descriptorLayerBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
769 
770 	const Unique<VkDescriptorSetLayout> descriptorSetLayout(descriptorLayerBuilder.build(deviceInterface, getDevice()));
771 
772 	// Create descriptor pool
773 	DescriptorPoolBuilder descriptorPoolBuilder;
774 
775 	descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSparseInfo.mipLevels);
776 
777 	descriptorPool = descriptorPoolBuilder.build(deviceInterface, getDevice(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, imageSparseInfo.mipLevels);
778 
779 	// Create sampler object
780 	const tcu::Sampler			samplerObject(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST);
781 	const VkSamplerCreateInfo	samplerCreateInfo = mapSampler(samplerObject, m_format);
782 	m_sampler = createSampler(deviceInterface, getDevice(), &samplerCreateInfo);
783 
784 	struct PushConstants
785 	{
786 		deUint32	lod;
787 		deUint32	padding;			// padding needed to satisfy std430 rules
788 		float		lodWidth;
789 		float		lodHeight;
790 	};
791 
792 	// Create pipeline layout
793 	const VkPushConstantRange lodConstantRange =
794 	{
795 		VK_SHADER_STAGE_FRAGMENT_BIT,	// VkShaderStageFlags	stageFlags;
796 		0u,								// deUint32			offset;
797 		sizeof(PushConstants),			// deUint32			size;
798 	};
799 
800 	const VkPipelineLayoutCreateInfo pipelineLayoutParams =
801 	{
802 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
803 		DE_NULL,											// const void*						pNext;
804 		0u,													// VkPipelineLayoutCreateFlags		flags;
805 		1u,													// deUint32							setLayoutCount;
806 		&descriptorSetLayout.get(),							// const VkDescriptorSetLayout*		pSetLayouts;
807 		1u,													// deUint32							pushConstantRangeCount;
808 		&lodConstantRange,									// const VkPushConstantRange*		pPushConstantRanges;
809 	};
810 
811 	const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(deviceInterface, getDevice(), &pipelineLayoutParams));
812 
813 	// Create graphics pipeline
814 	{
815 		Move<VkShaderModule> vertexModule	= createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0);
816 		Move<VkShaderModule> fragmentModule	= createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0);
817 		Move<VkShaderModule> geometryModule;
818 
819 		if (imageSparseInfo.arrayLayers > 1u)
820 		{
821 			requireFeatures(instance, physicalDevice, FEATURE_GEOMETRY_SHADER);
822 			geometryModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("geometry_shader"), (VkShaderModuleCreateFlags)0);
823 		}
824 
825 		pipelines.push_back(makeVkSharedPtr(makeGraphicsPipeline(
826 			deviceInterface, getDevice(), *pipelineLayout, *m_renderPass, *vertexModule, *fragmentModule, *geometryModule)));
827 	}
828 
829 	const VkPipeline graphicsPipeline = **pipelines[0];
830 
831 	{
832 		const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
833 
834 		VkImageMemoryBarrier imageShaderAccessBarriers[3];
835 
836 		imageShaderAccessBarriers[0] = makeImageMemoryBarrier
837 		(
838 			VK_ACCESS_TRANSFER_WRITE_BIT,
839 			VK_ACCESS_SHADER_READ_BIT,
840 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
841 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
842 			imageSparse,
843 			fullImageSubresourceRange
844 		);
845 
846 		imageShaderAccessBarriers[1] = makeImageMemoryBarrier
847 		(
848 			0u,
849 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
850 			VK_IMAGE_LAYOUT_UNDEFINED,
851 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
852 			imageTexels,
853 			fullImageSubresourceRange
854 		);
855 
856 		imageShaderAccessBarriers[2] = makeImageMemoryBarrier
857 		(
858 			0u,
859 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
860 			VK_IMAGE_LAYOUT_UNDEFINED,
861 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
862 			imageResidency,
863 			fullImageSubresourceRange
864 		);
865 
866 		deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 3u, imageShaderAccessBarriers);
867 	}
868 
869 	imageSparseViews.resize(imageSparseInfo.mipLevels);
870 	imageTexelsViews.resize(imageSparseInfo.mipLevels);
871 	imageResidencyViews.resize(imageSparseInfo.mipLevels);
872 	m_framebuffers.resize(imageSparseInfo.mipLevels);
873 	descriptorSets.resize(imageSparseInfo.mipLevels);
874 
875 	std::vector<VkClearValue> clearValues;
876 	clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
877 	clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
878 
879 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
880 	{
881 		const vk::VkExtent3D mipLevelSize = mipLevelExtents(imageSparseInfo.extent, mipLevelNdx);
882 
883 		const vk::VkRect2D renderArea =
884 		{
885 			makeOffset2D(0u, 0u),
886 			makeExtent2D(mipLevelSize.width, mipLevelSize.height),
887 		};
888 
889 		const VkViewport viewport = makeViewport
890 		(
891 			0.0f, 0.0f,
892 			static_cast<float>(mipLevelSize.width), static_cast<float>(mipLevelSize.height),
893 			0.0f, 1.0f
894 		);
895 
896 		const VkImageSubresourceRange mipLevelRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevelNdx, 1u, 0u, imageSparseInfo.arrayLayers);
897 
898 		// Create color attachments image views
899 		imageTexelsViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageTexels, mapImageViewType(m_imageType), imageSparseInfo.format, mipLevelRange));
900 		imageResidencyViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageResidency, mapImageViewType(m_imageType), mapTextureFormat(m_residencyFormat), mipLevelRange));
901 
902 		const VkImageView attachmentsViews[] = { **imageTexelsViews[mipLevelNdx], **imageResidencyViews[mipLevelNdx] };
903 
904 		// Create framebuffer
905 		const VkFramebufferCreateInfo framebufferInfo =
906 		{
907 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType                             sType;
908 			DE_NULL,									// const void*                                 pNext;
909 			(VkFramebufferCreateFlags)0,				// VkFramebufferCreateFlags                    flags;
910 			*m_renderPass,								// VkRenderPass                                renderPass;
911 			2u,											// uint32_t                                    attachmentCount;
912 			attachmentsViews,							// const VkImageView*                          pAttachments;
913 			mipLevelSize.width,							// uint32_t                                    width;
914 			mipLevelSize.height,						// uint32_t                                    height;
915 			imageSparseInfo.arrayLayers,				// uint32_t                                    layers;
916 		};
917 
918 		m_framebuffers[mipLevelNdx] = makeVkSharedPtr(createFramebuffer(deviceInterface, getDevice(), &framebufferInfo));
919 
920 		// Create descriptor set
921 		descriptorSets[mipLevelNdx] = makeVkSharedPtr(makeDescriptorSet(deviceInterface, getDevice(), *descriptorPool, *descriptorSetLayout));
922 		const VkDescriptorSet descriptorSet = **descriptorSets[mipLevelNdx];
923 
924 		// Update descriptor set
925 		const VkImageSubresourceRange sparseImageSubresourceRange = sampledImageRangeToBind(imageSparseInfo, mipLevelNdx);
926 
927 		imageSparseViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageSparse, mapImageViewType(m_imageType), imageSparseInfo.format, sparseImageSubresourceRange));
928 
929 		const VkDescriptorImageInfo imageSparseDescInfo = makeDescriptorImageInfo(*m_sampler, **imageSparseViews[mipLevelNdx], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
930 
931 		DescriptorSetUpdateBuilder descriptorUpdateBuilder;
932 
933 		descriptorUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(BINDING_IMAGE_SPARSE), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSparseDescInfo);
934 		descriptorUpdateBuilder.update(deviceInterface, getDevice());
935 
936 		// Begin render pass
937 		{
938 			const VkRenderPassBeginInfo renderPassBeginInfo =
939 			{
940 				VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
941 				DE_NULL,										// const void*             pNext;
942 				*m_renderPass,									// VkRenderPass            renderPass;
943 				**m_framebuffers[mipLevelNdx],					// VkFramebuffer           framebuffer;
944 				renderArea,										// VkRect2D                renderArea;
945 				static_cast<deUint32>(clearValues.size()),		// deUint32                clearValueCount;
946 				&clearValues[0],								// const VkClearValue*     pClearValues;
947 			};
948 
949 			deviceInterface.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
950 		}
951 
952 		// Bind graphics pipeline
953 		deviceInterface.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
954 
955 		// Bind descriptor set
956 		deviceInterface.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
957 
958 		// Bind vertex buffer
959 		{
960 			const VkDeviceSize offset = 0ull;
961 			deviceInterface.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &m_vertexBuffer.get(), &offset);
962 		}
963 
964 		// Bind Viewport
965 		deviceInterface.cmdSetViewport(commandBuffer, 0u, 1u, &viewport);
966 
967 		// Bind Scissor Rectangle
968 		deviceInterface.cmdSetScissor(commandBuffer, 0u, 1u, &renderArea);
969 
970 		const PushConstants pushConstants =
971 		{
972 			mipLevelNdx,
973 			0u,											// padding
974 			static_cast<float>(mipLevelSize.width),
975 			static_cast<float>(mipLevelSize.height)
976 		};
977 
978 		// Update push constants
979 		deviceInterface.cmdPushConstants(commandBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(PushConstants), &pushConstants);
980 
981 		// Draw full screen quad
982 		deviceInterface.cmdDraw(commandBuffer, 4u, 1u, 0u, 0u);
983 
984 		// End render pass
985 		deviceInterface.cmdEndRenderPass(commandBuffer);
986 	}
987 
988 	{
989 		const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
990 
991 		VkImageMemoryBarrier imageOutputTransferSrcBarriers[2];
992 
993 		imageOutputTransferSrcBarriers[0] = makeImageMemoryBarrier
994 		(
995 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
996 			VK_ACCESS_TRANSFER_READ_BIT,
997 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
998 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
999 			imageTexels,
1000 			fullImageSubresourceRange
1001 		);
1002 
1003 		imageOutputTransferSrcBarriers[1] = makeImageMemoryBarrier
1004 		(
1005 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1006 			VK_ACCESS_TRANSFER_READ_BIT,
1007 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1008 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1009 			imageResidency,
1010 			fullImageSubresourceRange
1011 		);
1012 
1013 		deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageOutputTransferSrcBarriers);
1014 	}
1015 }
1016 
1017 class SparseShaderIntrinsicsInstanceSampledExplicit : public SparseShaderIntrinsicsInstanceSampledBase
1018 {
1019 public:
SparseShaderIntrinsicsInstanceSampledExplicit(Context & context,const SpirVFunction function,const ImageType imageType,const tcu::UVec3 & imageSize,const tcu::TextureFormat & format)1020 	SparseShaderIntrinsicsInstanceSampledExplicit	(Context&					context,
1021 													 const SpirVFunction		function,
1022 													 const ImageType			imageType,
1023 													 const tcu::UVec3&			imageSize,
1024 													 const tcu::TextureFormat&	format)
1025 	: SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
1026 
sampledImageRangeToBind(const VkImageCreateInfo & imageSparseInfo,const deUint32 mipLevel) const1027 	VkImageSubresourceRange sampledImageRangeToBind (const VkImageCreateInfo&	imageSparseInfo,
1028 													 const deUint32				mipLevel) const
1029 	{
1030 		DE_UNREF(mipLevel);
1031 		return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
1032 	}
1033 };
1034 
createInstance(Context & context) const1035 TestInstance* SparseShaderIntrinsicsCaseSampledExplicit::createInstance (Context& context) const
1036 {
1037 	return new SparseShaderIntrinsicsInstanceSampledExplicit(context, m_function, m_imageType, m_imageSize, m_format);
1038 }
1039 
1040 class SparseShaderIntrinsicsInstanceSampledImplicit : public SparseShaderIntrinsicsInstanceSampledBase
1041 {
1042 public:
SparseShaderIntrinsicsInstanceSampledImplicit(Context & context,const SpirVFunction function,const ImageType imageType,const tcu::UVec3 & imageSize,const tcu::TextureFormat & format)1043 	SparseShaderIntrinsicsInstanceSampledImplicit	(Context&					context,
1044 													 const SpirVFunction		function,
1045 													 const ImageType			imageType,
1046 													 const tcu::UVec3&			imageSize,
1047 													 const tcu::TextureFormat&	format)
1048 	: SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
1049 
sampledImageRangeToBind(const VkImageCreateInfo & imageSparseInfo,const deUint32 mipLevel) const1050 	VkImageSubresourceRange	sampledImageRangeToBind	(const VkImageCreateInfo&	imageSparseInfo,
1051 													 const deUint32				mipLevel) const
1052 	{
1053 		return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 1u, 0u, imageSparseInfo.arrayLayers);
1054 	}
1055 };
1056 
createInstance(Context & context) const1057 TestInstance* SparseShaderIntrinsicsCaseSampledImplicit::createInstance (Context& context) const
1058 {
1059 	return new SparseShaderIntrinsicsInstanceSampledImplicit(context, m_function, m_imageType, m_imageSize, m_format);
1060 }
1061 
1062 } // sparse
1063 } // vkt
1064