1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2019 Google Inc.
6 * Copyright (c) 2019 The Khronos Group Inc.
7 * Copyright (c) 2014 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Geometry shader layered rendering tests
24 *//*--------------------------------------------------------------------*/
26 #include "vktGeometryLayeredRenderingTests.hpp"
27 #include "vktTestCase.hpp"
28 #include "vktTestCaseUtil.hpp"
29 #include "vktGeometryTestsUtil.hpp"
31 #include "vkPrograms.hpp"
32 #include "vkStrUtil.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkRefUtil.hpp"
36 #include "vkBarrierUtil.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkImageUtil.hpp"
39 #include "vkBuilderUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 #include "vkObjUtil.hpp"
43 #include "deStringUtil.hpp"
44 #include "deUniquePtr.hpp"
46 #include "tcuTextureUtil.hpp"
47 #include "tcuVectorUtil.hpp"
48 #include "tcuTestLog.hpp"
64 TEST_TYPE_DEFAULT_LAYER, // !< draw to default layer
65 TEST_TYPE_SINGLE_LAYER, // !< draw to single layer
66 TEST_TYPE_ALL_LAYERS, // !< draw all layers
67 TEST_TYPE_DIFFERENT_CONTENT, // !< draw different content to different layers
68 TEST_TYPE_LAYER_ID, // !< draw to all layers, verify gl_Layer fragment input
69 TEST_TYPE_INVOCATION_PER_LAYER, // !< draw to all layers, one invocation per layer
70 TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION, // !< draw to all layers, multiple invocations write to multiple layers
71 TEST_TYPE_LAYERED_READBACK, // !< draw to two layers multiple times
72 TEST_TYPE_SECONDARY_CMD_BUFFER // !< layered rendering using secondary command buffer
77 VkImageViewType viewType;
86 bool inheritFramebuffer;
89 const float s_colors[][4] =
91 { 1.0f, 1.0f, 1.0f, 1.0f }, // white
92 { 1.0f, 0.0f, 0.0f, 1.0f }, // red
93 { 0.0f, 1.0f, 0.0f, 1.0f }, // green
94 { 0.0f, 0.0f, 1.0f, 1.0f }, // blue
95 { 1.0f, 1.0f, 0.0f, 1.0f }, // yellow
96 { 1.0f, 0.0f, 1.0f, 1.0f }, // magenta
99 const tcu::Vec4 secondaryCmdBufClearColors[] =
101 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
102 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
103 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
104 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
105 tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f),
106 tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f)
109 tcu::Vec4 scaleColor(const tcu::Vec4& color, float factor)
111 return tcu::Vec4(color[0] * factor,
117 deUint32 getTargetLayer (const ImageParams& imageParams)
119 if (imageParams.viewType == VK_IMAGE_VIEW_TYPE_3D)
120 return imageParams.size.depth / 2;
122 return imageParams.numLayers / 2;
125 std::string getShortImageViewTypeName (const VkImageViewType imageViewType)
127 std::string s(getImageViewTypeName(imageViewType));
128 return de::toLower(s.substr(19));
131 VkImageType getImageType (const VkImageViewType viewType)
135 case VK_IMAGE_VIEW_TYPE_1D:
136 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
137 return VK_IMAGE_TYPE_1D;
139 case VK_IMAGE_VIEW_TYPE_2D:
140 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
141 case VK_IMAGE_VIEW_TYPE_CUBE:
142 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
143 return VK_IMAGE_TYPE_2D;
145 case VK_IMAGE_VIEW_TYPE_3D:
146 return VK_IMAGE_TYPE_3D;
150 return VK_IMAGE_TYPE_LAST;
154 VkFormat getStencilBufferFormat(VkFormat depthStencilImageFormat)
156 const tcu::TextureFormat tcuFormat = mapVkFormat(depthStencilImageFormat);
157 const VkFormat result = (tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS) ? VK_FORMAT_S8_UINT : VK_FORMAT_UNDEFINED;
159 DE_ASSERT(result != VK_FORMAT_UNDEFINED);
164 inline bool isCubeImageViewType (const VkImageViewType viewType)
166 return viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
169 void checkImageFormatProperties (const InstanceInterface& vki,
170 const VkPhysicalDevice& physDevice,
171 const VkImageType& imageType,
172 const VkImageTiling& imageTiling,
173 const VkImageUsageFlags imageUsageFlags,
174 const VkImageCreateFlags imageCreateFlags,
175 const VkFormat format,
176 const VkExtent3D& requiredSize,
177 const deUint32 requiredLayers)
179 VkImageFormatProperties imageFormatProperties;
182 deMemset(&imageFormatProperties, 0, sizeof(imageFormatProperties));
184 result = vki.getPhysicalDeviceImageFormatProperties(physDevice, format, imageType, imageTiling, imageUsageFlags, imageCreateFlags, &imageFormatProperties);
186 if (result != VK_SUCCESS ||
187 imageFormatProperties.maxArrayLayers < requiredLayers ||
188 imageFormatProperties.maxExtent.height < requiredSize.height ||
189 imageFormatProperties.maxExtent.width < requiredSize.width ||
190 imageFormatProperties.maxExtent.depth < requiredSize.depth)
192 TCU_THROW(NotSupportedError, "Depth/stencil format is not supported");
196 VkImageCreateInfo makeImageCreateInfo (const VkImageCreateFlags flags, const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const VkImageUsageFlags usage)
198 const VkImageCreateInfo imageParams =
200 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
201 DE_NULL, // const void* pNext;
202 flags, // VkImageCreateFlags flags;
203 type, // VkImageType imageType;
204 format, // VkFormat format;
205 size, // VkExtent3D extent;
206 1u, // deUint32 mipLevels;
207 numLayers, // deUint32 arrayLayers;
208 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
209 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
210 usage, // VkImageUsageFlags usage;
211 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
212 0u, // deUint32 queueFamilyIndexCount;
213 DE_NULL, // const deUint32* pQueueFamilyIndices;
214 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
219 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
220 const VkDevice device,
221 const VkFormat colorFormat,
222 const VkFormat dsFormat,
223 const bool useDepthStencil)
225 return vk::makeRenderPass(vk, device, colorFormat, useDepthStencil ? dsFormat : VK_FORMAT_UNDEFINED, VK_ATTACHMENT_LOAD_OP_LOAD);
228 Move<VkRenderPass> makeRenderPassWithSelfDependency (const DeviceInterface& vk,
229 const VkDevice device,
230 const VkFormat colorFormat)
232 const VkAttachmentDescription attachmentDescription =
234 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
235 colorFormat, // VkFormat format
236 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
237 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
238 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
239 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
240 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
241 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
242 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
245 const VkAttachmentReference colorAttachmentRef =
247 0u, // deUint32 attachment
248 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
251 const VkSubpassDescription subpassDescription =
253 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
254 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
255 0u, // deUint32 inputAttachmentCount
256 DE_NULL, // const VkAttachmentReference* pInputAttachments
257 1u, // deUint32 colorAttachmentCount
258 &colorAttachmentRef, // const VkAttachmentReference* pColorAttachments
259 DE_NULL, // const VkAttachmentReference* pResolveAttachments
260 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment
261 0u, // deUint32 preserveAttachmentCount
262 DE_NULL // const deUint32* pPreserveAttachments
265 const VkSubpassDependency subpassDependency =
267 0u, // deUint32 srcSubpass
268 0u, // deUint32 dstSubpass
269 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags srcStageMask
270 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask
271 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask
272 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask
273 VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags
276 const VkRenderPassCreateInfo renderPassInfo =
278 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType
279 DE_NULL, // const void* pNext
280 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
281 1u, // deUint32 attachmentCount
282 &attachmentDescription, // const VkAttachmentDescription* pAttachments
283 1u, // deUint32 subpassCount
284 &subpassDescription, // const VkSubpassDescription* pSubpasses
285 1u, // deUint32 dependencyCount
286 &subpassDependency // const VkSubpassDependency* pDependencies
289 return createRenderPass(vk, device, &renderPassInfo);
292 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
293 const VkDevice device,
294 const VkPipelineLayout pipelineLayout,
295 const VkRenderPass renderPass,
296 const VkShaderModule vertexModule,
297 const VkShaderModule geometryModule,
298 const VkShaderModule fragmentModule,
299 const VkExtent2D renderSize,
300 const bool useDepthStencil = false)
302 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
303 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
305 const VkStencilOpState stencilOpState = makeStencilOpState(
306 VK_STENCIL_OP_KEEP, // stencil fail
307 VK_STENCIL_OP_INCREMENT_AND_CLAMP, // depth & stencil pass
308 VK_STENCIL_OP_KEEP, // depth only fail
309 VK_COMPARE_OP_ALWAYS, // compare op
314 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
316 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
317 DE_NULL, // const void* pNext
318 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags
319 useDepthStencil ? VK_TRUE : VK_FALSE, // VkBool32 depthTestEnable
320 useDepthStencil ? VK_TRUE : VK_FALSE, // VkBool32 depthWriteEnable
321 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp
322 VK_FALSE, // VkBool32 depthBoundsTestEnable
323 useDepthStencil ? VK_TRUE : VK_FALSE, // VkBool32 stencilTestEnable
324 stencilOpState, // VkStencilOpState front
325 stencilOpState, // VkStencilOpState back
326 0.0f, // float minDepthBounds
327 1.0f // float maxDepthBounds
330 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
332 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
333 DE_NULL, // const void* pNext
334 0u, // VkPipelineVertexInputStateCreateFlags flags
335 0u, // deUint32 vertexBindingDescriptionCount
336 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
337 0u, // deUint32 vertexAttributeDescriptionCount
338 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
341 return vk::makeGraphicsPipeline(vk, // const DeviceInterface& vk
342 device, // const VkDevice device
343 pipelineLayout, // const VkPipelineLayout pipelineLayout
344 vertexModule, // const VkShaderModule vertexShaderModule
345 DE_NULL, // const VkShaderModule tessellationControlModule
346 DE_NULL, // const VkShaderModule tessellationEvalModule
347 geometryModule, // const VkShaderModule geometryShaderModule
348 fragmentModule, // const VkShaderModule fragmentShaderModule
349 renderPass, // const VkRenderPass renderPass
350 viewports, // const std::vector<VkViewport>& viewports
351 scissors, // const std::vector<VkRect2D>& scissors
352 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // const VkPrimitiveTopology topology
353 0u, // const deUint32 subpass
354 0u, // const deUint32 patchControlPoints
355 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
356 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
357 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
358 &pipelineDepthStencilStateInfo); // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
361 void copyLayeredImageToBuffer(const DeviceInterface& vk, VkCommandBuffer cmdBuffer, VkImage image, VkBuffer buffer, const ImageParams& imageParams)
363 // Image read barrier
365 const VkImageSubresourceRange colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, imageParams.numLayers);
366 const VkImageMemoryBarrier barrier =
368 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
369 DE_NULL, // const void* pNext
370 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags outputMask
371 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags inputMask
372 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout
373 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout
374 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex
375 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex
376 image, // VkImage image
377 colorSubresourceRange // VkImageSubresourceRange subresourceRange
380 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
382 // Color image -> host buffer
384 const VkBufferImageCopy region =
386 0ull, // VkDeviceSize bufferOffset
387 0u, // deUint32 bufferRowLength
388 0u, // deUint32 bufferImageHeight
389 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageParams.numLayers), // VkImageSubresourceLayers imageSubresource
390 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset
391 imageParams.size // VkExtent3D imageExtent
394 vk.cmdCopyImageToBuffer(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, ®ion);
396 // Buffer write barrier
398 const VkBufferMemoryBarrier barrier =
400 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType
401 DE_NULL, // const void* pNext
402 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
403 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask
404 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex
405 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex
406 buffer, // VkBuffer buffer
407 0ull, // VkDeviceSize offset
408 VK_WHOLE_SIZE // VkDeviceSize size
411 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, DE_NULL, 0u);
415 //! Convenience wrapper to access 1D, 2D, and 3D image layers/slices in a uniform way.
416 class LayeredImageAccess
419 static LayeredImageAccess create (const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const void* pData)
421 if (type == VK_IMAGE_TYPE_1D)
422 return LayeredImageAccess(format, size.width, numLayers, pData);
424 return LayeredImageAccess(type, format, size, numLayers, pData);
427 inline tcu::ConstPixelBufferAccess getLayer (const int layer) const
429 return tcu::getSubregion(m_wholeImage, 0, (m_1dModifier * layer), ((~m_1dModifier & 1) * layer), m_width, m_height, 1);
432 inline int getNumLayersOrSlices (void) const
438 // Specialized for 1D images.
439 LayeredImageAccess (const VkFormat format, const deUint32 width, const deUint32 numLayers, const void* pData)
440 : m_width (static_cast<int>(width))
443 , m_layers (numLayers)
444 , m_wholeImage (tcu::ConstPixelBufferAccess(mapVkFormat(format), m_width, m_layers, 1, pData))
448 LayeredImageAccess (const VkImageType type, const VkFormat format, const VkExtent3D size, const deUint32 numLayers, const void* pData)
449 : m_width (static_cast<int>(size.width))
450 , m_height (static_cast<int>(size.height))
452 , m_layers (static_cast<int>(type == VK_IMAGE_TYPE_3D ? size.depth : numLayers))
453 , m_wholeImage (tcu::ConstPixelBufferAccess(mapVkFormat(format), m_width, m_height, m_layers, pData))
459 const int m_1dModifier;
461 const tcu::ConstPixelBufferAccess m_wholeImage;
464 inline bool compareColors (const Vec4& colorA, const Vec4& colorB, const Vec4& threshold)
466 return tcu::allEqual(
467 tcu::lessThan(tcu::abs(colorA - colorB), threshold),
468 tcu::BVec4(true, true, true, true));
471 bool verifyImageSingleColoredRow (tcu::TestLog& log, const tcu::ConstPixelBufferAccess image, const float rowWidthRatio, const tcu::Vec4& barColor, bool topRightCleared = false, bool bottomRightCleared = false)
473 DE_ASSERT(rowWidthRatio > 0.0f);
475 const Vec4 black (0.0f, 0.0f, 0.0f, 1.0f);
476 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
477 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
478 const Vec4 brown (0.5f, 0.25f, 0.0f, 1.0f);
479 const Vec4 threshold (0.02f);
480 const int barLength = static_cast<int>(rowWidthRatio * static_cast<float>(image.getWidth()));
481 const int barLengthThreshold = 1;
482 tcu::TextureLevel errorMask (image.getFormat(), image.getWidth(), image.getHeight());
483 tcu::PixelBufferAccess errorMaskAccess = errorMask.getAccess();
485 tcu::clear(errorMask.getAccess(), green);
487 log << tcu::TestLog::Message
488 << "Expecting all pixels with distance less or equal to (about) " << barLength
489 << " pixels from left border to be of color " << barColor.swizzle(0, 1, 2) << "."
490 << tcu::TestLog::EndMessage;
492 bool allPixelsOk = true;
494 for (int y = 0; y < image.getHeight(); ++y)
495 for (int x = 0; x < image.getWidth(); ++x)
497 const Vec4 color = image.getPixel(x, y);
498 const bool isBlack = compareColors(color, black, threshold);
499 const bool isBrown = compareColors(color, brown, threshold);
500 const bool isColor = compareColors(color, barColor, threshold);
501 const bool isOutsideColor = ((topRightCleared && y < image.getHeight() / 2) || (bottomRightCleared && y >= image.getHeight() / 2)) ? isBrown : isBlack;
505 if (x <= barLength - barLengthThreshold)
507 else if (x >= barLength + barLengthThreshold)
509 isOk = isOutsideColor;
512 isOk = isColor || isOutsideColor;
517 errorMaskAccess.setPixel(red, x, y);
522 log << tcu::TestLog::Message << "Image is valid." << tcu::TestLog::EndMessage
523 << tcu::TestLog::ImageSet("LayerContent", "Layer content")
524 << tcu::TestLog::Image("Layer", "Layer", image)
525 << tcu::TestLog::EndImageSet;
530 log << tcu::TestLog::Message << "Image verification failed. Got unexpected pixels." << tcu::TestLog::EndMessage
531 << tcu::TestLog::ImageSet("LayerContent", "Layer content")
532 << tcu::TestLog::Image("Layer", "Layer", image)
533 << tcu::TestLog::Image("ErrorMask", "Errors", errorMask)
534 << tcu::TestLog::EndImageSet;
538 // Note: this is never reached
539 log << tcu::TestLog::Image("LayerContent", "Layer content", image);
544 static bool verifyImageMultipleBars (tcu::TestLog& log,
545 const tcu::ConstPixelBufferAccess image,
546 const float* barWidthRatios,
547 const tcu::Vec4* barValues,
549 const int numUsedChannels,
550 const std::string& imageTypeName)
552 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
553 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
554 const Vec4 threshold (0.02f);
555 const tcu::TextureFormat errorMaskFormat (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8));
556 tcu::TextureLevel errorMask (errorMaskFormat, image.getWidth(), image.getHeight());
557 tcu::PixelBufferAccess errorMaskAccess = errorMask.getAccess();
558 bool allPixelsOk = true;
560 DE_ASSERT(barsCount > 0);
562 tcu::clear(errorMask.getAccess(), green);
564 // Format information message
568 std::ostringstream str;
570 for (int barNdx = 0; barNdx < barsCount; ++barNdx)
572 leftBorder = rightBorder;
573 rightBorder = static_cast<int>(barWidthRatios[barNdx] * static_cast<float>(image.getWidth()));
575 DE_ASSERT(leftBorder < rightBorder);
577 str << std::endl << " [" << leftBorder << "," <<rightBorder << "): ";
579 switch (numUsedChannels)
581 case 1: str << barValues[barNdx][0]; break;
582 case 4: str << barValues[barNdx]; break;
583 default: DE_ASSERT(false); break;
587 log << tcu::TestLog::Message
588 << "Expecting " + imageTypeName + " values depending x-axis position to be of following values: "
590 << tcu::TestLog::EndMessage;
593 for (int x = 0; x < image.getWidth(); ++x)
595 tcu::Vec4 expectedValue = barValues[0];
597 for (int barNdx = 0; barNdx < barsCount; ++barNdx)
599 const int rightBorder = static_cast<int>(barWidthRatios[barNdx] * static_cast<float>(image.getWidth()));
603 expectedValue = barValues[barNdx];
609 for (int y = 0; y < image.getHeight(); ++y)
611 const tcu::Vec4 realValue = image.getPixel(x, y);
614 switch (numUsedChannels)
616 case 1: isOk = fabs(realValue[0] - expectedValue[0]) < threshold[0]; break;
617 case 4: isOk = compareColors(realValue, expectedValue, threshold); break;
618 default: DE_ASSERT(false); break;
622 errorMaskAccess.setPixel(red, x, y);
624 allPixelsOk = allPixelsOk && isOk;
630 log << tcu::TestLog::Message << "Image is valid." << tcu::TestLog::EndMessage
631 << tcu::TestLog::ImageSet(imageTypeName + "LayerContent", imageTypeName + " Layer Content")
632 << tcu::TestLog::Image("Layer", "Layer", image)
633 << tcu::TestLog::EndImageSet;
637 log << tcu::TestLog::Message << "Image verification failed. Got unexpected pixels." << tcu::TestLog::EndMessage
638 << tcu::TestLog::ImageSet(imageTypeName + "LayerContent", imageTypeName + " Layer Content")
639 << tcu::TestLog::Image("Layer", "Layer", image)
640 << tcu::TestLog::Image("ErrorMask", "Errors", errorMask)
641 << tcu::TestLog::EndImageSet;
647 static void convertDepthToColorBufferAccess (const tcu::ConstPixelBufferAccess& inputImage, tcu::PixelBufferAccess& outputImage)
649 for (int y = 0; y < inputImage.getHeight(); y++)
650 for (int x = 0; x < inputImage.getWidth(); x++)
652 const float depth = inputImage.getPixDepth(x, y);
653 const tcu::Vec4 color = tcu::Vec4(depth, depth, depth, 1.0f);
655 outputImage.setPixel(color, x, y);
659 static void convertStencilToColorBufferAccess (const tcu::ConstPixelBufferAccess& inputImage, tcu::PixelBufferAccess& outputImage, int maxValue)
661 for (int y = 0; y < inputImage.getHeight(); y++)
662 for (int x = 0; x < inputImage.getWidth(); x++)
664 const int stencilInt = inputImage.getPixStencil(x, y);
665 const float stencil = (stencilInt < maxValue) ? float(stencilInt) / float(maxValue) : 1.0f;
666 const tcu::Vec4 color = tcu::Vec4(stencil, stencil, stencil, 1.0f);
668 outputImage.setPixel(color, x, y);
672 bool verifyEmptyImage (tcu::TestLog& log, const tcu::ConstPixelBufferAccess image)
674 log << tcu::TestLog::Message << "Expecting empty image" << tcu::TestLog::EndMessage;
676 const Vec4 black (0.0f, 0.0f, 0.0f, 1.0f);
677 const Vec4 threshold (0.02f);
679 for (int y = 0; y < image.getHeight(); ++y)
680 for (int x = 0; x < image.getWidth(); ++x)
682 const Vec4 color = image.getPixel(x, y);
684 if (!compareColors(color, black, threshold))
686 log << tcu::TestLog::Message
687 << "Found (at least) one bad pixel at " << x << "," << y << ". Pixel color is not background color."
688 << tcu::TestLog::EndMessage
689 << tcu::TestLog::ImageSet("LayerContent", "Layer content")
690 << tcu::TestLog::Image("Layer", "Layer", image)
691 << tcu::TestLog::EndImageSet;
696 log << tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage;
701 bool verifyLayerContent (tcu::TestLog& log, const TestType testType, const tcu::ConstPixelBufferAccess image, const int layerNdx, const int numLayers, const bool depthCheck, const bool stencilCheck)
703 const Vec4 white (1.0f, 1.0f, 1.0f, 1.0f);
704 const int targetLayer = numLayers / 2;
705 const float variableBarRatio = static_cast<float>(layerNdx) / static_cast<float>(numLayers);
709 case TEST_TYPE_DEFAULT_LAYER:
711 return verifyImageSingleColoredRow(log, image, 0.5f, white);
713 return verifyEmptyImage(log, image);
715 case TEST_TYPE_SINGLE_LAYER:
716 if (layerNdx == targetLayer)
717 return verifyImageSingleColoredRow(log, image, 0.5f, white);
719 return verifyEmptyImage(log, image);
721 case TEST_TYPE_ALL_LAYERS:
722 case TEST_TYPE_INVOCATION_PER_LAYER:
723 return verifyImageSingleColoredRow(log, image, 0.5f, s_colors[layerNdx % DE_LENGTH_OF_ARRAY(s_colors)]);
725 case TEST_TYPE_DIFFERENT_CONTENT:
726 case TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION:
728 return verifyEmptyImage(log, image);
730 return verifyImageSingleColoredRow(log, image, variableBarRatio, white);
732 case TEST_TYPE_LAYER_ID:
734 // This code must be in sync with the fragment shader.
735 const tcu::Vec4 layerColor( (layerNdx % 2) == 1 ? 1.0f : 0.5f,
736 ((layerNdx/2) % 2) == 1 ? 1.0f : 0.5f,
737 layerNdx == 0 ? 1.0f : 0.0f,
739 return verifyImageSingleColoredRow(log, image, 0.5f, layerColor);
742 case TEST_TYPE_LAYERED_READBACK:
744 const float barWidthRatios[] = { 0.25f, 0.5f, 1.0f };
745 const int barsCount = DE_LENGTH_OF_ARRAY(barWidthRatios);
750 const std::string checkType = "Depth";
751 const float pass0depth = static_cast<float>(layerNdx + 1) / static_cast<float>(2 * numLayers);
752 const float pass1depth = static_cast<float>(layerNdx + 0) / static_cast<float>(2 * numLayers);
753 const tcu::Vec4 barDepths[barsCount] = { tcu::Vec4(pass1depth), tcu::Vec4(pass0depth), tcu::Vec4(1.0f) };
754 tcu::TextureLevel depthAsColorBuffer (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), image.getWidth(), image.getHeight());
755 tcu::PixelBufferAccess depthAsColor (depthAsColorBuffer);
756 const int numUsedChannels (tcu::getNumUsedChannels(depthAsColor.getFormat().order));
758 convertDepthToColorBufferAccess(image, depthAsColor);
760 result = verifyImageMultipleBars(log, depthAsColor, barWidthRatios, barDepths, barsCount, numUsedChannels, checkType);
762 else if (stencilCheck)
764 const std::string checkType = "Stencil";
765 const int maxStencilValue = 4;
766 const float pass0stencil = static_cast<float>(1.0f / maxStencilValue);
767 const float pass1stencil = static_cast<float>(2.0f / maxStencilValue);
768 const tcu::Vec4 barStencils[barsCount] = { tcu::Vec4(pass1stencil), tcu::Vec4(pass0stencil), tcu::Vec4(0.0f) };
769 tcu::TextureLevel stencilAsColorBuffer (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), image.getWidth(), image.getHeight());
770 tcu::PixelBufferAccess stencilAsColor (stencilAsColorBuffer);
771 const int numUsedChannels (tcu::getNumUsedChannels(stencilAsColor.getFormat().order));
773 convertStencilToColorBufferAccess(image, stencilAsColor, maxStencilValue);
775 result = verifyImageMultipleBars(log, stencilAsColor, barWidthRatios, barStencils, barsCount, numUsedChannels, checkType);
779 const std::string checkType = "Color";
780 const tcu::Vec4 baseColor (s_colors[layerNdx % DE_LENGTH_OF_ARRAY(s_colors)]);
781 const tcu::Vec4 barColors[barsCount] = { scaleColor(baseColor, 1.00f), scaleColor(baseColor, 0.50f), scaleColor(baseColor, 0.25f) };
782 const int numUsedChannels (tcu::getNumUsedChannels(image.getFormat().order));
784 result = verifyImageMultipleBars(log, image, barWidthRatios, barColors, barsCount, numUsedChannels, checkType);
790 case TEST_TYPE_SECONDARY_CMD_BUFFER:
792 const tcu::Vec4 clearColor = secondaryCmdBufClearColors[layerNdx % DE_LENGTH_OF_ARRAY(secondaryCmdBufClearColors)];
793 const tcu::Vec4 quadColor = s_colors[layerNdx % DE_LENGTH_OF_ARRAY(s_colors)];
794 // The first draw: blend clearColor and quadColor
795 const tcu::Vec4 firstDraw = (clearColor + quadColor) * 0.5f;
796 // The second draw: blend previous result and quadColor
797 const tcu::Vec4 secondDraw = (firstDraw + quadColor) * 0.5f;
799 return verifyImageSingleColoredRow(log, image, 0.5f, secondDraw, layerNdx < numLayers / 2, layerNdx >= numLayers / 2);
808 std::string getLayerDescription (const VkImageViewType viewType, const int layer)
810 std::ostringstream str;
811 const int numCubeFaces = 6;
813 if (isCubeImageViewType(viewType))
814 str << "cube " << (layer / numCubeFaces) << ", face " << (layer % numCubeFaces);
815 else if (viewType == VK_IMAGE_VIEW_TYPE_3D)
816 str << "slice z = " << layer;
818 str << "layer " << layer;
823 bool verifyResults (tcu::TestLog& log, const TestParams& params, const VkFormat imageFormat, const void* resultData, const bool depthCheck = false, const bool stencilCheck = false)
825 const LayeredImageAccess image = LayeredImageAccess::create(getImageType(params.image.viewType), imageFormat, params.image.size, params.image.numLayers, resultData);
827 int numGoodLayers = 0;
829 for (int layerNdx = 0; layerNdx < image.getNumLayersOrSlices(); ++layerNdx)
831 const tcu::ConstPixelBufferAccess layerImage = image.getLayer(layerNdx);
833 log << tcu::TestLog::Message << "Verifying " << getLayerDescription(params.image.viewType, layerNdx) << tcu::TestLog::EndMessage;
835 if (verifyLayerContent(log, params.testType, layerImage, layerNdx, image.getNumLayersOrSlices(), depthCheck, stencilCheck))
839 return numGoodLayers == image.getNumLayersOrSlices();
842 std::string toGlsl (const Vec4& v)
844 std::ostringstream str;
846 for (int i = 0; i < 4; ++i)
847 str << (i != 0 ? ", " : "") << de::floatToString(v[i], 1);
852 void initPrograms (SourceCollections& programCollection, const TestParams params)
854 const bool geomOutputColor = (params.testType == TEST_TYPE_ALL_LAYERS || params.testType == TEST_TYPE_INVOCATION_PER_LAYER || params.testType == TEST_TYPE_LAYERED_READBACK || params.testType == TEST_TYPE_SECONDARY_CMD_BUFFER);
858 std::ostringstream src;
859 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
861 << "void main(void)\n"
865 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
870 const int numLayers = static_cast<int>(params.image.viewType == VK_IMAGE_VIEW_TYPE_3D ? params.image.size.depth : params.image.numLayers);
872 const int maxVertices = (params.testType == TEST_TYPE_DIFFERENT_CONTENT) ? (numLayers + 1) * numLayers :
873 (params.testType == TEST_TYPE_ALL_LAYERS
874 || params.testType == TEST_TYPE_LAYER_ID
875 || params.testType == TEST_TYPE_LAYERED_READBACK
876 || params.testType == TEST_TYPE_SECONDARY_CMD_BUFFER) ? numLayers * 4 :
877 (params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION) ? 6 : 4;
879 std::ostringstream src;
880 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
883 if (params.testType == TEST_TYPE_LAYERED_READBACK)
884 src << "layout(binding = 0) readonly uniform Input {\n"
888 if (params.testType == TEST_TYPE_INVOCATION_PER_LAYER || params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION)
889 src << "layout(points, invocations = " << numLayers << ") in;\n";
891 src << "layout(points) in;\n";
893 src << "layout(triangle_strip, max_vertices = " << maxVertices << ") out;\n"
895 << (geomOutputColor ? "layout(location = 0) out vec4 vert_color;\n\n" : "")
896 << "out gl_PerVertex {\n"
897 << " vec4 gl_Position;\n"
898 << " float gl_PointSize;\n"
901 << "void main(void)\n"
904 std::ostringstream colorTable;
906 const int numColors = DE_LENGTH_OF_ARRAY(s_colors);
908 colorTable << " const vec4 colors[" << numColors << "] = vec4[" << numColors << "](";
910 const std::string padding(colorTable.str().length(), ' ');
912 for (int i = 0; i < numColors; ++i)
913 colorTable << (i != 0 ? ",\n" + padding : "") << toGlsl(s_colors[i]);
915 colorTable << ");\n";
918 if (params.testType == TEST_TYPE_DEFAULT_LAYER)
920 src << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
921 << " gl_PointSize = 1.0;\n"
922 << " EmitVertex();\n"
924 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
925 << " gl_PointSize = 1.0;\n"
926 << " EmitVertex();\n"
928 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
929 << " gl_PointSize = 1.0;\n"
930 << " EmitVertex();\n"
932 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n"
933 << " gl_PointSize = 1.0;\n"
934 << " EmitVertex();\n";
936 else if (params.testType == TEST_TYPE_SINGLE_LAYER)
938 const deUint32 targetLayer = getTargetLayer(params.image);
940 src << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
941 << " gl_Layer = " << targetLayer << ";\n"
942 << " gl_PointSize = 1.0;\n"
943 << " EmitVertex();\n"
945 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
946 << " gl_Layer = " << targetLayer << ";\n"
947 << " gl_PointSize = 1.0;\n"
948 << " EmitVertex();\n"
950 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
951 << " gl_Layer = " << targetLayer << ";\n"
952 << " gl_PointSize = 1.0;\n"
953 << " EmitVertex();\n"
955 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n"
956 << " gl_Layer = " << targetLayer << ";\n"
957 << " gl_PointSize = 1.0;\n"
958 << " EmitVertex();\n";
960 else if (params.testType == TEST_TYPE_ALL_LAYERS || params.testType == TEST_TYPE_SECONDARY_CMD_BUFFER)
962 src << colorTable.str()
964 << " for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n"
965 << " const int colorNdx = layerNdx % " << DE_LENGTH_OF_ARRAY(s_colors) << ";\n"
967 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
968 << " gl_Layer = layerNdx;\n"
969 << " vert_color = colors[colorNdx];\n"
970 << " gl_PointSize = 1.0;\n"
971 << " EmitVertex();\n"
973 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
974 << " gl_Layer = layerNdx;\n"
975 << " vert_color = colors[colorNdx];\n"
976 << " gl_PointSize = 1.0;\n"
977 << " EmitVertex();\n"
979 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
980 << " gl_Layer = layerNdx;\n"
981 << " vert_color = colors[colorNdx];\n"
982 << " gl_PointSize = 1.0;\n"
983 << " EmitVertex();\n"
985 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n"
986 << " gl_Layer = layerNdx;\n"
987 << " vert_color = colors[colorNdx];\n"
988 << " gl_PointSize = 1.0;\n"
989 << " EmitVertex();\n"
990 << " EndPrimitive();\n"
993 else if (params.testType == TEST_TYPE_LAYER_ID)
995 src << " for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n"
996 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
997 << " gl_Layer = layerNdx;\n"
998 << " gl_PointSize = 1.0;\n"
999 << " EmitVertex();\n"
1001 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
1002 << " gl_Layer = layerNdx;\n"
1003 << " gl_PointSize = 1.0;\n"
1004 << " EmitVertex();\n"
1006 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
1007 << " gl_Layer = layerNdx;\n"
1008 << " gl_PointSize = 1.0;\n"
1009 << " EmitVertex();\n"
1011 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n"
1012 << " gl_Layer = layerNdx;\n"
1013 << " gl_PointSize = 1.0;\n"
1014 << " EmitVertex();\n"
1015 << " EndPrimitive();\n"
1018 else if (params.testType == TEST_TYPE_DIFFERENT_CONTENT)
1020 src << " for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n"
1021 << " for (int colNdx = 0; colNdx <= layerNdx; ++colNdx) {\n"
1022 << " const float posX = float(colNdx) / float(" << numLayers << ") * 2.0 - 1.0;\n"
1024 << " gl_Position = vec4(posX, 1.0, 0.0, 1.0);\n"
1025 << " gl_Layer = layerNdx;\n"
1026 << " gl_PointSize = 1.0;\n"
1027 << " EmitVertex();\n"
1029 << " gl_Position = vec4(posX, -1.0, 0.0, 1.0);\n"
1030 << " gl_Layer = layerNdx;\n"
1031 << " gl_PointSize = 1.0;\n"
1032 << " EmitVertex();\n"
1034 << " EndPrimitive();\n"
1037 else if (params.testType == TEST_TYPE_INVOCATION_PER_LAYER)
1039 src << colorTable.str()
1040 << " const int colorNdx = gl_InvocationID % " << DE_LENGTH_OF_ARRAY(s_colors) << ";\n"
1042 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
1043 << " gl_Layer = gl_InvocationID;\n"
1044 << " gl_PointSize = 1.0;\n"
1045 << " vert_color = colors[colorNdx];\n"
1046 << " EmitVertex();\n"
1048 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
1049 << " gl_Layer = gl_InvocationID;\n"
1050 << " gl_PointSize = 1.0;\n"
1051 << " vert_color = colors[colorNdx];\n"
1052 << " EmitVertex();\n"
1054 << " gl_Position = vec4( 0.0, -1.0, 0.0, 1.0);\n"
1055 << " gl_Layer = gl_InvocationID;\n"
1056 << " gl_PointSize = 1.0;\n"
1057 << " vert_color = colors[colorNdx];\n"
1058 << " EmitVertex();\n"
1060 << " gl_Position = vec4( 0.0, 1.0, 0.0, 1.0);\n"
1061 << " gl_Layer = gl_InvocationID;\n"
1062 << " gl_PointSize = 1.0;\n"
1063 << " vert_color = colors[colorNdx];\n"
1064 << " EmitVertex();\n"
1065 << " EndPrimitive();\n";
1067 else if (params.testType == TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION)
1069 src << " const int layerA = gl_InvocationID;\n"
1070 << " const int layerB = (gl_InvocationID + 1) % " << numLayers << ";\n"
1071 << " const float aEnd = float(layerA) / float(" << numLayers << ") * 2.0 - 1.0;\n"
1072 << " const float bEnd = float(layerB) / float(" << numLayers << ") * 2.0 - 1.0;\n"
1074 << " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
1075 << " gl_Layer = layerA;\n"
1076 << " gl_PointSize = 1.0;\n"
1077 << " EmitVertex();\n"
1079 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
1080 << " gl_Layer = layerA;\n"
1081 << " gl_PointSize = 1.0;\n"
1082 << " EmitVertex();\n"
1084 << " gl_Position = vec4(aEnd, -1.0, 0.0, 1.0);\n"
1085 << " gl_Layer = layerA;\n"
1086 << " gl_PointSize = 1.0;\n"
1087 << " EmitVertex();\n"
1088 << " EndPrimitive();\n"
1090 << " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
1091 << " gl_Layer = layerB;\n"
1092 << " gl_PointSize = 1.0;\n"
1093 << " EmitVertex();\n"
1095 << " gl_Position = vec4(bEnd, 1.0, 0.0, 1.0);\n"
1096 << " gl_Layer = layerB;\n"
1097 << " gl_PointSize = 1.0;\n"
1098 << " EmitVertex();\n"
1100 << " gl_Position = vec4(bEnd, -1.0, 0.0, 1.0);\n"
1101 << " gl_Layer = layerB;\n"
1102 << " gl_PointSize = 1.0;\n"
1103 << " EmitVertex();\n"
1104 << " EndPrimitive();\n";
1106 else if (params.testType == TEST_TYPE_LAYERED_READBACK)
1108 src << colorTable.str()
1109 << " for (int layerNdx = 0; layerNdx < " << numLayers << "; ++layerNdx) {\n"
1110 << " const int colorNdx = layerNdx % " << DE_LENGTH_OF_ARRAY(s_colors) << ";\n"
1111 << " const vec3 passColor0 = (uInput.pass == 0 ? 0.5 : 1.0) * vec3(colors[colorNdx]);\n"
1112 << " const vec4 passColor = vec4(passColor0, 1.0);\n"
1113 << " const float posX = (uInput.pass == 0 ? 0.0 : -0.5);\n"
1114 << " const float posZ = float(layerNdx + 1 - uInput.pass) / float(" << 2*numLayers << ");\n"
1116 << " gl_Position = vec4(-1.0, -1.0, posZ, 1.0);\n"
1117 << " gl_Layer = layerNdx;\n"
1118 << " gl_PointSize = 1.0;\n"
1119 << " vert_color = passColor;\n"
1120 << " EmitVertex();\n"
1122 << " gl_Position = vec4(-1.0, 1.0, posZ, 1.0);\n"
1123 << " gl_Layer = layerNdx;\n"
1124 << " gl_PointSize = 1.0;\n"
1125 << " vert_color = passColor;\n"
1126 << " EmitVertex();\n"
1128 << " gl_Position = vec4(posX, -1.0, posZ, 1.0);\n"
1129 << " gl_Layer = layerNdx;\n"
1130 << " gl_PointSize = 1.0;\n"
1131 << " vert_color = passColor;\n"
1132 << " EmitVertex();\n"
1134 << " gl_Position = vec4(posX, 1.0, posZ, 1.0);\n"
1135 << " gl_Layer = layerNdx;\n"
1136 << " gl_PointSize = 1.0;\n"
1137 << " vert_color = passColor;\n"
1138 << " EmitVertex();\n"
1140 << " EndPrimitive();\n"
1146 src << "}\n"; // end main
1148 programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
1153 std::string imageViewString;
1155 switch (params.image.viewType)
1157 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
1158 imageViewString = "image1DArray";
1160 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
1161 imageViewString = "image2DArray";
1163 case VK_IMAGE_VIEW_TYPE_CUBE:
1164 imageViewString = "imageCube";
1166 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
1167 imageViewString = "imageCubeArray";
1170 DE_ASSERT(params.image.viewType == VK_IMAGE_VIEW_TYPE_3D);
1171 imageViewString = "image3D";
1175 std::ostringstream src;
1176 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1178 << "layout(location = 0) out vec4 o_color;\n"
1179 << (geomOutputColor ? "layout(location = 0) in vec4 vert_color;\n" : "")
1180 << (params.testType == TEST_TYPE_SECONDARY_CMD_BUFFER ? std::string("layout(set = 0, binding = 0, rgba8) uniform " + imageViewString + " storageImage;\n") : std::string(""))
1182 << "void main(void)\n"
1185 if (params.testType == TEST_TYPE_LAYER_ID)
1187 // This code must be in sync with verifyLayerContent()
1188 src << " o_color = vec4( (gl_Layer % 2) == 1 ? 1.0 : 0.5,\n"
1189 << " ((gl_Layer/2) % 2) == 1 ? 1.0 : 0.5,\n"
1190 << " gl_Layer == 0 ? 1.0 : 0.0,\n"
1193 else if (params.testType == TEST_TYPE_SECONDARY_CMD_BUFFER)
1195 switch (params.image.viewType)
1197 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
1198 src << " ivec2 coord = ivec2(int(gl_FragCoord.x), gl_Layer);\n";
1201 src << " ivec3 coord = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), gl_Layer);\n";
1205 src << " vec4 src_color = imageLoad(storageImage, coord);\n"
1206 << " o_color = (vert_color + src_color) / 2.0;\n"
1207 << " imageStore(storageImage, coord, o_color);\n";
1209 else if (geomOutputColor)
1210 src << " o_color = vert_color;\n";
1212 src << " o_color = vec4(1.0);\n";
1216 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
1220 tcu::TestStatus test (Context& context, const TestParams params)
1222 const DeviceInterface& vk = context.getDeviceInterface();
1223 const InstanceInterface& vki = context.getInstanceInterface();
1224 const VkDevice device = context.getDevice();
1225 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
1226 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1227 const VkQueue queue = context.getUniversalQueue();
1228 Allocator& allocator = context.getDefaultAllocator();
1229 VkDeviceSize nonCoherentAtomSize = vk::getPhysicalDeviceProperties(vki, physDevice).limits.nonCoherentAtomSize;
1230 VkDeviceSize alignmentSize = std::max<VkDeviceSize>(nonCoherentAtomSize, 4u);
1232 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
1233 const deUint32 numLayers = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? params.image.size.depth : params.image.numLayers);
1234 const Vec4 clearColor = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1235 const deUint32 colorImagePixelSize = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(colorFormat)));
1236 const VkDeviceSize colorBufferSize = static_cast<VkDeviceSize>(deAlignSize(params.image.size.width * params.image.size.height * colorImagePixelSize, static_cast<std::size_t>(alignmentSize)) * params.image.size.depth * params.image.numLayers);
1237 const VkImageCreateFlags imageCreateFlags = (isCubeImageViewType(params.image.viewType) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlagBits)0) |
1238 (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT : (VkImageCreateFlagBits)0);
1239 const VkImageViewType viewType = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : params.image.viewType);
1241 const Unique<VkImage> colorImage (makeImage (vk, device, makeImageCreateInfo(imageCreateFlags, getImageType(params.image.viewType), colorFormat, params.image.size,
1242 params.image.numLayers, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)));
1243 const UniquePtr<Allocation> colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any));
1244 const Unique<VkImageView> colorAttachment (makeImageView (vk, device, *colorImage, viewType, colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, numLayers)));
1246 const Unique<VkBuffer> colorBuffer (makeBuffer (vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1247 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1249 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, context.getBinaryCollection().get("vert"), 0u));
1250 const Unique<VkShaderModule> geometryModule (createShaderModule (vk, device, context.getBinaryCollection().get("geom"), 0u));
1251 const Unique<VkShaderModule> fragmentModule (createShaderModule (vk, device, context.getBinaryCollection().get("frag"), 0u));
1253 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, colorFormat));
1254 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, *colorAttachment, params.image.size.width, params.image.size.height, numLayers));
1255 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout (vk, device));
1256 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, *geometryModule, *fragmentModule,
1257 makeExtent2D(params.image.size.width, params.image.size.height)));
1258 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1259 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1261 zeroBuffer(vk, device, *colorBufferAlloc, colorBufferSize);
1263 beginCommandBuffer(vk, *cmdBuffer);
1265 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, params.image.size.width, params.image.size.height), clearColor);
1267 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1268 vk.cmdDraw(*cmdBuffer, 1u, 1u, 0u, 0u);
1269 endRenderPass(vk, *cmdBuffer);
1271 // Copy color image to buffer
1272 copyLayeredImageToBuffer(vk, *cmdBuffer, *colorImage, *colorBuffer, params.image);
1274 endCommandBuffer(vk, *cmdBuffer);
1275 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1277 invalidateAlloc(vk, device, *colorBufferAlloc);
1279 if (!verifyResults(context.getTestContext().getLog(), params, colorFormat, colorBufferAlloc->getHostPtr()))
1280 return tcu::TestStatus::fail("Rendered images are incorrect");
1282 return tcu::TestStatus::pass("OK");
1285 tcu::TestStatus testLayeredReadBack (Context& context, const TestParams params)
1287 const DeviceInterface& vk = context.getDeviceInterface();
1288 const InstanceInterface& vki = context.getInstanceInterface();
1289 const VkDevice device = context.getDevice();
1290 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
1291 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1292 const VkQueue queue = context.getUniversalQueue();
1293 Allocator& allocator = context.getDefaultAllocator();
1294 VkDeviceSize nonCoherentAtomSize = vk::getPhysicalDeviceProperties(vki, physDevice).limits.nonCoherentAtomSize;
1295 VkDeviceSize alignmentSize = std::max<VkDeviceSize>(nonCoherentAtomSize, 4u);
1297 const size_t passCount = 2;
1298 const deUint32 numLayers = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? params.image.size.depth : params.image.numLayers);
1299 const VkImageCreateFlags imageCreateFlags = (isCubeImageViewType(params.image.viewType) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlagBits)0) |
1300 (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT : (VkImageCreateFlagBits)0);
1301 const VkImageViewType viewType = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : params.image.viewType);
1302 const VkImageType imageType = getImageType(params.image.viewType);
1303 const VkExtent2D imageExtent2D = makeExtent2D(params.image.size.width, params.image.size.height);
1305 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
1306 const deUint32 colorImagePixelSize = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(colorFormat)));
1307 const VkDeviceSize colorBufferSize = static_cast<VkDeviceSize>( deAlignSize(params.image.size.width * params.image.size.height * colorImagePixelSize, static_cast<std::size_t>(alignmentSize)) * params.image.size.depth * params.image.numLayers );
1308 const VkImageUsageFlags colorImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1310 const bool dsUsed = true;
1311 const VkFormat dsFormat = VK_FORMAT_D24_UNORM_S8_UINT;
1312 const VkImageType dsImageType = (imageType == VK_IMAGE_TYPE_3D ? VK_IMAGE_TYPE_2D : imageType); // depth/stencil 2D_ARRAY attachments cannot be taken from 3D image, use 2D_ARRAY image instead.
1313 const VkExtent3D dsImageSize = makeExtent3D(params.image.size.width, params.image.size.height, 1u);
1314 const VkImageCreateFlags dsImageCreateFlags = (isCubeImageViewType(params.image.viewType) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlagBits)0);
1315 const deUint32 dsImagePixelSize = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(dsFormat)));
1316 const VkImageUsageFlags dsImageUsage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1317 const VkImageAspectFlags dsAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1318 const VkDeviceSize depthBufferSize = static_cast<VkDeviceSize>(deAlignSize(params.image.size.width * params.image.size.height * dsImagePixelSize, static_cast<std::size_t>(alignmentSize)) * params.image.size.depth * params.image.numLayers);
1320 const VkFormat stencilBufferFormat = getStencilBufferFormat(dsFormat);
1321 const deUint32 stencilPixelSize = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(stencilBufferFormat)));
1322 const VkDeviceSize stencilBufferSize = static_cast<VkDeviceSize>(deAlignSize( params.image.size.width * params.image.size.height * stencilPixelSize, static_cast<std::size_t>(alignmentSize)) * params.image.size.depth * params.image.numLayers);
1324 checkImageFormatProperties(vki, physDevice, imageType, VK_IMAGE_TILING_OPTIMAL, dsImageUsage, imageCreateFlags, dsFormat, params.image.size, params.image.numLayers);
1326 const Unique<VkImage> colorImage (makeImage (vk, device, makeImageCreateInfo(imageCreateFlags, imageType, colorFormat, params.image.size, params.image.numLayers, colorImageUsage)));
1327 const UniquePtr<Allocation> colorImageAlloc (bindImage (vk, device, allocator, *colorImage, MemoryRequirement::Any));
1328 const Unique<VkImageView> colorAttachment (makeImageView (vk, device, *colorImage, viewType, colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, numLayers)));
1329 const Unique<VkBuffer> colorBuffer (makeBuffer (vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1330 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1332 const Unique<VkImage> dsImage (makeImage (vk, device, makeImageCreateInfo(dsImageCreateFlags, dsImageType, dsFormat, dsImageSize, numLayers, dsImageUsage)));
1333 const UniquePtr<Allocation> dsImageAlloc (bindImage (vk, device, allocator, *dsImage, MemoryRequirement::Any));
1334 const Unique<VkImageView> dsAttachment (makeImageView (vk, device, *dsImage, viewType, dsFormat, makeImageSubresourceRange(dsAspectFlags, 0u, 1u, 0u, numLayers)));
1335 const Unique<VkBuffer> depthBuffer (makeBuffer (vk, device, depthBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1336 const UniquePtr<Allocation> depthBufferAlloc (bindBuffer (vk, device, allocator, *depthBuffer, MemoryRequirement::HostVisible));
1337 const Unique<VkBuffer> stencilBuffer (makeBuffer (vk, device, stencilBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1338 const UniquePtr<Allocation> stencilBufferAlloc (bindBuffer (vk, device, allocator, *stencilBuffer, MemoryRequirement::HostVisible));
1340 const VkImageView attachments[] = {*colorAttachment, *dsAttachment};
1341 const deUint32 attachmentsCount = dsUsed ? DE_LENGTH_OF_ARRAY(attachments) : 1u;
1343 const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, context.getBinaryCollection().get("vert"), 0u));
1344 const Unique<VkShaderModule> geometryModule (createShaderModule (vk, device, context.getBinaryCollection().get("geom"), 0u));
1345 const Unique<VkShaderModule> fragmentModule (createShaderModule (vk, device, context.getBinaryCollection().get("frag"), 0u));
1347 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, colorFormat, dsFormat, dsUsed));
1348 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, attachmentsCount, attachments, params.image.size.width, params.image.size.height, numLayers));
1350 const Move<VkDescriptorPool> descriptorPool = DescriptorPoolBuilder()
1351 .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, passCount)
1352 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, passCount);
1353 const Move<VkDescriptorSetLayout> descriptorSetLayout = DescriptorSetLayoutBuilder()
1354 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_GEOMETRY_BIT)
1356 const Move<VkDescriptorSet> descriptorSet[] =
1358 makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout),
1359 makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout),
1362 const size_t uniformBufSize = sizeof(deUint32);
1363 const VkBufferCreateInfo uniformBufCI = makeBufferCreateInfo(uniformBufSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
1364 const Move<VkBuffer> uniformBuf[] = { createBuffer(vk, device, &uniformBufCI), createBuffer(vk, device, &uniformBufCI) };
1365 const MovePtr<Allocation> uniformBufAlloc[] =
1367 allocator.allocate(getBufferMemoryRequirements(vk, device, *uniformBuf[0]), MemoryRequirement::HostVisible),
1368 allocator.allocate(getBufferMemoryRequirements(vk, device, *uniformBuf[1]), MemoryRequirement::HostVisible),
1370 const VkDescriptorBufferInfo uniformBufDesc[] =
1372 makeDescriptorBufferInfo(*uniformBuf[0], 0ull, uniformBufSize),
1373 makeDescriptorBufferInfo(*uniformBuf[1], 0ull, uniformBufSize),
1376 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout (vk, device, *descriptorSetLayout));
1377 const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, *geometryModule, *fragmentModule, imageExtent2D, dsUsed));
1378 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1379 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1380 const VkImageSubresourceRange colorSubresRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, params.image.numLayers);
1381 const VkImageSubresourceRange dsSubresRange = makeImageSubresourceRange(dsAspectFlags, 0u, 1u, 0u, numLayers);
1384 beginCommandBuffer(vk, *cmdBuffer);
1386 // Transition the images to new layouts
1387 const VkImageMemoryBarrier colorBarrier = makeImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
1388 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, *colorImage, colorSubresRange);
1389 const VkImageMemoryBarrier dsBarrier = makeImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
1390 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, *dsImage, dsSubresRange);
1392 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &colorBarrier);
1395 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &dsBarrier);
1397 for (deUint32 layerNdx = 0; layerNdx < numLayers; ++layerNdx)
1399 const VkExtent3D imageExtent = makeExtent3D(params.image.size.width, params.image.size.height, 1u);
1401 // Clear color image with initial value
1403 const deUint32 layer = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType) ? 0u : layerNdx;
1404 const deUint32 imageDepth = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType) ? layerNdx : 0u;
1405 const VkOffset3D imageOffset = makeOffset3D(0u, 0u, imageDepth);
1407 const tcu::Vec4 clearColor = scaleColor(s_colors[layerNdx % DE_LENGTH_OF_ARRAY(s_colors)], 0.25f);
1408 const deUint32 bufferSliceSize = deAlign32( params.image.size.width * params.image.size.height * colorImagePixelSize, static_cast<deInt32>(alignmentSize));
1409 const VkDeviceSize bufferOffset = layerNdx * bufferSliceSize;
1410 const VkImageSubresourceLayers imageSubresource = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, layer, 1u);
1411 const VkBufferImageCopy bufferImageCopyRegion = makeBufferImageCopy(bufferOffset, imageSubresource, imageOffset, imageExtent);
1413 fillBuffer(vk, device, *colorBufferAlloc, bufferOffset, bufferSliceSize, colorFormat, clearColor);
1414 vk.cmdCopyBufferToImage(*cmdBuffer, *colorBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopyRegion);
1417 // Clear depth image with initial value
1420 const float depthValue = 1.0f;
1421 const deUint32 bufferSliceSize = deAlign32( params.image.size.width * params.image.size.height * dsImagePixelSize, static_cast<deInt32>(alignmentSize));
1422 const VkDeviceSize bufferOffset = layerNdx * bufferSliceSize;
1423 const VkImageSubresourceLayers imageSubresource = makeImageSubresourceLayers(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, layerNdx, 1u);
1424 const VkBufferImageCopy bufferImageCopyRegion = makeBufferImageCopy(bufferOffset, imageSubresource, makeOffset3D(0u, 0u, 0u), imageExtent);
1426 fillBuffer(vk, device, *depthBufferAlloc, bufferOffset, bufferSliceSize, dsFormat, depthValue);
1427 vk.cmdCopyBufferToImage(*cmdBuffer, *depthBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopyRegion);
1430 // Clear stencil image with initial value
1433 const deUint8 stencilValue = 0;
1434 const deUint32 bufferSliceSize = deAlign32( params.image.size.width * params.image.size.height * stencilPixelSize, static_cast<deInt32>(alignmentSize));
1435 const VkDeviceSize bufferOffset = layerNdx * bufferSliceSize;
1436 const VkImageSubresourceLayers imageSubresource = makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, layerNdx, 1u);
1437 const VkBufferImageCopy bufferImageCopyRegion = makeBufferImageCopy(bufferOffset, imageSubresource, makeOffset3D(0u, 0u, 0u), imageExtent);
1438 deUint8* bufferStart = static_cast<deUint8*>((*stencilBufferAlloc).getHostPtr());
1439 deUint8* bufferLayerStart = &bufferStart[bufferOffset];
1441 deMemset(bufferLayerStart, stencilValue, bufferSliceSize);
1442 flushMappedMemoryRange(vk, device, stencilBufferAlloc->getMemory(), stencilBufferAlloc->getOffset() + bufferOffset, bufferSliceSize);
1443 vk.cmdCopyBufferToImage(*cmdBuffer, *stencilBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopyRegion);
1447 // Change images layouts
1449 // VK_ATTACHMENT_LOAD_OP_LOAD is used for both color and D/S attachments. Thus,
1450 // VK_ACCESS_COLOR_ATTACHMENT_READ_BIT and VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
1451 // bits must be included in the destination access mask of the color and depth barriers
1453 const VkImageMemoryBarrier colorBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
1454 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, *colorImage, colorSubresRange);
1455 const VkImageMemoryBarrier dsBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
1456 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, *dsImage, dsSubresRange);
1458 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &colorBarrier);
1461 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &dsBarrier);
1465 // These barriers are inserted between each pair of renderpasses in the following
1466 // loop. Note that VK_ATTACHMENT_LOAD_OP_LOAD is used for color and D/S attachments
1467 // hence VK_ACCESS_COLOR_ATTACHMENT_READ_BIT and VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
1468 // bits are included in src and dst access mask of the color and depth barriers.
1469 const VkImageMemoryBarrier colorPassBarrier = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
1470 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
1471 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, *colorImage, colorSubresRange);
1472 const VkImageMemoryBarrier dsPassBarrier = makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
1473 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
1474 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, *dsImage, dsSubresRange);
1475 for (deUint32 pass = 0; pass < passCount; ++pass)
1477 DE_ASSERT(sizeof(pass) == uniformBufSize);
1479 VK_CHECK(vk.bindBufferMemory(device, *uniformBuf[pass], uniformBufAlloc[pass]->getMemory(), uniformBufAlloc[pass]->getOffset()));
1480 deMemcpy(uniformBufAlloc[pass]->getHostPtr(), &pass, uniformBufSize);
1481 flushMappedMemoryRange(vk, device, uniformBufAlloc[pass]->getMemory(), uniformBufAlloc[pass]->getOffset(), VK_WHOLE_SIZE);
1483 DescriptorSetUpdateBuilder()
1484 .writeSingle(*descriptorSet[pass], DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &uniformBufDesc[pass])
1485 .update(vk, device);
1487 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet[pass], 0u, DE_NULL);
1488 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(imageExtent2D));
1489 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1490 vk.cmdDraw(*cmdBuffer, 1u, 1u, 0u, 0u);
1491 endRenderPass(vk, *cmdBuffer);
1493 // Don't add the barrier after the last renderpass
1494 if (pass < passCount - 1)
1496 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &colorPassBarrier);
1499 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &dsPassBarrier);
1503 endCommandBuffer(vk, *cmdBuffer);
1504 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1506 zeroBuffer(vk, device, *colorBufferAlloc, colorBufferSize);
1507 zeroBuffer(vk, device, *depthBufferAlloc, depthBufferSize);
1508 zeroBuffer(vk, device, *stencilBufferAlloc, stencilBufferSize);
1510 beginCommandBuffer(vk, *cmdBuffer);
1514 const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
1515 VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorImage, colorSubresRange);
1516 const VkBufferImageCopy region = makeBufferImageCopy(params.image.size, makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, params.image.numLayers));
1517 const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);
1519 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
1520 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ®ion);
1521 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
1524 // Depth/Stencil image copy
1527 const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
1528 VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dsImage, dsSubresRange);
1529 const VkBufferImageCopy depthCopyRegion = makeBufferImageCopy(dsImageSize, makeImageSubresourceLayers(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, numLayers));
1530 const VkBufferImageCopy stencilCopyRegion = makeBufferImageCopy(dsImageSize, makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, numLayers));
1531 const VkBufferMemoryBarrier postCopyBarriers[] =
1533 makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *depthBuffer, 0ull, VK_WHOLE_SIZE),
1534 makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *stencilBuffer, 0ull, VK_WHOLE_SIZE),
1537 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
1538 vk.cmdCopyImageToBuffer(*cmdBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *depthBuffer, 1u, &depthCopyRegion);
1539 vk.cmdCopyImageToBuffer(*cmdBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *stencilBuffer, 1u, &stencilCopyRegion);
1540 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBarriers), postCopyBarriers, DE_NULL, 0u);
1543 endCommandBuffer(vk, *cmdBuffer);
1544 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1546 invalidateAlloc(vk, device, *colorBufferAlloc);
1547 invalidateAlloc(vk, device, *depthBufferAlloc);
1548 invalidateAlloc(vk, device, *stencilBufferAlloc);
1550 if (!verifyResults(context.getTestContext().getLog(), params, colorFormat, colorBufferAlloc->getHostPtr()))
1555 if (!verifyResults(context.getTestContext().getLog(), params, dsFormat, depthBufferAlloc->getHostPtr(), true, false))
1558 if (!verifyResults(context.getTestContext().getLog(), params, stencilBufferFormat, stencilBufferAlloc->getHostPtr(), false, true))
1559 result += " Stencil";
1563 return tcu::TestStatus::pass("OK");
1565 return tcu::TestStatus::fail("Following parts of image are incorrect:" + result);
1568 tcu::TestStatus testSecondaryCmdBuffer (Context& context, const TestParams params)
1570 const DeviceInterface& vk = context.getDeviceInterface();
1571 const InstanceInterface& vki = context.getInstanceInterface();
1572 const VkDevice device = context.getDevice();
1573 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
1574 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1575 const VkQueue queue = context.getUniversalQueue();
1576 Allocator& allocator = context.getDefaultAllocator();
1577 VkDeviceSize nonCoherentAtomSize = vk::getPhysicalDeviceProperties(vki, physDevice).limits.nonCoherentAtomSize;
1578 VkDeviceSize alignmentSize = std::max<VkDeviceSize>(nonCoherentAtomSize, 4u);
1580 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
1581 const deUint32 numLayers = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? params.image.size.depth : params.image.numLayers);
1582 const Vec4 clearColor = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1583 const deUint32 colorImagePixelSize = static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(colorFormat)));
1584 const VkDeviceSize colorBufferSize = static_cast<VkDeviceSize>(deAlignSize(params.image.size.width * params.image.size.height * colorImagePixelSize, static_cast<std::size_t>(alignmentSize)) * params.image.size.depth * params.image.numLayers);
1586 const VkImageCreateFlags imageCreateFlags = (isCubeImageViewType(params.image.viewType) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlagBits)0) |
1587 (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT : (VkImageCreateFlagBits)0);
1588 const VkImageViewType viewType = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : params.image.viewType);
1590 const Unique<VkImage> colorImage (makeImage(vk, device, makeImageCreateInfo(imageCreateFlags, getImageType(params.image.viewType), colorFormat, params.image.size,
1591 params.image.numLayers, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)));
1592 const UniquePtr<Allocation> colorImageAlloc (bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any));
1593 const Unique<VkImageView> colorImageView (makeImageView(vk, device, *colorImage, viewType, colorFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, numLayers)));
1595 const Unique<VkImage> offscreenImage (makeImage(vk, device, makeImageCreateInfo(imageCreateFlags, getImageType(params.image.viewType), colorFormat, params.image.size,
1596 params.image.numLayers, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)));
1597 const UniquePtr<Allocation> offscreenImageAlloc (bindImage(vk, device, allocator, *offscreenImage, MemoryRequirement::Any));
1598 const Unique<VkImageView> offscreenImageView (makeImageView(vk, device, *offscreenImage, params.image.viewType, colorFormat,
1599 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, params.image.numLayers)));
1601 const Unique<VkBuffer> colorBuffer (makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1602 const UniquePtr<Allocation> colorBufferAlloc (bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1604 const Move<VkDescriptorPool> descriptorPool = DescriptorPoolBuilder() .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1u) .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1605 const Move<VkDescriptorSetLayout> descriptorSetLayout = DescriptorSetLayoutBuilder() .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT) .build(vk, device);
1606 const Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
1608 const Unique<VkShaderModule> vertexModule (createShaderModule(vk, device, context.getBinaryCollection().get("vert"), 0u));
1609 const Unique<VkShaderModule> geometryModule (createShaderModule(vk, device, context.getBinaryCollection().get("geom"), 0u));
1610 const Unique<VkShaderModule> fragmentModule (createShaderModule(vk, device, context.getBinaryCollection().get("frag"), 0u));
1612 const Unique<VkRenderPass> renderPass (makeRenderPassWithSelfDependency(vk, device, colorFormat));
1613 const Unique<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, *colorImageView, params.image.size.width, params.image.size.height, numLayers));
1614 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout));
1615 const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *geometryModule, *fragmentModule,
1616 makeExtent2D(params.image.size.width, params.image.size.height)));
1618 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1619 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1620 const Unique<VkCommandBuffer> secondaryCmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY));
1622 zeroBuffer(vk, device, *colorBufferAlloc, colorBufferSize);
1624 const VkDescriptorImageInfo imageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, *offscreenImageView, VK_IMAGE_LAYOUT_GENERAL);
1626 DescriptorSetUpdateBuilder()
1627 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageDescriptorInfo)
1628 .update(vk, device);
1630 // Clear each layer of storage image
1632 vk::Unique<vk::VkCommandBuffer> clearCmdBuffer (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1633 beginCommandBuffer(vk, *clearCmdBuffer);
1635 const vk::VkImageSubresourceRange subresourceRange =
1637 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1638 0u, // deUint32 baseMipLevel
1639 1u, // deUint32 levelCount
1640 0u, // deUint32 baseArrayLayer
1641 params.image.numLayers // deUint32 layerCount
1644 const vk::VkImageMemoryBarrier preImageBarrier =
1646 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1647 DE_NULL, // const void* pNext
1648 0u, // VkAccessFlags srcAccessMask
1649 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1650 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
1651 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
1652 queueFamilyIndex, // deUint32 srcQueueFamilyIndex
1653 queueFamilyIndex, // deUint32 dstQueueFamilyIndex
1654 *offscreenImage, // VkImage image
1655 subresourceRange // VkImageSubresourceRange subresourceRange
1658 const vk::VkImageMemoryBarrier postImageBarrier =
1660 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
1661 DE_NULL, // const void* pNext
1662 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1663 vk::VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags dstAccessMask
1664 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
1665 vk::VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
1666 queueFamilyIndex, // deUint32 srcQueueFamilyIndex
1667 queueFamilyIndex, // deUint32 dstQueueFamilyIndex
1668 *offscreenImage, // VkImage image
1669 subresourceRange // VkImageSubresourceRange subresourceRange
1672 vk.cmdPipelineBarrier(*clearCmdBuffer,
1673 vk::VK_PIPELINE_STAGE_HOST_BIT,
1674 vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
1675 (vk::VkDependencyFlags)0,
1676 0, (const vk::VkMemoryBarrier*)DE_NULL,
1677 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
1678 1, &preImageBarrier);
1680 for (deUint32 layerNdx = 0; layerNdx < numLayers; ++layerNdx)
1682 const deUint32 imageDepth = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType) ? layerNdx : 0u;
1683 const deUint32 layer = (VK_IMAGE_VIEW_TYPE_3D == params.image.viewType) ? 0u : layerNdx;
1684 const VkOffset3D imageOffset = makeOffset3D(0u, 0u, imageDepth);
1685 const VkExtent3D imageExtent = makeExtent3D(params.image.size.width, params.image.size.height, 1u);
1688 const tcu::Vec4 storageImageClearColor = secondaryCmdBufClearColors[layerNdx % DE_LENGTH_OF_ARRAY(secondaryCmdBufClearColors)];
1689 const deUint32 bufferSliceSize = deAlign32(params.image.size.width * params.image.size.height * colorImagePixelSize, static_cast<deInt32>(alignmentSize));
1690 const VkDeviceSize bufferOffset = layerNdx * bufferSliceSize;
1691 const VkImageSubresourceLayers imageSubresource = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, layer, 1u);
1692 const VkBufferImageCopy bufferImageCopyRegion = makeBufferImageCopy(bufferOffset, imageSubresource, imageOffset, imageExtent);
1694 fillBuffer(vk, device, *colorBufferAlloc, bufferOffset, bufferSliceSize, colorFormat, storageImageClearColor);
1695 vk.cmdCopyBufferToImage(*clearCmdBuffer, *colorBuffer, *offscreenImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopyRegion);
1699 vk.cmdPipelineBarrier(*clearCmdBuffer,
1700 vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
1701 vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
1702 (vk::VkDependencyFlags)0,
1703 0, (const vk::VkMemoryBarrier*)DE_NULL,
1704 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
1705 1, &postImageBarrier);
1707 endCommandBuffer(vk, *clearCmdBuffer);
1709 submitCommandsAndWait(vk, device, queue, *clearCmdBuffer);
1712 // Begin secondary command buffer
1714 const VkCommandBufferInheritanceInfo commandBufferInheritanceInfo =
1716 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // VkStructureType sType
1717 DE_NULL, // const void* pNext
1718 *renderPass, // VkRenderPass renderPass
1719 0u, // deUint32 subpass
1720 params.inheritFramebuffer ? *framebuffer : (VkFramebuffer)0, // VkFramebuffer framebuffer
1721 VK_FALSE, // VkBool32 occlusionQueryEnable
1722 0u, // VkQueryControlFlags queryFlags
1723 0u // VkQueryPipelineStatisticFlags pipelineStatistics
1726 const VkCommandBufferBeginInfo commandBufferBeginInfo =
1728 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType
1729 DE_NULL, // const void* pNext
1730 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
1731 | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, // VkCommandBufferUsageFlags flags
1732 &commandBufferInheritanceInfo // const VkCommandBufferInheritanceInfo* pInheritanceInfo
1735 VK_CHECK(vk.beginCommandBuffer(*secondaryCmdBuffer, &commandBufferBeginInfo));
1738 vk.cmdBindDescriptorSets(*secondaryCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
1740 // Clear framebuffer: upper right corner for half of the layers and bottom right for the others.
1742 const VkClearAttachment clearAttachment =
1744 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
1745 0u, // deUint32 colorAttachment
1746 makeClearValueColorF32(0.5f, 0.25, 0.0f, 1.0f) // VkClearValue clearValue
1749 const VkOffset2D offsetTop = { (deInt32)params.image.size.width / 2, 0 };
1750 const VkOffset2D offsetBottom = { (deInt32)params.image.size.width / 2, (deInt32)params.image.size.height / 2 };
1751 const VkExtent2D extentTop = { params.image.size.width / 2, params.image.size.height / 2 };
1752 const VkExtent2D extentBottom = { params.image.size.width / 2, de::max(params.image.size.height / 2, 1u) };
1753 const VkRect2D rectRightTop = { offsetTop, extentTop };
1754 const VkRect2D rectRightBottom = { offsetBottom, extentBottom };
1756 const VkClearRect rects[] =
1759 rectRightBottom, // VkRect2D rect
1760 numLayers / 2, // deUint32 baseArrayLayer
1761 numLayers / 2 // deUint32 layerCount
1764 rectRightTop, // VkRect2D rect
1765 0u, // deUint32 baseArrayLayer
1766 numLayers / 2 // deUint32 layerCount
1770 vk.cmdClearAttachments(*secondaryCmdBuffer, 1u, &clearAttachment, extentTop.height > 0 ? 2u : 1u, rects);
1773 vk.cmdBindPipeline(*secondaryCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1774 vk.cmdDraw(*secondaryCmdBuffer, 1u, 1u, 0u, 0u);
1775 // Barrier between draws
1777 const VkMemoryBarrier barrier =
1779 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType
1780 DE_NULL, // const void* pNext
1781 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask
1782 VK_ACCESS_SHADER_READ_BIT // VkAccessFlags dstAccessMask
1785 vk.cmdPipelineBarrier(*secondaryCmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 1u, &barrier, 0u, DE_NULL, 0u, DE_NULL);
1787 vk.cmdDraw(*secondaryCmdBuffer, 1u, 1u, 0u, 0u);
1788 endCommandBuffer(vk, *secondaryCmdBuffer);
1790 beginCommandBuffer(vk, *cmdBuffer);
1791 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, params.image.size.width, params.image.size.height), clearColor, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
1792 vk.cmdExecuteCommands(*cmdBuffer, 1u, &(*secondaryCmdBuffer));
1793 endRenderPass(vk, *cmdBuffer);
1795 copyLayeredImageToBuffer(vk, *cmdBuffer, *colorImage, *colorBuffer, params.image);
1797 endCommandBuffer(vk, *cmdBuffer);
1798 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1800 invalidateAlloc(vk, device, *colorBufferAlloc);
1802 if (!verifyResults(context.getTestContext().getLog(), params, colorFormat, colorBufferAlloc->getHostPtr()))
1803 return tcu::TestStatus::fail("Rendered images are incorrect");
1805 return tcu::TestStatus::pass("OK");
1808 void checkSupport (Context& context, const TestParams params)
1810 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
1812 if (params.image.viewType == VK_IMAGE_VIEW_TYPE_3D)
1814 context.requireDeviceFunctionality("VK_KHR_maintenance1");
1816 #ifndef CTS_USES_VULKANSC
1817 if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
1818 !context.getPortabilitySubsetFeatures().imageView2DOn3DImage)
1820 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Implementation does not support 2D or 2D array image view to be created on a 3D VkImage");
1822 #endif // CTS_USES_VULKANSC
1825 if (params.testType == TEST_TYPE_SECONDARY_CMD_BUFFER)
1827 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS);
1828 #ifdef CTS_USES_VULKANSC
1829 if (!params.inheritFramebuffer && context.getDeviceVulkanSC10Properties().secondaryCommandBufferNullOrImagelessFramebuffer == VK_FALSE)
1830 TCU_THROW(NotSupportedError, "secondaryCommandBufferNullFramebuffer is not supported");
1837 tcu::TestCaseGroup* createLayeredRenderingTests (tcu::TestContext& testCtx)
1839 MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "layered", "Layered rendering tests."));
1845 const char* description;
1848 { TEST_TYPE_DEFAULT_LAYER, "render_to_default_layer", "Render to the default layer" },
1849 { TEST_TYPE_SINGLE_LAYER, "render_to_one", "Render to one layer" },
1850 { TEST_TYPE_ALL_LAYERS, "render_to_all", "Render to all layers" },
1851 { TEST_TYPE_DIFFERENT_CONTENT, "render_different_content", "Render different data to different layers" },
1852 { TEST_TYPE_LAYER_ID, "fragment_layer", "Read gl_Layer in fragment shader" },
1853 { TEST_TYPE_INVOCATION_PER_LAYER, "invocation_per_layer", "Render to multiple layers with multiple invocations, one invocation per layer" },
1854 { TEST_TYPE_MULTIPLE_LAYERS_PER_INVOCATION, "multiple_layers_per_invocation", "Render to multiple layers with multiple invocations, multiple layers per invocation", },
1855 { TEST_TYPE_LAYERED_READBACK, "readback", "Render to multiple layers with two passes to check LOAD_OP_LOAD capability" },
1856 { TEST_TYPE_SECONDARY_CMD_BUFFER, "secondary_cmd_buffer", "Layered rendering using secondary command buffer" }
1861 VkImageViewType viewType;
1862 ImageParams imageParams[2];
1863 } imageParamGroups[] =
1865 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, { { VK_IMAGE_VIEW_TYPE_1D_ARRAY, { 64, 1, 1 }, 4 }, { VK_IMAGE_VIEW_TYPE_1D_ARRAY, { 12, 1, 1 }, 6 } } },
1866 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, { { VK_IMAGE_VIEW_TYPE_2D_ARRAY, { 64, 64, 1 }, 4 }, { VK_IMAGE_VIEW_TYPE_2D_ARRAY, { 12, 36, 1 }, 6 } } },
1867 { VK_IMAGE_VIEW_TYPE_CUBE, { { VK_IMAGE_VIEW_TYPE_CUBE, { 64, 64, 1 }, 6 }, { VK_IMAGE_VIEW_TYPE_CUBE, { 36, 36, 1 }, 6 } } },
1868 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, { { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, { 64, 64, 1 }, 2*6 }, { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, { 36, 36, 1 }, 2*6 } } },
1869 { VK_IMAGE_VIEW_TYPE_3D, { { VK_IMAGE_VIEW_TYPE_3D, { 64, 64, 8 }, 1 }, { VK_IMAGE_VIEW_TYPE_3D, { 12, 36, 6 }, 1 } } }
1872 for (int imageParamGroupNdx = 0; imageParamGroupNdx < DE_LENGTH_OF_ARRAY(imageParamGroups); ++imageParamGroupNdx)
1874 MovePtr<tcu::TestCaseGroup> viewTypeMainGroup(new tcu::TestCaseGroup(testCtx, getShortImageViewTypeName(imageParamGroups[imageParamGroupNdx].viewType).c_str(), ""));
1876 for (int imageParamNdx = 0; imageParamNdx < 2; imageParamNdx++)
1878 std::ostringstream viewTypeGroupName;
1879 viewTypeGroupName << imageParamGroups[imageParamGroupNdx].imageParams[imageParamNdx].size.width << "_" << imageParamGroups[imageParamGroupNdx].imageParams[imageParamNdx].size.height << "_";
1880 if (imageParamGroups[imageParamGroupNdx].imageParams[imageParamNdx].viewType == VK_IMAGE_VIEW_TYPE_3D)
1881 viewTypeGroupName << imageParamGroups[imageParamGroupNdx].imageParams[imageParamNdx].size.depth;
1883 viewTypeGroupName << imageParamGroups[imageParamGroupNdx].imageParams[imageParamNdx].numLayers;
1884 MovePtr<tcu::TestCaseGroup> viewTypeGroup(new tcu::TestCaseGroup(testCtx, viewTypeGroupName.str().c_str(), ""));
1886 for (int testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
1890 testTypes[testTypeNdx].test,
1891 imageParamGroups[imageParamGroupNdx].imageParams[imageParamNdx],
1895 if (testTypes[testTypeNdx].test == TEST_TYPE_LAYERED_READBACK)
1896 addFunctionCaseWithPrograms(viewTypeGroup.get(), testTypes[testTypeNdx].name, testTypes[testTypeNdx].description, checkSupport, initPrograms, testLayeredReadBack, params);
1897 else if (testTypes[testTypeNdx].test == TEST_TYPE_SECONDARY_CMD_BUFFER)
1899 addFunctionCaseWithPrograms(viewTypeGroup.get(), "secondary_cmd_buffer", testTypes[testTypeNdx].description, checkSupport, initPrograms, testSecondaryCmdBuffer, params);
1900 params.inheritFramebuffer = true;
1901 addFunctionCaseWithPrograms(viewTypeGroup.get(), "secondary_cmd_buffer_inherit_framebuffer", testTypes[testTypeNdx].description, checkSupport, initPrograms, testSecondaryCmdBuffer, params);
1904 addFunctionCaseWithPrograms(viewTypeGroup.get(), testTypes[testTypeNdx].name, testTypes[testTypeNdx].description, checkSupport, initPrograms, test, params);
1906 viewTypeMainGroup->addChild(viewTypeGroup.release());
1908 group->addChild(viewTypeMainGroup.release());
1911 return group.release();