1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Tests for mutable images
22 *//*--------------------------------------------------------------------*/
24 #include "vktImageMutableTests.hpp"
25 #include "vktImageLoadStoreUtil.hpp"
26 #include "vktTestCaseUtil.hpp"
27 #include "vktImageTexture.hpp"
28 #include "vktCustomInstancesDevices.hpp"
30 #include "vkBuilderUtil.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vkObjUtil.hpp"
37 #include "vkPlatform.hpp"
38 #include "vkWsiUtil.hpp"
39 #include "vkDeviceUtil.hpp"
40 #include "vkSafetyCriticalUtil.hpp"
42 #include "deUniquePtr.hpp"
43 #include "deSharedPtr.hpp"
45 #include "tcuImageCompare.hpp"
46 #include "tcuTestLog.hpp"
47 #include "tcuTextureUtil.hpp"
48 #include "tcuPlatform.hpp"
49 #include "tcuCommandLine.hpp"
56 using namespace vk::wsi;
69 typedef SharedPtr<Unique<VkPipeline> > SharedPtrVkPipeline;
70 typedef SharedPtr<Unique<VkImageView> > SharedPtrVkImageView;
73 inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move)
75 return SharedPtr<Unique<T> >(new Unique<T>(move));
93 std::string getUploadString (const int upload)
95 const char* strs[] = { "clear", "copy", "store", "draw" };
99 std::string getDownloadString (const int download)
101 const char* strs[] = { "copy", "load", "texture" };
102 return strs[download];
110 VkFormat imageFormat;
113 enum Download download;
114 bool isFormatListTest;
115 bool isSwapchainImageTest;
119 static const deUint32 COLOR_TABLE_SIZE = 4;
121 // Reference color values for float color rendering. Values have been chosen
122 // so that when the bit patterns are reinterpreted as a 16-bit float, we do not
123 // run into NaN / inf / denorm values.
124 static const Vec4 COLOR_TABLE_FLOAT[COLOR_TABLE_SIZE] =
126 Vec4(0.00f, 0.40f, 0.80f, 0.10f),
127 Vec4(0.50f, 0.10f, 0.90f, 0.20f),
128 Vec4(0.20f, 0.60f, 1.00f, 0.30f),
129 Vec4(0.30f, 0.70f, 0.00f, 0.40f),
132 // Reference color values for integer color rendering. We avoid negative
133 // values (even for SINT formats) to avoid the situation where sign extension
134 // leads to NaN / inf values when they are reinterpreted with a float
136 static const IVec4 COLOR_TABLE_INT[COLOR_TABLE_SIZE] =
138 IVec4(0x70707070, 0x3C3C3C3C, 0x65656565, 0x29292929),
139 IVec4(0x3C3C3C3C, 0x65656565, 0x29292929, 0x70707070),
140 IVec4(0x29292929, 0x70707070, 0x3C3C3C3C, 0x65656565),
141 IVec4(0x65656565, 0x29292929, 0x70707070, 0x3C3C3C3C),
144 // Reference clear colors created from the color table values
145 static const VkClearValue REFERENCE_CLEAR_COLOR_FLOAT[COLOR_TABLE_SIZE] =
147 makeClearValueColorF32(COLOR_TABLE_FLOAT[0].x(), COLOR_TABLE_FLOAT[0].y(), COLOR_TABLE_FLOAT[0].z(), COLOR_TABLE_FLOAT[0].w()),
148 makeClearValueColorF32(COLOR_TABLE_FLOAT[1].x(), COLOR_TABLE_FLOAT[1].y(), COLOR_TABLE_FLOAT[1].z(), COLOR_TABLE_FLOAT[1].w()),
149 makeClearValueColorF32(COLOR_TABLE_FLOAT[2].x(), COLOR_TABLE_FLOAT[2].y(), COLOR_TABLE_FLOAT[2].z(), COLOR_TABLE_FLOAT[2].w()),
150 makeClearValueColorF32(COLOR_TABLE_FLOAT[3].x(), COLOR_TABLE_FLOAT[3].y(), COLOR_TABLE_FLOAT[3].z(), COLOR_TABLE_FLOAT[3].w()),
153 static const Texture s_textures[] =
155 Texture(IMAGE_TYPE_2D, tcu::IVec3(32, 32, 1), 1),
156 Texture(IMAGE_TYPE_2D_ARRAY, tcu::IVec3(32, 32, 1), 4),
159 static VkClearValue getClearValueInt(const CaseDef& caseDef, deUint32 colorTableIndex)
161 VkClearValue clearValue;
162 deUint32 channelMask = 0;
164 if (caseDef.upload == UPLOAD_DRAW)
166 // We use this mask to get small color values in the vertex buffer and
167 // avoid possible round off errors from int-to-float conversions.
173 tcu::TextureFormat tcuFormat;
175 // Select a mask such that no integer-based color values end up
176 // reinterpreted as NaN/Inf/denorm values.
177 if (caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY)
178 format = caseDef.imageFormat;
180 format = caseDef.viewFormat;
182 tcuFormat = mapVkFormat(format);
184 switch (getChannelSize(tcuFormat.type))
190 channelMask = 0xFFFFu;
193 channelMask = 0xFFFFFFFFu;
200 clearValue.color.int32[0] = COLOR_TABLE_INT[colorTableIndex].x() & channelMask;
201 clearValue.color.int32[1] = COLOR_TABLE_INT[colorTableIndex].y() & channelMask;
202 clearValue.color.int32[2] = COLOR_TABLE_INT[colorTableIndex].z() & channelMask;
203 clearValue.color.int32[3] = COLOR_TABLE_INT[colorTableIndex].w() & channelMask;
208 VkImageType getImageType (const ImageType textureImageType)
210 switch (textureImageType)
213 case IMAGE_TYPE_2D_ARRAY:
214 return VK_IMAGE_TYPE_2D;
218 return VK_IMAGE_TYPE_LAST;
222 VkImageViewType getImageViewType (const ImageType textureImageType)
224 switch (textureImageType)
227 return VK_IMAGE_VIEW_TYPE_2D;
228 case IMAGE_TYPE_2D_ARRAY:
229 return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
233 return VK_IMAGE_VIEW_TYPE_LAST;
237 static const VkFormat s_formats[] =
239 VK_FORMAT_R32G32B32A32_SFLOAT,
240 VK_FORMAT_R16G16B16A16_SFLOAT,
241 VK_FORMAT_R32G32_SFLOAT,
242 VK_FORMAT_R16G16_SFLOAT,
243 VK_FORMAT_R32_SFLOAT,
245 VK_FORMAT_R32G32B32A32_UINT,
246 VK_FORMAT_R16G16B16A16_UINT,
247 VK_FORMAT_R8G8B8A8_UINT,
248 VK_FORMAT_R32G32_UINT,
249 VK_FORMAT_R16G16_UINT,
252 VK_FORMAT_R32G32B32A32_SINT,
253 VK_FORMAT_R16G16B16A16_SINT,
254 VK_FORMAT_R8G8B8A8_SINT,
255 VK_FORMAT_R32G32_SINT,
256 VK_FORMAT_R16G16_SINT,
259 VK_FORMAT_R8G8B8A8_UNORM,
260 VK_FORMAT_R8G8B8A8_SNORM,
261 VK_FORMAT_R8G8B8A8_SRGB,
262 VK_FORMAT_B8G8R8A8_UNORM,
263 VK_FORMAT_B8G8R8A8_SNORM,
264 VK_FORMAT_B8G8R8A8_SRGB,
267 static const VkFormat s_swapchainFormats[] =
269 VK_FORMAT_R8G8B8A8_UNORM,
270 VK_FORMAT_R8G8B8A8_SNORM,
271 VK_FORMAT_R8G8B8A8_SRGB,
272 VK_FORMAT_B8G8R8A8_UNORM,
273 VK_FORMAT_B8G8R8A8_SNORM,
274 VK_FORMAT_B8G8R8A8_SRGB,
277 bool isSRGBConversionRequired(const CaseDef& caseDef)
279 bool required = false;
281 if (isSRGB(mapVkFormat(caseDef.imageFormat)))
283 if (caseDef.upload == UPLOAD_CLEAR)
289 if (isSRGB(mapVkFormat(caseDef.viewFormat)))
291 if (caseDef.upload == UPLOAD_DRAW || caseDef.upload == UPLOAD_STORE)
301 inline bool formatsAreCompatible (const VkFormat format0, const VkFormat format1)
303 return format0 == format1 || mapVkFormat(format0).getPixelSize() == mapVkFormat(format1).getPixelSize();
306 std::string getColorFormatStr (const int numComponents, const bool isUint, const bool isSint)
308 std::ostringstream str;
309 if (numComponents == 1)
310 str << (isUint ? "uint" : isSint ? "int" : "float");
312 str << (isUint ? "u" : isSint ? "i" : "") << "vec" << numComponents;
317 std::string getShaderSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
319 std::ostringstream samplerType;
321 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
323 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
328 case VK_IMAGE_VIEW_TYPE_2D:
329 samplerType << "sampler2D";
332 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
333 samplerType << "sampler2DArray";
337 DE_FATAL("Ivalid image view type");
341 return samplerType.str();
344 void initPrograms (SourceCollections& programCollection, const CaseDef caseDef)
346 if (caseDef.upload == UPLOAD_DRAW)
349 std::ostringstream src;
350 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
352 << "layout(location = 0) in vec4 in_position;\n"
353 << "layout(location = 1) in vec4 in_color;\n"
354 << "layout(location = 0) out vec4 out_color;\n"
356 << "out gl_PerVertex {\n"
357 << " vec4 gl_Position;\n"
360 << "void main(void)\n"
362 << " gl_Position = in_position;\n"
363 << " out_color = in_color;\n"
366 programCollection.glslSources.add("uploadDrawVert") << glu::VertexSource(src.str());
370 const int numComponents = getNumUsedChannels(mapVkFormat(caseDef.viewFormat).order);
371 const bool isUint = isUintFormat(caseDef.viewFormat);
372 const bool isSint = isIntFormat(caseDef.viewFormat);
373 const std::string colorFormat = getColorFormatStr(numComponents, isUint, isSint);
375 std::ostringstream src;
376 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
378 << "layout(location = 0) in vec4 in_color;\n"
379 << "layout(location = 0) out " << colorFormat << " out_color;\n"
381 << "void main(void)\n"
383 << " out_color = " << colorFormat << "("
384 << (numComponents == 1 ? "in_color.r" :
385 numComponents == 2 ? "in_color.rg" :
386 numComponents == 3 ? "in_color.rgb" : "in_color")
390 programCollection.glslSources.add("uploadDrawFrag") << glu::FragmentSource(src.str());
394 if (caseDef.upload == UPLOAD_STORE)
396 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
397 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
398 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
399 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
400 const bool isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);
402 std::ostringstream src;
403 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
405 << "layout (local_size_x = 1) in;\n"
407 << "layout(binding=0, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " u_image;\n"
409 << "const " << colorTypeStr << " colorTable[] = " << colorTypeStr << "[](\n";
410 for (deUint32 idx = 0; idx < COLOR_TABLE_SIZE; idx++)
414 const VkClearValue clearValue = getClearValueInt(caseDef, idx);
416 src << " " << colorTypeStr << "(" << clearValue.color.int32[0] << ", " << clearValue.color.int32[1] << ", " << clearValue.color.int32[2] << ", " << clearValue.color.int32[3] << ")";
419 src << " " << colorTypeStr << "(" << COLOR_TABLE_FLOAT[idx].x() << ", " << COLOR_TABLE_FLOAT[idx].y() << ", " << COLOR_TABLE_FLOAT[idx].z() << ", " << COLOR_TABLE_FLOAT[idx].w() << ")";
420 if (idx < COLOR_TABLE_SIZE - 1)
426 << "void main(void)\n"
428 if (caseDef.imageType == IMAGE_TYPE_2D)
430 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
434 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
435 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
437 src << " " << colorTypeStr << " color = colorTable[gl_GlobalInvocationID.z];\n"
438 << " imageStore(u_image, pos, color);\n"
441 programCollection.glslSources.add("uploadStoreComp") << glu::ComputeSource(src.str());
444 if (caseDef.download == DOWNLOAD_LOAD)
446 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
447 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
448 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
449 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
451 std::ostringstream src;
452 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
454 << "layout (local_size_x = 1) in;\n"
456 << "layout(binding=0, " << imageFormatStr << ") readonly uniform " << imageTypeStr << " in_image;\n"
457 << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
459 << "void main(void)\n"
461 if (caseDef.imageType == IMAGE_TYPE_2D)
463 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
467 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
468 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
470 src << " imageStore(out_image, pos, imageLoad(in_image, pos));\n"
473 programCollection.glslSources.add("downloadLoadComp") << glu::ComputeSource(src.str());
476 if (caseDef.download == DOWNLOAD_TEXTURE)
478 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
479 const VkImageViewType viewType = getImageViewType(caseDef.imageType);
480 const std::string samplerTypeStr = getShaderSamplerType(tcuFormat, viewType);
481 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
482 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
483 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
485 std::ostringstream src;
486 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
488 << "layout (local_size_x = 1) in;\n"
490 << "layout(binding=0) uniform " << samplerTypeStr << " u_tex;\n"
491 << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
493 << "void main(void)\n"
495 if (caseDef.imageType == IMAGE_TYPE_2D)
497 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
501 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
502 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
504 src << " imageStore(out_image, pos, texelFetch(u_tex, pos, 0));\n"
507 programCollection.glslSources.add("downloadTextureComp") << glu::ComputeSource(src.str());
511 Move<VkImage> makeImage (const DeviceInterface& vk,
512 const VkDevice device,
513 VkImageCreateFlags flags,
514 VkImageType imageType,
515 const VkFormat format,
516 const VkFormat viewFormat,
517 const bool useImageFormatList,
519 const deUint32 numMipLevels,
520 const deUint32 numLayers,
521 const VkImageUsageFlags usage)
523 const VkFormat formatList[2] =
529 const VkImageFormatListCreateInfo formatListInfo =
531 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO, // VkStructureType sType;
532 DE_NULL, // const void* pNext;
533 2u, // deUint32 viewFormatCount
534 formatList // const VkFormat* pViewFormats
537 const VkImageCreateInfo imageParams =
539 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
540 useImageFormatList ? &formatListInfo : DE_NULL, // const void* pNext;
541 flags, // VkImageCreateFlags flags;
542 imageType, // VkImageType imageType;
543 format, // VkFormat format;
544 makeExtent3D(size), // VkExtent3D extent;
545 numMipLevels, // deUint32 mipLevels;
546 numLayers, // deUint32 arrayLayers;
547 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
548 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
549 usage, // VkImageUsageFlags usage;
550 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
551 0u, // deUint32 queueFamilyIndexCount;
552 DE_NULL, // const deUint32* pQueueFamilyIndices;
553 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
555 return createImage(vk, device, &imageParams);
558 inline VkImageSubresourceRange makeColorSubresourceRange (const int baseArrayLayer, const int layerCount)
560 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, static_cast<deUint32>(baseArrayLayer), static_cast<deUint32>(layerCount));
563 Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice device)
565 const VkSamplerCreateInfo samplerParams =
567 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
568 DE_NULL, // const void* pNext;
569 (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags;
570 VK_FILTER_NEAREST, // VkFilter magFilter;
571 VK_FILTER_NEAREST, // VkFilter minFilter;
572 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
573 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
574 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
575 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
576 0.0f, // float mipLodBias;
577 VK_FALSE, // VkBool32 anisotropyEnable;
578 1.0f, // float maxAnisotropy;
579 VK_FALSE, // VkBool32 compareEnable;
580 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
581 0.0f, // float minLod;
582 0.0f, // float maxLod;
583 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
584 VK_FALSE, // VkBool32 unnormalizedCoordinates;
587 return createSampler(vk, device, &samplerParams);
590 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
591 const VkDevice device,
592 const VkPipelineLayout pipelineLayout,
593 const VkRenderPass renderPass,
594 const VkShaderModule vertexModule,
595 const VkShaderModule fragmentModule,
596 const IVec2& renderSize,
597 const VkPrimitiveTopology topology,
598 const deUint32 subpass)
600 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
601 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
603 const VkVertexInputBindingDescription vertexInputBindingDescription =
605 0u, // deUint32 binding;
606 (deUint32)(2 * sizeof(Vec4)), // deUint32 stride;
607 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
610 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
613 0u, // deUint32 location;
614 0u, // deUint32 binding;
615 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
616 0u, // deUint32 offset;
619 1u, // deUint32 location;
620 0u, // deUint32 binding;
621 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
622 (deUint32)sizeof(Vec4), // deUint32 offset;
626 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
628 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
629 DE_NULL, // const void* pNext;
630 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
631 1u, // deUint32 vertexBindingDescriptionCount;
632 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
633 2u, // deUint32 vertexAttributeDescriptionCount;
634 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
637 return vk::makeGraphicsPipeline(vk, // const DeviceInterface& vk
638 device, // const VkDevice device
639 pipelineLayout, // const VkPipelineLayout pipelineLayout
640 vertexModule, // const VkShaderModule vertexShaderModule
641 DE_NULL, // const VkShaderModule tessellationControlModule
642 DE_NULL, // const VkShaderModule tessellationEvalModule
643 DE_NULL, // const VkShaderModule geometryShaderModule
644 fragmentModule, // const VkShaderModule fragmentShaderModule
645 renderPass, // const VkRenderPass renderPass
646 viewports, // const std::vector<VkViewport>& viewports
647 scissors, // const std::vector<VkRect2D>& scissors
648 topology, // const VkPrimitiveTopology topology
649 subpass, // const deUint32 subpass
650 0u, // const deUint32 patchControlPoints
651 &vertexInputStateCreateInfo); // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
654 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
655 const VkDevice device,
656 const VkFormat colorFormat,
657 const deUint32 numLayers)
659 const VkAttachmentDescription colorAttachmentDescription =
661 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
662 colorFormat, // VkFormat format;
663 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
664 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
665 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
666 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
667 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
668 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
669 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
671 vector<VkAttachmentDescription> attachmentDescriptions(numLayers, colorAttachmentDescription);
673 // Create a subpass for each attachment (each attachement is a layer of an arrayed image).
674 vector<VkAttachmentReference> colorAttachmentReferences (numLayers);
675 vector<VkSubpassDescription> subpasses;
677 // Ordering here must match the framebuffer attachments
678 for (deUint32 i = 0; i < numLayers; ++i)
680 const VkAttachmentReference attachmentRef =
682 i, // deUint32 attachment;
683 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
686 colorAttachmentReferences[i] = attachmentRef;
688 const VkSubpassDescription subpassDescription =
690 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
691 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
692 0u, // deUint32 inputAttachmentCount;
693 DE_NULL, // const VkAttachmentReference* pInputAttachments;
694 1u, // deUint32 colorAttachmentCount;
695 &colorAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments;
696 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
697 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
698 0u, // deUint32 preserveAttachmentCount;
699 DE_NULL // const deUint32* pPreserveAttachments;
701 subpasses.push_back(subpassDescription);
704 const VkRenderPassCreateInfo renderPassInfo =
706 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
707 DE_NULL, // const void* pNext;
708 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
709 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
710 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
711 static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount;
712 &subpasses[0], // const VkSubpassDescription* pSubpasses;
713 0u, // deUint32 dependencyCount;
714 DE_NULL // const VkSubpassDependency* pDependencies;
717 return createRenderPass(vk, device, &renderPassInfo);
720 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
722 return allocateCommandBuffer(vk, device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
725 vector<Vec4> genVertexData (const CaseDef& caseDef)
727 vector<Vec4> vectorData;
728 const bool isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);
730 for (deUint32 z = 0; z < caseDef.numLayers; z++)
732 const deUint32 colorIdx = z % COLOR_TABLE_SIZE;
737 const VkClearValue clearValue = getClearValueInt(caseDef, colorIdx);
738 const IVec4 colorInt (clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);
740 color = colorInt.cast<float>();
744 color = COLOR_TABLE_FLOAT[colorIdx];
747 vectorData.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
748 vectorData.push_back(color);
749 vectorData.push_back(Vec4(-1.0f, 1.0f, 0.0f, 1.0f));
750 vectorData.push_back(color);
751 vectorData.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
752 vectorData.push_back(color);
753 vectorData.push_back(Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
754 vectorData.push_back(color);
760 void generateExpectedImage(const tcu::PixelBufferAccess& image, const CaseDef& caseDef)
762 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(image.getFormat().type);
763 const bool isIntegerFormat = channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
764 const IVec2 size = caseDef.size.swizzle(0, 1);
766 for (int z = 0; z < static_cast<int>(caseDef.numLayers); z++)
768 const deUint32 colorIdx = z % COLOR_TABLE_SIZE;
769 for (int y = 0; y < size.y(); y++)
770 for (int x = 0; x < size.x(); x++)
774 const VkClearValue clearValue = getClearValueInt(caseDef, colorIdx);
775 const IVec4 colorInt (clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);
777 image.setPixel(colorInt, x, y, z);
780 if(isSRGBConversionRequired(caseDef))
781 image.setPixel(tcu::linearToSRGB(COLOR_TABLE_FLOAT[colorIdx]), x, y, z);
783 image.setPixel(COLOR_TABLE_FLOAT[colorIdx], x, y, z);
788 VkImageUsageFlags getImageUsageForTestCase (const CaseDef& caseDef)
790 VkImageUsageFlags flags = 0u;
792 switch (caseDef.upload)
795 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
798 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
801 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
804 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
807 DE_FATAL("Invalid upload method");
811 switch (caseDef.download)
813 case DOWNLOAD_TEXTURE:
814 flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
817 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
820 flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
823 DE_FATAL("Invalid download method");
827 // We can only create a view for the image if it is going to be used for any of these usages,
828 // so let's make sure that we have at least one of them.
829 VkImageUsageFlags viewRequiredFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
830 if (!(flags & viewRequiredFlags))
831 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
836 // Executes a combination of upload/download methods
837 class UploadDownloadExecutor
840 UploadDownloadExecutor(Context& context, VkDevice device, VkQueue queue, deUint32 queueFamilyIndex, const CaseDef& caseSpec) :
842 m_haveMaintenance2(context.isDeviceFunctionalitySupported("VK_KHR_maintenance2")),
843 m_vk(context.getDeviceInterface()),
846 m_queueFamilyIndex(queueFamilyIndex),
847 m_allocator(context.getDeviceInterface(), device,
848 getPhysicalDeviceMemoryProperties(context.getInstanceInterface(),
849 context.getPhysicalDevice()))
853 void runSwapchain(Context& context, VkBuffer buffer, VkImage image);
855 void run(Context& context, VkBuffer buffer);
858 void uploadClear(Context& context);
859 void uploadStore(Context& context);
860 void uploadCopy(Context& context);
861 void uploadDraw(Context& context);
862 void downloadCopy(Context& context, VkBuffer buffer);
863 void downloadTexture(Context& context, VkBuffer buffer);
864 void downloadLoad(Context& context, VkBuffer buffer);
866 void copyImageToBuffer(VkImage image,
869 const VkAccessFlags srcAccessMask,
870 const VkImageLayout oldLayout,
871 const deUint32 numLayers);
873 const CaseDef& m_caseDef;
875 bool m_haveMaintenance2;
877 const DeviceInterface& m_vk;
878 const VkDevice m_device;
879 const VkQueue m_queue;
880 const deUint32 m_queueFamilyIndex;
881 SimpleAllocator m_allocator;
883 Move<VkCommandPool> m_cmdPool;
884 Move<VkCommandBuffer> m_cmdBuffer;
886 bool m_imageIsIntegerFormat;
887 bool m_viewIsIntegerFormat;
889 // Target image for upload paths
891 Move<VkImage> m_imageHolder;
892 MovePtr<Allocation> m_imageAlloc;
897 Move<VkBuffer> colorBuffer;
898 VkDeviceSize colorBufferSize;
899 MovePtr<Allocation> colorBufferAlloc;
905 Move<VkBuffer> vertexBuffer;
906 MovePtr<Allocation> vertexBufferAlloc;
907 Move<VkPipelineLayout> pipelineLayout;
908 Move<VkRenderPass> renderPass;
909 Move<VkShaderModule> vertexModule;
910 Move<VkShaderModule> fragmentModule;
911 vector<SharedPtrVkImageView> attachments;
912 vector<VkImageView> attachmentHandles;
913 vector<SharedPtrVkPipeline> pipelines;
914 Move<VkFramebuffer> framebuffer;
920 Move<VkDescriptorPool> descriptorPool;
921 Move<VkPipelineLayout> pipelineLayout;
922 Move<VkDescriptorSetLayout> descriptorSetLayout;
923 Move<VkDescriptorSet> descriptorSet;
924 VkDescriptorImageInfo imageDescriptorInfo;
925 Move<VkShaderModule> computeModule;
926 Move<VkPipeline> computePipeline;
927 Move<VkImageView> imageView;
933 Move<VkDescriptorPool> descriptorPool;
934 Move<VkPipelineLayout> pipelineLayout;
935 Move<VkDescriptorSetLayout> descriptorSetLayout;
936 Move<VkDescriptorSet> descriptorSet;
937 Move<VkShaderModule> computeModule;
938 Move<VkPipeline> computePipeline;
939 Move<VkImageView> inImageView;
940 VkDescriptorImageInfo inImageDescriptorInfo;
941 Move<VkImage> outImage;
942 Move<VkImageView> outImageView;
943 MovePtr<Allocation> outImageAlloc;
944 VkDescriptorImageInfo outImageDescriptorInfo;
950 Move<VkDescriptorPool> descriptorPool;
951 Move<VkPipelineLayout> pipelineLayout;
952 Move<VkDescriptorSetLayout> descriptorSetLayout;
953 Move<VkDescriptorSet> descriptorSet;
954 Move<VkShaderModule> computeModule;
955 Move<VkPipeline> computePipeline;
956 Move<VkImageView> inImageView;
957 VkDescriptorImageInfo inImageDescriptorInfo;
958 Move<VkSampler> sampler;
959 Move<VkImage> outImage;
960 Move<VkImageView> outImageView;
961 MovePtr<Allocation> outImageAlloc;
962 VkDescriptorImageInfo outImageDescriptorInfo;
965 VkImageLayout m_imageLayoutAfterUpload;
966 VkAccessFlagBits m_imageUploadAccessMask;
970 void UploadDownloadExecutor::runSwapchain(Context& context, VkBuffer buffer, VkImage image)
972 m_imageIsIntegerFormat = isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat);
973 m_viewIsIntegerFormat = isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat);
975 m_cmdPool = createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex);
976 m_cmdBuffer = makeCommandBuffer(m_vk, m_device, *m_cmdPool);
977 beginCommandBuffer(m_vk, *m_cmdBuffer);
981 switch (m_caseDef.upload)
987 uploadStore(context);
990 uploadClear(context);
996 DE_FATAL("Unsupported upload method");
999 switch (m_caseDef.download)
1002 downloadCopy(context, buffer);
1005 downloadLoad(context, buffer);
1007 case DOWNLOAD_TEXTURE:
1008 downloadTexture(context, buffer);
1011 DE_FATAL("Unsupported download method");
1014 endCommandBuffer(m_vk, *m_cmdBuffer);
1015 submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer);
1019 void UploadDownloadExecutor::run(Context& context, VkBuffer buffer)
1021 m_imageIsIntegerFormat = isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat);
1022 m_viewIsIntegerFormat = isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat);
1024 m_cmdPool = createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex);
1025 m_cmdBuffer = makeCommandBuffer(m_vk, m_device, *m_cmdPool);
1026 beginCommandBuffer(m_vk, *m_cmdBuffer);
1028 const VkImageUsageFlags imageUsage = getImageUsageForTestCase(m_caseDef);
1029 const VkImageCreateFlags imageFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | (m_haveMaintenance2 ? VK_IMAGE_CREATE_EXTENDED_USAGE_BIT : 0);
1031 VkImageFormatProperties properties;
1032 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(),
1033 m_caseDef.imageFormat,
1034 getImageType(m_caseDef.imageType),
1035 VK_IMAGE_TILING_OPTIMAL,
1038 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1040 TCU_THROW(NotSupportedError, "Format not supported");
1043 m_imageHolder = makeImage(m_vk, m_device, imageFlags, getImageType(m_caseDef.imageType), m_caseDef.imageFormat, m_caseDef.viewFormat,
1044 m_caseDef.isFormatListTest, m_caseDef.size, 1u, m_caseDef.numLayers, imageUsage);
1045 m_image = *m_imageHolder;
1046 m_imageAlloc = bindImage(m_vk, m_device, m_allocator, m_image, MemoryRequirement::Any);
1048 switch (m_caseDef.upload)
1051 uploadDraw(context);
1054 uploadStore(context);
1057 uploadClear(context);
1060 uploadCopy(context);
1063 DE_FATAL("Unsupported upload method");
1066 switch (m_caseDef.download)
1069 downloadCopy(context, buffer);
1072 downloadLoad(context, buffer);
1074 case DOWNLOAD_TEXTURE:
1075 downloadTexture(context, buffer);
1078 DE_FATAL("Unsupported download method");
1081 endCommandBuffer(m_vk, *m_cmdBuffer);
1082 submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer);
1085 void UploadDownloadExecutor::uploadClear(Context& context)
1089 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1091 const VkImageSubresourceRange subresourceRange = makeColorSubresourceRange(0, m_caseDef.numLayers);
1092 const VkImageMemoryBarrier imageInitBarrier =
1094 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1095 DE_NULL, // const void* pNext;
1096 0u, // VkAccessFlags srcAccessMask;
1097 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAcessMask;
1098 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1099 requiredImageLayout, // VkImageLayout newLayout;
1100 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1101 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1102 m_image, // VkImage image;
1103 subresourceRange // VkImageSubresourceRange subresourceRange;
1106 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1107 0u, DE_NULL, 0u, DE_NULL, 1u, &imageInitBarrier);
1109 for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
1111 const VkImageSubresourceRange layerSubresourceRange = makeColorSubresourceRange(layer, 1u);
1112 const deUint32 colorIdx = layer % COLOR_TABLE_SIZE;
1113 const VkClearColorValue clearColor = m_imageIsIntegerFormat ? getClearValueInt(m_caseDef, colorIdx).color : REFERENCE_CLEAR_COLOR_FLOAT[colorIdx].color;
1114 m_vk.cmdClearColorImage(*m_cmdBuffer, m_image, requiredImageLayout, &clearColor, 1u, &layerSubresourceRange);
1117 m_imageLayoutAfterUpload = requiredImageLayout;
1118 m_imageUploadAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1121 void UploadDownloadExecutor::uploadStore(Context& context)
1123 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1125 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, // VkStructureType sType
1126 DE_NULL, // const void* pNext
1127 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage;
1129 m_uStore.imageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1130 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1132 // Setup compute pipeline
1133 m_uStore.descriptorPool = DescriptorPoolBuilder()
1134 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1135 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1137 m_uStore.descriptorSetLayout = DescriptorSetLayoutBuilder()
1138 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1139 .build(m_vk, m_device);
1141 m_uStore.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_uStore.descriptorSetLayout);
1142 m_uStore.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_uStore.descriptorPool, *m_uStore.descriptorSetLayout);
1143 m_uStore.imageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_uStore.imageView, VK_IMAGE_LAYOUT_GENERAL);
1144 m_uStore.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadStoreComp"), 0);
1145 m_uStore.computePipeline = makeComputePipeline(m_vk, m_device, *m_uStore.pipelineLayout, *m_uStore.computeModule);
1147 DescriptorSetUpdateBuilder()
1148 .writeSingle(*m_uStore.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_uStore.imageDescriptorInfo)
1149 .update(m_vk, m_device);
1151 // Transition storage image for shader access (imageStore)
1152 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1153 const VkImageMemoryBarrier imageBarrier =
1155 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1156 DE_NULL, // const void* pNext;
1157 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1158 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1159 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1160 requiredImageLayout, // VkImageLayout newLayout;
1161 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1162 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1163 m_image, // VkImage image;
1164 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1167 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1168 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
1171 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.computePipeline);
1172 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.pipelineLayout, 0u, 1u, &m_uStore.descriptorSet.get(), 0u, DE_NULL);
1173 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1175 m_imageLayoutAfterUpload = requiredImageLayout;
1176 m_imageUploadAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
1179 void UploadDownloadExecutor::uploadCopy(Context& context)
1183 // Create a host-mappable buffer with the color data to upload
1184 const VkDeviceSize pixelSize = tcu::getPixelSize(mapVkFormat(m_caseDef.imageFormat));
1185 const VkDeviceSize layerSize = m_caseDef.size.x() * m_caseDef.size.y() * m_caseDef.size.z() * pixelSize;
1187 m_uCopy.colorBufferSize = layerSize * m_caseDef.numLayers;
1188 m_uCopy.colorBuffer = makeBuffer(m_vk, m_device, m_uCopy.colorBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
1189 m_uCopy.colorBufferAlloc = bindBuffer(m_vk, m_device, m_allocator, *m_uCopy.colorBuffer, MemoryRequirement::HostVisible);
1191 // Fill color buffer
1192 const tcu::TextureFormat tcuFormat = mapVkFormat(m_caseDef.imageFormat);
1193 VkDeviceSize layerOffset = 0ull;
1194 for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
1196 tcu::PixelBufferAccess imageAccess = tcu::PixelBufferAccess(tcuFormat, m_caseDef.size.x(), m_caseDef.size.y(), 1u, (deUint8*) m_uCopy.colorBufferAlloc->getHostPtr() + layerOffset);
1197 const deUint32 colorIdx = layer % COLOR_TABLE_SIZE;
1198 if (m_imageIsIntegerFormat)
1200 const VkClearValue clearValue = getClearValueInt(m_caseDef, colorIdx);
1201 const IVec4 colorInt (clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);
1203 tcu::clear(imageAccess, colorInt);
1206 tcu::clear(imageAccess, COLOR_TABLE_FLOAT[colorIdx]);
1207 layerOffset += layerSize;
1210 flushAlloc(m_vk, m_device, *(m_uCopy.colorBufferAlloc));
1212 // Prepare buffer and image for copy
1213 const VkBufferMemoryBarrier bufferInitBarrier =
1215 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1216 DE_NULL, // const void* pNext;
1217 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
1218 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1219 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1220 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1221 *m_uCopy.colorBuffer, // VkBuffer buffer;
1222 0ull, // VkDeviceSize offset;
1223 VK_WHOLE_SIZE, // VkDeviceSize size;
1226 const VkImageMemoryBarrier imageInitBarrier =
1228 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1229 DE_NULL, // const void* pNext;
1230 0u, // VkAccessFlags srcAccessMask;
1231 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1232 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1233 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1234 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1235 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1236 m_image, // VkImage image;
1237 makeColorSubresourceRange(0, m_caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
1240 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1241 0u, DE_NULL, 1u, &bufferInitBarrier, 1u, &imageInitBarrier);
1243 // Copy buffer to image
1244 const VkImageSubresourceLayers subresource =
1246 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1247 0u, // deUint32 mipLevel;
1248 0u, // deUint32 baseArrayLayer;
1249 m_caseDef.numLayers, // deUint32 layerCount;
1252 const VkBufferImageCopy region =
1254 0ull, // VkDeviceSize bufferOffset;
1255 0u, // deUint32 bufferRowLength;
1256 0u, // deUint32 bufferImageHeight;
1257 subresource, // VkImageSubresourceLayers imageSubresource;
1258 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
1259 makeExtent3D(m_caseDef.size), // VkExtent3D imageExtent;
1262 m_vk.cmdCopyBufferToImage(*m_cmdBuffer, *m_uCopy.colorBuffer, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ®ion);
1264 const VkImageMemoryBarrier imagePostInitBarrier =
1266 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1267 DE_NULL, // const void* pNext;
1268 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1269 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1270 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1271 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1272 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1273 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1274 m_image, // VkImage image;
1275 makeColorSubresourceRange(0, m_caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
1278 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1279 0u, DE_NULL, 0u, DE_NULL, 1u, &imagePostInitBarrier);
1281 m_imageLayoutAfterUpload = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1282 m_imageUploadAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1285 void UploadDownloadExecutor::uploadDraw(Context& context)
1287 // Create vertex buffer
1289 const vector<Vec4> vertices = genVertexData(m_caseDef);
1290 const VkDeviceSize vertexBufferSize = vertices.size() * sizeof(Vec4);
1292 m_uDraw.vertexBuffer = makeBuffer(m_vk, m_device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
1293 m_uDraw.vertexBufferAlloc = bindBuffer(m_vk, m_device, m_allocator, *m_uDraw.vertexBuffer, MemoryRequirement::HostVisible);
1294 deMemcpy(m_uDraw.vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
1295 flushAlloc(m_vk, m_device, *(m_uDraw.vertexBufferAlloc));
1298 // Create attachments and pipelines for each image layer
1299 m_uDraw.pipelineLayout = makePipelineLayout(m_vk, m_device);
1300 m_uDraw.renderPass = makeRenderPass(m_vk, m_device, m_caseDef.viewFormat, m_caseDef.numLayers);
1301 m_uDraw.vertexModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawVert"), 0u);
1302 m_uDraw.fragmentModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawFrag"), 0u);
1304 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
1306 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1308 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, // VkStructureType sType
1309 DE_NULL, // const void* pNext
1310 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags usage;
1312 Move<VkImageView> imageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1313 makeColorSubresourceRange(subpassNdx, 1), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1314 m_uDraw.attachmentHandles.push_back(*imageView);
1315 m_uDraw.attachments.push_back(makeSharedPtr(imageView));
1316 m_uDraw.pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(m_vk, m_device, *m_uDraw.pipelineLayout, *m_uDraw.renderPass, *m_uDraw.vertexModule, *m_uDraw.fragmentModule,
1317 m_caseDef.size.swizzle(0, 1), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, subpassNdx)));
1320 // Create framebuffer
1322 const IVec2 size = m_caseDef.size.swizzle(0, 1);
1324 m_uDraw.framebuffer = makeFramebuffer(m_vk, m_device, *m_uDraw.renderPass, static_cast<deUint32>(m_uDraw.attachmentHandles.size()), &m_uDraw.attachmentHandles[0], static_cast<deUint32>(size.x()), static_cast<deUint32>(size.y()));
1327 // Create command buffer
1330 vector<VkClearValue> clearValues (m_caseDef.numLayers, m_viewIsIntegerFormat ? getClearValueInt(m_caseDef, 0) : REFERENCE_CLEAR_COLOR_FLOAT[0]);
1332 beginRenderPass(m_vk, *m_cmdBuffer, *m_uDraw.renderPass, *m_uDraw.framebuffer, makeRect2D(0, 0, m_caseDef.size.x(), m_caseDef.size.y()), (deUint32)clearValues.size(), &clearValues[0]);
1336 const VkDeviceSize vertexDataPerDraw = 4 * 2 * sizeof(Vec4);
1337 VkDeviceSize vertexBufferOffset = 0ull;
1338 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
1340 if (subpassNdx != 0)
1341 m_vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
1343 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_uDraw.pipelines[subpassNdx]);
1345 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_uDraw.vertexBuffer.get(), &vertexBufferOffset);
1346 m_vk.cmdDraw(*m_cmdBuffer, 4u, 1u, 0u, 0u);
1347 vertexBufferOffset += vertexDataPerDraw;
1350 endRenderPass(m_vk, *m_cmdBuffer);
1353 m_imageLayoutAfterUpload = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1354 m_imageUploadAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1357 void UploadDownloadExecutor::downloadCopy(Context& context, VkBuffer buffer)
1361 copyImageToBuffer(m_image, buffer, m_caseDef.size, m_imageUploadAccessMask, m_imageLayoutAfterUpload, m_caseDef.numLayers);
1364 void UploadDownloadExecutor::downloadTexture(Context& context, VkBuffer buffer)
1366 // Create output image with download result
1367 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1368 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);
1369 m_dTex.outImageAlloc = bindImage(m_vk, m_device, m_allocator, *m_dTex.outImage, MemoryRequirement::Any);
1370 m_dTex.outImageView = makeImageView(m_vk, m_device, *m_dTex.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));
1372 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1374 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, // VkStructureType sType
1375 DE_NULL, // const void* pNext
1376 VK_IMAGE_USAGE_SAMPLED_BIT, // VkImageUsageFlags usage;
1378 m_dTex.inImageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1379 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1380 m_dTex.sampler = makeSampler(m_vk, m_device);
1382 // Setup compute pipeline
1383 m_dTex.descriptorPool = DescriptorPoolBuilder()
1384 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1385 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1386 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1388 m_dTex.descriptorSetLayout = DescriptorSetLayoutBuilder()
1389 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT, &m_dTex.sampler.get())
1390 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1391 .build(m_vk, m_device);
1393 m_dTex.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_dTex.descriptorSetLayout);
1394 m_dTex.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_dTex.descriptorPool, *m_dTex.descriptorSetLayout);
1395 m_dTex.inImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dTex.inImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1396 m_dTex.outImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dTex.outImageView, VK_IMAGE_LAYOUT_GENERAL);
1397 m_dTex.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadTextureComp"), 0);
1398 m_dTex.computePipeline = makeComputePipeline(m_vk, m_device, *m_dTex.pipelineLayout, *m_dTex.computeModule);
1400 DescriptorSetUpdateBuilder()
1401 .writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &m_dTex.inImageDescriptorInfo)
1402 .writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dTex.outImageDescriptorInfo)
1403 .update(m_vk, m_device);
1405 // Transition images for shader access (texture / imageStore)
1406 const VkImageMemoryBarrier imageBarriers[] =
1409 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1410 DE_NULL, // const void* pNext;
1411 (VkAccessFlags)m_imageUploadAccessMask, // VkAccessFlags srcAccessMask;
1412 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
1413 m_imageLayoutAfterUpload, // VkImageLayout oldLayout;
1414 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
1415 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1416 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1417 m_image, // VkImage image;
1418 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1421 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1422 DE_NULL, // const void* pNext;
1423 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1424 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1425 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1426 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout;
1427 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1428 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1429 *m_dTex.outImage, // VkImage image;
1430 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1434 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1435 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
1438 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.computePipeline);
1439 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.pipelineLayout, 0u, 1u, &m_dTex.descriptorSet.get(), 0u, DE_NULL);
1440 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1442 // Copy output image to color buffer
1443 copyImageToBuffer(*m_dTex.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL, m_caseDef.numLayers);
1446 void UploadDownloadExecutor::downloadLoad(Context& context, VkBuffer buffer)
1448 // Create output image with download result
1449 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1450 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);
1451 m_dLoad.outImageAlloc = bindImage(m_vk, m_device, m_allocator, *m_dLoad.outImage, MemoryRequirement::Any);
1452 m_dLoad.outImageView = makeImageView(m_vk, m_device, *m_dLoad.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));
1454 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1456 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, // VkStructureType sType
1457 DE_NULL, // const void* pNext
1458 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage;
1460 m_dLoad.inImageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1461 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1463 // Setup compute pipeline
1464 m_dLoad.descriptorPool = DescriptorPoolBuilder()
1465 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2u)
1466 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1468 m_dLoad.descriptorSetLayout = DescriptorSetLayoutBuilder()
1469 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1470 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1471 .build(m_vk, m_device);
1473 m_dLoad.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_dLoad.descriptorSetLayout);
1474 m_dLoad.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_dLoad.descriptorPool, *m_dLoad.descriptorSetLayout);
1475 m_dLoad.inImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dLoad.inImageView, VK_IMAGE_LAYOUT_GENERAL);
1476 m_dLoad.outImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dLoad.outImageView, VK_IMAGE_LAYOUT_GENERAL);
1477 m_dLoad.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadLoadComp"), 0);
1478 m_dLoad.computePipeline = makeComputePipeline(m_vk, m_device, *m_dLoad.pipelineLayout, *m_dLoad.computeModule);
1480 DescriptorSetUpdateBuilder()
1481 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.inImageDescriptorInfo)
1482 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.outImageDescriptorInfo)
1483 .update(m_vk, m_device);
1485 // Transition storage images for shader access (imageLoad/Store)
1486 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1487 const VkImageMemoryBarrier imageBarriers[] =
1490 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1491 DE_NULL, // const void* pNext;
1492 (VkAccessFlags)m_imageUploadAccessMask, // VkAccessFlags srcAccessMask;
1493 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
1494 m_imageLayoutAfterUpload, // VkImageLayout oldLayout;
1495 requiredImageLayout, // VkImageLayout newLayout;
1496 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1497 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1498 m_image, // VkImage image;
1499 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1502 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1503 DE_NULL, // const void* pNext;
1504 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1505 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1506 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1507 requiredImageLayout, // VkImageLayout newLayout;
1508 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1509 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1510 *m_dLoad.outImage, // VkImage image;
1511 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1515 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1516 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
1519 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.computePipeline);
1520 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.pipelineLayout, 0u, 1u, &m_dLoad.descriptorSet.get(), 0u, DE_NULL);
1521 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1523 // Copy output image to color buffer
1524 copyImageToBuffer(*m_dLoad.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, requiredImageLayout, m_caseDef.numLayers);
1527 void UploadDownloadExecutor::copyImageToBuffer(VkImage sourceImage,
1530 const VkAccessFlags srcAccessMask,
1531 const VkImageLayout oldLayout,
1532 const deUint32 numLayers)
1534 // Copy result to host visible buffer for inspection
1535 const VkImageMemoryBarrier imageBarrier =
1537 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1538 DE_NULL, // const void* pNext;
1539 srcAccessMask, // VkAccessFlags srcAccessMask;
1540 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1541 oldLayout, // VkImageLayout oldLayout;
1542 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
1543 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1544 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1545 sourceImage, // VkImage image;
1546 makeColorSubresourceRange(0, numLayers) // VkImageSubresourceRange subresourceRange;
1549 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1550 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
1552 const VkImageSubresourceLayers subresource =
1554 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1555 0u, // deUint32 mipLevel;
1556 0u, // deUint32 baseArrayLayer;
1557 numLayers, // deUint32 layerCount;
1560 const VkBufferImageCopy region =
1562 0ull, // VkDeviceSize bufferOffset;
1563 0u, // deUint32 bufferRowLength;
1564 0u, // deUint32 bufferImageHeight;
1565 subresource, // VkImageSubresourceLayers imageSubresource;
1566 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
1567 makeExtent3D(size), // VkExtent3D imageExtent;
1570 m_vk.cmdCopyImageToBuffer(*m_cmdBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, ®ion);
1572 const VkBufferMemoryBarrier bufferBarrier =
1574 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1575 DE_NULL, // const void* pNext;
1576 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1577 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
1578 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1579 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1580 buffer, // VkBuffer buffer;
1581 0ull, // VkDeviceSize offset;
1582 VK_WHOLE_SIZE, // VkDeviceSize size;
1585 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
1586 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
1589 tcu::TestStatus testMutable (Context& context, const CaseDef caseDef)
1591 const DeviceInterface& vk = context.getDeviceInterface();
1592 const VkDevice device = context.getDevice();
1593 Allocator& allocator = context.getDefaultAllocator();
1595 // Create a color buffer for host-inspection of results
1596 // For the Copy download method, this is the target of the download, for other
1597 // download methods, pixel data will be copied to this buffer from the download
1599 const VkDeviceSize colorBufferSize = caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat));
1600 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1601 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1602 deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
1603 flushAlloc(vk, device, *colorBufferAlloc);
1606 UploadDownloadExecutor executor(context, device, context.getUniversalQueue(), context.getUniversalQueueFamilyIndex(), caseDef);
1607 executor.run(context, *colorBuffer);
1611 invalidateAlloc(vk, device, *colorBufferAlloc);
1613 // For verification purposes, we use the format of the upload to generate the expected image
1614 const VkFormat format = caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat;
1615 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
1616 const bool isIntegerFormat = isUintFormat(format) || isIntFormat(format);
1617 const tcu::ConstPixelBufferAccess resultImage (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr());
1618 tcu::TextureLevel textureLevel (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers);
1619 const tcu::PixelBufferAccess expectedImage = textureLevel.getAccess();
1620 generateExpectedImage(expectedImage, caseDef);
1623 if (isIntegerFormat)
1624 ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
1626 ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
1627 return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
1631 void checkSupport (Context& context, const CaseDef caseDef)
1633 const InstanceInterface& vki = context.getInstanceInterface();
1634 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
1636 // If this is a VK_KHR_image_format_list test, check that the extension is supported
1637 if (caseDef.isFormatListTest)
1638 context.requireDeviceFunctionality("VK_KHR_image_format_list");
1640 // Check required features on the format for the required upload/download methods
1641 VkFormatProperties imageFormatProps, viewFormatProps;
1642 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.imageFormat, &imageFormatProps);
1643 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.viewFormat, &viewFormatProps);
1645 VkFormatFeatureFlags viewFormatFeatureFlags = 0u;
1646 switch (caseDef.upload)
1649 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
1652 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1655 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1658 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1661 DE_FATAL("Invalid upload method");
1664 switch (caseDef.download)
1666 case DOWNLOAD_TEXTURE:
1667 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
1668 // For the texture case we write the samples read to a separate output image with the same view format
1669 // so we need to check that we can also use the view format for storage
1670 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1673 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1676 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1679 DE_FATAL("Invalid download method");
1683 if ((viewFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags)
1684 TCU_THROW(NotSupportedError, "View format doesn't support upload/download method");
1686 const bool haveMaintenance2 = context.isDeviceFunctionalitySupported("VK_KHR_maintenance2");
1688 // We don't use the base image for anything other than transfer
1689 // operations so there are no features to check. However, The Vulkan
1690 // 1.0 spec does not allow us to create an image view with usage that
1691 // is not supported by the main format. With VK_KHR_maintenance2, we
1692 // can do this via VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR.
1693 if ((imageFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags &&
1696 TCU_THROW(NotSupportedError, "Image format doesn't support upload/download method");
1699 // If no format feature flags are supported, the format itself is not supported,
1700 // and images of that format cannot be created.
1701 if (imageFormatProps.optimalTilingFeatures == 0)
1703 TCU_THROW(NotSupportedError, "Base image format is not supported");
1707 tcu::TestCaseGroup* createImageMutableTests (TestContext& testCtx)
1709 de::MovePtr<TestCaseGroup> testGroup (new TestCaseGroup(testCtx, "mutable", "Cases with mutable images"));
1710 for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx)
1712 const Texture& texture = s_textures[textureNdx];
1713 de::MovePtr<tcu::TestCaseGroup> groupByImageViewType (new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), ""));
1715 for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++imageFormatNdx)
1716 for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++viewFormatNdx)
1718 if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_formats[imageFormatNdx], s_formats[viewFormatNdx]))
1720 for (int upload = 0; upload < UPLOAD_LAST; upload++)
1722 if (upload == UPLOAD_STORE && !isFormatImageLoadStoreCapable(s_formats[viewFormatNdx]))
1725 for (int download = 0; download < DOWNLOAD_LAST; download++)
1727 if ((download == DOWNLOAD_LOAD || download == DOWNLOAD_TEXTURE) &&
1728 !isFormatImageLoadStoreCapable(s_formats[viewFormatNdx]))
1734 texture.layerSize(),
1735 static_cast<deUint32>(texture.numLayers()),
1736 s_formats[imageFormatNdx],
1737 s_formats[viewFormatNdx],
1738 static_cast<enum Upload>(upload),
1739 static_cast<enum Download>(download),
1740 false, // isFormatListTest;
1741 false, // isSwapchainImageTest
1742 vk::wsi::TYPE_LAST // wsiType
1745 std::string caseName = getFormatShortString(s_formats[imageFormatNdx]) + "_" + getFormatShortString(s_formats[viewFormatNdx]) +
1746 "_" + getUploadString(upload) + "_" + getDownloadString(download);
1747 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", checkSupport, initPrograms, testMutable, caseDef);
1749 caseDef.isFormatListTest = true;
1750 caseName += "_format_list";
1751 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", checkSupport, initPrograms, testMutable, caseDef);
1757 testGroup->addChild(groupByImageViewType.release());
1760 return testGroup.release();
1763 typedef vector<VkExtensionProperties> Extensions;
1765 void checkAllSupported(const Extensions& supportedExtensions, const vector<string>& requiredExtensions)
1767 for (vector<string>::const_iterator requiredExtName = requiredExtensions.begin();
1768 requiredExtName != requiredExtensions.end();
1771 if (!isExtensionStructSupported(supportedExtensions, RequiredExtension(*requiredExtName)))
1772 TCU_THROW(NotSupportedError, (*requiredExtName + " is not supported").c_str());
1776 CustomInstance createInstanceWithWsi(Context& context,
1777 const Extensions& supportedExtensions,
1779 const VkAllocationCallbacks* pAllocator = DE_NULL)
1781 vector<string> extensions;
1783 extensions.push_back("VK_KHR_surface");
1784 extensions.push_back(getExtensionName(wsiType));
1785 if (isDisplaySurface(wsiType))
1786 extensions.push_back("VK_KHR_display");
1788 // VK_EXT_swapchain_colorspace adds new surface formats. Driver can enumerate
1789 // the formats regardless of whether VK_EXT_swapchain_colorspace was enabled,
1790 // but using them without enabling the extension is not allowed. Thus we have
1793 // 1) Filter out non-core formats to stay within valid usage.
1795 // 2) Enable VK_EXT_swapchain colorspace if advertised by the driver.
1797 // We opt for (2) as it provides basic coverage for the extension as a bonus.
1798 if (isExtensionStructSupported(supportedExtensions, RequiredExtension("VK_EXT_swapchain_colorspace")))
1799 extensions.push_back("VK_EXT_swapchain_colorspace");
1801 checkAllSupported(supportedExtensions, extensions);
1803 return createCustomInstanceWithExtensions(context, extensions, pAllocator);
1807 Move<VkDevice> createDeviceWithWsi(const PlatformInterface& vkp,
1808 VkInstance instance,
1809 const InstanceInterface& vki,
1810 VkPhysicalDevice physicalDevice,
1811 const Extensions& supportedExtensions,
1812 const deUint32 queueFamilyIndex,
1813 const VkAllocationCallbacks* pAllocator,
1814 #ifdef CTS_USES_VULKANSC
1815 de::SharedPtr<vk::ResourceInterface> resourceInterface,
1816 #endif // CTS_USES_VULKANSC
1817 const tcu::CommandLine& cmdLine)
1819 const float queuePriorities[] = { 1.0f };
1820 const VkDeviceQueueCreateInfo queueInfos[] =
1823 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1825 (VkDeviceQueueCreateFlags)0,
1827 DE_LENGTH_OF_ARRAY(queuePriorities),
1831 VkPhysicalDeviceFeatures features;
1832 deMemset(&features, 0x0, sizeof(features));
1834 const char* const extensions[] = { "VK_KHR_swapchain", "VK_KHR_swapchain_mutable_format" };
1836 void* pNext = DE_NULL;
1837 #ifdef CTS_USES_VULKANSC
1838 VkDeviceObjectReservationCreateInfo memReservationInfo = cmdLine.isSubProcess() ? resourceInterface->getStatMax() : resetDeviceObjectReservationCreateInfo();
1839 memReservationInfo.pNext = pNext;
1840 pNext = &memReservationInfo;
1842 VkPhysicalDeviceVulkanSC10Features sc10Features = createDefaultSC10Features();
1843 sc10Features.pNext = pNext;
1844 pNext = &sc10Features;
1846 VkPipelineCacheCreateInfo pcCI;
1847 std::vector<VkPipelinePoolSize> poolSizes;
1848 if (cmdLine.isSubProcess())
1850 if (resourceInterface->getCacheDataSize() > 0)
1854 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
1855 DE_NULL, // const void* pNext;
1856 VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
1857 VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
1858 resourceInterface->getCacheDataSize(), // deUintptr initialDataSize;
1859 resourceInterface->getCacheData() // const void* pInitialData;
1861 memReservationInfo.pipelineCacheCreateInfoCount = 1;
1862 memReservationInfo.pPipelineCacheCreateInfos = &pcCI;
1865 poolSizes = resourceInterface->getPipelinePoolSizes();
1866 if (!poolSizes.empty())
1868 memReservationInfo.pipelinePoolSizeCount = deUint32(poolSizes.size());
1869 memReservationInfo.pPipelinePoolSizes = poolSizes.data();
1872 #endif // CTS_USES_VULKANSC
1874 const VkDeviceCreateInfo deviceParams =
1876 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1878 (VkDeviceCreateFlags)0,
1879 DE_LENGTH_OF_ARRAY(queueInfos),
1881 0u, // enabledLayerCount
1882 DE_NULL, // ppEnabledLayerNames
1883 DE_LENGTH_OF_ARRAY(extensions), // enabledExtensionCount
1884 DE_ARRAY_BEGIN(extensions), // ppEnabledExtensionNames
1888 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(extensions); ++ndx)
1890 if (!isExtensionStructSupported(supportedExtensions, RequiredExtension(extensions[ndx])))
1891 TCU_THROW(NotSupportedError, (string(extensions[ndx]) + " is not supported").c_str());
1894 return createCustomDevice(cmdLine.isValidationEnabled(), vkp, instance, vki, physicalDevice, &deviceParams, pAllocator);
1897 struct InstanceHelper
1899 const vector<VkExtensionProperties> supportedExtensions;
1900 const CustomInstance instance;
1901 const InstanceDriver& vki;
1903 InstanceHelper(Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
1904 : supportedExtensions(enumerateInstanceExtensionProperties(context.getPlatformInterface(),
1906 , instance(createInstanceWithWsi(context,
1907 supportedExtensions,
1910 , vki(instance.getDriver())
1917 const VkPhysicalDevice physicalDevice;
1918 const deUint32 queueFamilyIndex;
1919 const Unique<VkDevice> device;
1920 const DeviceDriver vkd;
1921 const VkQueue queue;
1923 DeviceHelper(Context& context,
1924 const InstanceInterface& vki,
1925 VkInstance instance,
1926 VkSurfaceKHR surface,
1927 const VkAllocationCallbacks* pAllocator = DE_NULL)
1928 : physicalDevice(chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
1929 , queueFamilyIndex(chooseQueueFamilyIndex(vki, physicalDevice, surface))
1930 , device(createDeviceWithWsi(context.getPlatformInterface(),
1931 context.getInstance(),
1934 enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL),
1937 #ifdef CTS_USES_VULKANSC
1938 context.getResourceInterface(),
1939 #endif // CTS_USES_VULKANSC
1940 context.getTestContext().getCommandLine()))
1941 , vkd(context.getPlatformInterface(), context.getInstance(), *device)
1942 , queue(getDeviceQueue(vkd, *device, queueFamilyIndex, 0))
1947 MovePtr<Display> createDisplay(const vk::Platform& platform,
1948 const Extensions& supportedExtensions,
1953 return MovePtr<Display>(platform.createWsiDisplay(wsiType));
1955 catch (const tcu::NotSupportedError& e)
1957 if (isExtensionStructSupported(supportedExtensions, RequiredExtension(getExtensionName(wsiType))) &&
1958 platform.hasDisplay(wsiType))
1960 // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
1961 // must support creating native display & window for that WSI type.
1962 throw tcu::TestError(e.getMessage());
1969 MovePtr<Window> createWindow(const Display& display, const Maybe<UVec2>& initialSize)
1973 return MovePtr<Window>(display.createWindow(initialSize));
1975 catch (const tcu::NotSupportedError& e)
1977 // See createDisplay - assuming that wsi::Display was supported platform port
1978 // should also support creating a window.
1979 throw tcu::TestError(e.getMessage());
1983 struct NativeObjects
1985 const UniquePtr<Display> display;
1986 const UniquePtr<Window> window;
1988 NativeObjects(Context& context,
1989 const Extensions& supportedExtensions,
1991 const Maybe<UVec2>& initialWindowSize = tcu::Nothing)
1992 : display(createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
1993 , window(createWindow(*display, initialWindowSize))
1997 Move<VkSwapchainKHR> makeSwapchain(const DeviceInterface& vk,
1998 const VkDevice device,
1999 const vk::wsi::Type wsiType,
2000 const VkSurfaceKHR surface,
2001 const VkSurfaceCapabilitiesKHR capabilities,
2002 const VkSurfaceFormatKHR surfaceFormat,
2003 const VkFormat viewFormat,
2004 const deUint32 numLayers,
2005 const VkImageUsageFlags usage,
2006 const tcu::UVec2& desiredSize,
2007 deUint32 desiredImageCount
2010 const VkFormat formatList[2] =
2012 surfaceFormat.format,
2016 const VkImageFormatListCreateInfo formatListInfo =
2018 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO, // VkStructureType sType;
2019 DE_NULL, // const void* pNext;
2020 2u, // deUint32 viewFormatCount
2021 formatList // const VkFormat* pViewFormats
2024 const VkSurfaceTransformFlagBitsKHR transform = (capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
2025 const PlatformProperties& platformProperties = getPlatformProperties(wsiType);
2027 const VkSwapchainCreateInfoKHR swapchainInfo =
2029 VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, // VkStructureType sType;
2030 &formatListInfo, // const void* pNext;
2031 VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR, // VkSwapchainCreateFlagsKHR flags;
2032 surface, // VkSurfaceKHR surface;
2033 de::clamp(desiredImageCount, capabilities.minImageCount, capabilities.maxImageCount > 0 ? capabilities.maxImageCount : capabilities.minImageCount + desiredImageCount), // deUint32 minImageCount;
2034 surfaceFormat.format, // VkFormat imageFormat;
2035 surfaceFormat.colorSpace, // VkColorSpaceKHR imageColorSpace;
2036 (platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE
2037 ? capabilities.currentExtent : vk::makeExtent2D(desiredSize.x(), desiredSize.y())), // VkExtent2D imageExtent;
2038 numLayers, // deUint32 imageArrayLayers;
2039 usage, // VkImageUsageFlags imageUsage;
2040 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode imageSharingMode;
2041 0u, // deUint32 queueFamilyIndexCount;
2042 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2043 transform, // VkSurfaceTransformFlagBitsKHR preTransform;
2044 VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, // VkCompositeAlphaFlagBitsKHR compositeAlpha;
2045 VK_PRESENT_MODE_FIFO_KHR, // VkPresentModeKHR presentMode;
2046 VK_FALSE, // VkBool32 clipped;
2047 (VkSwapchainKHR)0 // VkSwapchainKHR oldSwapchain;
2050 return createSwapchainKHR(vk, device, &swapchainInfo);
2053 tcu::TestStatus testSwapchainMutable(Context& context, CaseDef caseDef)
2055 const Type wsiType(caseDef.wsiType);
2056 const tcu::UVec2 desiredSize(256, 256);
2057 const InstanceHelper instHelper(context, wsiType);
2058 const NativeObjects native(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
2059 const Unique<VkSurfaceKHR> surface(createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window, context.getTestContext().getCommandLine()));
2060 const DeviceHelper devHelper(context, instHelper.vki, instHelper.instance, *surface);
2061 const DeviceInterface& vk = devHelper.vkd;
2062 const InstanceDriver& vki = instHelper.vki;
2063 const VkDevice device = *devHelper.device;
2064 const VkPhysicalDevice physDevice = devHelper.physicalDevice;
2065 SimpleAllocator allocator(vk, device, getPhysicalDeviceMemoryProperties(vki, context.getPhysicalDevice()));
2067 const VkImageUsageFlags imageUsage = getImageUsageForTestCase(caseDef);
2070 VkImageFormatProperties properties;
2073 result = vki.getPhysicalDeviceImageFormatProperties(physDevice, caseDef.imageFormat, getImageType(caseDef.imageType), VK_IMAGE_TILING_OPTIMAL, imageUsage, 0, &properties);
2075 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
2077 TCU_THROW(NotSupportedError, "Image format is not supported for required usage");
2080 result = vki.getPhysicalDeviceImageFormatProperties(physDevice, caseDef.viewFormat, getImageType(caseDef.imageType), VK_IMAGE_TILING_OPTIMAL, imageUsage, 0, &properties);
2082 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
2084 TCU_THROW(NotSupportedError, "Image view format is not supported for required usage");
2088 const VkSurfaceCapabilitiesKHR capabilities = getPhysicalDeviceSurfaceCapabilities(vki,
2092 if (caseDef.numLayers > capabilities.maxImageArrayLayers)
2093 caseDef.numLayers = capabilities.maxImageArrayLayers;
2095 // Check support for requested formats by swapchain surface
2096 const vector<VkSurfaceFormatKHR>surfaceFormats = getPhysicalDeviceSurfaceFormats(vki,
2100 const VkSurfaceFormatKHR* surfaceFormat = DE_NULL;
2101 const VkFormat* viewFormat = DE_NULL;
2103 for (vector<VkSurfaceFormatKHR>::size_type i = 0; i < surfaceFormats.size(); i++)
2105 if (surfaceFormats[i].format == caseDef.imageFormat)
2106 surfaceFormat = &surfaceFormats[i];
2108 if (surfaceFormats[i].format == caseDef.viewFormat)
2109 viewFormat = &surfaceFormats[i].format;
2112 if (surfaceFormat == DE_NULL)
2113 TCU_THROW(NotSupportedError, "Image format is not supported by swapchain.");
2115 if (viewFormat == DE_NULL)
2116 TCU_THROW(NotSupportedError, "Image view format is not supported by swapchain.");
2118 if ((capabilities.supportedUsageFlags & imageUsage) != imageUsage)
2119 TCU_THROW(NotSupportedError, "Image usage request not supported by swapchain.");
2121 const Unique<VkSwapchainKHR> swapchain(
2135 const vector<VkImage> swapchainImages = getSwapchainImages(vk, device, *swapchain);
2137 // Create a color buffer for host-inspection of results
2138 // For the Copy download method, this is the target of the download, for other
2139 // download methods, pixel data will be copied to this buffer from the download
2141 const VkDeviceSize colorBufferSize = caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat));
2142 const Unique<VkBuffer> colorBuffer(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2143 const UniquePtr<Allocation> colorBufferAlloc(bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
2144 deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
2145 flushAlloc(vk, device, *colorBufferAlloc);
2149 UploadDownloadExecutor executor(context, device, devHelper.queue, devHelper.queueFamilyIndex, caseDef);
2151 executor.runSwapchain(context, *colorBuffer, swapchainImages[0]);
2155 invalidateAlloc(vk, device, *colorBufferAlloc);
2157 // For verification purposes, we use the format of the upload to generate the expected image
2158 const VkFormat format = caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat;
2159 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
2160 const bool isIntegerFormat = isUintFormat(format) || isIntFormat(format);
2161 const tcu::ConstPixelBufferAccess resultImage(tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr());
2162 tcu::TextureLevel textureLevel(tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers);
2163 const tcu::PixelBufferAccess expectedImage = textureLevel.getAccess();
2164 generateExpectedImage(expectedImage, caseDef);
2167 if (isIntegerFormat)
2168 ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
2170 ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
2171 return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
2175 tcu::TestCaseGroup* createSwapchainImageMutableTests(TestContext& testCtx)
2177 de::MovePtr<TestCaseGroup> testGroup(new TestCaseGroup(testCtx, "swapchain_mutable", "Cases with swapchain mutable images"));
2179 for (int typeNdx = 0; typeNdx < vk::wsi::TYPE_LAST; ++typeNdx)
2181 const vk::wsi::Type wsiType = (vk::wsi::Type)typeNdx;
2183 de::MovePtr<TestCaseGroup> testGroupWsi(new TestCaseGroup(testCtx, getName(wsiType), ""));
2185 for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx)
2187 const Texture& texture = s_textures[textureNdx];
2188 de::MovePtr<tcu::TestCaseGroup> groupByImageViewType(new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), ""));
2190 for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_swapchainFormats); ++imageFormatNdx)
2191 for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_swapchainFormats); ++viewFormatNdx)
2193 if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_swapchainFormats[imageFormatNdx], s_swapchainFormats[viewFormatNdx]))
2195 for (int upload = 0; upload < UPLOAD_LAST; upload++)
2197 if (upload == UPLOAD_STORE && !isFormatImageLoadStoreCapable(s_swapchainFormats[viewFormatNdx]))
2200 for (int download = 0; download < DOWNLOAD_LAST; download++)
2202 if ((download == DOWNLOAD_LOAD || download == DOWNLOAD_TEXTURE) &&
2203 !isFormatImageLoadStoreCapable(s_swapchainFormats[viewFormatNdx]))
2209 texture.layerSize(),
2210 static_cast<deUint32>(texture.numLayers()),
2211 s_swapchainFormats[imageFormatNdx],
2212 s_swapchainFormats[viewFormatNdx],
2213 static_cast<enum Upload>(upload),
2214 static_cast<enum Download>(download),
2215 true, // isFormatListTest;
2216 true, // isSwapchainImageTest
2220 std::string caseName = getFormatShortString(s_swapchainFormats[imageFormatNdx]) + "_" + getFormatShortString(s_swapchainFormats[viewFormatNdx]) +
2221 "_" + getUploadString(upload) + "_" + getDownloadString(download) + "_format_list";
2223 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", checkSupport, initPrograms, testSwapchainMutable, caseDef);
2229 testGroupWsi->addChild(groupByImageViewType.release());
2232 testGroup->addChild(testGroupWsi.release());
2234 return testGroup.release();