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