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 #include "vkTypeUtil.hpp"
26 #include "vkCmdUtil.hpp"
27 #include "vkObjUtil.hpp"
28 #include "vkBarrierUtil.hpp"
29 #include "vkBufferWithMemory.hpp"
30
31 using namespace vk;
32
33 namespace vkt
34 {
35 namespace sparse
36 {
37 namespace
38 {
39
makeGraphicsPipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkRenderPass renderPass,const VkShaderModule vertexModule,const VkShaderModule fragmentModule,const VkShaderModule geometryModule)40 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
41 const VkDevice device,
42 const VkPipelineLayout pipelineLayout,
43 const VkRenderPass renderPass,
44 const VkShaderModule vertexModule,
45 const VkShaderModule fragmentModule,
46 const VkShaderModule geometryModule)
47 {
48 const std::vector<VkViewport> noViewports;
49 const std::vector<VkRect2D> noScissors;
50
51 const VkFormat format = VK_FORMAT_R32G32_SFLOAT;
52 const deUint32 size = tcu::getPixelSize(mapVkFormat(format));
53
54 const VkVertexInputBindingDescription vertexBinding =
55 {
56 0u, // deUint32 binding;
57 size * 2, // deUint32 stride;
58 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
59 };
60
61 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
62 {
63 // position
64 {
65 0u, // deUint32 location;
66 0u, // deUint32 binding;
67 format, // VkFormat format;
68 0u // deUint32 offset;
69 },
70 // texture coordinates
71 {
72 1u, // deUint32 location;
73 0u, // deUint32 binding;
74 format, // VkFormat format;
75 size // deUint32 offset;
76 },
77 };
78
79 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
80 {
81 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
82 DE_NULL, // const void* pNext;
83 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
84 1u, // deUint32 vertexBindingDescriptionCount;
85 &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
86 2u, // deUint32 vertexAttributeDescriptionCount;
87 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
88 };
89
90 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
91 const VkPipelineColorBlendAttachmentState defaultColorBlendAttachmentState =
92 {
93 VK_FALSE, // VkBool32 blendEnable;
94 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
95 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
96 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
97 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
98 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
99 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
100 colorComponentsAll // VkColorComponentFlags colorWriteMask;
101 };
102
103 const VkPipelineColorBlendAttachmentState colorBlendAttachmentStates[] =
104 {
105 defaultColorBlendAttachmentState,
106 defaultColorBlendAttachmentState
107 };
108
109 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
110 {
111 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
112 DE_NULL, // const void* pNext;
113 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
114 VK_FALSE, // VkBool32 logicOpEnable;
115 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
116 DE_LENGTH_OF_ARRAY(colorBlendAttachmentStates), // deUint32 attachmentCount;
117 colorBlendAttachmentStates, // const VkPipelineColorBlendAttachmentState* pAttachments;
118 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
119 };
120
121 return vk::makeGraphicsPipeline(vk, // const DeviceInterface& vk
122 device, // const VkDevice device
123 pipelineLayout, // const VkPipelineLayout pipelineLayout
124 vertexModule, // const VkShaderModule vertexShaderModule
125 DE_NULL, // const VkShaderModule tessellationControlModule
126 DE_NULL, // const VkShaderModule tessellationEvalModule
127 geometryModule, // const VkShaderModule geometryShaderModule
128 fragmentModule, // const VkShaderModule fragmentShaderModule
129 renderPass, // const VkRenderPass renderPass
130 noViewports, // const std::vector<VkViewport>& viewports
131 noScissors, // const std::vector<VkRect2D>& scissors
132 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology
133 0u, // const deUint32 subpass
134 0u, // const deUint32 patchControlPoints
135 &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
136 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
137 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
138 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
139 &pipelineColorBlendStateInfo); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
140 }
141
142 } // anonymous
143
initPrograms(vk::SourceCollections & programCollection) const144 void SparseShaderIntrinsicsCaseSampledBase::initPrograms (vk::SourceCollections& programCollection) const
145 {
146 const PlanarFormatDescription formatDescription = getPlanarFormatDescription(m_format);
147 const deUint32 numLayers = getNumLayers(m_imageType, m_imageSize);
148 const std::string coordString = getShaderImageCoordinates(m_imageType, "%local_texCoord_x", "%local_texCoord_xy", "%local_texCoord_xyz");
149
150 // Create vertex shader
151 std::ostringstream vs;
152
153 vs << "#version 440\n"
154 << "#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require\n"
155 << "#extension GL_EXT_shader_image_int64 : require\n"
156 << "layout(location = 0) in highp vec2 vs_in_position;\n"
157 << "layout(location = 1) in highp vec2 vs_in_texCoord;\n"
158 << "\n"
159 << "layout(location = 0) out highp vec3 vs_out_texCoord;\n"
160 << "\n"
161 << "out gl_PerVertex {\n"
162 << " vec4 gl_Position;\n"
163 << "};\n"
164 << "void main (void)\n"
165 << "{\n"
166 << " gl_Position = vec4(vs_in_position, 0.0f, 1.0f);\n"
167 << " vs_out_texCoord = vec3(vs_in_texCoord, 0.0f);\n"
168 << "}\n";
169
170 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
171
172 if (numLayers > 1u)
173 {
174 const deInt32 maxVertices = 3u * numLayers;
175
176 // Create geometry shader
177 std::ostringstream gs;
178
179 gs << "#version 440\n"
180 << "layout(triangles) in;\n"
181 << "layout(triangle_strip, max_vertices = " << static_cast<deInt32>(maxVertices) << ") out;\n"
182 << "\n"
183 << "in gl_PerVertex {\n"
184 << " vec4 gl_Position;\n"
185 << "} gl_in[];\n"
186 << "out gl_PerVertex {\n"
187 << " vec4 gl_Position;\n"
188 << "};\n"
189 << "layout(location = 0) in highp vec3 gs_in_texCoord[];\n"
190 << "\n"
191 << "layout(location = 0) out highp vec3 gs_out_texCoord;\n"
192 << "\n"
193 << "void main (void)\n"
194 << "{\n"
195 << " for (int layerNdx = 0; layerNdx < " << static_cast<deInt32>(numLayers) << "; ++layerNdx)\n"
196 << " {\n"
197 << " for (int vertexNdx = 0; vertexNdx < gl_in.length(); ++vertexNdx)\n"
198 << " {\n"
199 << " gl_Layer = layerNdx;\n"
200 << " gl_Position = gl_in[vertexNdx].gl_Position;\n"
201 << " gs_out_texCoord = vec3(gs_in_texCoord[vertexNdx].xy, float(layerNdx));\n"
202 << " EmitVertex();\n"
203 << " }\n"
204 << " EndPrimitive();\n"
205 << " }\n"
206 << "}\n";
207
208 programCollection.glslSources.add("geometry_shader") << glu::GeometrySource(gs.str());
209 }
210
211 // Create fragment shader
212 std::ostringstream fs;
213
214 const std::string typeImgComp = getImageComponentTypeName(formatDescription);
215 const std::string typeImgCompVec4 = getImageComponentVec4TypeName(formatDescription);
216
217 SpirvVersion spirvVersion = SPIRV_VERSION_1_0;
218 std::string interfaceList = "";
219
220 if (m_operand.find("Nontemporal") != std::string::npos)
221 {
222 spirvVersion = SPIRV_VERSION_1_6;
223 interfaceList = " %uniformconst_image_sparse %uniformblock_instance";
224 }
225
226 fs << "OpCapability Shader\n"
227 << "OpCapability SampledCubeArray\n"
228 << "OpCapability ImageCubeArray\n"
229 << "OpCapability SparseResidency\n"
230 << "OpCapability StorageImageExtendedFormats\n";
231
232 if (formatIsR64(m_format))
233 {
234 fs << "OpCapability Int64\n"
235 << "OpCapability Int64ImageEXT\n"
236 << "OpExtension \"SPV_EXT_shader_image_int64\"\n";
237 }
238
239 fs << "%ext_import = OpExtInstImport \"GLSL.std.450\"\n"
240 << "OpMemoryModel Logical GLSL450\n"
241 << "OpEntryPoint Fragment %func_main \"main\" %varying_texCoord %output_texel %output_residency " << interfaceList << "\n"
242 << "OpExecutionMode %func_main OriginUpperLeft\n"
243 << "OpSource GLSL 440\n"
244
245 << "OpName %func_main \"main\"\n"
246
247 << "OpName %varying_texCoord \"varying_texCoord\"\n"
248
249 << "OpName %output_texel \"out_texel\"\n"
250 << "OpName %output_residency \"out_residency\"\n"
251
252 << "OpName %type_uniformblock \"LodBlock\"\n"
253 << "OpMemberName %type_uniformblock 0 \"lod\"\n"
254 << "OpMemberName %type_uniformblock 1 \"size\"\n"
255 << "OpName %uniformblock_instance \"lodInstance\"\n"
256
257 << "OpName %uniformconst_image_sparse \"u_imageSparse\"\n"
258
259 << "OpDecorate %varying_texCoord Location 0\n"
260
261 << "OpDecorate %output_texel Location 0\n"
262 << "OpDecorate %output_residency Location 1\n"
263
264 << "OpDecorate %type_uniformblock Block\n"
265 << "OpMemberDecorate %type_uniformblock 0 Offset 0\n"
266 << "OpMemberDecorate %type_uniformblock 1 Offset 8\n"
267
268 << "OpDecorate %uniformconst_image_sparse DescriptorSet 0\n"
269 << "OpDecorate %uniformconst_image_sparse Binding " << BINDING_IMAGE_SPARSE << "\n"
270
271 << "%type_void = OpTypeVoid\n"
272 << "%type_void_func = OpTypeFunction %type_void\n"
273
274 << "%type_bool = OpTypeBool\n"
275 << "%type_int = OpTypeInt 32 1\n"
276 << "%type_uint = OpTypeInt 32 0\n"
277 << "%type_float = OpTypeFloat 32\n"
278 << "%type_vec2 = OpTypeVector %type_float 2\n"
279 << "%type_vec3 = OpTypeVector %type_float 3\n"
280 << "%type_vec4 = OpTypeVector %type_float 4\n"
281 << "%type_ivec4 = OpTypeVector %type_int 4\n"
282 << "%type_uvec4 = OpTypeVector %type_uint 4\n"
283 << "%type_uniformblock = OpTypeStruct %type_uint %type_vec2\n";
284
285 if (formatIsR64(m_format))
286 {
287 fs << "%type_int64 = OpTypeInt 64 1\n"
288 << "%type_uint64 = OpTypeInt 64 0\n"
289 << "%type_i64vec2 = OpTypeVector %type_int64 2\n"
290 << "%type_i64vec3 = OpTypeVector %type_int64 3\n"
291 << "%type_i64vec4 = OpTypeVector %type_int64 4\n"
292 << "%type_u64vec3 = OpTypeVector %type_uint64 3\n"
293 << "%type_u64vec4 = OpTypeVector %type_uint64 4\n";
294 }
295
296 fs << "%type_struct_int_img_comp_vec4 = OpTypeStruct %type_int "<< typeImgCompVec4 << "\n"
297 << "%type_input_vec3 = OpTypePointer Input %type_vec3\n"
298 << "%type_input_float = OpTypePointer Input %type_float\n";
299
300 if (formatIsR64(m_format))
301 fs << "%type_output_img_comp_vec4 = OpTypePointer Output " << "%type_ivec4" << "\n";
302 else
303 fs << "%type_output_img_comp_vec4 = OpTypePointer Output " << typeImgCompVec4 << "\n";
304
305 fs << "%type_output_uint = OpTypePointer Output %type_uint\n"
306
307 << "%type_function_int = OpTypePointer Function %type_int\n"
308 << "%type_function_img_comp_vec4 = OpTypePointer Function " << typeImgCompVec4 << "\n"
309 << "%type_function_int_img_comp_vec4 = OpTypePointer Function %type_struct_int_img_comp_vec4\n"
310
311 << "%type_pushconstant_uniformblock = OpTypePointer PushConstant %type_uniformblock\n"
312 << "%type_pushconstant_uniformblock_member_lod = OpTypePointer PushConstant %type_uint\n"
313 << "%type_pushconstant_uniformblock_member_size = OpTypePointer PushConstant %type_vec2\n"
314
315 << "%type_image_sparse = " << getOpTypeImageSparse(m_imageType, m_format, typeImgComp, true) << "\n"
316 << "%type_sampled_image_sparse = OpTypeSampledImage %type_image_sparse\n"
317 << "%type_uniformconst_image_sparse = OpTypePointer UniformConstant %type_sampled_image_sparse\n"
318
319 << "%varying_texCoord = OpVariable %type_input_vec3 Input\n"
320
321 << "%output_texel = OpVariable %type_output_img_comp_vec4 Output\n"
322 << "%output_residency = OpVariable %type_output_uint Output\n"
323
324 << "%uniformconst_image_sparse = OpVariable %type_uniformconst_image_sparse UniformConstant\n"
325
326 << "%uniformblock_instance = OpVariable %type_pushconstant_uniformblock PushConstant\n"
327
328 // Declare constants
329 << "%constant_uint_0 = OpConstant %type_uint 0\n"
330 << "%constant_uint_1 = OpConstant %type_uint 1\n"
331 << "%constant_uint_2 = OpConstant %type_uint 2\n"
332 << "%constant_uint_3 = OpConstant %type_uint 3\n"
333 << "%constant_int_0 = OpConstant %type_int 0\n"
334 << "%constant_int_1 = OpConstant %type_int 1\n"
335 << "%constant_int_2 = OpConstant %type_int 2\n"
336 << "%constant_int_3 = OpConstant %type_int 3\n"
337 << "%constant_float_0 = OpConstant %type_float 0.0\n"
338 << "%constant_float_half = OpConstant %type_float 0.5\n"
339 << "%constant_texel_resident = OpConstant %type_uint " << MEMORY_BLOCK_BOUND_VALUE << "\n"
340 << "%constant_texel_not_resident = OpConstant %type_uint " << MEMORY_BLOCK_NOT_BOUND_VALUE << "\n"
341
342 // Call main function
343 << "%func_main = OpFunction %type_void None %type_void_func\n"
344 << "%label_func_main = OpLabel\n"
345
346 << "%local_image_sparse = OpLoad %type_sampled_image_sparse %uniformconst_image_sparse\n"
347
348 << "%texCoord = OpLoad %type_vec3 %varying_texCoord\n"
349
350 << "%local_texCoord_x = OpCompositeExtract %type_float %texCoord 0\n"
351 << "%local_texCoord_y = OpCompositeExtract %type_float %texCoord 1\n"
352 << "%local_texCoord_z = OpCompositeExtract %type_float %texCoord 2\n"
353
354 << "%local_texCoord_xy = OpCompositeConstruct %type_vec2 %local_texCoord_x %local_texCoord_y\n"
355 << "%local_texCoord_xyz = OpCompositeConstruct %type_vec3 %local_texCoord_x %local_texCoord_y %local_texCoord_z\n"
356
357 << "%access_uniformblock_member_uint_lod = OpAccessChain %type_pushconstant_uniformblock_member_lod %uniformblock_instance %constant_int_0\n"
358 << "%local_uniformblock_member_uint_lod = OpLoad %type_uint %access_uniformblock_member_uint_lod\n"
359 << "%local_uniformblock_member_float_lod = OpConvertUToF %type_float %local_uniformblock_member_uint_lod\n"
360 << "%access_uniformblock_member_size = OpAccessChain %type_pushconstant_uniformblock_member_size %uniformblock_instance %constant_int_1\n"
361 << "%local_uniformblock_member_size = OpLoad %type_vec2 %access_uniformblock_member_size\n"
362
363 << sparseImageOpString("%local_sparse_op_result", "%type_struct_int_img_comp_vec4", "%local_image_sparse", coordString, "%local_uniformblock_member_float_lod") << "\n"
364
365 // Load texel value
366 << "%local_img_comp_vec4 = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_op_result 1\n";
367
368 if (formatIsR64(m_format))
369 {
370 fs << "%local_img_comp32b = OpSConvert %type_ivec4 %local_img_comp_vec4\n"
371 << "OpStore %output_texel %local_img_comp32b\n";
372 }
373 else
374 {
375 fs << "OpStore %output_texel %local_img_comp_vec4\n";
376 }
377
378 // Load residency code
379 fs << "%local_residency_code = OpCompositeExtract %type_int %local_sparse_op_result 0\n"
380
381 // Check if loaded texel is placed in resident memory
382 << "%local_texel_resident = OpImageSparseTexelsResident %type_bool %local_residency_code\n"
383 << "OpSelectionMerge %branch_texel_resident None\n"
384 << "OpBranchConditional %local_texel_resident %label_texel_resident %label_texel_not_resident\n"
385 << "%label_texel_resident = OpLabel\n"
386
387 // Loaded texel is in resident memory
388 << "OpStore %output_residency %constant_texel_resident\n"
389
390 << "OpBranch %branch_texel_resident\n"
391 << "%label_texel_not_resident = OpLabel\n"
392
393 // Loaded texel is not in resident memory
394 << "OpStore %output_residency %constant_texel_not_resident\n"
395
396 << "OpBranch %branch_texel_resident\n"
397 << "%branch_texel_resident = OpLabel\n"
398
399 << "OpReturn\n"
400 << "OpFunctionEnd\n";
401
402 programCollection.spirvAsmSources.add("fragment_shader") << fs.str()
403 << vk::SpirVAsmBuildOptions(programCollection.usedVulkanVersion, spirvVersion);
404
405 }
406
sparseImageOpString(const std::string & resultVariable,const std::string & resultType,const std::string & image,const std::string & coord,const std::string & miplevel) const407 std::string SparseCaseOpImageSparseSampleExplicitLod::sparseImageOpString (const std::string& resultVariable,
408 const std::string& resultType,
409 const std::string& image,
410 const std::string& coord,
411 const std::string& miplevel) const
412 {
413 std::ostringstream src;
414 std::string additionalOperand = (m_operand.empty() ? " " : (std::string("|") + m_operand + " "));
415
416 src << resultVariable << " = OpImageSparseSampleExplicitLod " << resultType << " " << image << " " << coord << " Lod" << additionalOperand << miplevel << "\n";
417
418 return src.str();
419 }
420
sparseImageOpString(const std::string & resultVariable,const std::string & resultType,const std::string & image,const std::string & coord,const std::string & miplevel) const421 std::string SparseCaseOpImageSparseSampleImplicitLod::sparseImageOpString (const std::string& resultVariable,
422 const std::string& resultType,
423 const std::string& image,
424 const std::string& coord,
425 const std::string& miplevel) const
426 {
427 DE_UNREF(miplevel);
428
429 std::ostringstream src;
430
431 src << resultVariable << " = OpImageSparseSampleImplicitLod " << resultType << " " << image << " " << coord << " " << m_operand << "\n";
432
433 return src.str();
434 }
435
sparseImageOpString(const std::string & resultVariable,const std::string & resultType,const std::string & image,const std::string & coord,const std::string & miplevel) const436 std::string SparseCaseOpImageSparseGather::sparseImageOpString (const std::string& resultVariable,
437 const std::string& resultType,
438 const std::string& image,
439 const std::string& coord,
440 const std::string& miplevel) const
441 {
442 DE_UNREF(miplevel);
443
444 std::ostringstream src;
445
446 const PlanarFormatDescription formatDescription = getPlanarFormatDescription(m_format);
447 const std::string typeImgComp = getImageComponentTypeName(formatDescription);
448 const std::string typeImgCompVec4 = getImageComponentVec4TypeName(formatDescription);
449
450 // Bias the coord value by half a texel, so we sample from center of 2x2 gather rectangle
451
452 src << "%local_image_width = OpCompositeExtract %type_float %local_uniformblock_member_size 0\n";
453 src << "%local_image_height = OpCompositeExtract %type_float %local_uniformblock_member_size 1\n";
454 src << "%local_coord_x_bias = OpFDiv %type_float %constant_float_half %local_image_width\n";
455 src << "%local_coord_y_bias = OpFDiv %type_float %constant_float_half %local_image_height\n";
456
457 switch (m_imageType)
458 {
459 case IMAGE_TYPE_2D:
460 {
461 src << "%local_coord_bias = OpCompositeConstruct %type_vec2 %local_coord_x_bias %local_coord_y_bias\n";
462 src << "%local_coord_biased = OpFAdd %type_vec2 " << coord << " %local_coord_bias\n";
463
464 break;
465 }
466
467 case IMAGE_TYPE_2D_ARRAY:
468 case IMAGE_TYPE_3D:
469 {
470 src << "%local_coord_bias = OpCompositeConstruct %type_vec3 %local_coord_x_bias %local_coord_y_bias %constant_float_0\n";
471 src << "%local_coord_biased = OpFAdd %type_vec3 " << coord << " %local_coord_bias\n";
472
473 break;
474 }
475
476 default:
477 {
478 DE_FATAL("Unexpected image type");
479 }
480 }
481
482 src << "%local_sparse_gather_result_x = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_0 " + m_operand + "\n";
483 src << "%local_sparse_gather_result_y = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_1 " + m_operand + "\n";
484 src << "%local_sparse_gather_result_z = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_2 " + m_operand + "\n";
485 src << "%local_sparse_gather_result_w = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_3 " + m_operand + "\n";
486
487 src << "%local_gather_residency_code = OpCompositeExtract %type_int %local_sparse_gather_result_x 0\n";
488
489 src << "%local_gather_texels_x = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_x 1\n";
490 src << "%local_gather_texels_y = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_y 1\n";
491 src << "%local_gather_texels_z = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_z 1\n";
492 src << "%local_gather_texels_w = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_w 1\n";
493
494 src << "%local_gather_primary_texel_x = OpCompositeExtract " << typeImgComp << " %local_gather_texels_x 3\n";
495 src << "%local_gather_primary_texel_y = OpCompositeExtract " << typeImgComp << " %local_gather_texels_y 3\n";
496 src << "%local_gather_primary_texel_z = OpCompositeExtract " << typeImgComp << " %local_gather_texels_z 3\n";
497 src << "%local_gather_primary_texel_w = OpCompositeExtract " << typeImgComp << " %local_gather_texels_w 3\n";
498
499 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";
500 src << resultVariable << " = OpCompositeConstruct " << resultType << " %local_gather_residency_code %local_gather_primary_texel\n";
501
502 return src.str();
503 }
504
505 class SparseShaderIntrinsicsInstanceSampledBase : public SparseShaderIntrinsicsInstanceBase
506 {
507 public:
SparseShaderIntrinsicsInstanceSampledBase(Context & context,const SpirVFunction function,const ImageType imageType,const tcu::UVec3 & imageSize,const VkFormat format)508 SparseShaderIntrinsicsInstanceSampledBase (Context& context,
509 const SpirVFunction function,
510 const ImageType imageType,
511 const tcu::UVec3& imageSize,
512 const VkFormat format)
513 : SparseShaderIntrinsicsInstanceBase(context, function, imageType, imageSize, format) {}
514
515 VkImageUsageFlags imageSparseUsageFlags (void) const;
516 VkImageUsageFlags imageOutputUsageFlags (void) const;
517
518 VkQueueFlags getQueueFlags (void) const;
519
520 void recordCommands (const VkCommandBuffer commandBuffer,
521 const VkImageCreateInfo& imageSparseInfo,
522 const VkImage imageSparse,
523 const VkImage imageTexels,
524 const VkImage imageResidency);
525
526 virtual void checkSupport (VkImageCreateInfo imageSparseInfo) const;
527
528 virtual VkImageSubresourceRange sampledImageRangeToBind(const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const = 0;
529
530 private:
531 typedef de::SharedPtr< vk::Unique<VkFramebuffer> > VkFramebufferSp;
532
533 Move<VkBuffer> m_vertexBuffer;
534 de::MovePtr<Allocation> m_vertexBufferAlloc;
535 std::vector<VkFramebufferSp> m_framebuffers;
536 Move<VkRenderPass> m_renderPass;
537 Move<VkSampler> m_sampler;
538 };
539
imageSparseUsageFlags(void) const540 VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageSparseUsageFlags (void) const
541 {
542 return VK_IMAGE_USAGE_SAMPLED_BIT;
543 }
544
imageOutputUsageFlags(void) const545 VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageOutputUsageFlags (void) const
546 {
547 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
548 }
549
getQueueFlags(void) const550 VkQueueFlags SparseShaderIntrinsicsInstanceSampledBase::getQueueFlags (void) const
551 {
552 return VK_QUEUE_GRAPHICS_BIT;
553 }
554
checkSupport(VkImageCreateInfo imageSparseInfo) const555 void SparseShaderIntrinsicsInstanceSampledBase::checkSupport(VkImageCreateInfo imageSparseInfo) const
556 {
557 const InstanceInterface& instance = m_context.getInstanceInterface();
558 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
559 const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
560
561 SparseShaderIntrinsicsInstanceBase::checkSupport(imageSparseInfo);
562
563 if (imageSparseInfo.extent.width > deviceProperties.limits.maxFramebufferWidth ||
564 imageSparseInfo.extent.height > deviceProperties.limits.maxFramebufferHeight ||
565 imageSparseInfo.arrayLayers > deviceProperties.limits.maxFramebufferLayers)
566 {
567 TCU_THROW(NotSupportedError, "Image size exceeds allowed framebuffer dimensions");
568 }
569
570 // Check if device supports image format for sampled images
571 if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
572 TCU_THROW(NotSupportedError, "Device does not support image format for sampled images");
573
574 // Check if device supports image format for color attachment
575 if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
576 TCU_THROW(NotSupportedError, "Device does not support image format for color attachment");
577
578 // Make sure device supports VK_FORMAT_R32_UINT format for color attachment
579 if (!checkImageFormatFeatureSupport(instance, physicalDevice, mapTextureFormat(m_residencyFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
580 TCU_THROW(TestError, "Device does not support VK_FORMAT_R32_UINT format for color attachment");
581 }
582
recordCommands(const VkCommandBuffer commandBuffer,const VkImageCreateInfo & imageSparseInfo,const VkImage imageSparse,const VkImage imageTexels,const VkImage imageResidency)583 void SparseShaderIntrinsicsInstanceSampledBase::recordCommands (const VkCommandBuffer commandBuffer,
584 const VkImageCreateInfo& imageSparseInfo,
585 const VkImage imageSparse,
586 const VkImage imageTexels,
587 const VkImage imageResidency)
588 {
589 const InstanceInterface& instance = m_context.getInstanceInterface();
590 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
591 const DeviceInterface& deviceInterface = getDeviceInterface();
592
593 // Create buffer storing vertex data
594 std::vector<tcu::Vec2> vertexData;
595
596 vertexData.push_back(tcu::Vec2(-1.0f,-1.0f));
597 vertexData.push_back(tcu::Vec2( 0.0f, 0.0f));
598
599 vertexData.push_back(tcu::Vec2(-1.0f, 1.0f));
600 vertexData.push_back(tcu::Vec2( 0.0f, 1.0f));
601
602 vertexData.push_back(tcu::Vec2( 1.0f,-1.0f));
603 vertexData.push_back(tcu::Vec2( 1.0f, 0.0f));
604
605 vertexData.push_back(tcu::Vec2( 1.0f, 1.0f));
606 vertexData.push_back(tcu::Vec2( 1.0f, 1.0f));
607
608 const VkDeviceSize vertexDataSizeInBytes = sizeInBytes(vertexData);
609 const VkBufferCreateInfo vertexBufferCreateInfo = makeBufferCreateInfo(vertexDataSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
610
611 m_vertexBuffer = createBuffer(deviceInterface, getDevice(), &vertexBufferCreateInfo);
612 m_vertexBufferAlloc = bindBuffer(deviceInterface, getDevice(), getAllocator(), *m_vertexBuffer, MemoryRequirement::HostVisible);
613
614 deMemcpy(m_vertexBufferAlloc->getHostPtr(), &vertexData[0], static_cast<std::size_t>(vertexDataSizeInBytes));
615 flushAlloc(deviceInterface, getDevice(), *m_vertexBufferAlloc);
616
617 // Create render pass
618 const VkAttachmentDescription texelsAttachmentDescription =
619 {
620 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
621 imageSparseInfo.format, // VkFormat format;
622 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
623 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
624 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
625 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
626 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
627 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
628 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
629 };
630
631 const VkAttachmentDescription residencyAttachmentDescription =
632 {
633 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
634 mapTextureFormat(m_residencyFormat), // VkFormat format;
635 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
636 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
637 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
638 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
639 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
640 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
641 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
642 };
643
644 const VkAttachmentDescription colorAttachmentsDescription[] = { texelsAttachmentDescription, residencyAttachmentDescription };
645
646 const VkAttachmentReference texelsAttachmentReference =
647 {
648 0u, // deUint32 attachment;
649 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
650 };
651
652 const VkAttachmentReference residencyAttachmentReference =
653 {
654 1u, // deUint32 attachment;
655 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
656 };
657
658 const VkAttachmentReference colorAttachmentsReference[] = { texelsAttachmentReference, residencyAttachmentReference };
659
660 const VkAttachmentReference depthAttachmentReference =
661 {
662 VK_ATTACHMENT_UNUSED, // deUint32 attachment;
663 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout;
664 };
665
666 const VkSubpassDescription subpassDescription =
667 {
668 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
669 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
670 0u, // deUint32 inputAttachmentCount;
671 DE_NULL, // const VkAttachmentReference* pInputAttachments;
672 2u, // deUint32 colorAttachmentCount;
673 colorAttachmentsReference, // const VkAttachmentReference* pColorAttachments;
674 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
675 &depthAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment;
676 0u, // deUint32 preserveAttachmentCount;
677 DE_NULL // const deUint32* pPreserveAttachments;
678 };
679
680 const VkRenderPassCreateInfo renderPassInfo =
681 {
682 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
683 DE_NULL, // const void* pNext;
684 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
685 2u, // deUint32 attachmentCount;
686 colorAttachmentsDescription, // const VkAttachmentDescription* pAttachments;
687 1u, // deUint32 subpassCount;
688 &subpassDescription, // const VkSubpassDescription* pSubpasses;
689 0u, // deUint32 dependencyCount;
690 DE_NULL // const VkSubpassDependency* pDependencies;
691 };
692
693 m_renderPass = createRenderPass(deviceInterface, getDevice(), &renderPassInfo);
694
695 // Create descriptor set layout
696 DescriptorSetLayoutBuilder descriptorLayerBuilder;
697
698 descriptorLayerBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
699
700 const Unique<VkDescriptorSetLayout> descriptorSetLayout(descriptorLayerBuilder.build(deviceInterface, getDevice()));
701
702 // Create descriptor pool
703 DescriptorPoolBuilder descriptorPoolBuilder;
704
705 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSparseInfo.mipLevels);
706
707 descriptorPool = descriptorPoolBuilder.build(deviceInterface, getDevice(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, imageSparseInfo.mipLevels);
708
709 VkSamplerCreateInfo samplerCreateInfo =
710 {
711 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
712 DE_NULL,
713 (VkSamplerCreateFlags)0,
714 mapFilterMode(tcu::Sampler::NEAREST), // magFilter
715 mapFilterMode(tcu::Sampler::NEAREST_MIPMAP_NEAREST), // minFilter
716 mapMipmapMode(tcu::Sampler::NEAREST_MIPMAP_NEAREST), // mipMode
717 mapWrapMode(tcu::Sampler::REPEAT_GL), // addressU
718 mapWrapMode(tcu::Sampler::REPEAT_GL), // addressV
719 mapWrapMode(tcu::Sampler::REPEAT_GL), // addressW
720 0.0f, // mipLodBias
721 VK_FALSE, // anisotropyEnable
722 1.0f, // maxAnisotropy
723 VK_FALSE, // compareEnable
724 mapCompareMode(tcu::Sampler::COMPAREMODE_ALWAYS), // compareOp
725 0.0f, // minLod
726 1000.0f, // maxLod
727 VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, // borderColor
728 VK_FALSE, // unnormalizedCoords
729 };
730 m_sampler = createSampler(deviceInterface, getDevice(), &samplerCreateInfo);
731
732 struct PushConstants
733 {
734 deUint32 lod;
735 deUint32 padding; // padding needed to satisfy std430 rules
736 float lodWidth;
737 float lodHeight;
738 };
739
740 // Create pipeline layout
741 const VkPushConstantRange lodConstantRange =
742 {
743 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
744 0u, // deUint32 offset;
745 sizeof(PushConstants), // deUint32 size;
746 };
747
748 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
749 {
750 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
751 DE_NULL, // const void* pNext;
752 0u, // VkPipelineLayoutCreateFlags flags;
753 1u, // deUint32 setLayoutCount;
754 &descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
755 1u, // deUint32 pushConstantRangeCount;
756 &lodConstantRange, // const VkPushConstantRange* pPushConstantRanges;
757 };
758
759 pipelineLayout = createPipelineLayout(deviceInterface, getDevice(), &pipelineLayoutParams);
760
761 // Create graphics pipeline
762 {
763 Move<VkShaderModule> vertexModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0);
764 Move<VkShaderModule> fragmentModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0);
765 Move<VkShaderModule> geometryModule;
766
767 if (imageSparseInfo.arrayLayers > 1u)
768 {
769 requireFeatures(instance, physicalDevice, FEATURE_GEOMETRY_SHADER);
770 geometryModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("geometry_shader"), (VkShaderModuleCreateFlags)0);
771 }
772
773 pipelines.push_back(makeVkSharedPtr(makeGraphicsPipeline(
774 deviceInterface, getDevice(), *pipelineLayout, *m_renderPass, *vertexModule, *fragmentModule, *geometryModule)));
775 }
776
777 const VkPipeline graphicsPipeline = **pipelines[0];
778
779 {
780 const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
781
782 VkImageMemoryBarrier imageShaderAccessBarriers[3];
783
784 imageShaderAccessBarriers[0] = makeImageMemoryBarrier
785 (
786 VK_ACCESS_TRANSFER_WRITE_BIT,
787 VK_ACCESS_SHADER_READ_BIT,
788 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
789 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
790 imageSparse,
791 fullImageSubresourceRange
792 );
793
794 imageShaderAccessBarriers[1] = makeImageMemoryBarrier
795 (
796 0u,
797 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
798 VK_IMAGE_LAYOUT_UNDEFINED,
799 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
800 imageTexels,
801 fullImageSubresourceRange
802 );
803
804 imageShaderAccessBarriers[2] = makeImageMemoryBarrier
805 (
806 0u,
807 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
808 VK_IMAGE_LAYOUT_UNDEFINED,
809 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
810 imageResidency,
811 fullImageSubresourceRange
812 );
813
814 deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 3u, imageShaderAccessBarriers);
815 }
816
817 imageSparseViews.resize(imageSparseInfo.mipLevels);
818 imageTexelsViews.resize(imageSparseInfo.mipLevels);
819 imageResidencyViews.resize(imageSparseInfo.mipLevels);
820 m_framebuffers.resize(imageSparseInfo.mipLevels);
821 descriptorSets.resize(imageSparseInfo.mipLevels);
822
823 std::vector<VkClearValue> clearValues;
824 clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
825 clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
826
827 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
828 {
829 const VkExtent3D mipLevelSize = mipLevelExtents(imageSparseInfo.extent, mipLevelNdx);
830 const VkRect2D renderArea = makeRect2D(mipLevelSize);
831 const VkViewport viewport = makeViewport(mipLevelSize);
832 const VkImageSubresourceRange mipLevelRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevelNdx, 1u, 0u, imageSparseInfo.arrayLayers);
833
834 // Create color attachments image views
835 imageTexelsViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageTexels, mapImageViewType(m_imageType), imageSparseInfo.format, mipLevelRange));
836 imageResidencyViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageResidency, mapImageViewType(m_imageType), mapTextureFormat(m_residencyFormat), mipLevelRange));
837
838 const VkImageView attachmentsViews[] = { **imageTexelsViews[mipLevelNdx], **imageResidencyViews[mipLevelNdx] };
839
840 // Create framebuffer
841 const VkFramebufferCreateInfo framebufferInfo =
842 {
843 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
844 DE_NULL, // const void* pNext;
845 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
846 *m_renderPass, // VkRenderPass renderPass;
847 2u, // uint32_t attachmentCount;
848 attachmentsViews, // const VkImageView* pAttachments;
849 mipLevelSize.width, // uint32_t width;
850 mipLevelSize.height, // uint32_t height;
851 imageSparseInfo.arrayLayers, // uint32_t layers;
852 };
853
854 m_framebuffers[mipLevelNdx] = makeVkSharedPtr(createFramebuffer(deviceInterface, getDevice(), &framebufferInfo));
855
856 // Create descriptor set
857 descriptorSets[mipLevelNdx] = makeVkSharedPtr(makeDescriptorSet(deviceInterface, getDevice(), *descriptorPool, *descriptorSetLayout));
858 const VkDescriptorSet descriptorSet = **descriptorSets[mipLevelNdx];
859
860 // Update descriptor set
861 const VkImageSubresourceRange sparseImageSubresourceRange = sampledImageRangeToBind(imageSparseInfo, mipLevelNdx);
862
863 imageSparseViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageSparse, mapImageViewType(m_imageType), imageSparseInfo.format, sparseImageSubresourceRange));
864
865 const VkDescriptorImageInfo imageSparseDescInfo = makeDescriptorImageInfo(*m_sampler, **imageSparseViews[mipLevelNdx], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
866
867 DescriptorSetUpdateBuilder descriptorUpdateBuilder;
868
869 descriptorUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(BINDING_IMAGE_SPARSE), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSparseDescInfo);
870 descriptorUpdateBuilder.update(deviceInterface, getDevice());
871
872 beginRenderPass(deviceInterface, commandBuffer, *m_renderPass, **m_framebuffers[mipLevelNdx], renderArea, (deUint32)clearValues.size(), &clearValues[0]);
873
874 // Bind graphics pipeline
875 deviceInterface.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
876
877 // Bind descriptor set
878 deviceInterface.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
879
880 // Bind vertex buffer
881 {
882 const VkDeviceSize offset = 0ull;
883 deviceInterface.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &m_vertexBuffer.get(), &offset);
884 }
885
886 // Bind Viewport
887 deviceInterface.cmdSetViewport(commandBuffer, 0u, 1u, &viewport);
888
889 // Bind Scissor Rectangle
890 deviceInterface.cmdSetScissor(commandBuffer, 0u, 1u, &renderArea);
891
892 const PushConstants pushConstants =
893 {
894 mipLevelNdx,
895 0u, // padding
896 static_cast<float>(mipLevelSize.width),
897 static_cast<float>(mipLevelSize.height)
898 };
899
900 // Update push constants
901 deviceInterface.cmdPushConstants(commandBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(PushConstants), &pushConstants);
902
903 // Draw full screen quad
904 deviceInterface.cmdDraw(commandBuffer, 4u, 1u, 0u, 0u);
905
906 // End render pass
907 endRenderPass(deviceInterface, commandBuffer);
908 }
909
910 {
911 const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
912
913 VkImageMemoryBarrier imageOutputTransferSrcBarriers[2];
914
915 imageOutputTransferSrcBarriers[0] = makeImageMemoryBarrier
916 (
917 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
918 VK_ACCESS_TRANSFER_READ_BIT,
919 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
920 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
921 imageTexels,
922 fullImageSubresourceRange
923 );
924
925 imageOutputTransferSrcBarriers[1] = makeImageMemoryBarrier
926 (
927 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
928 VK_ACCESS_TRANSFER_READ_BIT,
929 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
930 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
931 imageResidency,
932 fullImageSubresourceRange
933 );
934
935 deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageOutputTransferSrcBarriers);
936 }
937 }
938
939 class SparseShaderIntrinsicsInstanceSampledExplicit : public SparseShaderIntrinsicsInstanceSampledBase
940 {
941 public:
SparseShaderIntrinsicsInstanceSampledExplicit(Context & context,const SpirVFunction function,const ImageType imageType,const tcu::UVec3 & imageSize,const VkFormat format)942 SparseShaderIntrinsicsInstanceSampledExplicit (Context& context,
943 const SpirVFunction function,
944 const ImageType imageType,
945 const tcu::UVec3& imageSize,
946 const VkFormat format)
947 : SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
948
sampledImageRangeToBind(const VkImageCreateInfo & imageSparseInfo,const deUint32 mipLevel) const949 VkImageSubresourceRange sampledImageRangeToBind (const VkImageCreateInfo& imageSparseInfo,
950 const deUint32 mipLevel) const
951 {
952 DE_UNREF(mipLevel);
953 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
954 }
955 };
956
createInstance(Context & context) const957 TestInstance* SparseShaderIntrinsicsCaseSampledExplicit::createInstance (Context& context) const
958 {
959 return new SparseShaderIntrinsicsInstanceSampledExplicit(context, m_function, m_imageType, m_imageSize, m_format);
960 }
961
962 class SparseShaderIntrinsicsInstanceSampledImplicit : public SparseShaderIntrinsicsInstanceSampledBase
963 {
964 public:
SparseShaderIntrinsicsInstanceSampledImplicit(Context & context,const SpirVFunction function,const ImageType imageType,const tcu::UVec3 & imageSize,const VkFormat format)965 SparseShaderIntrinsicsInstanceSampledImplicit (Context& context,
966 const SpirVFunction function,
967 const ImageType imageType,
968 const tcu::UVec3& imageSize,
969 const VkFormat format)
970 : SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
971
sampledImageRangeToBind(const VkImageCreateInfo & imageSparseInfo,const deUint32 mipLevel) const972 VkImageSubresourceRange sampledImageRangeToBind (const VkImageCreateInfo& imageSparseInfo,
973 const deUint32 mipLevel) const
974 {
975 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 1u, 0u, imageSparseInfo.arrayLayers);
976 }
977 };
978
createInstance(Context & context) const979 TestInstance* SparseShaderIntrinsicsCaseSampledImplicit::createInstance (Context& context) const
980 {
981 return new SparseShaderIntrinsicsInstanceSampledImplicit(context, m_function, m_imageType, m_imageSize, m_format);
982 }
983
984 } // sparse
985 } // vkt
986