10abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch/*------------------------------------------------------------------------
20abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch * Vulkan Conformance Tests
30abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch * ------------------------
40abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch *
50abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch * Copyright (c) 2016 The Khronos Group Inc.
60abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch *
70abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch * Licensed under the Apache License, Version 2.0 (the "License");
80abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch * you may not use this file except in compliance with the License.
90abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch * You may obtain a copy of the License at
100abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch *
110abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch *      http://www.apache.org/licenses/LICENSE-2.0
120abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch *
130abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch * Unless required by applicable law or agreed to in writing, software
140abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch * distributed under the License is distributed on an "AS IS" BASIS,
150abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
160abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch * See the License for the specific language governing permissions and
170abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch * limitations under the License.
180abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch *
190abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch *//*
200abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch * \file  vktSparseResourcesShaderIntrinsicsSampled.cpp
210abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch * \brief Sparse Resources Shader Intrinsics for sampled images
220abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch *//*--------------------------------------------------------------------*/
230abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
240abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch#include "vktSparseResourcesShaderIntrinsicsSampled.hpp"
250abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
260abb8ae884208e3355eb68bde6cedab1dd7b773cKantochusing namespace vk;
270abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
280abb8ae884208e3355eb68bde6cedab1dd7b773cKantochnamespace vkt
290abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
300abb8ae884208e3355eb68bde6cedab1dd7b773cKantochnamespace sparse
310abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
32a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowskinamespace
33a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski{
34a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
35a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej JesionowskiMove<VkPipeline> makeGraphicsPipeline (const DeviceInterface&			vk,
36a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski									   const VkDevice					device,
37a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski									   const VkPipelineLayout			pipelineLayout,
38a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski									   const VkRenderPass				renderPass,
39a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski									   const VkShaderModule				vertexModule,
40a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski									   const VkShaderModule				fragmentModule,
41a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski									   const VkShaderModule				geometryModule)
42a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski{
43a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkFormat		vertexFormatPosition		= VK_FORMAT_R32G32_SFLOAT;
44a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkFormat		vertexFormatTexCoord		= VK_FORMAT_R32G32_SFLOAT;
45a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const deUint32		vertexSizePosition			= tcu::getPixelSize(mapVkFormat(vertexFormatPosition));
46a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const deUint32		vertexSizeTexCoord			= tcu::getPixelSize(mapVkFormat(vertexFormatTexCoord));
47a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const deUint32		vertexBufferOffsetPosition	= 0u;
48a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const deUint32		vertexBufferOffsetTexCoord	= vertexSizePosition;
49a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const deUint32		vertexDataStride			= vertexSizePosition + vertexSizeTexCoord;
50a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
51a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkVertexInputBindingDescription vertexBinding =
52a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
53a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		0u,							// deUint32				binding;
54a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		vertexDataStride,			// deUint32				stride;
55a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputRate	inputRate;
56a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
57a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
58a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
59a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
60a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		// position
61a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		{
62a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			0u,							// deUint32	location;
63a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			0u,							// deUint32	binding;
64a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			vertexFormatPosition,		// VkFormat	format;
65a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			vertexBufferOffsetPosition,	// deUint32	offset;
66a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		},
67a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		// texture coordinates
68a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		{
69a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			1u,							// deUint32	location;
70a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			0u,							// deUint32	binding;
71a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			vertexFormatTexCoord,		// VkFormat	format;
72a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			vertexBufferOffsetTexCoord,	// deUint32	offset;
73a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		},
74a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
75a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
76a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
77a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
78a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType                             sType;
79a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_NULL,														// const void*                                 pNext;
80a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags       flags;
81a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		1u,																// uint32_t                                    vertexBindingDescriptionCount;
82a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		&vertexBinding,													// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
83a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),			// uint32_t                                    vertexAttributeDescriptionCount;
84a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		vertexInputAttributeDescriptions,								// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
85a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
86a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
87a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
88a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
89a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
90a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_NULL,														// const void*                                 pNext;
91a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags     flags;
92a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,							// VkPrimitiveTopology                         topology;
93a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_FALSE,														// VkBool32                                    primitiveRestartEnable;
94a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
95a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
96a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
97a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
98a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType                             sType;
99a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_NULL,														// const void*                                 pNext;
100a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		(VkPipelineViewportStateCreateFlags)0,							// VkPipelineViewportStateCreateFlags          flags;
101a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		1u,																// uint32_t                                    viewportCount;
102a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_NULL, // dynamic state										// const VkViewport*                           pViewports;
103a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		1u,																// uint32_t                                    scissorCount;
104a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_NULL, // dynamic state										// const VkRect2D*                             pScissors;
105a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
106a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
107a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
108a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
109a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
110a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_NULL,														// const void*                              pNext;
111a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
112a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_FALSE,														// VkBool32                                 depthClampEnable;
113a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_FALSE,														// VkBool32                                 rasterizerDiscardEnable;
114a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
115a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
116a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
117a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_FALSE,														// VkBool32									depthBiasEnable;
118a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		0.0f,															// float									depthBiasConstantFactor;
119a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		0.0f,															// float									depthBiasClamp;
120a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		0.0f,															// float									depthBiasSlopeFactor;
121a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		1.0f,															// float									lineWidth;
122a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
123a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
124a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
125a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
126a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType							sType;
127a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_NULL,														// const void*								pNext;
128a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		(VkPipelineMultisampleStateCreateFlags)0,						// VkPipelineMultisampleStateCreateFlags	flags;
129a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits					rasterizationSamples;
130a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_FALSE,														// VkBool32									sampleShadingEnable;
131a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		0.0f,															// float									minSampleShading;
132a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_NULL,														// const VkSampleMask*						pSampleMask;
133a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_FALSE,														// VkBool32									alphaToCoverageEnable;
134a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_FALSE														// VkBool32									alphaToOneEnable;
135a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
136a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
137a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkStencilOpState stencilOpState = makeStencilOpState(
138a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_STENCIL_OP_KEEP,				// stencil fail
139a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_STENCIL_OP_KEEP,				// depth & stencil pass
140a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_STENCIL_OP_KEEP,				// depth only fail
141a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_COMPARE_OP_ALWAYS,			// compare op
142a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		0u,								// compare mask
143a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		0u,								// write mask
144a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		0u);							// reference
145a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
146a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
147a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
148a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,		// VkStructureType							sType;
149a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_NULL,														// const void*								pNext;
150a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		(VkPipelineDepthStencilStateCreateFlags)0,						// VkPipelineDepthStencilStateCreateFlags	flags;
151a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_FALSE,														// VkBool32									depthTestEnable;
152a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_FALSE,														// VkBool32									depthWriteEnable;
153a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_COMPARE_OP_LESS,												// VkCompareOp								depthCompareOp;
154a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_FALSE,														// VkBool32									depthBoundsTestEnable;
155a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_FALSE,														// VkBool32									stencilTestEnable;
156a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		stencilOpState,													// VkStencilOpState							front;
157a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		stencilOpState,													// VkStencilOpState							back;
158a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		0.0f,															// float									minDepthBounds;
159a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		1.0f,															// float									maxDepthBounds;
160a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
161a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
162a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkColorComponentFlags					colorComponentsAll					= VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
163a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkPipelineColorBlendAttachmentState	defaultColorBlendAttachmentState	=
164a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
165a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_FALSE,						// VkBool32					blendEnable;
166a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_BLEND_FACTOR_ONE,			// VkBlendFactor			srcColorBlendFactor;
167a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstColorBlendFactor;
168a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_BLEND_OP_ADD,				// VkBlendOp				colorBlendOp;
169a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_BLEND_FACTOR_ONE,			// VkBlendFactor			srcAlphaBlendFactor;
170a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstAlphaBlendFactor;
171a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_BLEND_OP_ADD,				// VkBlendOp				alphaBlendOp;
172a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		colorComponentsAll,				// VkColorComponentFlags	colorWriteMask;
173a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
174a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
175a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkPipelineColorBlendAttachmentState	colorBlendAttachmentStates[] =
176a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
177a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		defaultColorBlendAttachmentState,
178a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		defaultColorBlendAttachmentState,
179a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
180a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
181a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
182a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
183a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,		// VkStructureType								sType;
184a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_NULL,														// const void*									pNext;
185a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		(VkPipelineColorBlendStateCreateFlags)0,						// VkPipelineColorBlendStateCreateFlags			flags;
186a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_FALSE,														// VkBool32										logicOpEnable;
187a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_LOGIC_OP_COPY,												// VkLogicOp									logicOp;
188a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_LENGTH_OF_ARRAY(colorBlendAttachmentStates),					// deUint32										attachmentCount;
189a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		colorBlendAttachmentStates,										// const VkPipelineColorBlendAttachmentState*	pAttachments;
190a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		{ 0.0f, 0.0f, 0.0f, 0.0f },										// float										blendConstants[4];
191a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
192a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
193a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkDynamicState dynamicStates[] =
194a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
195a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_DYNAMIC_STATE_VIEWPORT,
196a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_DYNAMIC_STATE_SCISSOR,
197a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
198a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
199a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
200a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
201a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,	// VkStructureType						sType;
202a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_NULL,												// const void*							pNext;
203a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		(VkPipelineDynamicStateCreateFlags)0,					// VkPipelineDynamicStateCreateFlags	flags;
204a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_LENGTH_OF_ARRAY(dynamicStates),						// deUint32								dynamicStateCount;
205a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		dynamicStates,											// const VkDynamicState*				pDynamicStates;
206a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
207a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
208a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkPipelineShaderStageCreateInfo pShaderStages[] =
209a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
210a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		{
211a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
212a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			DE_NULL,													// const void*							pNext;
213a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
214a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBits				stage;
215a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			vertexModule,												// VkShaderModule						module;
216a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			"main",														// const char*							pName;
217a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			DE_NULL,													// const VkSpecializationInfo*			pSpecializationInfo;
218a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		},
219a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		{
220a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
221a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			DE_NULL,													// const void*							pNext;
222a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
223a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBits				stage;
224a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			fragmentModule,												// VkShaderModule						module;
225a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			"main",														// const char*							pName;
226a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			DE_NULL,													// const VkSpecializationInfo*			pSpecializationInfo;
227a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		},
228a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		{
229a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
230a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			DE_NULL,													// const void*							pNext;
231a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags		flags;
232a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			VK_SHADER_STAGE_GEOMETRY_BIT,								// VkShaderStageFlagBits				stage;
233a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			geometryModule,												// VkShaderModule						module;
234a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			"main",														// const char*							pName;
235a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			DE_NULL,													// const VkSpecializationInfo*			pSpecializationInfo;
236a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		},
237a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
238a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
239a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const deUint32 numActiveShaderStages = DE_LENGTH_OF_ARRAY(pShaderStages) - (geometryModule == DE_NULL ? 1u : 0u);
240a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
241a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
242a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
243a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
244a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_NULL,											// const void*										pNext;
245a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags							flags;
246a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		numActiveShaderStages,								// deUint32											stageCount;
247a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		pShaderStages,										// const VkPipelineShaderStageCreateInfo*			pStages;
248a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		&vertexInputStateInfo,								// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
249a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		&pipelineInputAssemblyStateInfo,					// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
250a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
251a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		&pipelineViewportStateInfo,							// const VkPipelineViewportStateCreateInfo*			pViewportState;
252a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		&pipelineRasterizationStateInfo,					// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
253a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		&pipelineMultisampleStateInfo,						// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
254a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		&pipelineDepthStencilStateInfo,						// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
255a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		&pipelineColorBlendStateInfo,						// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
256a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		&dynamicStateCreateInfo,							// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
257a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		pipelineLayout,										// VkPipelineLayout									layout;
258a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		renderPass,											// VkRenderPass										renderPass;
259a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		0u,													// deUint32											subpass;
260a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_NULL,											// VkPipeline										basePipelineHandle;
261a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		0,													// deInt32											basePipelineIndex;
262a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	};
263a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
264a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
265a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski}
266a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
267a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski} // anonymous
2680abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
2690abb8ae884208e3355eb68bde6cedab1dd7b773cKantochvoid SparseShaderIntrinsicsCaseSampledBase::initPrograms (vk::SourceCollections& programCollection) const
2700abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
2710abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const deUint32		numLayers	= getNumLayers(m_imageType, m_imageSize);
2720abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const std::string	coordString = getShaderImageCoordinates(m_imageType, "%local_texCoord_x", "%local_texCoord_xy", "%local_texCoord_xyz");
2730abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
2740abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	// Create vertex shader
2750abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	std::ostringstream vs;
2760abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
2770abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	vs	<< "#version 440\n"
2780abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "layout(location = 0) in  highp vec2 vs_in_position;\n"
2790abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "layout(location = 1) in  highp vec2 vs_in_texCoord;\n"
2800abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "\n"
2810abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "layout(location = 0) out highp vec3 vs_out_texCoord;\n"
2820abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "\n"
2830abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "out gl_PerVertex {\n"
2840abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "	vec4  gl_Position;\n"
2850abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "};\n"
2860abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "void main (void)\n"
2870abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "{\n"
2880abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "	gl_Position		= vec4(vs_in_position, 0.0f, 1.0f);\n"
2890abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "	vs_out_texCoord = vec3(vs_in_texCoord, 0.0f);\n"
2900abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "}\n";
2910abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
2920abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
2930abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
2940abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	if (numLayers > 1u)
2950abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
2960abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		const deInt32 maxVertices = 3u * numLayers;
2970abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
2980abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Create geometry shader
2990abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		std::ostringstream gs;
3000abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3010abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		gs << "#version 440\n"
3020abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "layout(triangles) in;\n"
3030abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "layout(triangle_strip, max_vertices = " << static_cast<deInt32>(maxVertices) << ") out;\n"
3040abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "\n"
3050abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "in gl_PerVertex {\n"
3060abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "	vec4  gl_Position;\n"
3070abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "} gl_in[];\n"
3080abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "out gl_PerVertex {\n"
3090abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "	vec4  gl_Position;\n"
3100abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "};\n"
3110abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "layout(location = 0) in  highp vec3 gs_in_texCoord[];\n"
3120abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "\n"
3130abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "layout(location = 0) out highp vec3 gs_out_texCoord;\n"
3140abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "\n"
3150abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "void main (void)\n"
3160abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "{\n"
3170abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "    for (int layerNdx = 0; layerNdx < " << static_cast<deInt32>(numLayers) << "; ++layerNdx)\n"
3180abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "    {\n"
3190abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "		for (int vertexNdx = 0; vertexNdx < gl_in.length(); ++vertexNdx)\n"
3200abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "		{\n"
3210abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "			gl_Layer		= layerNdx;\n"
3220abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "			gl_Position		= gl_in[vertexNdx].gl_Position;\n"
3230abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "			gs_out_texCoord = vec3(gs_in_texCoord[vertexNdx].xy, float(layerNdx));\n"
3240abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "			EmitVertex();\n"
3250abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "		}\n"
3260abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "		EndPrimitive();\n"
3270abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "    }\n"
3280abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			<< "}\n";
3290abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3300abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		programCollection.glslSources.add("geometry_shader") << glu::GeometrySource(gs.str());
3310abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	}
3320abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3330abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	// Create fragment shader
3340abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	std::ostringstream fs;
3350abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3360d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov	const std::string	typeImgComp		= getImageComponentTypeName(m_format);
3370d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov	const std::string	typeImgCompVec4	= getImageComponentVec4TypeName(m_format);
3380d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov
3390abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	fs	<< "OpCapability Shader\n"
3400abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpCapability SampledCubeArray\n"
3410abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpCapability ImageCubeArray\n"
3420abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpCapability SparseResidency\n"
3430abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpCapability StorageImageExtendedFormats\n"
3440abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3450abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%ext_import = OpExtInstImport \"GLSL.std.450\"\n"
3460abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpMemoryModel Logical GLSL450\n"
3470abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpEntryPoint Fragment %func_main \"main\" %varying_texCoord %output_texel %output_residency\n"
3480abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpExecutionMode %func_main OriginUpperLeft\n"
3490abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpSource GLSL 440\n"
3500abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3510abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpName %func_main \"main\"\n"
3520abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3530abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpName %varying_texCoord \"varying_texCoord\"\n"
3540abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3550abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpName %output_texel \"out_texel\"\n"
3560abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpName %output_residency \"out_residency\"\n"
3570abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
35857162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "OpName %type_uniformblock \"LodBlock\"\n"
35957162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "OpMemberName %type_uniformblock 0 \"lod\"\n"
36057162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "OpMemberName %type_uniformblock 1 \"size\"\n"
36157162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "OpName %uniformblock_instance \"lodInstance\"\n"
3620abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3630abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpName %uniformconst_image_sparse \"u_imageSparse\"\n"
3640abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3650abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpDecorate %varying_texCoord Location 0\n"
3660abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3670abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpDecorate %output_texel	 Location 0\n"
3680abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpDecorate %output_residency Location 1\n"
3690abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
37057162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "OpDecorate		 %type_uniformblock Block\n"
37157162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "OpMemberDecorate %type_uniformblock 0 Offset 0\n"
37257162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "OpMemberDecorate %type_uniformblock 1 Offset 8\n"
3730abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3740abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpDecorate %uniformconst_image_sparse DescriptorSet 0\n"
3750abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpDecorate %uniformconst_image_sparse Binding " << BINDING_IMAGE_SPARSE << "\n"
3760abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3770abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_void = OpTypeVoid\n"
3780abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_void_func = OpTypeFunction %type_void\n"
3790abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
380653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos		<< "%type_bool							= OpTypeBool\n"
3810abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_int							= OpTypeInt 32 1\n"
3820abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_uint							= OpTypeInt 32 0\n"
3830abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_float							= OpTypeFloat 32\n"
3840abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_vec2							= OpTypeVector %type_float 2\n"
3850abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_vec3							= OpTypeVector %type_float 3\n"
3860abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_vec4							= OpTypeVector %type_float 4\n"
3870d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov		<< "%type_ivec4						= OpTypeVector %type_int  4\n"
3880d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov		<< "%type_uvec4						= OpTypeVector %type_uint 4\n"
38957162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "%type_uniformblock					= OpTypeStruct %type_uint %type_vec2\n"
3900d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov		<< "%type_struct_int_img_comp_vec4	= OpTypeStruct %type_int " << typeImgCompVec4 << "\n"
3910abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3920abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_input_vec3					= OpTypePointer Input %type_vec3\n"
3930abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_input_float					= OpTypePointer Input %type_float\n"
3940abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
3950d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov		<< "%type_output_img_comp_vec4			= OpTypePointer Output " << typeImgCompVec4 << "\n"
3960abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_output_uint					= OpTypePointer Output %type_uint\n"
3970abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
398653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos		<< "%type_function_int					= OpTypePointer Function %type_int\n"
3990d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov		<< "%type_function_img_comp_vec4		= OpTypePointer Function " << typeImgCompVec4 << "\n"
4000abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_function_int_img_comp_vec4	= OpTypePointer Function %type_struct_int_img_comp_vec4\n"
4010abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
40257162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "%type_pushconstant_uniformblock				= OpTypePointer PushConstant %type_uniformblock\n"
4030abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_pushconstant_uniformblock_member_lod  = OpTypePointer PushConstant %type_uint\n"
40457162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "%type_pushconstant_uniformblock_member_size = OpTypePointer PushConstant %type_vec2\n"
4050abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4060d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov		<< "%type_image_sparse				= " << getOpTypeImageSparse(m_imageType, m_format, typeImgComp, true) << "\n"
4070abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_sampled_image_sparse		= OpTypeSampledImage %type_image_sparse\n"
4080abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%type_uniformconst_image_sparse = OpTypePointer UniformConstant %type_sampled_image_sparse\n"
4090abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4100abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%varying_texCoord			= OpVariable %type_input_vec3 Input\n"
4110abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4120abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%output_texel				= OpVariable %type_output_img_comp_vec4 Output\n"
4130abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%output_residency			= OpVariable %type_output_uint Output\n"
4140abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4150abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%uniformconst_image_sparse	= OpVariable %type_uniformconst_image_sparse UniformConstant\n"
4160abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
41757162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "%uniformblock_instance  = OpVariable %type_pushconstant_uniformblock PushConstant\n"
4180abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4190abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Declare constants
4200abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%constant_uint_0				= OpConstant %type_uint 0\n"
421653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos		<< "%constant_uint_1				= OpConstant %type_uint 1\n"
422653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos		<< "%constant_uint_2				= OpConstant %type_uint 2\n"
423653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos		<< "%constant_uint_3				= OpConstant %type_uint 3\n"
424653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos		<< "%constant_int_0					= OpConstant %type_int  0\n"
425653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos		<< "%constant_int_1					= OpConstant %type_int  1\n"
426653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos		<< "%constant_int_2					= OpConstant %type_int  2\n"
427653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos		<< "%constant_int_3					= OpConstant %type_int  3\n"
42857162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "%constant_float_0				= OpConstant %type_float 0.0\n"
42957162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "%constant_float_half			= OpConstant %type_float 0.5\n"
430653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos		<< "%constant_texel_resident		= OpConstant %type_uint " << MEMORY_BLOCK_BOUND_VALUE << "\n"
4310abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%constant_texel_not_resident	= OpConstant %type_uint " << MEMORY_BLOCK_NOT_BOUND_VALUE << "\n"
4320abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4330abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Call main function
434653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos		<< "%func_main		 = OpFunction %type_void None %type_void_func\n"
4350abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%label_func_main = OpLabel\n"
4360abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4370abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%local_image_sparse = OpLoad %type_sampled_image_sparse %uniformconst_image_sparse\n"
4380abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4398dbcd50b26a3d29df3ae9fdfd2c32186369de2a0Slawomir Cygan		<< "%texCoord = OpLoad %type_vec3 %varying_texCoord\n"
4408dbcd50b26a3d29df3ae9fdfd2c32186369de2a0Slawomir Cygan
4418dbcd50b26a3d29df3ae9fdfd2c32186369de2a0Slawomir Cygan		<< "%local_texCoord_x = OpCompositeExtract %type_float %texCoord 0\n"
4428dbcd50b26a3d29df3ae9fdfd2c32186369de2a0Slawomir Cygan		<< "%local_texCoord_y = OpCompositeExtract %type_float %texCoord 1\n"
4438dbcd50b26a3d29df3ae9fdfd2c32186369de2a0Slawomir Cygan		<< "%local_texCoord_z = OpCompositeExtract %type_float %texCoord 2\n"
4440abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
445653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos		<< "%local_texCoord_xy	= OpCompositeConstruct %type_vec2 %local_texCoord_x %local_texCoord_y\n"
4460abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%local_texCoord_xyz = OpCompositeConstruct %type_vec3 %local_texCoord_x %local_texCoord_y %local_texCoord_z\n"
4470abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
44857162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "%access_uniformblock_member_uint_lod = OpAccessChain %type_pushconstant_uniformblock_member_lod %uniformblock_instance %constant_int_0\n"
4490abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%local_uniformblock_member_uint_lod  = OpLoad %type_uint %access_uniformblock_member_uint_lod\n"
4500abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%local_uniformblock_member_float_lod = OpConvertUToF %type_float %local_uniformblock_member_uint_lod\n"
45157162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "%access_uniformblock_member_size	 = OpAccessChain %type_pushconstant_uniformblock_member_size %uniformblock_instance %constant_int_1\n"
45257162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		<< "%local_uniformblock_member_size		 = OpLoad %type_vec2 %access_uniformblock_member_size\n"
4530abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4540abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< sparseImageOpString("%local_sparse_op_result", "%type_struct_int_img_comp_vec4", "%local_image_sparse", coordString, "%local_uniformblock_member_float_lod") << "\n"
4550abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4560abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Load texel value
4570d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov		<< "%local_img_comp_vec4 = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_op_result 1\n"
4580abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4590abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpStore %output_texel %local_img_comp_vec4\n"
4600abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4610abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Load residency code
4620abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%local_residency_code = OpCompositeExtract %type_int %local_sparse_op_result 0\n"
4630abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4640abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Check if loaded texel is placed in resident memory
4650abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%local_texel_resident = OpImageSparseTexelsResident %type_bool %local_residency_code\n"
4660abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpSelectionMerge %branch_texel_resident None\n"
4670abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpBranchConditional %local_texel_resident %label_texel_resident %label_texel_not_resident\n"
4680abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%label_texel_resident = OpLabel\n"
4690abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4700abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Loaded texel is in resident memory
4710abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpStore %output_residency %constant_texel_resident\n"
4720abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4730abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpBranch %branch_texel_resident\n"
4740abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%label_texel_not_resident = OpLabel\n"
4750abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4760abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Loaded texel is not in resident memory
4770abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpStore %output_residency %constant_texel_not_resident\n"
4780abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4790abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpBranch %branch_texel_resident\n"
4800abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "%branch_texel_resident = OpLabel\n"
481a15e7d7f566d93c76ca90171eb728e3d1cd82378Pyry Haulos
4820abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpReturn\n"
4830abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		<< "OpFunctionEnd\n";
4840abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4850abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	programCollection.spirvAsmSources.add("fragment_shader") << fs.str();
4860abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch}
4870abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4880abb8ae884208e3355eb68bde6cedab1dd7b773cKantochstd::string	SparseCaseOpImageSparseSampleExplicitLod::sparseImageOpString (const std::string& resultVariable,
4890abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																		   const std::string& resultType,
4900abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																		   const std::string& image,
4910abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																		   const std::string& coord,
4920abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																		   const std::string& miplevel) const
4930abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
4940abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	std::ostringstream	src;
4950abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4960abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	src << resultVariable << " = OpImageSparseSampleExplicitLod " << resultType << " " << image << " " << coord << " Lod " << miplevel << "\n";
4970abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
4980abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	return src.str();
4990abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch}
5000abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5010abb8ae884208e3355eb68bde6cedab1dd7b773cKantochstd::string	SparseCaseOpImageSparseSampleImplicitLod::sparseImageOpString  (const std::string& resultVariable,
5020abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																			const std::string& resultType,
5030abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																			const std::string& image,
5040abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																			const std::string& coord,
5050abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																			const std::string& miplevel) const
5060abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
5070abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	DE_UNREF(miplevel);
5080abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5090abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	std::ostringstream	src;
5100abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5110abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	src << resultVariable << " = OpImageSparseSampleImplicitLod " << resultType << " " << image << " " << coord << "\n";
5120abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5130abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	return src.str();
5140abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch}
5150abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5160abb8ae884208e3355eb68bde6cedab1dd7b773cKantochstd::string	SparseCaseOpImageSparseGather::sparseImageOpString (const std::string& resultVariable,
5170abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																const std::string& resultType,
5180abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																const std::string& image,
5190abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																const std::string& coord,
5200abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																const std::string& miplevel) const
5210abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
5220abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	DE_UNREF(miplevel);
5230abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5240abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	std::ostringstream	src;
5250abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5260d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov	const std::string	typeImgComp		= getImageComponentTypeName(m_format);
5270d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov	const std::string	typeImgCompVec4	= getImageComponentVec4TypeName(m_format);
5280d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov
52957162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan	// Bias the coord value by half a texel, so we sample from center of 2x2 gather rectangle
53057162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan
53157162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan	src << "%local_image_width	= OpCompositeExtract %type_float %local_uniformblock_member_size 0\n";
53257162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan	src << "%local_image_height	= OpCompositeExtract %type_float %local_uniformblock_member_size 1\n";
53357162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan	src << "%local_coord_x_bias	= OpFDiv %type_float %constant_float_half %local_image_width\n";
53457162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan	src << "%local_coord_y_bias	= OpFDiv %type_float %constant_float_half %local_image_height\n";
535175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak
536175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak	switch (m_imageType)
537175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak	{
538175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak		case IMAGE_TYPE_2D:
539175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak		{
540175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak			src << "%local_coord_bias	= OpCompositeConstruct %type_vec2 %local_coord_x_bias %local_coord_y_bias\n";
541175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak			src << "%local_coord_biased	= OpFAdd %type_vec2 " << coord << " %local_coord_bias\n";
542175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak
543175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak			break;
544175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak		}
545175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak
546175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak		case IMAGE_TYPE_2D_ARRAY:
547175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak		case IMAGE_TYPE_3D:
548175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak		{
549175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak			src << "%local_coord_bias	= OpCompositeConstruct %type_vec3 %local_coord_x_bias %local_coord_y_bias %constant_float_0\n";
550175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak			src << "%local_coord_biased	= OpFAdd %type_vec3 " << coord << " %local_coord_bias\n";
551175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak
552175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak			break;
553175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak		}
554175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak
555175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak		default:
556175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak		{
557175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak			/* This can't be happening. */
558175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak			DE_ASSERT(DE_FALSE);
559175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak		}
560175b1a36b6a6700c85270bec34136979f05c3f67Dominik Witczak	}
56157162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan
56257162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan	src << "%local_sparse_gather_result_x = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_0\n";
56357162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan	src << "%local_sparse_gather_result_y = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_1\n";
56457162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan	src << "%local_sparse_gather_result_z = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_2\n";
56557162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan	src << "%local_sparse_gather_result_w = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_3\n";
5660abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5670abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	src << "%local_gather_residency_code = OpCompositeExtract %type_int %local_sparse_gather_result_x 0\n";
5680abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5690d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov	src << "%local_gather_texels_x = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_x 1\n";
5700d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov	src << "%local_gather_texels_y = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_y 1\n";
5710d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov	src << "%local_gather_texels_z = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_z 1\n";
5720d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov	src << "%local_gather_texels_w = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_w 1\n";
5730abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5740d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov	src << "%local_gather_primary_texel_x = OpCompositeExtract " << typeImgComp << " %local_gather_texels_x 3\n";
5750d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov	src << "%local_gather_primary_texel_y = OpCompositeExtract " << typeImgComp << " %local_gather_texels_y 3\n";
5760d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov	src << "%local_gather_primary_texel_z = OpCompositeExtract " << typeImgComp << " %local_gather_texels_z 3\n";
5770d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov	src << "%local_gather_primary_texel_w = OpCompositeExtract " << typeImgComp << " %local_gather_texels_w 3\n";
5780abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5790d16f7a9a94a1a2356c9a4e0c4265efb887a8c6fAndrey Tuganov	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";
5800abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	src << resultVariable << " = OpCompositeConstruct " << resultType << " %local_gather_residency_code %local_gather_primary_texel\n";
5810abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5820abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	return src.str();
5830abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch}
5840abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5850abb8ae884208e3355eb68bde6cedab1dd7b773cKantochclass SparseShaderIntrinsicsInstanceSampledBase : public SparseShaderIntrinsicsInstanceBase
5860abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
5870abb8ae884208e3355eb68bde6cedab1dd7b773cKantochpublic:
5880abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	SparseShaderIntrinsicsInstanceSampledBase	(Context&					context,
5890abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch												 const SpirVFunction		function,
5900abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch												 const ImageType			imageType,
5910abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch												 const tcu::UVec3&			imageSize,
5920abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch												 const tcu::TextureFormat&	format)
5930abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	: SparseShaderIntrinsicsInstanceBase(context, function, imageType, imageSize, format) {}
5940abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5950abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	VkImageUsageFlags		imageSparseUsageFlags	(void) const;
5960abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	VkImageUsageFlags		imageOutputUsageFlags	(void) const;
5970abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
5980abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	VkQueueFlags			getQueueFlags			(void) const;
5990abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
600a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	void					recordCommands			(const VkCommandBuffer		commandBuffer,
6010abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch													 const VkImageCreateInfo&	imageSparseInfo,
6020abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch													 const VkImage				imageSparse,
6030abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch													 const VkImage				imageTexels,
6040abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch													 const VkImage				imageResidency);
6050abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
6060abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	virtual VkImageSubresourceRange	sampledImageRangeToBind(const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const = 0;
6070abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
6080abb8ae884208e3355eb68bde6cedab1dd7b773cKantochprivate:
609a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	typedef de::SharedPtr< vk::Unique<vk::VkFramebuffer> > VkFramebufferSp;
6100abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
611a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	Move<VkBuffer>					m_vertexBuffer;
612a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	de::MovePtr<Allocation>			m_vertexBufferAlloc;
613a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	std::vector<VkFramebufferSp>	m_framebuffers;
614a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	Move<VkRenderPass>				m_renderPass;
615a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	Move<VkSampler>					m_sampler;
6160abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch};
6170abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
6180abb8ae884208e3355eb68bde6cedab1dd7b773cKantochVkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageSparseUsageFlags (void) const
6190abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
6200abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	return VK_IMAGE_USAGE_SAMPLED_BIT;
6210abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch}
6220abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
6230abb8ae884208e3355eb68bde6cedab1dd7b773cKantochVkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageOutputUsageFlags (void) const
6240abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
6250abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
6260abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch}
6270abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
6280abb8ae884208e3355eb68bde6cedab1dd7b773cKantochVkQueueFlags SparseShaderIntrinsicsInstanceSampledBase::getQueueFlags (void) const
6290abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
6300abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	return VK_QUEUE_GRAPHICS_BIT;
6310abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch}
6320abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
633a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowskivoid SparseShaderIntrinsicsInstanceSampledBase::recordCommands (const VkCommandBuffer		commandBuffer,
6340abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																const VkImageCreateInfo&	imageSparseInfo,
6350abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																const VkImage				imageSparse,
6360abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																const VkImage				imageTexels,
6370abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch																const VkImage				imageResidency)
6380abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
6390abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const InstanceInterface&		 instance			= m_context.getInstanceInterface();
6400d621e6dd1cce20b9d5d2826b996d923a2305f4cMaciej Jesionowski	const DeviceInterface&			 deviceInterface	= getDeviceInterface();
6410abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkPhysicalDevice			 physicalDevice		= m_context.getPhysicalDevice();
6420abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkPhysicalDeviceProperties deviceProperties	= getPhysicalDeviceProperties(instance, physicalDevice);
6430abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
6440abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	if (imageSparseInfo.extent.width  > deviceProperties.limits.maxFramebufferWidth  ||
6450abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		imageSparseInfo.extent.height > deviceProperties.limits.maxFramebufferHeight ||
6460abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		imageSparseInfo.arrayLayers   > deviceProperties.limits.maxFramebufferLayers)
6470abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
6480abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		TCU_THROW(NotSupportedError, "Image size exceeds allowed framebuffer dimensions");
6490abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	}
6500abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
6510abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	// Check if device supports image format for sampled images
6520abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
6530abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		TCU_THROW(NotSupportedError, "Device does not support image format for sampled images");
6540abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
655a15e7d7f566d93c76ca90171eb728e3d1cd82378Pyry Haulos	// Check if device supports image format for color attachment
6560abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
6570abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		TCU_THROW(NotSupportedError, "Device does not support image format for color attachment");
6580abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
6590abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	// Make sure device supports VK_FORMAT_R32_UINT format for color attachment
6600abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	if (!checkImageFormatFeatureSupport(instance, physicalDevice, mapTextureFormat(m_residencyFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
6610abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		TCU_THROW(TestError, "Device does not support VK_FORMAT_R32_UINT format for color attachment");
6620abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
6630abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	// Create buffer storing vertex data
6640abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	std::vector<tcu::Vec2> vertexData;
6650abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
6660abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	vertexData.push_back(tcu::Vec2(-1.0f,-1.0f));
6670abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	vertexData.push_back(tcu::Vec2( 0.0f, 0.0f));
668a15e7d7f566d93c76ca90171eb728e3d1cd82378Pyry Haulos
6690abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	vertexData.push_back(tcu::Vec2(-1.0f, 1.0f));
6700abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	vertexData.push_back(tcu::Vec2( 0.0f, 1.0f));
6710abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
6720abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	vertexData.push_back(tcu::Vec2( 1.0f,-1.0f));
6730abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	vertexData.push_back(tcu::Vec2( 1.0f, 0.0f));
6740abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
6750abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	vertexData.push_back(tcu::Vec2( 1.0f, 1.0f));
6760abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	vertexData.push_back(tcu::Vec2( 1.0f, 1.0f));
6770abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
678a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkDeviceSize			vertexDataSizeInBytes	= sizeInBytes(vertexData);
679a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const VkBufferCreateInfo	vertexBufferCreateInfo	= makeBufferCreateInfo(vertexDataSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
6800abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
681a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	m_vertexBuffer		= createBuffer(deviceInterface, getDevice(), &vertexBufferCreateInfo);
682a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	m_vertexBufferAlloc	= bindBuffer(deviceInterface, getDevice(), getAllocator(), *m_vertexBuffer, MemoryRequirement::HostVisible);
6830abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
684a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	deMemcpy(m_vertexBufferAlloc->getHostPtr(), &vertexData[0], static_cast<std::size_t>(vertexDataSizeInBytes));
685a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	flushMappedMemoryRange(deviceInterface, getDevice(), m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexDataSizeInBytes);
6860abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
6870abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	// Create render pass
6880abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkAttachmentDescription texelsAttachmentDescription =
6890abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
6900abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
6910abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		imageSparseInfo.format,								// VkFormat							format;
6920abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
6930abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
6940abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
6950abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
6960abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
6970abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
6980abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
6990abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	};
7000abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
7010abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkAttachmentDescription residencyAttachmentDescription =
7020abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
7030abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
7040abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		mapTextureFormat(m_residencyFormat),				// VkFormat							format;
7050abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
7060abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
7070abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
7080abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
7090abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
7100abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
7110abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
7120abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	};
7130abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
7140abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkAttachmentDescription colorAttachmentsDescription[] = { texelsAttachmentDescription, residencyAttachmentDescription };
7150abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
7160abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkAttachmentReference texelsAttachmentReference =
7170abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
7180abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		0u,													// deUint32			attachment;
7190abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
7200abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	};
7210abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
7220abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkAttachmentReference residencyAttachmentReference =
7230abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
7240abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		1u,													// deUint32			attachment;
7250abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
7260abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	};
7270abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
7280abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkAttachmentReference colorAttachmentsReference[] = { texelsAttachmentReference, residencyAttachmentReference };
7290abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
7300abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkAttachmentReference depthAttachmentReference =
7310abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
7320abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_ATTACHMENT_UNUSED,								// deUint32			attachment;
7330abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_IMAGE_LAYOUT_UNDEFINED							// VkImageLayout	layout;
7340abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	};
7350abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
7360abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkSubpassDescription subpassDescription =
7370abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
7380abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags;
7390abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
7400abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		0u,													// deUint32							inputAttachmentCount;
7410abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
7420abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		2u,													// deUint32							colorAttachmentCount;
7430abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		colorAttachmentsReference,							// const VkAttachmentReference*		pColorAttachments;
7440abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
7450abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		&depthAttachmentReference,							// const VkAttachmentReference*		pDepthStencilAttachment;
7460abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		0u,													// deUint32							preserveAttachmentCount;
7470abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		DE_NULL												// const deUint32*					pPreserveAttachments;
7480abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	};
7490abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
7500abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkRenderPassCreateInfo renderPassInfo =
7510abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
7520abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
7530abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		DE_NULL,											// const void*						pNext;
7540abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags;
7550abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		2u,													// deUint32							attachmentCount;
7560abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		colorAttachmentsDescription,						// const VkAttachmentDescription*	pAttachments;
7570abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		1u,													// deUint32							subpassCount;
7580abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
7590abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		0u,													// deUint32							dependencyCount;
7600abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		DE_NULL												// const VkSubpassDependency*		pDependencies;
7610abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	};
7620abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
763a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	m_renderPass = createRenderPass(deviceInterface, getDevice(), &renderPassInfo);
7640abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
7650abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	// Create descriptor set layout
7660abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	DescriptorSetLayoutBuilder descriptorLayerBuilder;
7670abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
7680abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	descriptorLayerBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
7690abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
770a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const Unique<VkDescriptorSetLayout> descriptorSetLayout(descriptorLayerBuilder.build(deviceInterface, getDevice()));
7710abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
7720abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	// Create descriptor pool
7730abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	DescriptorPoolBuilder descriptorPoolBuilder;
7740abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
7750abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSparseInfo.mipLevels);
7760abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
777a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	descriptorPool = descriptorPoolBuilder.build(deviceInterface, getDevice(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, imageSparseInfo.mipLevels);
7780abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
7790abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	// Create sampler object
7800abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const tcu::Sampler			samplerObject(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST);
7810abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkSamplerCreateInfo	samplerCreateInfo = mapSampler(samplerObject, m_format);
782a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	m_sampler = createSampler(deviceInterface, getDevice(), &samplerCreateInfo);
7830abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
78457162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan	struct PushConstants
78557162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan	{
78657162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		deUint32	lod;
78757162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		deUint32	padding;			// padding needed to satisfy std430 rules
78857162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		float		lodWidth;
78957162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		float		lodHeight;
79057162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan	};
79157162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan
7920abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	// Create pipeline layout
7930abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkPushConstantRange lodConstantRange =
7940abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
7950abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_SHADER_STAGE_FRAGMENT_BIT,	// VkShaderStageFlags	stageFlags;
7960abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		0u,								// deUint32			offset;
79757162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		sizeof(PushConstants),			// deUint32			size;
7980abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	};
7990abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8000abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkPipelineLayoutCreateInfo pipelineLayoutParams =
8010abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
8020abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
8030abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		DE_NULL,											// const void*						pNext;
8040abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		0u,													// VkPipelineLayoutCreateFlags		flags;
8050abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		1u,													// deUint32							setLayoutCount;
8060abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		&descriptorSetLayout.get(),							// const VkDescriptorSetLayout*		pSetLayouts;
8070abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		1u,													// deUint32							pushConstantRangeCount;
8080abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		&lodConstantRange,									// const VkPushConstantRange*		pPushConstantRanges;
8090abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	};
8100abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
811a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(deviceInterface, getDevice(), &pipelineLayoutParams));
8120abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8130abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	// Create graphics pipeline
8140abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
815a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		Move<VkShaderModule> vertexModule	= createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0);
816a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		Move<VkShaderModule> fragmentModule	= createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0);
817a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		Move<VkShaderModule> geometryModule;
8180abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8190abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		if (imageSparseInfo.arrayLayers > 1u)
8200abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		{
8210abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			requireFeatures(instance, physicalDevice, FEATURE_GEOMETRY_SHADER);
822a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			geometryModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("geometry_shader"), (VkShaderModuleCreateFlags)0);
8230abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		}
8240abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
825a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		pipelines.push_back(makeVkSharedPtr(makeGraphicsPipeline(
826a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			deviceInterface, getDevice(), *pipelineLayout, *m_renderPass, *vertexModule, *fragmentModule, *geometryModule)));
8270abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	}
8280abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8290abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	const VkPipeline graphicsPipeline = **pipelines[0];
8300abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8310abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
8320abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
8330abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8340abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VkImageMemoryBarrier imageShaderAccessBarriers[3];
8350abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8360abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		imageShaderAccessBarriers[0] = makeImageMemoryBarrier
8370abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		(
8380abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_ACCESS_TRANSFER_WRITE_BIT,
8390abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_ACCESS_SHADER_READ_BIT,
8400abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
8410abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
8420abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			imageSparse,
8430abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			fullImageSubresourceRange
8440abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		);
8450abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8460abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		imageShaderAccessBarriers[1] = makeImageMemoryBarrier
8470abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		(
8480abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			0u,
8490abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
8500abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_IMAGE_LAYOUT_UNDEFINED,
8510abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
8520abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			imageTexels,
8530abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			fullImageSubresourceRange
8540abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		);
8550abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8560abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		imageShaderAccessBarriers[2] = makeImageMemoryBarrier
8570abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		(
8580abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			0u,
8590abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
8600abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_IMAGE_LAYOUT_UNDEFINED,
8610abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
8620abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			imageResidency,
8630abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			fullImageSubresourceRange
8640abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		);
8650abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8660abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 3u, imageShaderAccessBarriers);
8670abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	}
8680abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8690abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	imageSparseViews.resize(imageSparseInfo.mipLevels);
8700abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	imageTexelsViews.resize(imageSparseInfo.mipLevels);
8710abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	imageResidencyViews.resize(imageSparseInfo.mipLevels);
872a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	m_framebuffers.resize(imageSparseInfo.mipLevels);
8730abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	descriptorSets.resize(imageSparseInfo.mipLevels);
8740abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8750abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	std::vector<VkClearValue> clearValues;
8760abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
8770abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
8780abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8790abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
8800abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
8810abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		const vk::VkExtent3D mipLevelSize = mipLevelExtents(imageSparseInfo.extent, mipLevelNdx);
882a15e7d7f566d93c76ca90171eb728e3d1cd82378Pyry Haulos
883a15e7d7f566d93c76ca90171eb728e3d1cd82378Pyry Haulos		const vk::VkRect2D renderArea =
8840abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		{
8850abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			makeOffset2D(0u, 0u),
8860abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			makeExtent2D(mipLevelSize.width, mipLevelSize.height),
8870abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		};
8880abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8890abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		const VkViewport viewport = makeViewport
8900abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		(
8910abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			0.0f, 0.0f,
8920abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			static_cast<float>(mipLevelSize.width), static_cast<float>(mipLevelSize.height),
8930abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			0.0f, 1.0f
8940abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		);
8950abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8960abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		const VkImageSubresourceRange mipLevelRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevelNdx, 1u, 0u, imageSparseInfo.arrayLayers);
8970abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
8980abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Create color attachments image views
899a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		imageTexelsViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageTexels, mapImageViewType(m_imageType), imageSparseInfo.format, mipLevelRange));
900a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		imageResidencyViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageResidency, mapImageViewType(m_imageType), mapTextureFormat(m_residencyFormat), mipLevelRange));
9010abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9020abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		const VkImageView attachmentsViews[] = { **imageTexelsViews[mipLevelNdx], **imageResidencyViews[mipLevelNdx] };
9030abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9040abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Create framebuffer
9050abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		const VkFramebufferCreateInfo framebufferInfo =
9060abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		{
9070abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType                             sType;
9080abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			DE_NULL,									// const void*                                 pNext;
9090abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			(VkFramebufferCreateFlags)0,				// VkFramebufferCreateFlags                    flags;
910a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			*m_renderPass,								// VkRenderPass                                renderPass;
9110abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			2u,											// uint32_t                                    attachmentCount;
9120abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			attachmentsViews,							// const VkImageView*                          pAttachments;
9130abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			mipLevelSize.width,							// uint32_t                                    width;
9140abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			mipLevelSize.height,						// uint32_t                                    height;
9150abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			imageSparseInfo.arrayLayers,				// uint32_t                                    layers;
9160abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		};
9170abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
918a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		m_framebuffers[mipLevelNdx] = makeVkSharedPtr(createFramebuffer(deviceInterface, getDevice(), &framebufferInfo));
9190abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9200abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Create descriptor set
921a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		descriptorSets[mipLevelNdx] = makeVkSharedPtr(makeDescriptorSet(deviceInterface, getDevice(), *descriptorPool, *descriptorSetLayout));
9220abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		const VkDescriptorSet descriptorSet = **descriptorSets[mipLevelNdx];
9230abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9240abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Update descriptor set
9250abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		const VkImageSubresourceRange sparseImageSubresourceRange = sampledImageRangeToBind(imageSparseInfo, mipLevelNdx);
9260abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
927a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		imageSparseViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageSparse, mapImageViewType(m_imageType), imageSparseInfo.format, sparseImageSubresourceRange));
9280abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
929a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		const VkDescriptorImageInfo imageSparseDescInfo = makeDescriptorImageInfo(*m_sampler, **imageSparseViews[mipLevelNdx], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
9300abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9310abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		DescriptorSetUpdateBuilder descriptorUpdateBuilder;
9320abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9330abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		descriptorUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(BINDING_IMAGE_SPARSE), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSparseDescInfo);
934a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		descriptorUpdateBuilder.update(deviceInterface, getDevice());
9350abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9360abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Begin render pass
937a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		{
938a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			const VkRenderPassBeginInfo renderPassBeginInfo =
939a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			{
940a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski				VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
941a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski				DE_NULL,										// const void*             pNext;
942a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski				*m_renderPass,									// VkRenderPass            renderPass;
943a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski				**m_framebuffers[mipLevelNdx],					// VkFramebuffer           framebuffer;
944a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski				renderArea,										// VkRect2D                renderArea;
945a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski				static_cast<deUint32>(clearValues.size()),		// deUint32                clearValueCount;
946a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski				&clearValues[0],								// const VkClearValue*     pClearValues;
947a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			};
948a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
949a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			deviceInterface.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
950a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		}
9510abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9520abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Bind graphics pipeline
9530abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		deviceInterface.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
9540abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9550abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Bind descriptor set
9560abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		deviceInterface.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
9570abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9580abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Bind vertex buffer
959a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		{
960a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			const VkDeviceSize offset = 0ull;
961a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski			deviceInterface.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &m_vertexBuffer.get(), &offset);
962a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		}
9630abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9640abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Bind Viewport
9650abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		deviceInterface.cmdSetViewport(commandBuffer, 0u, 1u, &viewport);
9660abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9670abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Bind Scissor Rectangle
9680abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		deviceInterface.cmdSetScissor(commandBuffer, 0u, 1u, &renderArea);
9690abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
97057162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		const PushConstants pushConstants =
97157162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		{
97257162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan			mipLevelNdx,
97357162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan			0u,											// padding
97457162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan			static_cast<float>(mipLevelSize.width),
97557162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan			static_cast<float>(mipLevelSize.height)
97657162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		};
97757162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan
9780abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Update push constants
97957162191ce545755054f989c1bc029a30ede72c8Slawomir Cygan		deviceInterface.cmdPushConstants(commandBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(PushConstants), &pushConstants);
9800abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9810abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// Draw full screen quad
9820abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		deviceInterface.cmdDraw(commandBuffer, 4u, 1u, 0u, 0u);
983a15e7d7f566d93c76ca90171eb728e3d1cd82378Pyry Haulos
9840abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		// End render pass
985a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		deviceInterface.cmdEndRenderPass(commandBuffer);
9860abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	}
9870abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9880abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	{
9890abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
9900abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9910abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		VkImageMemoryBarrier imageOutputTransferSrcBarriers[2];
9920abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
9930abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		imageOutputTransferSrcBarriers[0] = makeImageMemoryBarrier
9940abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		(
9950abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
9960abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_ACCESS_TRANSFER_READ_BIT,
9970abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
9980abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
9990abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			imageTexels,
10000abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			fullImageSubresourceRange
10010abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		);
10020abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
10030abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		imageOutputTransferSrcBarriers[1] = makeImageMemoryBarrier
10040abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		(
10050abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
10060abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_ACCESS_TRANSFER_READ_BIT,
10070abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
10080abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
10090abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			imageResidency,
10100abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch			fullImageSubresourceRange
10110abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		);
10120abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
10130abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch		deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageOutputTransferSrcBarriers);
10140abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	}
10150abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch}
10160abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
10170abb8ae884208e3355eb68bde6cedab1dd7b773cKantochclass SparseShaderIntrinsicsInstanceSampledExplicit : public SparseShaderIntrinsicsInstanceSampledBase
10180abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
10190abb8ae884208e3355eb68bde6cedab1dd7b773cKantochpublic:
10200abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	SparseShaderIntrinsicsInstanceSampledExplicit	(Context&					context,
10210abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch													 const SpirVFunction		function,
10220abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch													 const ImageType			imageType,
10230abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch													 const tcu::UVec3&			imageSize,
10240abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch													 const tcu::TextureFormat&	format)
10250abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	: SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
10260abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
1027a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	VkImageSubresourceRange sampledImageRangeToBind (const VkImageCreateInfo&	imageSparseInfo,
1028a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski													 const deUint32				mipLevel) const
1029a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
1030a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		DE_UNREF(mipLevel);
1031a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
1032a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	}
10330abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch};
10340abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
10350abb8ae884208e3355eb68bde6cedab1dd7b773cKantochTestInstance* SparseShaderIntrinsicsCaseSampledExplicit::createInstance (Context& context) const
10360abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
10370abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	return new SparseShaderIntrinsicsInstanceSampledExplicit(context, m_function, m_imageType, m_imageSize, m_format);
10380abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch}
10390abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
10400abb8ae884208e3355eb68bde6cedab1dd7b773cKantochclass SparseShaderIntrinsicsInstanceSampledImplicit : public SparseShaderIntrinsicsInstanceSampledBase
10410abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
10420abb8ae884208e3355eb68bde6cedab1dd7b773cKantochpublic:
10430abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	SparseShaderIntrinsicsInstanceSampledImplicit	(Context&					context,
10440abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch													 const SpirVFunction		function,
10450abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch													 const ImageType			imageType,
10460abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch													 const tcu::UVec3&			imageSize,
10470abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch													 const tcu::TextureFormat&	format)
10480abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	: SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
10490abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
1050a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	VkImageSubresourceRange	sampledImageRangeToBind	(const VkImageCreateInfo&	imageSparseInfo,
1051a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski													 const deUint32				mipLevel) const
1052a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	{
1053a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski		return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 1u, 0u, imageSparseInfo.arrayLayers);
1054a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski	}
10550abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch};
10560abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
10570abb8ae884208e3355eb68bde6cedab1dd7b773cKantochTestInstance* SparseShaderIntrinsicsCaseSampledImplicit::createInstance (Context& context) const
10580abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch{
10590abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch	return new SparseShaderIntrinsicsInstanceSampledImplicit(context, m_function, m_imageType, m_imageSize, m_format);
10600abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch}
10610abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch
10620abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch} // sparse
10630abb8ae884208e3355eb68bde6cedab1dd7b773cKantoch} // vkt
1064