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"
29 #include "vkBuilderUtil.hpp"
30 #include "vkQueryUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkCmdUtil.hpp"
33 #include "vkObjUtil.hpp"
36 #include "vkPlatform.hpp"
37 #include "vkWsiUtil.hpp"
38 #include "vkDeviceUtil.hpp"
40 #include "deUniquePtr.hpp"
41 #include "deSharedPtr.hpp"
43 #include "tcuImageCompare.hpp"
44 #include "tcuTestLog.hpp"
45 #include "tcuTextureUtil.hpp"
46 #include "tcuPlatform.hpp"
53 using namespace vk::wsi;
66 typedef SharedPtr<Unique<VkPipeline> > SharedPtrVkPipeline;
67 typedef SharedPtr<Unique<VkImageView> > SharedPtrVkImageView;
70 inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move)
72 return SharedPtr<Unique<T> >(new Unique<T>(move));
90 std::string getUploadString (const int upload)
92 const char* strs[] = { "clear", "copy", "store", "draw" };
96 std::string getDownloadString (const int download)
98 const char* strs[] = { "copy", "load", "texture" };
99 return strs[download];
107 VkFormat imageFormat;
110 enum Download download;
111 bool isFormatListTest;
112 bool isSwapchainImageTest;
116 static const deUint32 COLOR_TABLE_SIZE = 4;
118 // Reference color values for float color rendering. Values have been chosen
119 // so that when the bit patterns are reinterpreted as a 16-bit float, we do not
120 // run into NaN / inf / denorm values.
121 static const Vec4 COLOR_TABLE_FLOAT[COLOR_TABLE_SIZE] =
123 Vec4(0.00f, 0.40f, 0.80f, 0.10f),
124 Vec4(0.50f, 0.10f, 0.90f, 0.20f),
125 Vec4(0.20f, 0.60f, 1.00f, 0.30f),
126 Vec4(0.30f, 0.70f, 0.00f, 0.40f),
129 // Reference color values for integer color rendering. We avoid negative
130 // values (even for SINT formats) to avoid the situation where sign extension
131 // leads to NaN / inf values when they are reinterpreted with a float
133 static const IVec4 COLOR_TABLE_INT[COLOR_TABLE_SIZE] =
135 IVec4(0x70707070, 0x3C3C3C3C, 0x65656565, 0x29292929),
136 IVec4(0x3C3C3C3C, 0x65656565, 0x29292929, 0x70707070),
137 IVec4(0x29292929, 0x70707070, 0x3C3C3C3C, 0x65656565),
138 IVec4(0x65656565, 0x29292929, 0x70707070, 0x3C3C3C3C),
141 // Reference clear colors created from the color table values
142 static const VkClearValue REFERENCE_CLEAR_COLOR_FLOAT[COLOR_TABLE_SIZE] =
144 makeClearValueColorF32(COLOR_TABLE_FLOAT[0].x(), COLOR_TABLE_FLOAT[0].y(), COLOR_TABLE_FLOAT[0].z(), COLOR_TABLE_FLOAT[0].w()),
145 makeClearValueColorF32(COLOR_TABLE_FLOAT[1].x(), COLOR_TABLE_FLOAT[1].y(), COLOR_TABLE_FLOAT[1].z(), COLOR_TABLE_FLOAT[1].w()),
146 makeClearValueColorF32(COLOR_TABLE_FLOAT[2].x(), COLOR_TABLE_FLOAT[2].y(), COLOR_TABLE_FLOAT[2].z(), COLOR_TABLE_FLOAT[2].w()),
147 makeClearValueColorF32(COLOR_TABLE_FLOAT[3].x(), COLOR_TABLE_FLOAT[3].y(), COLOR_TABLE_FLOAT[3].z(), COLOR_TABLE_FLOAT[3].w()),
150 static const Texture s_textures[] =
152 Texture(IMAGE_TYPE_2D, tcu::IVec3(32, 32, 1), 1),
153 Texture(IMAGE_TYPE_2D_ARRAY, tcu::IVec3(32, 32, 1), 4),
156 static VkClearValue getClearValueInt(const CaseDef& caseDef, deUint32 colorTableIndex)
158 VkClearValue clearValue;
159 deUint32 channelMask = 0;
161 if (caseDef.upload == UPLOAD_DRAW)
163 // We use this mask to get small color values in the vertex buffer and
164 // avoid possible round off errors from int-to-float conversions.
170 tcu::TextureFormat tcuFormat;
172 // Select a mask such that no integer-based color values end up
173 // reinterpreted as NaN/Inf/denorm values.
174 if (caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY)
175 format = caseDef.imageFormat;
177 format = caseDef.viewFormat;
179 tcuFormat = mapVkFormat(format);
181 switch (getChannelSize(tcuFormat.type))
187 channelMask = 0xFFFFu;
190 channelMask = 0xFFFFFFFFu;
197 clearValue.color.int32[0] = COLOR_TABLE_INT[colorTableIndex].x() & channelMask;
198 clearValue.color.int32[1] = COLOR_TABLE_INT[colorTableIndex].y() & channelMask;
199 clearValue.color.int32[2] = COLOR_TABLE_INT[colorTableIndex].z() & channelMask;
200 clearValue.color.int32[3] = COLOR_TABLE_INT[colorTableIndex].w() & channelMask;
205 VkImageType getImageType (const ImageType textureImageType)
207 switch (textureImageType)
210 case IMAGE_TYPE_2D_ARRAY:
211 return VK_IMAGE_TYPE_2D;
215 return VK_IMAGE_TYPE_LAST;
219 VkImageViewType getImageViewType (const ImageType textureImageType)
221 switch (textureImageType)
224 return VK_IMAGE_VIEW_TYPE_2D;
225 case IMAGE_TYPE_2D_ARRAY:
226 return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
230 return VK_IMAGE_VIEW_TYPE_LAST;
234 static const VkFormat s_formats[] =
236 VK_FORMAT_R32G32B32A32_SFLOAT,
237 VK_FORMAT_R16G16B16A16_SFLOAT,
238 VK_FORMAT_R32G32_SFLOAT,
239 VK_FORMAT_R16G16_SFLOAT,
240 VK_FORMAT_R32_SFLOAT,
242 VK_FORMAT_R32G32B32A32_UINT,
243 VK_FORMAT_R16G16B16A16_UINT,
244 VK_FORMAT_R8G8B8A8_UINT,
245 VK_FORMAT_R32G32_UINT,
246 VK_FORMAT_R16G16_UINT,
249 VK_FORMAT_R32G32B32A32_SINT,
250 VK_FORMAT_R16G16B16A16_SINT,
251 VK_FORMAT_R8G8B8A8_SINT,
252 VK_FORMAT_R32G32_SINT,
253 VK_FORMAT_R16G16_SINT,
256 VK_FORMAT_R8G8B8A8_UNORM,
257 VK_FORMAT_R8G8B8A8_SNORM,
258 VK_FORMAT_R8G8B8A8_SRGB,
259 VK_FORMAT_B8G8R8A8_UNORM,
260 VK_FORMAT_B8G8R8A8_SNORM,
261 VK_FORMAT_B8G8R8A8_SRGB,
264 static const VkFormat s_swapchainFormats[] =
266 VK_FORMAT_R8G8B8A8_UNORM,
267 VK_FORMAT_R8G8B8A8_SNORM,
268 VK_FORMAT_R8G8B8A8_SRGB,
269 VK_FORMAT_B8G8R8A8_UNORM,
270 VK_FORMAT_B8G8R8A8_SNORM,
271 VK_FORMAT_B8G8R8A8_SRGB,
274 bool isSRGBConversionRequired(const CaseDef& caseDef)
276 bool required = false;
278 if (isSRGB(mapVkFormat(caseDef.imageFormat)))
280 if (caseDef.upload == UPLOAD_CLEAR)
286 if (isSRGB(mapVkFormat(caseDef.viewFormat)))
288 if (caseDef.upload == UPLOAD_DRAW || caseDef.upload == UPLOAD_STORE)
298 inline bool formatsAreCompatible (const VkFormat format0, const VkFormat format1)
300 return format0 == format1 || mapVkFormat(format0).getPixelSize() == mapVkFormat(format1).getPixelSize();
303 std::string getColorFormatStr (const int numComponents, const bool isUint, const bool isSint)
305 std::ostringstream str;
306 if (numComponents == 1)
307 str << (isUint ? "uint" : isSint ? "int" : "float");
309 str << (isUint ? "u" : isSint ? "i" : "") << "vec" << numComponents;
314 std::string getShaderSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
316 std::ostringstream samplerType;
318 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
320 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
325 case VK_IMAGE_VIEW_TYPE_2D:
326 samplerType << "sampler2D";
329 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
330 samplerType << "sampler2DArray";
334 DE_FATAL("Ivalid image view type");
338 return samplerType.str();
341 void initPrograms (SourceCollections& programCollection, const CaseDef caseDef)
343 if (caseDef.upload == UPLOAD_DRAW)
346 std::ostringstream src;
347 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
349 << "layout(location = 0) in vec4 in_position;\n"
350 << "layout(location = 1) in vec4 in_color;\n"
351 << "layout(location = 0) out vec4 out_color;\n"
353 << "out gl_PerVertex {\n"
354 << " vec4 gl_Position;\n"
357 << "void main(void)\n"
359 << " gl_Position = in_position;\n"
360 << " out_color = in_color;\n"
363 programCollection.glslSources.add("uploadDrawVert") << glu::VertexSource(src.str());
367 const int numComponents = getNumUsedChannels(mapVkFormat(caseDef.viewFormat).order);
368 const bool isUint = isUintFormat(caseDef.viewFormat);
369 const bool isSint = isIntFormat(caseDef.viewFormat);
370 const std::string colorFormat = getColorFormatStr(numComponents, isUint, isSint);
372 std::ostringstream src;
373 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
375 << "layout(location = 0) in vec4 in_color;\n"
376 << "layout(location = 0) out " << colorFormat << " out_color;\n"
378 << "void main(void)\n"
380 << " out_color = " << colorFormat << "("
381 << (numComponents == 1 ? "in_color.r" :
382 numComponents == 2 ? "in_color.rg" :
383 numComponents == 3 ? "in_color.rgb" : "in_color")
387 programCollection.glslSources.add("uploadDrawFrag") << glu::FragmentSource(src.str());
391 if (caseDef.upload == UPLOAD_STORE)
393 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
394 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
395 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
396 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
397 const bool isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);
399 std::ostringstream src;
400 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
402 << "layout (local_size_x = 1) in;\n"
404 << "layout(binding=0, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " u_image;\n"
406 << "const " << colorTypeStr << " colorTable[] = " << colorTypeStr << "[](\n";
407 for (deUint32 idx = 0; idx < COLOR_TABLE_SIZE; idx++)
411 const VkClearValue clearValue = getClearValueInt(caseDef, idx);
413 src << " " << colorTypeStr << "(" << clearValue.color.int32[0] << ", " << clearValue.color.int32[1] << ", " << clearValue.color.int32[2] << ", " << clearValue.color.int32[3] << ")";
416 src << " " << colorTypeStr << "(" << COLOR_TABLE_FLOAT[idx].x() << ", " << COLOR_TABLE_FLOAT[idx].y() << ", " << COLOR_TABLE_FLOAT[idx].z() << ", " << COLOR_TABLE_FLOAT[idx].w() << ")";
417 if (idx < COLOR_TABLE_SIZE - 1)
423 << "void main(void)\n"
425 if (caseDef.imageType == IMAGE_TYPE_2D)
427 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
431 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
432 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
434 src << " " << colorTypeStr << " color = colorTable[gl_GlobalInvocationID.z];\n"
435 << " imageStore(u_image, pos, color);\n"
438 programCollection.glslSources.add("uploadStoreComp") << glu::ComputeSource(src.str());
441 if (caseDef.download == DOWNLOAD_LOAD)
443 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
444 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
445 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
446 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
448 std::ostringstream src;
449 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
451 << "layout (local_size_x = 1) in;\n"
453 << "layout(binding=0, " << imageFormatStr << ") readonly uniform " << imageTypeStr << " in_image;\n"
454 << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
456 << "void main(void)\n"
458 if (caseDef.imageType == IMAGE_TYPE_2D)
460 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
464 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
465 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
467 src << " imageStore(out_image, pos, imageLoad(in_image, pos));\n"
470 programCollection.glslSources.add("downloadLoadComp") << glu::ComputeSource(src.str());
473 if (caseDef.download == DOWNLOAD_TEXTURE)
475 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
476 const VkImageViewType viewType = getImageViewType(caseDef.imageType);
477 const std::string samplerTypeStr = getShaderSamplerType(tcuFormat, viewType);
478 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
479 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
480 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
482 std::ostringstream src;
483 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
485 << "layout (local_size_x = 1) in;\n"
487 << "layout(binding=0) uniform " << samplerTypeStr << " u_tex;\n"
488 << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
490 << "void main(void)\n"
492 if (caseDef.imageType == IMAGE_TYPE_2D)
494 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
498 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
499 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
501 src << " imageStore(out_image, pos, texelFetch(u_tex, pos, 0));\n"
504 programCollection.glslSources.add("downloadTextureComp") << glu::ComputeSource(src.str());
508 Move<VkImage> makeImage (const DeviceInterface& vk,
509 const VkDevice device,
510 VkImageCreateFlags flags,
511 VkImageType imageType,
512 const VkFormat format,
513 const VkFormat viewFormat,
514 const bool useImageFormatList,
516 const deUint32 numMipLevels,
517 const deUint32 numLayers,
518 const VkImageUsageFlags usage)
520 const VkFormat formatList[2] =
526 const VkImageFormatListCreateInfoKHR formatListInfo =
528 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR, // VkStructureType sType;
529 DE_NULL, // const void* pNext;
530 2u, // deUint32 viewFormatCount
531 formatList // const VkFormat* pViewFormats
534 const VkImageCreateInfo imageParams =
536 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
537 useImageFormatList ? &formatListInfo : DE_NULL, // const void* pNext;
538 flags, // VkImageCreateFlags flags;
539 imageType, // VkImageType imageType;
540 format, // VkFormat format;
541 makeExtent3D(size), // VkExtent3D extent;
542 numMipLevels, // deUint32 mipLevels;
543 numLayers, // deUint32 arrayLayers;
544 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
545 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
546 usage, // VkImageUsageFlags usage;
547 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
548 0u, // deUint32 queueFamilyIndexCount;
549 DE_NULL, // const deUint32* pQueueFamilyIndices;
550 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
552 return createImage(vk, device, &imageParams);
555 inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize bufferSize, const VkBufferUsageFlags usage)
557 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSize, usage);
558 return createBuffer(vk, device, &bufferCreateInfo);
561 inline VkImageSubresourceRange makeColorSubresourceRange (const int baseArrayLayer, const int layerCount)
563 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, static_cast<deUint32>(baseArrayLayer), static_cast<deUint32>(layerCount));
566 Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice device)
568 const VkSamplerCreateInfo samplerParams =
570 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
571 DE_NULL, // const void* pNext;
572 (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags;
573 VK_FILTER_NEAREST, // VkFilter magFilter;
574 VK_FILTER_NEAREST, // VkFilter minFilter;
575 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
576 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
577 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
578 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
579 0.0f, // float mipLodBias;
580 VK_FALSE, // VkBool32 anisotropyEnable;
581 1.0f, // float maxAnisotropy;
582 VK_FALSE, // VkBool32 compareEnable;
583 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
584 0.0f, // float minLod;
585 0.0f, // float maxLod;
586 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
587 VK_FALSE, // VkBool32 unnormalizedCoordinates;
590 return createSampler(vk, device, &samplerParams);
594 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk,
595 const VkDevice device)
597 const VkPipelineLayoutCreateInfo info =
599 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
601 (VkPipelineLayoutCreateFlags)0,
607 return createPipelineLayout(vk, device, &info);
610 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
611 const VkDevice device,
612 const VkPipelineLayout pipelineLayout,
613 const VkRenderPass renderPass,
614 const VkShaderModule vertexModule,
615 const VkShaderModule fragmentModule,
616 const IVec2& renderSize,
617 const VkPrimitiveTopology topology,
618 const deUint32 subpass)
620 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
621 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
623 const VkVertexInputBindingDescription vertexInputBindingDescription =
625 0u, // deUint32 binding;
626 (deUint32)(2 * sizeof(Vec4)), // deUint32 stride;
627 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
630 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
633 0u, // deUint32 location;
634 0u, // deUint32 binding;
635 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
636 0u, // deUint32 offset;
639 1u, // deUint32 location;
640 0u, // deUint32 binding;
641 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
642 (deUint32)sizeof(Vec4), // deUint32 offset;
646 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
648 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
649 DE_NULL, // const void* pNext;
650 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
651 1u, // deUint32 vertexBindingDescriptionCount;
652 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
653 2u, // deUint32 vertexAttributeDescriptionCount;
654 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
657 return vk::makeGraphicsPipeline(vk, // const DeviceInterface& vk
658 device, // const VkDevice device
659 pipelineLayout, // const VkPipelineLayout pipelineLayout
660 vertexModule, // const VkShaderModule vertexShaderModule
661 DE_NULL, // const VkShaderModule tessellationControlModule
662 DE_NULL, // const VkShaderModule tessellationEvalModule
663 DE_NULL, // const VkShaderModule geometryShaderModule
664 fragmentModule, // const VkShaderModule fragmentShaderModule
665 renderPass, // const VkRenderPass renderPass
666 viewports, // const std::vector<VkViewport>& viewports
667 scissors, // const std::vector<VkRect2D>& scissors
668 topology, // const VkPrimitiveTopology topology
669 subpass, // const deUint32 subpass
670 0u, // const deUint32 patchControlPoints
671 &vertexInputStateCreateInfo); // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
674 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
675 const VkDevice device,
676 const VkPipelineLayout pipelineLayout,
677 const VkShaderModule shaderModule,
678 const VkSpecializationInfo* specInfo)
680 const VkPipelineShaderStageCreateInfo shaderStageInfo =
682 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
683 DE_NULL, // const void* pNext;
684 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
685 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
686 shaderModule, // VkShaderModule module;
687 "main", // const char* pName;
688 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
690 const VkComputePipelineCreateInfo pipelineInfo =
692 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
693 DE_NULL, // const void* pNext;
694 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
695 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage;
696 pipelineLayout, // VkPipelineLayout layout;
697 DE_NULL, // VkPipeline basePipelineHandle;
698 0, // deInt32 basePipelineIndex;
700 return createComputePipeline(vk, device, DE_NULL , &pipelineInfo);
703 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
704 const VkDevice device,
705 const VkFormat colorFormat,
706 const deUint32 numLayers)
708 const VkAttachmentDescription colorAttachmentDescription =
710 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
711 colorFormat, // VkFormat format;
712 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
713 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
714 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
715 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
716 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
717 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
718 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
720 vector<VkAttachmentDescription> attachmentDescriptions(numLayers, colorAttachmentDescription);
722 // Create a subpass for each attachment (each attachement is a layer of an arrayed image).
723 vector<VkAttachmentReference> colorAttachmentReferences (numLayers);
724 vector<VkSubpassDescription> subpasses;
726 // Ordering here must match the framebuffer attachments
727 for (deUint32 i = 0; i < numLayers; ++i)
729 const VkAttachmentReference attachmentRef =
731 i, // deUint32 attachment;
732 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
735 colorAttachmentReferences[i] = attachmentRef;
737 const VkSubpassDescription subpassDescription =
739 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
740 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
741 0u, // deUint32 inputAttachmentCount;
742 DE_NULL, // const VkAttachmentReference* pInputAttachments;
743 1u, // deUint32 colorAttachmentCount;
744 &colorAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments;
745 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
746 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
747 0u, // deUint32 preserveAttachmentCount;
748 DE_NULL // const deUint32* pPreserveAttachments;
750 subpasses.push_back(subpassDescription);
753 const VkRenderPassCreateInfo renderPassInfo =
755 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
756 DE_NULL, // const void* pNext;
757 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
758 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
759 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
760 static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount;
761 &subpasses[0], // const VkSubpassDescription* pSubpasses;
762 0u, // deUint32 dependencyCount;
763 DE_NULL // const VkSubpassDependency* pDependencies;
766 return createRenderPass(vk, device, &renderPassInfo);
769 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk,
770 const VkDevice device,
771 const VkRenderPass renderPass,
772 const deUint32 attachmentCount,
773 const VkImageView* pAttachments,
776 const VkFramebufferCreateInfo framebufferInfo =
778 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
780 (VkFramebufferCreateFlags)0,
784 static_cast<deUint32>(size.x()),
785 static_cast<deUint32>(size.y()),
789 return createFramebuffer(vk, device, &framebufferInfo);
792 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
794 return allocateCommandBuffer(vk, device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
797 MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
799 MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
800 VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
804 MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
806 MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
807 VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
811 vector<Vec4> genVertexData (const CaseDef& caseDef)
813 vector<Vec4> vectorData;
814 const bool isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);
816 for (deUint32 z = 0; z < caseDef.numLayers; z++)
818 const deUint32 colorIdx = z % COLOR_TABLE_SIZE;
823 const VkClearValue clearValue = getClearValueInt(caseDef, colorIdx);
824 const IVec4 colorInt (clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);
826 color = colorInt.cast<float>();
830 color = COLOR_TABLE_FLOAT[colorIdx];
833 vectorData.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
834 vectorData.push_back(color);
835 vectorData.push_back(Vec4(-1.0f, 1.0f, 0.0f, 1.0f));
836 vectorData.push_back(color);
837 vectorData.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
838 vectorData.push_back(color);
839 vectorData.push_back(Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
840 vectorData.push_back(color);
846 void generateExpectedImage(const tcu::PixelBufferAccess& image, const CaseDef& caseDef)
848 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(image.getFormat().type);
849 const bool isIntegerFormat = channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
850 const IVec2 size = caseDef.size.swizzle(0, 1);
852 for (int z = 0; z < static_cast<int>(caseDef.numLayers); z++)
854 const deUint32 colorIdx = z % COLOR_TABLE_SIZE;
855 for (int y = 0; y < size.y(); y++)
856 for (int x = 0; x < size.x(); x++)
860 const VkClearValue clearValue = getClearValueInt(caseDef, colorIdx);
861 const IVec4 colorInt (clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);
863 image.setPixel(colorInt, x, y, z);
866 if(isSRGBConversionRequired(caseDef))
867 image.setPixel(tcu::linearToSRGB(COLOR_TABLE_FLOAT[colorIdx]), x, y, z);
869 image.setPixel(COLOR_TABLE_FLOAT[colorIdx], x, y, z);
874 VkImageUsageFlags getImageUsageForTestCase (const CaseDef& caseDef)
876 VkImageUsageFlags flags = 0u;
878 switch (caseDef.upload)
881 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
884 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
887 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
890 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
893 DE_FATAL("Invalid upload method");
897 switch (caseDef.download)
899 case DOWNLOAD_TEXTURE:
900 flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
903 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
906 flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
909 DE_FATAL("Invalid download method");
913 // We can only create a view for the image if it is going to be used for any of these usages,
914 // so let's make sure that we have at least one of them.
915 VkImageUsageFlags viewRequiredFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
916 if (!(flags & viewRequiredFlags))
917 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
922 // Executes a combination of upload/download methods
923 class UploadDownloadExecutor
926 UploadDownloadExecutor(Context& context, VkDevice device, VkQueue queue, deUint32 queueFamilyIndex, const CaseDef& caseSpec) :
928 m_haveMaintenance2(isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance2")),
929 m_vk(context.getDeviceInterface()),
932 m_queueFamilyIndex(queueFamilyIndex),
933 m_allocator(context.getDeviceInterface(), device,
934 getPhysicalDeviceMemoryProperties(context.getInstanceInterface(),
935 context.getPhysicalDevice()))
939 void runSwapchain(Context& context, VkBuffer buffer, VkImage image);
941 void run(Context& context, VkBuffer buffer);
944 void uploadClear(Context& context);
945 void uploadStore(Context& context);
946 void uploadCopy(Context& context);
947 void uploadDraw(Context& context);
948 void downloadCopy(Context& context, VkBuffer buffer);
949 void downloadTexture(Context& context, VkBuffer buffer);
950 void downloadLoad(Context& context, VkBuffer buffer);
952 void copyImageToBuffer(VkImage image,
955 const VkAccessFlags srcAccessMask,
956 const VkImageLayout oldLayout,
957 const deUint32 numLayers);
959 const CaseDef& m_caseDef;
961 bool m_haveMaintenance2;
963 const DeviceInterface& m_vk;
964 const VkDevice m_device;
965 const VkQueue m_queue;
966 const deUint32 m_queueFamilyIndex;
967 SimpleAllocator m_allocator;
969 Move<VkCommandPool> m_cmdPool;
970 Move<VkCommandBuffer> m_cmdBuffer;
972 bool m_imageIsIntegerFormat;
973 bool m_viewIsIntegerFormat;
975 // Target image for upload paths
977 Move<VkImage> m_imageHolder;
978 MovePtr<Allocation> m_imageAlloc;
983 Move<VkBuffer> colorBuffer;
984 VkDeviceSize colorBufferSize;
985 MovePtr<Allocation> colorBufferAlloc;
991 Move<VkBuffer> vertexBuffer;
992 MovePtr<Allocation> vertexBufferAlloc;
993 Move<VkPipelineLayout> pipelineLayout;
994 Move<VkRenderPass> renderPass;
995 Move<VkShaderModule> vertexModule;
996 Move<VkShaderModule> fragmentModule;
997 vector<SharedPtrVkImageView> attachments;
998 vector<VkImageView> attachmentHandles;
999 vector<SharedPtrVkPipeline> pipelines;
1000 Move<VkFramebuffer> framebuffer;
1006 Move<VkDescriptorPool> descriptorPool;
1007 Move<VkPipelineLayout> pipelineLayout;
1008 Move<VkDescriptorSetLayout> descriptorSetLayout;
1009 Move<VkDescriptorSet> descriptorSet;
1010 VkDescriptorImageInfo imageDescriptorInfo;
1011 Move<VkShaderModule> computeModule;
1012 Move<VkPipeline> computePipeline;
1013 Move<VkImageView> imageView;
1019 Move<VkDescriptorPool> descriptorPool;
1020 Move<VkPipelineLayout> pipelineLayout;
1021 Move<VkDescriptorSetLayout> descriptorSetLayout;
1022 Move<VkDescriptorSet> descriptorSet;
1023 Move<VkShaderModule> computeModule;
1024 Move<VkPipeline> computePipeline;
1025 Move<VkImageView> inImageView;
1026 VkDescriptorImageInfo inImageDescriptorInfo;
1027 Move<VkImage> outImage;
1028 Move<VkImageView> outImageView;
1029 MovePtr<Allocation> outImageAlloc;
1030 VkDescriptorImageInfo outImageDescriptorInfo;
1036 Move<VkDescriptorPool> descriptorPool;
1037 Move<VkPipelineLayout> pipelineLayout;
1038 Move<VkDescriptorSetLayout> descriptorSetLayout;
1039 Move<VkDescriptorSet> descriptorSet;
1040 Move<VkShaderModule> computeModule;
1041 Move<VkPipeline> computePipeline;
1042 Move<VkImageView> inImageView;
1043 VkDescriptorImageInfo inImageDescriptorInfo;
1044 Move<VkSampler> sampler;
1045 Move<VkImage> outImage;
1046 Move<VkImageView> outImageView;
1047 MovePtr<Allocation> outImageAlloc;
1048 VkDescriptorImageInfo outImageDescriptorInfo;
1051 VkImageLayout m_imageLayoutAfterUpload;
1052 VkAccessFlagBits m_imageUploadAccessMask;
1056 void UploadDownloadExecutor::runSwapchain(Context& context, VkBuffer buffer, VkImage image)
1058 m_imageIsIntegerFormat = isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat);
1059 m_viewIsIntegerFormat = isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat);
1061 m_cmdPool = createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex);
1062 m_cmdBuffer = makeCommandBuffer(m_vk, m_device, *m_cmdPool);
1063 beginCommandBuffer(m_vk, *m_cmdBuffer);
1067 switch (m_caseDef.upload)
1070 uploadDraw(context);
1073 uploadStore(context);
1076 uploadClear(context);
1079 uploadCopy(context);
1082 DE_FATAL("Unsupported upload method");
1085 switch (m_caseDef.download)
1088 downloadCopy(context, buffer);
1091 downloadLoad(context, buffer);
1093 case DOWNLOAD_TEXTURE:
1094 downloadTexture(context, buffer);
1097 DE_FATAL("Unsupported download method");
1100 endCommandBuffer(m_vk, *m_cmdBuffer);
1101 submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer);
1105 void UploadDownloadExecutor::run(Context& context, VkBuffer buffer)
1107 m_imageIsIntegerFormat = isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat);
1108 m_viewIsIntegerFormat = isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat);
1110 m_cmdPool = createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex);
1111 m_cmdBuffer = makeCommandBuffer(m_vk, m_device, *m_cmdPool);
1112 beginCommandBuffer(m_vk, *m_cmdBuffer);
1114 const VkImageUsageFlags imageUsage = getImageUsageForTestCase(m_caseDef);
1115 const VkImageCreateFlags imageFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | (m_haveMaintenance2 ? VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR : 0);
1117 m_imageHolder = makeImage(m_vk, m_device, imageFlags, getImageType(m_caseDef.imageType), m_caseDef.imageFormat, m_caseDef.viewFormat,
1118 m_caseDef.isFormatListTest, m_caseDef.size, 1u, m_caseDef.numLayers, imageUsage);
1119 m_image = *m_imageHolder;
1120 m_imageAlloc = bindImage(m_vk, m_device, m_allocator, m_image, MemoryRequirement::Any);
1122 switch (m_caseDef.upload)
1125 uploadDraw(context);
1128 uploadStore(context);
1131 uploadClear(context);
1134 uploadCopy(context);
1137 DE_FATAL("Unsupported upload method");
1140 switch (m_caseDef.download)
1143 downloadCopy(context, buffer);
1146 downloadLoad(context, buffer);
1148 case DOWNLOAD_TEXTURE:
1149 downloadTexture(context, buffer);
1152 DE_FATAL("Unsupported download method");
1155 endCommandBuffer(m_vk, *m_cmdBuffer);
1156 submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer);
1159 void UploadDownloadExecutor::uploadClear(Context& context)
1163 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1165 const VkImageSubresourceRange subresourceRange = makeColorSubresourceRange(0, m_caseDef.numLayers);
1166 const VkImageMemoryBarrier imageInitBarrier =
1168 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1169 DE_NULL, // const void* pNext;
1170 0u, // VkAccessFlags srcAccessMask;
1171 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAcessMask;
1172 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1173 requiredImageLayout, // VkImageLayout newLayout;
1174 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1175 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1176 m_image, // VkImage image;
1177 subresourceRange // VkImageSubresourceRange subresourceRange;
1180 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1181 0u, DE_NULL, 0u, DE_NULL, 1u, &imageInitBarrier);
1183 for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
1185 const VkImageSubresourceRange layerSubresourceRange = makeColorSubresourceRange(layer, 1u);
1186 const deUint32 colorIdx = layer % COLOR_TABLE_SIZE;
1187 const VkClearColorValue clearColor = m_imageIsIntegerFormat ? getClearValueInt(m_caseDef, colorIdx).color : REFERENCE_CLEAR_COLOR_FLOAT[colorIdx].color;
1188 m_vk.cmdClearColorImage(*m_cmdBuffer, m_image, requiredImageLayout, &clearColor, 1u, &layerSubresourceRange);
1191 m_imageLayoutAfterUpload = requiredImageLayout;
1192 m_imageUploadAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1195 void UploadDownloadExecutor::uploadStore(Context& context)
1197 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1199 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1200 DE_NULL, // const void* pNext
1201 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage;
1203 m_uStore.imageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1204 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1206 // Setup compute pipeline
1207 m_uStore.descriptorPool = DescriptorPoolBuilder()
1208 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1209 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1211 m_uStore.descriptorSetLayout = DescriptorSetLayoutBuilder()
1212 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1213 .build(m_vk, m_device);
1215 m_uStore.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_uStore.descriptorSetLayout);
1216 m_uStore.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_uStore.descriptorPool, *m_uStore.descriptorSetLayout);
1217 m_uStore.imageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_uStore.imageView, VK_IMAGE_LAYOUT_GENERAL);
1218 m_uStore.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadStoreComp"), 0);
1219 m_uStore.computePipeline = makeComputePipeline(m_vk, m_device, *m_uStore.pipelineLayout, *m_uStore.computeModule, DE_NULL);
1221 DescriptorSetUpdateBuilder()
1222 .writeSingle(*m_uStore.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_uStore.imageDescriptorInfo)
1223 .update(m_vk, m_device);
1225 // Transition storage image for shader access (imageStore)
1226 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1227 const VkImageMemoryBarrier imageBarrier =
1229 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1230 DE_NULL, // const void* pNext;
1231 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1232 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1233 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1234 requiredImageLayout, // VkImageLayout newLayout;
1235 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1236 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1237 m_image, // VkImage image;
1238 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1241 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1242 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
1245 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.computePipeline);
1246 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.pipelineLayout, 0u, 1u, &m_uStore.descriptorSet.get(), 0u, DE_NULL);
1247 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1249 m_imageLayoutAfterUpload = requiredImageLayout;
1250 m_imageUploadAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
1253 void UploadDownloadExecutor::uploadCopy(Context& context)
1257 // Create a host-mappable buffer with the color data to upload
1258 const VkDeviceSize pixelSize = tcu::getPixelSize(mapVkFormat(m_caseDef.imageFormat));
1259 const VkDeviceSize layerSize = m_caseDef.size.x() * m_caseDef.size.y() * m_caseDef.size.z() * pixelSize;
1261 m_uCopy.colorBufferSize = layerSize * m_caseDef.numLayers;
1262 m_uCopy.colorBuffer = makeBuffer(m_vk, m_device, m_uCopy.colorBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
1263 m_uCopy.colorBufferAlloc = bindBuffer(m_vk, m_device, m_allocator, *m_uCopy.colorBuffer, MemoryRequirement::HostVisible);
1265 // Fill color buffer
1266 const tcu::TextureFormat tcuFormat = mapVkFormat(m_caseDef.imageFormat);
1267 VkDeviceSize layerOffset = 0ull;
1268 for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
1270 tcu::PixelBufferAccess imageAccess = tcu::PixelBufferAccess(tcuFormat, m_caseDef.size.x(), m_caseDef.size.y(), 1u, (deUint8*) m_uCopy.colorBufferAlloc->getHostPtr() + layerOffset);
1271 const deUint32 colorIdx = layer % COLOR_TABLE_SIZE;
1272 if (m_imageIsIntegerFormat)
1274 const VkClearValue clearValue = getClearValueInt(m_caseDef, colorIdx);
1275 const IVec4 colorInt (clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);
1277 tcu::clear(imageAccess, colorInt);
1280 tcu::clear(imageAccess, COLOR_TABLE_FLOAT[colorIdx]);
1281 layerOffset += layerSize;
1284 flushAlloc(m_vk, m_device, *(m_uCopy.colorBufferAlloc));
1286 // Prepare buffer and image for copy
1287 const VkBufferMemoryBarrier bufferInitBarrier =
1289 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1290 DE_NULL, // const void* pNext;
1291 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
1292 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1293 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1294 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1295 *m_uCopy.colorBuffer, // VkBuffer buffer;
1296 0ull, // VkDeviceSize offset;
1297 VK_WHOLE_SIZE, // VkDeviceSize size;
1300 const VkImageMemoryBarrier imageInitBarrier =
1302 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1303 DE_NULL, // const void* pNext;
1304 0u, // VkAccessFlags srcAccessMask;
1305 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1306 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1307 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1308 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1309 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1310 m_image, // VkImage image;
1311 makeColorSubresourceRange(0, m_caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
1314 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1315 0u, DE_NULL, 1u, &bufferInitBarrier, 1u, &imageInitBarrier);
1317 // Copy buffer to image
1318 const VkImageSubresourceLayers subresource =
1320 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1321 0u, // deUint32 mipLevel;
1322 0u, // deUint32 baseArrayLayer;
1323 m_caseDef.numLayers, // deUint32 layerCount;
1326 const VkBufferImageCopy region =
1328 0ull, // VkDeviceSize bufferOffset;
1329 0u, // deUint32 bufferRowLength;
1330 0u, // deUint32 bufferImageHeight;
1331 subresource, // VkImageSubresourceLayers imageSubresource;
1332 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
1333 makeExtent3D(m_caseDef.size), // VkExtent3D imageExtent;
1336 m_vk.cmdCopyBufferToImage(*m_cmdBuffer, *m_uCopy.colorBuffer, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ®ion);
1338 const VkImageMemoryBarrier imagePostInitBarrier =
1340 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1341 DE_NULL, // const void* pNext;
1342 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1343 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1344 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1345 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1346 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1347 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1348 m_image, // VkImage image;
1349 makeColorSubresourceRange(0, m_caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
1352 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1353 0u, DE_NULL, 0u, DE_NULL, 1u, &imagePostInitBarrier);
1355 m_imageLayoutAfterUpload = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1356 m_imageUploadAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1359 void UploadDownloadExecutor::uploadDraw(Context& context)
1361 // Create vertex buffer
1363 const vector<Vec4> vertices = genVertexData(m_caseDef);
1364 const VkDeviceSize vertexBufferSize = vertices.size() * sizeof(Vec4);
1366 m_uDraw.vertexBuffer = makeBuffer(m_vk, m_device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
1367 m_uDraw.vertexBufferAlloc = bindBuffer(m_vk, m_device, m_allocator, *m_uDraw.vertexBuffer, MemoryRequirement::HostVisible);
1368 deMemcpy(m_uDraw.vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
1369 flushAlloc(m_vk, m_device, *(m_uDraw.vertexBufferAlloc));
1372 // Create attachments and pipelines for each image layer
1373 m_uDraw.pipelineLayout = makePipelineLayout(m_vk, m_device);
1374 m_uDraw.renderPass = makeRenderPass(m_vk, m_device, m_caseDef.viewFormat, m_caseDef.numLayers);
1375 m_uDraw.vertexModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawVert"), 0u);
1376 m_uDraw.fragmentModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawFrag"), 0u);
1378 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
1380 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1382 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1383 DE_NULL, // const void* pNext
1384 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags usage;
1386 Move<VkImageView> imageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1387 makeColorSubresourceRange(subpassNdx, 1), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1388 m_uDraw.attachmentHandles.push_back(*imageView);
1389 m_uDraw.attachments.push_back(makeSharedPtr(imageView));
1390 m_uDraw.pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(m_vk, m_device, *m_uDraw.pipelineLayout, *m_uDraw.renderPass, *m_uDraw.vertexModule, *m_uDraw.fragmentModule,
1391 m_caseDef.size.swizzle(0, 1), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, subpassNdx)));
1394 // Create framebuffer
1395 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));
1397 // Create command buffer
1400 vector<VkClearValue> clearValues (m_caseDef.numLayers, m_viewIsIntegerFormat ? getClearValueInt(m_caseDef, 0) : REFERENCE_CLEAR_COLOR_FLOAT[0]);
1402 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]);
1406 const VkDeviceSize vertexDataPerDraw = 4 * 2 * sizeof(Vec4);
1407 VkDeviceSize vertexBufferOffset = 0ull;
1408 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
1410 if (subpassNdx != 0)
1411 m_vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
1413 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_uDraw.pipelines[subpassNdx]);
1415 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_uDraw.vertexBuffer.get(), &vertexBufferOffset);
1416 m_vk.cmdDraw(*m_cmdBuffer, 4u, 1u, 0u, 0u);
1417 vertexBufferOffset += vertexDataPerDraw;
1420 endRenderPass(m_vk, *m_cmdBuffer);
1423 m_imageLayoutAfterUpload = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1424 m_imageUploadAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1427 void UploadDownloadExecutor::downloadCopy(Context& context, VkBuffer buffer)
1431 copyImageToBuffer(m_image, buffer, m_caseDef.size, m_imageUploadAccessMask, m_imageLayoutAfterUpload, m_caseDef.numLayers);
1434 void UploadDownloadExecutor::downloadTexture(Context& context, VkBuffer buffer)
1436 // Create output image with download result
1437 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1438 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);
1439 m_dTex.outImageAlloc = bindImage(m_vk, m_device, m_allocator, *m_dTex.outImage, MemoryRequirement::Any);
1440 m_dTex.outImageView = makeImageView(m_vk, m_device, *m_dTex.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));
1442 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1444 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1445 DE_NULL, // const void* pNext
1446 VK_IMAGE_USAGE_SAMPLED_BIT, // VkImageUsageFlags usage;
1448 m_dTex.inImageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1449 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1450 m_dTex.sampler = makeSampler(m_vk, m_device);
1452 // Setup compute pipeline
1453 m_dTex.descriptorPool = DescriptorPoolBuilder()
1454 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1455 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1456 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1458 m_dTex.descriptorSetLayout = DescriptorSetLayoutBuilder()
1459 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT, &m_dTex.sampler.get())
1460 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1461 .build(m_vk, m_device);
1463 m_dTex.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_dTex.descriptorSetLayout);
1464 m_dTex.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_dTex.descriptorPool, *m_dTex.descriptorSetLayout);
1465 m_dTex.inImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dTex.inImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1466 m_dTex.outImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dTex.outImageView, VK_IMAGE_LAYOUT_GENERAL);
1467 m_dTex.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadTextureComp"), 0);
1468 m_dTex.computePipeline = makeComputePipeline(m_vk, m_device, *m_dTex.pipelineLayout, *m_dTex.computeModule, DE_NULL);
1470 DescriptorSetUpdateBuilder()
1471 .writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &m_dTex.inImageDescriptorInfo)
1472 .writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dTex.outImageDescriptorInfo)
1473 .update(m_vk, m_device);
1475 // Transition images for shader access (texture / imageStore)
1476 const VkImageMemoryBarrier imageBarriers[] =
1479 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1480 DE_NULL, // const void* pNext;
1481 (VkAccessFlags)m_imageUploadAccessMask, // VkAccessFlags srcAccessMask;
1482 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
1483 m_imageLayoutAfterUpload, // VkImageLayout oldLayout;
1484 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
1485 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1486 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1487 m_image, // VkImage image;
1488 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1491 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1492 DE_NULL, // const void* pNext;
1493 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1494 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1495 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1496 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout;
1497 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1498 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1499 *m_dTex.outImage, // VkImage image;
1500 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1504 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1505 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
1508 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.computePipeline);
1509 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.pipelineLayout, 0u, 1u, &m_dTex.descriptorSet.get(), 0u, DE_NULL);
1510 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1512 // Copy output image to color buffer
1513 copyImageToBuffer(*m_dTex.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL, m_caseDef.numLayers);
1516 void UploadDownloadExecutor::downloadLoad(Context& context, VkBuffer buffer)
1518 // Create output image with download result
1519 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1520 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);
1521 m_dLoad.outImageAlloc = bindImage(m_vk, m_device, m_allocator, *m_dLoad.outImage, MemoryRequirement::Any);
1522 m_dLoad.outImageView = makeImageView(m_vk, m_device, *m_dLoad.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));
1524 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1526 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1527 DE_NULL, // const void* pNext
1528 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage;
1530 m_dLoad.inImageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1531 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1533 // Setup compute pipeline
1534 m_dLoad.descriptorPool = DescriptorPoolBuilder()
1535 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2u)
1536 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1538 m_dLoad.descriptorSetLayout = DescriptorSetLayoutBuilder()
1539 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1540 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1541 .build(m_vk, m_device);
1543 m_dLoad.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_dLoad.descriptorSetLayout);
1544 m_dLoad.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_dLoad.descriptorPool, *m_dLoad.descriptorSetLayout);
1545 m_dLoad.inImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dLoad.inImageView, VK_IMAGE_LAYOUT_GENERAL);
1546 m_dLoad.outImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dLoad.outImageView, VK_IMAGE_LAYOUT_GENERAL);
1547 m_dLoad.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadLoadComp"), 0);
1548 m_dLoad.computePipeline = makeComputePipeline(m_vk, m_device, *m_dLoad.pipelineLayout, *m_dLoad.computeModule, DE_NULL);
1550 DescriptorSetUpdateBuilder()
1551 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.inImageDescriptorInfo)
1552 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.outImageDescriptorInfo)
1553 .update(m_vk, m_device);
1555 // Transition storage images for shader access (imageLoad/Store)
1556 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1557 const VkImageMemoryBarrier imageBarriers[] =
1560 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1561 DE_NULL, // const void* pNext;
1562 (VkAccessFlags)m_imageUploadAccessMask, // VkAccessFlags srcAccessMask;
1563 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
1564 m_imageLayoutAfterUpload, // VkImageLayout oldLayout;
1565 requiredImageLayout, // VkImageLayout newLayout;
1566 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1567 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1568 m_image, // VkImage image;
1569 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1572 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1573 DE_NULL, // const void* pNext;
1574 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1575 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1576 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1577 requiredImageLayout, // VkImageLayout newLayout;
1578 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1579 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1580 *m_dLoad.outImage, // VkImage image;
1581 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1585 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1586 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
1589 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.computePipeline);
1590 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.pipelineLayout, 0u, 1u, &m_dLoad.descriptorSet.get(), 0u, DE_NULL);
1591 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1593 // Copy output image to color buffer
1594 copyImageToBuffer(*m_dLoad.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, requiredImageLayout, m_caseDef.numLayers);
1597 void UploadDownloadExecutor::copyImageToBuffer(VkImage sourceImage,
1600 const VkAccessFlags srcAccessMask,
1601 const VkImageLayout oldLayout,
1602 const deUint32 numLayers)
1604 // Copy result to host visible buffer for inspection
1605 const VkImageMemoryBarrier imageBarrier =
1607 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1608 DE_NULL, // const void* pNext;
1609 srcAccessMask, // VkAccessFlags srcAccessMask;
1610 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1611 oldLayout, // VkImageLayout oldLayout;
1612 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
1613 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1614 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1615 sourceImage, // VkImage image;
1616 makeColorSubresourceRange(0, numLayers) // VkImageSubresourceRange subresourceRange;
1619 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1620 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
1622 const VkImageSubresourceLayers subresource =
1624 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1625 0u, // deUint32 mipLevel;
1626 0u, // deUint32 baseArrayLayer;
1627 numLayers, // deUint32 layerCount;
1630 const VkBufferImageCopy region =
1632 0ull, // VkDeviceSize bufferOffset;
1633 0u, // deUint32 bufferRowLength;
1634 0u, // deUint32 bufferImageHeight;
1635 subresource, // VkImageSubresourceLayers imageSubresource;
1636 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
1637 makeExtent3D(size), // VkExtent3D imageExtent;
1640 m_vk.cmdCopyImageToBuffer(*m_cmdBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, ®ion);
1642 const VkBufferMemoryBarrier bufferBarrier =
1644 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1645 DE_NULL, // const void* pNext;
1646 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1647 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
1648 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1649 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1650 buffer, // VkBuffer buffer;
1651 0ull, // VkDeviceSize offset;
1652 VK_WHOLE_SIZE, // VkDeviceSize size;
1655 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
1656 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
1659 tcu::TestStatus testMutable (Context& context, const CaseDef caseDef)
1661 const DeviceInterface& vk = context.getDeviceInterface();
1662 const InstanceInterface& vki = context.getInstanceInterface();
1663 const VkDevice device = context.getDevice();
1664 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
1665 Allocator& allocator = context.getDefaultAllocator();
1667 // If this is a VK_KHR_image_format_list test, check that the extension is supported
1668 if (caseDef.isFormatListTest && !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_image_format_list"))
1669 TCU_THROW(NotSupportedError, "VK_KHR_image_format_list not supported");
1671 // Check required features on the format for the required upload/download methods
1672 VkFormatProperties imageFormatProps, viewFormatProps;
1673 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.imageFormat, &imageFormatProps);
1674 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.viewFormat, &viewFormatProps);
1676 VkFormatFeatureFlags viewFormatFeatureFlags = 0u;
1677 switch (caseDef.upload)
1680 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
1683 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1686 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1689 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1692 DE_FATAL("Invalid upload method");
1695 switch (caseDef.download)
1697 case DOWNLOAD_TEXTURE:
1698 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
1699 // For the texture case we write the samples read to a separate output image with the same view format
1700 // so we need to check that we can also use the view format for storage
1701 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1704 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1707 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1710 DE_FATAL("Invalid download method");
1714 if ((viewFormatFeatureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) &&
1715 isStorageImageExtendedFormat(caseDef.viewFormat) &&
1716 !getPhysicalDeviceFeatures(vki, physDevice).shaderStorageImageExtendedFormats)
1718 TCU_THROW(NotSupportedError, "View format requires shaderStorageImageExtended");
1721 if ((viewFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags)
1722 TCU_THROW(NotSupportedError, "View format doesn't support upload/download method");
1724 const bool haveMaintenance2 = isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance2");
1726 // We don't use the base image for anything other than transfer
1727 // operations so there are no features to check. However, The Vulkan
1728 // 1.0 spec does not allow us to create an image view with usage that
1729 // is not supported by the main format. With VK_KHR_maintenance2, we
1730 // can do this via VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR.
1731 if ((imageFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags &&
1734 TCU_THROW(NotSupportedError, "Image format doesn't support upload/download method");
1737 // If no format feature flags are supported, the format itself is not supported,
1738 // and images of that format cannot be created.
1739 if (imageFormatProps.optimalTilingFeatures == 0)
1741 TCU_THROW(NotSupportedError, "Base image format is not supported");
1744 // Create a color buffer for host-inspection of results
1745 // For the Copy download method, this is the target of the download, for other
1746 // download methods, pixel data will be copied to this buffer from the download
1748 const VkDeviceSize colorBufferSize = caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat));
1749 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1750 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1751 deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
1752 flushAlloc(vk, device, *colorBufferAlloc);
1755 UploadDownloadExecutor executor(context, device, context.getUniversalQueue(), context.getUniversalQueueFamilyIndex(), caseDef);
1756 executor.run(context, *colorBuffer);
1760 invalidateAlloc(vk, device, *colorBufferAlloc);
1762 // For verification purposes, we use the format of the upload to generate the expected image
1763 const VkFormat format = caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat;
1764 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
1765 const bool isIntegerFormat = isUintFormat(format) || isIntFormat(format);
1766 const tcu::ConstPixelBufferAccess resultImage (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr());
1767 tcu::TextureLevel textureLevel (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers);
1768 const tcu::PixelBufferAccess expectedImage = textureLevel.getAccess();
1769 generateExpectedImage(expectedImage, caseDef);
1772 if (isIntegerFormat)
1773 ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
1775 ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
1776 return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
1780 tcu::TestCaseGroup* createImageMutableTests (TestContext& testCtx)
1782 de::MovePtr<TestCaseGroup> testGroup (new TestCaseGroup(testCtx, "mutable", "Cases with mutable images"));
1783 for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx)
1785 const Texture& texture = s_textures[textureNdx];
1786 de::MovePtr<tcu::TestCaseGroup> groupByImageViewType (new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), ""));
1788 for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++imageFormatNdx)
1789 for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++viewFormatNdx)
1791 if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_formats[imageFormatNdx], s_formats[viewFormatNdx]))
1793 for (int upload = 0; upload < UPLOAD_LAST; upload++)
1795 if (upload == UPLOAD_STORE && !isFormatImageLoadStoreCapable(s_formats[viewFormatNdx]))
1798 for (int download = 0; download < DOWNLOAD_LAST; download++)
1800 if ((download == DOWNLOAD_LOAD || download == DOWNLOAD_TEXTURE) &&
1801 !isFormatImageLoadStoreCapable(s_formats[viewFormatNdx]))
1807 texture.layerSize(),
1808 static_cast<deUint32>(texture.numLayers()),
1809 s_formats[imageFormatNdx],
1810 s_formats[viewFormatNdx],
1811 static_cast<enum Upload>(upload),
1812 static_cast<enum Download>(download),
1813 false, // isFormatListTest;
1814 false, // isSwapchainImageTest
1815 vk::wsi::TYPE_LAST // wsiType
1818 std::string caseName = getFormatShortString(s_formats[imageFormatNdx]) + "_" + getFormatShortString(s_formats[viewFormatNdx]) +
1819 "_" + getUploadString(upload) + "_" + getDownloadString(download);
1820 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", initPrograms, testMutable, caseDef);
1822 caseDef.isFormatListTest = true;
1823 caseName += "_format_list";
1824 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", initPrograms, testMutable, caseDef);
1830 testGroup->addChild(groupByImageViewType.release());
1833 return testGroup.release();
1836 typedef vector<VkExtensionProperties> Extensions;
1838 void checkAllSupported(const Extensions& supportedExtensions, const vector<string>& requiredExtensions)
1840 for (vector<string>::const_iterator requiredExtName = requiredExtensions.begin();
1841 requiredExtName != requiredExtensions.end();
1844 if (!isExtensionSupported(supportedExtensions, RequiredExtension(*requiredExtName)))
1845 TCU_THROW(NotSupportedError, (*requiredExtName + " is not supported").c_str());
1849 Move<VkInstance> createInstanceWithWsi(const PlatformInterface& vkp,
1851 const Extensions& supportedExtensions,
1853 const VkAllocationCallbacks* pAllocator = DE_NULL)
1855 vector<string> extensions;
1857 extensions.push_back("VK_KHR_surface");
1858 extensions.push_back(getExtensionName(wsiType));
1860 // VK_EXT_swapchain_colorspace adds new surface formats. Driver can enumerate
1861 // the formats regardless of whether VK_EXT_swapchain_colorspace was enabled,
1862 // but using them without enabling the extension is not allowed. Thus we have
1865 // 1) Filter out non-core formats to stay within valid usage.
1867 // 2) Enable VK_EXT_swapchain colorspace if advertised by the driver.
1869 // We opt for (2) as it provides basic coverage for the extension as a bonus.
1870 if (isExtensionSupported(supportedExtensions, RequiredExtension("VK_EXT_swapchain_colorspace")))
1871 extensions.push_back("VK_EXT_swapchain_colorspace");
1873 checkAllSupported(supportedExtensions, extensions);
1875 return vk::createDefaultInstance(vkp, version, vector<string>(), extensions, pAllocator);
1879 Move<VkDevice> createDeviceWithWsi(const PlatformInterface& vkp,
1880 VkInstance instance,
1881 const InstanceInterface& vki,
1882 VkPhysicalDevice physicalDevice,
1883 const Extensions& supportedExtensions,
1884 const deUint32 queueFamilyIndex,
1885 const VkAllocationCallbacks* pAllocator = DE_NULL)
1887 const float queuePriorities[] = { 1.0f };
1888 const VkDeviceQueueCreateInfo queueInfos[] =
1891 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1893 (VkDeviceQueueCreateFlags)0,
1895 DE_LENGTH_OF_ARRAY(queuePriorities),
1899 VkPhysicalDeviceFeatures features;
1900 deMemset(&features, 0x0, sizeof(features));
1902 const char* const extensions[] = { "VK_KHR_swapchain", "VK_KHR_swapchain_mutable_format" };
1903 const VkDeviceCreateInfo deviceParams =
1905 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1907 (VkDeviceCreateFlags)0,
1908 DE_LENGTH_OF_ARRAY(queueInfos),
1910 0u, // enabledLayerCount
1911 DE_NULL, // ppEnabledLayerNames
1912 DE_LENGTH_OF_ARRAY(extensions), // enabledExtensionCount
1913 DE_ARRAY_BEGIN(extensions), // ppEnabledExtensionNames
1917 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(extensions); ++ndx)
1919 if (!isExtensionSupported(supportedExtensions, RequiredExtension(extensions[ndx])))
1920 TCU_THROW(NotSupportedError, (string(extensions[ndx]) + " is not supported").c_str());
1923 return createDevice(vkp, instance, vki, physicalDevice, &deviceParams, pAllocator);
1926 deUint32 getNumQueueFamilyIndices(const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
1928 deUint32 numFamilies = 0;
1930 vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
1935 vector<deUint32> getSupportedQueueFamilyIndices(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
1937 const deUint32 numTotalFamilyIndices = getNumQueueFamilyIndices(vki, physicalDevice);
1938 vector<deUint32> supportedFamilyIndices;
1940 for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
1942 if (getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
1943 supportedFamilyIndices.push_back(queueFamilyNdx);
1946 return supportedFamilyIndices;
1949 deUint32 chooseQueueFamilyIndex(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
1951 const vector<deUint32> supportedFamilyIndices = getSupportedQueueFamilyIndices(vki, physicalDevice, surface);
1953 if (supportedFamilyIndices.empty())
1954 TCU_THROW(NotSupportedError, "Device doesn't support presentation");
1956 return supportedFamilyIndices[0];
1959 struct InstanceHelper
1961 const vector<VkExtensionProperties> supportedExtensions;
1962 const Unique<VkInstance> instance;
1963 const InstanceDriver vki;
1965 InstanceHelper(Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
1966 : supportedExtensions(enumerateInstanceExtensionProperties(context.getPlatformInterface(),
1968 , instance(createInstanceWithWsi(context.getPlatformInterface(),
1969 context.getUsedApiVersion(),
1970 supportedExtensions,
1973 , vki(context.getPlatformInterface(), *instance)
1980 const VkPhysicalDevice physicalDevice;
1981 const deUint32 queueFamilyIndex;
1982 const Unique<VkDevice> device;
1983 const DeviceDriver vkd;
1984 const VkQueue queue;
1986 DeviceHelper(Context& context,
1987 const InstanceInterface& vki,
1988 VkInstance instance,
1989 VkSurfaceKHR surface,
1990 const VkAllocationCallbacks* pAllocator = DE_NULL)
1991 : physicalDevice(chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
1992 , queueFamilyIndex(chooseQueueFamilyIndex(vki, physicalDevice, surface))
1993 , device(createDeviceWithWsi(context.getPlatformInterface(),
1994 context.getInstance(),
1997 enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL),
2000 , vkd(context.getPlatformInterface(), context.getInstance(), *device)
2001 , queue(getDeviceQueue(vkd, *device, queueFamilyIndex, 0))
2006 MovePtr<Display> createDisplay(const vk::Platform& platform,
2007 const Extensions& supportedExtensions,
2012 return MovePtr<Display>(platform.createWsiDisplay(wsiType));
2014 catch (const tcu::NotSupportedError& e)
2016 if (isExtensionSupported(supportedExtensions, RequiredExtension(getExtensionName(wsiType))) &&
2017 platform.hasDisplay(wsiType))
2019 // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
2020 // must support creating native display & window for that WSI type.
2021 throw tcu::TestError(e.getMessage());
2028 MovePtr<Window> createWindow(const Display& display, const Maybe<UVec2>& initialSize)
2032 return MovePtr<Window>(display.createWindow(initialSize));
2034 catch (const tcu::NotSupportedError& e)
2036 // See createDisplay - assuming that wsi::Display was supported platform port
2037 // should also support creating a window.
2038 throw tcu::TestError(e.getMessage());
2042 struct NativeObjects
2044 const UniquePtr<Display> display;
2045 const UniquePtr<Window> window;
2047 NativeObjects(Context& context,
2048 const Extensions& supportedExtensions,
2050 const Maybe<UVec2>& initialWindowSize = tcu::nothing<UVec2>())
2051 : display(createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
2052 , window(createWindow(*display, initialWindowSize))
2056 Move<VkSwapchainKHR> makeSwapchain(const DeviceInterface& vk,
2057 const VkDevice device,
2058 const vk::wsi::Type wsiType,
2059 const VkSurfaceKHR surface,
2060 const VkSurfaceCapabilitiesKHR capabilities,
2061 const VkSurfaceFormatKHR surfaceFormat,
2062 const VkFormat viewFormat,
2063 const deUint32 numLayers,
2064 const VkImageUsageFlags usage,
2065 const tcu::UVec2& desiredSize,
2066 deUint32 desiredImageCount
2069 const VkFormat formatList[2] =
2071 surfaceFormat.format,
2075 const VkImageFormatListCreateInfoKHR formatListInfo =
2077 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR, // VkStructureType sType;
2078 DE_NULL, // const void* pNext;
2079 2u, // deUint32 viewFormatCount
2080 formatList // const VkFormat* pViewFormats
2083 const VkSurfaceTransformFlagBitsKHR transform = (capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
2084 const PlatformProperties& platformProperties = getPlatformProperties(wsiType);
2086 const VkSwapchainCreateInfoKHR swapchainInfo =
2088 VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, // VkStructureType sType;
2089 &formatListInfo, // const void* pNext;
2090 VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR, // VkSwapchainCreateFlagsKHR flags;
2091 surface, // VkSurfaceKHR surface;
2092 de::clamp(desiredImageCount, capabilities.minImageCount, capabilities.maxImageCount > 0 ? capabilities.maxImageCount : capabilities.minImageCount + desiredImageCount), // deUint32 minImageCount;
2093 surfaceFormat.format, // VkFormat imageFormat;
2094 surfaceFormat.colorSpace, // VkColorSpaceKHR imageColorSpace;
2095 (platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE
2096 ? capabilities.currentExtent : vk::makeExtent2D(desiredSize.x(), desiredSize.y())), // VkExtent2D imageExtent;
2097 numLayers, // deUint32 imageArrayLayers;
2098 usage, // VkImageUsageFlags imageUsage;
2099 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode imageSharingMode;
2100 0u, // deUint32 queueFamilyIndexCount;
2101 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2102 transform, // VkSurfaceTransformFlagBitsKHR preTransform;
2103 VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, // VkCompositeAlphaFlagBitsKHR compositeAlpha;
2104 VK_PRESENT_MODE_FIFO_KHR, // VkPresentModeKHR presentMode;
2105 VK_FALSE, // VkBool32 clipped;
2106 (VkSwapchainKHR)0 // VkSwapchainKHR oldSwapchain;
2109 return createSwapchainKHR(vk, device, &swapchainInfo);
2112 tcu::TestStatus testSwapchainMutable(Context& context, CaseDef caseDef)
2114 const Type wsiType(caseDef.wsiType);
2115 const tcu::UVec2 desiredSize(256, 256);
2116 const InstanceHelper instHelper(context, wsiType);
2117 const NativeObjects native(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
2118 const Unique<VkSurfaceKHR> surface(createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
2119 const DeviceHelper devHelper(context, instHelper.vki, *instHelper.instance, *surface);
2120 const DeviceInterface& vk = devHelper.vkd;
2121 const InstanceDriver& vki = instHelper.vki;
2122 const VkDevice device = *devHelper.device;
2123 const VkPhysicalDevice physDevice = devHelper.physicalDevice;
2125 SimpleAllocator allocator(vk, device, getPhysicalDeviceMemoryProperties(vki, context.getPhysicalDevice()));
2127 // Check required features on the format for the required upload/download methods
2128 VkFormatProperties imageFormatProps, viewFormatProps;
2129 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.imageFormat, &imageFormatProps);
2130 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.viewFormat, &viewFormatProps);
2132 const VkImageUsageFlags imageUsage = getImageUsageForTestCase(caseDef);
2135 VkImageFormatProperties properties;
2138 result = vki.getPhysicalDeviceImageFormatProperties(physDevice, caseDef.imageFormat, getImageType(caseDef.imageType), VK_IMAGE_TILING_OPTIMAL, imageUsage, 0, &properties);
2140 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
2142 TCU_THROW(NotSupportedError, "Image format is not supported for required usage");
2145 result = vki.getPhysicalDeviceImageFormatProperties(physDevice, caseDef.viewFormat, getImageType(caseDef.imageType), VK_IMAGE_TILING_OPTIMAL, imageUsage, 0, &properties);
2147 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
2149 TCU_THROW(NotSupportedError, "Image view format is not supported for required usage");
2153 const VkSurfaceCapabilitiesKHR capabilities = getPhysicalDeviceSurfaceCapabilities(vki,
2157 if (caseDef.numLayers > capabilities.maxImageArrayLayers)
2158 caseDef.numLayers = capabilities.maxImageArrayLayers;
2160 // Check support for requested formats by swapchain surface
2161 const vector<VkSurfaceFormatKHR> surfaceFormats = getPhysicalDeviceSurfaceFormats(vki,
2165 const VkSurfaceFormatKHR* surfaceFormat = DE_NULL;
2166 const VkFormat* viewFormat = DE_NULL;
2168 for (vector<VkSurfaceFormatKHR>::size_type i = 0; i < surfaceFormats.size(); i++)
2170 if (surfaceFormats[i].format == caseDef.imageFormat)
2171 surfaceFormat = &surfaceFormats[i];
2173 if (surfaceFormats[i].format == caseDef.viewFormat)
2174 viewFormat = &surfaceFormats[i].format;
2177 if (surfaceFormat == DE_NULL)
2178 TCU_THROW(NotSupportedError, "Image format is not supported by swapchain.");
2180 if (viewFormat == DE_NULL)
2181 TCU_THROW(NotSupportedError, "Image view format is not supported by swapchain.");
2183 if ((capabilities.supportedUsageFlags & imageUsage) != imageUsage)
2184 TCU_THROW(NotSupportedError, "Image usage request not supported by swapchain.");
2186 const Unique<VkSwapchainKHR> swapchain(
2200 const vector<VkImage> swapchainImages = getSwapchainImages(vk, device, *swapchain);
2202 VkFormatFeatureFlags viewFormatFeatureFlags = 0u;
2203 switch (caseDef.upload)
2206 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
2209 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
2212 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
2215 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
2218 DE_FATAL("Invalid upload method");
2221 switch (caseDef.download)
2223 case DOWNLOAD_TEXTURE:
2224 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
2225 // For the texture case we write the samples read to a separate output image with the same view format
2226 // so we need to check that we can also use the view format for storage
2227 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
2230 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
2233 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
2236 DE_FATAL("Invalid download method");
2240 if ((viewFormatFeatureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) &&
2241 isStorageImageExtendedFormat(caseDef.viewFormat) &&
2242 !getPhysicalDeviceFeatures(vki, physDevice).shaderStorageImageExtendedFormats)
2244 TCU_THROW(NotSupportedError, "View format requires shaderStorageImageExtended");
2247 if ((viewFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags)
2248 TCU_THROW(NotSupportedError, "View format doesn't support upload/download method");
2250 const bool haveMaintenance2 = isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance2");
2252 // We don't use the base image for anything other than transfer
2253 // operations so there are no features to check. However, The Vulkan
2254 // 1.0 spec does not allow us to create an image view with usage that
2255 // is not supported by the main format. With VK_KHR_maintenance2, we
2256 // can do this via VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR.
2257 if ((imageFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags &&
2260 TCU_THROW(NotSupportedError, "Image format doesn't support upload/download method");
2263 // If no format feature flags are supported, the format itself is not supported,
2264 // and images of that format cannot be created.
2265 if (imageFormatProps.optimalTilingFeatures == 0)
2267 TCU_THROW(NotSupportedError, "Base image format is not supported");
2270 // Create a color buffer for host-inspection of results
2271 // For the Copy download method, this is the target of the download, for other
2272 // download methods, pixel data will be copied to this buffer from the download
2274 const VkDeviceSize colorBufferSize = caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat));
2275 const Unique<VkBuffer> colorBuffer(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2276 const UniquePtr<Allocation> colorBufferAlloc(bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
2277 deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
2278 flushAlloc(vk, device, *colorBufferAlloc);
2282 UploadDownloadExecutor executor(context, device, devHelper.queue, devHelper.queueFamilyIndex, caseDef);
2284 executor.runSwapchain(context, *colorBuffer, swapchainImages[0]);
2288 invalidateAlloc(vk, device, *colorBufferAlloc);
2290 // For verification purposes, we use the format of the upload to generate the expected image
2291 const VkFormat format = caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat;
2292 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
2293 const bool isIntegerFormat = isUintFormat(format) || isIntFormat(format);
2294 const tcu::ConstPixelBufferAccess resultImage(tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr());
2295 tcu::TextureLevel textureLevel(tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers);
2296 const tcu::PixelBufferAccess expectedImage = textureLevel.getAccess();
2297 generateExpectedImage(expectedImage, caseDef);
2300 if (isIntegerFormat)
2301 ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
2303 ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
2304 return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
2308 tcu::TestCaseGroup* createSwapchainImageMutableTests(TestContext& testCtx)
2310 de::MovePtr<TestCaseGroup> testGroup(new TestCaseGroup(testCtx, "swapchain_mutable", "Cases with swapchain mutable images"));
2312 for (int typeNdx = 0; typeNdx < vk::wsi::TYPE_LAST; ++typeNdx)
2314 const vk::wsi::Type wsiType = (vk::wsi::Type)typeNdx;
2316 de::MovePtr<TestCaseGroup> testGroupWsi(new TestCaseGroup(testCtx, getName(wsiType), ""));
2318 for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx)
2320 const Texture& texture = s_textures[textureNdx];
2321 de::MovePtr<tcu::TestCaseGroup> groupByImageViewType(new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), ""));
2323 for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_swapchainFormats); ++imageFormatNdx)
2324 for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_swapchainFormats); ++viewFormatNdx)
2326 if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_swapchainFormats[imageFormatNdx], s_swapchainFormats[viewFormatNdx]))
2328 for (int upload = 0; upload < UPLOAD_LAST; upload++)
2330 if (upload == UPLOAD_STORE && !isFormatImageLoadStoreCapable(s_swapchainFormats[viewFormatNdx]))
2333 for (int download = 0; download < DOWNLOAD_LAST; download++)
2335 if ((download == DOWNLOAD_LOAD || download == DOWNLOAD_TEXTURE) &&
2336 !isFormatImageLoadStoreCapable(s_swapchainFormats[viewFormatNdx]))
2342 texture.layerSize(),
2343 static_cast<deUint32>(texture.numLayers()),
2344 s_swapchainFormats[imageFormatNdx],
2345 s_swapchainFormats[viewFormatNdx],
2346 static_cast<enum Upload>(upload),
2347 static_cast<enum Download>(download),
2348 true, // isFormatListTest;
2349 true, // isSwapchainImageTest
2353 std::string caseName = getFormatShortString(s_swapchainFormats[imageFormatNdx]) + "_" + getFormatShortString(s_swapchainFormats[viewFormatNdx]) +
2354 "_" + getUploadString(upload) + "_" + getDownloadString(download) + "_format_list";
2356 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", initPrograms, testSwapchainMutable, caseDef);
2362 testGroupWsi->addChild(groupByImageViewType.release());
2365 testGroup->addChild(testGroupWsi.release());
2367 return testGroup.release();