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"
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)
302 const VkAttachmentDescription colorAttachmentDescription =
304 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
305 colorFormat, // VkFormat format;
306 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
307 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
308 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
309 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
310 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
311 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
312 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
314 const vector<VkAttachmentDescription> attachmentDescriptions(numLayers, colorAttachmentDescription);
316 // Create a subpass for each attachment (each attachement is a layer of an arrayed image).
317 vector<VkAttachmentReference> colorAttachmentReferences(numLayers);
318 vector<VkSubpassDescription> subpasses;
320 for (deUint32 i = 0; i < numLayers; ++i)
322 const VkAttachmentReference attachmentRef =
324 i, // deUint32 attachment;
325 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
327 colorAttachmentReferences[i] = attachmentRef;
329 const VkSubpassDescription subpassDescription =
331 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
332 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
333 0u, // deUint32 inputAttachmentCount;
334 DE_NULL, // const VkAttachmentReference* pInputAttachments;
335 1u, // deUint32 colorAttachmentCount;
336 &colorAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments;
337 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
338 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
339 0u, // deUint32 preserveAttachmentCount;
340 DE_NULL // const deUint32* pPreserveAttachments;
342 subpasses.push_back(subpassDescription);
345 const VkRenderPassCreateInfo renderPassInfo =
347 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
348 DE_NULL, // const void* pNext;
349 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
350 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
351 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
352 static_cast<deUint32>(subpasses.size()), // deUint32 subpassCount;
353 &subpasses[0], // const VkSubpassDescription* pSubpasses;
354 0u, // deUint32 dependencyCount;
355 DE_NULL // const VkSubpassDependency* pDependencies;
358 return createRenderPass(vk, device, &renderPassInfo);
361 Move<VkImage> makeImage (const DeviceInterface& vk,
362 const VkDevice device,
363 VkImageCreateFlags flags,
364 VkImageType imageType,
365 const VkFormat format,
367 const deUint32 numLayers,
368 const VkImageUsageFlags usage)
370 const VkImageCreateInfo imageParams =
372 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
373 DE_NULL, // const void* pNext;
374 flags, // VkImageCreateFlags flags;
375 imageType, // VkImageType imageType;
376 format, // VkFormat format;
377 makeExtent3D(size), // VkExtent3D extent;
378 1u, // deUint32 mipLevels;
379 numLayers, // deUint32 arrayLayers;
380 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
381 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
382 usage, // VkImageUsageFlags usage;
383 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
384 0u, // deUint32 queueFamilyIndexCount;
385 DE_NULL, // const deUint32* pQueueFamilyIndices;
386 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
388 return createImage(vk, device, &imageParams);
391 inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize bufferSize, const VkBufferUsageFlags usage)
393 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSize, usage);
394 return createBuffer(vk, device, &bufferCreateInfo);
397 inline VkImageSubresourceRange makeColorSubresourceRange (const int baseArrayLayer, const int layerCount)
399 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, static_cast<deUint32>(baseArrayLayer), static_cast<deUint32>(layerCount));
402 //! Get a reference clear value based on color format.
403 VkClearValue getClearValue (const VkFormat format)
405 if (isUintFormat(format) || isIntFormat(format))
406 return makeClearValueColorU32(REFERENCE_COLOR_VALUE, REFERENCE_COLOR_VALUE, REFERENCE_COLOR_VALUE, REFERENCE_COLOR_VALUE);
408 return makeClearValueColorF32(1.0f, 1.0f, 1.0f, 1.0f);
411 std::string getColorFormatStr (const int numComponents, const bool isUint, const bool isSint)
413 std::ostringstream str;
414 if (numComponents == 1)
415 str << (isUint ? "uint" : isSint ? "int" : "float");
417 str << (isUint ? "u" : isSint ? "i" : "") << "vec" << numComponents;
422 //! A half-viewport quad. Use with TRIANGLE_STRIP topology.
423 vector<Vertex4RGBA> genFullQuadVertices (const int subpassCount, const vector<Vec4>& color)
425 vector<Vertex4RGBA> vectorData;
426 for (int subpassNdx = 0; subpassNdx < subpassCount; ++subpassNdx)
430 Vec4(0.0f, -1.0f, 0.0f, 1.0f),
431 color[subpassNdx % color.size()],
433 vectorData.push_back(data);
434 data.position = Vec4(0.0f, 1.0f, 0.0f, 1.0f);
435 vectorData.push_back(data);
436 data.position = Vec4(1.0f, -1.0f, 0.0f, 1.0f);
437 vectorData.push_back(data);
438 data.position = Vec4(1.0f, 1.0f, 0.0f, 1.0f);
439 vectorData.push_back(data);
444 VkImageType getImageType (const VkImageViewType viewType)
448 case VK_IMAGE_VIEW_TYPE_1D:
449 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
450 return VK_IMAGE_TYPE_1D;
452 case VK_IMAGE_VIEW_TYPE_2D:
453 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
454 case VK_IMAGE_VIEW_TYPE_CUBE:
455 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
456 return VK_IMAGE_TYPE_2D;
458 case VK_IMAGE_VIEW_TYPE_3D:
459 return VK_IMAGE_TYPE_3D;
463 return VK_IMAGE_TYPE_LAST;
467 void initPrograms (SourceCollections& programCollection, const CaseDef caseDef)
469 const int numComponents = getNumUsedChannels(mapVkFormat(caseDef.colorFormat).order);
470 const bool isUint = isUintFormat(caseDef.colorFormat);
471 const bool isSint = isIntFormat(caseDef.colorFormat);
475 std::ostringstream src;
476 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
478 << "layout(location = 0) in vec4 in_position;\n"
479 << "layout(location = 1) in vec4 in_color;\n"
480 << "layout(location = 0) out vec4 out_color;\n"
482 << "out gl_PerVertex {\n"
483 << " vec4 gl_Position;\n"
486 << "void main(void)\n"
488 << " gl_Position = in_position;\n"
489 << " out_color = in_color;\n"
492 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
497 std::ostringstream colorValue;
498 colorValue << REFERENCE_COLOR_VALUE;
499 const std::string colorFormat = getColorFormatStr(numComponents, isUint, isSint);
500 const std::string colorInteger = (isUint || isSint ? " * "+colorFormat+"("+colorValue.str()+")" :"");
502 std::ostringstream src;
503 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
505 << "layout(location = 0) in vec4 in_color;\n"
506 << "layout(location = 0) out " << colorFormat << " o_color;\n"
508 << "void main(void)\n"
510 << " o_color = " << colorFormat << "("
511 << (numComponents == 1 ? "in_color.r" :
512 numComponents == 2 ? "in_color.rg" :
513 numComponents == 3 ? "in_color.rgb" : "in_color")
518 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
522 tcu::PixelBufferAccess getExpectedData (tcu::TextureLevel& textureLevel, const CaseDef& caseDef, const Vec4* color, const int sizeColor)
524 const bool isInt = isUintFormat(caseDef.colorFormat) || isIntFormat(caseDef.colorFormat);
525 const tcu::PixelBufferAccess expectedImage (textureLevel);
528 tcu::clear(expectedImage, tcu::IVec4(REFERENCE_COLOR_VALUE));
530 tcu::clear(expectedImage, tcu::Vec4(1.0));
532 for (int z = 0; z < expectedImage.getDepth(); ++z)
534 const Vec4& setColor = color[z % sizeColor];
535 const IVec4 setColorInt = (static_cast<float>(REFERENCE_COLOR_VALUE) * setColor).cast<deInt32>();
537 for (int y = 0; y < caseDef.renderSize.y(); ++y)
538 for (int x = caseDef.renderSize.x()/2; x < caseDef.renderSize.x(); ++x)
541 expectedImage.setPixel(setColorInt, x, y, z);
543 expectedImage.setPixel(setColor, x, y, z);
546 return expectedImage;
549 tcu::TestStatus test (Context& context, const CaseDef caseDef)
551 if (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType &&
552 (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance1")))
553 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
555 const DeviceInterface& vk = context.getDeviceInterface();
556 const VkDevice device = context.getDevice();
557 const VkQueue queue = context.getUniversalQueue();
558 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
559 Allocator& allocator = context.getDefaultAllocator();
560 Move<VkImage> colorImage;
561 MovePtr<Allocation> colorImageAlloc;
564 Vec4(0.9f, 0.0f, 0.0f, 1.0f),
565 Vec4(0.6f, 1.0f, 0.0f, 1.0f),
566 Vec4(0.3f, 0.0f, 1.0f, 1.0f),
567 Vec4(0.1f, 0.0f, 1.0f, 1.0f)
570 const int numLayers = (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType ? caseDef.renderSize.z() : caseDef.numLayers);
571 const VkDeviceSize colorBufferSize = caseDef.renderSize.x() * caseDef.renderSize.y() * caseDef.renderSize.z() * caseDef.numLayers * tcu::getPixelSize(mapVkFormat(caseDef.colorFormat));
572 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
573 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
575 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, context.getBinaryCollection().get("vert"), 0u));
576 const Unique<VkShaderModule> fragmentModule (createShaderModule (vk, device, context.getBinaryCollection().get("frag"), 0u));
577 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, caseDef.colorFormat, static_cast<deUint32>(numLayers)));
578 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout (vk, device));
579 vector<SharedPtrVkPipeline> pipeline;
580 const Unique<VkCommandPool> cmdPool (makeCommandPool (vk, device, queueFamilyIndex));
581 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool));
583 vector<SharedPtrVkImageView> colorAttachments;
584 vector<VkImageView> attachmentHandles;
585 Move<VkBuffer> vertexBuffer;
586 MovePtr<Allocation> vertexBufferAlloc;
587 Move<VkFramebuffer> framebuffer;
591 const VkImageViewCreateFlags flags = (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType ? (VkImageViewCreateFlags)VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR : (VkImageViewCreateFlags)0);
592 const VkImageUsageFlags colorImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
593 colorImage = makeImage(vk, device, flags, getImageType(caseDef.imageType), caseDef.colorFormat, caseDef.renderSize, caseDef.numLayers, colorImageUsage);
594 colorImageAlloc = bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any);
597 //create vertexBuffer
599 const vector<Vertex4RGBA> vertices = genFullQuadVertices(numLayers, vector<Vec4>(color, color + DE_LENGTH_OF_ARRAY(color)));
600 const VkDeviceSize vertexBufferSize = sizeInBytes(vertices);
602 vertexBuffer = makeBuffer(vk, device, vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
603 vertexBufferAlloc = bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible);
604 deMemcpy(vertexBufferAlloc->getHostPtr(), &vertices[0], static_cast<std::size_t>(vertexBufferSize));
605 flushMappedMemoryRange(vk, device, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexBufferSize);
608 //create attachmentHandles and pipelines
609 for (int layerNdx = 0; layerNdx < numLayers; ++layerNdx)
611 const VkImageViewType imageType = (VK_IMAGE_VIEW_TYPE_3D == caseDef.imageType ? VK_IMAGE_VIEW_TYPE_2D_ARRAY :
612 (VK_IMAGE_VIEW_TYPE_CUBE == caseDef.imageType || VK_IMAGE_VIEW_TYPE_CUBE_ARRAY == caseDef.imageType ? VK_IMAGE_VIEW_TYPE_2D :
615 colorAttachments.push_back(makeSharedPtr(makeImageView(vk, device, *colorImage, imageType, caseDef.colorFormat, makeColorSubresourceRange(layerNdx, 1))));
616 attachmentHandles.push_back(**colorAttachments.back());
618 pipeline.push_back(makeSharedPtr(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule,
619 caseDef.renderSize, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, static_cast<deUint32>(layerNdx))));
622 framebuffer = makeFramebuffer(vk, device, *renderPass, numLayers, &attachmentHandles[0], static_cast<deUint32>(caseDef.renderSize.x()), static_cast<deUint32>(caseDef.renderSize.y()));
624 beginCommandBuffer(vk, *cmdBuffer);
626 const vector<VkClearValue> clearValues (numLayers, getClearValue(caseDef.colorFormat));
627 const VkRect2D renderArea =
630 makeExtent2D(caseDef.renderSize.x(), caseDef.renderSize.y()),
632 const VkRenderPassBeginInfo renderPassBeginInfo =
634 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
635 DE_NULL, // const void* pNext;
636 *renderPass, // VkRenderPass renderPass;
637 *framebuffer, // VkFramebuffer framebuffer;
638 renderArea, // VkRect2D renderArea;
639 static_cast<deUint32>(clearValues.size()), // uint32_t clearValueCount;
640 &clearValues[0], // const VkClearValue* pClearValues;
642 const VkDeviceSize vertexBufferOffset = 0ull;
644 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
645 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
649 for (deUint32 layerNdx = 0; layerNdx < static_cast<deUint32>(numLayers); ++layerNdx)
652 vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
654 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipeline[layerNdx]);
655 vk.cmdDraw(*cmdBuffer, 4u, 1u, layerNdx*4u, 0u);
658 vk.cmdEndRenderPass(*cmdBuffer);
660 // copy colorImage -> host visible colorBuffer
662 const VkImageMemoryBarrier imageBarriers[] =
665 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
666 DE_NULL, // const void* pNext;
667 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags outputMask;
668 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags inputMask;
669 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
670 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
671 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
672 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
673 *colorImage, // VkImage image;
674 makeColorSubresourceRange(0, caseDef.numLayers) // VkImageSubresourceRange subresourceRange;
678 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
679 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
681 const VkBufferImageCopy region =
683 0ull, // VkDeviceSize bufferOffset;
684 0u, // uint32_t bufferRowLength;
685 0u, // uint32_t bufferImageHeight;
686 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, caseDef.numLayers), // VkImageSubresourceLayers imageSubresource;
687 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
688 makeExtent3D(caseDef.renderSize), // VkExtent3D imageExtent;
691 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ®ion);
693 const VkBufferMemoryBarrier bufferBarriers[] =
696 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
697 DE_NULL, // const void* pNext;
698 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
699 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
700 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
701 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
702 *colorBuffer, // VkBuffer buffer;
703 0ull, // VkDeviceSize offset;
704 VK_WHOLE_SIZE, // VkDeviceSize size;
708 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
709 0u, DE_NULL, DE_LENGTH_OF_ARRAY(bufferBarriers), bufferBarriers, 0u, DE_NULL);
712 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
713 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
717 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), VK_WHOLE_SIZE);
719 const tcu::TextureFormat format = mapVkFormat(caseDef.colorFormat);
720 const int depth = deMax32(caseDef.renderSize.z(), caseDef.numLayers);
721 tcu::TextureLevel textureLevel (format, caseDef.renderSize.x(), caseDef.renderSize.y(), depth);
722 const tcu::PixelBufferAccess expectedImage = getExpectedData (textureLevel, caseDef, color, DE_LENGTH_OF_ARRAY(color));
723 const tcu::ConstPixelBufferAccess resultImage (format, caseDef.renderSize.x(), caseDef.renderSize.y(), depth, colorBufferAlloc->getHostPtr());
725 if (!tcu::intThresholdCompare(context.getTestContext().getLog(), "Image Comparison", "", expectedImage, resultImage, tcu::UVec4(2), tcu::COMPARE_LOG_RESULT))
726 return tcu::TestStatus::fail("Fail");
728 return tcu::TestStatus::pass("Pass");
731 std::string getSizeString (const IVec3& size, const int numLayer)
733 std::ostringstream str;
735 if (size.y() > 1) str << "x" << size.y();
736 if (size.z() > 1) str << "x" << size.z();
737 if (numLayer > 1) str << "_" << numLayer;
742 std::string getFormatString (const VkFormat format)
744 std::string name(getFormatName(format));
745 return de::toLower(name.substr(10));
748 std::string getShortImageViewTypeName (const VkImageViewType imageViewType)
750 std::string s(getImageViewTypeName(imageViewType));
751 return de::toLower(s.substr(19));
754 CaseDef caseDefWithFormat (CaseDef caseDef, const VkFormat format)
756 caseDef.colorFormat = format;
760 void addTestCasesWithFunctions (tcu::TestCaseGroup* group)
762 const CaseDef caseDef[] =
764 { VK_IMAGE_VIEW_TYPE_1D, IVec3(54, 1, 1), 1, VK_FORMAT_UNDEFINED},
765 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, IVec3(54, 1, 1), 4, VK_FORMAT_UNDEFINED},
766 { VK_IMAGE_VIEW_TYPE_2D, IVec3(22, 64, 1), 1, VK_FORMAT_UNDEFINED},
767 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, IVec3(22, 64, 1), 4, VK_FORMAT_UNDEFINED},
768 { VK_IMAGE_VIEW_TYPE_3D, IVec3(22, 64, 7), 1, VK_FORMAT_UNDEFINED},
769 { VK_IMAGE_VIEW_TYPE_CUBE, IVec3(35, 35, 1), 6, VK_FORMAT_UNDEFINED},
770 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, IVec3(35, 35, 1), 2*6, VK_FORMAT_UNDEFINED},
773 const VkFormat format[] =
775 VK_FORMAT_R8G8B8A8_UNORM,
777 VK_FORMAT_R16G16_SINT,
778 VK_FORMAT_R32G32B32A32_SFLOAT,
781 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(caseDef); ++sizeNdx)
783 MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(group->getTestContext(), getShortImageViewTypeName(caseDef[sizeNdx].imageType).c_str(), ""));
785 MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(group->getTestContext(), getSizeString(caseDef[sizeNdx].renderSize, caseDef[sizeNdx].numLayers).c_str(), ""));
787 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(format); ++formatNdx)
788 addFunctionCaseWithPrograms(sizeGroup.get(), getFormatString(format[formatNdx]).c_str(), "", initPrograms, test, caseDefWithFormat(caseDef[sizeNdx], format[formatNdx]));
790 imageGroup->addChild(sizeGroup.release());
792 group->addChild(imageGroup.release());
798 tcu::TestCaseGroup* createRenderToImageTests (tcu::TestContext& testCtx)
800 return createTestGroup(testCtx, "render_to_image", "Render to image tests", addTestCasesWithFunctions);