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 "vktTestCaseUtil.hpp"
26 #include "vktImageTexture.hpp"
28 #include "vkBuilderUtil.hpp"
29 #include "vkQueryUtil.hpp"
30 #include "vkImageUtil.hpp"
32 #include "deUniquePtr.hpp"
33 #include "deSharedPtr.hpp"
35 #include "tcuImageCompare.hpp"
36 #include "tcuTestLog.hpp"
37 #include "tcuTextureUtil.hpp"
55 typedef SharedPtr<Unique<VkPipeline> > SharedPtrVkPipeline;
56 typedef SharedPtr<Unique<VkImageView> > SharedPtrVkImageView;
59 inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move)
61 return SharedPtr<Unique<T> >(new Unique<T>(move));
79 std::string getUploadString (const int upload)
81 const char* strs[] = { "clear", "copy", "store", "draw" };
85 std::string getDownloadString (const int download)
87 const char* strs[] = { "copy", "load", "texture" };
88 return strs[download];
99 enum Download download;
102 static const deUint32 COLOR_TABLE_SIZE = 4;
104 // Reference color values for float color rendering. Values have been chosen
105 // so that when the bit patterns are reinterpreted as a 16-bit float, we do not
106 // run into NaN / inf / denorm values.
107 static const Vec4 COLOR_TABLE_FLOAT[COLOR_TABLE_SIZE] =
109 Vec4(0.00f, 0.40f, 0.80f, 0.10f),
110 Vec4(0.10f, 0.50f, 0.90f, 0.20f),
111 Vec4(0.20f, 0.60f, 1.00f, 0.30f),
112 Vec4(0.30f, 0.70f, 0.00f, 0.40f),
115 // Reference color values for integer color rendering. We avoid negative
116 // values (even for SINT formats) to avoid the situation where sign extension
117 // leads to NaN / inf values when they are reinterpreted with a float
119 static const IVec4 COLOR_TABLE_INT[COLOR_TABLE_SIZE] =
121 IVec4(112, 60, 101, 41),
122 IVec4( 60, 101, 41, 112),
123 IVec4( 41, 112, 60, 101),
124 IVec4(101, 41, 112, 60),
127 // Reference clear colors created from the color table values
128 static const VkClearValue REFERENCE_CLEAR_COLOR_FLOAT[COLOR_TABLE_SIZE] =
130 makeClearValueColorF32(COLOR_TABLE_FLOAT[0].x(), COLOR_TABLE_FLOAT[0].y(), COLOR_TABLE_FLOAT[0].z(), COLOR_TABLE_FLOAT[0].w()),
131 makeClearValueColorF32(COLOR_TABLE_FLOAT[1].x(), COLOR_TABLE_FLOAT[1].y(), COLOR_TABLE_FLOAT[1].z(), COLOR_TABLE_FLOAT[1].w()),
132 makeClearValueColorF32(COLOR_TABLE_FLOAT[2].x(), COLOR_TABLE_FLOAT[2].y(), COLOR_TABLE_FLOAT[2].z(), COLOR_TABLE_FLOAT[2].w()),
133 makeClearValueColorF32(COLOR_TABLE_FLOAT[3].x(), COLOR_TABLE_FLOAT[3].y(), COLOR_TABLE_FLOAT[3].z(), COLOR_TABLE_FLOAT[3].w()),
136 static const VkClearValue REFERENCE_CLEAR_COLOR_INT[COLOR_TABLE_SIZE] =
138 makeClearValueColorI32(COLOR_TABLE_INT[0].x(), COLOR_TABLE_INT[0].y(), COLOR_TABLE_INT[0].z(), COLOR_TABLE_INT[0].w()),
139 makeClearValueColorI32(COLOR_TABLE_INT[1].x(), COLOR_TABLE_INT[1].y(), COLOR_TABLE_INT[1].z(), COLOR_TABLE_INT[1].w()),
140 makeClearValueColorI32(COLOR_TABLE_INT[2].x(), COLOR_TABLE_INT[2].y(), COLOR_TABLE_INT[2].z(), COLOR_TABLE_INT[2].w()),
141 makeClearValueColorI32(COLOR_TABLE_INT[3].x(), COLOR_TABLE_INT[3].y(), COLOR_TABLE_INT[3].z(), COLOR_TABLE_INT[3].w()),
144 static const Texture s_textures[] =
146 Texture(IMAGE_TYPE_2D, tcu::IVec3(32, 32, 1), 1),
147 Texture(IMAGE_TYPE_2D_ARRAY, tcu::IVec3(32, 32, 1), 4),
150 VkImageType getImageType (const ImageType textureImageType)
152 switch (textureImageType)
155 case IMAGE_TYPE_2D_ARRAY:
156 return VK_IMAGE_TYPE_2D;
160 return VK_IMAGE_TYPE_LAST;
164 VkImageViewType getImageViewType (const ImageType textureImageType)
166 switch (textureImageType)
169 return VK_IMAGE_VIEW_TYPE_2D;
170 case IMAGE_TYPE_2D_ARRAY:
171 return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
175 return VK_IMAGE_VIEW_TYPE_LAST;
179 static const VkFormat s_formats[] =
181 VK_FORMAT_R32G32B32A32_SFLOAT,
182 VK_FORMAT_R16G16B16A16_SFLOAT,
183 VK_FORMAT_R32G32_SFLOAT,
184 VK_FORMAT_R16G16_SFLOAT,
185 VK_FORMAT_R32_SFLOAT,
187 VK_FORMAT_R32G32B32A32_UINT,
188 VK_FORMAT_R16G16B16A16_UINT,
189 VK_FORMAT_R8G8B8A8_UINT,
190 VK_FORMAT_R32G32_UINT,
191 VK_FORMAT_R16G16_UINT,
194 VK_FORMAT_R32G32B32A32_SINT,
195 VK_FORMAT_R16G16B16A16_SINT,
196 VK_FORMAT_R8G8B8A8_SINT,
197 VK_FORMAT_R32G32_SINT,
198 VK_FORMAT_R16G16_SINT,
201 VK_FORMAT_R8G8B8A8_UNORM,
203 VK_FORMAT_R8G8B8A8_SNORM,
206 inline bool formatsAreCompatible (const VkFormat format0, const VkFormat format1)
208 return format0 == format1 || mapVkFormat(format0).getPixelSize() == mapVkFormat(format1).getPixelSize();
211 std::string getColorFormatStr (const int numComponents, const bool isUint, const bool isSint)
213 std::ostringstream str;
214 if (numComponents == 1)
215 str << (isUint ? "uint" : isSint ? "int" : "float");
217 str << (isUint ? "u" : isSint ? "i" : "") << "vec" << numComponents;
222 std::string getShaderSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
224 std::ostringstream samplerType;
226 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
228 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
233 case VK_IMAGE_VIEW_TYPE_2D:
234 samplerType << "sampler2D";
237 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
238 samplerType << "sampler2DArray";
242 DE_FATAL("Ivalid image view type");
246 return samplerType.str();
249 void initPrograms (SourceCollections& programCollection, const CaseDef caseDef)
251 if (caseDef.upload == UPLOAD_DRAW)
254 std::ostringstream src;
255 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
257 << "layout(location = 0) in vec4 in_position;\n"
258 << "layout(location = 1) in vec4 in_color;\n"
259 << "layout(location = 0) out vec4 out_color;\n"
261 << "out gl_PerVertex {\n"
262 << " vec4 gl_Position;\n"
265 << "void main(void)\n"
267 << " gl_Position = in_position;\n"
268 << " out_color = in_color;\n"
271 programCollection.glslSources.add("uploadDrawVert") << glu::VertexSource(src.str());
275 const int numComponents = getNumUsedChannels(mapVkFormat(caseDef.viewFormat).order);
276 const bool isUint = isUintFormat(caseDef.viewFormat);
277 const bool isSint = isIntFormat(caseDef.viewFormat);
278 const std::string colorFormat = getColorFormatStr(numComponents, isUint, isSint);
280 std::ostringstream src;
281 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
283 << "layout(location = 0) in vec4 in_color;\n"
284 << "layout(location = 0) out " << colorFormat << " out_color;\n"
286 << "void main(void)\n"
288 << " out_color = " << colorFormat << "("
289 << (numComponents == 1 ? "in_color.r" :
290 numComponents == 2 ? "in_color.rg" :
291 numComponents == 3 ? "in_color.rgb" : "in_color")
295 programCollection.glslSources.add("uploadDrawFrag") << glu::FragmentSource(src.str());
299 if (caseDef.upload == UPLOAD_STORE)
301 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
302 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
303 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
304 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
305 const bool isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);
307 std::ostringstream src;
308 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
310 << "layout (local_size_x = 1) in;\n"
312 << "layout(binding=0, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " u_image;\n"
314 << "const " << colorTypeStr << " colorTable[] = " << colorTypeStr << "[](\n";
315 for (deUint32 idx = 0; idx < COLOR_TABLE_SIZE; idx++)
318 src << " " << colorTypeStr << "(" << COLOR_TABLE_INT[idx].x() << ", " << COLOR_TABLE_INT[idx].y() << ", " << COLOR_TABLE_INT[idx].z() << ", " << COLOR_TABLE_INT[idx].w() << ")";
320 src << " " << colorTypeStr << "(" << COLOR_TABLE_FLOAT[idx].x() << ", " << COLOR_TABLE_FLOAT[idx].y() << ", " << COLOR_TABLE_FLOAT[idx].z() << ", " << COLOR_TABLE_FLOAT[idx].w() << ")";
321 if (idx < COLOR_TABLE_SIZE - 1)
327 << "void main(void)\n"
329 if (caseDef.imageType == IMAGE_TYPE_2D)
331 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
335 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
336 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
338 src << " " << colorTypeStr << " color = colorTable[gl_GlobalInvocationID.z];\n"
339 << " imageStore(u_image, pos, color);\n"
342 programCollection.glslSources.add("uploadStoreComp") << glu::ComputeSource(src.str());
345 if (caseDef.download == DOWNLOAD_LOAD)
347 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
348 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
349 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
350 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
352 std::ostringstream src;
353 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
355 << "layout (local_size_x = 1) in;\n"
357 << "layout(binding=0, " << imageFormatStr << ") readonly uniform " << imageTypeStr << " in_image;\n"
358 << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
360 << "void main(void)\n"
362 if (caseDef.imageType == IMAGE_TYPE_2D)
364 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
368 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
369 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
371 src << " imageStore(out_image, pos, imageLoad(in_image, pos));\n"
374 programCollection.glslSources.add("downloadLoadComp") << glu::ComputeSource(src.str());
377 if (caseDef.download == DOWNLOAD_TEXTURE)
379 const TextureFormat tcuFormat = mapVkFormat(caseDef.viewFormat);
380 const VkImageViewType viewType = getImageViewType(caseDef.imageType);
381 const std::string samplerTypeStr = getShaderSamplerType(tcuFormat, viewType);
382 const std::string imageFormatStr = getShaderImageFormatQualifier(tcuFormat);
383 const std::string imageTypeStr = getShaderImageType(tcuFormat, caseDef.imageType);
384 const std::string colorTypeStr = isUintFormat(caseDef.viewFormat) ? "uvec4" : isIntFormat(caseDef.viewFormat) ? "ivec4" : "vec4";
386 std::ostringstream src;
387 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
389 << "layout (local_size_x = 1) in;\n"
391 << "layout(binding=0) uniform " << samplerTypeStr << " u_tex;\n"
392 << "layout(binding=1, " << imageFormatStr << ") writeonly uniform " << imageTypeStr << " out_image;\n"
394 << "void main(void)\n"
396 if (caseDef.imageType == IMAGE_TYPE_2D)
398 src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n";
402 DE_ASSERT(caseDef.imageType == IMAGE_TYPE_2D_ARRAY);
403 src << " ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);\n";
405 src << " imageStore(out_image, pos, texelFetch(u_tex, pos, 0));\n"
408 programCollection.glslSources.add("downloadTextureComp") << glu::ComputeSource(src.str());
412 Move<VkImage> makeImage (const DeviceInterface& vk,
413 const VkDevice device,
414 VkImageCreateFlags flags,
415 VkImageType imageType,
416 const VkFormat format,
418 const deUint32 numMipLevels,
419 const deUint32 numLayers,
420 const VkImageUsageFlags usage)
422 const VkImageCreateInfo imageParams =
424 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
425 DE_NULL, // const void* pNext;
426 flags, // VkImageCreateFlags flags;
427 imageType, // VkImageType imageType;
428 format, // VkFormat format;
429 makeExtent3D(size), // VkExtent3D extent;
430 numMipLevels, // deUint32 mipLevels;
431 numLayers, // deUint32 arrayLayers;
432 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
433 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
434 usage, // VkImageUsageFlags usage;
435 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
436 0u, // deUint32 queueFamilyIndexCount;
437 DE_NULL, // const deUint32* pQueueFamilyIndices;
438 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
440 return createImage(vk, device, &imageParams);
443 inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize bufferSize, const VkBufferUsageFlags usage)
445 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSize, usage);
446 return createBuffer(vk, device, &bufferCreateInfo);
449 inline VkImageSubresourceRange makeColorSubresourceRange (const int baseArrayLayer, const int layerCount)
451 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, static_cast<deUint32>(baseArrayLayer), static_cast<deUint32>(layerCount));
454 Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice device)
456 const VkSamplerCreateInfo samplerParams =
458 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
459 DE_NULL, // const void* pNext;
460 (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags;
461 VK_FILTER_NEAREST, // VkFilter magFilter;
462 VK_FILTER_NEAREST, // VkFilter minFilter;
463 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
464 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
465 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
466 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
467 0.0f, // float mipLodBias;
468 VK_FALSE, // VkBool32 anisotropyEnable;
469 1.0f, // float maxAnisotropy;
470 VK_FALSE, // VkBool32 compareEnable;
471 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
472 0.0f, // float minLod;
473 0.0f, // float maxLod;
474 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
475 VK_FALSE, // VkBool32 unnormalizedCoordinates;
478 return createSampler(vk, device, &samplerParams);
482 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk,
483 const VkDevice device)
485 const VkPipelineLayoutCreateInfo info =
487 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
489 (VkPipelineLayoutCreateFlags)0,
495 return createPipelineLayout(vk, device, &info);
498 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
499 const VkDevice device,
500 const VkPipelineLayout pipelineLayout,
501 const VkRenderPass renderPass,
502 const VkShaderModule vertexModule,
503 const VkShaderModule fragmentModule,
504 const IVec2& renderSize,
505 const VkPrimitiveTopology topology,
506 const deUint32 subpass)
508 const VkVertexInputBindingDescription vertexInputBindingDescription =
510 0u, // uint32_t binding;
511 (uint32_t)(2 * sizeof(Vec4)), // uint32_t stride;
512 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
515 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
518 0u, // uint32_t location;
519 0u, // uint32_t binding;
520 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
521 0u, // uint32_t offset;
524 1u, // uint32_t location;
525 0u, // uint32_t binding;
526 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
527 (uint32_t)sizeof(Vec4), // uint32_t offset;
531 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
533 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
534 DE_NULL, // const void* pNext;
535 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
536 1u, // uint32_t vertexBindingDescriptionCount;
537 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
538 DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions), // uint32_t vertexAttributeDescriptionCount;
539 vertexInputAttributeDescriptions, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
542 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
544 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
545 DE_NULL, // const void* pNext;
546 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
547 topology, // VkPrimitiveTopology topology;
548 VK_FALSE, // VkBool32 primitiveRestartEnable;
551 const VkViewport viewport = makeViewport(
553 static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()),
556 const VkRect2D scissor =
559 makeExtent2D(renderSize.x(), renderSize.y()),
562 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
564 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
565 DE_NULL, // const void* pNext;
566 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
567 1u, // uint32_t viewportCount;
568 &viewport, // const VkViewport* pViewports;
569 1u, // uint32_t scissorCount;
570 &scissor, // const VkRect2D* pScissors;
573 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
575 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
576 DE_NULL, // const void* pNext;
577 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
578 VK_FALSE, // VkBool32 depthClampEnable;
579 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
580 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
581 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
582 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
583 VK_FALSE, // VkBool32 depthBiasEnable;
584 0.0f, // float depthBiasConstantFactor;
585 0.0f, // float depthBiasClamp;
586 0.0f, // float depthBiasSlopeFactor;
587 1.0f, // float lineWidth;
590 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
592 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
593 DE_NULL, // const void* pNext;
594 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
595 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
596 VK_FALSE, // VkBool32 sampleShadingEnable;
597 0.0f, // float minSampleShading;
598 DE_NULL, // const VkSampleMask* pSampleMask;
599 VK_FALSE, // VkBool32 alphaToCoverageEnable;
600 VK_FALSE // VkBool32 alphaToOneEnable;
603 const VkStencilOpState stencilOpState = makeStencilOpState(
604 VK_STENCIL_OP_KEEP, // stencil fail
605 VK_STENCIL_OP_ZERO, // depth & stencil pass
606 VK_STENCIL_OP_KEEP, // depth only fail
607 VK_COMPARE_OP_EQUAL, // compare op
612 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
614 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
615 DE_NULL, // const void* pNext;
616 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
617 VK_FALSE, // VkBool32 depthTestEnable;
618 VK_FALSE, // VkBool32 depthWriteEnable;
619 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
620 VK_FALSE, // VkBool32 depthBoundsTestEnable;
621 VK_FALSE, // VkBool32 stencilTestEnable;
622 stencilOpState, // VkStencilOpState front;
623 stencilOpState, // VkStencilOpState back;
624 0.0f, // float minDepthBounds;
625 1.0f, // float maxDepthBounds;
628 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
629 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
631 VK_FALSE, // VkBool32 blendEnable;
632 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
633 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
634 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
635 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
636 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
637 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
638 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
641 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
643 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
644 DE_NULL, // const void* pNext;
645 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
646 VK_FALSE, // VkBool32 logicOpEnable;
647 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
648 1u, // deUint32 attachmentCount;
649 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
650 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
653 const VkPipelineShaderStageCreateInfo pShaderStages[] =
656 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
657 DE_NULL, // const void* pNext;
658 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
659 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
660 vertexModule, // VkShaderModule module;
661 "main", // const char* pName;
662 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
665 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
666 DE_NULL, // const void* pNext;
667 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
668 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
669 fragmentModule, // VkShaderModule module;
670 "main", // const char* pName;
671 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
675 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
677 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
678 DE_NULL, // const void* pNext;
679 0u, // VkPipelineCreateFlags flags;
680 DE_LENGTH_OF_ARRAY(pShaderStages), // deUint32 stageCount;
681 pShaderStages, // const VkPipelineShaderStageCreateInfo* pStages;
682 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
683 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
684 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
685 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
686 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
687 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
688 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
689 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
690 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
691 pipelineLayout, // VkPipelineLayout layout;
692 renderPass, // VkRenderPass renderPass;
693 subpass, // deUint32 subpass;
694 DE_NULL, // VkPipeline basePipelineHandle;
695 0, // deInt32 basePipelineIndex;
698 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
701 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
702 const VkDevice device,
703 const VkPipelineLayout pipelineLayout,
704 const VkShaderModule shaderModule,
705 const VkSpecializationInfo* specInfo)
707 const VkPipelineShaderStageCreateInfo shaderStageInfo =
709 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
710 DE_NULL, // const void* pNext;
711 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
712 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
713 shaderModule, // VkShaderModule module;
714 "main", // const char* pName;
715 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
717 const VkComputePipelineCreateInfo pipelineInfo =
719 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
720 DE_NULL, // const void* pNext;
721 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
722 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage;
723 pipelineLayout, // VkPipelineLayout layout;
724 DE_NULL, // VkPipeline basePipelineHandle;
725 0, // deInt32 basePipelineIndex;
727 return createComputePipeline(vk, device, DE_NULL , &pipelineInfo);
730 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
731 const VkDevice device,
732 const VkFormat colorFormat,
733 const deUint32 numLayers)
735 const VkAttachmentDescription colorAttachmentDescription =
737 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
738 colorFormat, // VkFormat format;
739 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
740 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
741 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
742 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
743 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
744 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
745 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
747 vector<VkAttachmentDescription> attachmentDescriptions(numLayers, colorAttachmentDescription);
749 // Create a subpass for each attachment (each attachement is a layer of an arrayed image).
750 vector<VkAttachmentReference> colorAttachmentReferences (numLayers);
751 vector<VkSubpassDescription> subpasses;
753 // Ordering here must match the framebuffer attachments
754 for (deUint32 i = 0; i < numLayers; ++i)
756 const VkAttachmentReference attachmentRef =
758 i, // deUint32 attachment;
759 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
762 colorAttachmentReferences[i] = attachmentRef;
764 const VkSubpassDescription subpassDescription =
766 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
767 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
768 0u, // deUint32 inputAttachmentCount;
769 DE_NULL, // const VkAttachmentReference* pInputAttachments;
770 1u, // deUint32 colorAttachmentCount;
771 &colorAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments;
772 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
773 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
774 0u, // deUint32 preserveAttachmentCount;
775 DE_NULL // const deUint32* pPreserveAttachments;
777 subpasses.push_back(subpassDescription);
780 const VkRenderPassCreateInfo renderPassInfo =
782 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
783 DE_NULL, // const void* pNext;
784 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
785 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
786 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
787 static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount;
788 &subpasses[0], // const VkSubpassDescription* pSubpasses;
789 0u, // deUint32 dependencyCount;
790 DE_NULL // const VkSubpassDependency* pDependencies;
793 return createRenderPass(vk, device, &renderPassInfo);
796 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk,
797 const VkDevice device,
798 const VkRenderPass renderPass,
799 const deUint32 attachmentCount,
800 const VkImageView* pAttachments,
803 const VkFramebufferCreateInfo framebufferInfo =
805 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
807 (VkFramebufferCreateFlags)0,
811 static_cast<deUint32>(size.x()),
812 static_cast<deUint32>(size.y()),
816 return createFramebuffer(vk, device, &framebufferInfo);
819 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
821 return allocateCommandBuffer(vk, device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
824 MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
826 MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
827 VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
831 MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
833 MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
834 VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
838 vector<Vec4> genVertexData (const CaseDef& caseDef)
840 vector<Vec4> vectorData;
841 const bool isIntegerFormat = isUintFormat(caseDef.viewFormat) || isIntFormat(caseDef.viewFormat);
843 for (deUint32 z = 0; z < caseDef.numLayers; z++)
845 const deUint32 colorIdx = z % COLOR_TABLE_SIZE;
846 const Vec4 color = isIntegerFormat ? COLOR_TABLE_INT[colorIdx].cast<float>() : COLOR_TABLE_FLOAT[colorIdx];
848 vectorData.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
849 vectorData.push_back(color);
850 vectorData.push_back(Vec4(-1.0f, 1.0f, 0.0f, 1.0f));
851 vectorData.push_back(color);
852 vectorData.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
853 vectorData.push_back(color);
854 vectorData.push_back(Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
855 vectorData.push_back(color);
861 void generateExpectedImage(const tcu::PixelBufferAccess& image, const CaseDef& caseDef)
863 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(image.getFormat().type);
864 const bool isIntegerFormat = channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
865 const IVec2 size = caseDef.size.swizzle(0, 1);
867 for (int z = 0; z < static_cast<int>(caseDef.numLayers); z++)
869 const deUint32 colorIdx = z % COLOR_TABLE_SIZE;
870 for (int y = 0; y < size.y(); y++)
871 for (int x = 0; x < size.x(); x++)
874 image.setPixel(COLOR_TABLE_INT[colorIdx], x, y, z);
876 image.setPixel(COLOR_TABLE_FLOAT[colorIdx], x, y, z);
881 VkImageUsageFlags getImageUsageForTestCase (const CaseDef& caseDef)
883 VkImageUsageFlags flags = 0u;
885 switch (caseDef.upload)
888 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
891 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
894 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
897 flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
900 DE_ASSERT("Invalid upload method");
904 switch (caseDef.download)
906 case DOWNLOAD_TEXTURE:
907 flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
910 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
913 flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
916 DE_ASSERT("Invalid download method");
920 // We can only create a view for the image if it is going to be used for any of these usages,
921 // so let's make sure that we have at least one of them.
922 VkImageUsageFlags viewRequiredFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
923 if (!(flags & viewRequiredFlags))
924 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
929 // Executes a combination of upload/download methods
930 class UploadDownloadExecutor
933 UploadDownloadExecutor(Context &context, const CaseDef& caseSpec) :
935 m_haveMaintenance2(de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance2")),
936 m_vk(context.getDeviceInterface()),
937 m_device(context.getDevice()),
938 m_queue(context.getUniversalQueue()),
939 m_queueFamilyIndex(context.getUniversalQueueFamilyIndex()),
940 m_allocator(context.getDefaultAllocator())
944 void run(Context& context, VkBuffer buffer);
947 void uploadClear(Context& context);
948 void uploadStore(Context& context);
949 void uploadCopy(Context& context);
950 void uploadDraw(Context& context);
951 void downloadCopy(Context& context, VkBuffer buffer);
952 void downloadTexture(Context& context, VkBuffer buffer);
953 void downloadLoad(Context& context, VkBuffer buffer);
955 void copyImageToBuffer(VkImage image,
958 const VkAccessFlags srcAccessMask,
959 const VkImageLayout oldLayout,
960 const deUint32 numLayers);
962 const CaseDef& m_caseDef;
964 bool m_haveMaintenance2;
966 const DeviceInterface& m_vk;
967 const VkDevice m_device;
968 const VkQueue m_queue;
969 const deUint32 m_queueFamilyIndex;
970 Allocator& m_allocator;
972 Move<VkCommandPool> m_cmdPool;
973 Move<VkCommandBuffer> m_cmdBuffer;
975 bool m_imageIsIntegerFormat;
976 bool m_viewIsIntegerFormat;
978 // Target image for upload paths
979 Move<VkImage> m_image;
980 MovePtr<Allocation> m_imageAlloc;
985 Move<VkBuffer> colorBuffer;
986 VkDeviceSize colorBufferSize;
987 MovePtr<Allocation> colorBufferAlloc;
993 Move<VkBuffer> vertexBuffer;
994 MovePtr<Allocation> vertexBufferAlloc;
995 Move<VkPipelineLayout> pipelineLayout;
996 Move<VkRenderPass> renderPass;
997 Move<VkShaderModule> vertexModule;
998 Move<VkShaderModule> fragmentModule;
999 vector<SharedPtrVkImageView> attachments;
1000 vector<VkImageView> attachmentHandles;
1001 vector<SharedPtrVkPipeline> pipelines;
1002 Move<VkFramebuffer> framebuffer;
1008 Move<VkDescriptorPool> descriptorPool;
1009 Move<VkPipelineLayout> pipelineLayout;
1010 Move<VkDescriptorSetLayout> descriptorSetLayout;
1011 Move<VkDescriptorSet> descriptorSet;
1012 VkDescriptorImageInfo imageDescriptorInfo;
1013 Move<VkShaderModule> computeModule;
1014 Move<VkPipeline> computePipeline;
1015 Move<VkImageView> imageView;
1021 Move<VkDescriptorPool> descriptorPool;
1022 Move<VkPipelineLayout> pipelineLayout;
1023 Move<VkDescriptorSetLayout> descriptorSetLayout;
1024 Move<VkDescriptorSet> descriptorSet;
1025 Move<VkShaderModule> computeModule;
1026 Move<VkPipeline> computePipeline;
1027 Move<VkImageView> inImageView;
1028 VkDescriptorImageInfo inImageDescriptorInfo;
1029 Move<VkImage> outImage;
1030 Move<VkImageView> outImageView;
1031 MovePtr<Allocation> outImageAlloc;
1032 VkDescriptorImageInfo outImageDescriptorInfo;
1038 Move<VkDescriptorPool> descriptorPool;
1039 Move<VkPipelineLayout> pipelineLayout;
1040 Move<VkDescriptorSetLayout> descriptorSetLayout;
1041 Move<VkDescriptorSet> descriptorSet;
1042 Move<VkShaderModule> computeModule;
1043 Move<VkPipeline> computePipeline;
1044 Move<VkImageView> inImageView;
1045 VkDescriptorImageInfo inImageDescriptorInfo;
1046 Move<VkSampler> sampler;
1047 Move<VkImage> outImage;
1048 Move<VkImageView> outImageView;
1049 MovePtr<Allocation> outImageAlloc;
1050 VkDescriptorImageInfo outImageDescriptorInfo;
1053 VkImageLayout m_imageLayoutAfterUpload;
1054 VkAccessFlagBits m_imageUploadAccessMask;
1057 void UploadDownloadExecutor::run(Context& context, VkBuffer buffer)
1059 m_imageIsIntegerFormat = isUintFormat(m_caseDef.imageFormat) || isIntFormat(m_caseDef.imageFormat);
1060 m_viewIsIntegerFormat = isUintFormat(m_caseDef.viewFormat) || isIntFormat(m_caseDef.viewFormat);
1062 m_cmdPool = createCommandPool(m_vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_queueFamilyIndex);
1063 m_cmdBuffer = makeCommandBuffer(m_vk, m_device, *m_cmdPool);
1064 beginCommandBuffer(m_vk, *m_cmdBuffer);
1066 const VkImageUsageFlags imageUsage = getImageUsageForTestCase(m_caseDef);
1067 const VkImageCreateFlags imageFlags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | (m_haveMaintenance2 ? VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR : 0);
1068 m_image = makeImage(m_vk, m_device, imageFlags, getImageType(m_caseDef.imageType), m_caseDef.imageFormat, m_caseDef.size, 1u, m_caseDef.numLayers, imageUsage);
1069 m_imageAlloc = bindImage(m_vk, m_device, m_allocator, *m_image, MemoryRequirement::Any);
1071 switch (m_caseDef.upload)
1074 uploadDraw(context);
1077 uploadStore(context);
1080 uploadClear(context);
1083 uploadCopy(context);
1086 DE_ASSERT("Unsupported upload method");
1089 switch (m_caseDef.download)
1092 downloadCopy(context, buffer);
1095 downloadLoad(context, buffer);
1097 case DOWNLOAD_TEXTURE:
1098 downloadTexture(context, buffer);
1101 DE_ASSERT("Unsupported download method");
1104 VK_CHECK(m_vk.endCommandBuffer(*m_cmdBuffer));
1105 submitCommandsAndWait(m_vk, m_device, m_queue, *m_cmdBuffer);
1108 void UploadDownloadExecutor::uploadClear(Context& context)
1112 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1114 const VkImageSubresourceRange subresourceRange = makeColorSubresourceRange(0, m_caseDef.numLayers);
1115 const VkImageMemoryBarrier imageInitBarrier =
1117 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1118 DE_NULL, // const void* pNext;
1119 0u, // VkAccessFlags srcAccessMask;
1120 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAcessMask;
1121 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1122 requiredImageLayout, // VkImageLayout newLayout;
1123 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1124 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1125 *m_image, // VkImage image;
1126 subresourceRange // VkImageSubresourceRange subresourceRange;
1129 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1130 0u, DE_NULL, 0u, DE_NULL, 1u, &imageInitBarrier);
1132 for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
1134 const VkImageSubresourceRange layerSubresourceRange = makeColorSubresourceRange(layer, 1u);
1135 const deUint32 colorIdx = layer % COLOR_TABLE_SIZE;
1136 const VkClearColorValue clearColor = m_imageIsIntegerFormat ? REFERENCE_CLEAR_COLOR_INT[colorIdx].color : REFERENCE_CLEAR_COLOR_FLOAT[colorIdx].color;
1137 m_vk.cmdClearColorImage(*m_cmdBuffer, *m_image, requiredImageLayout, &clearColor, 1u, &layerSubresourceRange);
1140 m_imageLayoutAfterUpload = requiredImageLayout;
1141 m_imageUploadAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1144 void UploadDownloadExecutor::uploadStore(Context& context)
1146 const vk::VkImageViewUsageCreateInfoKHR viewUsageCreateInfo = {
1147 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1148 DE_NULL, // const void* pNext
1149 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage;
1151 m_uStore.imageView = makeImageView(m_vk, m_device, *m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1152 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1154 // Setup compute pipeline
1155 m_uStore.descriptorPool = DescriptorPoolBuilder()
1156 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1157 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1159 m_uStore.descriptorSetLayout = DescriptorSetLayoutBuilder()
1160 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1161 .build(m_vk, m_device);
1163 m_uStore.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_uStore.descriptorSetLayout);
1164 m_uStore.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_uStore.descriptorPool, *m_uStore.descriptorSetLayout);
1165 m_uStore.imageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_uStore.imageView, VK_IMAGE_LAYOUT_GENERAL);
1166 m_uStore.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadStoreComp"), 0);
1167 m_uStore.computePipeline = makeComputePipeline(m_vk, m_device, *m_uStore.pipelineLayout, *m_uStore.computeModule, DE_NULL);
1169 DescriptorSetUpdateBuilder()
1170 .writeSingle(*m_uStore.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_uStore.imageDescriptorInfo)
1171 .update(m_vk, m_device);
1173 // Transition storage image for shader access (imageStore)
1174 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1175 const VkImageMemoryBarrier imageBarrier =
1177 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1178 DE_NULL, // const void* pNext;
1179 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1180 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1181 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1182 requiredImageLayout, // VkImageLayout newLayout;
1183 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1184 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1185 *m_image, // VkImage image;
1186 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1189 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1190 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
1193 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.computePipeline);
1194 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_uStore.pipelineLayout, 0u, 1u, &m_uStore.descriptorSet.get(), 0u, DE_NULL);
1195 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1197 m_imageLayoutAfterUpload = requiredImageLayout;
1198 m_imageUploadAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
1201 void UploadDownloadExecutor::uploadCopy(Context& context)
1205 // Create a host-mappable buffer with the color data to upload
1206 const VkDeviceSize pixelSize = tcu::getPixelSize(mapVkFormat(m_caseDef.imageFormat));
1207 const VkDeviceSize layerSize = m_caseDef.size.x() * m_caseDef.size.y() * m_caseDef.size.z() * pixelSize;
1209 m_uCopy.colorBufferSize = layerSize * m_caseDef.numLayers;
1210 m_uCopy.colorBuffer = makeBuffer(m_vk, m_device, m_uCopy.colorBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
1211 m_uCopy.colorBufferAlloc = bindBuffer(m_vk, m_device, m_allocator, *m_uCopy.colorBuffer, MemoryRequirement::HostVisible);
1213 // Fill color buffer
1214 const tcu::TextureFormat tcuFormat = mapVkFormat(m_caseDef.imageFormat);
1215 VkDeviceSize layerOffset = 0ull;
1216 for (deUint32 layer = 0; layer < m_caseDef.numLayers; layer++)
1218 tcu::PixelBufferAccess imageAccess = tcu::PixelBufferAccess(tcuFormat, m_caseDef.size.x(), m_caseDef.size.y(), 1u, (deUint8*) m_uCopy.colorBufferAlloc->getHostPtr() + layerOffset);
1219 const deUint32 colorIdx = layer % COLOR_TABLE_SIZE;
1220 if (m_imageIsIntegerFormat)
1221 tcu::clear(imageAccess, COLOR_TABLE_INT[colorIdx]);
1223 tcu::clear(imageAccess, COLOR_TABLE_FLOAT[colorIdx]);
1224 layerOffset += layerSize;
1227 flushMappedMemoryRange(m_vk, m_device, m_uCopy.colorBufferAlloc->getMemory(), m_uCopy.colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
1229 // Prepare buffer and image for copy
1230 const VkBufferMemoryBarrier bufferInitBarrier =
1232 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1233 DE_NULL, // const void* pNext;
1234 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
1235 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1236 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1237 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1238 *m_uCopy.colorBuffer, // VkBuffer buffer;
1239 0ull, // VkDeviceSize offset;
1240 VK_WHOLE_SIZE, // VkDeviceSize size;
1243 const VkImageMemoryBarrier imageInitBarrier =
1245 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1246 DE_NULL, // const void* pNext;
1247 0u, // VkAccessFlags outputMask;
1248 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags inputMask;
1249 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1250 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1251 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1252 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1253 *m_image, // VkImage image;
1254 makeColorSubresourceRange(0, m_caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
1257 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1258 0u, DE_NULL, 1u, &bufferInitBarrier, 1u, &imageInitBarrier);
1260 // Copy buffer to image
1261 const VkImageSubresourceLayers subresource =
1263 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1264 0u, // uint32_t mipLevel;
1265 0u, // uint32_t baseArrayLayer;
1266 m_caseDef.numLayers, // uint32_t layerCount;
1269 const VkBufferImageCopy region =
1271 0ull, // VkDeviceSize bufferOffset;
1272 0u, // uint32_t bufferRowLength;
1273 0u, // uint32_t bufferImageHeight;
1274 subresource, // VkImageSubresourceLayers imageSubresource;
1275 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
1276 makeExtent3D(m_caseDef.size), // VkExtent3D imageExtent;
1279 m_vk.cmdCopyBufferToImage(*m_cmdBuffer, *m_uCopy.colorBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ®ion);
1281 const VkImageMemoryBarrier imagePostInitBarrier =
1283 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1284 DE_NULL, // const void* pNext;
1285 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags outputMask;
1286 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags inputMask;
1287 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1288 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1289 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1290 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1291 *m_image, // VkImage image;
1292 makeColorSubresourceRange(0, m_caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
1295 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1296 0u, DE_NULL, 0u, DE_NULL, 1u, &imagePostInitBarrier);
1298 m_imageLayoutAfterUpload = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1299 m_imageUploadAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1302 void UploadDownloadExecutor::uploadDraw(Context& context)
1304 // Create vertex buffer
1306 const vector<Vec4> vertices = genVertexData(m_caseDef);
1307 const VkDeviceSize vertexBufferSize = vertices.size() * sizeof(Vec4);
1309 m_uDraw.vertexBuffer = makeBuffer(m_vk, m_device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
1310 m_uDraw.vertexBufferAlloc = bindBuffer(m_vk, m_device, m_allocator, *m_uDraw.vertexBuffer, MemoryRequirement::HostVisible);
1311 deMemcpy(m_uDraw.vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
1312 flushMappedMemoryRange(m_vk, m_device, m_uDraw.vertexBufferAlloc->getMemory(), m_uDraw.vertexBufferAlloc->getOffset(), vertexBufferSize);
1315 // Create attachments and pipelines for each image layer
1316 m_uDraw.pipelineLayout = makePipelineLayout(m_vk, m_device);
1317 m_uDraw.renderPass = makeRenderPass(m_vk, m_device, m_caseDef.viewFormat, m_caseDef.numLayers);
1318 m_uDraw.vertexModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawVert"), 0u);
1319 m_uDraw.fragmentModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("uploadDrawFrag"), 0u);
1321 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
1323 const vk::VkImageViewUsageCreateInfoKHR viewUsageCreateInfo = {
1324 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1325 DE_NULL, // const void* pNext
1326 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags usage;
1328 Move<VkImageView> imageView = makeImageView(m_vk, m_device, *m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1329 makeColorSubresourceRange(subpassNdx, 1), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1330 m_uDraw.attachmentHandles.push_back(*imageView);
1331 m_uDraw.attachments.push_back(makeSharedPtr(imageView));
1332 m_uDraw.pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(m_vk, m_device, *m_uDraw.pipelineLayout, *m_uDraw.renderPass, *m_uDraw.vertexModule, *m_uDraw.fragmentModule,
1333 m_caseDef.size.swizzle(0, 1), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, subpassNdx)));
1336 // Create framebuffer
1337 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));
1339 // Create command buffer
1342 vector<VkClearValue> clearValues (m_caseDef.numLayers, m_viewIsIntegerFormat ? REFERENCE_CLEAR_COLOR_INT[0] : REFERENCE_CLEAR_COLOR_FLOAT[0]);
1344 const VkRect2D renderArea =
1347 makeExtent2D(m_caseDef.size.x(), m_caseDef.size.y()),
1350 const VkRenderPassBeginInfo renderPassBeginInfo =
1352 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1353 DE_NULL, // const void* pNext;
1354 *m_uDraw.renderPass, // VkRenderPass renderPass;
1355 *m_uDraw.framebuffer, // VkFramebuffer framebuffer;
1356 renderArea, // VkRect2D renderArea;
1357 static_cast<deUint32>(clearValues.size()), // uint32_t clearValueCount;
1358 &clearValues[0], // const VkClearValue* pClearValues;
1361 m_vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1365 const VkDeviceSize vertexDataPerDraw = 4 * 2 * sizeof(Vec4);
1366 VkDeviceSize vertexBufferOffset = 0ull;
1367 for (deUint32 subpassNdx = 0; subpassNdx < m_caseDef.numLayers; ++subpassNdx)
1369 if (subpassNdx != 0)
1370 m_vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
1372 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_uDraw.pipelines[subpassNdx]);
1374 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_uDraw.vertexBuffer.get(), &vertexBufferOffset);
1375 m_vk.cmdDraw(*m_cmdBuffer, 4u, 1u, 0u, 0u);
1376 vertexBufferOffset += vertexDataPerDraw;
1379 m_vk.cmdEndRenderPass(*m_cmdBuffer);
1382 m_imageLayoutAfterUpload = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1383 m_imageUploadAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1386 void UploadDownloadExecutor::downloadCopy(Context& context, VkBuffer buffer)
1390 copyImageToBuffer(*m_image, buffer, m_caseDef.size, m_imageUploadAccessMask, m_imageLayoutAfterUpload, m_caseDef.numLayers);
1393 void UploadDownloadExecutor::downloadTexture(Context& context, VkBuffer buffer)
1395 // Create output image with download result
1396 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1397 m_dTex.outImage = makeImage(m_vk, m_device, 0u, VK_IMAGE_TYPE_2D, m_caseDef.viewFormat, m_caseDef.size, 1u, m_caseDef.numLayers, usageFlags);
1398 m_dTex.outImageAlloc = bindImage(m_vk, m_device, m_allocator, *m_dTex.outImage, MemoryRequirement::Any);
1399 m_dTex.outImageView = makeImageView(m_vk, m_device, *m_dTex.outImage, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat, makeColorSubresourceRange(0, m_caseDef.numLayers));
1401 const vk::VkImageViewUsageCreateInfoKHR 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.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::VkImageViewUsageCreateInfoKHR viewUsageCreateInfo = {
1483 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, // VkStructureType sType
1484 DE_NULL, // const void* pNext
1485 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage;
1487 m_dLoad.inImageView = makeImageView(m_vk, m_device, *m_image, getImageViewType(m_caseDef.imageType), m_caseDef.viewFormat,
1488 makeColorSubresourceRange(0, m_caseDef.numLayers), m_haveMaintenance2 ? &viewUsageCreateInfo : DE_NULL);
1490 // Setup compute pipeline
1491 m_dLoad.descriptorPool = DescriptorPoolBuilder()
1492 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2u)
1493 .build(m_vk, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1495 m_dLoad.descriptorSetLayout = DescriptorSetLayoutBuilder()
1496 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1497 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1498 .build(m_vk, m_device);
1500 m_dLoad.pipelineLayout = makePipelineLayout(m_vk, m_device, *m_dLoad.descriptorSetLayout);
1501 m_dLoad.descriptorSet = makeDescriptorSet(m_vk, m_device, *m_dLoad.descriptorPool, *m_dLoad.descriptorSetLayout);
1502 m_dLoad.inImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dLoad.inImageView, VK_IMAGE_LAYOUT_GENERAL);
1503 m_dLoad.outImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *m_dLoad.outImageView, VK_IMAGE_LAYOUT_GENERAL);
1504 m_dLoad.computeModule = createShaderModule(m_vk, m_device, context.getBinaryCollection().get("downloadLoadComp"), 0);
1505 m_dLoad.computePipeline = makeComputePipeline(m_vk, m_device, *m_dLoad.pipelineLayout, *m_dLoad.computeModule, DE_NULL);
1507 DescriptorSetUpdateBuilder()
1508 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.inImageDescriptorInfo)
1509 .writeSingle(*m_dLoad.descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &m_dLoad.outImageDescriptorInfo)
1510 .update(m_vk, m_device);
1512 // Transition storage images for shader access (imageLoad/Store)
1513 VkImageLayout requiredImageLayout = VK_IMAGE_LAYOUT_GENERAL;
1514 const VkImageMemoryBarrier imageBarriers[] =
1517 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1518 DE_NULL, // const void* pNext;
1519 (VkAccessFlags)m_imageUploadAccessMask, // VkAccessFlags srcAccessMask;
1520 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
1521 m_imageLayoutAfterUpload, // VkImageLayout oldLayout;
1522 requiredImageLayout, // VkImageLayout newLayout;
1523 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1524 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1525 *m_image, // VkImage image;
1526 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1529 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1530 DE_NULL, // const void* pNext;
1531 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
1532 (VkAccessFlags)VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1533 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1534 requiredImageLayout, // VkImageLayout newLayout;
1535 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1536 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1537 *m_dLoad.outImage, // VkImage image;
1538 makeColorSubresourceRange(0, m_caseDef.numLayers), // VkImageSubresourceRange subresourceRange;
1542 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u,
1543 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
1546 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.computePipeline);
1547 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_dLoad.pipelineLayout, 0u, 1u, &m_dLoad.descriptorSet.get(), 0u, DE_NULL);
1548 m_vk.cmdDispatch(*m_cmdBuffer, m_caseDef.size.x(), m_caseDef.size.y(), m_caseDef.numLayers);
1550 // Copy output image to color buffer
1551 copyImageToBuffer(*m_dLoad.outImage, buffer, m_caseDef.size, VK_ACCESS_SHADER_WRITE_BIT, requiredImageLayout, m_caseDef.numLayers);
1554 void UploadDownloadExecutor::copyImageToBuffer(VkImage sourceImage,
1557 const VkAccessFlags srcAccessMask,
1558 const VkImageLayout oldLayout,
1559 const deUint32 numLayers)
1561 // Copy result to host visible buffer for inspection
1562 const VkImageMemoryBarrier imageBarrier =
1564 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1565 DE_NULL, // const void* pNext;
1566 srcAccessMask, // VkAccessFlags outputMask;
1567 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags inputMask;
1568 oldLayout, // VkImageLayout oldLayout;
1569 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
1570 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1571 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
1572 sourceImage, // VkImage image;
1573 makeColorSubresourceRange(0, numLayers) // VkImageSubresourceRange subresourceRange;
1576 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
1577 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
1579 const VkImageSubresourceLayers subresource =
1581 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1582 0u, // uint32_t mipLevel;
1583 0u, // uint32_t baseArrayLayer;
1584 numLayers, // uint32_t layerCount;
1587 const VkBufferImageCopy region =
1589 0ull, // VkDeviceSize bufferOffset;
1590 0u, // uint32_t bufferRowLength;
1591 0u, // uint32_t bufferImageHeight;
1592 subresource, // VkImageSubresourceLayers imageSubresource;
1593 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
1594 makeExtent3D(size), // VkExtent3D imageExtent;
1597 m_vk.cmdCopyImageToBuffer(*m_cmdBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, ®ion);
1599 const VkBufferMemoryBarrier bufferBarrier =
1601 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1602 DE_NULL, // const void* pNext;
1603 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1604 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
1605 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1606 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1607 buffer, // VkBuffer buffer;
1608 0ull, // VkDeviceSize offset;
1609 VK_WHOLE_SIZE, // VkDeviceSize size;
1612 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
1613 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
1616 bool isStorageImageExtendedFormat (const VkFormat format)
1620 case VK_FORMAT_R32G32_SFLOAT:
1621 case VK_FORMAT_R32G32_SINT:
1622 case VK_FORMAT_R32G32_UINT:
1623 case VK_FORMAT_R16G16B16A16_UNORM:
1624 case VK_FORMAT_R16G16B16A16_SNORM:
1625 case VK_FORMAT_R16G16_SFLOAT:
1626 case VK_FORMAT_R16G16_UNORM:
1627 case VK_FORMAT_R16G16_SNORM:
1628 case VK_FORMAT_R16G16_SINT:
1629 case VK_FORMAT_R16G16_UINT:
1630 case VK_FORMAT_R16_SFLOAT:
1631 case VK_FORMAT_R16_UNORM:
1632 case VK_FORMAT_R16_SNORM:
1633 case VK_FORMAT_R16_SINT:
1634 case VK_FORMAT_R16_UINT:
1635 case VK_FORMAT_R8G8_UNORM:
1636 case VK_FORMAT_R8G8_SNORM:
1637 case VK_FORMAT_R8G8_SINT:
1638 case VK_FORMAT_R8G8_UINT:
1639 case VK_FORMAT_R8_UNORM:
1640 case VK_FORMAT_R8_SNORM:
1641 case VK_FORMAT_R8_SINT:
1642 case VK_FORMAT_R8_UINT:
1650 tcu::TestStatus testMutable (Context& context, const CaseDef caseDef)
1652 const DeviceInterface& vk = context.getDeviceInterface();
1653 const InstanceInterface& vki = context.getInstanceInterface();
1654 const VkDevice device = context.getDevice();
1655 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
1656 Allocator& allocator = context.getDefaultAllocator();
1658 // Check required features on the format for the required upload/download methods
1659 VkFormatProperties imageFormatProps, viewFormatProps;
1660 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.imageFormat, &imageFormatProps);
1661 vki.getPhysicalDeviceFormatProperties(physDevice, caseDef.viewFormat, &viewFormatProps);
1663 VkFormatFeatureFlags viewFormatFeatureFlags = 0u;
1664 switch (caseDef.upload)
1667 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
1670 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1673 DE_ASSERT("Invalid upload method");
1676 switch (caseDef.download)
1678 case DOWNLOAD_TEXTURE:
1679 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
1680 // For the texture case we write the samples read to a separate output image with the same view format
1681 // so we need to check that we can also use the view format for storage
1682 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1685 viewFormatFeatureFlags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1688 DE_ASSERT("Invalid download method");
1692 if ((viewFormatFeatureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) &&
1693 isStorageImageExtendedFormat(caseDef.viewFormat) &&
1694 !getPhysicalDeviceFeatures(vki, physDevice).shaderStorageImageExtendedFormats)
1696 TCU_THROW(NotSupportedError, "View format requires shaderStorageImageExtended");
1699 if ((viewFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags)
1700 TCU_THROW(NotSupportedError, "View format doesn't support upload/download method");
1702 // We don't use the base image for anything other than transfer
1703 // operations so there are no features to check. However, The Vulkan
1704 // 1.0 spec does not allow us to create an image view with usage that
1705 // is not supported by the main format. With VK_KHR_maintenance2, we
1706 // can do this via VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR.
1707 if ((imageFormatProps.optimalTilingFeatures & viewFormatFeatureFlags) != viewFormatFeatureFlags &&
1708 !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance2"))
1710 TCU_THROW(NotSupportedError, "Image format doesn't support upload/download method");
1713 // Create a color buffer for host-inspection of results
1714 // For the Copy download method, this is the target of the download, for other
1715 // download methods, pixel data will be copied to this buffer from the download
1717 const VkDeviceSize colorBufferSize = caseDef.size.x() * caseDef.size.y() * caseDef.size.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.imageFormat));
1718 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1719 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1720 deMemset(colorBufferAlloc->getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
1721 flushMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
1724 UploadDownloadExecutor executor(context, caseDef);
1725 executor.run(context, *colorBuffer);
1729 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
1731 // For verification purposes, we use the format of the upload to generate the expected image
1732 const VkFormat format = caseDef.upload == UPLOAD_CLEAR || caseDef.upload == UPLOAD_COPY ? caseDef.imageFormat : caseDef.viewFormat;
1733 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
1734 const bool isIntegerFormat = isUintFormat(format) || isIntFormat(format);
1735 const tcu::ConstPixelBufferAccess resultImage (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers, colorBufferAlloc->getHostPtr());
1736 tcu::TextureLevel textureLevel (tcuFormat, caseDef.size.x(), caseDef.size.y(), caseDef.numLayers);
1737 const tcu::PixelBufferAccess expectedImage = textureLevel.getAccess();
1738 generateExpectedImage(expectedImage, caseDef);
1741 if (isIntegerFormat)
1742 ok = tcu::intThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
1744 ok = tcu::floatThresholdCompare(context.getTestContext().getLog(), "Image comparison", "", expectedImage, resultImage, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
1745 return ok ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Fail");
1749 tcu::TestCaseGroup* createImageMutableTests (TestContext& testCtx)
1751 de::MovePtr<TestCaseGroup> testGroup (new TestCaseGroup(testCtx, "mutable", "Cases with mutable images"));
1752 for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx)
1754 const Texture& texture = s_textures[textureNdx];
1755 de::MovePtr<tcu::TestCaseGroup> groupByImageViewType (new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str(), ""));
1757 for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++imageFormatNdx)
1758 for (int viewFormatNdx = 0; viewFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++viewFormatNdx)
1760 if (imageFormatNdx != viewFormatNdx && formatsAreCompatible(s_formats[imageFormatNdx], s_formats[viewFormatNdx]))
1762 for (int upload = 0; upload < UPLOAD_LAST; upload++)
1763 for (int download = 0; download < DOWNLOAD_LAST; download++)
1765 const CaseDef caseDef =
1768 texture.layerSize(),
1769 static_cast<deUint32>(texture.numLayers()),
1770 s_formats[imageFormatNdx],
1771 s_formats[viewFormatNdx],
1772 static_cast<enum Upload>(upload),
1773 static_cast<enum Download>(download)
1776 const std::string caseName = getFormatShortString(s_formats[imageFormatNdx]) + "_" + getFormatShortString(s_formats[viewFormatNdx]) +
1777 "_" + getUploadString(upload) + "_" + getDownloadString(download);
1778 addFunctionCaseWithPrograms(groupByImageViewType.get(), caseName, "", initPrograms, testMutable, caseDef);
1783 testGroup->addChild(groupByImageViewType.release());
1786 return testGroup.release();