1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2014 The Android Open Source Project
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 * \brief Geometry shader layered rendering tests
23 *//*--------------------------------------------------------------------*/
25 #include "vktGeometryLayeredRenderingTests.hpp"
26 #include "vktTestCase.hpp"
27 #include "vktTestCaseUtil.hpp"
28 #include "vktGeometryTestsUtil.hpp"
30 #include "vkPrograms.hpp"
31 #include "vkStrUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkImageUtil.hpp"
38 #include "deStringUtil.hpp"
39 #include "deUniquePtr.hpp"
41 #include "tcuTextureUtil.hpp"
42 #include "tcuVectorUtil.hpp"
58 TEST_TYPE_DEFAULT_LAYER, // !< draw to default layer
59 TEST_TYPE_SINGLE_LAYER, // !< draw to single layer
60 TEST_TYPE_ALL_LAYERS, // !< draw all layers
61 TEST_TYPE_DIFFERENT_CONTENT, // !< draw different content to different layers
62 TEST_TYPE_LAYER_ID, // !< draw to all layers, verify gl_Layer fragment input
63 TEST_TYPE_INVOCATION_PER_LAYER, // !< draw to all layers, one invocation per layer
64 TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION, // !< draw to all layers, multiple invocations write to multiple layers
69 VkImageViewType viewType;
80 static const float s_colors[][4] =
82 { 1.0f, 1.0f, 1.0f, 1.0f }, // white
83 { 1.0f, 0.0f, 0.0f, 1.0f }, // red
84 { 0.0f, 1.0f, 0.0f, 1.0f }, // green
85 { 0.0f, 0.0f, 1.0f, 1.0f }, // blue
86 { 1.0f, 1.0f, 0.0f, 1.0f }, // yellow
87 { 1.0f, 0.0f, 1.0f, 1.0f }, // magenta
90 deUint32 getTargetLayer (const ImageParams& imageParams)
92 if (imageParams.viewType == VK_IMAGE_VIEW_TYPE_3D)
93 return imageParams.size.depth / 2;
95 return imageParams.numLayers / 2;
98 std::string getShortImageViewTypeName (const VkImageViewType imageViewType)
100 std::string s(getImageViewTypeName(imageViewType));
101 return de::toLower(s.substr(19));
104 VkImageType getImageType (const VkImageViewType viewType)
108 case VK_IMAGE_VIEW_TYPE_1D:
109 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
110 return VK_IMAGE_TYPE_1D;
112 case VK_IMAGE_VIEW_TYPE_2D:
113 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
114 case VK_IMAGE_VIEW_TYPE_CUBE:
115 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
116 return VK_IMAGE_TYPE_2D;
118 case VK_IMAGE_VIEW_TYPE_3D:
119 return VK_IMAGE_TYPE_3D;
123 return VK_IMAGE_TYPE_LAST;
127 inline bool isCubeImageViewType (const VkImageViewType viewType)
129 return viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
132 VkImageCreateInfo makeImageCreateInfo (const VkImageCreateFlags flags, const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const VkImageUsageFlags usage)
134 const VkImageCreateInfo imageParams =
136 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
137 DE_NULL, // const void* pNext;
138 flags, // VkImageCreateFlags flags;
139 type, // VkImageType imageType;
140 format, // VkFormat format;
141 size, // VkExtent3D extent;
142 1u, // deUint32 mipLevels;
143 numLayers, // deUint32 arrayLayers;
144 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
145 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
146 usage, // VkImageUsageFlags usage;
147 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
148 0u, // deUint32 queueFamilyIndexCount;
149 DE_NULL, // const deUint32* pQueueFamilyIndices;
150 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
155 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
156 const VkDevice device,
157 const VkFormat colorFormat)
159 const VkAttachmentDescription colorAttachmentDescription =
161 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
162 colorFormat, // VkFormat format;
163 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
164 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
165 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
166 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
167 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
168 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
169 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
172 const VkAttachmentReference colorAttachmentRef =
174 0u, // deUint32 attachment;
175 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
178 const VkSubpassDescription subpassDescription =
180 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
181 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
182 0u, // deUint32 inputAttachmentCount;
183 DE_NULL, // const VkAttachmentReference* pInputAttachments;
184 1u, // deUint32 colorAttachmentCount;
185 &colorAttachmentRef, // const VkAttachmentReference* pColorAttachments;
186 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
187 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
188 0u, // deUint32 preserveAttachmentCount;
189 DE_NULL // const deUint32* pPreserveAttachments;
192 const VkRenderPassCreateInfo renderPassInfo =
194 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
195 DE_NULL, // const void* pNext;
196 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
197 1u, // deUint32 attachmentCount;
198 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments;
199 1u, // deUint32 subpassCount;
200 &subpassDescription, // const VkSubpassDescription* pSubpasses;
201 0u, // deUint32 dependencyCount;
202 DE_NULL // const VkSubpassDependency* pDependencies;
205 return createRenderPass(vk, device, &renderPassInfo);
208 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
209 const VkDevice device,
210 const VkPipelineLayout pipelineLayout,
211 const VkRenderPass renderPass,
212 const VkShaderModule vertexModule,
213 const VkShaderModule geometryModule,
214 const VkShaderModule fragmentModule,
215 const VkExtent2D renderSize)
217 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
219 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
220 DE_NULL, // const void* pNext;
221 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
222 0u, // uint32_t vertexBindingDescriptionCount;
223 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
224 0u, // uint32_t vertexAttributeDescriptionCount;
225 DE_NULL, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
228 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
230 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
231 DE_NULL, // const void* pNext;
232 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
233 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // VkPrimitiveTopology topology;
234 VK_FALSE, // VkBool32 primitiveRestartEnable;
237 const VkViewport viewport = makeViewport(
239 static_cast<float>(renderSize.width), static_cast<float>(renderSize.height),
241 const VkRect2D scissor =
244 makeExtent2D(renderSize.width, renderSize.height),
247 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
249 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
250 DE_NULL, // const void* pNext;
251 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
252 1u, // uint32_t viewportCount;
253 &viewport, // const VkViewport* pViewports;
254 1u, // uint32_t scissorCount;
255 &scissor, // const VkRect2D* pScissors;
258 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
260 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
261 DE_NULL, // const void* pNext;
262 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
263 VK_FALSE, // VkBool32 depthClampEnable;
264 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
265 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
266 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
267 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
268 VK_FALSE, // VkBool32 depthBiasEnable;
269 0.0f, // float depthBiasConstantFactor;
270 0.0f, // float depthBiasClamp;
271 0.0f, // float depthBiasSlopeFactor;
272 1.0f, // float lineWidth;
275 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
277 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
278 DE_NULL, // const void* pNext;
279 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
280 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
281 VK_FALSE, // VkBool32 sampleShadingEnable;
282 0.0f, // float minSampleShading;
283 DE_NULL, // const VkSampleMask* pSampleMask;
284 VK_FALSE, // VkBool32 alphaToCoverageEnable;
285 VK_FALSE // VkBool32 alphaToOneEnable;
288 const VkStencilOpState stencilOpState = makeStencilOpState(
289 VK_STENCIL_OP_KEEP, // stencil fail
290 VK_STENCIL_OP_KEEP, // depth & stencil pass
291 VK_STENCIL_OP_KEEP, // depth only fail
292 VK_COMPARE_OP_ALWAYS, // compare op
297 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
299 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
300 DE_NULL, // const void* pNext;
301 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
302 VK_FALSE, // VkBool32 depthTestEnable;
303 VK_FALSE, // VkBool32 depthWriteEnable;
304 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
305 VK_FALSE, // VkBool32 depthBoundsTestEnable;
306 VK_FALSE, // VkBool32 stencilTestEnable;
307 stencilOpState, // VkStencilOpState front;
308 stencilOpState, // VkStencilOpState back;
309 0.0f, // float minDepthBounds;
310 1.0f, // float maxDepthBounds;
313 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
314 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
316 VK_FALSE, // VkBool32 blendEnable;
317 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
318 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
319 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
320 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
321 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
322 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
323 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
326 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
328 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
329 DE_NULL, // const void* pNext;
330 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
331 VK_FALSE, // VkBool32 logicOpEnable;
332 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
333 1u, // deUint32 attachmentCount;
334 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
335 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
338 const VkPipelineShaderStageCreateInfo pShaderStages[] =
341 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
342 DE_NULL, // const void* pNext;
343 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
344 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
345 vertexModule, // VkShaderModule module;
346 "main", // const char* pName;
347 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
350 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
351 DE_NULL, // const void* pNext;
352 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
353 VK_SHADER_STAGE_GEOMETRY_BIT, // VkShaderStageFlagBits stage;
354 geometryModule, // VkShaderModule module;
355 "main", // const char* pName;
356 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
359 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
360 DE_NULL, // const void* pNext;
361 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
362 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
363 fragmentModule, // VkShaderModule module;
364 "main", // const char* pName;
365 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
369 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
371 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
372 DE_NULL, // const void* pNext;
373 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
374 DE_LENGTH_OF_ARRAY(pShaderStages), // deUint32 stageCount;
375 pShaderStages, // const VkPipelineShaderStageCreateInfo* pStages;
376 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
377 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
378 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
379 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
380 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
381 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
382 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
383 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
384 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
385 pipelineLayout, // VkPipelineLayout layout;
386 renderPass, // VkRenderPass renderPass;
387 0u, // deUint32 subpass;
388 DE_NULL, // VkPipeline basePipelineHandle;
389 0, // deInt32 basePipelineIndex;
392 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
395 //! Convenience wrapper to access 1D, 2D, and 3D image layers/slices in a uniform way.
396 class LayeredImageAccess
399 static LayeredImageAccess create (const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const void* pData)
401 if (type == VK_IMAGE_TYPE_1D)
402 return LayeredImageAccess(format, size.width, numLayers, pData);
404 return LayeredImageAccess(type, format, size, numLayers, pData);
407 inline tcu::ConstPixelBufferAccess getLayer (const int layer) const
409 return tcu::getSubregion(m_wholeImage, 0, (m_1dModifier * layer), ((~m_1dModifier & 1) * layer), m_width, m_height, 1);
412 inline int getNumLayersOrSlices (void) const
418 // Specialized for 1D images.
419 LayeredImageAccess (const VkFormat format, const deUint32 width, const deUint32 numLayers, const void* pData)
420 : m_width (static_cast<int>(width))
423 , m_layers (numLayers)
424 , m_wholeImage (tcu::ConstPixelBufferAccess(mapVkFormat(format), m_width, m_layers, 1, pData))
428 LayeredImageAccess (const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const void* pData)
429 : m_width (static_cast<int>(size.width))
430 , m_height (static_cast<int>(size.height))
432 , m_layers (static_cast<int>(type == VK_IMAGE_TYPE_3D ? size.depth : numLayers))
433 , m_wholeImage (tcu::ConstPixelBufferAccess(mapVkFormat(format), m_width, m_height, m_layers, pData))
439 const int m_1dModifier;
441 const tcu::ConstPixelBufferAccess m_wholeImage;
444 inline bool compareColors (const Vec4& colorA, const Vec4& colorB, const Vec4& threshold)
446 return tcu::allEqual(
447 tcu::lessThan(tcu::abs(colorA - colorB), threshold),
448 tcu::BVec4(true, true, true, true));
451 bool verifyImageSingleColoredRow (tcu::TestLog& log, const tcu::ConstPixelBufferAccess image, const float rowWidthRatio, const tcu::Vec4& barColor)
453 DE_ASSERT(rowWidthRatio > 0.0f);
455 const Vec4 black (0.0f, 0.0f, 0.0f, 1.0f);
456 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
457 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
458 const Vec4 threshold (0.02f);
459 const int barLength = static_cast<int>(rowWidthRatio * static_cast<float>(image.getWidth()));
460 const int barLengthThreshold = 1;
461 tcu::TextureLevel errorMask (image.getFormat(), image.getWidth(), image.getHeight());
462 tcu::PixelBufferAccess errorMaskAccess = errorMask.getAccess();
464 tcu::clear(errorMask.getAccess(), green);
466 log << tcu::TestLog::Message
467 << "Expecting all pixels with distance less or equal to (about) " << barLength
468 << " pixels from left border to be of color " << barColor.swizzle(0, 1, 2) << "."
469 << tcu::TestLog::EndMessage;
471 bool allPixelsOk = true;
473 for (int y = 0; y < image.getHeight(); ++y)
474 for (int x = 0; x < image.getWidth(); ++x)
476 const Vec4 color = image.getPixel(x, y);
477 const bool isBlack = compareColors(color, black, threshold);
478 const bool isColor = compareColors(color, barColor, threshold);
482 if (x <= barLength - barLengthThreshold)
484 else if (x >= barLength + barLengthThreshold)
487 isOk = isColor || isBlack;
492 errorMaskAccess.setPixel(red, x, y);
497 log << tcu::TestLog::Message << "Image is valid." << tcu::TestLog::EndMessage
498 << tcu::TestLog::ImageSet("LayerContent", "Layer content")
499 << tcu::TestLog::Image("Layer", "Layer", image)
500 << tcu::TestLog::EndImageSet;
505 log << tcu::TestLog::Message << "Image verification failed. Got unexpected pixels." << tcu::TestLog::EndMessage
506 << tcu::TestLog::ImageSet("LayerContent", "Layer content")
507 << tcu::TestLog::Image("Layer", "Layer", image)
508 << tcu::TestLog::Image("ErrorMask", "Errors", errorMask)
509 << tcu::TestLog::EndImageSet;
513 log << tcu::TestLog::Image("LayerContent", "Layer content", image);
518 bool verifyEmptyImage (tcu::TestLog& log, const tcu::ConstPixelBufferAccess image)
520 log << tcu::TestLog::Message << "Expecting empty image" << tcu::TestLog::EndMessage;
522 const Vec4 black (0.0f, 0.0f, 0.0f, 1.0f);
523 const Vec4 threshold (0.02f);
525 for (int y = 0; y < image.getHeight(); ++y)
526 for (int x = 0; x < image.getWidth(); ++x)
528 const Vec4 color = image.getPixel(x, y);
530 if (!compareColors(color, black, threshold))
532 log << tcu::TestLog::Message
533 << "Found (at least) one bad pixel at " << x << "," << y << ". Pixel color is not background color."
534 << tcu::TestLog::EndMessage
535 << tcu::TestLog::ImageSet("LayerContent", "Layer content")
536 << tcu::TestLog::Image("Layer", "Layer", image)
537 << tcu::TestLog::EndImageSet;
542 log << tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage;
547 bool verifyLayerContent (tcu::TestLog& log, const TestType testType, const tcu::ConstPixelBufferAccess image, const int layerNdx, const int numLayers)
549 const Vec4 white (1.0f, 1.0f, 1.0f, 1.0f);
550 const int targetLayer = numLayers / 2;
551 const float variableBarRatio = static_cast<float>(layerNdx) / static_cast<float>(numLayers);
555 case TEST_TYPE_DEFAULT_LAYER:
557 return verifyImageSingleColoredRow(log, image, 0.5f, white);
559 return verifyEmptyImage(log, image);
561 case TEST_TYPE_SINGLE_LAYER:
562 if (layerNdx == targetLayer)
563 return verifyImageSingleColoredRow(log, image, 0.5f, white);
565 return verifyEmptyImage(log, image);
567 case TEST_TYPE_ALL_LAYERS:
568 case TEST_TYPE_INVOCATION_PER_LAYER:
569 return verifyImageSingleColoredRow(log, image, 0.5f, s_colors[layerNdx % DE_LENGTH_OF_ARRAY(s_colors)]);
571 case TEST_TYPE_DIFFERENT_CONTENT:
572 case TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION:
574 return verifyEmptyImage(log, image);
576 return verifyImageSingleColoredRow(log, image, variableBarRatio, white);
578 case TEST_TYPE_LAYER_ID:
580 // This code must be in sync with the fragment shader.
581 const tcu::Vec4 layerColor( (layerNdx % 2) == 1 ? 1.0f : 0.5f,
582 ((layerNdx/2) % 2) == 1 ? 1.0f : 0.5f,
583 layerNdx == 0 ? 1.0f : 0.0f,
585 return verifyImageSingleColoredRow(log, image, 0.5f, layerColor);
594 std::string getLayerDescription (const VkImageViewType viewType, const int layer)
596 std::ostringstream str;
597 const int numCubeFaces = 6;
599 if (isCubeImageViewType(viewType))
600 str << "cube " << (layer / numCubeFaces) << ", face " << (layer % numCubeFaces);
601 else if (viewType == VK_IMAGE_VIEW_TYPE_3D)
602 str << "slice z = " << layer;
604 str << "layer " << layer;
609 bool verifyResults (tcu::TestLog& log, const TestParams& params, const VkFormat colorFormat, const void* resultData)
611 const LayeredImageAccess image = LayeredImageAccess::create(getImageType(params.image.viewType), colorFormat, params.image.size, params.image.numLayers, resultData);
613 int numGoodLayers = 0;
615 for (int layerNdx = 0; layerNdx < image.getNumLayersOrSlices(); ++layerNdx)
617 const tcu::ConstPixelBufferAccess layerImage = image.getLayer(layerNdx);
619 log << tcu::TestLog::Message << "Verifying " << getLayerDescription(params.image.viewType, layerNdx) << tcu::TestLog::EndMessage;
621 if (verifyLayerContent(log, params.testType, layerImage, layerNdx, image.getNumLayersOrSlices()))
625 return numGoodLayers == image.getNumLayersOrSlices();
628 std::string toGlsl (const Vec4& v)
630 std::ostringstream str;
632 for (int i = 0; i < 4; ++i)
633 str << (i != 0 ? ", " : "") << de::floatToString(v[i], 1);
638 void initPrograms (SourceCollections& programCollection, const TestParams params)
640 const bool geomOutputColor = (params.testType == TEST_TYPE_ALL_LAYERS || params.testType == TEST_TYPE_INVOCATION_PER_LAYER);
644 std::ostringstream src;
645 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
647 << "void main(void)\n"
651 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
656 const int numLayers = static_cast<int>(params.image.viewType == VK_IMAGE_VIEW_TYPE_3D ? params.image.size.depth : params.image.numLayers);
658 const int maxVertices = (params.testType == TEST_TYPE_DIFFERENT_CONTENT) ? (numLayers + 1) * numLayers :
659 (params.testType == TEST_TYPE_ALL_LAYERS || params.testType == TEST_TYPE_LAYER_ID) ? numLayers * 4 :
660 (params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION) ? 6 : 4;
662 std::ostringstream src;
663 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
666 if (params.testType == TEST_TYPE_INVOCATION_PER_LAYER || params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION)
667 src << "layout(points, invocations = " << numLayers << ") in;\n";
669 src << "layout(points) in;\n";
671 src << "layout(triangle_strip, max_vertices = " << maxVertices << ") out;\n"
673 << (geomOutputColor ? "layout(location = 0) out vec4 vert_color;\n\n" : "")
674 << "out gl_PerVertex {\n"
675 << " vec4 gl_Position;\n"
678 << "void main(void)\n"
681 std::ostringstream colorTable;
683 const int numColors = DE_LENGTH_OF_ARRAY(s_colors);
685 colorTable << " const vec4 colors[" << numColors << "] = vec4[" << numColors << "](";
687 const std::string padding(colorTable.str().length(), ' ');
689 for (int i = 0; i < numColors; ++i)
690 colorTable << (i != 0 ? ",\n" + padding : "") << toGlsl(s_colors[i]);
692 colorTable << ");\n";
695 if (params.testType == TEST_TYPE_DEFAULT_LAYER)
697 src << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
698 << " EmitVertex();\n"
700 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
701 << " EmitVertex();\n"
703 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
704 << " EmitVertex();\n"
706 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n"
707 << " EmitVertex();\n";
709 else if (params.testType == TEST_TYPE_SINGLE_LAYER)
711 const deUint32 targetLayer = getTargetLayer(params.image);
713 src << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
714 << " gl_Layer = " << targetLayer << ";\n"
715 << " EmitVertex();\n"
717 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
718 << " gl_Layer = " << targetLayer << ";\n"
719 << " EmitVertex();\n"
721 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
722 << " gl_Layer = " << targetLayer << ";\n"
723 << " EmitVertex();\n"
725 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n"
726 << " gl_Layer = " << targetLayer << ";\n"
727 << " EmitVertex();\n";
729 else if (params.testType == TEST_TYPE_ALL_LAYERS)
731 src << colorTable.str()
733 << " for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n"
734 << " const int colorNdx = layerNdx % " << DE_LENGTH_OF_ARRAY(s_colors) << ";\n"
736 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
737 << " gl_Layer = layerNdx;\n"
738 << " vert_color = colors[colorNdx];\n"
739 << " EmitVertex();\n"
741 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
742 << " gl_Layer = layerNdx;\n"
743 << " vert_color = colors[colorNdx];\n"
744 << " EmitVertex();\n"
746 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
747 << " gl_Layer = layerNdx;\n"
748 << " vert_color = colors[colorNdx];\n"
749 << " EmitVertex();\n"
751 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n"
752 << " gl_Layer = layerNdx;\n"
753 << " vert_color = colors[colorNdx];\n"
754 << " EmitVertex();\n"
755 << " EndPrimitive();\n"
758 else if (params.testType == TEST_TYPE_LAYER_ID)
760 src << " for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n"
761 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
762 << " gl_Layer = layerNdx;\n"
763 << " EmitVertex();\n"
765 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
766 << " gl_Layer = layerNdx;\n"
767 << " EmitVertex();\n"
769 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
770 << " gl_Layer = layerNdx;\n"
771 << " EmitVertex();\n"
773 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n"
774 << " gl_Layer = layerNdx;\n"
775 << " EmitVertex();\n"
776 << " EndPrimitive();\n"
779 else if (params.testType == TEST_TYPE_DIFFERENT_CONTENT)
781 src << " for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n"
782 << " for (int colNdx = 0; colNdx <= layerNdx; ++colNdx) {\n"
783 << " const float posX = float(colNdx) / float(" << numLayers << ") * 2.0 - 1.0;\n"
785 << " gl_Position = vec4(posX, 1.0, 0.0, 1.0);\n"
786 << " gl_Layer = layerNdx;\n"
787 << " EmitVertex();\n"
789 << " gl_Position = vec4(posX, -1.0, 0.0, 1.0);\n"
790 << " gl_Layer = layerNdx;\n"
791 << " EmitVertex();\n"
793 << " EndPrimitive();\n"
796 else if (params.testType == TEST_TYPE_INVOCATION_PER_LAYER)
798 src << colorTable.str()
799 << " const int colorNdx = gl_InvocationID % " << DE_LENGTH_OF_ARRAY(s_colors) << ";\n"
801 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
802 << " gl_Layer = gl_InvocationID;\n"
803 << " vert_color = colors[colorNdx];\n"
804 << " EmitVertex();\n"
806 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
807 << " gl_Layer = gl_InvocationID;\n"
808 << " vert_color = colors[colorNdx];\n"
809 << " EmitVertex();\n"
811 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
812 << " gl_Layer = gl_InvocationID;\n"
813 << " vert_color = colors[colorNdx];\n"
814 << " EmitVertex();\n"
816 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n"
817 << " gl_Layer = gl_InvocationID;\n"
818 << " vert_color = colors[colorNdx];\n"
819 << " EmitVertex();\n"
820 << " EndPrimitive();\n";
822 else if (params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION)
824 src << " const int layerA = gl_InvocationID;\n"
825 << " const int layerB = (gl_InvocationID + 1) % " << numLayers << ";\n"
826 << " const float aEnd = float(layerA) / float(" << numLayers << ") * 2.0 - 1.0;\n"
827 << " const float bEnd = float(layerB) / float(" << numLayers << ") * 2.0 - 1.0;\n"
829 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
830 << " gl_Layer = layerA;\n"
831 << " EmitVertex();\n"
833 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
834 << " gl_Layer = layerA;\n"
835 << " EmitVertex();\n"
837 << " gl_Position = vec4(aEnd, -1.0, 0.0, 1.0);\n"
838 << " gl_Layer = layerA;\n"
839 << " EmitVertex();\n"
840 << " EndPrimitive();\n"
842 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
843 << " gl_Layer = layerB;\n"
844 << " EmitVertex();\n"
846 << " gl_Position = vec4(bEnd, 1.0, 0.0, 1.0);\n"
847 << " gl_Layer = layerB;\n"
848 << " EmitVertex();\n"
850 << " gl_Position = vec4(bEnd, -1.0, 0.0, 1.0);\n"
851 << " gl_Layer = layerB;\n"
852 << " EmitVertex();\n"
853 << " EndPrimitive();\n";
858 src << "}\n"; // end main
860 programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
865 std::ostringstream src;
866 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
868 << "layout(location = 0) out vec4 o_color;\n"
869 << (geomOutputColor ? "layout(location = 0) in vec4 vert_color;\n" : "")
871 << "void main(void)\n"
874 if (params.testType == TEST_TYPE_LAYER_ID)
876 // This code must be in sync with verifyLayerContent()
877 src << " o_color = vec4( (gl_Layer % 2) == 1 ? 1.0 : 0.5,\n"
878 << " ((gl_Layer/2) % 2) == 1 ? 1.0 : 0.5,\n"
879 << " gl_Layer == 0 ? 1.0 : 0.0,\n"
882 else if (geomOutputColor)
883 src << " o_color = vert_color;\n";
885 src << " o_color = vec4(1.0);\n";
889 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
893 tcu::TestStatus test (Context& context, const TestParams params)
895 if (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType &&
896 (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance1")))
897 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
899 const DeviceInterface& vk = context.getDeviceInterface();
900 const InstanceInterface& vki = context.getInstanceInterface();
901 const VkDevice device = context.getDevice();
902 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
903 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
904 const VkQueue queue = context.getUniversalQueue();
905 Allocator& allocator = context.getDefaultAllocator();
907 checkGeometryShaderSupport(vki, physDevice);
909 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
910 const deUint32 numLayers = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? params.image.size.depth : params.image.numLayers);
911 const Vec4 clearColor = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
912 const VkDeviceSize colorBufferSize = params.image.size.width * params.image.size.height * params.image.size.depth * params.image.numLayers * tcu::getPixelSize(mapVkFormat(colorFormat));
913 const VkImageCreateFlags imageCreateFlags = (isCubeImageViewType(params.image.viewType) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlagBits)0) |
914 (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR : (VkImageCreateFlagBits)0);
915 const VkImageViewType viewType = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : params.image.viewType);
917 const Unique<VkImage> colorImage (makeImage (vk, device, makeImageCreateInfo(imageCreateFlags, getImageType(params.image.viewType), colorFormat, params.image.size,
918 params.image.numLayers, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)));
919 const UniquePtr<Allocation> colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any));
920 const Unique<VkImageView> colorAttachment (makeImageView (vk, device, *colorImage, viewType, colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, numLayers)));
922 const Unique<VkBuffer> colorBuffer (makeBuffer (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
923 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
925 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, context.getBinaryCollection().get("vert"), 0u));
926 const Unique<VkShaderModule> geometryModule (createShaderModule (vk, device, context.getBinaryCollection().get("geom"), 0u));
927 const Unique<VkShaderModule> fragmentModule (createShaderModule (vk, device, context.getBinaryCollection().get("frag"), 0u));
929 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, colorFormat));
930 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, *colorAttachment, params.image.size.width, params.image.size.height, numLayers));
931 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout (vk, device));
932 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, *geometryModule, *fragmentModule,
933 makeExtent2D(params.image.size.width, params.image.size.height)));
934 const Unique<VkCommandPool> cmdPool (makeCommandPool (vk, device, queueFamilyIndex));
935 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer (vk, device, *cmdPool));
937 zeroBuffer(vk, device, *colorBufferAlloc, colorBufferSize);
939 beginCommandBuffer(vk, *cmdBuffer);
941 const VkClearValue clearValue = makeClearValueColor(clearColor);
942 const VkRect2D renderArea =
945 makeExtent2D(params.image.size.width, params.image.size.height),
947 const VkRenderPassBeginInfo renderPassBeginInfo =
949 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
950 DE_NULL, // const void* pNext;
951 *renderPass, // VkRenderPass renderPass;
952 *framebuffer, // VkFramebuffer framebuffer;
953 renderArea, // VkRect2D renderArea;
954 1u, // uint32_t clearValueCount;
955 &clearValue, // const VkClearValue* pClearValues;
957 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
959 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
960 vk.cmdDraw(*cmdBuffer, 1u, 1u, 0u, 0u);
961 vk.cmdEndRenderPass(*cmdBuffer);
963 // Prepare color image for copy
965 const VkImageSubresourceRange colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, params.image.numLayers);
966 const VkImageMemoryBarrier barriers[] =
969 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
970 DE_NULL, // const void* pNext;
971 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags outputMask;
972 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags inputMask;
973 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
974 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
975 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
976 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
977 *colorImage, // VkImage image;
978 colorSubresourceRange, // VkImageSubresourceRange subresourceRange;
982 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
983 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers);
985 // Color image -> host buffer
987 const VkBufferImageCopy region =
989 0ull, // VkDeviceSize bufferOffset;
990 0u, // uint32_t bufferRowLength;
991 0u, // uint32_t bufferImageHeight;
992 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, params.image.numLayers), // VkImageSubresourceLayers imageSubresource;
993 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
994 params.image.size, // VkExtent3D imageExtent;
997 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ®ion);
999 // Buffer write barrier
1001 const VkBufferMemoryBarrier barriers[] =
1004 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1005 DE_NULL, // const void* pNext;
1006 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1007 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
1008 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1009 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1010 *colorBuffer, // VkBuffer buffer;
1011 0ull, // VkDeviceSize offset;
1012 VK_WHOLE_SIZE, // VkDeviceSize size;
1016 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
1017 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers, DE_NULL, 0u);
1020 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1021 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1023 invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), colorBufferSize);
1025 if (!verifyResults(context.getTestContext().getLog(), params, colorFormat, colorBufferAlloc->getHostPtr()))
1026 return tcu::TestStatus::fail("Rendered images are incorrect");
1028 return tcu::TestStatus::pass("OK");
1033 tcu::TestCaseGroup* createLayeredRenderingTests (tcu::TestContext& testCtx)
1035 MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "layered", "Layered rendering tests."));
1041 const char* description;
1044 { TEST_TYPE_DEFAULT_LAYER, "render_to_default_layer", "Render to the default layer" },
1045 { TEST_TYPE_SINGLE_LAYER, "render_to_one", "Render to one layer" },
1046 { TEST_TYPE_ALL_LAYERS, "render_to_all", "Render to all layers" },
1047 { TEST_TYPE_DIFFERENT_CONTENT, "render_different_content", "Render different data to different layers" },
1048 { TEST_TYPE_LAYER_ID, "fragment_layer", "Read gl_Layer in fragment shader" },
1049 { TEST_TYPE_INVOCATION_PER_LAYER, "invocation_per_layer", "Render to multiple layers with multiple invocations, one invocation per layer" },
1050 { TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION, "multiple_layers_per_invocation", "Render to multiple layers with multiple invocations, multiple layers per invocation", },
1053 const ImageParams imageParams[] =
1055 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, { 64, 1, 1 }, 4 },
1056 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, { 64, 64, 1 }, 4 },
1057 { VK_IMAGE_VIEW_TYPE_CUBE, { 64, 64, 1 }, 6 },
1058 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, { 64, 64, 1 }, 2*6 },
1059 { VK_IMAGE_VIEW_TYPE_3D, { 64, 64, 8 }, 1 }
1062 for (int imageParamNdx = 0; imageParamNdx < DE_LENGTH_OF_ARRAY(imageParams); ++imageParamNdx)
1064 MovePtr<tcu::TestCaseGroup> viewTypeGroup(new tcu::TestCaseGroup(testCtx, getShortImageViewTypeName(imageParams[imageParamNdx].viewType).c_str(), ""));
1066 for (int testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
1068 const TestParams params =
1070 testTypes[testTypeNdx].test,
1071 imageParams[imageParamNdx],
1073 addFunctionCaseWithPrograms(viewTypeGroup.get(), testTypes[testTypeNdx].name, testTypes[testTypeNdx].description, initPrograms, test, params);
1076 group->addChild(viewTypeGroup.release());
1079 return group.release();