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(112, 60, 101, 41),
136 IVec4( 60, 101, 41, 112),
137 IVec4( 41, 112, 60, 101),
138 IVec4(101, 41, 112, 60),
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 VkClearValue REFERENCE_CLEAR_COLOR_INT[COLOR_TABLE_SIZE] =
152 makeClearValueColorI32(COLOR_TABLE_INT[0].x(), COLOR_TABLE_INT[0].y(), COLOR_TABLE_INT[0].z(), COLOR_TABLE_INT[0].w()),
153 makeClearValueColorI32(COLOR_TABLE_INT[1].x(), COLOR_TABLE_INT[1].y(), COLOR_TABLE_INT[1].z(), COLOR_TABLE_INT[1].w()),
154 makeClearValueColorI32(COLOR_TABLE_INT[2].x(), COLOR_TABLE_INT[2].y(), COLOR_TABLE_INT[2].z(), COLOR_TABLE_INT[2].w()),
155 makeClearValueColorI32(COLOR_TABLE_INT[3].x(), COLOR_TABLE_INT[3].y(), COLOR_TABLE_INT[3].z(), COLOR_TABLE_INT[3].w()),
158 static const Texture s_textures[] =
160 Texture(IMAGE_TYPE_2D, tcu::IVec3(32, 32, 1), 1),
161 Texture(IMAGE_TYPE_2D_ARRAY, tcu::IVec3(32, 32, 1), 4),
164 VkImageType getImageType (const ImageType textureImageType)
166 switch (textureImageType)
169 case IMAGE_TYPE_2D_ARRAY:
170 return VK_IMAGE_TYPE_2D;
174 return VK_IMAGE_TYPE_LAST;
178 VkImageViewType getImageViewType (const ImageType textureImageType)
180 switch (textureImageType)
183 return VK_IMAGE_VIEW_TYPE_2D;
184 case IMAGE_TYPE_2D_ARRAY:
185 return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
189 return VK_IMAGE_VIEW_TYPE_LAST;
193 static const VkFormat s_formats[] =
195 VK_FORMAT_R32G32B32A32_SFLOAT,
196 VK_FORMAT_R16G16B16A16_SFLOAT,
197 VK_FORMAT_R32G32_SFLOAT,
198 VK_FORMAT_R16G16_SFLOAT,
199 VK_FORMAT_R32_SFLOAT,
201 VK_FORMAT_R32G32B32A32_UINT,
202 VK_FORMAT_R16G16B16A16_UINT,
203 VK_FORMAT_R8G8B8A8_UINT,
204 VK_FORMAT_R32G32_UINT,
205 VK_FORMAT_R16G16_UINT,
208 VK_FORMAT_R32G32B32A32_SINT,
209 VK_FORMAT_R16G16B16A16_SINT,
210 VK_FORMAT_R8G8B8A8_SINT,
211 VK_FORMAT_R32G32_SINT,
212 VK_FORMAT_R16G16_SINT,
215 VK_FORMAT_R8G8B8A8_UNORM,
216 VK_FORMAT_R8G8B8A8_SNORM,
217 VK_FORMAT_R8G8B8A8_SRGB,
218 VK_FORMAT_B8G8R8A8_UNORM,
219 VK_FORMAT_B8G8R8A8_SNORM,
220 VK_FORMAT_B8G8R8A8_SRGB,
223 static const VkFormat s_swapchainFormats[] =
225 VK_FORMAT_R8G8B8A8_UNORM,
226 VK_FORMAT_R8G8B8A8_SNORM,
227 VK_FORMAT_R8G8B8A8_SRGB,
228 VK_FORMAT_B8G8R8A8_UNORM,
229 VK_FORMAT_B8G8R8A8_SNORM,
230 VK_FORMAT_B8G8R8A8_SRGB,
233 bool isSRGBConversionRequired(const CaseDef& caseDef)
235 bool required = false;
237 if (isSRGB(mapVkFormat(caseDef.imageFormat)))
239 if (caseDef.upload == UPLOAD_CLEAR)
245 if (isSRGB(mapVkFormat(caseDef.viewFormat)))
247 if (caseDef.upload == UPLOAD_DRAW)
252 // Following modes require VK_IMAGE_USAGE_STORAGE_BIT usage, not supported by srgb format
253 DE_ASSERT(caseDef.upload != UPLOAD_STORE);
254 DE_ASSERT(caseDef.download != DOWNLOAD_LOAD);
255 DE_ASSERT(caseDef.download != DOWNLOAD_TEXTURE);
262 inline bool formatsAreCompatible (const VkFormat format0, const VkFormat format1)
264 return format0 == format1 || mapVkFormat(format0).getPixelSize() == mapVkFormat(format1).getPixelSize();
267 std::string getColorFormatStr (const int numComponents, const bool isUint, const bool isSint)
269 std::ostringstream str;
270 if (numComponents == 1)
271 str << (isUint ? "uint" : isSint ? "int" : "float");
273 str << (isUint ? "u" : isSint ? "i" : "") << "vec" << numComponents;
278 std::string getShaderSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
280 std::ostringstream samplerType;
282 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
284 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
289 case VK_IMAGE_VIEW_TYPE_2D:
290 samplerType << "sampler2D";
293 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
294 samplerType << "sampler2DArray";
298 DE_FATAL("Ivalid image view type");
302 return samplerType.str();
305 void initPrograms (SourceCollections& programCollection, const CaseDef caseDef)
307 if (caseDef.upload == UPLOAD_DRAW)
310 std::ostringstream src;
311 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
313 << "layout(location = 0) in vec4 in_position;\n"
314 << "layout(location = 1) in vec4 in_color;\n"
315 << "layout(location = 0) out vec4 out_color;\n"
317 << "out gl_PerVertex {\n"
318 << " vec4 gl_Position;\n"
321 << "void main(void)\n"
323 << " gl_Position = in_position;\n"
324 << " out_color = in_color;\n"
327 programCollection.glslSources.add("uploadDrawVert") << glu::VertexSource(src.str());
331 const int numComponents = getNumUsedChannels(mapVkFormat(caseDef.viewFormat).order);
332 const bool isUint = isUintFormat(caseDef.viewFormat);
333 const bool isSint = isIntFormat(caseDef.viewFormat);
334 const std::string colorFormat = getColorFormatStr(numComponents, isUint, isSint);
336 std::ostringstream src;
337 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
339 << "layout(location = 0) in vec4 in_color;\n"
340 << "layout(location = 0) out " << colorFormat << " out_color;\n"
342 << "void main(void)\n"
344 << " out_color = " << colorFormat << "("
345 << (numComponents == 1 ? "in_color.r" :
346 numComponents == 2 ? "in_color.rg" :
347 numComponents == 3 ? "in_color.rgb" : "in_color")
351 programCollection.glslSources.add("uploadDrawFrag") << glu::FragmentSource(src.str());
355 if (caseDef.upload == UPLOAD_STORE)
357 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
358 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
359 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
360 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
361 const bool isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);
363 std::ostringstream src;
364 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
366 << "layout (local_size_x = 1) in;\n"
368 << "layout(binding=0, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " u_image;\n"
370 << "const " << colorTypeStr << " colorTable[] = " << colorTypeStr << "[](\n";
371 for (deUint32 idx = 0; idx < COLOR_TABLE_SIZE; idx++)
374 src << " " << colorTypeStr << "(" << COLOR_TABLE_INT[idx].x() << ", " << COLOR_TABLE_INT[idx].y() << ", " << COLOR_TABLE_INT[idx].z() << ", " << COLOR_TABLE_INT[idx].w() << ")";
376 src << " " << colorTypeStr << "(" << COLOR_TABLE_FLOAT[idx].x() << ", " << COLOR_TABLE_FLOAT[idx].y() << ", " << COLOR_TABLE_FLOAT[idx].z() << ", " << COLOR_TABLE_FLOAT[idx].w() << ")";
377 if (idx < COLOR_TABLE_SIZE - 1)
383 << "void main(void)\n"
385 if (caseDef.imageType == IMAGE_TYPE_2D)
387 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
391 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
392 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
394 src << " " << colorTypeStr << " color = colorTable[gl_GlobalInvocationID.z];\n"
395 << " imageStore(u_image, pos, color);\n"
398 programCollection.glslSources.add("uploadStoreComp") << glu::ComputeSource(src.str());
401 if (caseDef.download == DOWNLOAD_LOAD)
403 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
404 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
405 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
406 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
408 std::ostringstream src;
409 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
411 << "layout (local_size_x = 1) in;\n"
413 << "layout(binding=0, " << imageFormatStr << ") readonly uniform " << imageTypeStr << " in_image;\n"
414 << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
416 << "void main(void)\n"
418 if (caseDef.imageType == IMAGE_TYPE_2D)
420 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
424 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
425 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
427 src << " imageStore(out_image, pos, imageLoad(in_image, pos));\n"
430 programCollection.glslSources.add("downloadLoadComp") << glu::ComputeSource(src.str());
433 if (caseDef.download == DOWNLOAD_TEXTURE)
435 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
436 const VkImageViewType viewType = getImageViewType(caseDef.imageType);
437 const std::string samplerTypeStr = getShaderSamplerType(tcuFormat, viewType);
438 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
439 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
440 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
442 std::ostringstream src;
443 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
445 << "layout (local_size_x = 1) in;\n"
447 << "layout(binding=0) uniform " << samplerTypeStr << " u_tex;\n"
448 << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
450 << "void main(void)\n"
452 if (caseDef.imageType == IMAGE_TYPE_2D)
454 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
458 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
459 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
461 src << " imageStore(out_image, pos, texelFetch(u_tex, pos, 0));\n"
464 programCollection.glslSources.add("downloadTextureComp") << glu::ComputeSource(src.str());
468 Move<VkImage> makeImage (const DeviceInterface& vk,
469 const VkDevice device,
470 VkImageCreateFlags flags,
471 VkImageType imageType,
472 const VkFormat format,
473 const VkFormat viewFormat,
474 const bool useImageFormatList,
476 const deUint32 numMipLevels,
477 const deUint32 numLayers,
478 const VkImageUsageFlags usage)
480 const VkFormat formatList[2] =
486 const VkImageFormatListCreateInfoKHR formatListInfo =
488 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR, // VkStructureType sType;
489 DE_NULL, // const void* pNext;
490 2u, // deUint32 viewFormatCount
491 formatList // const VkFormat* pViewFormats
494 const VkImageCreateInfo imageParams =
496 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
497 useImageFormatList ? &formatListInfo : DE_NULL, // const void* pNext;
498 flags, // VkImageCreateFlags flags;
499 imageType, // VkImageType imageType;
500 format, // VkFormat format;
501 makeExtent3D(size), // VkExtent3D extent;
502 numMipLevels, // deUint32 mipLevels;
503 numLayers, // deUint32 arrayLayers;
504 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
505 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
506 usage, // VkImageUsageFlags usage;
507 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
508 0u, // deUint32 queueFamilyIndexCount;
509 DE_NULL, // const deUint32* pQueueFamilyIndices;
510 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
512 return createImage(vk, device, &imageParams);
515 inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize bufferSize, const VkBufferUsageFlags usage)
517 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSize, usage);
518 return createBuffer(vk, device, &bufferCreateInfo);
521 inline VkImageSubresourceRange makeColorSubresourceRange (const int baseArrayLayer, const int layerCount)
523 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, static_cast<deUint32>(baseArrayLayer), static_cast<deUint32>(layerCount));
526 Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice device)
528 const VkSamplerCreateInfo samplerParams =
530 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
531 DE_NULL, // const void* pNext;
532 (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags;
533 VK_FILTER_NEAREST, // VkFilter magFilter;
534 VK_FILTER_NEAREST, // VkFilter minFilter;
535 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
536 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
537 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
538 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
539 0.0f, // float mipLodBias;
540 VK_FALSE, // VkBool32 anisotropyEnable;
541 1.0f, // float maxAnisotropy;
542 VK_FALSE, // VkBool32 compareEnable;
543 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
544 0.0f, // float minLod;
545 0.0f, // float maxLod;
546 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
547 VK_FALSE, // VkBool32 unnormalizedCoordinates;
550 return createSampler(vk, device, &samplerParams);
554 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk,
555 const VkDevice device)
557 const VkPipelineLayoutCreateInfo info =
559 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
561 (VkPipelineLayoutCreateFlags)0,
567 return createPipelineLayout(vk, device, &info);
570 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
571 const VkDevice device,
572 const VkPipelineLayout pipelineLayout,
573 const VkRenderPass renderPass,
574 const VkShaderModule vertexModule,
575 const VkShaderModule fragmentModule,
576 const IVec2& renderSize,
577 const VkPrimitiveTopology topology,
578 const deUint32 subpass)
580 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
581 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
583 const VkVertexInputBindingDescription vertexInputBindingDescription =
585 0u, // deUint32 binding;
586 (deUint32)(2 * sizeof(Vec4)), // deUint32 stride;
587 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
590 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
593 0u, // deUint32 location;
594 0u, // deUint32 binding;
595 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
596 0u, // deUint32 offset;
599 1u, // deUint32 location;
600 0u, // deUint32 binding;
601 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
602 (deUint32)sizeof(Vec4), // deUint32 offset;
606 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
608 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
609 DE_NULL, // const void* pNext;
610 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
611 1u, // deUint32 vertexBindingDescriptionCount;
612 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
613 2u, // deUint32 vertexAttributeDescriptionCount;
614 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
617 return vk::makeGraphicsPipeline(vk, // const DeviceInterface& vk
618 device, // const VkDevice device
619 pipelineLayout, // const VkPipelineLayout pipelineLayout
620 vertexModule, // const VkShaderModule vertexShaderModule
621 DE_NULL, // const VkShaderModule tessellationControlModule
622 DE_NULL, // const VkShaderModule tessellationEvalModule
623 DE_NULL, // const VkShaderModule geometryShaderModule
624 fragmentModule, // const VkShaderModule fragmentShaderModule
625 renderPass, // const VkRenderPass renderPass
626 viewports, // const std::vector<VkViewport>& viewports
627 scissors, // const std::vector<VkRect2D>& scissors
628 topology, // const VkPrimitiveTopology topology
629 subpass, // const deUint32 subpass
630 0u, // const deUint32 patchControlPoints
631 &vertexInputStateCreateInfo); // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
634 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
635 const VkDevice device,
636 const VkPipelineLayout pipelineLayout,
637 const VkShaderModule shaderModule,
638 const VkSpecializationInfo* specInfo)
640 const VkPipelineShaderStageCreateInfo shaderStageInfo =
642 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
643 DE_NULL, // const void* pNext;
644 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
645 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
646 shaderModule, // VkShaderModule module;
647 "main", // const char* pName;
648 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
650 const VkComputePipelineCreateInfo pipelineInfo =
652 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
653 DE_NULL, // const void* pNext;
654 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
655 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage;
656 pipelineLayout, // VkPipelineLayout layout;
657 DE_NULL, // VkPipeline basePipelineHandle;
658 0, // deInt32 basePipelineIndex;
660 return createComputePipeline(vk, device, DE_NULL , &pipelineInfo);
663 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
664 const VkDevice device,
665 const VkFormat colorFormat,
666 const deUint32 numLayers)
668 const VkAttachmentDescription colorAttachmentDescription =
670 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
671 colorFormat, // VkFormat format;
672 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
673 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
674 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
675 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
676 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
677 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
678 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
680 vector<VkAttachmentDescription> attachmentDescriptions(numLayers, colorAttachmentDescription);
682 // Create a subpass for each attachment (each attachement is a layer of an arrayed image).
683 vector<VkAttachmentReference> colorAttachmentReferences (numLayers);
684 vector<VkSubpassDescription> subpasses;
686 // Ordering here must match the framebuffer attachments
687 for (deUint32 i = 0; i < numLayers; ++i)
689 const VkAttachmentReference attachmentRef =
691 i, // deUint32 attachment;
692 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
695 colorAttachmentReferences[i] = attachmentRef;
697 const VkSubpassDescription subpassDescription =
699 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
700 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
701 0u, // deUint32 inputAttachmentCount;
702 DE_NULL, // const VkAttachmentReference* pInputAttachments;
703 1u, // deUint32 colorAttachmentCount;
704 &colorAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments;
705 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
706 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
707 0u, // deUint32 preserveAttachmentCount;
708 DE_NULL // const deUint32* pPreserveAttachments;
710 subpasses.push_back(subpassDescription);
713 const VkRenderPassCreateInfo renderPassInfo =
715 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
716 DE_NULL, // const void* pNext;
717 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
718 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
719 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
720 static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount;
721 &subpasses[0], // const VkSubpassDescription* pSubpasses;
722 0u, // deUint32 dependencyCount;
723 DE_NULL // const VkSubpassDependency* pDependencies;
726 return createRenderPass(vk, device, &renderPassInfo);
729 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk,
730 const VkDevice device,
731 const VkRenderPass renderPass,
732 const deUint32 attachmentCount,
733 const VkImageView* pAttachments,
736 const VkFramebufferCreateInfo framebufferInfo =
738 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
740 (VkFramebufferCreateFlags)0,
744 static_cast<deUint32>(size.x()),
745 static_cast<deUint32>(size.y()),
749 return createFramebuffer(vk, device, &framebufferInfo);
752 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
754 return allocateCommandBuffer(vk, device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
757 MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
759 MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
760 VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
764 MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
766 MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
767 VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
771 vector<Vec4> genVertexData (const CaseDef& caseDef)
773 vector<Vec4> vectorData;
774 const bool isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);
776 for (deUint32 z = 0; z < caseDef.numLayers; z++)
778 const deUint32 colorIdx = z % COLOR_TABLE_SIZE;
779 const Vec4 color = isIntegerFormat ? COLOR_TABLE_INT[colorIdx].cast<float>() : COLOR_TABLE_FLOAT[colorIdx];
781 vectorData.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
782 vectorData.push_back(color);
783 vectorData.push_back(Vec4(-1.0f, 1.0f, 0.0f, 1.0f));
784 vectorData.push_back(color);
785 vectorData.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
786 vectorData.push_back(color);
787 vectorData.push_back(Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
788 vectorData.push_back(color);
794 void generateExpectedImage(const tcu::PixelBufferAccess& image, const CaseDef& caseDef)
796 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(image.getFormat().type);
797 const bool isIntegerFormat = channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
798 const IVec2 size = caseDef.size.swizzle(0, 1);
800 for (int z = 0; z < static_cast<int>(caseDef.numLayers); z++)
802 const deUint32 colorIdx = z % COLOR_TABLE_SIZE;
803 for (int y = 0; y < size.y(); y++)
804 for (int x = 0; x < size.x(); x++)
807 image.setPixel(COLOR_TABLE_INT[colorIdx], x, y, z);
809 if(isSRGBConversionRequired(caseDef))
810 image.setPixel(tcu::linearToSRGB(COLOR_TABLE_FLOAT[colorIdx]), x, y, z);
812 image.setPixel(COLOR_TABLE_FLOAT[colorIdx], x, y, z);
817 VkImageUsageFlags getImageUsageForTestCase (const CaseDef& caseDef)
819 VkImageUsageFlags flags = 0u;
821 switch (caseDef.upload)
824 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
827 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
830 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
833 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
836 DE_FATAL("Invalid upload method");
840 switch (caseDef.download)
842 case DOWNLOAD_TEXTURE:
843 flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
846 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
849 flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
852 DE_FATAL("Invalid download method");
856 // We can only create a view for the image if it is going to be used for any of these usages,
857 // so let's make sure that we have at least one of them.
858 VkImageUsageFlags viewRequiredFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
859 if (!(flags & viewRequiredFlags))
860 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
865 // Executes a combination of upload/download methods
866 class UploadDownloadExecutor
869 UploadDownloadExecutor(Context& context, const CaseDef& caseSpec) :
871 m_haveMaintenance2(isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance2")),
872 m_vk(context.getDeviceInterface()),
873 m_device(context.getDevice()),
874 m_queue(context.getUniversalQueue()),
875 m_queueFamilyIndex(context.getUniversalQueueFamilyIndex()),
876 m_allocator(context.getDefaultAllocator())
880 void runSwapchain(Context& context, VkBuffer buffer, VkImage image);
882 void run(Context& context, VkBuffer buffer);
885 void uploadClear(Context& context);
886 void uploadStore(Context& context);
887 void uploadCopy(Context& context);
888 void uploadDraw(Context& context);
889 void downloadCopy(Context& context, VkBuffer buffer);
890 void downloadTexture(Context& context, VkBuffer buffer);
891 void downloadLoad(Context& context, VkBuffer buffer);
893 void copyImageToBuffer(VkImage image,
896 const VkAccessFlags srcAccessMask,
897 const VkImageLayout oldLayout,
898 const deUint32 numLayers);
900 const CaseDef& m_caseDef;
902 bool m_haveMaintenance2;
904 const DeviceInterface& m_vk;
905 const VkDevice m_device;
906 const VkQueue m_queue;
907 const deUint32 m_queueFamilyIndex;
908 Allocator& m_allocator;
910 Move<VkCommandPool> m_cmdPool;
911 Move<VkCommandBuffer> m_cmdBuffer;
913 bool m_imageIsIntegerFormat;
914 bool m_viewIsIntegerFormat;
916 // Target image for upload paths
918 Move<VkImage> m_imageHolder;
919 MovePtr<Allocation> m_imageAlloc;
924 Move<VkBuffer> colorBuffer;
925 VkDeviceSize colorBufferSize;
926 MovePtr<Allocation> colorBufferAlloc;
932 Move<VkBuffer> vertexBuffer;
933 MovePtr<Allocation> vertexBufferAlloc;
934 Move<VkPipelineLayout> pipelineLayout;
935 Move<VkRenderPass> renderPass;
936 Move<VkShaderModule> vertexModule;
937 Move<VkShaderModule> fragmentModule;
938 vector<SharedPtrVkImageView> attachments;
939 vector<VkImageView> attachmentHandles;
940 vector<SharedPtrVkPipeline> pipelines;
941 Move<VkFramebuffer> framebuffer;
947 Move<VkDescriptorPool> descriptorPool;
948 Move<VkPipelineLayout> pipelineLayout;
949 Move<VkDescriptorSetLayout> descriptorSetLayout;
950 Move<VkDescriptorSet> descriptorSet;
951 VkDescriptorImageInfo imageDescriptorInfo;
952 Move<VkShaderModule> computeModule;
953 Move<VkPipeline> computePipeline;
954 Move<VkImageView> imageView;
960 Move<VkDescriptorPool> descriptorPool;
961 Move<VkPipelineLayout> pipelineLayout;
962 Move<VkDescriptorSetLayout> descriptorSetLayout;
963 Move<VkDescriptorSet> descriptorSet;
964 Move<VkShaderModule> computeModule;
965 Move<VkPipeline> computePipeline;
966 Move<VkImageView> inImageView;
967 VkDescriptorImageInfo inImageDescriptorInfo;
968 Move<VkImage> outImage;
969 Move<VkImageView> outImageView;
970 MovePtr<Allocation> outImageAlloc;
971 VkDescriptorImageInfo outImageDescriptorInfo;
977 Move<VkDescriptorPool> descriptorPool;
978 Move<VkPipelineLayout> pipelineLayout;
979 Move<VkDescriptorSetLayout> descriptorSetLayout;
980 Move<VkDescriptorSet> descriptorSet;
981 Move<VkShaderModule> computeModule;
982 Move<VkPipeline> computePipeline;
983 Move<VkImageView> inImageView;
984 VkDescriptorImageInfo inImageDescriptorInfo;
985 Move<VkSampler> sampler;
986 Move<VkImage> outImage;
987 Move<VkImageView> outImageView;
988 MovePtr<Allocation> outImageAlloc;
989 VkDescriptorImageInfo outImageDescriptorInfo;
992 VkImageLayout m_imageLayoutAfterUpload;
993 VkAccessFlagBits m_imageUploadAccessMask;
997 void UploadDownloadExecutor::runSwapchain(Context& context, VkBuffer buffer, VkImage image)
999 m_imageIsIntegerFormat = isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat);
1000 m_viewIsIntegerFormat = isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat);
1002 m_cmdPool = createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex);
1003 m_cmdBuffer = makeCommandBuffer(m_vk, m_device, *m_cmdPool);
1004 beginCommandBuffer(m_vk, *m_cmdBuffer);
1008 switch (m_caseDef.upload)
1011 uploadDraw(context);
1014 uploadStore(context);
1017 uploadClear(context);
1020 uploadCopy(context);
1023 DE_FATAL("Unsupported upload method");
1026 switch (m_caseDef.download)
1029 downloadCopy(context, buffer);
1032 downloadLoad(context, buffer);
1034 case DOWNLOAD_TEXTURE:
1035 downloadTexture(context, buffer);
1038 DE_FATAL("Unsupported download method");
1041 endCommandBuffer(m_vk, *m_cmdBuffer);
1042 submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer);
1046 void UploadDownloadExecutor::run(Context& context, VkBuffer buffer)
1048 m_imageIsIntegerFormat = isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat);
1049 m_viewIsIntegerFormat = isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat);
1051 m_cmdPool = createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex);
1052 m_cmdBuffer = makeCommandBuffer(m_vk, m_device, *m_cmdPool);
1053 beginCommandBuffer(m_vk, *m_cmdBuffer);
1055 const VkImageUsageFlags imageUsage = getImageUsageForTestCase(m_caseDef);
1056 const VkImageCreateFlags imageFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | (m_haveMaintenance2 ? VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR : 0);
1058 m_imageHolder = makeImage(m_vk, m_device, imageFlags, getImageType(m_caseDef.imageType), m_caseDef.imageFormat, m_caseDef.viewFormat,
1059 m_caseDef.isFormatListTest, m_caseDef.size, 1u, m_caseDef.numLayers, imageUsage);
1060 m_image = *m_imageHolder;
1061 m_imageAlloc = bindImage(m_vk, m_device, m_allocator, m_image, MemoryRequirement::Any);
1063 switch (m_caseDef.upload)
1066 uploadDraw(context);
1069 uploadStore(context);
1072 uploadClear(context);
1075 uploadCopy(context);
1078 DE_FATAL("Unsupported upload method");
1081 switch (m_caseDef.download)
1084 downloadCopy(context, buffer);
1087 downloadLoad(context, buffer);
1089 case DOWNLOAD_TEXTURE:
1090 downloadTexture(context, buffer);
1093 DE_FATAL("Unsupported download method");
1096 endCommandBuffer(m_vk, *m_cmdBuffer);
1097 submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer);
1100 void UploadDownloadExecutor::uploadClear(Context& context)
1104 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1106 const VkImageSubresourceRange subresourceRange = makeColorSubresourceRange(0, m_caseDef.numLayers);
1107 const VkImageMemoryBarrier imageInitBarrier =
1109 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1110 DE_NULL, // const void* pNext;
1111 0u, // VkAccessFlags srcAccessMask;
1112 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAcessMask;
1113 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1114 requiredImageLayout, // VkImageLayout newLayout;
1115 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1116 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1117 m_image, // VkImage image;
1118 subresourceRange // VkImageSubresourceRange subresourceRange;
1121 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1122 0u, DE_NULL, 0u, DE_NULL, 1u, &imageInitBarrier);
1124 for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
1126 const VkImageSubresourceRange layerSubresourceRange = makeColorSubresourceRange(layer, 1u);
1127 const deUint32 colorIdx = layer % COLOR_TABLE_SIZE;
1128 const VkClearColorValue clearColor = m_imageIsIntegerFormat ? REFERENCE_CLEAR_COLOR_INT[colorIdx].color : REFERENCE_CLEAR_COLOR_FLOAT[colorIdx].color;
1129 m_vk.cmdClearColorImage(*m_cmdBuffer, m_image, requiredImageLayout, &clearColor, 1u, &layerSubresourceRange);
1132 m_imageLayoutAfterUpload = requiredImageLayout;
1133 m_imageUploadAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1136 void UploadDownloadExecutor::uploadStore(Context& context)
1138 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1140 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1141 DE_NULL, // const void* pNext
1142 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage;
1144 m_uStore.imageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1145 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1147 // Setup compute pipeline
1148 m_uStore.descriptorPool = DescriptorPoolBuilder()
1149 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1150 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1152 m_uStore.descriptorSetLayout = DescriptorSetLayoutBuilder()
1153 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1154 .build(m_vk, m_device);
1156 m_uStore.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_uStore.descriptorSetLayout);
1157 m_uStore.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_uStore.descriptorPool, *m_uStore.descriptorSetLayout);
1158 m_uStore.imageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_uStore.imageView, VK_IMAGE_LAYOUT_GENERAL);
1159 m_uStore.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadStoreComp"), 0);
1160 m_uStore.computePipeline = makeComputePipeline(m_vk, m_device, *m_uStore.pipelineLayout, *m_uStore.computeModule, DE_NULL);
1162 DescriptorSetUpdateBuilder()
1163 .writeSingle(*m_uStore.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_uStore.imageDescriptorInfo)
1164 .update(m_vk, m_device);
1166 // Transition storage image for shader access (imageStore)
1167 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1168 const VkImageMemoryBarrier imageBarrier =
1170 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1171 DE_NULL, // const void* pNext;
1172 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1173 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1174 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1175 requiredImageLayout, // VkImageLayout newLayout;
1176 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1177 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1178 m_image, // VkImage image;
1179 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1182 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1183 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
1186 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.computePipeline);
1187 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.pipelineLayout, 0u, 1u, &m_uStore.descriptorSet.get(), 0u, DE_NULL);
1188 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1190 m_imageLayoutAfterUpload = requiredImageLayout;
1191 m_imageUploadAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
1194 void UploadDownloadExecutor::uploadCopy(Context& context)
1198 // Create a host-mappable buffer with the color data to upload
1199 const VkDeviceSize pixelSize = tcu::getPixelSize(mapVkFormat(m_caseDef.imageFormat));
1200 const VkDeviceSize layerSize = m_caseDef.size.x() * m_caseDef.size.y() * m_caseDef.size.z() * pixelSize;
1202 m_uCopy.colorBufferSize = layerSize * m_caseDef.numLayers;
1203 m_uCopy.colorBuffer = makeBuffer(m_vk, m_device, m_uCopy.colorBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
1204 m_uCopy.colorBufferAlloc = bindBuffer(m_vk, m_device, m_allocator, *m_uCopy.colorBuffer, MemoryRequirement::HostVisible);
1206 // Fill color buffer
1207 const tcu::TextureFormat tcuFormat = mapVkFormat(m_caseDef.imageFormat);
1208 VkDeviceSize layerOffset = 0ull;
1209 for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
1211 tcu::PixelBufferAccess imageAccess = tcu::PixelBufferAccess(tcuFormat, m_caseDef.size.x(), m_caseDef.size.y(), 1u, (deUint8*) m_uCopy.colorBufferAlloc->getHostPtr() + layerOffset);
1212 const deUint32 colorIdx = layer % COLOR_TABLE_SIZE;
1213 if (m_imageIsIntegerFormat)
1214 tcu::clear(imageAccess, COLOR_TABLE_INT[colorIdx]);
1216 tcu::clear(imageAccess, COLOR_TABLE_FLOAT[colorIdx]);
1217 layerOffset += layerSize;
1220 flushAlloc(m_vk, m_device, *(m_uCopy.colorBufferAlloc));
1222 // Prepare buffer and image for copy
1223 const VkBufferMemoryBarrier bufferInitBarrier =
1225 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1226 DE_NULL, // const void* pNext;
1227 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
1228 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1229 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1230 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1231 *m_uCopy.colorBuffer, // VkBuffer buffer;
1232 0ull, // VkDeviceSize offset;
1233 VK_WHOLE_SIZE, // VkDeviceSize size;
1236 const VkImageMemoryBarrier imageInitBarrier =
1238 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1239 DE_NULL, // const void* pNext;
1240 0u, // VkAccessFlags srcAccessMask;
1241 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1242 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1243 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1244 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1245 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1246 m_image, // VkImage image;
1247 makeColorSubresourceRange(0, m_caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
1250 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1251 0u, DE_NULL, 1u, &bufferInitBarrier, 1u, &imageInitBarrier);
1253 // Copy buffer to image
1254 const VkImageSubresourceLayers subresource =
1256 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1257 0u, // deUint32 mipLevel;
1258 0u, // deUint32 baseArrayLayer;
1259 m_caseDef.numLayers, // deUint32 layerCount;
1262 const VkBufferImageCopy region =
1264 0ull, // VkDeviceSize bufferOffset;
1265 0u, // deUint32 bufferRowLength;
1266 0u, // deUint32 bufferImageHeight;
1267 subresource, // VkImageSubresourceLayers imageSubresource;
1268 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
1269 makeExtent3D(m_caseDef.size), // VkExtent3D imageExtent;
1272 m_vk.cmdCopyBufferToImage(*m_cmdBuffer, *m_uCopy.colorBuffer, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ®ion);
1274 const VkImageMemoryBarrier imagePostInitBarrier =
1276 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1277 DE_NULL, // const void* pNext;
1278 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1279 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1280 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1281 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1282 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1283 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1284 m_image, // VkImage image;
1285 makeColorSubresourceRange(0, m_caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
1288 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1289 0u, DE_NULL, 0u, DE_NULL, 1u, &imagePostInitBarrier);
1291 m_imageLayoutAfterUpload = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1292 m_imageUploadAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1295 void UploadDownloadExecutor::uploadDraw(Context& context)
1297 // Create vertex buffer
1299 const vector<Vec4> vertices = genVertexData(m_caseDef);
1300 const VkDeviceSize vertexBufferSize = vertices.size() * sizeof(Vec4);
1302 m_uDraw.vertexBuffer = makeBuffer(m_vk, m_device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
1303 m_uDraw.vertexBufferAlloc = bindBuffer(m_vk, m_device, m_allocator, *m_uDraw.vertexBuffer, MemoryRequirement::HostVisible);
1304 deMemcpy(m_uDraw.vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
1305 flushAlloc(m_vk, m_device, *(m_uDraw.vertexBufferAlloc));
1308 // Create attachments and pipelines for each image layer
1309 m_uDraw.pipelineLayout = makePipelineLayout(m_vk, m_device);
1310 m_uDraw.renderPass = makeRenderPass(m_vk, m_device, m_caseDef.viewFormat, m_caseDef.numLayers);
1311 m_uDraw.vertexModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawVert"), 0u);
1312 m_uDraw.fragmentModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawFrag"), 0u);
1314 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
1316 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1318 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1319 DE_NULL, // const void* pNext
1320 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags usage;
1322 Move<VkImageView> imageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1323 makeColorSubresourceRange(subpassNdx, 1), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1324 m_uDraw.attachmentHandles.push_back(*imageView);
1325 m_uDraw.attachments.push_back(makeSharedPtr(imageView));
1326 m_uDraw.pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(m_vk, m_device, *m_uDraw.pipelineLayout, *m_uDraw.renderPass, *m_uDraw.vertexModule, *m_uDraw.fragmentModule,
1327 m_caseDef.size.swizzle(0, 1), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, subpassNdx)));
1330 // Create framebuffer
1331 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));
1333 // Create command buffer
1336 vector<VkClearValue> clearValues (m_caseDef.numLayers, m_viewIsIntegerFormat ? REFERENCE_CLEAR_COLOR_INT[0] : REFERENCE_CLEAR_COLOR_FLOAT[0]);
1338 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]);
1342 const VkDeviceSize vertexDataPerDraw = 4 * 2 * sizeof(Vec4);
1343 VkDeviceSize vertexBufferOffset = 0ull;
1344 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
1346 if (subpassNdx != 0)
1347 m_vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
1349 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_uDraw.pipelines[subpassNdx]);
1351 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_uDraw.vertexBuffer.get(), &vertexBufferOffset);
1352 m_vk.cmdDraw(*m_cmdBuffer, 4u, 1u, 0u, 0u);
1353 vertexBufferOffset += vertexDataPerDraw;
1356 endRenderPass(m_vk, *m_cmdBuffer);
1359 m_imageLayoutAfterUpload = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1360 m_imageUploadAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1363 void UploadDownloadExecutor::downloadCopy(Context& context, VkBuffer buffer)
1367 copyImageToBuffer(m_image, buffer, m_caseDef.size, m_imageUploadAccessMask, m_imageLayoutAfterUpload, m_caseDef.numLayers);
1370 void UploadDownloadExecutor::downloadTexture(Context& context, VkBuffer buffer)
1372 // Create output image with download result
1373 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1374 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);
1375 m_dTex.outImageAlloc = bindImage(m_vk, m_device, m_allocator, *m_dTex.outImage, MemoryRequirement::Any);
1376 m_dTex.outImageView = makeImageView(m_vk, m_device, *m_dTex.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));
1378 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1380 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1381 DE_NULL, // const void* pNext
1382 VK_IMAGE_USAGE_SAMPLED_BIT, // VkImageUsageFlags usage;
1384 m_dTex.inImageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1385 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1386 m_dTex.sampler = makeSampler(m_vk, m_device);
1388 // Setup compute pipeline
1389 m_dTex.descriptorPool = DescriptorPoolBuilder()
1390 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1391 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1392 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1394 m_dTex.descriptorSetLayout = DescriptorSetLayoutBuilder()
1395 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT, &m_dTex.sampler.get())
1396 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1397 .build(m_vk, m_device);
1399 m_dTex.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_dTex.descriptorSetLayout);
1400 m_dTex.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_dTex.descriptorPool, *m_dTex.descriptorSetLayout);
1401 m_dTex.inImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dTex.inImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1402 m_dTex.outImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dTex.outImageView, VK_IMAGE_LAYOUT_GENERAL);
1403 m_dTex.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadTextureComp"), 0);
1404 m_dTex.computePipeline = makeComputePipeline(m_vk, m_device, *m_dTex.pipelineLayout, *m_dTex.computeModule, DE_NULL);
1406 DescriptorSetUpdateBuilder()
1407 .writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &m_dTex.inImageDescriptorInfo)
1408 .writeSingle(*m_dTex.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dTex.outImageDescriptorInfo)
1409 .update(m_vk, m_device);
1411 // Transition images for shader access (texture / imageStore)
1412 const VkImageMemoryBarrier imageBarriers[] =
1415 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1416 DE_NULL, // const void* pNext;
1417 (VkAccessFlags)m_imageUploadAccessMask, // VkAccessFlags srcAccessMask;
1418 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
1419 m_imageLayoutAfterUpload, // VkImageLayout oldLayout;
1420 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
1421 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1422 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1423 m_image, // VkImage image;
1424 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1427 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1428 DE_NULL, // const void* pNext;
1429 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1430 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1431 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1432 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout;
1433 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1434 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1435 *m_dTex.outImage, // VkImage image;
1436 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1440 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1441 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
1444 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.computePipeline);
1445 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dTex.pipelineLayout, 0u, 1u, &m_dTex.descriptorSet.get(), 0u, DE_NULL);
1446 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1448 // Copy output image to color buffer
1449 copyImageToBuffer(*m_dTex.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL, m_caseDef.numLayers);
1452 void UploadDownloadExecutor::downloadLoad(Context& context, VkBuffer buffer)
1454 // Create output image with download result
1455 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1456 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);
1457 m_dLoad.outImageAlloc = bindImage(m_vk, m_device, m_allocator, *m_dLoad.outImage, MemoryRequirement::Any);
1458 m_dLoad.outImageView = makeImageView(m_vk, m_device, *m_dLoad.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));
1460 const vk::VkImageViewUsageCreateInfo viewUsageCreateInfo =
1462 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1463 DE_NULL, // const void* pNext
1464 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage;
1466 m_dLoad.inImageView = makeImageView(m_vk, m_device, m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1467 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1469 // Setup compute pipeline
1470 m_dLoad.descriptorPool = DescriptorPoolBuilder()
1471 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2u)
1472 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1474 m_dLoad.descriptorSetLayout = DescriptorSetLayoutBuilder()
1475 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1476 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1477 .build(m_vk, m_device);
1479 m_dLoad.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_dLoad.descriptorSetLayout);
1480 m_dLoad.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_dLoad.descriptorPool, *m_dLoad.descriptorSetLayout);
1481 m_dLoad.inImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dLoad.inImageView, VK_IMAGE_LAYOUT_GENERAL);
1482 m_dLoad.outImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dLoad.outImageView, VK_IMAGE_LAYOUT_GENERAL);
1483 m_dLoad.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadLoadComp"), 0);
1484 m_dLoad.computePipeline = makeComputePipeline(m_vk, m_device, *m_dLoad.pipelineLayout, *m_dLoad.computeModule, DE_NULL);
1486 DescriptorSetUpdateBuilder()
1487 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.inImageDescriptorInfo)
1488 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.outImageDescriptorInfo)
1489 .update(m_vk, m_device);
1491 // Transition storage images for shader access (imageLoad/Store)
1492 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1493 const VkImageMemoryBarrier imageBarriers[] =
1496 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1497 DE_NULL, // const void* pNext;
1498 (VkAccessFlags)m_imageUploadAccessMask, // VkAccessFlags srcAccessMask;
1499 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
1500 m_imageLayoutAfterUpload, // VkImageLayout oldLayout;
1501 requiredImageLayout, // VkImageLayout newLayout;
1502 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1503 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1504 m_image, // VkImage image;
1505 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1508 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1509 DE_NULL, // const void* pNext;
1510 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1511 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1512 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1513 requiredImageLayout, // VkImageLayout newLayout;
1514 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1515 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1516 *m_dLoad.outImage, // VkImage image;
1517 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1521 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1522 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
1525 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.computePipeline);
1526 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.pipelineLayout, 0u, 1u, &m_dLoad.descriptorSet.get(), 0u, DE_NULL);
1527 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1529 // Copy output image to color buffer
1530 copyImageToBuffer(*m_dLoad.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, requiredImageLayout, m_caseDef.numLayers);
1533 void UploadDownloadExecutor::copyImageToBuffer(VkImage sourceImage,
1536 const VkAccessFlags srcAccessMask,
1537 const VkImageLayout oldLayout,
1538 const deUint32 numLayers)
1540 // Copy result to host visible buffer for inspection
1541 const VkImageMemoryBarrier imageBarrier =
1543 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1544 DE_NULL, // const void* pNext;
1545 srcAccessMask, // VkAccessFlags srcAccessMask;
1546 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1547 oldLayout, // VkImageLayout oldLayout;
1548 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
1549 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1550 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1551 sourceImage, // VkImage image;
1552 makeColorSubresourceRange(0, numLayers) // VkImageSubresourceRange subresourceRange;
1555 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1556 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
1558 const VkImageSubresourceLayers subresource =
1560 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1561 0u, // deUint32 mipLevel;
1562 0u, // deUint32 baseArrayLayer;
1563 numLayers, // deUint32 layerCount;
1566 const VkBufferImageCopy region =
1568 0ull, // VkDeviceSize bufferOffset;
1569 0u, // deUint32 bufferRowLength;
1570 0u, // deUint32 bufferImageHeight;
1571 subresource, // VkImageSubresourceLayers imageSubresource;
1572 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
1573 makeExtent3D(size), // VkExtent3D imageExtent;
1576 m_vk.cmdCopyImageToBuffer(*m_cmdBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, ®ion);
1578 const VkBufferMemoryBarrier bufferBarrier =
1580 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1581 DE_NULL, // const void* pNext;
1582 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1583 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
1584 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1585 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1586 buffer, // VkBuffer buffer;
1587 0ull, // VkDeviceSize offset;
1588 VK_WHOLE_SIZE, // VkDeviceSize size;
1591 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
1592 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
1595 tcu::TestStatus testMutable (Context& context, const CaseDef caseDef)
1597 const DeviceInterface& vk = context.getDeviceInterface();
1598 const InstanceInterface& vki = context.getInstanceInterface();
1599 const VkDevice device = context.getDevice();
1600 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
1601 Allocator& allocator = context.getDefaultAllocator();
1603 // If this is a VK_KHR_image_format_list test, check that the extension is supported
1604 if (caseDef.isFormatListTest && !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_image_format_list"))
1605 TCU_THROW(NotSupportedError, "VK_KHR_image_format_list not supported");
1607 // Check required features on the format for the required upload/download methods
1608 VkFormatProperties imageFormatProps, viewFormatProps;
1609 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.imageFormat, &imageFormatProps);
1610 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.viewFormat, &viewFormatProps);
1612 VkFormatFeatureFlags viewFormatFeatureFlags = 0u;
1613 switch (caseDef.upload)
1616 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
1619 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1622 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1625 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1628 DE_FATAL("Invalid upload method");
1631 switch (caseDef.download)
1633 case DOWNLOAD_TEXTURE:
1634 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
1635 // For the texture case we write the samples read to a separate output image with the same view format
1636 // so we need to check that we can also use the view format for storage
1637 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1640 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1643 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1646 DE_FATAL("Invalid download method");
1650 if ((viewFormatFeatureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) &&
1651 isStorageImageExtendedFormat(caseDef.viewFormat) &&
1652 !getPhysicalDeviceFeatures(vki, physDevice).shaderStorageImageExtendedFormats)
1654 TCU_THROW(NotSupportedError, "View format requires shaderStorageImageExtended");
1657 if ((viewFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags)
1658 TCU_THROW(NotSupportedError, "View format doesn't support upload/download method");
1660 const bool haveMaintenance2 = isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance2");
1662 // We don't use the base image for anything other than transfer
1663 // operations so there are no features to check. However, The Vulkan
1664 // 1.0 spec does not allow us to create an image view with usage that
1665 // is not supported by the main format. With VK_KHR_maintenance2, we
1666 // can do this via VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR.
1667 if ((imageFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags &&
1670 TCU_THROW(NotSupportedError, "Image format doesn't support upload/download method");
1673 // If no format feature flags are supported, the format itself is not supported,
1674 // and images of that format cannot be created.
1675 if (imageFormatProps.optimalTilingFeatures == 0)
1677 TCU_THROW(NotSupportedError, "Base image format is not supported");
1680 // Create a color buffer for host-inspection of results
1681 // For the Copy download method, this is the target of the download, for other
1682 // download methods, pixel data will be copied to this buffer from the download
1684 const VkDeviceSize colorBufferSize = caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat));
1685 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1686 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1687 deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
1688 flushAlloc(vk, device, *colorBufferAlloc);
1691 UploadDownloadExecutor executor(context, caseDef);
1692 executor.run(context, *colorBuffer);
1696 invalidateAlloc(vk, device, *colorBufferAlloc);
1698 // For verification purposes, we use the format of the upload to generate the expected image
1699 const VkFormat format = caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat;
1700 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
1701 const bool isIntegerFormat = isUintFormat(format) || isIntFormat(format);
1702 const tcu::ConstPixelBufferAccess resultImage (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr());
1703 tcu::TextureLevel textureLevel (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers);
1704 const tcu::PixelBufferAccess expectedImage = textureLevel.getAccess();
1705 generateExpectedImage(expectedImage, caseDef);
1708 if (isIntegerFormat)
1709 ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
1711 ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
1712 return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
1716 tcu::TestCaseGroup* createImageMutableTests (TestContext& testCtx)
1718 de::MovePtr<TestCaseGroup> testGroup (new TestCaseGroup(testCtx, "mutable", "Cases with mutable images"));
1719 for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx)
1721 const Texture& texture = s_textures[textureNdx];
1722 de::MovePtr<tcu::TestCaseGroup> groupByImageViewType (new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), ""));
1724 for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++imageFormatNdx)
1725 for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++viewFormatNdx)
1727 if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_formats[imageFormatNdx], s_formats[viewFormatNdx]))
1729 for (int upload = 0; upload < UPLOAD_LAST; upload++)
1730 for (int download = 0; download < DOWNLOAD_LAST; download++)
1735 texture.layerSize(),
1736 static_cast<deUint32>(texture.numLayers()),
1737 s_formats[imageFormatNdx],
1738 s_formats[viewFormatNdx],
1739 static_cast<enum Upload>(upload),
1740 static_cast<enum Download>(download),
1741 false, // isFormatListTest;
1742 false, // isSwapchainImageTest
1743 vk::wsi::TYPE_LAST // wsiType
1746 std::string caseName = getFormatShortString(s_formats[imageFormatNdx]) + "_" + getFormatShortString(s_formats[viewFormatNdx]) +
1747 "_" + getUploadString(upload) + "_" + getDownloadString(download);
1748 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", initPrograms, testMutable, caseDef);
1750 caseDef.isFormatListTest = true;
1751 caseName += "_format_list";
1752 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", initPrograms, testMutable, caseDef);
1757 testGroup->addChild(groupByImageViewType.release());
1760 return testGroup.release();
1763 typedef vector<VkExtensionProperties> Extensions;
1765 void checkAllSupported(const Extensions& supportedExtensions, const vector<string>& requiredExtensions)
1767 for (vector<string>::const_iterator requiredExtName = requiredExtensions.begin();
1768 requiredExtName != requiredExtensions.end();
1771 if (!isExtensionSupported(supportedExtensions, RequiredExtension(*requiredExtName)))
1772 TCU_THROW(NotSupportedError, (*requiredExtName + " is not supported").c_str());
1776 Move<VkInstance> createInstanceWithWsi(const PlatformInterface& vkp,
1778 const Extensions& supportedExtensions,
1780 const VkAllocationCallbacks* pAllocator = DE_NULL)
1782 vector<string> extensions;
1784 extensions.push_back("VK_KHR_surface");
1785 extensions.push_back(getExtensionName(wsiType));
1787 // VK_EXT_swapchain_colorspace adds new surface formats. Driver can enumerate
1788 // the formats regardless of whether VK_EXT_swapchain_colorspace was enabled,
1789 // but using them without enabling the extension is not allowed. Thus we have
1792 // 1) Filter out non-core formats to stay within valid usage.
1794 // 2) Enable VK_EXT_swapchain colorspace if advertised by the driver.
1796 // We opt for (2) as it provides basic coverage for the extension as a bonus.
1797 if (isExtensionSupported(supportedExtensions, RequiredExtension("VK_EXT_swapchain_colorspace")))
1798 extensions.push_back("VK_EXT_swapchain_colorspace");
1800 checkAllSupported(supportedExtensions, extensions);
1802 return vk::createDefaultInstance(vkp, version, vector<string>(), extensions, pAllocator);
1806 Move<VkDevice> createDeviceWithWsi(const PlatformInterface& vkp,
1807 VkInstance instance,
1808 const InstanceInterface& vki,
1809 VkPhysicalDevice physicalDevice,
1810 const Extensions& supportedExtensions,
1811 const deUint32 queueFamilyIndex,
1812 const VkAllocationCallbacks* pAllocator = DE_NULL)
1814 const float queuePriorities[] = { 1.0f };
1815 const VkDeviceQueueCreateInfo queueInfos[] =
1818 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1820 (VkDeviceQueueCreateFlags)0,
1822 DE_LENGTH_OF_ARRAY(queuePriorities),
1826 VkPhysicalDeviceFeatures features;
1827 deMemset(&features, 0x0, sizeof(features));
1829 const char* const extensions[] = { "VK_KHR_swapchain", "VK_KHR_swapchain_mutable_format" };
1830 const VkDeviceCreateInfo deviceParams =
1832 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1834 (VkDeviceCreateFlags)0,
1835 DE_LENGTH_OF_ARRAY(queueInfos),
1837 0u, // enabledLayerCount
1838 DE_NULL, // ppEnabledLayerNames
1839 DE_LENGTH_OF_ARRAY(extensions), // enabledExtensionCount
1840 DE_ARRAY_BEGIN(extensions), // ppEnabledExtensionNames
1844 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(extensions); ++ndx)
1846 if (!isExtensionSupported(supportedExtensions, RequiredExtension(extensions[ndx])))
1847 TCU_THROW(NotSupportedError, (string(extensions[ndx]) + " is not supported").c_str());
1850 return createDevice(vkp, instance, vki, physicalDevice, &deviceParams, pAllocator);
1853 deUint32 getNumQueueFamilyIndices(const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
1855 deUint32 numFamilies = 0;
1857 vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
1862 vector<deUint32> getSupportedQueueFamilyIndices(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
1864 const deUint32 numTotalFamilyIndices = getNumQueueFamilyIndices(vki, physicalDevice);
1865 vector<deUint32> supportedFamilyIndices;
1867 for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
1869 if (getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
1870 supportedFamilyIndices.push_back(queueFamilyNdx);
1873 return supportedFamilyIndices;
1876 deUint32 chooseQueueFamilyIndex(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
1878 const vector<deUint32> supportedFamilyIndices = getSupportedQueueFamilyIndices(vki, physicalDevice, surface);
1880 if (supportedFamilyIndices.empty())
1881 TCU_THROW(NotSupportedError, "Device doesn't support presentation");
1883 return supportedFamilyIndices[0];
1886 struct InstanceHelper
1888 const vector<VkExtensionProperties> supportedExtensions;
1889 const Unique<VkInstance> instance;
1890 const InstanceDriver vki;
1892 InstanceHelper(Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
1893 : supportedExtensions(enumerateInstanceExtensionProperties(context.getPlatformInterface(),
1895 , instance(createInstanceWithWsi(context.getPlatformInterface(),
1896 context.getUsedApiVersion(),
1897 supportedExtensions,
1900 , vki(context.getPlatformInterface(), *instance)
1907 const VkPhysicalDevice physicalDevice;
1908 const deUint32 queueFamilyIndex;
1909 const Unique<VkDevice> device;
1910 const DeviceDriver vkd;
1911 const VkQueue queue;
1913 DeviceHelper(Context& context,
1914 const InstanceInterface& vki,
1915 VkInstance instance,
1916 VkSurfaceKHR surface,
1917 const VkAllocationCallbacks* pAllocator = DE_NULL)
1918 : physicalDevice(chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
1919 , queueFamilyIndex(chooseQueueFamilyIndex(vki, physicalDevice, surface))
1920 , device(createDeviceWithWsi(context.getPlatformInterface(),
1921 context.getInstance(),
1924 enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL),
1927 , vkd(context.getPlatformInterface(), context.getInstance(), *device)
1928 , queue(getDeviceQueue(vkd, *device, queueFamilyIndex, 0))
1933 MovePtr<Display> createDisplay(const vk::Platform& platform,
1934 const Extensions& supportedExtensions,
1939 return MovePtr<Display>(platform.createWsiDisplay(wsiType));
1941 catch (const tcu::NotSupportedError& e)
1943 if (isExtensionSupported(supportedExtensions, RequiredExtension(getExtensionName(wsiType))))
1945 // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
1946 // must support creating native display & window for that WSI type.
1947 throw tcu::TestError(e.getMessage());
1954 MovePtr<Window> createWindow(const Display& display, const Maybe<UVec2>& initialSize)
1958 return MovePtr<Window>(display.createWindow(initialSize));
1960 catch (const tcu::NotSupportedError& e)
1962 // See createDisplay - assuming that wsi::Display was supported platform port
1963 // should also support creating a window.
1964 throw tcu::TestError(e.getMessage());
1968 struct NativeObjects
1970 const UniquePtr<Display> display;
1971 const UniquePtr<Window> window;
1973 NativeObjects(Context& context,
1974 const Extensions& supportedExtensions,
1976 const Maybe<UVec2>& initialWindowSize = tcu::nothing<UVec2>())
1977 : display(createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
1978 , window(createWindow(*display, initialWindowSize))
1982 Move<VkSwapchainKHR> makeSwapchain(const DeviceInterface& vk,
1983 const VkDevice device,
1984 const vk::wsi::Type wsiType,
1985 const VkSurfaceKHR surface,
1986 const VkSurfaceCapabilitiesKHR capabilities,
1987 const VkSurfaceFormatKHR surfaceFormat,
1988 const VkFormat viewFormat,
1989 const deUint32 numLayers,
1990 const VkImageUsageFlags usage,
1991 const tcu::UVec2& desiredSize,
1992 deUint32 desiredImageCount
1995 const VkFormat formatList[2] =
1997 surfaceFormat.format,
2001 const VkImageFormatListCreateInfoKHR formatListInfo =
2003 VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR, // VkStructureType sType;
2004 DE_NULL, // const void* pNext;
2005 2u, // deUint32 viewFormatCount
2006 formatList // const VkFormat* pViewFormats
2009 const VkSurfaceTransformFlagBitsKHR transform = (capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
2010 const PlatformProperties& platformProperties = getPlatformProperties(wsiType);
2012 const VkSwapchainCreateInfoKHR swapchainInfo =
2014 VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, // VkStructureType sType;
2015 &formatListInfo, // const void* pNext;
2016 VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR, // VkSwapchainCreateFlagsKHR flags;
2017 surface, // VkSurfaceKHR surface;
2018 de::clamp(desiredImageCount, capabilities.minImageCount, capabilities.maxImageCount > 0 ? capabilities.maxImageCount : capabilities.minImageCount + desiredImageCount), // deUint32 minImageCount;
2019 surfaceFormat.format, // VkFormat imageFormat;
2020 surfaceFormat.colorSpace, // VkColorSpaceKHR imageColorSpace;
2021 (platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE
2022 ? capabilities.currentExtent : vk::makeExtent2D(desiredSize.x(), desiredSize.y())), // VkExtent2D imageExtent;
2023 numLayers, // deUint32 imageArrayLayers;
2024 usage, // VkImageUsageFlags imageUsage;
2025 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode imageSharingMode;
2026 0u, // deUint32 queueFamilyIndexCount;
2027 (const deUint32*)DE_NULL, // const deUint32* pQueueFamilyIndices;
2028 transform, // VkSurfaceTransformFlagBitsKHR preTransform;
2029 VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, // VkCompositeAlphaFlagBitsKHR compositeAlpha;
2030 VK_PRESENT_MODE_FIFO_KHR, // VkPresentModeKHR presentMode;
2031 VK_FALSE, // VkBool32 clipped;
2032 (VkSwapchainKHR)0 // VkSwapchainKHR oldSwapchain;
2035 return createSwapchainKHR(vk, device, &swapchainInfo);
2038 tcu::TestStatus testSwapchainMutable(Context& context, CaseDef caseDef)
2040 const Type wsiType(caseDef.wsiType);
2041 const tcu::UVec2 desiredSize(256, 256);
2042 const InstanceHelper instHelper(context, wsiType);
2043 const NativeObjects native(context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
2044 const Unique<VkSurfaceKHR> surface(createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
2045 const DeviceHelper devHelper(context, instHelper.vki, *instHelper.instance, *surface);
2046 const DeviceInterface& vk = devHelper.vkd;
2047 const InstanceDriver& vki = instHelper.vki;
2048 const VkDevice device = *devHelper.device;
2049 const VkPhysicalDevice physDevice = devHelper.physicalDevice;
2051 Allocator& allocator = context.getDefaultAllocator();
2053 // Check required features on the format for the required upload/download methods
2054 VkFormatProperties imageFormatProps, viewFormatProps;
2055 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.imageFormat, &imageFormatProps);
2056 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.viewFormat, &viewFormatProps);
2058 const VkImageUsageFlags imageUsage = getImageUsageForTestCase(caseDef);
2060 const VkSurfaceCapabilitiesKHR capabilities = getPhysicalDeviceSurfaceCapabilities(vki,
2064 if (caseDef.numLayers > capabilities.maxImageArrayLayers)
2065 caseDef.numLayers = capabilities.maxImageArrayLayers;
2067 // Check support for requested formats by swapchain surface
2068 const vector<VkSurfaceFormatKHR> surfaceFormats = getPhysicalDeviceSurfaceFormats(vki,
2072 const VkSurfaceFormatKHR* surfaceFormat = DE_NULL;
2073 const VkFormat* viewFormat = DE_NULL;
2075 for (vector<VkSurfaceFormatKHR>::size_type i = 0; i < surfaceFormats.size(); i++)
2077 if (surfaceFormats[i].format == caseDef.imageFormat)
2078 surfaceFormat = &surfaceFormats[i];
2080 if (surfaceFormats[i].format == caseDef.viewFormat)
2081 viewFormat = &surfaceFormats[i].format;
2084 if (surfaceFormat == DE_NULL)
2085 TCU_THROW(NotSupportedError, "Image format is not supported by swapchain.");
2087 if (viewFormat == DE_NULL)
2088 TCU_THROW(NotSupportedError, "Image view format is not supported by swapchain.");
2090 if ((capabilities.supportedUsageFlags & imageUsage) != imageUsage)
2091 TCU_THROW(NotSupportedError, "Image usage request not supported by swapchain.");
2093 const Unique<VkSwapchainKHR> swapchain(
2107 const vector<VkImage> swapchainImages = getSwapchainImages(vk, device, *swapchain);
2109 VkFormatFeatureFlags viewFormatFeatureFlags = 0u;
2110 switch (caseDef.upload)
2113 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
2116 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
2119 DE_FATAL("Invalid upload method");
2122 switch (caseDef.download)
2124 case DOWNLOAD_TEXTURE:
2125 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
2126 // For the texture case we write the samples read to a separate output image with the same view format
2127 // so we need to check that we can also use the view format for storage
2128 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
2131 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
2134 DE_FATAL("Invalid download method");
2138 if ((viewFormatFeatureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) &&
2139 isStorageImageExtendedFormat(caseDef.viewFormat) &&
2140 !getPhysicalDeviceFeatures(vki, physDevice).shaderStorageImageExtendedFormats)
2142 TCU_THROW(NotSupportedError, "View format requires shaderStorageImageExtended");
2145 if ((viewFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags)
2146 TCU_THROW(NotSupportedError, "View format doesn't support upload/download method");
2148 // We don't use the base image for anything other than transfer
2149 // operations so there are no features to check. However, The Vulkan
2150 // 1.0 spec does not allow us to create an image view with usage that
2151 // is not supported by the main format. With VK_KHR_maintenance2, we
2152 // can do this via VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR.
2153 if ((imageFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags &&
2154 !isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance2"))
2156 TCU_THROW(NotSupportedError, "Image format doesn't support upload/download method");
2159 // Create a color buffer for host-inspection of results
2160 // For the Copy download method, this is the target of the download, for other
2161 // download methods, pixel data will be copied to this buffer from the download
2163 const VkDeviceSize colorBufferSize = caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat));
2164 const Unique<VkBuffer> colorBuffer(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2165 const UniquePtr<Allocation> colorBufferAlloc(bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
2166 deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
2167 flushMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
2171 UploadDownloadExecutor executor(context, caseDef);
2173 executor.runSwapchain(context, *colorBuffer, swapchainImages[0]);
2177 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
2179 // For verification purposes, we use the format of the upload to generate the expected image
2180 const VkFormat format = caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat;
2181 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
2182 const bool isIntegerFormat = isUintFormat(format) || isIntFormat(format);
2183 const tcu::ConstPixelBufferAccess resultImage(tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr());
2184 tcu::TextureLevel textureLevel(tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers);
2185 const tcu::PixelBufferAccess expectedImage = textureLevel.getAccess();
2186 generateExpectedImage(expectedImage, caseDef);
2189 if (isIntegerFormat)
2190 ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
2192 ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
2193 return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
2197 tcu::TestCaseGroup* createSwapchainImageMutableTests(TestContext& testCtx)
2199 de::MovePtr<TestCaseGroup> testGroup(new TestCaseGroup(testCtx, "swapchain_mutable", "Cases with swapchain mutable images"));
2201 for (int typeNdx = 0; typeNdx < vk::wsi::TYPE_LAST; ++typeNdx)
2203 const vk::wsi::Type wsiType = (vk::wsi::Type)typeNdx;
2205 de::MovePtr<TestCaseGroup> testGroupWsi(new TestCaseGroup(testCtx, getName(wsiType), ""));
2207 for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx)
2209 const Texture& texture = s_textures[textureNdx];
2210 de::MovePtr<tcu::TestCaseGroup> groupByImageViewType(new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), ""));
2212 for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_swapchainFormats); ++imageFormatNdx)
2213 for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_swapchainFormats); ++viewFormatNdx)
2215 if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_swapchainFormats[imageFormatNdx], s_swapchainFormats[viewFormatNdx]))
2217 for (int upload = 0; upload < UPLOAD_LAST; upload++)
2218 for (int download = 0; download < DOWNLOAD_LAST; download++)
2223 texture.layerSize(),
2224 static_cast<deUint32>(texture.numLayers()),
2225 s_swapchainFormats[imageFormatNdx],
2226 s_swapchainFormats[viewFormatNdx],
2227 static_cast<enum Upload>(upload),
2228 static_cast<enum Download>(download),
2229 true, // isFormatListTest;
2230 true, // isSwapchainImageTest
2234 std::string caseName = getFormatShortString(s_swapchainFormats[imageFormatNdx]) + "_" + getFormatShortString(s_swapchainFormats[viewFormatNdx]) +
2235 "_" + getUploadString(upload) + "_" + getDownloadString(download) + "_format_list";
2237 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", initPrograms, testSwapchainMutable, caseDef);
2242 testGroupWsi->addChild(groupByImageViewType.release());
2245 testGroup->addChild(testGroupWsi.release());
2247 return testGroup.release();