1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 The Khronos Group Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Tests for mutable images
22 *//*--------------------------------------------------------------------*/
24 #include "vktImageMutableTests.hpp"
25 #include "vktImageLoadStoreUtil.hpp"
26 #include "vktTestCaseUtil.hpp"
27 #include "vktImageTexture.hpp"
28 #include "vktCustomInstancesDevices.hpp"
30 #include "vkBuilderUtil.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vkObjUtil.hpp"
37 #include "vkPlatform.hpp"
38 #include "vkWsiUtil.hpp"
39 #include "vkDeviceUtil.hpp"
41 #include "deUniquePtr.hpp"
42 #include "deSharedPtr.hpp"
44 #include "tcuImageCompare.hpp"
45 #include "tcuTestLog.hpp"
46 #include "tcuTextureUtil.hpp"
47 #include "tcuPlatform.hpp"
48 #include "tcuCommandLine.hpp"
55 using namespace vk::wsi;
68 typedef SharedPtr<Unique<VkPipeline> > SharedPtrVkPipeline;
69 typedef SharedPtr<Unique<VkImageView> > SharedPtrVkImageView;
72 inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move)
74 return SharedPtr<Unique<T> >(new Unique<T>(move));
92 std::string getUploadString (const int upload)
94 const char* strs[] = { "clear", "copy", "store", "draw" };
98 std::string getDownloadString (const int download)
100 const char* strs[] = { "copy", "load", "texture" };
101 return strs[download];
109 VkFormat imageFormat;
112 enum Download download;
113 bool isFormatListTest;
114 bool isSwapchainImageTest;
118 static const deUint32 COLOR_TABLE_SIZE = 4;
120 // Reference color values for float color rendering. Values have been chosen
121 // so that when the bit patterns are reinterpreted as a 16-bit float, we do not
122 // run into NaN / inf / denorm values.
123 static const Vec4 COLOR_TABLE_FLOAT[COLOR_TABLE_SIZE] =
125 Vec4(0.00f, 0.40f, 0.80f, 0.10f),
126 Vec4(0.50f, 0.10f, 0.90f, 0.20f),
127 Vec4(0.20f, 0.60f, 1.00f, 0.30f),
128 Vec4(0.30f, 0.70f, 0.00f, 0.40f),
131 // Reference color values for integer color rendering. We avoid negative
132 // values (even for SINT formats) to avoid the situation where sign extension
133 // leads to NaN / inf values when they are reinterpreted with a float
135 static const IVec4 COLOR_TABLE_INT[COLOR_TABLE_SIZE] =
137 IVec4(0x70707070, 0x3C3C3C3C, 0x65656565, 0x29292929),
138 IVec4(0x3C3C3C3C, 0x65656565, 0x29292929, 0x70707070),
139 IVec4(0x29292929, 0x70707070, 0x3C3C3C3C, 0x65656565),
140 IVec4(0x65656565, 0x29292929, 0x70707070, 0x3C3C3C3C),
143 // Reference clear colors created from the color table values
144 static const VkClearValue REFERENCE_CLEAR_COLOR_FLOAT[COLOR_TABLE_SIZE] =
146 makeClearValueColorF32(COLOR_TABLE_FLOAT[0].x(), COLOR_TABLE_FLOAT[0].y(), COLOR_TABLE_FLOAT[0].z(), COLOR_TABLE_FLOAT[0].w()),
147 makeClearValueColorF32(COLOR_TABLE_FLOAT[1].x(), COLOR_TABLE_FLOAT[1].y(), COLOR_TABLE_FLOAT[1].z(), COLOR_TABLE_FLOAT[1].w()),
148 makeClearValueColorF32(COLOR_TABLE_FLOAT[2].x(), COLOR_TABLE_FLOAT[2].y(), COLOR_TABLE_FLOAT[2].z(), COLOR_TABLE_FLOAT[2].w()),
149 makeClearValueColorF32(COLOR_TABLE_FLOAT[3].x(), COLOR_TABLE_FLOAT[3].y(), COLOR_TABLE_FLOAT[3].z(), COLOR_TABLE_FLOAT[3].w()),
152 static const Texture s_textures[] =
154 Texture(IMAGE_TYPE_2D, tcu::IVec3(32, 32, 1), 1),
155 Texture(IMAGE_TYPE_2D_ARRAY, tcu::IVec3(32, 32, 1), 4),
158 static VkClearValue getClearValueInt(const CaseDef& caseDef, deUint32 colorTableIndex)
160 VkClearValue clearValue;
161 deUint32 channelMask = 0;
163 if (caseDef.upload == UPLOAD_DRAW)
165 // We use this mask to get small color values in the vertex buffer and
166 // avoid possible round off errors from int-to-float conversions.
172 tcu::TextureFormat tcuFormat;
174 // Select a mask such that no integer-based color values end up
175 // reinterpreted as NaN/Inf/denorm values.
176 if (caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY)
177 format = caseDef.imageFormat;
179 format = caseDef.viewFormat;
181 tcuFormat = mapVkFormat(format);
183 switch (getChannelSize(tcuFormat.type))
189 channelMask = 0xFFFFu;
192 channelMask = 0xFFFFFFFFu;
199 clearValue.color.int32[0] = COLOR_TABLE_INT[colorTableIndex].x() & channelMask;
200 clearValue.color.int32[1] = COLOR_TABLE_INT[colorTableIndex].y() & channelMask;
201 clearValue.color.int32[2] = COLOR_TABLE_INT[colorTableIndex].z() & channelMask;
202 clearValue.color.int32[3] = COLOR_TABLE_INT[colorTableIndex].w() & channelMask;
207 VkImageType getImageType (const ImageType textureImageType)
209 switch (textureImageType)
212 case IMAGE_TYPE_2D_ARRAY:
213 return VK_IMAGE_TYPE_2D;
217 return VK_IMAGE_TYPE_LAST;
221 VkImageViewType getImageViewType (const ImageType textureImageType)
223 switch (textureImageType)
226 return VK_IMAGE_VIEW_TYPE_2D;
227 case IMAGE_TYPE_2D_ARRAY:
228 return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
232 return VK_IMAGE_VIEW_TYPE_LAST;
236 static const VkFormat s_formats[] =
238 VK_FORMAT_R32G32B32A32_SFLOAT,
239 VK_FORMAT_R16G16B16A16_SFLOAT,
240 VK_FORMAT_R32G32_SFLOAT,
241 VK_FORMAT_R16G16_SFLOAT,
242 VK_FORMAT_R32_SFLOAT,
244 VK_FORMAT_R32G32B32A32_UINT,
245 VK_FORMAT_R16G16B16A16_UINT,
246 VK_FORMAT_R8G8B8A8_UINT,
247 VK_FORMAT_R32G32_UINT,
248 VK_FORMAT_R16G16_UINT,
251 VK_FORMAT_R32G32B32A32_SINT,
252 VK_FORMAT_R16G16B16A16_SINT,
253 VK_FORMAT_R8G8B8A8_SINT,
254 VK_FORMAT_R32G32_SINT,
255 VK_FORMAT_R16G16_SINT,
258 VK_FORMAT_R8G8B8A8_UNORM,
259 VK_FORMAT_R8G8B8A8_SNORM,
260 VK_FORMAT_R8G8B8A8_SRGB,
261 VK_FORMAT_B8G8R8A8_UNORM,
262 VK_FORMAT_B8G8R8A8_SNORM,
263 VK_FORMAT_B8G8R8A8_SRGB,
266 static const VkFormat s_swapchainFormats[] =
268 VK_FORMAT_R8G8B8A8_UNORM,
269 VK_FORMAT_R8G8B8A8_SNORM,
270 VK_FORMAT_R8G8B8A8_SRGB,
271 VK_FORMAT_B8G8R8A8_UNORM,
272 VK_FORMAT_B8G8R8A8_SNORM,
273 VK_FORMAT_B8G8R8A8_SRGB,
276 bool isSRGBConversionRequired(const CaseDef& caseDef)
278 bool required = false;
280 if (isSRGB(mapVkFormat(caseDef.imageFormat)))
282 if (caseDef.upload == UPLOAD_CLEAR)
288 if (isSRGB(mapVkFormat(caseDef.viewFormat)))
290 if (caseDef.upload == UPLOAD_DRAW || caseDef.upload == UPLOAD_STORE)
300 inline bool formatsAreCompatible (const VkFormat format0, const VkFormat format1)
302 return format0 == format1 || mapVkFormat(format0).getPixelSize() == mapVkFormat(format1).getPixelSize();
305 std::string getColorFormatStr (const int numComponents, const bool isUint, const bool isSint)
307 std::ostringstream str;
308 if (numComponents == 1)
309 str << (isUint ? "uint" : isSint ? "int" : "float");
311 str << (isUint ? "u" : isSint ? "i" : "") << "vec" << numComponents;
316 std::string getShaderSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
318 std::ostringstream samplerType;
320 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
322 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
327 case VK_IMAGE_VIEW_TYPE_2D:
328 samplerType << "sampler2D";
331 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
332 samplerType << "sampler2DArray";
336 DE_FATAL("Ivalid image view type");
340 return samplerType.str();
343 void initPrograms (SourceCollections& programCollection, const CaseDef caseDef)
345 if (caseDef.upload == UPLOAD_DRAW)
348 std::ostringstream src;
349 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
351 << "layout(location = 0) in vec4 in_position;\n"
352 << "layout(location = 1) in vec4 in_color;\n"
353 << "layout(location = 0) out vec4 out_color;\n"
355 << "out gl_PerVertex {\n"
356 << " vec4 gl_Position;\n"
359 << "void main(void)\n"
361 << " gl_Position = in_position;\n"
362 << " out_color = in_color;\n"
365 programCollection.glslSources.add("uploadDrawVert") << glu::VertexSource(src.str());
369 const int numComponents = getNumUsedChannels(mapVkFormat(caseDef.viewFormat).order);
370 const bool isUint = isUintFormat(caseDef.viewFormat);
371 const bool isSint = isIntFormat(caseDef.viewFormat);
372 const std::string colorFormat = getColorFormatStr(numComponents, isUint, isSint);
374 std::ostringstream src;
375 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
377 << "layout(location = 0) in vec4 in_color;\n"
378 << "layout(location = 0) out " << colorFormat << " out_color;\n"
380 << "void main(void)\n"
382 << " out_color = " << colorFormat << "("
383 << (numComponents == 1 ? "in_color.r" :
384 numComponents == 2 ? "in_color.rg" :
385 numComponents == 3 ? "in_color.rgb" : "in_color")
389 programCollection.glslSources.add("uploadDrawFrag") << glu::FragmentSource(src.str());
393 if (caseDef.upload == UPLOAD_STORE)
395 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
396 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
397 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
398 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
399 const bool isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);
401 std::ostringstream src;
402 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
404 << "layout (local_size_x = 1) in;\n"
406 << "layout(binding=0, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " u_image;\n"
408 << "const " << colorTypeStr << " colorTable[] = " << colorTypeStr << "[](\n";
409 for (deUint32 idx = 0; idx < COLOR_TABLE_SIZE; idx++)
413 const VkClearValue clearValue = getClearValueInt(caseDef, idx);
415 src << " " << colorTypeStr << "(" << clearValue.color.int32[0] << ", " << clearValue.color.int32[1] << ", " << clearValue.color.int32[2] << ", " << clearValue.color.int32[3] << ")";
418 src << " " << colorTypeStr << "(" << COLOR_TABLE_FLOAT[idx].x() << ", " << COLOR_TABLE_FLOAT[idx].y() << ", " << COLOR_TABLE_FLOAT[idx].z() << ", " << COLOR_TABLE_FLOAT[idx].w() << ")";
419 if (idx < COLOR_TABLE_SIZE - 1)
425 << "void main(void)\n"
427 if (caseDef.imageType == IMAGE_TYPE_2D)
429 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
433 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
434 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
436 src << " " << colorTypeStr << " color = colorTable[gl_GlobalInvocationID.z];\n"
437 << " imageStore(u_image, pos, color);\n"
440 programCollection.glslSources.add("uploadStoreComp") << glu::ComputeSource(src.str());
443 if (caseDef.download == DOWNLOAD_LOAD)
445 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
446 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
447 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
448 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
450 std::ostringstream src;
451 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
453 << "layout (local_size_x = 1) in;\n"
455 << "layout(binding=0, " << imageFormatStr << ") readonly uniform " << imageTypeStr << " in_image;\n"
456 << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
458 << "void main(void)\n"
460 if (caseDef.imageType == IMAGE_TYPE_2D)
462 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
466 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
467 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
469 src << " imageStore(out_image, pos, imageLoad(in_image, pos));\n"
472 programCollection.glslSources.add("downloadLoadComp") << glu::ComputeSource(src.str());
475 if (caseDef.download == DOWNLOAD_TEXTURE)
477 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
478 const VkImageViewType viewType = getImageViewType(caseDef.imageType);
479 const std::string samplerTypeStr = getShaderSamplerType(tcuFormat, viewType);
480 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
481 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
482 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
484 std::ostringstream src;
485 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
487 << "layout (local_size_x = 1) in;\n"
489 << "layout(binding=0) uniform " << samplerTypeStr << " u_tex;\n"
490 << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
492 << "void main(void)\n"
494 if (caseDef.imageType == IMAGE_TYPE_2D)
496 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
500 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
501 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
503 src << " imageStore(out_image, pos, texelFetch(u_tex, pos, 0));\n"
506 programCollection.glslSources.add("downloadTextureComp") << glu::ComputeSource(src.str());
510 Move<VkImage> makeImage (const DeviceInterface& vk,
511 const VkDevice device,
512 VkImageCreateFlags flags,
513 VkImageType imageType,
514 const VkFormat format,
515 const VkFormat viewFormat,
516 const bool useImageFormatList,
518 const deUint32 numMipLevels,
519 const deUint32 numLayers,
520 const VkImageUsageFlags usage)
522 const VkFormat formatList[2] =
528 const VkImageFormatListCreateInfo formatListInfo =
530 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR, // VkStructureType sType;
531 DE_NULL, // const void* pNext;
532 2u, // deUint32 viewFormatCount
533 formatList // const VkFormat* pViewFormats
536 const VkImageCreateInfo imageParams =
538 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
539 useImageFormatList ? &formatListInfo : DE_NULL, // const void* pNext;
540 flags, // VkImageCreateFlags flags;
541 imageType, // VkImageType imageType;
542 format, // VkFormat format;
543 makeExtent3D(size), // VkExtent3D extent;
544 numMipLevels, // deUint32 mipLevels;
545 numLayers, // deUint32 arrayLayers;
546 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
547 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
548 usage, // VkImageUsageFlags usage;
549 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
550 0u, // deUint32 queueFamilyIndexCount;
551 DE_NULL, // const deUint32* pQueueFamilyIndices;
552 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
554 return createImage(vk, device, &imageParams);
557 inline VkImageSubresourceRange makeColorSubresourceRange (const int baseArrayLayer, const int layerCount)
559 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, static_cast<deUint32>(baseArrayLayer), static_cast<deUint32>(layerCount));
562 Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice device)
564 const VkSamplerCreateInfo samplerParams =
566 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
567 DE_NULL, // const void* pNext;
568 (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags;
569 VK_FILTER_NEAREST, // VkFilter magFilter;
570 VK_FILTER_NEAREST, // VkFilter minFilter;
571 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
572 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
573 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
574 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
575 0.0f, // float mipLodBias;
576 VK_FALSE, // VkBool32 anisotropyEnable;
577 1.0f, // float maxAnisotropy;
578 VK_FALSE, // VkBool32 compareEnable;
579 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
580 0.0f, // float minLod;
581 0.0f, // float maxLod;
582 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
583 VK_FALSE, // VkBool32 unnormalizedCoordinates;
586 return createSampler(vk, device, &samplerParams);
589 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
590 const VkDevice device,
591 const VkPipelineLayout pipelineLayout,
592 const VkRenderPass renderPass,
593 const VkShaderModule vertexModule,
594 const VkShaderModule fragmentModule,
595 const IVec2& renderSize,
596 const VkPrimitiveTopology topology,
597 const deUint32 subpass)
599 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
600 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
602 const VkVertexInputBindingDescription vertexInputBindingDescription =
604 0u, // deUint32 binding;
605 (deUint32)(2 * sizeof(Vec4)), // deUint32 stride;
606 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
609 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
612 0u, // deUint32 location;
613 0u, // deUint32 binding;
614 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
615 0u, // deUint32 offset;
618 1u, // deUint32 location;
619 0u, // deUint32 binding;
620 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
621 (deUint32)sizeof(Vec4), // deUint32 offset;
625 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
627 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
628 DE_NULL, // const void* pNext;
629 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
630 1u, // deUint32 vertexBindingDescriptionCount;
631 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
632 2u, // deUint32 vertexAttributeDescriptionCount;
633 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
636 return vk::makeGraphicsPipeline(vk, // const DeviceInterface& vk
637 device, // const VkDevice device
638 pipelineLayout, // const VkPipelineLayout pipelineLayout
639 vertexModule, // const VkShaderModule vertexShaderModule
640 DE_NULL, // const VkShaderModule tessellationControlModule
641 DE_NULL, // const VkShaderModule tessellationEvalModule
642 DE_NULL, // const VkShaderModule geometryShaderModule
643 fragmentModule, // const VkShaderModule fragmentShaderModule
644 renderPass, // const VkRenderPass renderPass
645 viewports, // const std::vector<VkViewport>& viewports
646 scissors, // const std::vector<VkRect2D>& scissors
647 topology, // const VkPrimitiveTopology topology
648 subpass, // const deUint32 subpass
649 0u, // const deUint32 patchControlPoints
650 &vertexInputStateCreateInfo); // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
653 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
654 const VkDevice device,
655 const VkPipelineLayout pipelineLayout,
656 const VkShaderModule shaderModule,
657 const VkSpecializationInfo* specInfo)
659 const VkPipelineShaderStageCreateInfo shaderStageInfo =
661 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
662 DE_NULL, // const void* pNext;
663 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
664 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
665 shaderModule, // VkShaderModule module;
666 "main", // const char* pName;
667 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
669 const VkComputePipelineCreateInfo pipelineInfo =
671 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
672 DE_NULL, // const void* pNext;
673 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
674 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage;
675 pipelineLayout, // VkPipelineLayout layout;
676 DE_NULL, // VkPipeline basePipelineHandle;
677 0, // deInt32 basePipelineIndex;
679 return createComputePipeline(vk, device, DE_NULL , &pipelineInfo);
682 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
683 const VkDevice device,
684 const VkFormat colorFormat,
685 const deUint32 numLayers)
687 const VkAttachmentDescription colorAttachmentDescription =
689 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
690 colorFormat, // VkFormat format;
691 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
692 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
693 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
694 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
695 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
696 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
697 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
699 vector<VkAttachmentDescription> attachmentDescriptions(numLayers, colorAttachmentDescription);
701 // Create a subpass for each attachment (each attachement is a layer of an arrayed image).
702 vector<VkAttachmentReference> colorAttachmentReferences (numLayers);
703 vector<VkSubpassDescription> subpasses;
705 // Ordering here must match the framebuffer attachments
706 for (deUint32 i = 0; i < numLayers; ++i)
708 const VkAttachmentReference attachmentRef =
710 i, // deUint32 attachment;
711 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
714 colorAttachmentReferences[i] = attachmentRef;
716 const VkSubpassDescription subpassDescription =
718 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
719 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
720 0u, // deUint32 inputAttachmentCount;
721 DE_NULL, // const VkAttachmentReference* pInputAttachments;
722 1u, // deUint32 colorAttachmentCount;
723 &colorAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments;
724 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
725 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
726 0u, // deUint32 preserveAttachmentCount;
727 DE_NULL // const deUint32* pPreserveAttachments;
729 subpasses.push_back(subpassDescription);
732 const VkRenderPassCreateInfo renderPassInfo =
734 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
735 DE_NULL, // const void* pNext;
736 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
737 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
738 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
739 static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount;
740 &subpasses[0], // const VkSubpassDescription* pSubpasses;
741 0u, // deUint32 dependencyCount;
742 DE_NULL // const VkSubpassDependency* pDependencies;
745 return createRenderPass(vk, device, &renderPassInfo);
748 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
750 return allocateCommandBuffer(vk, device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
753 vector<Vec4> genVertexData (const CaseDef& caseDef)
755 vector<Vec4> vectorData;
756 const bool isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);
758 for (deUint32 z = 0; z < caseDef.numLayers; z++)
760 const deUint32 colorIdx = z % COLOR_TABLE_SIZE;
765 const VkClearValue clearValue = getClearValueInt(caseDef, colorIdx);
766 const IVec4 colorInt (clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);
768 color = colorInt.cast<float>();
772 color = COLOR_TABLE_FLOAT[colorIdx];
775 vectorData.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
776 vectorData.push_back(color);
777 vectorData.push_back(Vec4(-1.0f, 1.0f, 0.0f, 1.0f));
778 vectorData.push_back(color);
779 vectorData.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
780 vectorData.push_back(color);
781 vectorData.push_back(Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
782 vectorData.push_back(color);
788 void generateExpectedImage(const tcu::PixelBufferAccess& image, const CaseDef& caseDef)
790 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(image.getFormat().type);
791 const bool isIntegerFormat = channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
792 const IVec2 size = caseDef.size.swizzle(0, 1);
794 for (int z = 0; z < static_cast<int>(caseDef.numLayers); z++)
796 const deUint32 colorIdx = z % COLOR_TABLE_SIZE;
797 for (int y = 0; y < size.y(); y++)
798 for (int x = 0; x < size.x(); x++)
802 const VkClearValue clearValue = getClearValueInt(caseDef, colorIdx);
803 const IVec4 colorInt (clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);
805 image.setPixel(colorInt, x, y, z);
808 if(isSRGBConversionRequired(caseDef))
809 image.setPixel(tcu::linearToSRGB(COLOR_TABLE_FLOAT[colorIdx]), x, y, z);
811 image.setPixel(COLOR_TABLE_FLOAT[colorIdx], x, y, z);
816 VkImageUsageFlags getImageUsageForTestCase (const CaseDef& caseDef)
818 VkImageUsageFlags flags = 0u;
820 switch (caseDef.upload)
823 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
826 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
829 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
832 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
835 DE_FATAL("Invalid upload method");
839 switch (caseDef.download)
841 case DOWNLOAD_TEXTURE:
842 flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
845 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
848 flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
851 DE_FATAL("Invalid download method");
855 // We can only create a view for the image if it is going to be used for any of these usages,
856 // so let's make sure that we have at least one of them.
857 VkImageUsageFlags viewRequiredFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
858 if (!(flags & viewRequiredFlags))
859 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
864 // Executes a combination of upload/download methods
865 class UploadDownloadExecutor
868 UploadDownloadExecutor(Context& context, VkDevice device, VkQueue queue, deUint32 queueFamilyIndex, const CaseDef& caseSpec) :
870 m_haveMaintenance2(context.isDeviceFunctionalitySupported("VK_KHR_maintenance2")),
871 m_vk(context.getDeviceInterface()),
874 m_queueFamilyIndex(queueFamilyIndex),
875 m_allocator(context.getDeviceInterface(), device,
876 getPhysicalDeviceMemoryProperties(context.getInstanceInterface(),
877 context.getPhysicalDevice()))
881 void runSwapchain(Context& context, VkBuffer buffer, VkImage image);
883 void run(Context& context, VkBuffer buffer);
886 void uploadClear(Context& context);
887 void uploadStore(Context& context);
888 void uploadCopy(Context& context);
889 void uploadDraw(Context& context);
890 void downloadCopy(Context& context, VkBuffer buffer);
891 void downloadTexture(Context& context, VkBuffer buffer);
892 void downloadLoad(Context& context, VkBuffer buffer);
894 void copyImageToBuffer(VkImage image,
897 const VkAccessFlags srcAccessMask,
898 const VkImageLayout oldLayout,
899 const deUint32 numLayers);
901 const CaseDef& m_caseDef;
903 bool m_haveMaintenance2;
905 const DeviceInterface& m_vk;
906 const VkDevice m_device;
907 const VkQueue m_queue;
908 const deUint32 m_queueFamilyIndex;
909 SimpleAllocator m_allocator;
911 Move<VkCommandPool> m_cmdPool;
912 Move<VkCommandBuffer> m_cmdBuffer;
914 bool m_imageIsIntegerFormat;
915 bool m_viewIsIntegerFormat;
917 // Target image for upload paths
919 Move<VkImage> m_imageHolder;
920 MovePtr<Allocation> m_imageAlloc;
925 Move<VkBuffer> colorBuffer;
926 VkDeviceSize colorBufferSize;
927 MovePtr<Allocation> colorBufferAlloc;
933 Move<VkBuffer> vertexBuffer;
934 MovePtr<Allocation> vertexBufferAlloc;
935 Move<VkPipelineLayout> pipelineLayout;
936 Move<VkRenderPass> renderPass;
937 Move<VkShaderModule> vertexModule;
938 Move<VkShaderModule> fragmentModule;
939 vector<SharedPtrVkImageView> attachments;
940 vector<VkImageView> attachmentHandles;
941 vector<SharedPtrVkPipeline> pipelines;
942 Move<VkFramebuffer> framebuffer;
948 Move<VkDescriptorPool> descriptorPool;
949 Move<VkPipelineLayout> pipelineLayout;
950 Move<VkDescriptorSetLayout> descriptorSetLayout;
951 Move<VkDescriptorSet> descriptorSet;
952 VkDescriptorImageInfo imageDescriptorInfo;
953 Move<VkShaderModule> computeModule;
954 Move<VkPipeline> computePipeline;
955 Move<VkImageView> imageView;
961 Move<VkDescriptorPool> descriptorPool;
962 Move<VkPipelineLayout> pipelineLayout;
963 Move<VkDescriptorSetLayout> descriptorSetLayout;
964 Move<VkDescriptorSet> descriptorSet;
965 Move<VkShaderModule> computeModule;
966 Move<VkPipeline> computePipeline;
967 Move<VkImageView> inImageView;
968 VkDescriptorImageInfo inImageDescriptorInfo;
969 Move<VkImage> outImage;
970 Move<VkImageView> outImageView;
971 MovePtr<Allocation> outImageAlloc;
972 VkDescriptorImageInfo outImageDescriptorInfo;
978 Move<VkDescriptorPool> descriptorPool;
979 Move<VkPipelineLayout> pipelineLayout;
980 Move<VkDescriptorSetLayout> descriptorSetLayout;
981 Move<VkDescriptorSet> descriptorSet;
982 Move<VkShaderModule> computeModule;
983 Move<VkPipeline> computePipeline;
984 Move<VkImageView> inImageView;
985 VkDescriptorImageInfo inImageDescriptorInfo;
986 Move<VkSampler> sampler;
987 Move<VkImage> outImage;
988 Move<VkImageView> outImageView;
989 MovePtr<Allocation> outImageAlloc;
990 VkDescriptorImageInfo outImageDescriptorInfo;
993 VkImageLayout m_imageLayoutAfterUpload;
994 VkAccessFlagBits m_imageUploadAccessMask;
998 void UploadDownloadExecutor::runSwapchain(Context& context, VkBuffer buffer, VkImage image)
1000 m_imageIsIntegerFormat = isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat);
1001 m_viewIsIntegerFormat = isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat);
1003 m_cmdPool = createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex);
1004 m_cmdBuffer = makeCommandBuffer(m_vk, m_device, *m_cmdPool);
1005 beginCommandBuffer(m_vk, *m_cmdBuffer);
1009 switch (m_caseDef.upload)
1012 uploadDraw(context);
1015 uploadStore(context);
1018 uploadClear(context);
1021 uploadCopy(context);
1024 DE_FATAL("Unsupported upload method");
1027 switch (m_caseDef.download)
1030 downloadCopy(context, buffer);
1033 downloadLoad(context, buffer);
1035 case DOWNLOAD_TEXTURE:
1036 downloadTexture(context, buffer);
1039 DE_FATAL("Unsupported download method");
1042 endCommandBuffer(m_vk, *m_cmdBuffer);
1043 submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer);
1047 void UploadDownloadExecutor::run(Context& context, VkBuffer buffer)
1049 m_imageIsIntegerFormat = isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat);
1050 m_viewIsIntegerFormat = isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat);
1052 m_cmdPool = createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex);
1053 m_cmdBuffer = makeCommandBuffer(m_vk, m_device, *m_cmdPool);
1054 beginCommandBuffer(m_vk, *m_cmdBuffer);
1056 const VkImageUsageFlags imageUsage = getImageUsageForTestCase(m_caseDef);
1057 const VkImageCreateFlags imageFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | (m_haveMaintenance2 ? VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR : 0);
1059 VkImageFormatProperties properties;
1060 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(),
1061 m_caseDef.imageFormat,
1062 getImageType(m_caseDef.imageType),
1063 VK_IMAGE_TILING_OPTIMAL,
1066 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1068 TCU_THROW(NotSupportedError, "Format not supported");
1071 m_imageHolder = makeImage(m_vk, m_device, imageFlags, getImageType(m_caseDef.imageType), m_caseDef.imageFormat, m_caseDef.viewFormat,
1072 m_caseDef.isFormatListTest, m_caseDef.size, 1u, m_caseDef.numLayers, imageUsage);
1073 m_image = *m_imageHolder;
1074 m_imageAlloc = bindImage(m_vk, m_device, m_allocator, m_image, MemoryRequirement::Any);
1076 switch (m_caseDef.upload)
1079 uploadDraw(context);
1082 uploadStore(context);
1085 uploadClear(context);
1088 uploadCopy(context);
1091 DE_FATAL("Unsupported upload method");
1094 switch (m_caseDef.download)
1097 downloadCopy(context, buffer);
1100 downloadLoad(context, buffer);
1102 case DOWNLOAD_TEXTURE:
1103 downloadTexture(context, buffer);
1106 DE_FATAL("Unsupported download method");
1109 endCommandBuffer(m_vk, *m_cmdBuffer);
1110 submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer);
1113 void UploadDownloadExecutor::uploadClear(Context& context)
1117 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1119 const VkImageSubresourceRange subresourceRange = makeColorSubresourceRange(0, m_caseDef.numLayers);
1120 const VkImageMemoryBarrier imageInitBarrier =
1122 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1123 DE_NULL, // const void* pNext;
1124 0u, // VkAccessFlags srcAccessMask;
1125 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAcessMask;
1126 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1127 requiredImageLayout, // VkImageLayout newLayout;
1128 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1129 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1130 m_image, // VkImage image;
1131 subresourceRange // VkImageSubresourceRange subresourceRange;
1134 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1135 0u, DE_NULL, 0u, DE_NULL, 1u, &imageInitBarrier);
1137 for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
1139 const VkImageSubresourceRange layerSubresourceRange = makeColorSubresourceRange(layer, 1u);
1140 const deUint32 colorIdx = layer % COLOR_TABLE_SIZE;
1141 const VkClearColorValue clearColor = m_imageIsIntegerFormat ? getClearValueInt(m_caseDef, colorIdx).color : REFERENCE_CLEAR_COLOR_FLOAT[colorIdx].color;
1142 m_vk.cmdClearColorImage(*m_cmdBuffer, m_image, requiredImageLayout, &clearColor, 1u, &layerSubresourceRange);
1145 m_imageLayoutAfterUpload = requiredImageLayout;
1146 m_imageUploadAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1149 void UploadDownloadExecutor::uploadStore(Context& context)
1151 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1153 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1154 DE_NULL, // const void* pNext
1155 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage;
1157 m_uStore.imageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1158 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1160 // Setup compute pipeline
1161 m_uStore.descriptorPool = DescriptorPoolBuilder()
1162 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1163 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1165 m_uStore.descriptorSetLayout = DescriptorSetLayoutBuilder()
1166 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1167 .build(m_vk, m_device);
1169 m_uStore.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_uStore.descriptorSetLayout);
1170 m_uStore.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_uStore.descriptorPool, *m_uStore.descriptorSetLayout);
1171 m_uStore.imageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_uStore.imageView, VK_IMAGE_LAYOUT_GENERAL);
1172 m_uStore.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadStoreComp"), 0);
1173 m_uStore.computePipeline = makeComputePipeline(m_vk, m_device, *m_uStore.pipelineLayout, *m_uStore.computeModule, DE_NULL);
1175 DescriptorSetUpdateBuilder()
1176 .writeSingle(*m_uStore.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_uStore.imageDescriptorInfo)
1177 .update(m_vk, m_device);
1179 // Transition storage image for shader access (imageStore)
1180 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1181 const VkImageMemoryBarrier imageBarrier =
1183 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1184 DE_NULL, // const void* pNext;
1185 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1186 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1187 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1188 requiredImageLayout, // VkImageLayout newLayout;
1189 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1190 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1191 m_image, // VkImage image;
1192 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1195 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1196 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
1199 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.computePipeline);
1200 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.pipelineLayout, 0u, 1u, &m_uStore.descriptorSet.get(), 0u, DE_NULL);
1201 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1203 m_imageLayoutAfterUpload = requiredImageLayout;
1204 m_imageUploadAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
1207 void UploadDownloadExecutor::uploadCopy(Context& context)
1211 // Create a host-mappable buffer with the color data to upload
1212 const VkDeviceSize pixelSize = tcu::getPixelSize(mapVkFormat(m_caseDef.imageFormat));
1213 const VkDeviceSize layerSize = m_caseDef.size.x() * m_caseDef.size.y() * m_caseDef.size.z() * pixelSize;
1215 m_uCopy.colorBufferSize = layerSize * m_caseDef.numLayers;
1216 m_uCopy.colorBuffer = makeBuffer(m_vk, m_device, m_uCopy.colorBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
1217 m_uCopy.colorBufferAlloc = bindBuffer(m_vk, m_device, m_allocator, *m_uCopy.colorBuffer, MemoryRequirement::HostVisible);
1219 // Fill color buffer
1220 const tcu::TextureFormat tcuFormat = mapVkFormat(m_caseDef.imageFormat);
1221 VkDeviceSize layerOffset = 0ull;
1222 for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
1224 tcu::PixelBufferAccess imageAccess = tcu::PixelBufferAccess(tcuFormat, m_caseDef.size.x(), m_caseDef.size.y(), 1u, (deUint8*) m_uCopy.colorBufferAlloc->getHostPtr() + layerOffset);
1225 const deUint32 colorIdx = layer % COLOR_TABLE_SIZE;
1226 if (m_imageIsIntegerFormat)
1228 const VkClearValue clearValue = getClearValueInt(m_caseDef, colorIdx);
1229 const IVec4 colorInt (clearValue.color.int32[0], clearValue.color.int32[1], clearValue.color.int32[2], clearValue.color.int32[3]);
1231 tcu::clear(imageAccess, colorInt);
1234 tcu::clear(imageAccess, COLOR_TABLE_FLOAT[colorIdx]);
1235 layerOffset += layerSize;
1238 flushAlloc(m_vk, m_device, *(m_uCopy.colorBufferAlloc));
1240 // Prepare buffer and image for copy
1241 const VkBufferMemoryBarrier bufferInitBarrier =
1243 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1244 DE_NULL, // const void* pNext;
1245 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
1246 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1247 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1248 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1249 *m_uCopy.colorBuffer, // VkBuffer buffer;
1250 0ull, // VkDeviceSize offset;
1251 VK_WHOLE_SIZE, // VkDeviceSize size;
1254 const VkImageMemoryBarrier imageInitBarrier =
1256 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1257 DE_NULL, // const void* pNext;
1258 0u, // VkAccessFlags srcAccessMask;
1259 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1260 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1261 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1262 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1263 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1264 m_image, // VkImage image;
1265 makeColorSubresourceRange(0, m_caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
1268 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1269 0u, DE_NULL, 1u, &bufferInitBarrier, 1u, &imageInitBarrier);
1271 // Copy buffer to image
1272 const VkImageSubresourceLayers subresource =
1274 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1275 0u, // deUint32 mipLevel;
1276 0u, // deUint32 baseArrayLayer;
1277 m_caseDef.numLayers, // deUint32 layerCount;
1280 const VkBufferImageCopy region =
1282 0ull, // VkDeviceSize bufferOffset;
1283 0u, // deUint32 bufferRowLength;
1284 0u, // deUint32 bufferImageHeight;
1285 subresource, // VkImageSubresourceLayers imageSubresource;
1286 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
1287 makeExtent3D(m_caseDef.size), // VkExtent3D imageExtent;
1290 m_vk.cmdCopyBufferToImage(*m_cmdBuffer, *m_uCopy.colorBuffer, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ®ion);
1292 const VkImageMemoryBarrier imagePostInitBarrier =
1294 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1295 DE_NULL, // const void* pNext;
1296 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1297 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1298 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1299 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1300 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1301 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1302 m_image, // VkImage image;
1303 makeColorSubresourceRange(0, m_caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
1306 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1307 0u, DE_NULL, 0u, DE_NULL, 1u, &imagePostInitBarrier);
1309 m_imageLayoutAfterUpload = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1310 m_imageUploadAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1313 void UploadDownloadExecutor::uploadDraw(Context& context)
1315 // Create vertex buffer
1317 const vector<Vec4> vertices = genVertexData(m_caseDef);
1318 const VkDeviceSize vertexBufferSize = vertices.size() * sizeof(Vec4);
1320 m_uDraw.vertexBuffer = makeBuffer(m_vk, m_device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
1321 m_uDraw.vertexBufferAlloc = bindBuffer(m_vk, m_device, m_allocator, *m_uDraw.vertexBuffer, MemoryRequirement::HostVisible);
1322 deMemcpy(m_uDraw.vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
1323 flushAlloc(m_vk, m_device, *(m_uDraw.vertexBufferAlloc));
1326 // Create attachments and pipelines for each image layer
1327 m_uDraw.pipelineLayout = makePipelineLayout(m_vk, m_device);
1328 m_uDraw.renderPass = makeRenderPass(m_vk, m_device, m_caseDef.viewFormat, m_caseDef.numLayers);
1329 m_uDraw.vertexModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawVert"), 0u);
1330 m_uDraw.fragmentModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawFrag"), 0u);
1332 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
1334 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1336 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1337 DE_NULL, // const void* pNext
1338 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags usage;
1340 Move<VkImageView> imageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1341 makeColorSubresourceRange(subpassNdx, 1), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1342 m_uDraw.attachmentHandles.push_back(*imageView);
1343 m_uDraw.attachments.push_back(makeSharedPtr(imageView));
1344 m_uDraw.pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(m_vk, m_device, *m_uDraw.pipelineLayout, *m_uDraw.renderPass, *m_uDraw.vertexModule, *m_uDraw.fragmentModule,
1345 m_caseDef.size.swizzle(0, 1), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, subpassNdx)));
1348 // Create framebuffer
1350 const IVec2 size = m_caseDef.size.swizzle(0, 1);
1352 m_uDraw.framebuffer = makeFramebuffer(m_vk, m_device, *m_uDraw.renderPass, static_cast<deUint32>(m_uDraw.attachmentHandles.size()), &m_uDraw.attachmentHandles[0], static_cast<deUint32>(size.x()), static_cast<deUint32>(size.y()));
1355 // Create command buffer
1358 vector<VkClearValue> clearValues (m_caseDef.numLayers, m_viewIsIntegerFormat ? getClearValueInt(m_caseDef, 0) : REFERENCE_CLEAR_COLOR_FLOAT[0]);
1360 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]);
1364 const VkDeviceSize vertexDataPerDraw = 4 * 2 * sizeof(Vec4);
1365 VkDeviceSize vertexBufferOffset = 0ull;
1366 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
1368 if (subpassNdx != 0)
1369 m_vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
1371 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_uDraw.pipelines[subpassNdx]);
1373 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_uDraw.vertexBuffer.get(), &vertexBufferOffset);
1374 m_vk.cmdDraw(*m_cmdBuffer, 4u, 1u, 0u, 0u);
1375 vertexBufferOffset += vertexDataPerDraw;
1378 endRenderPass(m_vk, *m_cmdBuffer);
1381 m_imageLayoutAfterUpload = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1382 m_imageUploadAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1385 void UploadDownloadExecutor::downloadCopy(Context& context, VkBuffer buffer)
1389 copyImageToBuffer(m_image, buffer, m_caseDef.size, m_imageUploadAccessMask, m_imageLayoutAfterUpload, m_caseDef.numLayers);
1392 void UploadDownloadExecutor::downloadTexture(Context& context, VkBuffer buffer)
1394 // Create output image with download result
1395 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1396 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);
1397 m_dTex.outImageAlloc = bindImage(m_vk, m_device, m_allocator, *m_dTex.outImage, MemoryRequirement::Any);
1398 m_dTex.outImageView = makeImageView(m_vk, m_device, *m_dTex.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));
1400 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1402 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1403 DE_NULL, // const void* pNext
1404 VK_IMAGE_USAGE_SAMPLED_BIT, // VkImageUsageFlags usage;
1406 m_dTex.inImageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1407 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1408 m_dTex.sampler = makeSampler(m_vk, m_device);
1410 // Setup compute pipeline
1411 m_dTex.descriptorPool = DescriptorPoolBuilder()
1412 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1413 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1414 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1416 m_dTex.descriptorSetLayout = DescriptorSetLayoutBuilder()
1417 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT, &m_dTex.sampler.get())
1418 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1419 .build(m_vk, m_device);
1421 m_dTex.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_dTex.descriptorSetLayout);
1422 m_dTex.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_dTex.descriptorPool, *m_dTex.descriptorSetLayout);
1423 m_dTex.inImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dTex.inImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1424 m_dTex.outImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dTex.outImageView, VK_IMAGE_LAYOUT_GENERAL);
1425 m_dTex.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadTextureComp"), 0);
1426 m_dTex.computePipeline = makeComputePipeline(m_vk, m_device, *m_dTex.pipelineLayout, *m_dTex.computeModule, DE_NULL);
1428 DescriptorSetUpdateBuilder()
1429 .writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &m_dTex.inImageDescriptorInfo)
1430 .writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dTex.outImageDescriptorInfo)
1431 .update(m_vk, m_device);
1433 // Transition images for shader access (texture / imageStore)
1434 const VkImageMemoryBarrier imageBarriers[] =
1437 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1438 DE_NULL, // const void* pNext;
1439 (VkAccessFlags)m_imageUploadAccessMask, // VkAccessFlags srcAccessMask;
1440 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
1441 m_imageLayoutAfterUpload, // VkImageLayout oldLayout;
1442 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
1443 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1444 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1445 m_image, // VkImage image;
1446 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1449 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1450 DE_NULL, // const void* pNext;
1451 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1452 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1453 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1454 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout;
1455 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1456 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1457 *m_dTex.outImage, // VkImage image;
1458 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1462 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1463 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
1466 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.computePipeline);
1467 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.pipelineLayout, 0u, 1u, &m_dTex.descriptorSet.get(), 0u, DE_NULL);
1468 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1470 // Copy output image to color buffer
1471 copyImageToBuffer(*m_dTex.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL, m_caseDef.numLayers);
1474 void UploadDownloadExecutor::downloadLoad(Context& context, VkBuffer buffer)
1476 // Create output image with download result
1477 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1478 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);
1479 m_dLoad.outImageAlloc = bindImage(m_vk, m_device, m_allocator, *m_dLoad.outImage, MemoryRequirement::Any);
1480 m_dLoad.outImageView = makeImageView(m_vk, m_device, *m_dLoad.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));
1482 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1484 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1485 DE_NULL, // const void* pNext
1486 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage;
1488 m_dLoad.inImageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1489 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1491 // Setup compute pipeline
1492 m_dLoad.descriptorPool = DescriptorPoolBuilder()
1493 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2u)
1494 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1496 m_dLoad.descriptorSetLayout = DescriptorSetLayoutBuilder()
1497 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1498 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1499 .build(m_vk, m_device);
1501 m_dLoad.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_dLoad.descriptorSetLayout);
1502 m_dLoad.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_dLoad.descriptorPool, *m_dLoad.descriptorSetLayout);
1503 m_dLoad.inImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dLoad.inImageView, VK_IMAGE_LAYOUT_GENERAL);
1504 m_dLoad.outImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dLoad.outImageView, VK_IMAGE_LAYOUT_GENERAL);
1505 m_dLoad.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadLoadComp"), 0);
1506 m_dLoad.computePipeline = makeComputePipeline(m_vk, m_device, *m_dLoad.pipelineLayout, *m_dLoad.computeModule, DE_NULL);
1508 DescriptorSetUpdateBuilder()
1509 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.inImageDescriptorInfo)
1510 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.outImageDescriptorInfo)
1511 .update(m_vk, m_device);
1513 // Transition storage images for shader access (imageLoad/Store)
1514 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1515 const VkImageMemoryBarrier imageBarriers[] =
1518 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1519 DE_NULL, // const void* pNext;
1520 (VkAccessFlags)m_imageUploadAccessMask, // VkAccessFlags srcAccessMask;
1521 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
1522 m_imageLayoutAfterUpload, // VkImageLayout oldLayout;
1523 requiredImageLayout, // VkImageLayout newLayout;
1524 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1525 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1526 m_image, // VkImage image;
1527 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1530 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1531 DE_NULL, // const void* pNext;
1532 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1533 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1534 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1535 requiredImageLayout, // VkImageLayout newLayout;
1536 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1537 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1538 *m_dLoad.outImage, // VkImage image;
1539 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1543 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1544 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
1547 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.computePipeline);
1548 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.pipelineLayout, 0u, 1u, &m_dLoad.descriptorSet.get(), 0u, DE_NULL);
1549 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1551 // Copy output image to color buffer
1552 copyImageToBuffer(*m_dLoad.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, requiredImageLayout, m_caseDef.numLayers);
1555 void UploadDownloadExecutor::copyImageToBuffer(VkImage sourceImage,
1558 const VkAccessFlags srcAccessMask,
1559 const VkImageLayout oldLayout,
1560 const deUint32 numLayers)
1562 // Copy result to host visible buffer for inspection
1563 const VkImageMemoryBarrier imageBarrier =
1565 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1566 DE_NULL, // const void* pNext;
1567 srcAccessMask, // VkAccessFlags srcAccessMask;
1568 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1569 oldLayout, // VkImageLayout oldLayout;
1570 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
1571 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1572 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1573 sourceImage, // VkImage image;
1574 makeColorSubresourceRange(0, numLayers) // VkImageSubresourceRange subresourceRange;
1577 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1578 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
1580 const VkImageSubresourceLayers subresource =
1582 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1583 0u, // deUint32 mipLevel;
1584 0u, // deUint32 baseArrayLayer;
1585 numLayers, // deUint32 layerCount;
1588 const VkBufferImageCopy region =
1590 0ull, // VkDeviceSize bufferOffset;
1591 0u, // deUint32 bufferRowLength;
1592 0u, // deUint32 bufferImageHeight;
1593 subresource, // VkImageSubresourceLayers imageSubresource;
1594 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
1595 makeExtent3D(size), // VkExtent3D imageExtent;
1598 m_vk.cmdCopyImageToBuffer(*m_cmdBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, ®ion);
1600 const VkBufferMemoryBarrier bufferBarrier =
1602 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1603 DE_NULL, // const void* pNext;
1604 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1605 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
1606 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1607 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1608 buffer, // VkBuffer buffer;
1609 0ull, // VkDeviceSize offset;
1610 VK_WHOLE_SIZE, // VkDeviceSize size;
1613 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
1614 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
1617 tcu::TestStatus testMutable (Context& context, const CaseDef caseDef)
1619 const DeviceInterface& vk = context.getDeviceInterface();
1620 const VkDevice device = context.getDevice();
1621 Allocator& allocator = context.getDefaultAllocator();
1623 // Create a color buffer for host-inspection of results
1624 // For the Copy download method, this is the target of the download, for other
1625 // download methods, pixel data will be copied to this buffer from the download
1627 const VkDeviceSize colorBufferSize = caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat));
1628 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1629 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1630 deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
1631 flushAlloc(vk, device, *colorBufferAlloc);
1634 UploadDownloadExecutor executor(context, device, context.getUniversalQueue(), context.getUniversalQueueFamilyIndex(), caseDef);
1635 executor.run(context, *colorBuffer);
1639 invalidateAlloc(vk, device, *colorBufferAlloc);
1641 // For verification purposes, we use the format of the upload to generate the expected image
1642 const VkFormat format = caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat;
1643 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
1644 const bool isIntegerFormat = isUintFormat(format) || isIntFormat(format);
1645 const tcu::ConstPixelBufferAccess resultImage (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr());
1646 tcu::TextureLevel textureLevel (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers);
1647 const tcu::PixelBufferAccess expectedImage = textureLevel.getAccess();
1648 generateExpectedImage(expectedImage, caseDef);
1651 if (isIntegerFormat)
1652 ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
1654 ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
1655 return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
1659 void checkSupport (Context& context, const CaseDef caseDef)
1661 const InstanceInterface& vki = context.getInstanceInterface();
1662 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
1664 // If this is a VK_KHR_image_format_list test, check that the extension is supported
1665 if (caseDef.isFormatListTest)
1666 context.requireDeviceFunctionality("VK_KHR_image_format_list");
1668 // Check required features on the format for the required upload/download methods
1669 VkFormatProperties imageFormatProps, viewFormatProps;
1670 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.imageFormat, &imageFormatProps);
1671 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.viewFormat, &viewFormatProps);
1673 VkFormatFeatureFlags viewFormatFeatureFlags = 0u;
1674 switch (caseDef.upload)
1677 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
1680 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1683 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1686 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1689 DE_FATAL("Invalid upload method");
1692 switch (caseDef.download)
1694 case DOWNLOAD_TEXTURE:
1695 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
1696 // For the texture case we write the samples read to a separate output image with the same view format
1697 // so we need to check that we can also use the view format for storage
1698 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1701 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1704 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1707 DE_FATAL("Invalid download method");
1711 if ((viewFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags)
1712 TCU_THROW(NotSupportedError, "View format doesn't support upload/download method");
1714 const bool haveMaintenance2 = context.isDeviceFunctionalitySupported("VK_KHR_maintenance2");
1716 // We don't use the base image for anything other than transfer
1717 // operations so there are no features to check. However, The Vulkan
1718 // 1.0 spec does not allow us to create an image view with usage that
1719 // is not supported by the main format. With VK_KHR_maintenance2, we
1720 // can do this via VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR.
1721 if ((imageFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags &&
1724 TCU_THROW(NotSupportedError, "Image format doesn't support upload/download method");
1727 // If no format feature flags are supported, the format itself is not supported,
1728 // and images of that format cannot be created.
1729 if (imageFormatProps.optimalTilingFeatures == 0)
1731 TCU_THROW(NotSupportedError, "Base image format is not supported");
1735 tcu::TestCaseGroup* createImageMutableTests (TestContext& testCtx)
1737 de::MovePtr<TestCaseGroup> testGroup (new TestCaseGroup(testCtx, "mutable", "Cases with mutable images"));
1738 for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx)
1740 const Texture& texture = s_textures[textureNdx];
1741 de::MovePtr<tcu::TestCaseGroup> groupByImageViewType (new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), ""));
1743 for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++imageFormatNdx)
1744 for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++viewFormatNdx)
1746 if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_formats[imageFormatNdx], s_formats[viewFormatNdx]))
1748 for (int upload = 0; upload < UPLOAD_LAST; upload++)
1750 if (upload == UPLOAD_STORE && !isFormatImageLoadStoreCapable(s_formats[viewFormatNdx]))
1753 for (int download = 0; download < DOWNLOAD_LAST; download++)
1755 if ((download == DOWNLOAD_LOAD || download == DOWNLOAD_TEXTURE) &&
1756 !isFormatImageLoadStoreCapable(s_formats[viewFormatNdx]))
1762 texture.layerSize(),
1763 static_cast<deUint32>(texture.numLayers()),
1764 s_formats[imageFormatNdx],
1765 s_formats[viewFormatNdx],
1766 static_cast<enum Upload>(upload),
1767 static_cast<enum Download>(download),
1768 false, // isFormatListTest;
1769 false, // isSwapchainImageTest
1770 vk::wsi::TYPE_LAST // wsiType
1773 std::string caseName = getFormatShortString(s_formats[imageFormatNdx]) + "_" + getFormatShortString(s_formats[viewFormatNdx]) +
1774 "_" + getUploadString(upload) + "_" + getDownloadString(download);
1775 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", checkSupport, initPrograms, testMutable, caseDef);
1777 caseDef.isFormatListTest = true;
1778 caseName += "_format_list";
1779 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", checkSupport, initPrograms, testMutable, caseDef);
1785 testGroup->addChild(groupByImageViewType.release());
1788 return testGroup.release();
1791 typedef vector<VkExtensionProperties> Extensions;
1793 void checkAllSupported(const Extensions& supportedExtensions, const vector<string>& requiredExtensions)
1795 for (vector<string>::const_iterator requiredExtName = requiredExtensions.begin();
1796 requiredExtName != requiredExtensions.end();
1799 if (!isExtensionSupported(supportedExtensions, RequiredExtension(*requiredExtName)))
1800 TCU_THROW(NotSupportedError, (*requiredExtName + " is not supported").c_str());
1804 CustomInstance createInstanceWithWsi(Context& context,
1805 const Extensions& supportedExtensions,
1807 const VkAllocationCallbacks* pAllocator = DE_NULL)
1809 vector<string> extensions;
1811 extensions.push_back("VK_KHR_surface");
1812 extensions.push_back(getExtensionName(wsiType));
1814 // VK_EXT_swapchain_colorspace adds new surface formats. Driver can enumerate
1815 // the formats regardless of whether VK_EXT_swapchain_colorspace was enabled,
1816 // but using them without enabling the extension is not allowed. Thus we have
1819 // 1) Filter out non-core formats to stay within valid usage.
1821 // 2) Enable VK_EXT_swapchain colorspace if advertised by the driver.
1823 // We opt for (2) as it provides basic coverage for the extension as a bonus.
1824 if (isExtensionSupported(supportedExtensions, RequiredExtension("VK_EXT_swapchain_colorspace")))
1825 extensions.push_back("VK_EXT_swapchain_colorspace");
1827 checkAllSupported(supportedExtensions, extensions);
1829 return createCustomInstanceWithExtensions(context, extensions, pAllocator);
1833 Move<VkDevice> createDeviceWithWsi(const PlatformInterface& vkp,
1834 VkInstance instance,
1835 const InstanceInterface& vki,
1836 VkPhysicalDevice physicalDevice,
1837 const Extensions& supportedExtensions,
1838 const deUint32 queueFamilyIndex,
1839 const VkAllocationCallbacks* pAllocator,
1840 bool enableValidation)
1842 const float queuePriorities[] = { 1.0f };
1843 const VkDeviceQueueCreateInfo queueInfos[] =
1846 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1848 (VkDeviceQueueCreateFlags)0,
1850 DE_LENGTH_OF_ARRAY(queuePriorities),
1854 VkPhysicalDeviceFeatures features;
1855 deMemset(&features, 0x0, sizeof(features));
1857 const char* const extensions[] = { "VK_KHR_swapchain", "VK_KHR_swapchain_mutable_format" };
1859 const VkDeviceCreateInfo deviceParams =
1861 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1863 (VkDeviceCreateFlags)0,
1864 DE_LENGTH_OF_ARRAY(queueInfos),
1866 0u, // enabledLayerCount
1867 DE_NULL, // ppEnabledLayerNames
1868 DE_LENGTH_OF_ARRAY(extensions), // enabledExtensionCount
1869 DE_ARRAY_BEGIN(extensions), // ppEnabledExtensionNames
1873 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(extensions); ++ndx)
1875 if (!isExtensionSupported(supportedExtensions, RequiredExtension(extensions[ndx])))
1876 TCU_THROW(NotSupportedError, (string(extensions[ndx]) + " is not supported").c_str());
1879 return createCustomDevice(enableValidation, vkp, instance, vki, physicalDevice, &deviceParams, pAllocator);
1882 struct InstanceHelper
1884 const vector<VkExtensionProperties> supportedExtensions;
1885 const CustomInstance instance;
1886 const InstanceDriver& vki;
1888 InstanceHelper(Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
1889 : supportedExtensions(enumerateInstanceExtensionProperties(context.getPlatformInterface(),
1891 , instance(createInstanceWithWsi(context,
1892 supportedExtensions,
1895 , vki(instance.getDriver())
1902 const VkPhysicalDevice physicalDevice;
1903 const deUint32 queueFamilyIndex;
1904 const Unique<VkDevice> device;
1905 const DeviceDriver vkd;
1906 const VkQueue queue;
1908 DeviceHelper(Context& context,
1909 const InstanceInterface& vki,
1910 VkInstance instance,
1911 VkSurfaceKHR surface,
1912 const VkAllocationCallbacks* pAllocator = DE_NULL)
1913 : physicalDevice(chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
1914 , queueFamilyIndex(chooseQueueFamilyIndex(vki, physicalDevice, surface))
1915 , device(createDeviceWithWsi(context.getPlatformInterface(),
1916 context.getInstance(),
1919 enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL),
1922 context.getTestContext().getCommandLine().isValidationEnabled()))
1923 , vkd(context.getPlatformInterface(), context.getInstance(), *device)
1924 , queue(getDeviceQueue(vkd, *device, queueFamilyIndex, 0))
1929 MovePtr<Display> createDisplay(const vk::Platform& platform,
1930 const Extensions& supportedExtensions,
1935 return MovePtr<Display>(platform.createWsiDisplay(wsiType));
1937 catch (const tcu::NotSupportedError& e)
1939 if (isExtensionSupported(supportedExtensions, RequiredExtension(getExtensionName(wsiType))) &&
1940 platform.hasDisplay(wsiType))
1942 // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
1943 // must support creating native display & window for that WSI type.
1944 throw tcu::TestError(e.getMessage());
1951 MovePtr<Window> createWindow(const Display& display, const Maybe<UVec2>& initialSize)
1955 return MovePtr<Window>(display.createWindow(initialSize));
1957 catch (const tcu::NotSupportedError& e)
1959 // See createDisplay - assuming that wsi::Display was supported platform port
1960 // should also support creating a window.
1961 throw tcu::TestError(e.getMessage());
1965 struct NativeObjects
1967 const UniquePtr<Display> display;
1968 const UniquePtr<Window> window;
1970 NativeObjects(Context& context,
1971 const Extensions& supportedExtensions,
1973 const Maybe<UVec2>& initialWindowSize = tcu::nothing<UVec2>())
1974 : display(createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
1975 , window(createWindow(*display, initialWindowSize))
1979 Move<VkSwapchainKHR> makeSwapchain(const DeviceInterface& vk,
1980 const VkDevice device,
1981 const vk::wsi::Type wsiType,
1982 const VkSurfaceKHR surface,
1983 const VkSurfaceCapabilitiesKHR capabilities,
1984 const VkSurfaceFormatKHR surfaceFormat,
1985 const VkFormat viewFormat,
1986 const deUint32 numLayers,
1987 const VkImageUsageFlags usage,
1988 const tcu::UVec2& desiredSize,
1989 deUint32 desiredImageCount
1992 const VkFormat formatList[2] =
1994 surfaceFormat.format,
1998 const VkImageFormatListCreateInfo formatListInfo =
2000 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR, // VkStructureType sType;
2001 DE_NULL, // const void* pNext;
2002 2u, // deUint32 viewFormatCount
2003 formatList // const VkFormat* pViewFormats
2006 const VkSurfaceTransformFlagBitsKHR transform = (capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
2007 const PlatformProperties& platformProperties = getPlatformProperties(wsiType);
2009 const VkSwapchainCreateInfoKHR swapchainInfo =
2011 VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, // VkStructureType sType;
2012 &formatListInfo, // const void* pNext;
2013 VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR, // VkSwapchainCreateFlagsKHR flags;
2014 surface, // VkSurfaceKHR surface;
2015 de::clamp(desiredImageCount, capabilities.minImageCount, capabilities.maxImageCount > 0 ? capabilities.maxImageCount : capabilities.minImageCount + desiredImageCount), // deUint32 minImageCount;
2016 surfaceFormat.format, // VkFormat imageFormat;
2017 surfaceFormat.colorSpace, // VkColorSpaceKHR imageColorSpace;
2018 (platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE
2019 ? capabilities.currentExtent : vk::makeExtent2D(desiredSize.x(), desiredSize.y())), // VkExtent2D imageExtent;
2020 numLayers, // deUint32 imageArrayLayers;
2021 usage, // VkImageUsageFlags imageUsage;
2022 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode imageSharingMode;
2023 0u, // deUint32 queueFamilyIndexCount;
2024 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2025 transform, // VkSurfaceTransformFlagBitsKHR preTransform;
2026 VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, // VkCompositeAlphaFlagBitsKHR compositeAlpha;
2027 VK_PRESENT_MODE_FIFO_KHR, // VkPresentModeKHR presentMode;
2028 VK_FALSE, // VkBool32 clipped;
2029 (VkSwapchainKHR)0 // VkSwapchainKHR oldSwapchain;
2032 return createSwapchainKHR(vk, device, &swapchainInfo);
2035 tcu::TestStatus testSwapchainMutable(Context& context, CaseDef caseDef)
2037 const Type wsiType(caseDef.wsiType);
2038 const tcu::UVec2 desiredSize(256, 256);
2039 const InstanceHelper instHelper(context, wsiType);
2040 const NativeObjects native(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
2041 const Unique<VkSurfaceKHR> surface(createSurface(instHelper.vki, instHelper.instance, wsiType, *native.display, *native.window));
2042 const DeviceHelper devHelper(context, instHelper.vki, instHelper.instance, *surface);
2043 const DeviceInterface& vk = devHelper.vkd;
2044 const InstanceDriver& vki = instHelper.vki;
2045 const VkDevice device = *devHelper.device;
2046 const VkPhysicalDevice physDevice = devHelper.physicalDevice;
2047 SimpleAllocator allocator(vk, device, getPhysicalDeviceMemoryProperties(vki, context.getPhysicalDevice()));
2049 const VkImageUsageFlags imageUsage = getImageUsageForTestCase(caseDef);
2052 VkImageFormatProperties properties;
2055 result = vki.getPhysicalDeviceImageFormatProperties(physDevice, caseDef.imageFormat, getImageType(caseDef.imageType), VK_IMAGE_TILING_OPTIMAL, imageUsage, 0, &properties);
2057 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
2059 TCU_THROW(NotSupportedError, "Image format is not supported for required usage");
2062 result = vki.getPhysicalDeviceImageFormatProperties(physDevice, caseDef.viewFormat, getImageType(caseDef.imageType), VK_IMAGE_TILING_OPTIMAL, imageUsage, 0, &properties);
2064 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
2066 TCU_THROW(NotSupportedError, "Image view format is not supported for required usage");
2070 const VkSurfaceCapabilitiesKHR capabilities = getPhysicalDeviceSurfaceCapabilities(vki,
2074 if (caseDef.numLayers > capabilities.maxImageArrayLayers)
2075 caseDef.numLayers = capabilities.maxImageArrayLayers;
2077 // Check support for requested formats by swapchain surface
2078 const vector<VkSurfaceFormatKHR>surfaceFormats = getPhysicalDeviceSurfaceFormats(vki,
2082 const VkSurfaceFormatKHR* surfaceFormat = DE_NULL;
2083 const VkFormat* viewFormat = DE_NULL;
2085 for (vector<VkSurfaceFormatKHR>::size_type i = 0; i < surfaceFormats.size(); i++)
2087 if (surfaceFormats[i].format == caseDef.imageFormat)
2088 surfaceFormat = &surfaceFormats[i];
2090 if (surfaceFormats[i].format == caseDef.viewFormat)
2091 viewFormat = &surfaceFormats[i].format;
2094 if (surfaceFormat == DE_NULL)
2095 TCU_THROW(NotSupportedError, "Image format is not supported by swapchain.");
2097 if (viewFormat == DE_NULL)
2098 TCU_THROW(NotSupportedError, "Image view format is not supported by swapchain.");
2100 if ((capabilities.supportedUsageFlags & imageUsage) != imageUsage)
2101 TCU_THROW(NotSupportedError, "Image usage request not supported by swapchain.");
2103 const Unique<VkSwapchainKHR> swapchain(
2117 const vector<VkImage> swapchainImages = getSwapchainImages(vk, device, *swapchain);
2119 // Create a color buffer for host-inspection of results
2120 // For the Copy download method, this is the target of the download, for other
2121 // download methods, pixel data will be copied to this buffer from the download
2123 const VkDeviceSize colorBufferSize = caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat));
2124 const Unique<VkBuffer> colorBuffer(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2125 const UniquePtr<Allocation> colorBufferAlloc(bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
2126 deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
2127 flushAlloc(vk, device, *colorBufferAlloc);
2131 UploadDownloadExecutor executor(context, device, devHelper.queue, devHelper.queueFamilyIndex, caseDef);
2133 executor.runSwapchain(context, *colorBuffer, swapchainImages[0]);
2137 invalidateAlloc(vk, device, *colorBufferAlloc);
2139 // For verification purposes, we use the format of the upload to generate the expected image
2140 const VkFormat format = caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat;
2141 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
2142 const bool isIntegerFormat = isUintFormat(format) || isIntFormat(format);
2143 const tcu::ConstPixelBufferAccess resultImage(tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr());
2144 tcu::TextureLevel textureLevel(tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers);
2145 const tcu::PixelBufferAccess expectedImage = textureLevel.getAccess();
2146 generateExpectedImage(expectedImage, caseDef);
2149 if (isIntegerFormat)
2150 ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
2152 ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
2153 return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
2157 tcu::TestCaseGroup* createSwapchainImageMutableTests(TestContext& testCtx)
2159 de::MovePtr<TestCaseGroup> testGroup(new TestCaseGroup(testCtx, "swapchain_mutable", "Cases with swapchain mutable images"));
2161 for (int typeNdx = 0; typeNdx < vk::wsi::TYPE_LAST; ++typeNdx)
2163 const vk::wsi::Type wsiType = (vk::wsi::Type)typeNdx;
2165 de::MovePtr<TestCaseGroup> testGroupWsi(new TestCaseGroup(testCtx, getName(wsiType), ""));
2167 for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx)
2169 const Texture& texture = s_textures[textureNdx];
2170 de::MovePtr<tcu::TestCaseGroup> groupByImageViewType(new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), ""));
2172 for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_swapchainFormats); ++imageFormatNdx)
2173 for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_swapchainFormats); ++viewFormatNdx)
2175 if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_swapchainFormats[imageFormatNdx], s_swapchainFormats[viewFormatNdx]))
2177 for (int upload = 0; upload < UPLOAD_LAST; upload++)
2179 if (upload == UPLOAD_STORE && !isFormatImageLoadStoreCapable(s_swapchainFormats[viewFormatNdx]))
2182 for (int download = 0; download < DOWNLOAD_LAST; download++)
2184 if ((download == DOWNLOAD_LOAD || download == DOWNLOAD_TEXTURE) &&
2185 !isFormatImageLoadStoreCapable(s_swapchainFormats[viewFormatNdx]))
2191 texture.layerSize(),
2192 static_cast<deUint32>(texture.numLayers()),
2193 s_swapchainFormats[imageFormatNdx],
2194 s_swapchainFormats[viewFormatNdx],
2195 static_cast<enum Upload>(upload),
2196 static_cast<enum Download>(download),
2197 true, // isFormatListTest;
2198 true, // isSwapchainImageTest
2202 std::string caseName = getFormatShortString(s_swapchainFormats[imageFormatNdx]) + "_" + getFormatShortString(s_swapchainFormats[viewFormatNdx]) +
2203 "_" + getUploadString(upload) + "_" + getDownloadString(download) + "_format_list";
2205 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", checkSupport, initPrograms, testSwapchainMutable, caseDef);
2211 testGroupWsi->addChild(groupByImageViewType.release());
2214 testGroup->addChild(testGroupWsi.release());
2216 return testGroup.release();