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.
20 * \file vktPipelineRenderToImageTests.cpp
21 * \brief Render to image tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktPipelineRenderToImageTests.hpp"
25 #include "vktPipelineMakeUtil.hpp"
26 #include "vktTestCase.hpp"
27 #include "vktTestCaseUtil.hpp"
28 #include "vktPipelineVertexUtil.hpp"
29 #include "vktTestGroupUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkBuilderUtil.hpp"
36 #include "vkPrograms.hpp"
37 #include "vkImageUtil.hpp"
39 #include "tcuTextureUtil.hpp"
40 #include "tcuImageCompare.hpp"
42 #include "deUniquePtr.hpp"
43 #include "deSharedPtr.hpp"
64 typedef SharedPtr<Unique<VkImageView> > SharedPtrVkImageView;
65 typedef SharedPtr<Unique<VkPipeline> > SharedPtrVkPipeline;
69 REFERENCE_COLOR_VALUE = 125
74 VkImageViewType imageType;
81 inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move)
83 return SharedPtr<Unique<T> >(new Unique<T>(move));
87 inline VkDeviceSize sizeInBytes (const vector<T>& vec)
89 return vec.size() * sizeof(vec[0]);
92 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
93 const VkDevice device,
94 const VkPipelineLayout pipelineLayout,
95 const VkRenderPass renderPass,
96 const VkShaderModule vertexModule,
97 const VkShaderModule fragmentModule,
98 const IVec3 renderSize,
99 const VkPrimitiveTopology topology,
100 const deUint32 subpass)
102 const VkVertexInputBindingDescription vertexInputBindingDescription =
104 0u, // uint32_t binding;
105 sizeof(Vertex4RGBA), // uint32_t stride;
106 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
109 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
112 0u, // uint32_t location;
113 0u, // uint32_t binding;
114 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
115 0u, // uint32_t offset;
118 1u, // uint32_t location;
119 0u, // uint32_t binding;
120 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
121 sizeof(Vec4), // uint32_t offset;
125 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
127 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
128 DE_NULL, // const void* pNext;
129 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
130 1u, // uint32_t vertexBindingDescriptionCount;
131 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
132 DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions), // uint32_t vertexAttributeDescriptionCount;
133 vertexInputAttributeDescriptions, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
136 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
138 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
139 DE_NULL, // const void* pNext;
140 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
141 topology, // VkPrimitiveTopology topology;
142 VK_FALSE, // VkBool32 primitiveRestartEnable;
145 const VkViewport viewport = makeViewport(
147 static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()),
150 const VkRect2D scissor =
153 makeExtent2D(renderSize.x(), renderSize.y()),
156 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
158 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
159 DE_NULL, // const void* pNext;
160 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
161 1u, // uint32_t viewportCount;
162 &viewport, // const VkViewport* pViewports;
163 1u, // uint32_t scissorCount;
164 &scissor, // const VkRect2D* pScissors;
167 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
169 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
170 DE_NULL, // const void* pNext;
171 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
172 VK_FALSE, // VkBool32 depthClampEnable;
173 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
174 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
175 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
176 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
177 VK_FALSE, // VkBool32 depthBiasEnable;
178 0.0f, // float depthBiasConstantFactor;
179 0.0f, // float depthBiasClamp;
180 0.0f, // float depthBiasSlopeFactor;
181 1.0f, // float lineWidth;
184 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
186 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
187 DE_NULL, // const void* pNext;
188 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
189 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
190 VK_FALSE, // VkBool32 sampleShadingEnable;
191 0.0f, // float minSampleShading;
192 DE_NULL, // const VkSampleMask* pSampleMask;
193 VK_FALSE, // VkBool32 alphaToCoverageEnable;
194 VK_FALSE // VkBool32 alphaToOneEnable;
197 const VkStencilOpState stencilOpState = makeStencilOpState(
198 VK_STENCIL_OP_KEEP, // stencil fail
199 VK_STENCIL_OP_KEEP, // depth & stencil pass
200 VK_STENCIL_OP_KEEP, // depth only fail
201 VK_COMPARE_OP_ALWAYS, // compare op
206 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
208 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
209 DE_NULL, // const void* pNext;
210 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
211 VK_FALSE, // VkBool32 depthTestEnable;
212 VK_FALSE, // VkBool32 depthWriteEnable;
213 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
214 VK_FALSE, // VkBool32 depthBoundsTestEnable;
215 VK_FALSE, // VkBool32 stencilTestEnable;
216 stencilOpState, // VkStencilOpState front;
217 stencilOpState, // VkStencilOpState back;
218 0.0f, // float minDepthBounds;
219 1.0f, // float maxDepthBounds;
222 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
223 // Number of blend attachments must equal the number of color attachments during any subpass.
224 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
226 VK_FALSE, // VkBool32 blendEnable;
227 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
228 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
229 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
230 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
231 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
232 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
233 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
236 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
238 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
239 DE_NULL, // const void* pNext;
240 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
241 VK_FALSE, // VkBool32 logicOpEnable;
242 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
243 1u, // deUint32 attachmentCount;
244 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
245 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
248 const VkPipelineShaderStageCreateInfo pShaderStages[] =
251 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
252 DE_NULL, // const void* pNext;
253 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
254 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
255 vertexModule, // VkShaderModule module;
256 "main", // const char* pName;
257 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
260 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
261 DE_NULL, // const void* pNext;
262 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
263 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
264 fragmentModule, // VkShaderModule module;
265 "main", // const char* pName;
266 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
270 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
272 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
273 DE_NULL, // const void* pNext;
274 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
275 DE_LENGTH_OF_ARRAY(pShaderStages), // deUint32 stageCount;
276 pShaderStages, // const VkPipelineShaderStageCreateInfo* pStages;
277 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
278 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
279 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
280 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
281 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
282 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
283 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
284 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
285 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
286 pipelineLayout, // VkPipelineLayout layout;
287 renderPass, // VkRenderPass renderPass;
288 subpass, // deUint32 subpass;
289 DE_NULL, // VkPipeline basePipelineHandle;
290 0, // deInt32 basePipelineIndex;
293 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
296 //! Make a render pass with one subpass per color attachment and one attachment per image layer.
297 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
298 const VkDevice device,
299 const VkFormat colorFormat,
300 const deUint32 numLayers,
301 const VkImageLayout initialColorImageLayout = VK_IMAGE_LAYOUT_UNDEFINED)
303 const VkAttachmentDescription colorAttachmentDescription =
305 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
306 colorFormat, // VkFormat format;
307 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
308 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
309 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
310 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
311 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
312 initialColorImageLayout, // VkImageLayout initialLayout;
313 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
315 const vector<VkAttachmentDescription> attachmentDescriptions(numLayers, colorAttachmentDescription);
317 // Create a subpass for each attachment (each attachement is a layer of an arrayed image).
318 vector<VkAttachmentReference> colorAttachmentReferences(numLayers);
319 vector<VkSubpassDescription> subpasses;
321 for (deUint32 i = 0; i < numLayers; ++i)
323 const VkAttachmentReference attachmentRef =
325 i, // deUint32 attachment;
326 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
328 colorAttachmentReferences[i] = attachmentRef;
330 const VkSubpassDescription subpassDescription =
332 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
333 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
334 0u, // deUint32 inputAttachmentCount;
335 DE_NULL, // const VkAttachmentReference* pInputAttachments;
336 1u, // deUint32 colorAttachmentCount;
337 &colorAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments;
338 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
339 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
340 0u, // deUint32 preserveAttachmentCount;
341 DE_NULL // const deUint32* pPreserveAttachments;
343 subpasses.push_back(subpassDescription);
346 const VkRenderPassCreateInfo renderPassInfo =
348 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
349 DE_NULL, // const void* pNext;
350 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
351 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
352 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
353 static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount;
354 &subpasses[0], // const VkSubpassDescription* pSubpasses;
355 0u, // deUint32 dependencyCount;
356 DE_NULL // const VkSubpassDependency* pDependencies;
359 return createRenderPass(vk, device, &renderPassInfo);
362 Move<VkImage> makeImage (const DeviceInterface& vk,
363 const VkDevice device,
364 VkImageCreateFlags flags,
365 VkImageType imageType,
366 const VkFormat format,
368 const deUint32 numLayers,
369 const VkImageUsageFlags usage)
371 const VkImageCreateInfo imageParams =
373 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
374 DE_NULL, // const void* pNext;
375 flags, // VkImageCreateFlags flags;
376 imageType, // VkImageType imageType;
377 format, // VkFormat format;
378 makeExtent3D(size), // VkExtent3D extent;
379 1u, // deUint32 mipLevels;
380 numLayers, // deUint32 arrayLayers;
381 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
382 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
383 usage, // VkImageUsageFlags usage;
384 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
385 0u, // deUint32 queueFamilyIndexCount;
386 DE_NULL, // const deUint32* pQueueFamilyIndices;
387 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
389 return createImage(vk, device, &imageParams);
392 inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize bufferSize, const VkBufferUsageFlags usage)
394 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSize, usage);
395 return createBuffer(vk, device, &bufferCreateInfo);
398 inline VkImageSubresourceRange makeColorSubresourceRange (const int baseArrayLayer, const int layerCount)
400 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, static_cast<deUint32>(baseArrayLayer), static_cast<deUint32>(layerCount));
403 //! Get a reference clear value based on color format.
404 VkClearValue getClearValue (const VkFormat format)
406 if (isUintFormat(format) || isIntFormat(format))
407 return makeClearValueColorU32(REFERENCE_COLOR_VALUE, REFERENCE_COLOR_VALUE, REFERENCE_COLOR_VALUE, REFERENCE_COLOR_VALUE);
409 return makeClearValueColorF32(1.0f, 1.0f, 1.0f, 1.0f);
412 std::string getColorFormatStr (const int numComponents, const bool isUint, const bool isSint)
414 std::ostringstream str;
415 if (numComponents == 1)
416 str << (isUint ? "uint" : isSint ? "int" : "float");
418 str << (isUint ? "u" : isSint ? "i" : "") << "vec" << numComponents;
423 //! A half-viewport quad. Use with TRIANGLE_STRIP topology.
424 vector<Vertex4RGBA> genFullQuadVertices (const int subpassCount, const vector<Vec4>& color)
426 vector<Vertex4RGBA> vectorData;
427 for (int subpassNdx = 0; subpassNdx < subpassCount; ++subpassNdx)
431 Vec4(0.0f, -1.0f, 0.0f, 1.0f),
432 color[subpassNdx % color.size()],
434 vectorData.push_back(data);
435 data.position = Vec4(0.0f, 1.0f, 0.0f, 1.0f);
436 vectorData.push_back(data);
437 data.position = Vec4(1.0f, -1.0f, 0.0f, 1.0f);
438 vectorData.push_back(data);
439 data.position = Vec4(1.0f, 1.0f, 0.0f, 1.0f);
440 vectorData.push_back(data);
445 VkImageType getImageType (const VkImageViewType viewType)
449 case VK_IMAGE_VIEW_TYPE_1D:
450 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
451 return VK_IMAGE_TYPE_1D;
453 case VK_IMAGE_VIEW_TYPE_2D:
454 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
455 case VK_IMAGE_VIEW_TYPE_CUBE:
456 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
457 return VK_IMAGE_TYPE_2D;
459 case VK_IMAGE_VIEW_TYPE_3D:
460 return VK_IMAGE_TYPE_3D;
464 return VK_IMAGE_TYPE_LAST;
468 void initPrograms (SourceCollections& programCollection, const CaseDef caseDef)
470 const int numComponents = getNumUsedChannels(mapVkFormat(caseDef.colorFormat).order);
471 const bool isUint = isUintFormat(caseDef.colorFormat);
472 const bool isSint = isIntFormat(caseDef.colorFormat);
476 std::ostringstream src;
477 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
479 << "layout(location = 0) in vec4 in_position;\n"
480 << "layout(location = 1) in vec4 in_color;\n"
481 << "layout(location = 0) out vec4 out_color;\n"
483 << "out gl_PerVertex {\n"
484 << " vec4 gl_Position;\n"
487 << "void main(void)\n"
489 << " gl_Position = in_position;\n"
490 << " out_color = in_color;\n"
493 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
498 std::ostringstream colorValue;
499 colorValue << REFERENCE_COLOR_VALUE;
500 const std::string colorFormat = getColorFormatStr(numComponents, isUint, isSint);
501 const std::string colorInteger = (isUint || isSint ? " * "+colorFormat+"("+colorValue.str()+")" :"");
503 std::ostringstream src;
504 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
506 << "layout(location = 0) in vec4 in_color;\n"
507 << "layout(location = 0) out " << colorFormat << " o_color;\n"
509 << "void main(void)\n"
511 << " o_color = " << colorFormat << "("
512 << (numComponents == 1 ? "in_color.r" :
513 numComponents == 2 ? "in_color.rg" :
514 numComponents == 3 ? "in_color.rgb" : "in_color")
519 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
523 tcu::PixelBufferAccess getExpectedData (tcu::TextureLevel& textureLevel, const CaseDef& caseDef, const Vec4* color, const int sizeColor)
525 const bool isInt = isUintFormat(caseDef.colorFormat) || isIntFormat(caseDef.colorFormat);
526 const tcu::PixelBufferAccess expectedImage (textureLevel);
529 tcu::clear(expectedImage, tcu::IVec4(REFERENCE_COLOR_VALUE));
531 tcu::clear(expectedImage, tcu::Vec4(1.0));
533 for (int z = 0; z < expectedImage.getDepth(); ++z)
535 const Vec4& setColor = color[z % sizeColor];
536 const IVec4 setColorInt = (static_cast<float>(REFERENCE_COLOR_VALUE) * setColor).cast<deInt32>();
538 for (int y = 0; y < caseDef.renderSize.y(); ++y)
539 for (int x = caseDef.renderSize.x()/2; x < caseDef.renderSize.x(); ++x)
542 expectedImage.setPixel(setColorInt, x, y, z);
544 expectedImage.setPixel(setColor, x, y, z);
547 return expectedImage;
550 tcu::TestStatus test (Context& context, const CaseDef caseDef)
552 if (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType &&
553 (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance1")))
554 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
556 const DeviceInterface& vk = context.getDeviceInterface();
557 const VkDevice device = context.getDevice();
558 const VkQueue queue = context.getUniversalQueue();
559 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
560 Allocator& allocator = context.getDefaultAllocator();
561 Move<VkImage> colorImage;
562 MovePtr<Allocation> colorImageAlloc;
565 Vec4(0.9f, 0.0f, 0.0f, 1.0f),
566 Vec4(0.6f, 1.0f, 0.0f, 1.0f),
567 Vec4(0.3f, 0.0f, 1.0f, 1.0f),
568 Vec4(0.1f, 0.0f, 1.0f, 1.0f)
571 const int numLayers = (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType ? caseDef.renderSize.z() : caseDef.numLayers);
572 const VkDeviceSize colorBufferSize = caseDef.renderSize.x() * caseDef.renderSize.y() * caseDef.renderSize.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.colorFormat));
573 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
574 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
576 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, context.getBinaryCollection().get("vert"), 0u));
577 const Unique<VkShaderModule> fragmentModule (createShaderModule (vk, device, context.getBinaryCollection().get("frag"), 0u));
578 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, caseDef.colorFormat, static_cast<deUint32>(numLayers),
579 (caseDef.imageType == VK_IMAGE_VIEW_TYPE_3D) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
580 : VK_IMAGE_LAYOUT_UNDEFINED));
581 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout (vk, device));
582 vector<SharedPtrVkPipeline> pipeline;
583 const Unique<VkCommandPool> cmdPool (makeCommandPool (vk, device, queueFamilyIndex));
584 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool));
586 vector<SharedPtrVkImageView> colorAttachments;
587 vector<VkImageView> attachmentHandles;
588 Move<VkBuffer> vertexBuffer;
589 MovePtr<Allocation> vertexBufferAlloc;
590 Move<VkFramebuffer> framebuffer;
594 const VkImageViewCreateFlags flags = (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType ? (VkImageViewCreateFlags)VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR : (VkImageViewCreateFlags)0);
595 const VkImageUsageFlags colorImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
596 colorImage = makeImage(vk, device, flags, getImageType(caseDef.imageType), caseDef.colorFormat, caseDef.renderSize, caseDef.numLayers, colorImageUsage);
597 colorImageAlloc = bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any);
600 //create vertexBuffer
602 const vector<Vertex4RGBA> vertices = genFullQuadVertices(numLayers, vector<Vec4>(color, color + DE_LENGTH_OF_ARRAY(color)));
603 const VkDeviceSize vertexBufferSize = sizeInBytes(vertices);
605 vertexBuffer = makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
606 vertexBufferAlloc = bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible);
607 deMemcpy(vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
608 flushMappedMemoryRange(vk, device, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexBufferSize);
611 //create attachmentHandles and pipelines
612 for (int layerNdx = 0; layerNdx < numLayers; ++layerNdx)
614 const VkImageViewType imageType = (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType ? VK_IMAGE_VIEW_TYPE_2D_ARRAY :
615 (VK_IMAGE_VIEW_TYPE_CUBE == caseDef.imageType || VK_IMAGE_VIEW_TYPE_CUBE_ARRAY == caseDef.imageType ? VK_IMAGE_VIEW_TYPE_2D :
618 colorAttachments.push_back(makeSharedPtr(makeImageView(vk, device, *colorImage, imageType, caseDef.colorFormat, makeColorSubresourceRange(layerNdx, 1))));
619 attachmentHandles.push_back(**colorAttachments.back());
621 pipeline.push_back(makeSharedPtr(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule,
622 caseDef.renderSize, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, static_cast<deUint32>(layerNdx))));
625 framebuffer = makeFramebuffer(vk, device, *renderPass, numLayers, &attachmentHandles[0], static_cast<deUint32>(caseDef.renderSize.x()), static_cast<deUint32>(caseDef.renderSize.y()));
627 beginCommandBuffer(vk, *cmdBuffer);
629 // Prepare color image upfront for rendering to individual slices. 3D slices aren't separate subresources, so they shouldn't be transitioned
630 // during each subpass like array layers.
631 if (caseDef.imageType == VK_IMAGE_VIEW_TYPE_3D)
633 const VkImageMemoryBarrier imageBarrier =
635 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
636 DE_NULL, // const void* pNext;
637 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
638 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
639 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
640 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
641 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
642 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
643 *colorImage, // VkImage image;
644 makeColorSubresourceRange(0, caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
647 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u,
648 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
652 const vector<VkClearValue> clearValues (numLayers, getClearValue(caseDef.colorFormat));
653 const VkRect2D renderArea =
656 makeExtent2D(caseDef.renderSize.x(), caseDef.renderSize.y()),
658 const VkRenderPassBeginInfo renderPassBeginInfo =
660 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
661 DE_NULL, // const void* pNext;
662 *renderPass, // VkRenderPass renderPass;
663 *framebuffer, // VkFramebuffer framebuffer;
664 renderArea, // VkRect2D renderArea;
665 static_cast<deUint32>(clearValues.size()), // uint32_t clearValueCount;
666 &clearValues[0], // const VkClearValue* pClearValues;
668 const VkDeviceSize vertexBufferOffset = 0ull;
670 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
671 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
675 for (deUint32 layerNdx = 0; layerNdx < static_cast<deUint32>(numLayers); ++layerNdx)
678 vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
680 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipeline[layerNdx]);
681 vk.cmdDraw(*cmdBuffer, 4u, 1u, layerNdx*4u, 0u);
684 vk.cmdEndRenderPass(*cmdBuffer);
686 // copy colorImage -> host visible colorBuffer
688 const VkImageMemoryBarrier imageBarriers[] =
691 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
692 DE_NULL, // const void* pNext;
693 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags outputMask;
694 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags inputMask;
695 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
696 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
697 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
698 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
699 *colorImage, // VkImage image;
700 makeColorSubresourceRange(0, caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
704 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
705 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
707 const VkBufferImageCopy region =
709 0ull, // VkDeviceSize bufferOffset;
710 0u, // uint32_t bufferRowLength;
711 0u, // uint32_t bufferImageHeight;
712 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, caseDef.numLayers), // VkImageSubresourceLayers imageSubresource;
713 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
714 makeExtent3D(caseDef.renderSize), // VkExtent3D imageExtent;
717 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ®ion);
719 const VkBufferMemoryBarrier bufferBarriers[] =
722 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
723 DE_NULL, // const void* pNext;
724 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
725 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
726 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
727 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
728 *colorBuffer, // VkBuffer buffer;
729 0ull, // VkDeviceSize offset;
730 VK_WHOLE_SIZE, // VkDeviceSize size;
734 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
735 0u, DE_NULL, DE_LENGTH_OF_ARRAY(bufferBarriers), bufferBarriers, 0u, DE_NULL);
738 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
739 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
743 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
745 const tcu::TextureFormat format = mapVkFormat(caseDef.colorFormat);
746 const int depth = deMax32(caseDef.renderSize.z(), caseDef.numLayers);
747 tcu::TextureLevel textureLevel (format, caseDef.renderSize.x(), caseDef.renderSize.y(), depth);
748 const tcu::PixelBufferAccess expectedImage = getExpectedData (textureLevel, caseDef, color, DE_LENGTH_OF_ARRAY(color));
749 const tcu::ConstPixelBufferAccess resultImage (format, caseDef.renderSize.x(), caseDef.renderSize.y(), depth, colorBufferAlloc->getHostPtr());
751 if (!tcu::intThresholdCompare(context.getTestContext().getLog(), "Image Comparison", "", expectedImage, resultImage, tcu::UVec4(2), tcu::COMPARE_LOG_RESULT))
752 return tcu::TestStatus::fail("Fail");
754 return tcu::TestStatus::pass("Pass");
757 std::string getSizeString (const IVec3& size, const int numLayer)
759 std::ostringstream str;
761 if (size.y() > 1) str << "x" << size.y();
762 if (size.z() > 1) str << "x" << size.z();
763 if (numLayer > 1) str << "_" << numLayer;
768 std::string getFormatString (const VkFormat format)
770 std::string name(getFormatName(format));
771 return de::toLower(name.substr(10));
774 std::string getShortImageViewTypeName (const VkImageViewType imageViewType)
776 std::string s(getImageViewTypeName(imageViewType));
777 return de::toLower(s.substr(19));
780 CaseDef caseDefWithFormat (CaseDef caseDef, const VkFormat format)
782 caseDef.colorFormat = format;
786 void addTestCasesWithFunctions (tcu::TestCaseGroup* group)
788 const CaseDef caseDef[] =
790 { VK_IMAGE_VIEW_TYPE_1D, IVec3(54, 1, 1), 1, VK_FORMAT_UNDEFINED},
791 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, IVec3(54, 1, 1), 4, VK_FORMAT_UNDEFINED},
792 { VK_IMAGE_VIEW_TYPE_2D, IVec3(22, 64, 1), 1, VK_FORMAT_UNDEFINED},
793 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, IVec3(22, 64, 1), 4, VK_FORMAT_UNDEFINED},
794 { VK_IMAGE_VIEW_TYPE_3D, IVec3(22, 64, 7), 1, VK_FORMAT_UNDEFINED},
795 { VK_IMAGE_VIEW_TYPE_CUBE, IVec3(35, 35, 1), 6, VK_FORMAT_UNDEFINED},
796 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, IVec3(35, 35, 1), 2*6, VK_FORMAT_UNDEFINED},
799 const VkFormat format[] =
801 VK_FORMAT_R8G8B8A8_UNORM,
803 VK_FORMAT_R16G16_SINT,
804 VK_FORMAT_R32G32B32A32_SFLOAT,
807 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(caseDef); ++sizeNdx)
809 MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(group->getTestContext(), getShortImageViewTypeName(caseDef[sizeNdx].imageType).c_str(), ""));
811 MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(group->getTestContext(), getSizeString(caseDef[sizeNdx].renderSize, caseDef[sizeNdx].numLayers).c_str(), ""));
813 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(format); ++formatNdx)
814 addFunctionCaseWithPrograms(sizeGroup.get(), getFormatString(format[formatNdx]).c_str(), "", initPrograms, test, caseDefWithFormat(caseDef[sizeNdx], format[formatNdx]));
816 imageGroup->addChild(sizeGroup.release());
818 group->addChild(imageGroup.release());
824 tcu::TestCaseGroup* createRenderToImageTests (tcu::TestContext& testCtx)
826 return createTestGroup(testCtx, "render_to_image", "Render to image tests", addTestCasesWithFunctions);