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)
293 // Following modes require VK_IMAGE_USAGE_STORAGE_BIT usage, not supported by srgb format
294 DE_ASSERT(caseDef.upload != UPLOAD_STORE);
295 DE_ASSERT(caseDef.download != DOWNLOAD_LOAD);
296 DE_ASSERT(caseDef.download != DOWNLOAD_TEXTURE);
303 inline bool formatsAreCompatible (const VkFormat format0, const VkFormat format1)
305 return format0 == format1 || mapVkFormat(format0).getPixelSize() == mapVkFormat(format1).getPixelSize();
308 std::string getColorFormatStr (const int numComponents, const bool isUint, const bool isSint)
310 std::ostringstream str;
311 if (numComponents == 1)
312 str << (isUint ? "uint" : isSint ? "int" : "float");
314 str << (isUint ? "u" : isSint ? "i" : "") << "vec" << numComponents;
319 std::string getShaderSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
321 std::ostringstream samplerType;
323 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
325 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
330 case VK_IMAGE_VIEW_TYPE_2D:
331 samplerType << "sampler2D";
334 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
335 samplerType << "sampler2DArray";
339 DE_FATAL("Ivalid image view type");
343 return samplerType.str();
346 void initPrograms (SourceCollections& programCollection, const CaseDef caseDef)
348 if (caseDef.upload == UPLOAD_DRAW)
351 std::ostringstream src;
352 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
354 << "layout(location = 0) in vec4 in_position;\n"
355 << "layout(location = 1) in vec4 in_color;\n"
356 << "layout(location = 0) out vec4 out_color;\n"
358 << "out gl_PerVertex {\n"
359 << " vec4 gl_Position;\n"
362 << "void main(void)\n"
364 << " gl_Position = in_position;\n"
365 << " out_color = in_color;\n"
368 programCollection.glslSources.add("uploadDrawVert") << glu::VertexSource(src.str());
372 const int numComponents = getNumUsedChannels(mapVkFormat(caseDef.viewFormat).order);
373 const bool isUint = isUintFormat(caseDef.viewFormat);
374 const bool isSint = isIntFormat(caseDef.viewFormat);
375 const std::string colorFormat = getColorFormatStr(numComponents, isUint, isSint);
377 std::ostringstream src;
378 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
380 << "layout(location = 0) in vec4 in_color;\n"
381 << "layout(location = 0) out " << colorFormat << " out_color;\n"
383 << "void main(void)\n"
385 << " out_color = " << colorFormat << "("
386 << (numComponents == 1 ? "in_color.r" :
387 numComponents == 2 ? "in_color.rg" :
388 numComponents == 3 ? "in_color.rgb" : "in_color")
392 programCollection.glslSources.add("uploadDrawFrag") << glu::FragmentSource(src.str());
396 if (caseDef.upload == UPLOAD_STORE)
398 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
399 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
400 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
401 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
402 const bool isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);
404 std::ostringstream src;
405 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
407 << "layout (local_size_x = 1) in;\n"
409 << "layout(binding=0, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " u_image;\n"
411 << "const " << colorTypeStr << " colorTable[] = " << colorTypeStr << "[](\n";
412 for (deUint32 idx = 0; idx < COLOR_TABLE_SIZE; idx++)
416 const VkClearValue clearValue = getClearValueInt(caseDef, idx);
418 src << " " << colorTypeStr << "(" << clearValue.color.int32[0] << ", " << clearValue.color.int32[1] << ", " << clearValue.color.int32[2] << ", " << clearValue.color.int32[3] << ")";
421 src << " " << colorTypeStr << "(" << COLOR_TABLE_FLOAT[idx].x() << ", " << COLOR_TABLE_FLOAT[idx].y() << ", " << COLOR_TABLE_FLOAT[idx].z() << ", " << COLOR_TABLE_FLOAT[idx].w() << ")";
422 if (idx < COLOR_TABLE_SIZE - 1)
428 << "void main(void)\n"
430 if (caseDef.imageType == IMAGE_TYPE_2D)
432 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
436 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
437 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
439 src << " " << colorTypeStr << " color = colorTable[gl_GlobalInvocationID.z];\n"
440 << " imageStore(u_image, pos, color);\n"
443 programCollection.glslSources.add("uploadStoreComp") << glu::ComputeSource(src.str());
446 if (caseDef.download == DOWNLOAD_LOAD)
448 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
449 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
450 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
451 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
453 std::ostringstream src;
454 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
456 << "layout (local_size_x = 1) in;\n"
458 << "layout(binding=0, " << imageFormatStr << ") readonly uniform " << imageTypeStr << " in_image;\n"
459 << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
461 << "void main(void)\n"
463 if (caseDef.imageType == IMAGE_TYPE_2D)
465 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
469 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
470 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
472 src << " imageStore(out_image, pos, imageLoad(in_image, pos));\n"
475 programCollection.glslSources.add("downloadLoadComp") << glu::ComputeSource(src.str());
478 if (caseDef.download == DOWNLOAD_TEXTURE)
480 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
481 const VkImageViewType viewType = getImageViewType(caseDef.imageType);
482 const std::string samplerTypeStr = getShaderSamplerType(tcuFormat, viewType);
483 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
484 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
485 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
487 std::ostringstream src;
488 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
490 << "layout (local_size_x = 1) in;\n"
492 << "layout(binding=0) uniform " << samplerTypeStr << " u_tex;\n"
493 << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
495 << "void main(void)\n"
497 if (caseDef.imageType == IMAGE_TYPE_2D)
499 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
503 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
504 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
506 src << " imageStore(out_image, pos, texelFetch(u_tex, pos, 0));\n"
509 programCollection.glslSources.add("downloadTextureComp") << glu::ComputeSource(src.str());
513 Move<VkImage> makeImage (const DeviceInterface& vk,
514 const VkDevice device,
515 VkImageCreateFlags flags,
516 VkImageType imageType,
517 const VkFormat format,
518 const VkFormat viewFormat,
519 const bool useImageFormatList,
521 const deUint32 numMipLevels,
522 const deUint32 numLayers,
523 const VkImageUsageFlags usage)
525 const VkFormat formatList[2] =
531 const VkImageFormatListCreateInfoKHR formatListInfo =
533 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR, // VkStructureType sType;
534 DE_NULL, // const void* pNext;
535 2u, // deUint32 viewFormatCount
536 formatList // const VkFormat* pViewFormats
539 const VkImageCreateInfo imageParams =
541 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
542 useImageFormatList ? &formatListInfo : DE_NULL, // const void* pNext;
543 flags, // VkImageCreateFlags flags;
544 imageType, // VkImageType imageType;
545 format, // VkFormat format;
546 makeExtent3D(size), // VkExtent3D extent;
547 numMipLevels, // deUint32 mipLevels;
548 numLayers, // deUint32 arrayLayers;
549 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
550 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
551 usage, // VkImageUsageFlags usage;
552 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
553 0u, // deUint32 queueFamilyIndexCount;
554 DE_NULL, // const deUint32* pQueueFamilyIndices;
555 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
557 return createImage(vk, device, &imageParams);
560 inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize bufferSize, const VkBufferUsageFlags usage)
562 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSize, usage);
563 return createBuffer(vk, device, &bufferCreateInfo);
566 inline VkImageSubresourceRange makeColorSubresourceRange (const int baseArrayLayer, const int layerCount)
568 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, static_cast<deUint32>(baseArrayLayer), static_cast<deUint32>(layerCount));
571 Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice device)
573 const VkSamplerCreateInfo samplerParams =
575 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
576 DE_NULL, // const void* pNext;
577 (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags;
578 VK_FILTER_NEAREST, // VkFilter magFilter;
579 VK_FILTER_NEAREST, // VkFilter minFilter;
580 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
581 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
582 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
583 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
584 0.0f, // float mipLodBias;
585 VK_FALSE, // VkBool32 anisotropyEnable;
586 1.0f, // float maxAnisotropy;
587 VK_FALSE, // VkBool32 compareEnable;
588 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
589 0.0f, // float minLod;
590 0.0f, // float maxLod;
591 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
592 VK_FALSE, // VkBool32 unnormalizedCoordinates;
595 return createSampler(vk, device, &samplerParams);
599 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk,
600 const VkDevice device)
602 const VkPipelineLayoutCreateInfo info =
604 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
606 (VkPipelineLayoutCreateFlags)0,
612 return createPipelineLayout(vk, device, &info);
615 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
616 const VkDevice device,
617 const VkPipelineLayout pipelineLayout,
618 const VkRenderPass renderPass,
619 const VkShaderModule vertexModule,
620 const VkShaderModule fragmentModule,
621 const IVec2& renderSize,
622 const VkPrimitiveTopology topology,
623 const deUint32 subpass)
625 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
626 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
628 const VkVertexInputBindingDescription vertexInputBindingDescription =
630 0u, // deUint32 binding;
631 (deUint32)(2 * sizeof(Vec4)), // deUint32 stride;
632 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
635 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
638 0u, // deUint32 location;
639 0u, // deUint32 binding;
640 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
641 0u, // deUint32 offset;
644 1u, // deUint32 location;
645 0u, // deUint32 binding;
646 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
647 (deUint32)sizeof(Vec4), // deUint32 offset;
651 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
653 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
654 DE_NULL, // const void* pNext;
655 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
656 1u, // deUint32 vertexBindingDescriptionCount;
657 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
658 2u, // deUint32 vertexAttributeDescriptionCount;
659 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
662 return vk::makeGraphicsPipeline(vk, // const DeviceInterface& vk
663 device, // const VkDevice device
664 pipelineLayout, // const VkPipelineLayout pipelineLayout
665 vertexModule, // const VkShaderModule vertexShaderModule
666 DE_NULL, // const VkShaderModule tessellationControlModule
667 DE_NULL, // const VkShaderModule tessellationEvalModule
668 DE_NULL, // const VkShaderModule geometryShaderModule
669 fragmentModule, // const VkShaderModule fragmentShaderModule
670 renderPass, // const VkRenderPass renderPass
671 viewports, // const std::vector<VkViewport>& viewports
672 scissors, // const std::vector<VkRect2D>& scissors
673 topology, // const VkPrimitiveTopology topology
674 subpass, // const deUint32 subpass
675 0u, // const deUint32 patchControlPoints
676 &vertexInputStateCreateInfo); // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
679 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
680 const VkDevice device,
681 const VkPipelineLayout pipelineLayout,
682 const VkShaderModule shaderModule,
683 const VkSpecializationInfo* specInfo)
685 const VkPipelineShaderStageCreateInfo shaderStageInfo =
687 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
688 DE_NULL, // const void* pNext;
689 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
690 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
691 shaderModule, // VkShaderModule module;
692 "main", // const char* pName;
693 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
695 const VkComputePipelineCreateInfo pipelineInfo =
697 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
698 DE_NULL, // const void* pNext;
699 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
700 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage;
701 pipelineLayout, // VkPipelineLayout layout;
702 DE_NULL, // VkPipeline basePipelineHandle;
703 0, // deInt32 basePipelineIndex;
705 return createComputePipeline(vk, device, DE_NULL , &pipelineInfo);
708 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
709 const VkDevice device,
710 const VkFormat colorFormat,
711 const deUint32 numLayers)
713 const VkAttachmentDescription colorAttachmentDescription =
715 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
716 colorFormat, // VkFormat format;
717 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
718 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
719 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
720 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
721 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
722 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
723 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
725 vector<VkAttachmentDescription> attachmentDescriptions(numLayers, colorAttachmentDescription);
727 // Create a subpass for each attachment (each attachement is a layer of an arrayed image).
728 vector<VkAttachmentReference> colorAttachmentReferences (numLayers);
729 vector<VkSubpassDescription> subpasses;
731 // Ordering here must match the framebuffer attachments
732 for (deUint32 i = 0; i < numLayers; ++i)
734 const VkAttachmentReference attachmentRef =
736 i, // deUint32 attachment;
737 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
740 colorAttachmentReferences[i] = attachmentRef;
742 const VkSubpassDescription subpassDescription =
744 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
745 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
746 0u, // deUint32 inputAttachmentCount;
747 DE_NULL, // const VkAttachmentReference* pInputAttachments;
748 1u, // deUint32 colorAttachmentCount;
749 &colorAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments;
750 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
751 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
752 0u, // deUint32 preserveAttachmentCount;
753 DE_NULL // const deUint32* pPreserveAttachments;
755 subpasses.push_back(subpassDescription);
758 const VkRenderPassCreateInfo renderPassInfo =
760 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
761 DE_NULL, // const void* pNext;
762 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
763 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
764 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
765 static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount;
766 &subpasses[0], // const VkSubpassDescription* pSubpasses;
767 0u, // deUint32 dependencyCount;
768 DE_NULL // const VkSubpassDependency* pDependencies;
771 return createRenderPass(vk, device, &renderPassInfo);
774 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk,
775 const VkDevice device,
776 const VkRenderPass renderPass,
777 const deUint32 attachmentCount,
778 const VkImageView* pAttachments,
781 const VkFramebufferCreateInfo framebufferInfo =
783 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
785 (VkFramebufferCreateFlags)0,
789 static_cast<deUint32>(size.x()),
790 static_cast<deUint32>(size.y()),
794 return createFramebuffer(vk, device, &framebufferInfo);
797 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
799 return allocateCommandBuffer(vk, device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
802 MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
804 MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
805 VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
809 MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
811 MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
812 VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
816 vector<Vec4> genVertexData (const CaseDef& caseDef)
818 vector<Vec4> vectorData;
819 const bool isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);
821 for (deUint32 z = 0; z < caseDef.numLayers; z++)
823 const deUint32 colorIdx = z % COLOR_TABLE_SIZE;
828 const VkClearValue clearValue = getClearValueInt(caseDef, colorIdx);
829 const IVec4 colorInt (clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);
831 color = colorInt.cast<float>();
835 color = COLOR_TABLE_FLOAT[colorIdx];
838 vectorData.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
839 vectorData.push_back(color);
840 vectorData.push_back(Vec4(-1.0f, 1.0f, 0.0f, 1.0f));
841 vectorData.push_back(color);
842 vectorData.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
843 vectorData.push_back(color);
844 vectorData.push_back(Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
845 vectorData.push_back(color);
851 void generateExpectedImage(const tcu::PixelBufferAccess& image, const CaseDef& caseDef)
853 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(image.getFormat().type);
854 const bool isIntegerFormat = channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
855 const IVec2 size = caseDef.size.swizzle(0, 1);
857 for (int z = 0; z < static_cast<int>(caseDef.numLayers); z++)
859 const deUint32 colorIdx = z % COLOR_TABLE_SIZE;
860 for (int y = 0; y < size.y(); y++)
861 for (int x = 0; x < size.x(); x++)
865 const VkClearValue clearValue = getClearValueInt(caseDef, colorIdx);
866 const IVec4 colorInt (clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);
868 image.setPixel(colorInt, x, y, z);
871 if(isSRGBConversionRequired(caseDef))
872 image.setPixel(tcu::linearToSRGB(COLOR_TABLE_FLOAT[colorIdx]), x, y, z);
874 image.setPixel(COLOR_TABLE_FLOAT[colorIdx], x, y, z);
879 VkImageUsageFlags getImageUsageForTestCase (const CaseDef& caseDef)
881 VkImageUsageFlags flags = 0u;
883 switch (caseDef.upload)
886 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
889 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
892 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
895 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
898 DE_FATAL("Invalid upload method");
902 switch (caseDef.download)
904 case DOWNLOAD_TEXTURE:
905 flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
908 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
911 flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
914 DE_FATAL("Invalid download method");
918 // We can only create a view for the image if it is going to be used for any of these usages,
919 // so let's make sure that we have at least one of them.
920 VkImageUsageFlags viewRequiredFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
921 if (!(flags & viewRequiredFlags))
922 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
927 // Executes a combination of upload/download methods
928 class UploadDownloadExecutor
931 UploadDownloadExecutor(Context& context, const CaseDef& caseSpec) :
933 m_haveMaintenance2(isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance2")),
934 m_vk(context.getDeviceInterface()),
935 m_device(context.getDevice()),
936 m_queue(context.getUniversalQueue()),
937 m_queueFamilyIndex(context.getUniversalQueueFamilyIndex()),
938 m_allocator(context.getDefaultAllocator())
942 void runSwapchain(Context& context, VkBuffer buffer, VkImage image);
944 void run(Context& context, VkBuffer buffer);
947 void uploadClear(Context& context);
948 void uploadStore(Context& context);
949 void uploadCopy(Context& context);
950 void uploadDraw(Context& context);
951 void downloadCopy(Context& context, VkBuffer buffer);
952 void downloadTexture(Context& context, VkBuffer buffer);
953 void downloadLoad(Context& context, VkBuffer buffer);
955 void copyImageToBuffer(VkImage image,
958 const VkAccessFlags srcAccessMask,
959 const VkImageLayout oldLayout,
960 const deUint32 numLayers);
962 const CaseDef& m_caseDef;
964 bool m_haveMaintenance2;
966 const DeviceInterface& m_vk;
967 const VkDevice m_device;
968 const VkQueue m_queue;
969 const deUint32 m_queueFamilyIndex;
970 Allocator& m_allocator;
972 Move<VkCommandPool> m_cmdPool;
973 Move<VkCommandBuffer> m_cmdBuffer;
975 bool m_imageIsIntegerFormat;
976 bool m_viewIsIntegerFormat;
978 // Target image for upload paths
980 Move<VkImage> m_imageHolder;
981 MovePtr<Allocation> m_imageAlloc;
986 Move<VkBuffer> colorBuffer;
987 VkDeviceSize colorBufferSize;
988 MovePtr<Allocation> colorBufferAlloc;
994 Move<VkBuffer> vertexBuffer;
995 MovePtr<Allocation> vertexBufferAlloc;
996 Move<VkPipelineLayout> pipelineLayout;
997 Move<VkRenderPass> renderPass;
998 Move<VkShaderModule> vertexModule;
999 Move<VkShaderModule> fragmentModule;
1000 vector<SharedPtrVkImageView> attachments;
1001 vector<VkImageView> attachmentHandles;
1002 vector<SharedPtrVkPipeline> pipelines;
1003 Move<VkFramebuffer> framebuffer;
1009 Move<VkDescriptorPool> descriptorPool;
1010 Move<VkPipelineLayout> pipelineLayout;
1011 Move<VkDescriptorSetLayout> descriptorSetLayout;
1012 Move<VkDescriptorSet> descriptorSet;
1013 VkDescriptorImageInfo imageDescriptorInfo;
1014 Move<VkShaderModule> computeModule;
1015 Move<VkPipeline> computePipeline;
1016 Move<VkImageView> imageView;
1022 Move<VkDescriptorPool> descriptorPool;
1023 Move<VkPipelineLayout> pipelineLayout;
1024 Move<VkDescriptorSetLayout> descriptorSetLayout;
1025 Move<VkDescriptorSet> descriptorSet;
1026 Move<VkShaderModule> computeModule;
1027 Move<VkPipeline> computePipeline;
1028 Move<VkImageView> inImageView;
1029 VkDescriptorImageInfo inImageDescriptorInfo;
1030 Move<VkImage> outImage;
1031 Move<VkImageView> outImageView;
1032 MovePtr<Allocation> outImageAlloc;
1033 VkDescriptorImageInfo outImageDescriptorInfo;
1039 Move<VkDescriptorPool> descriptorPool;
1040 Move<VkPipelineLayout> pipelineLayout;
1041 Move<VkDescriptorSetLayout> descriptorSetLayout;
1042 Move<VkDescriptorSet> descriptorSet;
1043 Move<VkShaderModule> computeModule;
1044 Move<VkPipeline> computePipeline;
1045 Move<VkImageView> inImageView;
1046 VkDescriptorImageInfo inImageDescriptorInfo;
1047 Move<VkSampler> sampler;
1048 Move<VkImage> outImage;
1049 Move<VkImageView> outImageView;
1050 MovePtr<Allocation> outImageAlloc;
1051 VkDescriptorImageInfo outImageDescriptorInfo;
1054 VkImageLayout m_imageLayoutAfterUpload;
1055 VkAccessFlagBits m_imageUploadAccessMask;
1059 void UploadDownloadExecutor::runSwapchain(Context& context, VkBuffer buffer, VkImage image)
1061 m_imageIsIntegerFormat = isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat);
1062 m_viewIsIntegerFormat = isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat);
1064 m_cmdPool = createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex);
1065 m_cmdBuffer = makeCommandBuffer(m_vk, m_device, *m_cmdPool);
1066 beginCommandBuffer(m_vk, *m_cmdBuffer);
1070 switch (m_caseDef.upload)
1073 uploadDraw(context);
1076 uploadStore(context);
1079 uploadClear(context);
1082 uploadCopy(context);
1085 DE_FATAL("Unsupported upload method");
1088 switch (m_caseDef.download)
1091 downloadCopy(context, buffer);
1094 downloadLoad(context, buffer);
1096 case DOWNLOAD_TEXTURE:
1097 downloadTexture(context, buffer);
1100 DE_FATAL("Unsupported download method");
1103 endCommandBuffer(m_vk, *m_cmdBuffer);
1104 submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer);
1108 void UploadDownloadExecutor::run(Context& context, VkBuffer buffer)
1110 m_imageIsIntegerFormat = isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat);
1111 m_viewIsIntegerFormat = isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat);
1113 m_cmdPool = createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex);
1114 m_cmdBuffer = makeCommandBuffer(m_vk, m_device, *m_cmdPool);
1115 beginCommandBuffer(m_vk, *m_cmdBuffer);
1117 const VkImageUsageFlags imageUsage = getImageUsageForTestCase(m_caseDef);
1118 const VkImageCreateFlags imageFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | (m_haveMaintenance2 ? VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR : 0);
1120 m_imageHolder = makeImage(m_vk, m_device, imageFlags, getImageType(m_caseDef.imageType), m_caseDef.imageFormat, m_caseDef.viewFormat,
1121 m_caseDef.isFormatListTest, m_caseDef.size, 1u, m_caseDef.numLayers, imageUsage);
1122 m_image = *m_imageHolder;
1123 m_imageAlloc = bindImage(m_vk, m_device, m_allocator, m_image, MemoryRequirement::Any);
1125 switch (m_caseDef.upload)
1128 uploadDraw(context);
1131 uploadStore(context);
1134 uploadClear(context);
1137 uploadCopy(context);
1140 DE_FATAL("Unsupported upload method");
1143 switch (m_caseDef.download)
1146 downloadCopy(context, buffer);
1149 downloadLoad(context, buffer);
1151 case DOWNLOAD_TEXTURE:
1152 downloadTexture(context, buffer);
1155 DE_FATAL("Unsupported download method");
1158 endCommandBuffer(m_vk, *m_cmdBuffer);
1159 submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer);
1162 void UploadDownloadExecutor::uploadClear(Context& context)
1166 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1168 const VkImageSubresourceRange subresourceRange = makeColorSubresourceRange(0, m_caseDef.numLayers);
1169 const VkImageMemoryBarrier imageInitBarrier =
1171 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1172 DE_NULL, // const void* pNext;
1173 0u, // VkAccessFlags srcAccessMask;
1174 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAcessMask;
1175 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1176 requiredImageLayout, // VkImageLayout newLayout;
1177 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1178 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1179 m_image, // VkImage image;
1180 subresourceRange // VkImageSubresourceRange subresourceRange;
1183 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1184 0u, DE_NULL, 0u, DE_NULL, 1u, &imageInitBarrier);
1186 for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
1188 const VkImageSubresourceRange layerSubresourceRange = makeColorSubresourceRange(layer, 1u);
1189 const deUint32 colorIdx = layer % COLOR_TABLE_SIZE;
1190 const VkClearColorValue clearColor = m_imageIsIntegerFormat ? getClearValueInt(m_caseDef, colorIdx).color : REFERENCE_CLEAR_COLOR_FLOAT[colorIdx].color;
1191 m_vk.cmdClearColorImage(*m_cmdBuffer, m_image, requiredImageLayout, &clearColor, 1u, &layerSubresourceRange);
1194 m_imageLayoutAfterUpload = requiredImageLayout;
1195 m_imageUploadAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1198 void UploadDownloadExecutor::uploadStore(Context& context)
1200 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1202 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1203 DE_NULL, // const void* pNext
1204 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage;
1206 m_uStore.imageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1207 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1209 // Setup compute pipeline
1210 m_uStore.descriptorPool = DescriptorPoolBuilder()
1211 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1212 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1214 m_uStore.descriptorSetLayout = DescriptorSetLayoutBuilder()
1215 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1216 .build(m_vk, m_device);
1218 m_uStore.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_uStore.descriptorSetLayout);
1219 m_uStore.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_uStore.descriptorPool, *m_uStore.descriptorSetLayout);
1220 m_uStore.imageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_uStore.imageView, VK_IMAGE_LAYOUT_GENERAL);
1221 m_uStore.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadStoreComp"), 0);
1222 m_uStore.computePipeline = makeComputePipeline(m_vk, m_device, *m_uStore.pipelineLayout, *m_uStore.computeModule, DE_NULL);
1224 DescriptorSetUpdateBuilder()
1225 .writeSingle(*m_uStore.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_uStore.imageDescriptorInfo)
1226 .update(m_vk, m_device);
1228 // Transition storage image for shader access (imageStore)
1229 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1230 const VkImageMemoryBarrier imageBarrier =
1232 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1233 DE_NULL, // const void* pNext;
1234 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1235 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1236 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1237 requiredImageLayout, // VkImageLayout newLayout;
1238 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1239 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1240 m_image, // VkImage image;
1241 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1244 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1245 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
1248 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.computePipeline);
1249 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.pipelineLayout, 0u, 1u, &m_uStore.descriptorSet.get(), 0u, DE_NULL);
1250 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1252 m_imageLayoutAfterUpload = requiredImageLayout;
1253 m_imageUploadAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
1256 void UploadDownloadExecutor::uploadCopy(Context& context)
1260 // Create a host-mappable buffer with the color data to upload
1261 const VkDeviceSize pixelSize = tcu::getPixelSize(mapVkFormat(m_caseDef.imageFormat));
1262 const VkDeviceSize layerSize = m_caseDef.size.x() * m_caseDef.size.y() * m_caseDef.size.z() * pixelSize;
1264 m_uCopy.colorBufferSize = layerSize * m_caseDef.numLayers;
1265 m_uCopy.colorBuffer = makeBuffer(m_vk, m_device, m_uCopy.colorBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
1266 m_uCopy.colorBufferAlloc = bindBuffer(m_vk, m_device, m_allocator, *m_uCopy.colorBuffer, MemoryRequirement::HostVisible);
1268 // Fill color buffer
1269 const tcu::TextureFormat tcuFormat = mapVkFormat(m_caseDef.imageFormat);
1270 VkDeviceSize layerOffset = 0ull;
1271 for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
1273 tcu::PixelBufferAccess imageAccess = tcu::PixelBufferAccess(tcuFormat, m_caseDef.size.x(), m_caseDef.size.y(), 1u, (deUint8*) m_uCopy.colorBufferAlloc->getHostPtr() + layerOffset);
1274 const deUint32 colorIdx = layer % COLOR_TABLE_SIZE;
1275 if (m_imageIsIntegerFormat)
1277 const VkClearValue clearValue = getClearValueInt(m_caseDef, colorIdx);
1278 const IVec4 colorInt (clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);
1280 tcu::clear(imageAccess, colorInt);
1283 tcu::clear(imageAccess, COLOR_TABLE_FLOAT[colorIdx]);
1284 layerOffset += layerSize;
1287 flushAlloc(m_vk, m_device, *(m_uCopy.colorBufferAlloc));
1289 // Prepare buffer and image for copy
1290 const VkBufferMemoryBarrier bufferInitBarrier =
1292 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1293 DE_NULL, // const void* pNext;
1294 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
1295 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1296 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1297 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1298 *m_uCopy.colorBuffer, // VkBuffer buffer;
1299 0ull, // VkDeviceSize offset;
1300 VK_WHOLE_SIZE, // VkDeviceSize size;
1303 const VkImageMemoryBarrier imageInitBarrier =
1305 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1306 DE_NULL, // const void* pNext;
1307 0u, // VkAccessFlags srcAccessMask;
1308 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1309 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1310 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1311 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1312 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1313 m_image, // VkImage image;
1314 makeColorSubresourceRange(0, m_caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
1317 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1318 0u, DE_NULL, 1u, &bufferInitBarrier, 1u, &imageInitBarrier);
1320 // Copy buffer to image
1321 const VkImageSubresourceLayers subresource =
1323 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1324 0u, // deUint32 mipLevel;
1325 0u, // deUint32 baseArrayLayer;
1326 m_caseDef.numLayers, // deUint32 layerCount;
1329 const VkBufferImageCopy region =
1331 0ull, // VkDeviceSize bufferOffset;
1332 0u, // deUint32 bufferRowLength;
1333 0u, // deUint32 bufferImageHeight;
1334 subresource, // VkImageSubresourceLayers imageSubresource;
1335 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
1336 makeExtent3D(m_caseDef.size), // VkExtent3D imageExtent;
1339 m_vk.cmdCopyBufferToImage(*m_cmdBuffer, *m_uCopy.colorBuffer, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ®ion);
1341 const VkImageMemoryBarrier imagePostInitBarrier =
1343 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1344 DE_NULL, // const void* pNext;
1345 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1346 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1347 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1348 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1349 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1350 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1351 m_image, // VkImage image;
1352 makeColorSubresourceRange(0, m_caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
1355 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1356 0u, DE_NULL, 0u, DE_NULL, 1u, &imagePostInitBarrier);
1358 m_imageLayoutAfterUpload = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1359 m_imageUploadAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1362 void UploadDownloadExecutor::uploadDraw(Context& context)
1364 // Create vertex buffer
1366 const vector<Vec4> vertices = genVertexData(m_caseDef);
1367 const VkDeviceSize vertexBufferSize = vertices.size() * sizeof(Vec4);
1369 m_uDraw.vertexBuffer = makeBuffer(m_vk, m_device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
1370 m_uDraw.vertexBufferAlloc = bindBuffer(m_vk, m_device, m_allocator, *m_uDraw.vertexBuffer, MemoryRequirement::HostVisible);
1371 deMemcpy(m_uDraw.vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
1372 flushAlloc(m_vk, m_device, *(m_uDraw.vertexBufferAlloc));
1375 // Create attachments and pipelines for each image layer
1376 m_uDraw.pipelineLayout = makePipelineLayout(m_vk, m_device);
1377 m_uDraw.renderPass = makeRenderPass(m_vk, m_device, m_caseDef.viewFormat, m_caseDef.numLayers);
1378 m_uDraw.vertexModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawVert"), 0u);
1379 m_uDraw.fragmentModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawFrag"), 0u);
1381 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
1383 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1385 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1386 DE_NULL, // const void* pNext
1387 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags usage;
1389 Move<VkImageView> imageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1390 makeColorSubresourceRange(subpassNdx, 1), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1391 m_uDraw.attachmentHandles.push_back(*imageView);
1392 m_uDraw.attachments.push_back(makeSharedPtr(imageView));
1393 m_uDraw.pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(m_vk, m_device, *m_uDraw.pipelineLayout, *m_uDraw.renderPass, *m_uDraw.vertexModule, *m_uDraw.fragmentModule,
1394 m_caseDef.size.swizzle(0, 1), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, subpassNdx)));
1397 // Create framebuffer
1398 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));
1400 // Create command buffer
1403 vector<VkClearValue> clearValues (m_caseDef.numLayers, m_viewIsIntegerFormat ? getClearValueInt(m_caseDef, 0) : REFERENCE_CLEAR_COLOR_FLOAT[0]);
1405 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]);
1409 const VkDeviceSize vertexDataPerDraw = 4 * 2 * sizeof(Vec4);
1410 VkDeviceSize vertexBufferOffset = 0ull;
1411 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
1413 if (subpassNdx != 0)
1414 m_vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
1416 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_uDraw.pipelines[subpassNdx]);
1418 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_uDraw.vertexBuffer.get(), &vertexBufferOffset);
1419 m_vk.cmdDraw(*m_cmdBuffer, 4u, 1u, 0u, 0u);
1420 vertexBufferOffset += vertexDataPerDraw;
1423 endRenderPass(m_vk, *m_cmdBuffer);
1426 m_imageLayoutAfterUpload = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1427 m_imageUploadAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1430 void UploadDownloadExecutor::downloadCopy(Context& context, VkBuffer buffer)
1434 copyImageToBuffer(m_image, buffer, m_caseDef.size, m_imageUploadAccessMask, m_imageLayoutAfterUpload, m_caseDef.numLayers);
1437 void UploadDownloadExecutor::downloadTexture(Context& context, VkBuffer buffer)
1439 // Create output image with download result
1440 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1441 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);
1442 m_dTex.outImageAlloc = bindImage(m_vk, m_device, m_allocator, *m_dTex.outImage, MemoryRequirement::Any);
1443 m_dTex.outImageView = makeImageView(m_vk, m_device, *m_dTex.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));
1445 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1447 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1448 DE_NULL, // const void* pNext
1449 VK_IMAGE_USAGE_SAMPLED_BIT, // VkImageUsageFlags usage;
1451 m_dTex.inImageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1452 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1453 m_dTex.sampler = makeSampler(m_vk, m_device);
1455 // Setup compute pipeline
1456 m_dTex.descriptorPool = DescriptorPoolBuilder()
1457 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1458 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1459 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1461 m_dTex.descriptorSetLayout = DescriptorSetLayoutBuilder()
1462 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT, &m_dTex.sampler.get())
1463 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1464 .build(m_vk, m_device);
1466 m_dTex.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_dTex.descriptorSetLayout);
1467 m_dTex.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_dTex.descriptorPool, *m_dTex.descriptorSetLayout);
1468 m_dTex.inImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dTex.inImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1469 m_dTex.outImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dTex.outImageView, VK_IMAGE_LAYOUT_GENERAL);
1470 m_dTex.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadTextureComp"), 0);
1471 m_dTex.computePipeline = makeComputePipeline(m_vk, m_device, *m_dTex.pipelineLayout, *m_dTex.computeModule, DE_NULL);
1473 DescriptorSetUpdateBuilder()
1474 .writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &m_dTex.inImageDescriptorInfo)
1475 .writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dTex.outImageDescriptorInfo)
1476 .update(m_vk, m_device);
1478 // Transition images for shader access (texture / imageStore)
1479 const VkImageMemoryBarrier imageBarriers[] =
1482 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1483 DE_NULL, // const void* pNext;
1484 (VkAccessFlags)m_imageUploadAccessMask, // VkAccessFlags srcAccessMask;
1485 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
1486 m_imageLayoutAfterUpload, // VkImageLayout oldLayout;
1487 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
1488 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1489 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1490 m_image, // VkImage image;
1491 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1494 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1495 DE_NULL, // const void* pNext;
1496 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1497 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1498 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1499 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout;
1500 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1501 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1502 *m_dTex.outImage, // VkImage image;
1503 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1507 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1508 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
1511 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.computePipeline);
1512 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.pipelineLayout, 0u, 1u, &m_dTex.descriptorSet.get(), 0u, DE_NULL);
1513 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1515 // Copy output image to color buffer
1516 copyImageToBuffer(*m_dTex.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL, m_caseDef.numLayers);
1519 void UploadDownloadExecutor::downloadLoad(Context& context, VkBuffer buffer)
1521 // Create output image with download result
1522 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1523 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);
1524 m_dLoad.outImageAlloc = bindImage(m_vk, m_device, m_allocator, *m_dLoad.outImage, MemoryRequirement::Any);
1525 m_dLoad.outImageView = makeImageView(m_vk, m_device, *m_dLoad.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));
1527 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1529 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1530 DE_NULL, // const void* pNext
1531 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage;
1533 m_dLoad.inImageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1534 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1536 // Setup compute pipeline
1537 m_dLoad.descriptorPool = DescriptorPoolBuilder()
1538 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2u)
1539 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1541 m_dLoad.descriptorSetLayout = DescriptorSetLayoutBuilder()
1542 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1543 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1544 .build(m_vk, m_device);
1546 m_dLoad.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_dLoad.descriptorSetLayout);
1547 m_dLoad.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_dLoad.descriptorPool, *m_dLoad.descriptorSetLayout);
1548 m_dLoad.inImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dLoad.inImageView, VK_IMAGE_LAYOUT_GENERAL);
1549 m_dLoad.outImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dLoad.outImageView, VK_IMAGE_LAYOUT_GENERAL);
1550 m_dLoad.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadLoadComp"), 0);
1551 m_dLoad.computePipeline = makeComputePipeline(m_vk, m_device, *m_dLoad.pipelineLayout, *m_dLoad.computeModule, DE_NULL);
1553 DescriptorSetUpdateBuilder()
1554 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.inImageDescriptorInfo)
1555 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.outImageDescriptorInfo)
1556 .update(m_vk, m_device);
1558 // Transition storage images for shader access (imageLoad/Store)
1559 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1560 const VkImageMemoryBarrier imageBarriers[] =
1563 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1564 DE_NULL, // const void* pNext;
1565 (VkAccessFlags)m_imageUploadAccessMask, // VkAccessFlags srcAccessMask;
1566 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
1567 m_imageLayoutAfterUpload, // VkImageLayout oldLayout;
1568 requiredImageLayout, // VkImageLayout newLayout;
1569 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1570 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1571 m_image, // VkImage image;
1572 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1575 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1576 DE_NULL, // const void* pNext;
1577 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1578 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1579 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1580 requiredImageLayout, // VkImageLayout newLayout;
1581 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1582 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1583 *m_dLoad.outImage, // VkImage image;
1584 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1588 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1589 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
1592 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.computePipeline);
1593 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.pipelineLayout, 0u, 1u, &m_dLoad.descriptorSet.get(), 0u, DE_NULL);
1594 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1596 // Copy output image to color buffer
1597 copyImageToBuffer(*m_dLoad.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, requiredImageLayout, m_caseDef.numLayers);
1600 void UploadDownloadExecutor::copyImageToBuffer(VkImage sourceImage,
1603 const VkAccessFlags srcAccessMask,
1604 const VkImageLayout oldLayout,
1605 const deUint32 numLayers)
1607 // Copy result to host visible buffer for inspection
1608 const VkImageMemoryBarrier imageBarrier =
1610 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1611 DE_NULL, // const void* pNext;
1612 srcAccessMask, // VkAccessFlags srcAccessMask;
1613 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1614 oldLayout, // VkImageLayout oldLayout;
1615 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
1616 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1617 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1618 sourceImage, // VkImage image;
1619 makeColorSubresourceRange(0, numLayers) // VkImageSubresourceRange subresourceRange;
1622 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1623 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
1625 const VkImageSubresourceLayers subresource =
1627 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1628 0u, // deUint32 mipLevel;
1629 0u, // deUint32 baseArrayLayer;
1630 numLayers, // deUint32 layerCount;
1633 const VkBufferImageCopy region =
1635 0ull, // VkDeviceSize bufferOffset;
1636 0u, // deUint32 bufferRowLength;
1637 0u, // deUint32 bufferImageHeight;
1638 subresource, // VkImageSubresourceLayers imageSubresource;
1639 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
1640 makeExtent3D(size), // VkExtent3D imageExtent;
1643 m_vk.cmdCopyImageToBuffer(*m_cmdBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, ®ion);
1645 const VkBufferMemoryBarrier bufferBarrier =
1647 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1648 DE_NULL, // const void* pNext;
1649 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1650 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
1651 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1652 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1653 buffer, // VkBuffer buffer;
1654 0ull, // VkDeviceSize offset;
1655 VK_WHOLE_SIZE, // VkDeviceSize size;
1658 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
1659 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
1662 tcu::TestStatus testMutable (Context& context, const CaseDef caseDef)
1664 const DeviceInterface& vk = context.getDeviceInterface();
1665 const InstanceInterface& vki = context.getInstanceInterface();
1666 const VkDevice device = context.getDevice();
1667 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
1668 Allocator& allocator = context.getDefaultAllocator();
1670 // If this is a VK_KHR_image_format_list test, check that the extension is supported
1671 if (caseDef.isFormatListTest && !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_image_format_list"))
1672 TCU_THROW(NotSupportedError, "VK_KHR_image_format_list not supported");
1674 // Check required features on the format for the required upload/download methods
1675 VkFormatProperties imageFormatProps, viewFormatProps;
1676 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.imageFormat, &imageFormatProps);
1677 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.viewFormat, &viewFormatProps);
1679 VkFormatFeatureFlags viewFormatFeatureFlags = 0u;
1680 switch (caseDef.upload)
1683 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
1686 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1689 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1692 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1695 DE_FATAL("Invalid upload method");
1698 switch (caseDef.download)
1700 case DOWNLOAD_TEXTURE:
1701 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
1702 // For the texture case we write the samples read to a separate output image with the same view format
1703 // so we need to check that we can also use the view format for storage
1704 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1707 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1710 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1713 DE_FATAL("Invalid download method");
1717 if ((viewFormatFeatureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) &&
1718 isStorageImageExtendedFormat(caseDef.viewFormat) &&
1719 !getPhysicalDeviceFeatures(vki, physDevice).shaderStorageImageExtendedFormats)
1721 TCU_THROW(NotSupportedError, "View format requires shaderStorageImageExtended");
1724 if ((viewFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags)
1725 TCU_THROW(NotSupportedError, "View format doesn't support upload/download method");
1727 const bool haveMaintenance2 = isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance2");
1729 // We don't use the base image for anything other than transfer
1730 // operations so there are no features to check. However, The Vulkan
1731 // 1.0 spec does not allow us to create an image view with usage that
1732 // is not supported by the main format. With VK_KHR_maintenance2, we
1733 // can do this via VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR.
1734 if ((imageFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags &&
1737 TCU_THROW(NotSupportedError, "Image format doesn't support upload/download method");
1740 // If no format feature flags are supported, the format itself is not supported,
1741 // and images of that format cannot be created.
1742 if (imageFormatProps.optimalTilingFeatures == 0)
1744 TCU_THROW(NotSupportedError, "Base image format is not supported");
1747 // Create a color buffer for host-inspection of results
1748 // For the Copy download method, this is the target of the download, for other
1749 // download methods, pixel data will be copied to this buffer from the download
1751 const VkDeviceSize colorBufferSize = caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat));
1752 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1753 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1754 deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
1755 flushAlloc(vk, device, *colorBufferAlloc);
1758 UploadDownloadExecutor executor(context, caseDef);
1759 executor.run(context, *colorBuffer);
1763 invalidateAlloc(vk, device, *colorBufferAlloc);
1765 // For verification purposes, we use the format of the upload to generate the expected image
1766 const VkFormat format = caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat;
1767 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
1768 const bool isIntegerFormat = isUintFormat(format) || isIntFormat(format);
1769 const tcu::ConstPixelBufferAccess resultImage (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr());
1770 tcu::TextureLevel textureLevel (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers);
1771 const tcu::PixelBufferAccess expectedImage = textureLevel.getAccess();
1772 generateExpectedImage(expectedImage, caseDef);
1775 if (isIntegerFormat)
1776 ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
1778 ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
1779 return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
1783 tcu::TestCaseGroup* createImageMutableTests (TestContext& testCtx)
1785 de::MovePtr<TestCaseGroup> testGroup (new TestCaseGroup(testCtx, "mutable", "Cases with mutable images"));
1786 for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx)
1788 const Texture& texture = s_textures[textureNdx];
1789 de::MovePtr<tcu::TestCaseGroup> groupByImageViewType (new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), ""));
1791 for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++imageFormatNdx)
1792 for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++viewFormatNdx)
1794 if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_formats[imageFormatNdx], s_formats[viewFormatNdx]))
1796 for (int upload = 0; upload < UPLOAD_LAST; upload++)
1797 for (int download = 0; download < DOWNLOAD_LAST; download++)
1802 texture.layerSize(),
1803 static_cast<deUint32>(texture.numLayers()),
1804 s_formats[imageFormatNdx],
1805 s_formats[viewFormatNdx],
1806 static_cast<enum Upload>(upload),
1807 static_cast<enum Download>(download),
1808 false, // isFormatListTest;
1809 false, // isSwapchainImageTest
1810 vk::wsi::TYPE_LAST // wsiType
1813 std::string caseName = getFormatShortString(s_formats[imageFormatNdx]) + "_" + getFormatShortString(s_formats[viewFormatNdx]) +
1814 "_" + getUploadString(upload) + "_" + getDownloadString(download);
1815 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", initPrograms, testMutable, caseDef);
1817 caseDef.isFormatListTest = true;
1818 caseName += "_format_list";
1819 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", initPrograms, testMutable, caseDef);
1824 testGroup->addChild(groupByImageViewType.release());
1827 return testGroup.release();
1830 typedef vector<VkExtensionProperties> Extensions;
1832 void checkAllSupported(const Extensions& supportedExtensions, const vector<string>& requiredExtensions)
1834 for (vector<string>::const_iterator requiredExtName = requiredExtensions.begin();
1835 requiredExtName != requiredExtensions.end();
1838 if (!isExtensionSupported(supportedExtensions, RequiredExtension(*requiredExtName)))
1839 TCU_THROW(NotSupportedError, (*requiredExtName + " is not supported").c_str());
1843 Move<VkInstance> createInstanceWithWsi(const PlatformInterface& vkp,
1845 const Extensions& supportedExtensions,
1847 const VkAllocationCallbacks* pAllocator = DE_NULL)
1849 vector<string> extensions;
1851 extensions.push_back("VK_KHR_surface");
1852 extensions.push_back(getExtensionName(wsiType));
1854 // VK_EXT_swapchain_colorspace adds new surface formats. Driver can enumerate
1855 // the formats regardless of whether VK_EXT_swapchain_colorspace was enabled,
1856 // but using them without enabling the extension is not allowed. Thus we have
1859 // 1) Filter out non-core formats to stay within valid usage.
1861 // 2) Enable VK_EXT_swapchain colorspace if advertised by the driver.
1863 // We opt for (2) as it provides basic coverage for the extension as a bonus.
1864 if (isExtensionSupported(supportedExtensions, RequiredExtension("VK_EXT_swapchain_colorspace")))
1865 extensions.push_back("VK_EXT_swapchain_colorspace");
1867 checkAllSupported(supportedExtensions, extensions);
1869 return vk::createDefaultInstance(vkp, version, vector<string>(), extensions, pAllocator);
1873 Move<VkDevice> createDeviceWithWsi(const PlatformInterface& vkp,
1874 VkInstance instance,
1875 const InstanceInterface& vki,
1876 VkPhysicalDevice physicalDevice,
1877 const Extensions& supportedExtensions,
1878 const deUint32 queueFamilyIndex,
1879 const VkAllocationCallbacks* pAllocator = DE_NULL)
1881 const float queuePriorities[] = { 1.0f };
1882 const VkDeviceQueueCreateInfo queueInfos[] =
1885 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1887 (VkDeviceQueueCreateFlags)0,
1889 DE_LENGTH_OF_ARRAY(queuePriorities),
1893 VkPhysicalDeviceFeatures features;
1894 deMemset(&features, 0x0, sizeof(features));
1896 const char* const extensions[] = { "VK_KHR_swapchain", "VK_KHR_swapchain_mutable_format" };
1897 const VkDeviceCreateInfo deviceParams =
1899 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1901 (VkDeviceCreateFlags)0,
1902 DE_LENGTH_OF_ARRAY(queueInfos),
1904 0u, // enabledLayerCount
1905 DE_NULL, // ppEnabledLayerNames
1906 DE_LENGTH_OF_ARRAY(extensions), // enabledExtensionCount
1907 DE_ARRAY_BEGIN(extensions), // ppEnabledExtensionNames
1911 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(extensions); ++ndx)
1913 if (!isExtensionSupported(supportedExtensions, RequiredExtension(extensions[ndx])))
1914 TCU_THROW(NotSupportedError, (string(extensions[ndx]) + " is not supported").c_str());
1917 return createDevice(vkp, instance, vki, physicalDevice, &deviceParams, pAllocator);
1920 deUint32 getNumQueueFamilyIndices(const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
1922 deUint32 numFamilies = 0;
1924 vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
1929 vector<deUint32> getSupportedQueueFamilyIndices(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
1931 const deUint32 numTotalFamilyIndices = getNumQueueFamilyIndices(vki, physicalDevice);
1932 vector<deUint32> supportedFamilyIndices;
1934 for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
1936 if (getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
1937 supportedFamilyIndices.push_back(queueFamilyNdx);
1940 return supportedFamilyIndices;
1943 deUint32 chooseQueueFamilyIndex(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
1945 const vector<deUint32> supportedFamilyIndices = getSupportedQueueFamilyIndices(vki, physicalDevice, surface);
1947 if (supportedFamilyIndices.empty())
1948 TCU_THROW(NotSupportedError, "Device doesn't support presentation");
1950 return supportedFamilyIndices[0];
1953 struct InstanceHelper
1955 const vector<VkExtensionProperties> supportedExtensions;
1956 const Unique<VkInstance> instance;
1957 const InstanceDriver vki;
1959 InstanceHelper(Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
1960 : supportedExtensions(enumerateInstanceExtensionProperties(context.getPlatformInterface(),
1962 , instance(createInstanceWithWsi(context.getPlatformInterface(),
1963 context.getUsedApiVersion(),
1964 supportedExtensions,
1967 , vki(context.getPlatformInterface(), *instance)
1974 const VkPhysicalDevice physicalDevice;
1975 const deUint32 queueFamilyIndex;
1976 const Unique<VkDevice> device;
1977 const DeviceDriver vkd;
1978 const VkQueue queue;
1980 DeviceHelper(Context& context,
1981 const InstanceInterface& vki,
1982 VkInstance instance,
1983 VkSurfaceKHR surface,
1984 const VkAllocationCallbacks* pAllocator = DE_NULL)
1985 : physicalDevice(chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
1986 , queueFamilyIndex(chooseQueueFamilyIndex(vki, physicalDevice, surface))
1987 , device(createDeviceWithWsi(context.getPlatformInterface(),
1988 context.getInstance(),
1991 enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL),
1994 , vkd(context.getPlatformInterface(), context.getInstance(), *device)
1995 , queue(getDeviceQueue(vkd, *device, queueFamilyIndex, 0))
2000 MovePtr<Display> createDisplay(const vk::Platform& platform,
2001 const Extensions& supportedExtensions,
2006 return MovePtr<Display>(platform.createWsiDisplay(wsiType));
2008 catch (const tcu::NotSupportedError& e)
2010 if (isExtensionSupported(supportedExtensions, RequiredExtension(getExtensionName(wsiType))))
2012 // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
2013 // must support creating native display & window for that WSI type.
2014 throw tcu::TestError(e.getMessage());
2021 MovePtr<Window> createWindow(const Display& display, const Maybe<UVec2>& initialSize)
2025 return MovePtr<Window>(display.createWindow(initialSize));
2027 catch (const tcu::NotSupportedError& e)
2029 // See createDisplay - assuming that wsi::Display was supported platform port
2030 // should also support creating a window.
2031 throw tcu::TestError(e.getMessage());
2035 struct NativeObjects
2037 const UniquePtr<Display> display;
2038 const UniquePtr<Window> window;
2040 NativeObjects(Context& context,
2041 const Extensions& supportedExtensions,
2043 const Maybe<UVec2>& initialWindowSize = tcu::nothing<UVec2>())
2044 : display(createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
2045 , window(createWindow(*display, initialWindowSize))
2049 Move<VkSwapchainKHR> makeSwapchain(const DeviceInterface& vk,
2050 const VkDevice device,
2051 const vk::wsi::Type wsiType,
2052 const VkSurfaceKHR surface,
2053 const VkSurfaceCapabilitiesKHR capabilities,
2054 const VkSurfaceFormatKHR surfaceFormat,
2055 const VkFormat viewFormat,
2056 const deUint32 numLayers,
2057 const VkImageUsageFlags usage,
2058 const tcu::UVec2& desiredSize,
2059 deUint32 desiredImageCount
2062 const VkFormat formatList[2] =
2064 surfaceFormat.format,
2068 const VkImageFormatListCreateInfoKHR formatListInfo =
2070 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR, // VkStructureType sType;
2071 DE_NULL, // const void* pNext;
2072 2u, // deUint32 viewFormatCount
2073 formatList // const VkFormat* pViewFormats
2076 const VkSurfaceTransformFlagBitsKHR transform = (capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
2077 const PlatformProperties& platformProperties = getPlatformProperties(wsiType);
2079 const VkSwapchainCreateInfoKHR swapchainInfo =
2081 VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, // VkStructureType sType;
2082 &formatListInfo, // const void* pNext;
2083 VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR, // VkSwapchainCreateFlagsKHR flags;
2084 surface, // VkSurfaceKHR surface;
2085 de::clamp(desiredImageCount, capabilities.minImageCount, capabilities.maxImageCount > 0 ? capabilities.maxImageCount : capabilities.minImageCount + desiredImageCount), // deUint32 minImageCount;
2086 surfaceFormat.format, // VkFormat imageFormat;
2087 surfaceFormat.colorSpace, // VkColorSpaceKHR imageColorSpace;
2088 (platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE
2089 ? capabilities.currentExtent : vk::makeExtent2D(desiredSize.x(), desiredSize.y())), // VkExtent2D imageExtent;
2090 numLayers, // deUint32 imageArrayLayers;
2091 usage, // VkImageUsageFlags imageUsage;
2092 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode imageSharingMode;
2093 0u, // deUint32 queueFamilyIndexCount;
2094 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2095 transform, // VkSurfaceTransformFlagBitsKHR preTransform;
2096 VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, // VkCompositeAlphaFlagBitsKHR compositeAlpha;
2097 VK_PRESENT_MODE_FIFO_KHR, // VkPresentModeKHR presentMode;
2098 VK_FALSE, // VkBool32 clipped;
2099 (VkSwapchainKHR)0 // VkSwapchainKHR oldSwapchain;
2102 return createSwapchainKHR(vk, device, &swapchainInfo);
2105 tcu::TestStatus testSwapchainMutable(Context& context, CaseDef caseDef)
2107 const Type wsiType(caseDef.wsiType);
2108 const tcu::UVec2 desiredSize(256, 256);
2109 const InstanceHelper instHelper(context, wsiType);
2110 const NativeObjects native(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
2111 const Unique<VkSurfaceKHR> surface(createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
2112 const DeviceHelper devHelper(context, instHelper.vki, *instHelper.instance, *surface);
2113 const DeviceInterface& vk = devHelper.vkd;
2114 const InstanceDriver& vki = instHelper.vki;
2115 const VkDevice device = *devHelper.device;
2116 const VkPhysicalDevice physDevice = devHelper.physicalDevice;
2118 Allocator& allocator = context.getDefaultAllocator();
2120 // Check required features on the format for the required upload/download methods
2121 VkFormatProperties imageFormatProps, viewFormatProps;
2122 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.imageFormat, &imageFormatProps);
2123 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.viewFormat, &viewFormatProps);
2125 const VkImageUsageFlags imageUsage = getImageUsageForTestCase(caseDef);
2127 const VkSurfaceCapabilitiesKHR capabilities = getPhysicalDeviceSurfaceCapabilities(vki,
2131 if (caseDef.numLayers > capabilities.maxImageArrayLayers)
2132 caseDef.numLayers = capabilities.maxImageArrayLayers;
2134 // Check support for requested formats by swapchain surface
2135 const vector<VkSurfaceFormatKHR> surfaceFormats = getPhysicalDeviceSurfaceFormats(vki,
2139 const VkSurfaceFormatKHR* surfaceFormat = DE_NULL;
2140 const VkFormat* viewFormat = DE_NULL;
2142 for (vector<VkSurfaceFormatKHR>::size_type i = 0; i < surfaceFormats.size(); i++)
2144 if (surfaceFormats[i].format == caseDef.imageFormat)
2145 surfaceFormat = &surfaceFormats[i];
2147 if (surfaceFormats[i].format == caseDef.viewFormat)
2148 viewFormat = &surfaceFormats[i].format;
2151 if (surfaceFormat == DE_NULL)
2152 TCU_THROW(NotSupportedError, "Image format is not supported by swapchain.");
2154 if (viewFormat == DE_NULL)
2155 TCU_THROW(NotSupportedError, "Image view format is not supported by swapchain.");
2157 if ((capabilities.supportedUsageFlags & imageUsage) != imageUsage)
2158 TCU_THROW(NotSupportedError, "Image usage request not supported by swapchain.");
2160 const Unique<VkSwapchainKHR> swapchain(
2174 const vector<VkImage> swapchainImages = getSwapchainImages(vk, device, *swapchain);
2176 VkFormatFeatureFlags viewFormatFeatureFlags = 0u;
2177 switch (caseDef.upload)
2180 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
2183 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
2186 DE_FATAL("Invalid upload method");
2189 switch (caseDef.download)
2191 case DOWNLOAD_TEXTURE:
2192 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
2193 // For the texture case we write the samples read to a separate output image with the same view format
2194 // so we need to check that we can also use the view format for storage
2195 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
2198 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
2201 DE_FATAL("Invalid download method");
2205 if ((viewFormatFeatureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) &&
2206 isStorageImageExtendedFormat(caseDef.viewFormat) &&
2207 !getPhysicalDeviceFeatures(vki, physDevice).shaderStorageImageExtendedFormats)
2209 TCU_THROW(NotSupportedError, "View format requires shaderStorageImageExtended");
2212 if ((viewFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags)
2213 TCU_THROW(NotSupportedError, "View format doesn't support upload/download method");
2215 // We don't use the base image for anything other than transfer
2216 // operations so there are no features to check. However, The Vulkan
2217 // 1.0 spec does not allow us to create an image view with usage that
2218 // is not supported by the main format. With VK_KHR_maintenance2, we
2219 // can do this via VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR.
2220 if ((imageFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags &&
2221 !isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance2"))
2223 TCU_THROW(NotSupportedError, "Image format doesn't support upload/download method");
2226 // Create a color buffer for host-inspection of results
2227 // For the Copy download method, this is the target of the download, for other
2228 // download methods, pixel data will be copied to this buffer from the download
2230 const VkDeviceSize colorBufferSize = caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat));
2231 const Unique<VkBuffer> colorBuffer(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2232 const UniquePtr<Allocation> colorBufferAlloc(bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
2233 deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
2234 flushMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
2238 UploadDownloadExecutor executor(context, caseDef);
2240 executor.runSwapchain(context, *colorBuffer, swapchainImages[0]);
2244 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
2246 // For verification purposes, we use the format of the upload to generate the expected image
2247 const VkFormat format = caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat;
2248 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
2249 const bool isIntegerFormat = isUintFormat(format) || isIntFormat(format);
2250 const tcu::ConstPixelBufferAccess resultImage(tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr());
2251 tcu::TextureLevel textureLevel(tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers);
2252 const tcu::PixelBufferAccess expectedImage = textureLevel.getAccess();
2253 generateExpectedImage(expectedImage, caseDef);
2256 if (isIntegerFormat)
2257 ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
2259 ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
2260 return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
2264 tcu::TestCaseGroup* createSwapchainImageMutableTests(TestContext& testCtx)
2266 de::MovePtr<TestCaseGroup> testGroup(new TestCaseGroup(testCtx, "swapchain_mutable", "Cases with swapchain mutable images"));
2268 for (int typeNdx = 0; typeNdx < vk::wsi::TYPE_LAST; ++typeNdx)
2270 const vk::wsi::Type wsiType = (vk::wsi::Type)typeNdx;
2272 de::MovePtr<TestCaseGroup> testGroupWsi(new TestCaseGroup(testCtx, getName(wsiType), ""));
2274 for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx)
2276 const Texture& texture = s_textures[textureNdx];
2277 de::MovePtr<tcu::TestCaseGroup> groupByImageViewType(new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), ""));
2279 for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_swapchainFormats); ++imageFormatNdx)
2280 for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_swapchainFormats); ++viewFormatNdx)
2282 if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_swapchainFormats[imageFormatNdx], s_swapchainFormats[viewFormatNdx]))
2284 for (int upload = 0; upload < UPLOAD_LAST; upload++)
2285 for (int download = 0; download < DOWNLOAD_LAST; download++)
2290 texture.layerSize(),
2291 static_cast<deUint32>(texture.numLayers()),
2292 s_swapchainFormats[imageFormatNdx],
2293 s_swapchainFormats[viewFormatNdx],
2294 static_cast<enum Upload>(upload),
2295 static_cast<enum Download>(download),
2296 true, // isFormatListTest;
2297 true, // isSwapchainImageTest
2301 std::string caseName = getFormatShortString(s_swapchainFormats[imageFormatNdx]) + "_" + getFormatShortString(s_swapchainFormats[viewFormatNdx]) +
2302 "_" + getUploadString(upload) + "_" + getDownloadString(download) + "_format_list";
2304 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", initPrograms, testSwapchainMutable, caseDef);
2309 testGroupWsi->addChild(groupByImageViewType.release());
2312 testGroup->addChild(testGroupWsi.release());
2314 return testGroup.release();