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