1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 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"
41 #include "tcuTestLog.hpp"
43 #include "deUniquePtr.hpp"
44 #include "deSharedPtr.hpp"
65 typedef SharedPtr<Unique<VkImageView> > SharedPtrVkImageView;
66 typedef SharedPtr<Unique<VkPipeline> > SharedPtrVkPipeline;
70 REFERENCE_COLOR_VALUE = 125
75 VkImageViewType imageType;
82 inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move)
84 return SharedPtr<Unique<T> >(new Unique<T>(move));
88 inline VkDeviceSize sizeInBytes (const vector<T>& vec)
90 return vec.size() * sizeof(vec[0]);
93 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
94 const VkDevice device,
95 const VkPipelineLayout pipelineLayout,
96 const VkRenderPass renderPass,
97 const VkShaderModule vertexModule,
98 const VkShaderModule fragmentModule,
99 const IVec3 renderSize,
100 const VkPrimitiveTopology topology,
101 const deUint32 subpass)
103 const VkVertexInputBindingDescription vertexInputBindingDescription =
105 0u, // uint32_t binding;
106 sizeof(Vertex4RGBA), // uint32_t stride;
107 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
110 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
113 0u, // uint32_t location;
114 0u, // uint32_t binding;
115 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
116 0u, // uint32_t offset;
119 1u, // uint32_t location;
120 0u, // uint32_t binding;
121 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
122 sizeof(Vec4), // uint32_t offset;
126 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
128 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
129 DE_NULL, // const void* pNext;
130 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
131 1u, // uint32_t vertexBindingDescriptionCount;
132 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
133 DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions), // uint32_t vertexAttributeDescriptionCount;
134 vertexInputAttributeDescriptions, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
137 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
139 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
140 DE_NULL, // const void* pNext;
141 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
142 topology, // VkPrimitiveTopology topology;
143 VK_FALSE, // VkBool32 primitiveRestartEnable;
146 const VkViewport viewport = makeViewport(
148 static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()),
151 const VkRect2D scissor =
154 makeExtent2D(renderSize.x(), renderSize.y()),
157 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
159 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
160 DE_NULL, // const void* pNext;
161 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
162 1u, // uint32_t viewportCount;
163 &viewport, // const VkViewport* pViewports;
164 1u, // uint32_t scissorCount;
165 &scissor, // const VkRect2D* pScissors;
168 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
170 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
171 DE_NULL, // const void* pNext;
172 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
173 VK_FALSE, // VkBool32 depthClampEnable;
174 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
175 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
176 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
177 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
178 VK_FALSE, // VkBool32 depthBiasEnable;
179 0.0f, // float depthBiasConstantFactor;
180 0.0f, // float depthBiasClamp;
181 0.0f, // float depthBiasSlopeFactor;
182 1.0f, // float lineWidth;
185 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
187 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
188 DE_NULL, // const void* pNext;
189 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
190 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
191 VK_FALSE, // VkBool32 sampleShadingEnable;
192 0.0f, // float minSampleShading;
193 DE_NULL, // const VkSampleMask* pSampleMask;
194 VK_FALSE, // VkBool32 alphaToCoverageEnable;
195 VK_FALSE // VkBool32 alphaToOneEnable;
198 const VkStencilOpState stencilOpState = makeStencilOpState(
199 VK_STENCIL_OP_KEEP, // stencil fail
200 VK_STENCIL_OP_KEEP, // depth & stencil pass
201 VK_STENCIL_OP_KEEP, // depth only fail
202 VK_COMPARE_OP_ALWAYS, // compare op
207 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
209 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
210 DE_NULL, // const void* pNext;
211 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
212 VK_FALSE, // VkBool32 depthTestEnable;
213 VK_FALSE, // VkBool32 depthWriteEnable;
214 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
215 VK_FALSE, // VkBool32 depthBoundsTestEnable;
216 VK_FALSE, // VkBool32 stencilTestEnable;
217 stencilOpState, // VkStencilOpState front;
218 stencilOpState, // VkStencilOpState back;
219 0.0f, // float minDepthBounds;
220 1.0f, // float maxDepthBounds;
223 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
224 // Number of blend attachments must equal the number of color attachments during any subpass.
225 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
227 VK_FALSE, // VkBool32 blendEnable;
228 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
229 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
230 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
231 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
232 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
233 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
234 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
237 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
239 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
240 DE_NULL, // const void* pNext;
241 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
242 VK_FALSE, // VkBool32 logicOpEnable;
243 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
244 1u, // deUint32 attachmentCount;
245 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
246 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
249 const VkPipelineShaderStageCreateInfo pShaderStages[] =
252 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
253 DE_NULL, // const void* pNext;
254 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
255 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
256 vertexModule, // VkShaderModule module;
257 "main", // const char* pName;
258 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
261 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
262 DE_NULL, // const void* pNext;
263 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
264 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
265 fragmentModule, // VkShaderModule module;
266 "main", // const char* pName;
267 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
271 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
273 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
274 DE_NULL, // const void* pNext;
275 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
276 DE_LENGTH_OF_ARRAY(pShaderStages), // deUint32 stageCount;
277 pShaderStages, // const VkPipelineShaderStageCreateInfo* pStages;
278 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
279 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
280 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
281 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
282 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
283 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
284 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
285 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
286 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
287 pipelineLayout, // VkPipelineLayout layout;
288 renderPass, // VkRenderPass renderPass;
289 subpass, // deUint32 subpass;
290 DE_NULL, // VkPipeline basePipelineHandle;
291 0, // deInt32 basePipelineIndex;
294 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
297 //! Make a render pass with one subpass per color attachment and one attachment per image layer.
298 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
299 const VkDevice device,
300 const VkFormat colorFormat,
301 const deUint32 numLayers)
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 VK_IMAGE_LAYOUT_UNDEFINED, // 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 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout (vk, device));
580 vector<SharedPtrVkPipeline> pipeline;
581 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
582 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool));
584 vector<SharedPtrVkImageView> colorAttachments;
585 vector<VkImageView> attachmentHandles;
586 Move<VkBuffer> vertexBuffer;
587 MovePtr<Allocation> vertexBufferAlloc;
588 Move<VkFramebuffer> framebuffer;
592 const VkImageViewCreateFlags flags = (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType ? (VkImageViewCreateFlags)VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR : (VkImageViewCreateFlags)0);
593 const VkImageUsageFlags colorImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
594 colorImage = makeImage(vk, device, flags, getImageType(caseDef.imageType), caseDef.colorFormat, caseDef.renderSize, caseDef.numLayers, colorImageUsage);
595 colorImageAlloc = bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any);
598 //create vertexBuffer
600 const vector<Vertex4RGBA> vertices = genFullQuadVertices(numLayers, vector<Vec4>(color, color + DE_LENGTH_OF_ARRAY(color)));
601 const VkDeviceSize vertexBufferSize = sizeInBytes(vertices);
603 vertexBuffer = makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
604 vertexBufferAlloc = bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible);
605 deMemcpy(vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
606 flushMappedMemoryRange(vk, device, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexBufferSize);
609 //create attachmentHandles and pipelines
610 for (int layerNdx = 0; layerNdx < numLayers; ++layerNdx)
612 const VkImageViewType imageType = (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType ? VK_IMAGE_VIEW_TYPE_2D_ARRAY :
613 (VK_IMAGE_VIEW_TYPE_CUBE == caseDef.imageType || VK_IMAGE_VIEW_TYPE_CUBE_ARRAY == caseDef.imageType ? VK_IMAGE_VIEW_TYPE_2D :
616 colorAttachments.push_back(makeSharedPtr(makeImageView(vk, device, *colorImage, imageType, caseDef.colorFormat, makeColorSubresourceRange(layerNdx, 1))));
617 attachmentHandles.push_back(**colorAttachments.back());
619 pipeline.push_back(makeSharedPtr(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule,
620 caseDef.renderSize, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, static_cast<deUint32>(layerNdx))));
623 framebuffer = makeFramebuffer(vk, device, *renderPass, numLayers, &attachmentHandles[0], static_cast<deUint32>(caseDef.renderSize.x()), static_cast<deUint32>(caseDef.renderSize.y()));
625 beginCommandBuffer(vk, *cmdBuffer);
627 const vector<VkClearValue> clearValues (numLayers, getClearValue(caseDef.colorFormat));
628 const VkRect2D renderArea =
631 makeExtent2D(caseDef.renderSize.x(), caseDef.renderSize.y()),
633 const VkRenderPassBeginInfo renderPassBeginInfo =
635 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
636 DE_NULL, // const void* pNext;
637 *renderPass, // VkRenderPass renderPass;
638 *framebuffer, // VkFramebuffer framebuffer;
639 renderArea, // VkRect2D renderArea;
640 static_cast<deUint32>(clearValues.size()), // uint32_t clearValueCount;
641 &clearValues[0], // const VkClearValue* pClearValues;
643 const VkDeviceSize vertexBufferOffset = 0ull;
645 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
646 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
650 for (deUint32 layerNdx = 0; layerNdx < static_cast<deUint32>(numLayers); ++layerNdx)
653 vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
655 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipeline[layerNdx]);
656 vk.cmdDraw(*cmdBuffer, 4u, 1u, layerNdx*4u, 0u);
659 vk.cmdEndRenderPass(*cmdBuffer);
661 // copy colorImage -> host visible colorBuffer
663 const VkImageMemoryBarrier imageBarriers[] =
666 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
667 DE_NULL, // const void* pNext;
668 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags outputMask;
669 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags inputMask;
670 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
671 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
672 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
673 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
674 *colorImage, // VkImage image;
675 makeColorSubresourceRange(0, caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
679 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
680 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
682 const VkBufferImageCopy region =
684 0ull, // VkDeviceSize bufferOffset;
685 0u, // uint32_t bufferRowLength;
686 0u, // uint32_t bufferImageHeight;
687 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, caseDef.numLayers), // VkImageSubresourceLayers imageSubresource;
688 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
689 makeExtent3D(caseDef.renderSize), // VkExtent3D imageExtent;
692 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ®ion);
694 const VkBufferMemoryBarrier bufferBarriers[] =
697 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
698 DE_NULL, // const void* pNext;
699 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
700 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
701 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
702 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
703 *colorBuffer, // VkBuffer buffer;
704 0ull, // VkDeviceSize offset;
705 VK_WHOLE_SIZE, // VkDeviceSize size;
709 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
710 0u, DE_NULL, DE_LENGTH_OF_ARRAY(bufferBarriers), bufferBarriers, 0u, DE_NULL);
713 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
714 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
718 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
720 const tcu::TextureFormat format = mapVkFormat(caseDef.colorFormat);
721 const int depth = deMax32(caseDef.renderSize.z(), caseDef.numLayers);
722 tcu::TextureLevel textureLevel (format, caseDef.renderSize.x(), caseDef.renderSize.y(), depth);
723 const tcu::PixelBufferAccess expectedImage = getExpectedData (textureLevel, caseDef, color, DE_LENGTH_OF_ARRAY(color));
724 const tcu::ConstPixelBufferAccess resultImage (format, caseDef.renderSize.x(), caseDef.renderSize.y(), depth, colorBufferAlloc->getHostPtr());
726 if (!tcu::intThresholdCompare(context.getTestContext().getLog(), "Image Comparison", "", expectedImage, resultImage, tcu::UVec4(2), tcu::COMPARE_LOG_RESULT))
727 return tcu::TestStatus::fail("Fail");
729 return tcu::TestStatus::pass("Pass");
732 std::string getSizeString (const IVec3& size, const int numLayer)
734 std::ostringstream str;
736 if (size.y() > 1) str << "x" << size.y();
737 if (size.z() > 1) str << "x" << size.z();
738 if (numLayer > 1) str << "_" << numLayer;
743 std::string getFormatString (const VkFormat format)
745 std::string name(getFormatName(format));
746 return de::toLower(name.substr(10));
749 std::string getShortImageViewTypeName (const VkImageViewType imageViewType)
751 std::string s(getImageViewTypeName(imageViewType));
752 return de::toLower(s.substr(19));
755 CaseDef caseDefWithFormat (CaseDef caseDef, const VkFormat format)
757 caseDef.colorFormat = format;
761 void addTestCasesWithFunctions (tcu::TestCaseGroup* group)
763 const CaseDef caseDef[] =
765 { VK_IMAGE_VIEW_TYPE_1D, IVec3(54, 1, 1), 1, VK_FORMAT_UNDEFINED},
766 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, IVec3(54, 1, 1), 4, VK_FORMAT_UNDEFINED},
767 { VK_IMAGE_VIEW_TYPE_2D, IVec3(22, 64, 1), 1, VK_FORMAT_UNDEFINED},
768 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, IVec3(22, 64, 1), 4, VK_FORMAT_UNDEFINED},
769 { VK_IMAGE_VIEW_TYPE_3D, IVec3(22, 64, 7), 1, VK_FORMAT_UNDEFINED},
770 { VK_IMAGE_VIEW_TYPE_CUBE, IVec3(35, 35, 1), 6, VK_FORMAT_UNDEFINED},
771 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, IVec3(35, 35, 1), 2*6, VK_FORMAT_UNDEFINED},
774 const VkFormat format[] =
776 VK_FORMAT_R8G8B8A8_UNORM,
778 VK_FORMAT_R16G16_SINT,
779 VK_FORMAT_R32G32B32A32_SFLOAT,
782 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(caseDef); ++sizeNdx)
784 MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(group->getTestContext(), getShortImageViewTypeName(caseDef[sizeNdx].imageType).c_str(), ""));
786 MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(group->getTestContext(), getSizeString(caseDef[sizeNdx].renderSize, caseDef[sizeNdx].numLayers).c_str(), ""));
788 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(format); ++formatNdx)
789 addFunctionCaseWithPrograms(sizeGroup.get(), getFormatString(format[formatNdx]).c_str(), "", initPrograms, test, caseDefWithFormat(caseDef[sizeNdx], format[formatNdx]));
791 imageGroup->addChild(sizeGroup.release());
793 group->addChild(imageGroup.release());
799 tcu::TestCaseGroup* createRenderToImageTests (tcu::TestContext& testCtx)
801 return createTestGroup(testCtx, "render_to_image", "Render to image tests", addTestCasesWithFunctions);