1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2017 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 21 * \brief Tests for mutable images 22 *//*--------------------------------------------------------------------*/ 23 24#include "vktImageMutableTests.hpp" 25#include "vktTestCaseUtil.hpp" 26#include "vktImageTexture.hpp" 27 28#include "vkBuilderUtil.hpp" 29#include "vkQueryUtil.hpp" 30#include "vkImageUtil.hpp" 31 32#include "deUniquePtr.hpp" 33#include "deSharedPtr.hpp" 34 35#include "tcuImageCompare.hpp" 36#include "tcuTestLog.hpp" 37#include "tcuTextureUtil.hpp" 38 39#include <string> 40#include <vector> 41 42using namespace vk; 43using namespace tcu; 44 45using de::UniquePtr; 46using de::MovePtr; 47using de::SharedPtr; 48using std::vector; 49 50namespace vkt 51{ 52namespace image 53{ 54 55typedef SharedPtr<Unique<VkPipeline> > SharedPtrVkPipeline; 56typedef SharedPtr<Unique<VkImageView> > SharedPtrVkImageView; 57 58template<typename T> 59inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move) 60{ 61 return SharedPtr<Unique<T> >(new Unique<T>(move)); 62} 63 64enum Upload { 65 UPLOAD_CLEAR = 0, 66 UPLOAD_COPY, 67 UPLOAD_STORE, 68 UPLOAD_DRAW, 69 UPLOAD_LAST 70}; 71 72enum Download { 73 DOWNLOAD_COPY = 0, 74 DOWNLOAD_LOAD, 75 DOWNLOAD_TEXTURE, 76 DOWNLOAD_LAST 77}; 78 79std::string getUploadString (const int upload) 80{ 81 const char* strs[] = { "clear", "copy", "store", "draw" }; 82 return strs[upload]; 83} 84 85std::string getDownloadString (const int download) 86{ 87 const char* strs[] = { "copy", "load", "texture" }; 88 return strs[download]; 89} 90 91struct CaseDef 92{ 93 ImageType imageType; 94 IVec3 size; 95 deUint32 numLayers; 96 VkFormat imageFormat; 97 VkFormat viewFormat; 98 enum Upload upload; 99 enum Download download; 100 bool isFormatListTest; 101}; 102 103static const deUint32 COLOR_TABLE_SIZE = 4; 104 105// Reference color values for float color rendering. Values have been chosen 106// so that when the bit patterns are reinterpreted as a 16-bit float, we do not 107// run into NaN / inf / denorm values. 108static const Vec4 COLOR_TABLE_FLOAT[COLOR_TABLE_SIZE] = 109{ 110 Vec4(0.00f, 0.40f, 0.80f, 0.10f), 111 Vec4(0.10f, 0.50f, 0.90f, 0.20f), 112 Vec4(0.20f, 0.60f, 1.00f, 0.30f), 113 Vec4(0.30f, 0.70f, 0.00f, 0.40f), 114}; 115 116// Reference color values for integer color rendering. We avoid negative 117// values (even for SINT formats) to avoid the situation where sign extension 118// leads to NaN / inf values when they are reinterpreted with a float 119// format. 120static const IVec4 COLOR_TABLE_INT[COLOR_TABLE_SIZE] = 121{ 122 IVec4(112, 60, 101, 41), 123 IVec4( 60, 101, 41, 112), 124 IVec4( 41, 112, 60, 101), 125 IVec4(101, 41, 112, 60), 126}; 127 128// Reference clear colors created from the color table values 129static const VkClearValue REFERENCE_CLEAR_COLOR_FLOAT[COLOR_TABLE_SIZE] = 130{ 131 makeClearValueColorF32(COLOR_TABLE_FLOAT[0].x(), COLOR_TABLE_FLOAT[0].y(), COLOR_TABLE_FLOAT[0].z(), COLOR_TABLE_FLOAT[0].w()), 132 makeClearValueColorF32(COLOR_TABLE_FLOAT[1].x(), COLOR_TABLE_FLOAT[1].y(), COLOR_TABLE_FLOAT[1].z(), COLOR_TABLE_FLOAT[1].w()), 133 makeClearValueColorF32(COLOR_TABLE_FLOAT[2].x(), COLOR_TABLE_FLOAT[2].y(), COLOR_TABLE_FLOAT[2].z(), COLOR_TABLE_FLOAT[2].w()), 134 makeClearValueColorF32(COLOR_TABLE_FLOAT[3].x(), COLOR_TABLE_FLOAT[3].y(), COLOR_TABLE_FLOAT[3].z(), COLOR_TABLE_FLOAT[3].w()), 135}; 136 137static const VkClearValue REFERENCE_CLEAR_COLOR_INT[COLOR_TABLE_SIZE] = 138{ 139 makeClearValueColorI32(COLOR_TABLE_INT[0].x(), COLOR_TABLE_INT[0].y(), COLOR_TABLE_INT[0].z(), COLOR_TABLE_INT[0].w()), 140 makeClearValueColorI32(COLOR_TABLE_INT[1].x(), COLOR_TABLE_INT[1].y(), COLOR_TABLE_INT[1].z(), COLOR_TABLE_INT[1].w()), 141 makeClearValueColorI32(COLOR_TABLE_INT[2].x(), COLOR_TABLE_INT[2].y(), COLOR_TABLE_INT[2].z(), COLOR_TABLE_INT[2].w()), 142 makeClearValueColorI32(COLOR_TABLE_INT[3].x(), COLOR_TABLE_INT[3].y(), COLOR_TABLE_INT[3].z(), COLOR_TABLE_INT[3].w()), 143}; 144 145static const Texture s_textures[] = 146{ 147 Texture(IMAGE_TYPE_2D, tcu::IVec3(32, 32, 1), 1), 148 Texture(IMAGE_TYPE_2D_ARRAY, tcu::IVec3(32, 32, 1), 4), 149}; 150 151VkImageType getImageType (const ImageType textureImageType) 152{ 153 switch (textureImageType) 154 { 155 case IMAGE_TYPE_2D: 156 case IMAGE_TYPE_2D_ARRAY: 157 return VK_IMAGE_TYPE_2D; 158 159 default: 160 DE_ASSERT(0); 161 return VK_IMAGE_TYPE_LAST; 162 } 163} 164 165VkImageViewType getImageViewType (const ImageType textureImageType) 166{ 167 switch (textureImageType) 168 { 169 case IMAGE_TYPE_2D: 170 return VK_IMAGE_VIEW_TYPE_2D; 171 case IMAGE_TYPE_2D_ARRAY: 172 return VK_IMAGE_VIEW_TYPE_2D_ARRAY; 173 174 default: 175 DE_ASSERT(0); 176 return VK_IMAGE_VIEW_TYPE_LAST; 177 } 178} 179 180static const VkFormat s_formats[] = 181{ 182 VK_FORMAT_R32G32B32A32_SFLOAT, 183 VK_FORMAT_R16G16B16A16_SFLOAT, 184 VK_FORMAT_R32G32_SFLOAT, 185 VK_FORMAT_R16G16_SFLOAT, 186 VK_FORMAT_R32_SFLOAT, 187 188 VK_FORMAT_R32G32B32A32_UINT, 189 VK_FORMAT_R16G16B16A16_UINT, 190 VK_FORMAT_R8G8B8A8_UINT, 191 VK_FORMAT_R32G32_UINT, 192 VK_FORMAT_R16G16_UINT, 193 VK_FORMAT_R32_UINT, 194 195 VK_FORMAT_R32G32B32A32_SINT, 196 VK_FORMAT_R16G16B16A16_SINT, 197 VK_FORMAT_R8G8B8A8_SINT, 198 VK_FORMAT_R32G32_SINT, 199 VK_FORMAT_R16G16_SINT, 200 VK_FORMAT_R32_SINT, 201 202 VK_FORMAT_R8G8B8A8_UNORM, 203 204 VK_FORMAT_R8G8B8A8_SNORM, 205}; 206 207inline bool formatsAreCompatible (const VkFormat format0, const VkFormat format1) 208{ 209 return format0 == format1 || mapVkFormat(format0).getPixelSize() == mapVkFormat(format1).getPixelSize(); 210} 211 212std::string getColorFormatStr (const int numComponents, const bool isUint, const bool isSint) 213{ 214 std::ostringstream str; 215 if (numComponents == 1) 216 str << (isUint ? "uint" : isSint ? "int" : "float"); 217 else 218 str << (isUint ? "u" : isSint ? "i" : "") << "vec" << numComponents; 219 220 return str.str(); 221} 222 223std::string getShaderSamplerType (const tcu::TextureFormat& format, VkImageViewType type) 224{ 225 std::ostringstream samplerType; 226 227 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 228 samplerType << "u"; 229 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) 230 samplerType << "i"; 231 232 switch (type) 233 { 234 case VK_IMAGE_VIEW_TYPE_2D: 235 samplerType << "sampler2D"; 236 break; 237 238 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 239 samplerType << "sampler2DArray"; 240 break; 241 242 default: 243 DE_FATAL("Ivalid image view type"); 244 break; 245 } 246 247 return samplerType.str(); 248} 249 250void initPrograms (SourceCollections& programCollection, const CaseDef caseDef) 251{ 252 if (caseDef.upload == UPLOAD_DRAW) 253 { 254 { 255 std::ostringstream src; 256 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 257 << "\n" 258 << "layout(location = 0) in vec4 in_position;\n" 259 << "layout(location = 1) in vec4 in_color;\n" 260 << "layout(location = 0) out vec4 out_color;\n" 261 << "\n" 262 << "out gl_PerVertex {\n" 263 << " vec4 gl_Position;\n" 264 << "};\n" 265 << "\n" 266 << "void main(void)\n" 267 << "{\n" 268 << " gl_Position = in_position;\n" 269 << " out_color = in_color;\n" 270 << "}\n"; 271 272 programCollection.glslSources.add("uploadDrawVert") << glu::VertexSource(src.str()); 273 } 274 275 { 276 const int numComponents = getNumUsedChannels(mapVkFormat(caseDef.viewFormat).order); 277 const bool isUint = isUintFormat(caseDef.viewFormat); 278 const bool isSint = isIntFormat(caseDef.viewFormat); 279 const std::string colorFormat = getColorFormatStr(numComponents, isUint, isSint); 280 281 std::ostringstream src; 282 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 283 << "\n" 284 << "layout(location = 0) in vec4 in_color;\n" 285 << "layout(location = 0) out " << colorFormat << " out_color;\n" 286 << "\n" 287 << "void main(void)\n" 288 << "{\n" 289 << " out_color = " << colorFormat << "(" 290 << (numComponents == 1 ? "in_color.r" : 291 numComponents == 2 ? "in_color.rg" : 292 numComponents == 3 ? "in_color.rgb" : "in_color") 293 << ");\n" 294 << "}\n"; 295 296 programCollection.glslSources.add("uploadDrawFrag") << glu::FragmentSource(src.str()); 297 } 298 } 299 300 if (caseDef.upload == UPLOAD_STORE) 301 { 302 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat); 303 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat); 304 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType); 305 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4"; 306 const bool isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat); 307 308 std::ostringstream src; 309 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 310 << "\n" 311 << "layout (local_size_x = 1) in;\n" 312 << "\n" 313 << "layout(binding=0, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " u_image;\n" 314 << "\n" 315 << "const " << colorTypeStr << " colorTable[] = " << colorTypeStr << "[](\n"; 316 for (deUint32 idx = 0; idx < COLOR_TABLE_SIZE; idx++) 317 { 318 if (isIntegerFormat) 319 src << " " << colorTypeStr << "(" << COLOR_TABLE_INT[idx].x() << ", " << COLOR_TABLE_INT[idx].y() << ", " << COLOR_TABLE_INT[idx].z() << ", " << COLOR_TABLE_INT[idx].w() << ")"; 320 else 321 src << " " << colorTypeStr << "(" << COLOR_TABLE_FLOAT[idx].x() << ", " << COLOR_TABLE_FLOAT[idx].y() << ", " << COLOR_TABLE_FLOAT[idx].z() << ", " << COLOR_TABLE_FLOAT[idx].w() << ")"; 322 if (idx < COLOR_TABLE_SIZE - 1) 323 src << ","; 324 src << "\n"; 325 } 326 src << ");\n" 327 << "\n" 328 << "void main(void)\n" 329 << "{\n"; 330 if (caseDef.imageType == IMAGE_TYPE_2D) 331 { 332 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n"; 333 } 334 else 335 { 336 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY); 337 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n"; 338 } 339 src << " " << colorTypeStr << " color = colorTable[gl_GlobalInvocationID.z];\n" 340 << " imageStore(u_image, pos, color);\n" 341 << "}\n"; 342 343 programCollection.glslSources.add("uploadStoreComp") << glu::ComputeSource(src.str()); 344 } 345 346 if (caseDef.download == DOWNLOAD_LOAD) 347 { 348 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat); 349 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat); 350 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType); 351 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4"; 352 353 std::ostringstream src; 354 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 355 << "\n" 356 << "layout (local_size_x = 1) in;\n" 357 << "\n" 358 << "layout(binding=0, " << imageFormatStr << ") readonly uniform " << imageTypeStr << " in_image;\n" 359 << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n" 360 << "\n" 361 << "void main(void)\n" 362 << "{\n"; 363 if (caseDef.imageType == IMAGE_TYPE_2D) 364 { 365 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n"; 366 } 367 else 368 { 369 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY); 370 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n"; 371 } 372 src << " imageStore(out_image, pos, imageLoad(in_image, pos));\n" 373 << "}\n"; 374 375 programCollection.glslSources.add("downloadLoadComp") << glu::ComputeSource(src.str()); 376 } 377 378 if (caseDef.download == DOWNLOAD_TEXTURE) 379 { 380 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat); 381 const VkImageViewType viewType = getImageViewType(caseDef.imageType); 382 const std::string samplerTypeStr = getShaderSamplerType(tcuFormat, viewType); 383 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat); 384 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType); 385 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4"; 386 387 std::ostringstream src; 388 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 389 << "\n" 390 << "layout (local_size_x = 1) in;\n" 391 << "\n" 392 << "layout(binding=0) uniform " << samplerTypeStr << " u_tex;\n" 393 << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n" 394 << "\n" 395 << "void main(void)\n" 396 << "{\n"; 397 if (caseDef.imageType == IMAGE_TYPE_2D) 398 { 399 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n"; 400 } 401 else 402 { 403 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY); 404 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n"; 405 } 406 src << " imageStore(out_image, pos, texelFetch(u_tex, pos, 0));\n" 407 << "}\n"; 408 409 programCollection.glslSources.add("downloadTextureComp") << glu::ComputeSource(src.str()); 410 } 411} 412 413Move<VkImage> makeImage (const DeviceInterface& vk, 414 const VkDevice device, 415 VkImageCreateFlags flags, 416 VkImageType imageType, 417 const VkFormat format, 418 const VkFormat viewFormat, 419 const bool useImageFormatList, 420 const IVec3& size, 421 const deUint32 numMipLevels, 422 const deUint32 numLayers, 423 const VkImageUsageFlags usage) 424{ 425 const VkFormat formatList[2] = 426 { 427 format, 428 viewFormat 429 }; 430 431 const VkImageFormatListCreateInfoKHR formatListInfo = 432 { 433 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR, // VkStructureType sType; 434 DE_NULL, // const void* pNext; 435 2u, // deUint32 viewFormatCount 436 formatList // const VkFormat* pViewFormats 437 }; 438 439 const VkImageCreateInfo imageParams = 440 { 441 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 442 useImageFormatList ? &formatListInfo : DE_NULL, // const void* pNext; 443 flags, // VkImageCreateFlags flags; 444 imageType, // VkImageType imageType; 445 format, // VkFormat format; 446 makeExtent3D(size), // VkExtent3D extent; 447 numMipLevels, // deUint32 mipLevels; 448 numLayers, // deUint32 arrayLayers; 449 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 450 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 451 usage, // VkImageUsageFlags usage; 452 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 453 0u, // deUint32 queueFamilyIndexCount; 454 DE_NULL, // const deUint32* pQueueFamilyIndices; 455 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 456 }; 457 return createImage(vk, device, &imageParams); 458} 459 460inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize bufferSize, const VkBufferUsageFlags usage) 461{ 462 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSize, usage); 463 return createBuffer(vk, device, &bufferCreateInfo); 464} 465 466inline VkImageSubresourceRange makeColorSubresourceRange (const int baseArrayLayer, const int layerCount) 467{ 468 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, static_cast<deUint32>(baseArrayLayer), static_cast<deUint32>(layerCount)); 469} 470 471Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice device) 472{ 473 const VkSamplerCreateInfo samplerParams = 474 { 475 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType; 476 DE_NULL, // const void* pNext; 477 (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags; 478 VK_FILTER_NEAREST, // VkFilter magFilter; 479 VK_FILTER_NEAREST, // VkFilter minFilter; 480 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode; 481 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU; 482 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV; 483 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW; 484 0.0f, // float mipLodBias; 485 VK_FALSE, // VkBool32 anisotropyEnable; 486 1.0f, // float maxAnisotropy; 487 VK_FALSE, // VkBool32 compareEnable; 488 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp; 489 0.0f, // float minLod; 490 0.0f, // float maxLod; 491 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor; 492 VK_FALSE, // VkBool32 unnormalizedCoordinates; 493 }; 494 495 return createSampler(vk, device, &samplerParams); 496} 497 498 499Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk, 500 const VkDevice device) 501{ 502 const VkPipelineLayoutCreateInfo info = 503 { 504 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 505 DE_NULL, 506 (VkPipelineLayoutCreateFlags)0, 507 0u, 508 DE_NULL, 509 0u, 510 DE_NULL, 511 }; 512 return createPipelineLayout(vk, device, &info); 513} 514 515Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk, 516 const VkDevice device, 517 const VkPipelineLayout pipelineLayout, 518 const VkRenderPass renderPass, 519 const VkShaderModule vertexModule, 520 const VkShaderModule fragmentModule, 521 const IVec2& renderSize, 522 const VkPrimitiveTopology topology, 523 const deUint32 subpass) 524{ 525 const VkVertexInputBindingDescription vertexInputBindingDescription = 526 { 527 0u, // deUint32 binding; 528 (deUint32)(2 * sizeof(Vec4)), // deUint32 stride; 529 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate; 530 }; 531 532 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = 533 { 534 { 535 0u, // deUint32 location; 536 0u, // deUint32 binding; 537 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 538 0u, // deUint32 offset; 539 }, 540 { 541 1u, // deUint32 location; 542 0u, // deUint32 binding; 543 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 544 (deUint32)sizeof(Vec4), // deUint32 offset; 545 } 546 }; 547 548 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = 549 { 550 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 551 DE_NULL, // const void* pNext; 552 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 553 1u, // deUint32 vertexBindingDescriptionCount; 554 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 555 DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions), // deUint32 vertexAttributeDescriptionCount; 556 vertexInputAttributeDescriptions, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 557 }; 558 559 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = 560 { 561 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 562 DE_NULL, // const void* pNext; 563 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags; 564 topology, // VkPrimitiveTopology topology; 565 VK_FALSE, // VkBool32 primitiveRestartEnable; 566 }; 567 568 const VkViewport viewport = makeViewport( 569 0.0f, 0.0f, 570 static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()), 571 0.0f, 1.0f); 572 573 const VkRect2D scissor = 574 { 575 makeOffset2D(0, 0), 576 makeExtent2D(renderSize.x(), renderSize.y()), 577 }; 578 579 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo = 580 { 581 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 582 DE_NULL, // const void* pNext; 583 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags; 584 1u, // deUint32 viewportCount; 585 &viewport, // const VkViewport* pViewports; 586 1u, // deUint32 scissorCount; 587 &scissor, // const VkRect2D* pScissors; 588 }; 589 590 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo = 591 { 592 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 593 DE_NULL, // const void* pNext; 594 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags; 595 VK_FALSE, // VkBool32 depthClampEnable; 596 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 597 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 598 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 599 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 600 VK_FALSE, // VkBool32 depthBiasEnable; 601 0.0f, // float depthBiasConstantFactor; 602 0.0f, // float depthBiasClamp; 603 0.0f, // float depthBiasSlopeFactor; 604 1.0f, // float lineWidth; 605 }; 606 607 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo = 608 { 609 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 610 DE_NULL, // const void* pNext; 611 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags; 612 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 613 VK_FALSE, // VkBool32 sampleShadingEnable; 614 0.0f, // float minSampleShading; 615 DE_NULL, // const VkSampleMask* pSampleMask; 616 VK_FALSE, // VkBool32 alphaToCoverageEnable; 617 VK_FALSE // VkBool32 alphaToOneEnable; 618 }; 619 620 const VkStencilOpState stencilOpState = makeStencilOpState( 621 VK_STENCIL_OP_KEEP, // stencil fail 622 VK_STENCIL_OP_ZERO, // depth & stencil pass 623 VK_STENCIL_OP_KEEP, // depth only fail 624 VK_COMPARE_OP_EQUAL, // compare op 625 ~0u, // compare mask 626 ~0u, // write mask 627 0u); // reference 628 629 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = 630 { 631 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 632 DE_NULL, // const void* pNext; 633 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags; 634 VK_FALSE, // VkBool32 depthTestEnable; 635 VK_FALSE, // VkBool32 depthWriteEnable; 636 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 637 VK_FALSE, // VkBool32 depthBoundsTestEnable; 638 VK_FALSE, // VkBool32 stencilTestEnable; 639 stencilOpState, // VkStencilOpState front; 640 stencilOpState, // VkStencilOpState back; 641 0.0f, // float minDepthBounds; 642 1.0f, // float maxDepthBounds; 643 }; 644 645 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 646 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = 647 { 648 VK_FALSE, // VkBool32 blendEnable; 649 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 650 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 651 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 652 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 653 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 654 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 655 colorComponentsAll, // VkColorComponentFlags colorWriteMask; 656 }; 657 658 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo = 659 { 660 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 661 DE_NULL, // const void* pNext; 662 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; 663 VK_FALSE, // VkBool32 logicOpEnable; 664 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 665 1u, // deUint32 attachmentCount; 666 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 667 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 668 }; 669 670 const VkPipelineShaderStageCreateInfo pShaderStages[] = 671 { 672 { 673 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 674 DE_NULL, // const void* pNext; 675 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 676 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; 677 vertexModule, // VkShaderModule module; 678 "main", // const char* pName; 679 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 680 }, 681 { 682 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 683 DE_NULL, // const void* pNext; 684 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 685 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; 686 fragmentModule, // VkShaderModule module; 687 "main", // const char* pName; 688 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 689 } 690 }; 691 692 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo = 693 { 694 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 695 DE_NULL, // const void* pNext; 696 0u, // VkPipelineCreateFlags flags; 697 DE_LENGTH_OF_ARRAY(pShaderStages), // deUint32 stageCount; 698 pShaderStages, // const VkPipelineShaderStageCreateInfo* pStages; 699 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 700 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 701 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 702 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState; 703 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 704 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 705 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 706 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 707 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 708 pipelineLayout, // VkPipelineLayout layout; 709 renderPass, // VkRenderPass renderPass; 710 subpass, // deUint32 subpass; 711 DE_NULL, // VkPipeline basePipelineHandle; 712 0, // deInt32 basePipelineIndex; 713 }; 714 715 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo); 716} 717 718Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk, 719 const VkDevice device, 720 const VkPipelineLayout pipelineLayout, 721 const VkShaderModule shaderModule, 722 const VkSpecializationInfo* specInfo) 723{ 724 const VkPipelineShaderStageCreateInfo shaderStageInfo = 725 { 726 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 727 DE_NULL, // const void* pNext; 728 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 729 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage; 730 shaderModule, // VkShaderModule module; 731 "main", // const char* pName; 732 specInfo, // const VkSpecializationInfo* pSpecializationInfo; 733 }; 734 const VkComputePipelineCreateInfo pipelineInfo = 735 { 736 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType; 737 DE_NULL, // const void* pNext; 738 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; 739 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage; 740 pipelineLayout, // VkPipelineLayout layout; 741 DE_NULL, // VkPipeline basePipelineHandle; 742 0, // deInt32 basePipelineIndex; 743 }; 744 return createComputePipeline(vk, device, DE_NULL , &pipelineInfo); 745} 746 747Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk, 748 const VkDevice device, 749 const VkFormat colorFormat, 750 const deUint32 numLayers) 751{ 752 const VkAttachmentDescription colorAttachmentDescription = 753 { 754 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 755 colorFormat, // VkFormat format; 756 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 757 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 758 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 759 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 760 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 761 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 762 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 763 }; 764 vector<VkAttachmentDescription> attachmentDescriptions(numLayers, colorAttachmentDescription); 765 766 // Create a subpass for each attachment (each attachement is a layer of an arrayed image). 767 vector<VkAttachmentReference> colorAttachmentReferences (numLayers); 768 vector<VkSubpassDescription> subpasses; 769 770 // Ordering here must match the framebuffer attachments 771 for (deUint32 i = 0; i < numLayers; ++i) 772 { 773 const VkAttachmentReference attachmentRef = 774 { 775 i, // deUint32 attachment; 776 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 777 }; 778 779 colorAttachmentReferences[i] = attachmentRef; 780 781 const VkSubpassDescription subpassDescription = 782 { 783 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; 784 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 785 0u, // deUint32 inputAttachmentCount; 786 DE_NULL, // const VkAttachmentReference* pInputAttachments; 787 1u, // deUint32 colorAttachmentCount; 788 &colorAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments; 789 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 790 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 791 0u, // deUint32 preserveAttachmentCount; 792 DE_NULL // const deUint32* pPreserveAttachments; 793 }; 794 subpasses.push_back(subpassDescription); 795 } 796 797 const VkRenderPassCreateInfo renderPassInfo = 798 { 799 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 800 DE_NULL, // const void* pNext; 801 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; 802 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount; 803 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments; 804 static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount; 805 &subpasses[0], // const VkSubpassDescription* pSubpasses; 806 0u, // deUint32 dependencyCount; 807 DE_NULL // const VkSubpassDependency* pDependencies; 808 }; 809 810 return createRenderPass(vk, device, &renderPassInfo); 811} 812 813Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk, 814 const VkDevice device, 815 const VkRenderPass renderPass, 816 const deUint32 attachmentCount, 817 const VkImageView* pAttachments, 818 const IVec2 size) 819{ 820 const VkFramebufferCreateInfo framebufferInfo = 821 { 822 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 823 DE_NULL, 824 (VkFramebufferCreateFlags)0, 825 renderPass, 826 attachmentCount, 827 pAttachments, 828 static_cast<deUint32>(size.x()), 829 static_cast<deUint32>(size.y()), 830 1u, 831 }; 832 833 return createFramebuffer(vk, device, &framebufferInfo); 834} 835 836Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool) 837{ 838 return allocateCommandBuffer(vk, device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 839} 840 841MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement) 842{ 843 MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement); 844 VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset())); 845 return alloc; 846} 847 848MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement) 849{ 850 MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement)); 851 VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset())); 852 return alloc; 853} 854 855vector<Vec4> genVertexData (const CaseDef& caseDef) 856{ 857 vector<Vec4> vectorData; 858 const bool isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat); 859 860 for (deUint32 z = 0; z < caseDef.numLayers; z++) 861 { 862 const deUint32 colorIdx = z % COLOR_TABLE_SIZE; 863 const Vec4 color = isIntegerFormat ? COLOR_TABLE_INT[colorIdx].cast<float>() : COLOR_TABLE_FLOAT[colorIdx]; 864 865 vectorData.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f)); 866 vectorData.push_back(color); 867 vectorData.push_back(Vec4(-1.0f, 1.0f, 0.0f, 1.0f)); 868 vectorData.push_back(color); 869 vectorData.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f)); 870 vectorData.push_back(color); 871 vectorData.push_back(Vec4( 1.0f, 1.0f, 0.0f, 1.0f)); 872 vectorData.push_back(color); 873 } 874 875 return vectorData; 876} 877 878void generateExpectedImage(const tcu::PixelBufferAccess& image, const CaseDef& caseDef) 879{ 880 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(image.getFormat().type); 881 const bool isIntegerFormat = channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER; 882 const IVec2 size = caseDef.size.swizzle(0, 1); 883 884 for (int z = 0; z < static_cast<int>(caseDef.numLayers); z++) 885 { 886 const deUint32 colorIdx = z % COLOR_TABLE_SIZE; 887 for (int y = 0; y < size.y(); y++) 888 for (int x = 0; x < size.x(); x++) 889 { 890 if (isIntegerFormat) 891 image.setPixel(COLOR_TABLE_INT[colorIdx], x, y, z); 892 else 893 image.setPixel(COLOR_TABLE_FLOAT[colorIdx], x, y, z); 894 } 895 } 896} 897 898VkImageUsageFlags getImageUsageForTestCase (const CaseDef& caseDef) 899{ 900 VkImageUsageFlags flags = 0u; 901 902 switch (caseDef.upload) 903 { 904 case UPLOAD_CLEAR: 905 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; 906 break; 907 case UPLOAD_DRAW: 908 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 909 break; 910 case UPLOAD_STORE: 911 flags |= VK_IMAGE_USAGE_STORAGE_BIT; 912 break; 913 case UPLOAD_COPY: 914 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; 915 break; 916 default: 917 DE_ASSERT("Invalid upload method"); 918 break; 919 } 920 921 switch (caseDef.download) 922 { 923 case DOWNLOAD_TEXTURE: 924 flags |= VK_IMAGE_USAGE_SAMPLED_BIT; 925 break; 926 case DOWNLOAD_LOAD: 927 flags |= VK_IMAGE_USAGE_STORAGE_BIT; 928 break; 929 case DOWNLOAD_COPY: 930 flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 931 break; 932 default: 933 DE_ASSERT("Invalid download method"); 934 break; 935 } 936 937 // We can only create a view for the image if it is going to be used for any of these usages, 938 // so let's make sure that we have at least one of them. 939 VkImageUsageFlags viewRequiredFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 940 if (!(flags & viewRequiredFlags)) 941 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 942 943 return flags; 944} 945 946// Executes a combination of upload/download methods 947class UploadDownloadExecutor 948{ 949public: 950 UploadDownloadExecutor(Context &context, const CaseDef& caseSpec) : 951 m_caseDef(caseSpec), 952 m_haveMaintenance2(de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance2")), 953 m_vk(context.getDeviceInterface()), 954 m_device(context.getDevice()), 955 m_queue(context.getUniversalQueue()), 956 m_queueFamilyIndex(context.getUniversalQueueFamilyIndex()), 957 m_allocator(context.getDefaultAllocator()) 958 { 959 } 960 961 void run(Context& context, VkBuffer buffer); 962 963private: 964 void uploadClear(Context& context); 965 void uploadStore(Context& context); 966 void uploadCopy(Context& context); 967 void uploadDraw(Context& context); 968 void downloadCopy(Context& context, VkBuffer buffer); 969 void downloadTexture(Context& context, VkBuffer buffer); 970 void downloadLoad(Context& context, VkBuffer buffer); 971 972 void copyImageToBuffer(VkImage image, 973 VkBuffer buffer, 974 const IVec3 size, 975 const VkAccessFlags srcAccessMask, 976 const VkImageLayout oldLayout, 977 const deUint32 numLayers); 978 979 const CaseDef& m_caseDef; 980 981 bool m_haveMaintenance2; 982 983 const DeviceInterface& m_vk; 984 const VkDevice m_device; 985 const VkQueue m_queue; 986 const deUint32 m_queueFamilyIndex; 987 Allocator& m_allocator; 988 989 Move<VkCommandPool> m_cmdPool; 990 Move<VkCommandBuffer> m_cmdBuffer; 991 992 bool m_imageIsIntegerFormat; 993 bool m_viewIsIntegerFormat; 994 995 // Target image for upload paths 996 Move<VkImage> m_image; 997 MovePtr<Allocation> m_imageAlloc; 998 999 // Upload copy 1000 struct 1001 { 1002 Move<VkBuffer> colorBuffer; 1003 VkDeviceSize colorBufferSize; 1004 MovePtr<Allocation> colorBufferAlloc; 1005 } m_uCopy; 1006 1007 // Upload draw 1008 struct 1009 { 1010 Move<VkBuffer> vertexBuffer; 1011 MovePtr<Allocation> vertexBufferAlloc; 1012 Move<VkPipelineLayout> pipelineLayout; 1013 Move<VkRenderPass> renderPass; 1014 Move<VkShaderModule> vertexModule; 1015 Move<VkShaderModule> fragmentModule; 1016 vector<SharedPtrVkImageView> attachments; 1017 vector<VkImageView> attachmentHandles; 1018 vector<SharedPtrVkPipeline> pipelines; 1019 Move<VkFramebuffer> framebuffer; 1020 } m_uDraw; 1021 1022 // Upload store 1023 struct 1024 { 1025 Move<VkDescriptorPool> descriptorPool; 1026 Move<VkPipelineLayout> pipelineLayout; 1027 Move<VkDescriptorSetLayout> descriptorSetLayout; 1028 Move<VkDescriptorSet> descriptorSet; 1029 VkDescriptorImageInfo imageDescriptorInfo; 1030 Move<VkShaderModule> computeModule; 1031 Move<VkPipeline> computePipeline; 1032 Move<VkImageView> imageView; 1033 } m_uStore; 1034 1035 // Download load 1036 struct 1037 { 1038 Move<VkDescriptorPool> descriptorPool; 1039 Move<VkPipelineLayout> pipelineLayout; 1040 Move<VkDescriptorSetLayout> descriptorSetLayout; 1041 Move<VkDescriptorSet> descriptorSet; 1042 Move<VkShaderModule> computeModule; 1043 Move<VkPipeline> computePipeline; 1044 Move<VkImageView> inImageView; 1045 VkDescriptorImageInfo inImageDescriptorInfo; 1046 Move<VkImage> outImage; 1047 Move<VkImageView> outImageView; 1048 MovePtr<Allocation> outImageAlloc; 1049 VkDescriptorImageInfo outImageDescriptorInfo; 1050 } m_dLoad; 1051 1052 // Download texture 1053 struct 1054 { 1055 Move<VkDescriptorPool> descriptorPool; 1056 Move<VkPipelineLayout> pipelineLayout; 1057 Move<VkDescriptorSetLayout> descriptorSetLayout; 1058 Move<VkDescriptorSet> descriptorSet; 1059 Move<VkShaderModule> computeModule; 1060 Move<VkPipeline> computePipeline; 1061 Move<VkImageView> inImageView; 1062 VkDescriptorImageInfo inImageDescriptorInfo; 1063 Move<VkSampler> sampler; 1064 Move<VkImage> outImage; 1065 Move<VkImageView> outImageView; 1066 MovePtr<Allocation> outImageAlloc; 1067 VkDescriptorImageInfo outImageDescriptorInfo; 1068 } m_dTex; 1069 1070 VkImageLayout m_imageLayoutAfterUpload; 1071 VkAccessFlagBits m_imageUploadAccessMask; 1072}; 1073 1074void UploadDownloadExecutor::run(Context& context, VkBuffer buffer) 1075{ 1076 m_imageIsIntegerFormat = isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat); 1077 m_viewIsIntegerFormat = isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat); 1078 1079 m_cmdPool = createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex); 1080 m_cmdBuffer = makeCommandBuffer(m_vk, m_device, *m_cmdPool); 1081 beginCommandBuffer(m_vk, *m_cmdBuffer); 1082 1083 const VkImageUsageFlags imageUsage = getImageUsageForTestCase(m_caseDef); 1084 const VkImageCreateFlags imageFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | (m_haveMaintenance2 ? VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR : 0); 1085 m_image = makeImage(m_vk, m_device, imageFlags, getImageType(m_caseDef.imageType), m_caseDef.imageFormat, m_caseDef.viewFormat, 1086 m_caseDef.isFormatListTest, m_caseDef.size, 1u, m_caseDef.numLayers, imageUsage); 1087 m_imageAlloc = bindImage(m_vk, m_device, m_allocator, *m_image, MemoryRequirement::Any); 1088 1089 switch (m_caseDef.upload) 1090 { 1091 case UPLOAD_DRAW: 1092 uploadDraw(context); 1093 break; 1094 case UPLOAD_STORE: 1095 uploadStore(context); 1096 break; 1097 case UPLOAD_CLEAR: 1098 uploadClear(context); 1099 break; 1100 case UPLOAD_COPY: 1101 uploadCopy(context); 1102 break; 1103 default: 1104 DE_ASSERT("Unsupported upload method"); 1105 } 1106 1107 switch (m_caseDef.download) 1108 { 1109 case DOWNLOAD_COPY: 1110 downloadCopy(context, buffer); 1111 break; 1112 case DOWNLOAD_LOAD: 1113 downloadLoad(context, buffer); 1114 break; 1115 case DOWNLOAD_TEXTURE: 1116 downloadTexture(context, buffer); 1117 break; 1118 default: 1119 DE_ASSERT("Unsupported download method"); 1120 } 1121 1122 VK_CHECK(m_vk.endCommandBuffer(*m_cmdBuffer)); 1123 submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer); 1124} 1125 1126void UploadDownloadExecutor::uploadClear(Context& context) 1127{ 1128 (void) context; 1129 1130 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL; 1131 1132 const VkImageSubresourceRange subresourceRange = makeColorSubresourceRange(0, m_caseDef.numLayers); 1133 const VkImageMemoryBarrier imageInitBarrier = 1134 { 1135 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1136 DE_NULL, // const void* pNext; 1137 0u, // VkAccessFlags srcAccessMask; 1138 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAcessMask; 1139 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1140 requiredImageLayout, // VkImageLayout newLayout; 1141 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1142 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 1143 *m_image, // VkImage image; 1144 subresourceRange // VkImageSubresourceRange subresourceRange; 1145 }; 1146 1147 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1148 0u, DE_NULL, 0u, DE_NULL, 1u, &imageInitBarrier); 1149 1150 for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++) 1151 { 1152 const VkImageSubresourceRange layerSubresourceRange = makeColorSubresourceRange(layer, 1u); 1153 const deUint32 colorIdx = layer % COLOR_TABLE_SIZE; 1154 const VkClearColorValue clearColor = m_imageIsIntegerFormat ? REFERENCE_CLEAR_COLOR_INT[colorIdx].color : REFERENCE_CLEAR_COLOR_FLOAT[colorIdx].color; 1155 m_vk.cmdClearColorImage(*m_cmdBuffer, *m_image, requiredImageLayout, &clearColor, 1u, &layerSubresourceRange); 1156 } 1157 1158 m_imageLayoutAfterUpload = requiredImageLayout; 1159 m_imageUploadAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 1160} 1161 1162void UploadDownloadExecutor::uploadStore(Context& context) 1163{ 1164 const vk::VkImageViewUsageCreateInfoKHR viewUsageCreateInfo = { 1165 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType 1166 DE_NULL, // const void* pNext 1167 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage; 1168 }; 1169 m_uStore.imageView = makeImageView(m_vk, m_device, *m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, 1170 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL); 1171 1172 // Setup compute pipeline 1173 m_uStore.descriptorPool = DescriptorPoolBuilder() 1174 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) 1175 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 1176 1177 m_uStore.descriptorSetLayout = DescriptorSetLayoutBuilder() 1178 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 1179 .build(m_vk, m_device); 1180 1181 m_uStore.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_uStore.descriptorSetLayout); 1182 m_uStore.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_uStore.descriptorPool, *m_uStore.descriptorSetLayout); 1183 m_uStore.imageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_uStore.imageView, VK_IMAGE_LAYOUT_GENERAL); 1184 m_uStore.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadStoreComp"), 0); 1185 m_uStore.computePipeline = makeComputePipeline(m_vk, m_device, *m_uStore.pipelineLayout, *m_uStore.computeModule, DE_NULL); 1186 1187 DescriptorSetUpdateBuilder() 1188 .writeSingle(*m_uStore.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_uStore.imageDescriptorInfo) 1189 .update(m_vk, m_device); 1190 1191 // Transition storage image for shader access (imageStore) 1192 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL; 1193 const VkImageMemoryBarrier imageBarrier = 1194 { 1195 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1196 DE_NULL, // const void* pNext; 1197 (VkAccessFlags)0, // VkAccessFlags srcAccessMask; 1198 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask; 1199 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1200 requiredImageLayout, // VkImageLayout newLayout; 1201 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1202 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 1203 *m_image, // VkImage image; 1204 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange; 1205 }; 1206 1207 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 1208 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier); 1209 1210 // Dispatch 1211 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.computePipeline); 1212 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.pipelineLayout, 0u, 1u, &m_uStore.descriptorSet.get(), 0u, DE_NULL); 1213 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers); 1214 1215 m_imageLayoutAfterUpload = requiredImageLayout; 1216 m_imageUploadAccessMask = VK_ACCESS_SHADER_WRITE_BIT; 1217} 1218 1219void UploadDownloadExecutor::uploadCopy(Context& context) 1220{ 1221 (void) context; 1222 1223 // Create a host-mappable buffer with the color data to upload 1224 const VkDeviceSize pixelSize = tcu::getPixelSize(mapVkFormat(m_caseDef.imageFormat)); 1225 const VkDeviceSize layerSize = m_caseDef.size.x() * m_caseDef.size.y() * m_caseDef.size.z() * pixelSize; 1226 1227 m_uCopy.colorBufferSize = layerSize * m_caseDef.numLayers; 1228 m_uCopy.colorBuffer = makeBuffer(m_vk, m_device, m_uCopy.colorBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); 1229 m_uCopy.colorBufferAlloc = bindBuffer(m_vk, m_device, m_allocator, *m_uCopy.colorBuffer, MemoryRequirement::HostVisible); 1230 1231 // Fill color buffer 1232 const tcu::TextureFormat tcuFormat = mapVkFormat(m_caseDef.imageFormat); 1233 VkDeviceSize layerOffset = 0ull; 1234 for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++) 1235 { 1236 tcu::PixelBufferAccess imageAccess = tcu::PixelBufferAccess(tcuFormat, m_caseDef.size.x(), m_caseDef.size.y(), 1u, (deUint8*) m_uCopy.colorBufferAlloc->getHostPtr() + layerOffset); 1237 const deUint32 colorIdx = layer % COLOR_TABLE_SIZE; 1238 if (m_imageIsIntegerFormat) 1239 tcu::clear(imageAccess, COLOR_TABLE_INT[colorIdx]); 1240 else 1241 tcu::clear(imageAccess, COLOR_TABLE_FLOAT[colorIdx]); 1242 layerOffset += layerSize; 1243 } 1244 1245 flushMappedMemoryRange(m_vk, m_device, m_uCopy.colorBufferAlloc->getMemory(), m_uCopy.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE); 1246 1247 // Prepare buffer and image for copy 1248 const VkBufferMemoryBarrier bufferInitBarrier = 1249 { 1250 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1251 DE_NULL, // const void* pNext; 1252 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; 1253 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 1254 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1255 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1256 *m_uCopy.colorBuffer, // VkBuffer buffer; 1257 0ull, // VkDeviceSize offset; 1258 VK_WHOLE_SIZE, // VkDeviceSize size; 1259 }; 1260 1261 const VkImageMemoryBarrier imageInitBarrier = 1262 { 1263 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1264 DE_NULL, // const void* pNext; 1265 0u, // VkAccessFlags outputMask; 1266 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags inputMask; 1267 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1268 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 1269 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1270 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 1271 *m_image, // VkImage image; 1272 makeColorSubresourceRange(0, m_caseDef.numLayers) // VkImageSubresourceRange subresourceRange; 1273 }; 1274 1275 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1276 0u, DE_NULL, 1u, &bufferInitBarrier, 1u, &imageInitBarrier); 1277 1278 // Copy buffer to image 1279 const VkImageSubresourceLayers subresource = 1280 { 1281 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 1282 0u, // deUint32 mipLevel; 1283 0u, // deUint32 baseArrayLayer; 1284 m_caseDef.numLayers, // deUint32 layerCount; 1285 }; 1286 1287 const VkBufferImageCopy region = 1288 { 1289 0ull, // VkDeviceSize bufferOffset; 1290 0u, // deUint32 bufferRowLength; 1291 0u, // deUint32 bufferImageHeight; 1292 subresource, // VkImageSubresourceLayers imageSubresource; 1293 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; 1294 makeExtent3D(m_caseDef.size), // VkExtent3D imageExtent; 1295 }; 1296 1297 m_vk.cmdCopyBufferToImage(*m_cmdBuffer, *m_uCopy.colorBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ®ion); 1298 1299 const VkImageMemoryBarrier imagePostInitBarrier = 1300 { 1301 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1302 DE_NULL, // const void* pNext; 1303 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags outputMask; 1304 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags inputMask; 1305 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 1306 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 1307 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1308 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 1309 *m_image, // VkImage image; 1310 makeColorSubresourceRange(0, m_caseDef.numLayers) // VkImageSubresourceRange subresourceRange; 1311 }; 1312 1313 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1314 0u, DE_NULL, 0u, DE_NULL, 1u, &imagePostInitBarrier); 1315 1316 m_imageLayoutAfterUpload = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 1317 m_imageUploadAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 1318} 1319 1320void UploadDownloadExecutor::uploadDraw(Context& context) 1321{ 1322 // Create vertex buffer 1323 { 1324 const vector<Vec4> vertices = genVertexData(m_caseDef); 1325 const VkDeviceSize vertexBufferSize = vertices.size() * sizeof(Vec4); 1326 1327 m_uDraw.vertexBuffer = makeBuffer(m_vk, m_device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); 1328 m_uDraw.vertexBufferAlloc = bindBuffer(m_vk, m_device, m_allocator, *m_uDraw.vertexBuffer, MemoryRequirement::HostVisible); 1329 deMemcpy(m_uDraw.vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize)); 1330 flushMappedMemoryRange(m_vk, m_device, m_uDraw.vertexBufferAlloc->getMemory(), m_uDraw.vertexBufferAlloc->getOffset(), vertexBufferSize); 1331 } 1332 1333 // Create attachments and pipelines for each image layer 1334 m_uDraw.pipelineLayout = makePipelineLayout(m_vk, m_device); 1335 m_uDraw.renderPass = makeRenderPass(m_vk, m_device, m_caseDef.viewFormat, m_caseDef.numLayers); 1336 m_uDraw.vertexModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawVert"), 0u); 1337 m_uDraw.fragmentModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawFrag"), 0u); 1338 1339 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx) 1340 { 1341 const vk::VkImageViewUsageCreateInfoKHR viewUsageCreateInfo = { 1342 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType 1343 DE_NULL, // const void* pNext 1344 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags usage; 1345 }; 1346 Move<VkImageView> imageView = makeImageView(m_vk, m_device, *m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, 1347 makeColorSubresourceRange(subpassNdx, 1), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL); 1348 m_uDraw.attachmentHandles.push_back(*imageView); 1349 m_uDraw.attachments.push_back(makeSharedPtr(imageView)); 1350 m_uDraw.pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(m_vk, m_device, *m_uDraw.pipelineLayout, *m_uDraw.renderPass, *m_uDraw.vertexModule, *m_uDraw.fragmentModule, 1351 m_caseDef.size.swizzle(0, 1), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, subpassNdx))); 1352 } 1353 1354 // Create framebuffer 1355 m_uDraw.framebuffer = makeFramebuffer(m_vk, m_device, *m_uDraw.renderPass, static_cast<deUint32>(m_uDraw.attachmentHandles.size()), &m_uDraw.attachmentHandles[0], m_caseDef.size.swizzle(0, 1)); 1356 1357 // Create command buffer 1358 { 1359 { 1360 vector<VkClearValue> clearValues (m_caseDef.numLayers, m_viewIsIntegerFormat ? REFERENCE_CLEAR_COLOR_INT[0] : REFERENCE_CLEAR_COLOR_FLOAT[0]); 1361 1362 const VkRect2D renderArea = 1363 { 1364 makeOffset2D(0, 0), 1365 makeExtent2D(m_caseDef.size.x(), m_caseDef.size.y()), 1366 }; 1367 1368 const VkRenderPassBeginInfo renderPassBeginInfo = 1369 { 1370 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1371 DE_NULL, // const void* pNext; 1372 *m_uDraw.renderPass, // VkRenderPass renderPass; 1373 *m_uDraw.framebuffer, // VkFramebuffer framebuffer; 1374 renderArea, // VkRect2D renderArea; 1375 static_cast<deUint32>(clearValues.size()), // deUint32 clearValueCount; 1376 &clearValues[0], // const VkClearValue* pClearValues; 1377 }; 1378 1379 m_vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 1380 } 1381 1382 // Render 1383 const VkDeviceSize vertexDataPerDraw = 4 * 2 * sizeof(Vec4); 1384 VkDeviceSize vertexBufferOffset = 0ull; 1385 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx) 1386 { 1387 if (subpassNdx != 0) 1388 m_vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); 1389 1390 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_uDraw.pipelines[subpassNdx]); 1391 1392 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_uDraw.vertexBuffer.get(), &vertexBufferOffset); 1393 m_vk.cmdDraw(*m_cmdBuffer, 4u, 1u, 0u, 0u); 1394 vertexBufferOffset += vertexDataPerDraw; 1395 } 1396 1397 m_vk.cmdEndRenderPass(*m_cmdBuffer); 1398 } 1399 1400 m_imageLayoutAfterUpload = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 1401 m_imageUploadAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 1402} 1403 1404void UploadDownloadExecutor::downloadCopy(Context& context, VkBuffer buffer) 1405{ 1406 (void) context; 1407 1408 copyImageToBuffer(*m_image, buffer, m_caseDef.size, m_imageUploadAccessMask, m_imageLayoutAfterUpload, m_caseDef.numLayers); 1409} 1410 1411void UploadDownloadExecutor::downloadTexture(Context& context, VkBuffer buffer) 1412{ 1413 // Create output image with download result 1414 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1415 m_dTex.outImage = makeImage(m_vk, m_device, 0u, VK_IMAGE_TYPE_2D, m_caseDef.viewFormat, m_caseDef.viewFormat, false, m_caseDef.size, 1u, m_caseDef.numLayers, usageFlags); 1416 m_dTex.outImageAlloc = bindImage(m_vk, m_device, m_allocator, *m_dTex.outImage, MemoryRequirement::Any); 1417 m_dTex.outImageView = makeImageView(m_vk, m_device, *m_dTex.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers)); 1418 1419 const vk::VkImageViewUsageCreateInfoKHR viewUsageCreateInfo = { 1420 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType 1421 DE_NULL, // const void* pNext 1422 VK_IMAGE_USAGE_SAMPLED_BIT, // VkImageUsageFlags usage; 1423 }; 1424 m_dTex.inImageView = makeImageView(m_vk, m_device, *m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, 1425 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL); 1426 m_dTex.sampler = makeSampler(m_vk, m_device); 1427 1428 // Setup compute pipeline 1429 m_dTex.descriptorPool = DescriptorPoolBuilder() 1430 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 1431 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) 1432 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 1433 1434 m_dTex.descriptorSetLayout = DescriptorSetLayoutBuilder() 1435 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT, &m_dTex.sampler.get()) 1436 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 1437 .build(m_vk, m_device); 1438 1439 m_dTex.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_dTex.descriptorSetLayout); 1440 m_dTex.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_dTex.descriptorPool, *m_dTex.descriptorSetLayout); 1441 m_dTex.inImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dTex.inImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 1442 m_dTex.outImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dTex.outImageView, VK_IMAGE_LAYOUT_GENERAL); 1443 m_dTex.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadTextureComp"), 0); 1444 m_dTex.computePipeline = makeComputePipeline(m_vk, m_device, *m_dTex.pipelineLayout, *m_dTex.computeModule, DE_NULL); 1445 1446 DescriptorSetUpdateBuilder() 1447 .writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &m_dTex.inImageDescriptorInfo) 1448 .writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dTex.outImageDescriptorInfo) 1449 .update(m_vk, m_device); 1450 1451 // Transition images for shader access (texture / imageStore) 1452 const VkImageMemoryBarrier imageBarriers[] = 1453 { 1454 { 1455 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1456 DE_NULL, // const void* pNext; 1457 (VkAccessFlags)m_imageUploadAccessMask, // VkAccessFlags srcAccessMask; 1458 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask; 1459 m_imageLayoutAfterUpload, // VkImageLayout oldLayout; 1460 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout; 1461 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1462 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 1463 *m_image, // VkImage image; 1464 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange; 1465 }, 1466 { 1467 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1468 DE_NULL, // const void* pNext; 1469 (VkAccessFlags)0, // VkAccessFlags srcAccessMask; 1470 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask; 1471 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1472 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout; 1473 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1474 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 1475 *m_dTex.outImage, // VkImage image; 1476 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange; 1477 } 1478 }; 1479 1480 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 1481 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers); 1482 1483 // Dispatch 1484 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.computePipeline); 1485 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.pipelineLayout, 0u, 1u, &m_dTex.descriptorSet.get(), 0u, DE_NULL); 1486 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers); 1487 1488 // Copy output image to color buffer 1489 copyImageToBuffer(*m_dTex.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL, m_caseDef.numLayers); 1490} 1491 1492void UploadDownloadExecutor::downloadLoad(Context& context, VkBuffer buffer) 1493{ 1494 // Create output image with download result 1495 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1496 m_dLoad.outImage = makeImage(m_vk, m_device, 0u, VK_IMAGE_TYPE_2D, m_caseDef.viewFormat, m_caseDef.viewFormat, false, m_caseDef.size, 1u, m_caseDef.numLayers, usageFlags); 1497 m_dLoad.outImageAlloc = bindImage(m_vk, m_device, m_allocator, *m_dLoad.outImage, MemoryRequirement::Any); 1498 m_dLoad.outImageView = makeImageView(m_vk, m_device, *m_dLoad.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers)); 1499 1500 const vk::VkImageViewUsageCreateInfoKHR viewUsageCreateInfo = { 1501 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType 1502 DE_NULL, // const void* pNext 1503 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage; 1504 }; 1505 m_dLoad.inImageView = makeImageView(m_vk, m_device, *m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, 1506 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL); 1507 1508 // Setup compute pipeline 1509 m_dLoad.descriptorPool = DescriptorPoolBuilder() 1510 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2u) 1511 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 1512 1513 m_dLoad.descriptorSetLayout = DescriptorSetLayoutBuilder() 1514 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 1515 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 1516 .build(m_vk, m_device); 1517 1518 m_dLoad.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_dLoad.descriptorSetLayout); 1519 m_dLoad.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_dLoad.descriptorPool, *m_dLoad.descriptorSetLayout); 1520 m_dLoad.inImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dLoad.inImageView, VK_IMAGE_LAYOUT_GENERAL); 1521 m_dLoad.outImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dLoad.outImageView, VK_IMAGE_LAYOUT_GENERAL); 1522 m_dLoad.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadLoadComp"), 0); 1523 m_dLoad.computePipeline = makeComputePipeline(m_vk, m_device, *m_dLoad.pipelineLayout, *m_dLoad.computeModule, DE_NULL); 1524 1525 DescriptorSetUpdateBuilder() 1526 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.inImageDescriptorInfo) 1527 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.outImageDescriptorInfo) 1528 .update(m_vk, m_device); 1529 1530 // Transition storage images for shader access (imageLoad/Store) 1531 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL; 1532 const VkImageMemoryBarrier imageBarriers[] = 1533 { 1534 { 1535 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1536 DE_NULL, // const void* pNext; 1537 (VkAccessFlags)m_imageUploadAccessMask, // VkAccessFlags srcAccessMask; 1538 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask; 1539 m_imageLayoutAfterUpload, // VkImageLayout oldLayout; 1540 requiredImageLayout, // VkImageLayout newLayout; 1541 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1542 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 1543 *m_image, // VkImage image; 1544 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange; 1545 }, 1546 { 1547 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1548 DE_NULL, // const void* pNext; 1549 (VkAccessFlags)0, // VkAccessFlags srcAccessMask; 1550 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask; 1551 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1552 requiredImageLayout, // VkImageLayout newLayout; 1553 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1554 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 1555 *m_dLoad.outImage, // VkImage image; 1556 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange; 1557 } 1558 }; 1559 1560 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 1561 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers); 1562 1563 // Dispatch 1564 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.computePipeline); 1565 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.pipelineLayout, 0u, 1u, &m_dLoad.descriptorSet.get(), 0u, DE_NULL); 1566 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers); 1567 1568 // Copy output image to color buffer 1569 copyImageToBuffer(*m_dLoad.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, requiredImageLayout, m_caseDef.numLayers); 1570} 1571 1572void UploadDownloadExecutor::copyImageToBuffer(VkImage sourceImage, 1573 VkBuffer buffer, 1574 const IVec3 size, 1575 const VkAccessFlags srcAccessMask, 1576 const VkImageLayout oldLayout, 1577 const deUint32 numLayers) 1578{ 1579 // Copy result to host visible buffer for inspection 1580 const VkImageMemoryBarrier imageBarrier = 1581 { 1582 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1583 DE_NULL, // const void* pNext; 1584 srcAccessMask, // VkAccessFlags outputMask; 1585 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags inputMask; 1586 oldLayout, // VkImageLayout oldLayout; 1587 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; 1588 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1589 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 1590 sourceImage, // VkImage image; 1591 makeColorSubresourceRange(0, numLayers) // VkImageSubresourceRange subresourceRange; 1592 }; 1593 1594 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1595 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier); 1596 1597 const VkImageSubresourceLayers subresource = 1598 { 1599 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 1600 0u, // deUint32 mipLevel; 1601 0u, // deUint32 baseArrayLayer; 1602 numLayers, // deUint32 layerCount; 1603 }; 1604 1605 const VkBufferImageCopy region = 1606 { 1607 0ull, // VkDeviceSize bufferOffset; 1608 0u, // deUint32 bufferRowLength; 1609 0u, // deUint32 bufferImageHeight; 1610 subresource, // VkImageSubresourceLayers imageSubresource; 1611 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; 1612 makeExtent3D(size), // VkExtent3D imageExtent; 1613 }; 1614 1615 m_vk.cmdCopyImageToBuffer(*m_cmdBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, ®ion); 1616 1617 const VkBufferMemoryBarrier bufferBarrier = 1618 { 1619 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1620 DE_NULL, // const void* pNext; 1621 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1622 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 1623 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1624 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1625 buffer, // VkBuffer buffer; 1626 0ull, // VkDeviceSize offset; 1627 VK_WHOLE_SIZE, // VkDeviceSize size; 1628 }; 1629 1630 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1631 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL); 1632} 1633 1634bool isStorageImageExtendedFormat (const VkFormat format) 1635{ 1636 switch (format) 1637 { 1638 case VK_FORMAT_R32G32_SFLOAT: 1639 case VK_FORMAT_R32G32_SINT: 1640 case VK_FORMAT_R32G32_UINT: 1641 case VK_FORMAT_R16G16B16A16_UNORM: 1642 case VK_FORMAT_R16G16B16A16_SNORM: 1643 case VK_FORMAT_R16G16_SFLOAT: 1644 case VK_FORMAT_R16G16_UNORM: 1645 case VK_FORMAT_R16G16_SNORM: 1646 case VK_FORMAT_R16G16_SINT: 1647 case VK_FORMAT_R16G16_UINT: 1648 case VK_FORMAT_R16_SFLOAT: 1649 case VK_FORMAT_R16_UNORM: 1650 case VK_FORMAT_R16_SNORM: 1651 case VK_FORMAT_R16_SINT: 1652 case VK_FORMAT_R16_UINT: 1653 case VK_FORMAT_R8G8_UNORM: 1654 case VK_FORMAT_R8G8_SNORM: 1655 case VK_FORMAT_R8G8_SINT: 1656 case VK_FORMAT_R8G8_UINT: 1657 case VK_FORMAT_R8_UNORM: 1658 case VK_FORMAT_R8_SNORM: 1659 case VK_FORMAT_R8_SINT: 1660 case VK_FORMAT_R8_UINT: 1661 return true; 1662 1663 default: 1664 return false; 1665 } 1666} 1667 1668tcu::TestStatus testMutable (Context& context, const CaseDef caseDef) 1669{ 1670 const DeviceInterface& vk = context.getDeviceInterface(); 1671 const InstanceInterface& vki = context.getInstanceInterface(); 1672 const VkDevice device = context.getDevice(); 1673 const VkPhysicalDevice physDevice = context.getPhysicalDevice(); 1674 Allocator& allocator = context.getDefaultAllocator(); 1675 1676 // If this is a VK_KHR_image_format_list test, check that the extension is supported 1677 if (caseDef.isFormatListTest && !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_image_format_list")) 1678 TCU_THROW(NotSupportedError, "VK_KHR_image_format_list not supported"); 1679 1680 // Check required features on the format for the required upload/download methods 1681 VkFormatProperties imageFormatProps, viewFormatProps; 1682 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.imageFormat, &imageFormatProps); 1683 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.viewFormat, &viewFormatProps); 1684 1685 VkFormatFeatureFlags viewFormatFeatureFlags = 0u; 1686 switch (caseDef.upload) 1687 { 1688 case UPLOAD_DRAW: 1689 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; 1690 break; 1691 case UPLOAD_STORE: 1692 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; 1693 break; 1694 default: 1695 DE_ASSERT("Invalid upload method"); 1696 break; 1697 } 1698 switch (caseDef.download) 1699 { 1700 case DOWNLOAD_TEXTURE: 1701 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; 1702 // For the texture case we write the samples read to a separate output image with the same view format 1703 // so we need to check that we can also use the view format for storage 1704 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; 1705 break; 1706 case DOWNLOAD_LOAD: 1707 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; 1708 break; 1709 default: 1710 DE_ASSERT("Invalid download method"); 1711 break; 1712 } 1713 1714 if ((viewFormatFeatureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) && 1715 isStorageImageExtendedFormat(caseDef.viewFormat) && 1716 !getPhysicalDeviceFeatures(vki, physDevice).shaderStorageImageExtendedFormats) 1717 { 1718 TCU_THROW(NotSupportedError, "View format requires shaderStorageImageExtended"); 1719 } 1720 1721 if ((viewFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags) 1722 TCU_THROW(NotSupportedError, "View format doesn't support upload/download method"); 1723 1724 // We don't use the base image for anything other than transfer 1725 // operations so there are no features to check. However, The Vulkan 1726 // 1.0 spec does not allow us to create an image view with usage that 1727 // is not supported by the main format. With VK_KHR_maintenance2, we 1728 // can do this via VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR. 1729 if ((imageFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags && 1730 !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance2")) 1731 { 1732 TCU_THROW(NotSupportedError, "Image format doesn't support upload/download method"); 1733 } 1734 1735 // Create a color buffer for host-inspection of results 1736 // For the Copy download method, this is the target of the download, for other 1737 // download methods, pixel data will be copied to this buffer from the download 1738 // target 1739 const VkDeviceSize colorBufferSize = caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat)); 1740 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)); 1741 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible)); 1742 deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize)); 1743 flushMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE); 1744 1745 // Execute the test 1746 UploadDownloadExecutor executor(context, caseDef); 1747 executor.run(context, *colorBuffer); 1748 1749 // Verify results 1750 { 1751 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE); 1752 1753 // For verification purposes, we use the format of the upload to generate the expected image 1754 const VkFormat format = caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat; 1755 const tcu::TextureFormat tcuFormat = mapVkFormat(format); 1756 const bool isIntegerFormat = isUintFormat(format) || isIntFormat(format); 1757 const tcu::ConstPixelBufferAccess resultImage (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr()); 1758 tcu::TextureLevel textureLevel (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers); 1759 const tcu::PixelBufferAccess expectedImage = textureLevel.getAccess(); 1760 generateExpectedImage(expectedImage, caseDef); 1761 1762 bool ok; 1763 if (isIntegerFormat) 1764 ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT); 1765 else 1766 ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT); 1767 return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail"); 1768 } 1769} 1770 1771tcu::TestCaseGroup* createImageMutableTests (TestContext& testCtx) 1772{ 1773 de::MovePtr<TestCaseGroup> testGroup (new TestCaseGroup(testCtx, "mutable", "Cases with mutable images")); 1774 for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx) 1775 { 1776 const Texture& texture = s_textures[textureNdx]; 1777 de::MovePtr<tcu::TestCaseGroup> groupByImageViewType (new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), "")); 1778 1779 for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++imageFormatNdx) 1780 for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++viewFormatNdx) 1781 { 1782 if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_formats[imageFormatNdx], s_formats[viewFormatNdx])) 1783 { 1784 for (int upload = 0; upload < UPLOAD_LAST; upload++) 1785 for (int download = 0; download < DOWNLOAD_LAST; download++) 1786 { 1787 CaseDef caseDef = 1788 { 1789 texture.type(), 1790 texture.layerSize(), 1791 static_cast<deUint32>(texture.numLayers()), 1792 s_formats[imageFormatNdx], 1793 s_formats[viewFormatNdx], 1794 static_cast<enum Upload>(upload), 1795 static_cast<enum Download>(download), 1796 false 1797 }; 1798 1799 std::string caseName = getFormatShortString(s_formats[imageFormatNdx]) + "_" + getFormatShortString(s_formats[viewFormatNdx]) + 1800 "_" + getUploadString(upload) + "_" + getDownloadString(download); 1801 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", initPrograms, testMutable, caseDef); 1802 1803 caseDef.isFormatListTest = true; 1804 caseName += "_format_list"; 1805 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", initPrograms, testMutable, caseDef); 1806 } 1807 } 1808 } 1809 1810 testGroup->addChild(groupByImageViewType.release()); 1811 } 1812 1813 return testGroup.release(); 1814} 1815 1816} // image 1817} // vkt 1818