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