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 31using namespace vk; 32 33namespace vkt 34{ 35namespace sparse 36{ 37namespace 38{ 39 40Move<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 144void 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 407std::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 421std::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 436std::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 505class SparseShaderIntrinsicsInstanceSampledBase : public SparseShaderIntrinsicsInstanceBase 506{ 507public: 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 530private: 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 540VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageSparseUsageFlags (void) const 541{ 542 return VK_IMAGE_USAGE_SAMPLED_BIT; 543} 544 545VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageOutputUsageFlags (void) const 546{ 547 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 548} 549 550VkQueueFlags SparseShaderIntrinsicsInstanceSampledBase::getQueueFlags (void) const 551{ 552 return VK_QUEUE_GRAPHICS_BIT; 553} 554 555void 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 583void 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 939class SparseShaderIntrinsicsInstanceSampledExplicit : public SparseShaderIntrinsicsInstanceSampledBase 940{ 941public: 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 949 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 957TestInstance* SparseShaderIntrinsicsCaseSampledExplicit::createInstance (Context& context) const 958{ 959 return new SparseShaderIntrinsicsInstanceSampledExplicit(context, m_function, m_imageType, m_imageSize, m_format); 960} 961 962class SparseShaderIntrinsicsInstanceSampledImplicit : public SparseShaderIntrinsicsInstanceSampledBase 963{ 964public: 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 972 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 979TestInstance* 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