1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * \file vktSparseResourcesShaderIntrinsicsSampled.cpp
21 * \brief Sparse Resources Shader Intrinsics for sampled images
22 *//*--------------------------------------------------------------------*/
24 #include "vktSparseResourcesShaderIntrinsicsSampled.hpp"
25 #include "vkTypeUtil.hpp"
26 #include "vkCmdUtil.hpp"
27 #include "vkObjUtil.hpp"
28 #include "vkBarrierUtil.hpp"
29 #include "vkBufferWithMemory.hpp"
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)
48 const std::vector<VkViewport> noViewports;
49 const std::vector<VkRect2D> noScissors;
51 const VkFormat format = VK_FORMAT_R32G32_SFLOAT;
52 const deUint32 size = tcu::getPixelSize(mapVkFormat(format));
54 const VkVertexInputBindingDescription vertexBinding =
56 0u, // deUint32 binding;
57 size * 2, // deUint32 stride;
58 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
61 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
65 0u, // deUint32 location;
66 0u, // deUint32 binding;
67 format, // VkFormat format;
68 0u // deUint32 offset;
70 // texture coordinates
72 1u, // deUint32 location;
73 0u, // deUint32 binding;
74 format, // VkFormat format;
75 size // deUint32 offset;
79 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
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;
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 =
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;
103 const VkPipelineColorBlendAttachmentState colorBlendAttachmentStates[] =
105 defaultColorBlendAttachmentState,
106 defaultColorBlendAttachmentState
109 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
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];
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
144 void SparseShaderIntrinsicsCaseSampledBase::initPrograms (vk::SourceCollections& programCollection) const
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");
150 // Create vertex shader
151 std::ostringstream vs;
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"
159 << "layout(location = 0) out highp vec3 vs_out_texCoord;\n"
161 << "out gl_PerVertex {\n"
162 << " vec4 gl_Position;\n"
164 << "void main (void)\n"
166 << " gl_Position = vec4(vs_in_position, 0.0f, 1.0f);\n"
167 << " vs_out_texCoord = vec3(vs_in_texCoord, 0.0f);\n"
170 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
174 const deInt32 maxVertices = 3u * numLayers;
176 // Create geometry shader
177 std::ostringstream gs;
179 gs << "#version 440\n"
180 << "layout(triangles) in;\n"
181 << "layout(triangle_strip, max_vertices = " << static_cast<deInt32>(maxVertices) << ") out;\n"
183 << "in gl_PerVertex {\n"
184 << " vec4 gl_Position;\n"
186 << "out gl_PerVertex {\n"
187 << " vec4 gl_Position;\n"
189 << "layout(location = 0) in highp vec3 gs_in_texCoord[];\n"
191 << "layout(location = 0) out highp vec3 gs_out_texCoord;\n"
193 << "void main (void)\n"
195 << " for (int layerNdx = 0; layerNdx < " << static_cast<deInt32>(numLayers) << "; ++layerNdx)\n"
197 << " for (int vertexNdx = 0; vertexNdx < gl_in.length(); ++vertexNdx)\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"
204 << " EndPrimitive();\n"
208 programCollection.glslSources.add("geometry_shader") << glu::GeometrySource(gs.str());
211 // Create fragment shader
212 std::ostringstream fs;
214 const std::string typeImgComp = getImageComponentTypeName(formatDescription);
215 const std::string typeImgCompVec4 = getImageComponentVec4TypeName(formatDescription);
217 fs << "OpCapability Shader\n"
218 << "OpCapability SampledCubeArray\n"
219 << "OpCapability ImageCubeArray\n"
220 << "OpCapability SparseResidency\n"
221 << "OpCapability StorageImageExtendedFormats\n";
223 if (formatIsR64(m_format))
225 fs << "OpCapability Int64\n"
226 << "OpCapability Int64ImageEXT\n"
227 << "OpExtension \"SPV_EXT_shader_image_int64\"\n";
230 fs << "%ext_import = OpExtInstImport \"GLSL.std.450\"\n"
231 << "OpMemoryModel Logical GLSL450\n"
232 << "OpEntryPoint Fragment %func_main \"main\" %varying_texCoord %output_texel %output_residency\n"
233 << "OpExecutionMode %func_main OriginUpperLeft\n"
234 << "OpSource GLSL 440\n"
236 << "OpName %func_main \"main\"\n"
238 << "OpName %varying_texCoord \"varying_texCoord\"\n"
240 << "OpName %output_texel \"out_texel\"\n"
241 << "OpName %output_residency \"out_residency\"\n"
243 << "OpName %type_uniformblock \"LodBlock\"\n"
244 << "OpMemberName %type_uniformblock 0 \"lod\"\n"
245 << "OpMemberName %type_uniformblock 1 \"size\"\n"
246 << "OpName %uniformblock_instance \"lodInstance\"\n"
248 << "OpName %uniformconst_image_sparse \"u_imageSparse\"\n"
250 << "OpDecorate %varying_texCoord Location 0\n"
252 << "OpDecorate %output_texel Location 0\n"
253 << "OpDecorate %output_residency Location 1\n"
255 << "OpDecorate %type_uniformblock Block\n"
256 << "OpMemberDecorate %type_uniformblock 0 Offset 0\n"
257 << "OpMemberDecorate %type_uniformblock 1 Offset 8\n"
259 << "OpDecorate %uniformconst_image_sparse DescriptorSet 0\n"
260 << "OpDecorate %uniformconst_image_sparse Binding " << BINDING_IMAGE_SPARSE << "\n"
262 << "%type_void = OpTypeVoid\n"
263 << "%type_void_func = OpTypeFunction %type_void\n"
265 << "%type_bool = OpTypeBool\n"
266 << "%type_int = OpTypeInt 32 1\n"
267 << "%type_uint = OpTypeInt 32 0\n"
268 << "%type_float = OpTypeFloat 32\n"
269 << "%type_vec2 = OpTypeVector %type_float 2\n"
270 << "%type_vec3 = OpTypeVector %type_float 3\n"
271 << "%type_vec4 = OpTypeVector %type_float 4\n"
272 << "%type_ivec4 = OpTypeVector %type_int 4\n"
273 << "%type_uvec4 = OpTypeVector %type_uint 4\n"
274 << "%type_uniformblock = OpTypeStruct %type_uint %type_vec2\n";
276 if (formatIsR64(m_format))
278 fs << "%type_int64 = OpTypeInt 64 1\n"
279 << "%type_uint64 = OpTypeInt 64 0\n"
280 << "%type_i64vec2 = OpTypeVector %type_int64 2\n"
281 << "%type_i64vec3 = OpTypeVector %type_int64 3\n"
282 << "%type_i64vec4 = OpTypeVector %type_int64 4\n"
283 << "%type_u64vec3 = OpTypeVector %type_uint64 3\n"
284 << "%type_u64vec4 = OpTypeVector %type_uint64 4\n";
287 fs << "%type_struct_int_img_comp_vec4 = OpTypeStruct %type_int "<< typeImgCompVec4 << "\n"
288 << "%type_input_vec3 = OpTypePointer Input %type_vec3\n"
289 << "%type_input_float = OpTypePointer Input %type_float\n";
291 if (formatIsR64(m_format))
292 fs << "%type_output_img_comp_vec4 = OpTypePointer Output " << "%type_ivec4" << "\n";
294 fs << "%type_output_img_comp_vec4 = OpTypePointer Output " << typeImgCompVec4 << "\n";
296 fs << "%type_output_uint = OpTypePointer Output %type_uint\n"
298 << "%type_function_int = OpTypePointer Function %type_int\n"
299 << "%type_function_img_comp_vec4 = OpTypePointer Function " << typeImgCompVec4 << "\n"
300 << "%type_function_int_img_comp_vec4 = OpTypePointer Function %type_struct_int_img_comp_vec4\n"
302 << "%type_pushconstant_uniformblock = OpTypePointer PushConstant %type_uniformblock\n"
303 << "%type_pushconstant_uniformblock_member_lod = OpTypePointer PushConstant %type_uint\n"
304 << "%type_pushconstant_uniformblock_member_size = OpTypePointer PushConstant %type_vec2\n"
306 << "%type_image_sparse = " << getOpTypeImageSparse(m_imageType, m_format, typeImgComp, true) << "\n"
307 << "%type_sampled_image_sparse = OpTypeSampledImage %type_image_sparse\n"
308 << "%type_uniformconst_image_sparse = OpTypePointer UniformConstant %type_sampled_image_sparse\n"
310 << "%varying_texCoord = OpVariable %type_input_vec3 Input\n"
312 << "%output_texel = OpVariable %type_output_img_comp_vec4 Output\n"
313 << "%output_residency = OpVariable %type_output_uint Output\n"
315 << "%uniformconst_image_sparse = OpVariable %type_uniformconst_image_sparse UniformConstant\n"
317 << "%uniformblock_instance = OpVariable %type_pushconstant_uniformblock PushConstant\n"
320 << "%constant_uint_0 = OpConstant %type_uint 0\n"
321 << "%constant_uint_1 = OpConstant %type_uint 1\n"
322 << "%constant_uint_2 = OpConstant %type_uint 2\n"
323 << "%constant_uint_3 = OpConstant %type_uint 3\n"
324 << "%constant_int_0 = OpConstant %type_int 0\n"
325 << "%constant_int_1 = OpConstant %type_int 1\n"
326 << "%constant_int_2 = OpConstant %type_int 2\n"
327 << "%constant_int_3 = OpConstant %type_int 3\n"
328 << "%constant_float_0 = OpConstant %type_float 0.0\n"
329 << "%constant_float_half = OpConstant %type_float 0.5\n"
330 << "%constant_texel_resident = OpConstant %type_uint " << MEMORY_BLOCK_BOUND_VALUE << "\n"
331 << "%constant_texel_not_resident = OpConstant %type_uint " << MEMORY_BLOCK_NOT_BOUND_VALUE << "\n"
333 // Call main function
334 << "%func_main = OpFunction %type_void None %type_void_func\n"
335 << "%label_func_main = OpLabel\n"
337 << "%local_image_sparse = OpLoad %type_sampled_image_sparse %uniformconst_image_sparse\n"
339 << "%texCoord = OpLoad %type_vec3 %varying_texCoord\n"
341 << "%local_texCoord_x = OpCompositeExtract %type_float %texCoord 0\n"
342 << "%local_texCoord_y = OpCompositeExtract %type_float %texCoord 1\n"
343 << "%local_texCoord_z = OpCompositeExtract %type_float %texCoord 2\n"
345 << "%local_texCoord_xy = OpCompositeConstruct %type_vec2 %local_texCoord_x %local_texCoord_y\n"
346 << "%local_texCoord_xyz = OpCompositeConstruct %type_vec3 %local_texCoord_x %local_texCoord_y %local_texCoord_z\n"
348 << "%access_uniformblock_member_uint_lod = OpAccessChain %type_pushconstant_uniformblock_member_lod %uniformblock_instance %constant_int_0\n"
349 << "%local_uniformblock_member_uint_lod = OpLoad %type_uint %access_uniformblock_member_uint_lod\n"
350 << "%local_uniformblock_member_float_lod = OpConvertUToF %type_float %local_uniformblock_member_uint_lod\n"
351 << "%access_uniformblock_member_size = OpAccessChain %type_pushconstant_uniformblock_member_size %uniformblock_instance %constant_int_1\n"
352 << "%local_uniformblock_member_size = OpLoad %type_vec2 %access_uniformblock_member_size\n"
354 << sparseImageOpString("%local_sparse_op_result", "%type_struct_int_img_comp_vec4", "%local_image_sparse", coordString, "%local_uniformblock_member_float_lod") << "\n"
357 << "%local_img_comp_vec4 = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_op_result 1\n";
359 if (formatIsR64(m_format))
361 fs << "%local_img_comp32b = OpSConvert %type_ivec4 %local_img_comp_vec4\n"
362 << "OpStore %output_texel %local_img_comp32b\n";
366 fs << "OpStore %output_texel %local_img_comp_vec4\n";
369 // Load residency code
370 fs << "%local_residency_code = OpCompositeExtract %type_int %local_sparse_op_result 0\n"
372 // Check if loaded texel is placed in resident memory
373 << "%local_texel_resident = OpImageSparseTexelsResident %type_bool %local_residency_code\n"
374 << "OpSelectionMerge %branch_texel_resident None\n"
375 << "OpBranchConditional %local_texel_resident %label_texel_resident %label_texel_not_resident\n"
376 << "%label_texel_resident = OpLabel\n"
378 // Loaded texel is in resident memory
379 << "OpStore %output_residency %constant_texel_resident\n"
381 << "OpBranch %branch_texel_resident\n"
382 << "%label_texel_not_resident = OpLabel\n"
384 // Loaded texel is not in resident memory
385 << "OpStore %output_residency %constant_texel_not_resident\n"
387 << "OpBranch %branch_texel_resident\n"
388 << "%branch_texel_resident = OpLabel\n"
391 << "OpFunctionEnd\n";
393 programCollection.spirvAsmSources.add("fragment_shader") << fs.str();
396 std::string SparseCaseOpImageSparseSampleExplicitLod::sparseImageOpString (const std::string& resultVariable,
397 const std::string& resultType,
398 const std::string& image,
399 const std::string& coord,
400 const std::string& miplevel) const
402 std::ostringstream src;
404 src << resultVariable << " = OpImageSparseSampleExplicitLod " << resultType << " " << image << " " << coord << " Lod " << miplevel << "\n";
409 std::string SparseCaseOpImageSparseSampleImplicitLod::sparseImageOpString (const std::string& resultVariable,
410 const std::string& resultType,
411 const std::string& image,
412 const std::string& coord,
413 const std::string& miplevel) const
417 std::ostringstream src;
419 src << resultVariable << " = OpImageSparseSampleImplicitLod " << resultType << " " << image << " " << coord << "\n";
424 std::string SparseCaseOpImageSparseGather::sparseImageOpString (const std::string& resultVariable,
425 const std::string& resultType,
426 const std::string& image,
427 const std::string& coord,
428 const std::string& miplevel) const
432 std::ostringstream src;
434 const PlanarFormatDescription formatDescription = getPlanarFormatDescription(m_format);
435 const std::string typeImgComp = getImageComponentTypeName(formatDescription);
436 const std::string typeImgCompVec4 = getImageComponentVec4TypeName(formatDescription);
438 // Bias the coord value by half a texel, so we sample from center of 2x2 gather rectangle
440 src << "%local_image_width = OpCompositeExtract %type_float %local_uniformblock_member_size 0\n";
441 src << "%local_image_height = OpCompositeExtract %type_float %local_uniformblock_member_size 1\n";
442 src << "%local_coord_x_bias = OpFDiv %type_float %constant_float_half %local_image_width\n";
443 src << "%local_coord_y_bias = OpFDiv %type_float %constant_float_half %local_image_height\n";
449 src << "%local_coord_bias = OpCompositeConstruct %type_vec2 %local_coord_x_bias %local_coord_y_bias\n";
450 src << "%local_coord_biased = OpFAdd %type_vec2 " << coord << " %local_coord_bias\n";
455 case IMAGE_TYPE_2D_ARRAY:
458 src << "%local_coord_bias = OpCompositeConstruct %type_vec3 %local_coord_x_bias %local_coord_y_bias %constant_float_0\n";
459 src << "%local_coord_biased = OpFAdd %type_vec3 " << coord << " %local_coord_bias\n";
466 DE_FATAL("Unexpected image type");
470 src << "%local_sparse_gather_result_x = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_0\n";
471 src << "%local_sparse_gather_result_y = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_1\n";
472 src << "%local_sparse_gather_result_z = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_2\n";
473 src << "%local_sparse_gather_result_w = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_3\n";
475 src << "%local_gather_residency_code = OpCompositeExtract %type_int %local_sparse_gather_result_x 0\n";
477 src << "%local_gather_texels_x = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_x 1\n";
478 src << "%local_gather_texels_y = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_y 1\n";
479 src << "%local_gather_texels_z = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_z 1\n";
480 src << "%local_gather_texels_w = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_w 1\n";
482 src << "%local_gather_primary_texel_x = OpCompositeExtract " << typeImgComp << " %local_gather_texels_x 3\n";
483 src << "%local_gather_primary_texel_y = OpCompositeExtract " << typeImgComp << " %local_gather_texels_y 3\n";
484 src << "%local_gather_primary_texel_z = OpCompositeExtract " << typeImgComp << " %local_gather_texels_z 3\n";
485 src << "%local_gather_primary_texel_w = OpCompositeExtract " << typeImgComp << " %local_gather_texels_w 3\n";
487 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";
488 src << resultVariable << " = OpCompositeConstruct " << resultType << " %local_gather_residency_code %local_gather_primary_texel\n";
493 class SparseShaderIntrinsicsInstanceSampledBase : public SparseShaderIntrinsicsInstanceBase
496 SparseShaderIntrinsicsInstanceSampledBase (Context& context,
497 const SpirVFunction function,
498 const ImageType imageType,
499 const tcu::UVec3& imageSize,
500 const VkFormat format)
501 : SparseShaderIntrinsicsInstanceBase(context, function, imageType, imageSize, format) {}
503 VkImageUsageFlags imageSparseUsageFlags (void) const;
504 VkImageUsageFlags imageOutputUsageFlags (void) const;
506 VkQueueFlags getQueueFlags (void) const;
508 void recordCommands (const VkCommandBuffer commandBuffer,
509 const VkImageCreateInfo& imageSparseInfo,
510 const VkImage imageSparse,
511 const VkImage imageTexels,
512 const VkImage imageResidency);
514 virtual void checkSupport (VkImageCreateInfo imageSparseInfo) const;
516 virtual VkImageSubresourceRange sampledImageRangeToBind(const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const = 0;
519 typedef de::SharedPtr< vk::Unique<VkFramebuffer> > VkFramebufferSp;
521 Move<VkBuffer> m_vertexBuffer;
522 de::MovePtr<Allocation> m_vertexBufferAlloc;
523 std::vector<VkFramebufferSp> m_framebuffers;
524 Move<VkRenderPass> m_renderPass;
525 Move<VkSampler> m_sampler;
528 VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageSparseUsageFlags (void) const
530 return VK_IMAGE_USAGE_SAMPLED_BIT;
533 VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageOutputUsageFlags (void) const
535 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
538 VkQueueFlags SparseShaderIntrinsicsInstanceSampledBase::getQueueFlags (void) const
540 return VK_QUEUE_GRAPHICS_BIT;
543 void SparseShaderIntrinsicsInstanceSampledBase::checkSupport(VkImageCreateInfo imageSparseInfo) const
545 const InstanceInterface& instance = m_context.getInstanceInterface();
546 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
547 const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
549 SparseShaderIntrinsicsInstanceBase::checkSupport(imageSparseInfo);
551 if (imageSparseInfo.extent.width > deviceProperties.limits.maxFramebufferWidth ||
552 imageSparseInfo.extent.height > deviceProperties.limits.maxFramebufferHeight ||
553 imageSparseInfo.arrayLayers > deviceProperties.limits.maxFramebufferLayers)
555 TCU_THROW(NotSupportedError, "Image size exceeds allowed framebuffer dimensions");
558 // Check if device supports image format for sampled images
559 if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
560 TCU_THROW(NotSupportedError, "Device does not support image format for sampled images");
562 // Check if device supports image format for color attachment
563 if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
564 TCU_THROW(NotSupportedError, "Device does not support image format for color attachment");
566 // Make sure device supports VK_FORMAT_R32_UINT format for color attachment
567 if (!checkImageFormatFeatureSupport(instance, physicalDevice, mapTextureFormat(m_residencyFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
568 TCU_THROW(TestError, "Device does not support VK_FORMAT_R32_UINT format for color attachment");
571 void SparseShaderIntrinsicsInstanceSampledBase::recordCommands (const VkCommandBuffer commandBuffer,
572 const VkImageCreateInfo& imageSparseInfo,
573 const VkImage imageSparse,
574 const VkImage imageTexels,
575 const VkImage imageResidency)
577 const InstanceInterface& instance = m_context.getInstanceInterface();
578 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
579 const DeviceInterface& deviceInterface = getDeviceInterface();
581 // Create buffer storing vertex data
582 std::vector<tcu::Vec2> vertexData;
584 vertexData.push_back(tcu::Vec2(-1.0f,-1.0f));
585 vertexData.push_back(tcu::Vec2( 0.0f, 0.0f));
587 vertexData.push_back(tcu::Vec2(-1.0f, 1.0f));
588 vertexData.push_back(tcu::Vec2( 0.0f, 1.0f));
590 vertexData.push_back(tcu::Vec2( 1.0f,-1.0f));
591 vertexData.push_back(tcu::Vec2( 1.0f, 0.0f));
593 vertexData.push_back(tcu::Vec2( 1.0f, 1.0f));
594 vertexData.push_back(tcu::Vec2( 1.0f, 1.0f));
596 const VkDeviceSize vertexDataSizeInBytes = sizeInBytes(vertexData);
597 const VkBufferCreateInfo vertexBufferCreateInfo = makeBufferCreateInfo(vertexDataSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
599 m_vertexBuffer = createBuffer(deviceInterface, getDevice(), &vertexBufferCreateInfo);
600 m_vertexBufferAlloc = bindBuffer(deviceInterface, getDevice(), getAllocator(), *m_vertexBuffer, MemoryRequirement::HostVisible);
602 deMemcpy(m_vertexBufferAlloc->getHostPtr(), &vertexData[0], static_cast<std::size_t>(vertexDataSizeInBytes));
603 flushAlloc(deviceInterface, getDevice(), *m_vertexBufferAlloc);
605 // Create render pass
606 const VkAttachmentDescription texelsAttachmentDescription =
608 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
609 imageSparseInfo.format, // VkFormat format;
610 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
611 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
612 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
613 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
614 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
615 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
616 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
619 const VkAttachmentDescription residencyAttachmentDescription =
621 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
622 mapTextureFormat(m_residencyFormat), // VkFormat format;
623 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
624 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
625 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
626 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
627 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
628 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
629 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
632 const VkAttachmentDescription colorAttachmentsDescription[] = { texelsAttachmentDescription, residencyAttachmentDescription };
634 const VkAttachmentReference texelsAttachmentReference =
636 0u, // deUint32 attachment;
637 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
640 const VkAttachmentReference residencyAttachmentReference =
642 1u, // deUint32 attachment;
643 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
646 const VkAttachmentReference colorAttachmentsReference[] = { texelsAttachmentReference, residencyAttachmentReference };
648 const VkAttachmentReference depthAttachmentReference =
650 VK_ATTACHMENT_UNUSED, // deUint32 attachment;
651 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout;
654 const VkSubpassDescription subpassDescription =
656 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
657 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
658 0u, // deUint32 inputAttachmentCount;
659 DE_NULL, // const VkAttachmentReference* pInputAttachments;
660 2u, // deUint32 colorAttachmentCount;
661 colorAttachmentsReference, // const VkAttachmentReference* pColorAttachments;
662 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
663 &depthAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment;
664 0u, // deUint32 preserveAttachmentCount;
665 DE_NULL // const deUint32* pPreserveAttachments;
668 const VkRenderPassCreateInfo renderPassInfo =
670 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
671 DE_NULL, // const void* pNext;
672 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
673 2u, // deUint32 attachmentCount;
674 colorAttachmentsDescription, // const VkAttachmentDescription* pAttachments;
675 1u, // deUint32 subpassCount;
676 &subpassDescription, // const VkSubpassDescription* pSubpasses;
677 0u, // deUint32 dependencyCount;
678 DE_NULL // const VkSubpassDependency* pDependencies;
681 m_renderPass = createRenderPass(deviceInterface, getDevice(), &renderPassInfo);
683 // Create descriptor set layout
684 DescriptorSetLayoutBuilder descriptorLayerBuilder;
686 descriptorLayerBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
688 const Unique<VkDescriptorSetLayout> descriptorSetLayout(descriptorLayerBuilder.build(deviceInterface, getDevice()));
690 // Create descriptor pool
691 DescriptorPoolBuilder descriptorPoolBuilder;
693 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSparseInfo.mipLevels);
695 descriptorPool = descriptorPoolBuilder.build(deviceInterface, getDevice(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, imageSparseInfo.mipLevels);
697 VkSamplerCreateInfo samplerCreateInfo =
699 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
701 (VkSamplerCreateFlags)0,
702 mapFilterMode(tcu::Sampler::NEAREST), // magFilter
703 mapFilterMode(tcu::Sampler::NEAREST_MIPMAP_NEAREST), // minFilter
704 mapMipmapMode(tcu::Sampler::NEAREST_MIPMAP_NEAREST), // mipMode
705 mapWrapMode(tcu::Sampler::REPEAT_GL), // addressU
706 mapWrapMode(tcu::Sampler::REPEAT_GL), // addressV
707 mapWrapMode(tcu::Sampler::REPEAT_GL), // addressW
709 VK_FALSE, // anisotropyEnable
710 1.0f, // maxAnisotropy
711 VK_FALSE, // compareEnable
712 mapCompareMode(tcu::Sampler::COMPAREMODE_ALWAYS), // compareOp
715 VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, // borderColor
716 VK_FALSE, // unnormalizedCoords
718 m_sampler = createSampler(deviceInterface, getDevice(), &samplerCreateInfo);
723 deUint32 padding; // padding needed to satisfy std430 rules
728 // Create pipeline layout
729 const VkPushConstantRange lodConstantRange =
731 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
732 0u, // deUint32 offset;
733 sizeof(PushConstants), // deUint32 size;
736 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
738 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
739 DE_NULL, // const void* pNext;
740 0u, // VkPipelineLayoutCreateFlags flags;
741 1u, // deUint32 setLayoutCount;
742 &descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
743 1u, // deUint32 pushConstantRangeCount;
744 &lodConstantRange, // const VkPushConstantRange* pPushConstantRanges;
747 pipelineLayout = createPipelineLayout(deviceInterface, getDevice(), &pipelineLayoutParams);
749 // Create graphics pipeline
751 Move<VkShaderModule> vertexModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0);
752 Move<VkShaderModule> fragmentModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0);
753 Move<VkShaderModule> geometryModule;
755 if (imageSparseInfo.arrayLayers > 1u)
757 requireFeatures(instance, physicalDevice, FEATURE_GEOMETRY_SHADER);
758 geometryModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("geometry_shader"), (VkShaderModuleCreateFlags)0);
761 pipelines.push_back(makeVkSharedPtr(makeGraphicsPipeline(
762 deviceInterface, getDevice(), *pipelineLayout, *m_renderPass, *vertexModule, *fragmentModule, *geometryModule)));
765 const VkPipeline graphicsPipeline = **pipelines[0];
768 const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
770 VkImageMemoryBarrier imageShaderAccessBarriers[3];
772 imageShaderAccessBarriers[0] = makeImageMemoryBarrier
774 VK_ACCESS_TRANSFER_WRITE_BIT,
775 VK_ACCESS_SHADER_READ_BIT,
776 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
777 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
779 fullImageSubresourceRange
782 imageShaderAccessBarriers[1] = makeImageMemoryBarrier
785 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
786 VK_IMAGE_LAYOUT_UNDEFINED,
787 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
789 fullImageSubresourceRange
792 imageShaderAccessBarriers[2] = makeImageMemoryBarrier
795 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
796 VK_IMAGE_LAYOUT_UNDEFINED,
797 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
799 fullImageSubresourceRange
802 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);
805 imageSparseViews.resize(imageSparseInfo.mipLevels);
806 imageTexelsViews.resize(imageSparseInfo.mipLevels);
807 imageResidencyViews.resize(imageSparseInfo.mipLevels);
808 m_framebuffers.resize(imageSparseInfo.mipLevels);
809 descriptorSets.resize(imageSparseInfo.mipLevels);
811 std::vector<VkClearValue> clearValues;
812 clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
813 clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
815 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
817 const VkExtent3D mipLevelSize = mipLevelExtents(imageSparseInfo.extent, mipLevelNdx);
818 const VkRect2D renderArea = makeRect2D(mipLevelSize);
819 const VkViewport viewport = makeViewport(mipLevelSize);
820 const VkImageSubresourceRange mipLevelRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevelNdx, 1u, 0u, imageSparseInfo.arrayLayers);
822 // Create color attachments image views
823 imageTexelsViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageTexels, mapImageViewType(m_imageType), imageSparseInfo.format, mipLevelRange));
824 imageResidencyViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageResidency, mapImageViewType(m_imageType), mapTextureFormat(m_residencyFormat), mipLevelRange));
826 const VkImageView attachmentsViews[] = { **imageTexelsViews[mipLevelNdx], **imageResidencyViews[mipLevelNdx] };
828 // Create framebuffer
829 const VkFramebufferCreateInfo framebufferInfo =
831 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
832 DE_NULL, // const void* pNext;
833 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
834 *m_renderPass, // VkRenderPass renderPass;
835 2u, // uint32_t attachmentCount;
836 attachmentsViews, // const VkImageView* pAttachments;
837 mipLevelSize.width, // uint32_t width;
838 mipLevelSize.height, // uint32_t height;
839 imageSparseInfo.arrayLayers, // uint32_t layers;
842 m_framebuffers[mipLevelNdx] = makeVkSharedPtr(createFramebuffer(deviceInterface, getDevice(), &framebufferInfo));
844 // Create descriptor set
845 descriptorSets[mipLevelNdx] = makeVkSharedPtr(makeDescriptorSet(deviceInterface, getDevice(), *descriptorPool, *descriptorSetLayout));
846 const VkDescriptorSet descriptorSet = **descriptorSets[mipLevelNdx];
848 // Update descriptor set
849 const VkImageSubresourceRange sparseImageSubresourceRange = sampledImageRangeToBind(imageSparseInfo, mipLevelNdx);
851 imageSparseViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageSparse, mapImageViewType(m_imageType), imageSparseInfo.format, sparseImageSubresourceRange));
853 const VkDescriptorImageInfo imageSparseDescInfo = makeDescriptorImageInfo(*m_sampler, **imageSparseViews[mipLevelNdx], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
855 DescriptorSetUpdateBuilder descriptorUpdateBuilder;
857 descriptorUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(BINDING_IMAGE_SPARSE), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSparseDescInfo);
858 descriptorUpdateBuilder.update(deviceInterface, getDevice());
860 beginRenderPass(deviceInterface, commandBuffer, *m_renderPass, **m_framebuffers[mipLevelNdx], renderArea, (deUint32)clearValues.size(), &clearValues[0]);
862 // Bind graphics pipeline
863 deviceInterface.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
865 // Bind descriptor set
866 deviceInterface.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
868 // Bind vertex buffer
870 const VkDeviceSize offset = 0ull;
871 deviceInterface.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &m_vertexBuffer.get(), &offset);
875 deviceInterface.cmdSetViewport(commandBuffer, 0u, 1u, &viewport);
877 // Bind Scissor Rectangle
878 deviceInterface.cmdSetScissor(commandBuffer, 0u, 1u, &renderArea);
880 const PushConstants pushConstants =
884 static_cast<float>(mipLevelSize.width),
885 static_cast<float>(mipLevelSize.height)
888 // Update push constants
889 deviceInterface.cmdPushConstants(commandBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(PushConstants), &pushConstants);
891 // Draw full screen quad
892 deviceInterface.cmdDraw(commandBuffer, 4u, 1u, 0u, 0u);
895 endRenderPass(deviceInterface, commandBuffer);
899 const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
901 VkImageMemoryBarrier imageOutputTransferSrcBarriers[2];
903 imageOutputTransferSrcBarriers[0] = makeImageMemoryBarrier
905 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
906 VK_ACCESS_TRANSFER_READ_BIT,
907 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
908 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
910 fullImageSubresourceRange
913 imageOutputTransferSrcBarriers[1] = makeImageMemoryBarrier
915 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
916 VK_ACCESS_TRANSFER_READ_BIT,
917 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
918 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
920 fullImageSubresourceRange
923 deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageOutputTransferSrcBarriers);
927 class SparseShaderIntrinsicsInstanceSampledExplicit : public SparseShaderIntrinsicsInstanceSampledBase
930 SparseShaderIntrinsicsInstanceSampledExplicit (Context& context,
931 const SpirVFunction function,
932 const ImageType imageType,
933 const tcu::UVec3& imageSize,
934 const VkFormat format)
935 : SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
937 VkImageSubresourceRange sampledImageRangeToBind (const VkImageCreateInfo& imageSparseInfo,
938 const deUint32 mipLevel) const
941 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
945 TestInstance* SparseShaderIntrinsicsCaseSampledExplicit::createInstance (Context& context) const
947 return new SparseShaderIntrinsicsInstanceSampledExplicit(context, m_function, m_imageType, m_imageSize, m_format);
950 class SparseShaderIntrinsicsInstanceSampledImplicit : public SparseShaderIntrinsicsInstanceSampledBase
953 SparseShaderIntrinsicsInstanceSampledImplicit (Context& context,
954 const SpirVFunction function,
955 const ImageType imageType,
956 const tcu::UVec3& imageSize,
957 const VkFormat format)
958 : SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
960 VkImageSubresourceRange sampledImageRangeToBind (const VkImageCreateInfo& imageSparseInfo,
961 const deUint32 mipLevel) const
963 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 1u, 0u, imageSparseInfo.arrayLayers);
967 TestInstance* SparseShaderIntrinsicsCaseSampledImplicit::createInstance (Context& context) const
969 return new SparseShaderIntrinsicsInstanceSampledImplicit(context, m_function, m_imageType, m_imageSize, m_format);