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