xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/pipeline/vktPipelineDepthTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Imagination Technologies Ltd.
7  * Copyright (c) 2023 LunarG, Inc.
8  * Copyright (c) 2023 Nintendo
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  *//*!
23  * \file
24  * \brief Depth Tests
25  *//*--------------------------------------------------------------------*/
26 
27 #include "vktPipelineDepthTests.hpp"
28 #include "vktPipelineClearUtil.hpp"
29 #include "vktPipelineImageUtil.hpp"
30 #include "vktPipelineVertexUtil.hpp"
31 #include "vktPipelineReferenceRenderer.hpp"
32 #include "vktTestCase.hpp"
33 #include "vktTestCaseUtil.hpp"
34 #include "vkImageUtil.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vkPrograms.hpp"
37 #include "vkQueryUtil.hpp"
38 #include "vkRef.hpp"
39 #include "vkRefUtil.hpp"
40 #include "vkTypeUtil.hpp"
41 #include "vkCmdUtil.hpp"
42 #include "vkObjUtil.hpp"
43 #include "tcuImageCompare.hpp"
44 #include "deUniquePtr.hpp"
45 #include "deStringUtil.hpp"
46 #include "deMemory.h"
47 
48 #include <sstream>
49 #include <vector>
50 
51 namespace vkt
52 {
53 namespace pipeline
54 {
55 
56 using namespace vk;
57 
58 namespace
59 {
60 
61 enum class DepthClipControlCase
62 {
63     DISABLED       = 0, // No depth clip control.
64     NORMAL         = 1, // Depth clip control with static viewport.
65     NORMAL_W       = 2, // Depth clip control with static viewport and .w different from 1.0f
66     BEFORE_STATIC  = 3, // Set dynamic viewport state, then bind a static pipeline.
67     BEFORE_DYNAMIC = 4, // Set dynamic viewport state, bind dynamic pipeline.
68     BEFORE_TWO_DYNAMICS =
69         5, // Set dynamic viewport state, bind dynamic pipeline with [0,1] view volume, then bind dynamic pipeline with [-1,1] view volume.
70     AFTER_DYNAMIC = 6, // Bind dynamic pipeline, then set dynamic viewport state.
71 };
72 
isSupportedDepthStencilFormat(const InstanceInterface & instanceInterface,VkPhysicalDevice device,VkFormat format)73 bool isSupportedDepthStencilFormat(const InstanceInterface &instanceInterface, VkPhysicalDevice device, VkFormat format)
74 {
75     VkFormatProperties formatProps;
76 
77     instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
78 
79     return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0u;
80 }
81 
testSupportsDepthStencilFormat(Context & context,VkFormat format)82 tcu::TestStatus testSupportsDepthStencilFormat(Context &context, VkFormat format)
83 {
84     DE_ASSERT(vk::isDepthStencilFormat(format));
85 
86     if (isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), format))
87         return tcu::TestStatus::pass("Format can be used in depth/stencil attachment");
88     else
89         return tcu::TestStatus::fail("Unsupported depth/stencil attachment format");
90 }
91 
testSupportsAtLeastOneDepthStencilFormat(Context & context,const std::vector<VkFormat> formats)92 tcu::TestStatus testSupportsAtLeastOneDepthStencilFormat(Context &context, const std::vector<VkFormat> formats)
93 {
94     std::ostringstream supportedFormatsMsg;
95     bool pass = false;
96 
97     DE_ASSERT(!formats.empty());
98 
99     for (size_t formatNdx = 0; formatNdx < formats.size(); formatNdx++)
100     {
101         const VkFormat format = formats[formatNdx];
102 
103         DE_ASSERT(vk::isDepthStencilFormat(format));
104 
105         if (isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), format))
106         {
107             pass = true;
108             supportedFormatsMsg << vk::getFormatName(format);
109 
110             if (formatNdx < formats.size() - 1)
111                 supportedFormatsMsg << ", ";
112         }
113     }
114 
115     if (pass)
116         return tcu::TestStatus::pass(std::string("Supported depth/stencil formats: ") + supportedFormatsMsg.str());
117     else
118         return tcu::TestStatus::fail("All depth/stencil formats are unsupported");
119 }
120 
121 class DepthTest : public vkt::TestCase
122 {
123 public:
124     enum
125     {
126         QUAD_COUNT = 4
127     };
128 
129     static const float quadDepths[QUAD_COUNT];
130     static const float quadDepthsMinusOneToOne[QUAD_COUNT];
131     static const float quadWs[QUAD_COUNT];
132 
133     DepthTest(tcu::TestContext &testContext, const std::string &name,
134               const PipelineConstructionType pipelineConstructionType, const VkFormat depthFormat,
135               const VkCompareOp depthCompareOps[QUAD_COUNT], const bool separateDepthStencilLayouts,
136               const VkPrimitiveTopology primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
137               const bool depthBoundsTestEnable = false, const float depthBoundsMin = 0.0f,
138               const float depthBoundsMax = 1.0f, const bool depthTestEnable = true,
139               const bool stencilTestEnable = false, const bool colorAttachmentEnable = true,
140               const bool hostVisible = false, const tcu::UVec2 renderSize = tcu::UVec2(32, 32),
141               const DepthClipControlCase depthClipControl = DepthClipControlCase::DISABLED);
142     virtual ~DepthTest(void);
143     virtual void initPrograms(SourceCollections &programCollection) const;
144     virtual void checkSupport(Context &context) const;
145     virtual TestInstance *createInstance(Context &context) const;
146 
147 private:
148     const PipelineConstructionType m_pipelineConstructionType;
149     const VkFormat m_depthFormat;
150     const bool m_separateDepthStencilLayouts;
151     VkPrimitiveTopology m_primitiveTopology;
152     const bool m_depthBoundsTestEnable;
153     const float m_depthBoundsMin;
154     const float m_depthBoundsMax;
155     const bool m_depthTestEnable;
156     const bool m_stencilTestEnable;
157     const bool m_colorAttachmentEnable;
158     const bool m_hostVisible;
159     const tcu::UVec2 m_renderSize;
160     const DepthClipControlCase m_depthClipControl;
161     VkCompareOp m_depthCompareOps[QUAD_COUNT];
162 };
163 
164 class DepthTestInstance : public vkt::TestInstance
165 {
166 public:
167     DepthTestInstance(Context &context, const PipelineConstructionType pipelineConstructionType,
168                       const VkFormat depthFormat, const VkCompareOp depthCompareOps[DepthTest::QUAD_COUNT],
169                       const bool separateDepthStencilLayouts, const VkPrimitiveTopology primitiveTopology,
170                       const bool depthBoundsTestEnable, const float depthBoundsMin, const float depthBoundsMax,
171                       const bool depthTestEnable, const bool stencilTestEnable, const bool colorAttachmentEnable,
172                       const bool hostVisible, const tcu::UVec2 renderSize, const DepthClipControlCase depthClipControl);
173 
174     virtual ~DepthTestInstance(void);
175     virtual tcu::TestStatus iterate(void);
176 
177 private:
178     tcu::TestStatus verifyImage(void);
179 
180 private:
181     VkCompareOp m_depthCompareOps[DepthTest::QUAD_COUNT];
182     const tcu::UVec2 m_renderSize;
183     const VkFormat m_colorFormat;
184     const VkFormat m_depthFormat;
185     const bool m_separateDepthStencilLayouts;
186     VkPrimitiveTopology m_primitiveTopology;
187     const bool m_depthBoundsTestEnable;
188     const float m_depthBoundsMin;
189     const float m_depthBoundsMax;
190     const bool m_depthTestEnable;
191     const bool m_stencilTestEnable;
192     const bool m_colorAttachmentEnable;
193     const bool m_hostVisible;
194     const DepthClipControlCase m_depthClipControl;
195     VkImageSubresourceRange m_depthImageSubresourceRange;
196 
197     Move<VkImage> m_colorImage;
198     de::MovePtr<Allocation> m_colorImageAlloc;
199     Move<VkImage> m_depthImage;
200     de::MovePtr<Allocation> m_depthImageAlloc;
201     Move<VkImageView> m_colorAttachmentView;
202     Move<VkImageView> m_depthAttachmentView;
203     RenderPassWrapper m_renderPass;
204     Move<VkFramebuffer> m_framebuffer;
205 
206     ShaderWrapper m_vertexShaderModule;
207     ShaderWrapper m_fragmentShaderModule;
208 
209     Move<VkBuffer> m_vertexBuffer;
210     std::vector<Vertex4RGBA> m_vertices;
211     de::MovePtr<Allocation> m_vertexBufferAlloc;
212 
213     Move<VkBuffer> m_altVertexBuffer;
214     std::vector<Vertex4RGBA> m_altVertices;
215     de::MovePtr<Allocation> m_altVertexBufferAlloc;
216 
217     PipelineLayoutWrapper m_pipelineLayout;
218     GraphicsPipelineWrapper m_graphicsPipelines[DepthTest::QUAD_COUNT];
219     GraphicsPipelineWrapper m_altGraphicsPipelines[DepthTest::QUAD_COUNT];
220 
221     Move<VkCommandPool> m_cmdPool;
222     Move<VkCommandBuffer> m_cmdBuffer;
223 };
224 
225 const float DepthTest::quadDepths[QUAD_COUNT] = {0.1f, 0.0f, 0.3f, 0.2f};
226 
227 // Depth values suitable for the depth range of -1..1.
228 const float DepthTest::quadDepthsMinusOneToOne[QUAD_COUNT] = {-0.8f, -1.0f, 0.6f, 0.2f};
229 
230 const float DepthTest::quadWs[QUAD_COUNT] = {2.0f, 1.25f, 0.5f, 0.25f};
231 
DepthTest(tcu::TestContext & testContext,const std::string & name,const PipelineConstructionType pipelineConstructionType,const VkFormat depthFormat,const VkCompareOp depthCompareOps[QUAD_COUNT],const bool separateDepthStencilLayouts,const VkPrimitiveTopology primitiveTopology,const bool depthBoundsTestEnable,const float depthBoundsMin,const float depthBoundsMax,const bool depthTestEnable,const bool stencilTestEnable,const bool colorAttachmentEnable,const bool hostVisible,const tcu::UVec2 renderSize,const DepthClipControlCase depthClipControl)232 DepthTest::DepthTest(tcu::TestContext &testContext, const std::string &name,
233                      const PipelineConstructionType pipelineConstructionType, const VkFormat depthFormat,
234                      const VkCompareOp depthCompareOps[QUAD_COUNT], const bool separateDepthStencilLayouts,
235                      const VkPrimitiveTopology primitiveTopology, const bool depthBoundsTestEnable,
236                      const float depthBoundsMin, const float depthBoundsMax, const bool depthTestEnable,
237                      const bool stencilTestEnable, const bool colorAttachmentEnable, const bool hostVisible,
238                      const tcu::UVec2 renderSize, const DepthClipControlCase depthClipControl)
239     : vkt::TestCase(testContext, name)
240     , m_pipelineConstructionType(pipelineConstructionType)
241     , m_depthFormat(depthFormat)
242     , m_separateDepthStencilLayouts(separateDepthStencilLayouts)
243     , m_primitiveTopology(primitiveTopology)
244     , m_depthBoundsTestEnable(depthBoundsTestEnable)
245     , m_depthBoundsMin(depthBoundsMin)
246     , m_depthBoundsMax(depthBoundsMax)
247     , m_depthTestEnable(depthTestEnable)
248     , m_stencilTestEnable(stencilTestEnable)
249     , m_colorAttachmentEnable(colorAttachmentEnable)
250     , m_hostVisible(hostVisible)
251     , m_renderSize(renderSize)
252     , m_depthClipControl(depthClipControl)
253 {
254     deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * QUAD_COUNT);
255 }
256 
~DepthTest(void)257 DepthTest::~DepthTest(void)
258 {
259 }
260 
checkSupport(Context & context) const261 void DepthTest::checkSupport(Context &context) const
262 {
263     if (m_depthBoundsTestEnable)
264         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BOUNDS);
265 
266     if (!isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_depthFormat))
267         throw tcu::NotSupportedError(std::string("Unsupported depth/stencil format: ") + getFormatName(m_depthFormat));
268 
269     if (m_separateDepthStencilLayouts &&
270         !context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
271         TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
272 
273     checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(),
274                                           m_pipelineConstructionType);
275 
276 #ifndef CTS_USES_VULKANSC
277     if (m_depthClipControl != DepthClipControlCase::DISABLED &&
278         !context.isDeviceFunctionalitySupported("VK_EXT_depth_clip_control"))
279         TCU_THROW(NotSupportedError, "VK_EXT_depth_clip_control is not supported");
280 #endif // CTS_USES_VULKANSC
281 }
282 
createInstance(Context & context) const283 TestInstance *DepthTest::createInstance(Context &context) const
284 {
285     return new DepthTestInstance(context, m_pipelineConstructionType, m_depthFormat, m_depthCompareOps,
286                                  m_separateDepthStencilLayouts, m_primitiveTopology, m_depthBoundsTestEnable,
287                                  m_depthBoundsMin, m_depthBoundsMax, m_depthTestEnable, m_stencilTestEnable,
288                                  m_colorAttachmentEnable, m_hostVisible, m_renderSize, m_depthClipControl);
289 }
290 
initPrograms(SourceCollections & programCollection) const291 void DepthTest::initPrograms(SourceCollections &programCollection) const
292 {
293     if (m_colorAttachmentEnable)
294     {
295         programCollection.glslSources.add("color_vert")
296             << glu::VertexSource("#version 310 es\n"
297                                  "layout(location = 0) in vec4 position;\n"
298                                  "layout(location = 1) in vec4 color;\n"
299                                  "layout(location = 0) out highp vec4 vtxColor;\n"
300                                  "void main (void)\n"
301                                  "{\n"
302                                  "    gl_Position = position;\n"
303                                  "    gl_PointSize = 1.0f;\n"
304                                  "    vtxColor = color;\n"
305                                  "}\n");
306 
307         programCollection.glslSources.add("color_frag")
308             << glu::FragmentSource("#version 310 es\n"
309                                    "layout(location = 0) in highp vec4 vtxColor;\n"
310                                    "layout(location = 0) out highp vec4 fragColor;\n"
311                                    "void main (void)\n"
312                                    "{\n"
313                                    "    fragColor = vtxColor;\n"
314                                    "}\n");
315     }
316     else
317     {
318         programCollection.glslSources.add("color_vert") << glu::VertexSource("#version 310 es\n"
319                                                                              "layout(location = 0) in vec4 position;\n"
320                                                                              "layout(location = 1) in vec4 color;\n"
321                                                                              "void main (void)\n"
322                                                                              "{\n"
323                                                                              "    gl_Position = position;\n"
324                                                                              "    gl_PointSize = 1.0f;\n"
325                                                                              "}\n");
326     }
327 }
328 
DepthTestInstance(Context & context,const PipelineConstructionType pipelineConstructionType,const VkFormat depthFormat,const VkCompareOp depthCompareOps[DepthTest::QUAD_COUNT],const bool separateDepthStencilLayouts,const VkPrimitiveTopology primitiveTopology,const bool depthBoundsTestEnable,const float depthBoundsMin,const float depthBoundsMax,const bool depthTestEnable,const bool stencilTestEnable,const bool colorAttachmentEnable,const bool hostVisible,const tcu::UVec2 renderSize,const DepthClipControlCase depthClipControl)329 DepthTestInstance::DepthTestInstance(Context &context, const PipelineConstructionType pipelineConstructionType,
330                                      const VkFormat depthFormat,
331                                      const VkCompareOp depthCompareOps[DepthTest::QUAD_COUNT],
332                                      const bool separateDepthStencilLayouts,
333                                      const VkPrimitiveTopology primitiveTopology, const bool depthBoundsTestEnable,
334                                      const float depthBoundsMin, const float depthBoundsMax, const bool depthTestEnable,
335                                      const bool stencilTestEnable, const bool colorAttachmentEnable,
336                                      const bool hostVisible, const tcu::UVec2 renderSize,
337                                      const DepthClipControlCase depthClipControl)
338     : vkt::TestInstance(context)
339     , m_renderSize(renderSize)
340     , m_colorFormat(colorAttachmentEnable ? VK_FORMAT_R8G8B8A8_UNORM : VK_FORMAT_UNDEFINED)
341     , m_depthFormat(depthFormat)
342     , m_separateDepthStencilLayouts(separateDepthStencilLayouts)
343     , m_primitiveTopology(primitiveTopology)
344     , m_depthBoundsTestEnable(depthBoundsTestEnable)
345     , m_depthBoundsMin(depthBoundsMin)
346     , m_depthBoundsMax(depthBoundsMax)
347     , m_depthTestEnable(depthTestEnable)
348     , m_stencilTestEnable(stencilTestEnable)
349     , m_colorAttachmentEnable(colorAttachmentEnable)
350     , m_hostVisible(hostVisible)
351     , m_depthClipControl(depthClipControl)
352     , m_graphicsPipelines{{context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
353                            context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType},
354                           {context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
355                            context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType},
356                           {context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
357                            context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType},
358                           {context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
359                            context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType}}
360     , m_altGraphicsPipelines{{context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
361                               context.getDevice(), m_context.getDeviceExtensions(), pipelineConstructionType},
362                              {context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
363                               context.getDevice(), m_context.getDeviceExtensions(), pipelineConstructionType},
364                              {context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
365                               context.getDevice(), m_context.getDeviceExtensions(), pipelineConstructionType},
366                              {context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
367                               context.getDevice(), m_context.getDeviceExtensions(), pipelineConstructionType}}
368 {
369     const DeviceInterface &vk       = context.getDeviceInterface();
370     const VkDevice vkDevice         = context.getDevice();
371     const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
372     SimpleAllocator memAlloc(
373         vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
374     const VkComponentMapping componentMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
375                                                      VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
376     const bool hasDepthClipControl                = (m_depthClipControl != DepthClipControlCase::DISABLED);
377     const bool useAltGraphicsPipelines            = (m_depthClipControl == DepthClipControlCase::BEFORE_TWO_DYNAMICS ||
378                                           m_depthClipControl == DepthClipControlCase::NORMAL_W);
379     const bool useAltVertices                     = m_depthClipControl == DepthClipControlCase::NORMAL_W;
380 
381     // Copy depth operators
382     deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * DepthTest::QUAD_COUNT);
383 
384     // Create color image
385     if (m_colorAttachmentEnable)
386     {
387         const VkImageCreateInfo colorImageParams = {
388             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                   // VkStructureType sType;
389             DE_NULL,                                                               // const void* pNext;
390             0u,                                                                    // VkImageCreateFlags flags;
391             VK_IMAGE_TYPE_2D,                                                      // VkImageType imageType;
392             m_colorFormat,                                                         // VkFormat format;
393             {m_renderSize.x(), m_renderSize.y(), 1u},                              // VkExtent3D extent;
394             1u,                                                                    // uint32_t mipLevels;
395             1u,                                                                    // uint32_t arrayLayers;
396             VK_SAMPLE_COUNT_1_BIT,                                                 // VkSampleCountFlagBits samples;
397             VK_IMAGE_TILING_OPTIMAL,                                               // VkImageTiling tiling;
398             VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
399             VK_SHARING_MODE_EXCLUSIVE,                                             // VkSharingMode sharingMode;
400             1u,                                                                    // uint32_t queueFamilyIndexCount;
401             &queueFamilyIndex,         // const uint32_t* pQueueFamilyIndices;
402             VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
403         };
404 
405         m_colorImage = createImage(vk, vkDevice, &colorImageParams);
406 
407         // Allocate and bind color image memory
408         m_colorImageAlloc =
409             memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
410         VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(),
411                                     m_colorImageAlloc->getOffset()));
412     }
413 
414     // Create depth image
415     {
416         const VkImageCreateInfo depthImageParams = {
417             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,      // VkStructureType sType;
418             DE_NULL,                                  // const void* pNext;
419             0u,                                       // VkImageCreateFlags flags;
420             VK_IMAGE_TYPE_2D,                         // VkImageType imageType;
421             m_depthFormat,                            // VkFormat format;
422             {m_renderSize.x(), m_renderSize.y(), 1u}, // VkExtent3D extent;
423             1u,                                       // uint32_t mipLevels;
424             1u,                                       // uint32_t arrayLayers;
425             VK_SAMPLE_COUNT_1_BIT,                    // VkSampleCountFlagBits samples;
426             VK_IMAGE_TILING_OPTIMAL,                  // VkImageTiling tiling;
427             VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
428             VK_SHARING_MODE_EXCLUSIVE,                                                     // VkSharingMode sharingMode;
429             1u,                        // uint32_t queueFamilyIndexCount;
430             &queueFamilyIndex,         // const uint32_t* pQueueFamilyIndices;
431             VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
432         };
433 
434         m_depthImage = createImage(vk, vkDevice, &depthImageParams);
435 
436         // Allocate and bind depth image memory
437         auto memReqs      = MemoryRequirement::Local | MemoryRequirement::HostVisible;
438         m_depthImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthImage),
439                                               m_hostVisible ? memReqs : MemoryRequirement::Any);
440         VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthImage, m_depthImageAlloc->getMemory(),
441                                     m_depthImageAlloc->getOffset()));
442 
443         const VkImageAspectFlags aspect = (mapVkFormat(m_depthFormat).order == tcu::TextureFormat::DS ?
444                                                VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT :
445                                                VK_IMAGE_ASPECT_DEPTH_BIT);
446         m_depthImageSubresourceRange =
447             makeImageSubresourceRange(aspect, 0u, depthImageParams.mipLevels, 0u, depthImageParams.arrayLayers);
448     }
449 
450     // Create color attachment view
451     if (m_colorAttachmentEnable)
452     {
453         const VkImageViewCreateInfo colorAttachmentViewParams = {
454             VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,   // VkStructureType sType;
455             DE_NULL,                                    // const void* pNext;
456             0u,                                         // VkImageViewCreateFlags flags;
457             *m_colorImage,                              // VkImage image;
458             VK_IMAGE_VIEW_TYPE_2D,                      // VkImageViewType viewType;
459             m_colorFormat,                              // VkFormat format;
460             componentMappingRGBA,                       // VkComponentMapping components;
461             {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u} // VkImageSubresourceRange subresourceRange;
462         };
463 
464         m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
465     }
466 
467     // Create depth attachment view
468     {
469         const VkImageViewCreateInfo depthAttachmentViewParams = {
470             VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
471             DE_NULL,                                  // const void* pNext;
472             0u,                                       // VkImageViewCreateFlags flags;
473             *m_depthImage,                            // VkImage image;
474             VK_IMAGE_VIEW_TYPE_2D,                    // VkImageViewType viewType;
475             m_depthFormat,                            // VkFormat format;
476             componentMappingRGBA,                     // VkComponentMapping components;
477             m_depthImageSubresourceRange,             // VkImageSubresourceRange subresourceRange;
478         };
479 
480         m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
481     }
482 
483     // Create render pass
484     m_renderPass = RenderPassWrapper(pipelineConstructionType, vk, vkDevice, m_colorFormat, m_depthFormat);
485 
486     // Create framebuffer
487     {
488         std::vector<VkImage> images;
489         std::vector<VkImageView> attachmentBindInfos;
490 
491         if (m_colorAttachmentEnable)
492         {
493             images.push_back(*m_colorImage);
494             attachmentBindInfos.push_back(*m_colorAttachmentView);
495         }
496 
497         images.push_back(*m_depthImage);
498         attachmentBindInfos.push_back(*m_depthAttachmentView);
499 
500         const VkFramebufferCreateInfo framebufferParams = {
501             VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
502             DE_NULL,                                   // const void* pNext;
503             0u,                                        // VkFramebufferCreateFlags flags;
504             *m_renderPass,                             // VkRenderPass renderPass;
505             (uint32_t)attachmentBindInfos.size(),      // uint32_t attachmentCount;
506             attachmentBindInfos.data(),                // const VkImageView* pAttachments;
507             (uint32_t)m_renderSize.x(),                // uint32_t width;
508             (uint32_t)m_renderSize.y(),                // uint32_t height;
509             1u                                         // uint32_t layers;
510         };
511 
512         m_renderPass.createFramebuffer(vk, vkDevice, &framebufferParams, images);
513     }
514 
515     // Create pipeline layout
516     {
517         const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
518             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
519             DE_NULL,                                       // const void* pNext;
520             0u,                                            // VkPipelineLayoutCreateFlags flags;
521             0u,                                            // uint32_t setLayoutCount;
522             DE_NULL,                                       // const VkDescriptorSetLayout* pSetLayouts;
523             0u,                                            // uint32_t pushConstantRangeCount;
524             DE_NULL                                        // const VkPushConstantRange* pPushConstantRanges;
525         };
526 
527         m_pipelineLayout = PipelineLayoutWrapper(pipelineConstructionType, vk, vkDevice, &pipelineLayoutParams);
528     }
529 
530     // Shader modules
531     m_vertexShaderModule = ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
532     if (m_colorAttachmentEnable)
533         m_fragmentShaderModule = ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
534 
535     const std::vector<VkViewport> viewports{makeViewport(m_renderSize)};
536     const std::vector<VkViewport> badViewports{makeViewport(0.0f, 0.0f, static_cast<float>(m_renderSize.x()) / 2.0f,
537                                                             static_cast<float>(m_renderSize.y()) / 2.0f, 1.0f, 0.0f)};
538     const std::vector<VkRect2D> scissors{makeRect2D(m_renderSize)};
539     const bool dynamicViewport =
540         (static_cast<int>(m_depthClipControl) > static_cast<int>(DepthClipControlCase::BEFORE_STATIC));
541 
542     // Create pipeline
543     {
544         const VkVertexInputBindingDescription vertexInputBindingDescription{
545             0u,                         // uint32_t binding;
546             sizeof(Vertex4RGBA),        // uint32_t strideInBytes;
547             VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate;
548         };
549 
550         const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2]{
551             {
552                 0u,                            // uint32_t location;
553                 0u,                            // uint32_t binding;
554                 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
555                 0u                             // uint32_t offset;
556             },
557             {
558                 1u,                            // uint32_t location;
559                 0u,                            // uint32_t binding;
560                 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
561                 offsetof(Vertex4RGBA, color),  // uint32_t offset;
562             }};
563 
564         const VkPipelineVertexInputStateCreateInfo vertexInputStateParams{
565             VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
566             DE_NULL,                                                   // const void* pNext;
567             0u,                                                        // VkPipelineVertexInputStateCreateFlags flags;
568             1u,                                                        // uint32_t vertexBindingDescriptionCount;
569             &vertexInputBindingDescription,  // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
570             2u,                              // uint32_t vertexAttributeDescriptionCount;
571             vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
572         };
573 
574         const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams{
575             VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType                                sType
576             DE_NULL,             // const void*                                    pNext
577             0u,                  // VkPipelineInputAssemblyStateCreateFlags        flags
578             m_primitiveTopology, // VkPrimitiveTopology                            topology
579             VK_FALSE             // VkBool32                                        primitiveRestartEnable
580         };
581 
582         VkPipelineDepthStencilStateCreateInfo depthStencilStateParams{
583             VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
584             DE_NULL,                                                    // const void* pNext;
585             0u,                                                         // VkPipelineDepthStencilStateCreateFlags flags;
586             m_depthTestEnable,                                          // VkBool32 depthTestEnable;
587             true,                                                       // VkBool32 depthWriteEnable;
588             VK_COMPARE_OP_LESS,                                         // VkCompareOp depthCompareOp;
589             m_depthBoundsTestEnable,                                    // VkBool32 depthBoundsTestEnable;
590             m_stencilTestEnable,                                        // VkBool32 stencilTestEnable;
591             // VkStencilOpState front;
592             {
593                 VK_STENCIL_OP_KEEP,  // VkStencilOp failOp;
594                 VK_STENCIL_OP_KEEP,  // VkStencilOp passOp;
595                 VK_STENCIL_OP_KEEP,  // VkStencilOp depthFailOp;
596                 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
597                 0u,                  // uint32_t compareMask;
598                 0u,                  // uint32_t writeMask;
599                 0u,                  // uint32_t reference;
600             },
601             // VkStencilOpState back;
602             {
603                 VK_STENCIL_OP_KEEP,  // VkStencilOp failOp;
604                 VK_STENCIL_OP_KEEP,  // VkStencilOp passOp;
605                 VK_STENCIL_OP_KEEP,  // VkStencilOp depthFailOp;
606                 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
607                 0u,                  // uint32_t compareMask;
608                 0u,                  // uint32_t writeMask;
609                 0u,                  // uint32_t reference;
610             },
611             m_depthBoundsMin, // float minDepthBounds;
612             m_depthBoundsMax, // float maxDepthBounds;
613         };
614 
615         // Make sure rasterization is not disabled when the fragment shader is missing.
616         const vk::VkPipelineRasterizationStateCreateInfo rasterizationStateParams{
617             vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
618             nullptr,                                                        // const void* pNext;
619             0u,                                  // VkPipelineRasterizationStateCreateFlags flags;
620             VK_FALSE,                            // VkBool32 depthClampEnable;
621             VK_FALSE,                            // VkBool32 rasterizerDiscardEnable;
622             vk::VK_POLYGON_MODE_FILL,            // VkPolygonMode polygonMode;
623             vk::VK_CULL_MODE_NONE,               // VkCullModeFlags cullMode;
624             vk::VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
625             VK_FALSE,                            // VkBool32 depthBiasEnable;
626             0.0f,                                // float depthBiasConstantFactor;
627             0.0f,                                // float depthBiasClamp;
628             0.0f,                                // float depthBiasSlopeFactor;
629             1.0f,                                // float lineWidth;
630         };
631 
632         PipelineViewportDepthClipControlCreateInfoWrapper depthClipControlWrapper;
633         PipelineViewportDepthClipControlCreateInfoWrapper depthClipControl01Wrapper;
634 
635 #ifndef CTS_USES_VULKANSC
636         VkPipelineViewportDepthClipControlCreateInfoEXT depthClipControlCreateInfo{
637             VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT, // VkStructureType sType;
638             DE_NULL,                                                                // const void* pNext;
639             VK_TRUE,                                                                // VkBool32 negativeOneToOne;
640         };
641         if (hasDepthClipControl)
642             depthClipControlWrapper.ptr = &depthClipControlCreateInfo;
643 
644         // Using the range 0,1 in the structure.
645         VkPipelineViewportDepthClipControlCreateInfoEXT depthClipControlCreateInfo01{
646             VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT, // VkStructureType sType;
647             DE_NULL,                                                                // const void* pNext;
648             VK_FALSE,                                                               // VkBool32 negativeOneToOne;
649         };
650         depthClipControl01Wrapper.ptr = &depthClipControlCreateInfo01;
651 #endif // CTS_USES_VULKANSC
652 
653         // Dynamic viewport if needed.
654         std::vector<VkDynamicState> dynamicStates;
655 
656         if (m_depthClipControl == DepthClipControlCase::BEFORE_DYNAMIC ||
657             m_depthClipControl == DepthClipControlCase::BEFORE_TWO_DYNAMICS ||
658             m_depthClipControl == DepthClipControlCase::AFTER_DYNAMIC)
659         {
660             dynamicStates.push_back(VK_DYNAMIC_STATE_VIEWPORT);
661         }
662 
663         const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = {
664             VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
665             nullptr,                                              // const void* pNext;
666             0u,                                                   // VkPipelineDynamicStateCreateFlags flags;
667             static_cast<uint32_t>(dynamicStates.size()),          // uint32_t dynamicStateCount;
668             de::dataOrNull(dynamicStates),                        // const VkDynamicState* pDynamicStates;
669         };
670 
671         const vk::VkPipelineColorBlendAttachmentState blendState{
672             VK_FALSE,
673             VK_BLEND_FACTOR_ONE,
674             VK_BLEND_FACTOR_ONE,
675             VK_BLEND_OP_ADD,
676             VK_BLEND_FACTOR_ONE,
677             VK_BLEND_FACTOR_ONE,
678             VK_BLEND_OP_ADD,
679             VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
680         };
681 
682         uint32_t colorAttachmentCount = (m_colorFormat != VK_FORMAT_UNDEFINED) ? 1u : 0u;
683 
684         const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo{
685             VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType                                sType
686             DE_NULL,                 // const void*                                    pNext
687             0u,                      // VkPipelineColorBlendStateCreateFlags            flags
688             VK_FALSE,                // VkBool32                                        logicOpEnable
689             VK_LOGIC_OP_CLEAR,       // VkLogicOp                                    logicOp
690             colorAttachmentCount,    // uint32_t                                        attachmentCount
691             &blendState,             // const VkPipelineColorBlendAttachmentState*    pAttachments
692             {0.0f, 0.0f, 0.0f, 0.0f} // float                                        blendConstants[4]
693         };
694 
695         for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
696         {
697             depthStencilStateParams.depthCompareOp = depthCompareOps[quadNdx];
698 
699             m_graphicsPipelines[quadNdx]
700                 .setDefaultMultisampleState()
701                 .setDefaultColorBlendState()
702                 .setViewportStatePnext(depthClipControlWrapper.ptr)
703                 .setDynamicState(&dynamicStateCreateInfo)
704                 .setupVertexInputState(&vertexInputStateParams, &inputAssemblyStateParams)
705                 .setupPreRasterizationShaderState((dynamicViewport ? badViewports : viewports), scissors,
706                                                   m_pipelineLayout, *m_renderPass, 0u, m_vertexShaderModule,
707                                                   &rasterizationStateParams)
708                 .setupFragmentShaderState(m_pipelineLayout, *m_renderPass, 0u, m_fragmentShaderModule,
709                                           &depthStencilStateParams)
710                 .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateCreateInfo)
711                 .setMonolithicPipelineLayout(m_pipelineLayout)
712                 .buildPipeline();
713 
714             if (useAltGraphicsPipelines)
715             {
716                 if (m_depthClipControl == DepthClipControlCase::NORMAL_W)
717                 {
718                     m_altGraphicsPipelines[quadNdx]
719                         .setDefaultMultisampleState()
720                         .setDefaultColorBlendState()
721                         .setViewportStatePnext(depthClipControl01Wrapper.ptr)
722                         .setDynamicState(&dynamicStateCreateInfo)
723                         .setupVertexInputState(&vertexInputStateParams, &inputAssemblyStateParams)
724                         .setupPreRasterizationShaderState((dynamicViewport ? badViewports : viewports), scissors,
725                                                           m_pipelineLayout, *m_renderPass, 0u, m_vertexShaderModule,
726                                                           &rasterizationStateParams)
727                         .setupFragmentShaderState(m_pipelineLayout, *m_renderPass, 0u, m_fragmentShaderModule,
728                                                   &depthStencilStateParams)
729                         .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateCreateInfo)
730                         .setMonolithicPipelineLayout(m_pipelineLayout)
731                         .buildPipeline();
732                 }
733                 else
734                 {
735                     m_altGraphicsPipelines[quadNdx]
736                         .setDefaultMultisampleState()
737                         .setDefaultColorBlendState()
738                         .setViewportStatePnext(depthClipControl01Wrapper.ptr)
739                         .setDynamicState(&dynamicStateCreateInfo)
740                         .setupVertexInputState(&vertexInputStateParams)
741                         .setupPreRasterizationShaderState((dynamicViewport ? badViewports : viewports), scissors,
742                                                           m_pipelineLayout, *m_renderPass, 0u, m_vertexShaderModule,
743                                                           &rasterizationStateParams)
744                         .setupFragmentShaderState(m_pipelineLayout, *m_renderPass, 0u, m_fragmentShaderModule,
745                                                   &depthStencilStateParams)
746                         .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateCreateInfo)
747                         .setMonolithicPipelineLayout(m_pipelineLayout)
748                         .buildPipeline();
749                 }
750             }
751         }
752     }
753 
754     // Create vertex buffer
755     {
756         const VkBufferCreateInfo vertexBufferParams = {
757             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
758             DE_NULL,                              // const void* pNext;
759             0u,                                   // VkBufferCreateFlags flags;
760             1024u,                                // VkDeviceSize size;
761             VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,    // VkBufferUsageFlags usage;
762             VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
763             1u,                                   // uint32_t queueFamilyIndexCount;
764             &queueFamilyIndex                     // const uint32_t* pQueueFamilyIndices;
765         };
766 
767         m_vertices          = createOverlappingQuads();
768         m_vertexBuffer      = createBuffer(vk, vkDevice, &vertexBufferParams);
769         m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer),
770                                                 MemoryRequirement::HostVisible);
771 
772         VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(),
773                                      m_vertexBufferAlloc->getOffset()));
774 
775         if (useAltVertices)
776         {
777             m_altVertices          = createOverlappingQuads();
778             m_altVertexBuffer      = createBuffer(vk, vkDevice, &vertexBufferParams);
779             m_altVertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_altVertexBuffer),
780                                                        MemoryRequirement::HostVisible);
781 
782             VK_CHECK(vk.bindBufferMemory(vkDevice, *m_altVertexBuffer, m_altVertexBufferAlloc->getMemory(),
783                                          m_altVertexBufferAlloc->getOffset()));
784         }
785 
786         // Adjust depths
787         for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
788             for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++)
789             {
790                 m_vertices[quadNdx * 6 + vertexNdx].position.z() =
791                     (hasDepthClipControl ? DepthTest::quadDepthsMinusOneToOne[quadNdx] :
792                                            DepthTest::quadDepths[quadNdx]);
793                 if (m_depthClipControl == DepthClipControlCase::NORMAL_W)
794                 {
795                     const float w = DepthTest::quadWs[quadNdx];
796                     m_vertices[quadNdx * 6 + vertexNdx].position.x() *= w;
797                     m_vertices[quadNdx * 6 + vertexNdx].position.y() *= w;
798                     m_vertices[quadNdx * 6 + vertexNdx].position.z() *= w;
799                     m_vertices[quadNdx * 6 + vertexNdx].position.w() = w;
800                 }
801                 if (useAltVertices)
802                 {
803                     m_altVertices[quadNdx * 6 + vertexNdx].position = m_vertices[quadNdx * 6 + vertexNdx].position;
804                     float z = m_altVertices[quadNdx * 6 + vertexNdx].position.z();
805                     float w = m_altVertices[quadNdx * 6 + vertexNdx].position.w();
806                     if (depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_NOT_EQUAL ||
807                         depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_LESS ||
808                         depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_LESS_OR_EQUAL)
809                     {
810                         z += 0.01f;
811                     }
812                     else if (depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_GREATER ||
813                              depthCompareOps[quadNdx] == vk::VK_COMPARE_OP_GREATER_OR_EQUAL)
814                     {
815                         z -= 0.01f;
816                     }
817                     m_altVertices[quadNdx * 6 + vertexNdx].position.z() = (z + w) * 0.5f;
818                 }
819             }
820 
821         // Load vertices into vertex buffer
822         deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
823         flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
824 
825         if (useAltVertices)
826         {
827             deMemcpy(m_altVertexBufferAlloc->getHostPtr(), m_altVertices.data(),
828                      m_altVertices.size() * sizeof(Vertex4RGBA));
829             flushAlloc(vk, vkDevice, *m_altVertexBufferAlloc);
830         }
831     }
832 
833     // Create command pool
834     m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
835 
836     // Create command buffer
837     {
838         std::vector<VkClearValue> attachmentClearValues;
839 
840         if (m_colorAttachmentEnable)
841             attachmentClearValues.push_back(defaultClearValue(m_colorFormat));
842 
843         attachmentClearValues.push_back(defaultClearValue(m_depthFormat));
844 
845         const VkImageMemoryBarrier colorBarrier = {
846             VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,     // VkStructureType            sType;
847             DE_NULL,                                    // const void*                pNext;
848             (VkAccessFlags)0,                           // VkAccessFlags              srcAccessMask;
849             VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,       // VkAccessFlags              dstAccessMask;
850             VK_IMAGE_LAYOUT_UNDEFINED,                  // VkImageLayout              oldLayout;
851             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,   // VkImageLayout              newLayout;
852             VK_QUEUE_FAMILY_IGNORED,                    // uint32_t                   srcQueueFamilyIndex;
853             VK_QUEUE_FAMILY_IGNORED,                    // uint32_t                   dstQueueFamilyIndex;
854             *m_colorImage,                              // VkImage                    image;
855             {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u} // VkImageSubresourceRange    subresourceRange;
856         };
857 
858         VkImageSubresourceRange depthBarrierSubresourceRange = m_depthImageSubresourceRange;
859         VkImageLayout newLayout                              = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
860         if (m_separateDepthStencilLayouts)
861         {
862             depthBarrierSubresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
863             newLayout                               = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
864         }
865 
866         const VkImageMemoryBarrier depthBarrier = {
867             VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,       // VkStructureType            sType;
868             DE_NULL,                                      // const void*                pNext;
869             (VkAccessFlags)0,                             // VkAccessFlags              srcAccessMask;
870             VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags              dstAccessMask;
871             VK_IMAGE_LAYOUT_UNDEFINED,                    // VkImageLayout              oldLayout;
872             newLayout,                                    // VkImageLayout              newLayout;
873             VK_QUEUE_FAMILY_IGNORED,                      // uint32_t                   srcQueueFamilyIndex;
874             VK_QUEUE_FAMILY_IGNORED,                      // uint32_t                   dstQueueFamilyIndex;
875             *m_depthImage,                                // VkImage                    image;
876             depthBarrierSubresourceRange,                 // VkImageSubresourceRange    subresourceRange;
877         };
878 
879         std::vector<VkImageMemoryBarrier> imageLayoutBarriers;
880 
881         if (m_colorAttachmentEnable)
882             imageLayoutBarriers.push_back(colorBarrier);
883 
884         imageLayoutBarriers.push_back(depthBarrier);
885 
886         m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
887 
888         beginCommandBuffer(vk, *m_cmdBuffer, 0u);
889 
890         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
891                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
892                                   VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
893                                   VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
894                               (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, (uint32_t)imageLayoutBarriers.size(),
895                               imageLayoutBarriers.data());
896 
897         m_renderPass.begin(vk, *m_cmdBuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()),
898                            (uint32_t)attachmentClearValues.size(), attachmentClearValues.data());
899 
900         const VkDeviceSize quadOffset = (m_vertices.size() / DepthTest::QUAD_COUNT) * sizeof(Vertex4RGBA);
901 
902         for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
903         {
904             VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;
905 
906             if (m_depthClipControl == DepthClipControlCase::NORMAL_W &&
907                 depthCompareOps[quadNdx] != vk::VK_COMPARE_OP_NEVER)
908             {
909                 m_altGraphicsPipelines[quadNdx].bind(*m_cmdBuffer);
910                 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_altVertexBuffer.get(), &vertexBufferOffset);
911                 vk.cmdDraw(*m_cmdBuffer, (uint32_t)(m_altVertices.size() / DepthTest::QUAD_COUNT), 1, 0, 0);
912             }
913 
914             if (m_depthClipControl == DepthClipControlCase::BEFORE_STATIC ||
915                 m_depthClipControl == DepthClipControlCase::BEFORE_DYNAMIC ||
916                 m_depthClipControl == DepthClipControlCase::BEFORE_TWO_DYNAMICS)
917             {
918                 if (vk::isConstructionTypeShaderObject(pipelineConstructionType))
919                 {
920 #ifndef CTS_USES_VULKANSC
921                     vk.cmdSetViewportWithCount(*m_cmdBuffer, 1u, viewports.data());
922 #else
923                     vk.cmdSetViewportWithCountEXT(*m_cmdBuffer, 1u, viewports.data());
924 #endif
925                 }
926                 else
927                 {
928                     vk.cmdSetViewport(*m_cmdBuffer, 0u, 1u, viewports.data());
929                 }
930             }
931 
932             if (m_depthClipControl == DepthClipControlCase::BEFORE_TWO_DYNAMICS)
933                 m_altGraphicsPipelines[quadNdx].bind(*m_cmdBuffer);
934             m_graphicsPipelines[quadNdx].bind(*m_cmdBuffer);
935 
936             if (m_depthClipControl == DepthClipControlCase::AFTER_DYNAMIC)
937             {
938                 if (vk::isConstructionTypeShaderObject(pipelineConstructionType))
939                 {
940 #ifndef CTS_USES_VULKANSC
941                     vk.cmdSetViewportWithCount(*m_cmdBuffer, 1u, viewports.data());
942 #else
943                     vk.cmdSetViewportWithCountEXT(*m_cmdBuffer, 1u, viewports.data());
944 #endif
945                 }
946                 else
947                 {
948                     vk.cmdSetViewport(*m_cmdBuffer, 0u, 1u, viewports.data());
949                 }
950             }
951 
952             vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
953             vk.cmdDraw(*m_cmdBuffer, (uint32_t)(m_vertices.size() / DepthTest::QUAD_COUNT), 1, 0, 0);
954         }
955 
956         m_renderPass.end(vk, *m_cmdBuffer);
957         endCommandBuffer(vk, *m_cmdBuffer);
958     }
959 }
960 
~DepthTestInstance(void)961 DepthTestInstance::~DepthTestInstance(void)
962 {
963 }
964 
iterate(void)965 tcu::TestStatus DepthTestInstance::iterate(void)
966 {
967     const DeviceInterface &vk = m_context.getDeviceInterface();
968     const VkDevice vkDevice   = m_context.getDevice();
969     const VkQueue queue       = m_context.getUniversalQueue();
970 
971     submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
972 
973     return verifyImage();
974 }
975 
verifyImage(void)976 tcu::TestStatus DepthTestInstance::verifyImage(void)
977 {
978     const tcu::TextureFormat tcuColorFormat = mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM);
979     const tcu::TextureFormat tcuDepthFormat = mapVkFormat(m_depthFormat);
980     const ColorVertexShader vertexShader;
981     const ColorFragmentShader fragmentShader(tcuColorFormat, tcuDepthFormat,
982                                              (m_depthClipControl != DepthClipControlCase::DISABLED));
983     const rr::Program program(&vertexShader, &fragmentShader);
984     ReferenceRenderer refRenderer(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
985     bool colorCompareOk = false;
986     bool depthCompareOk = false;
987 
988     // Render reference image
989     {
990         for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
991         {
992             // Set depth state
993             rr::RenderState renderState(refRenderer.getViewportState(),
994                                         m_context.getDeviceProperties().limits.subPixelPrecisionBits);
995             renderState.fragOps.depthTestEnabled = m_depthTestEnable;
996             renderState.fragOps.depthFunc        = mapVkCompareOp(m_depthCompareOps[quadNdx]);
997             if (m_depthBoundsTestEnable)
998             {
999                 renderState.fragOps.depthBoundsTestEnabled = true;
1000                 renderState.fragOps.minDepthBound          = m_depthBoundsMin;
1001                 renderState.fragOps.maxDepthBound          = m_depthBoundsMax;
1002             }
1003 
1004             refRenderer.draw(
1005                 renderState, mapVkPrimitiveTopology(m_primitiveTopology),
1006                 std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6, m_vertices.begin() + (quadNdx + 1) * 6));
1007         }
1008     }
1009 
1010     // Compare color result with reference image
1011     if (m_colorAttachmentEnable)
1012     {
1013         const DeviceInterface &vk       = m_context.getDeviceInterface();
1014         const VkDevice vkDevice         = m_context.getDevice();
1015         const VkQueue queue             = m_context.getUniversalQueue();
1016         const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1017         SimpleAllocator allocator(
1018             vk, vkDevice,
1019             getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1020         de::MovePtr<tcu::TextureLevel> result = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator,
1021                                                                     *m_colorImage, m_colorFormat, m_renderSize);
1022 
1023         colorCompareOk = tcu::intThresholdPositionDeviationCompare(
1024             m_context.getTestContext().getLog(), "IntImageCompare", "Image comparison", refRenderer.getAccess(),
1025             result->getAccess(), tcu::UVec4(2, 2, 2, 2), tcu::IVec3(1, 1, 0), true, tcu::COMPARE_LOG_RESULT);
1026     }
1027     else
1028     {
1029         colorCompareOk = true;
1030     }
1031 
1032     // Compare depth result with reference image
1033     {
1034         const DeviceInterface &vk       = m_context.getDeviceInterface();
1035         const VkDevice vkDevice         = m_context.getDevice();
1036         const VkQueue queue             = m_context.getUniversalQueue();
1037         const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1038         SimpleAllocator allocator(
1039             vk, vkDevice,
1040             getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1041         de::MovePtr<tcu::TextureLevel> result = readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator,
1042                                                                     *m_depthImage, m_depthFormat, m_renderSize);
1043 
1044         {
1045             de::MovePtr<tcu::TextureLevel> convertedReferenceLevel;
1046             tcu::Maybe<tcu::TextureFormat> convertedFormat;
1047 
1048             if (refRenderer.getDepthStencilAccess().getFormat().type == tcu::TextureFormat::UNSIGNED_INT_24_8_REV)
1049             {
1050                 convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT24);
1051             }
1052             else if (refRenderer.getDepthStencilAccess().getFormat().type == tcu::TextureFormat::UNSIGNED_INT_16_8_8)
1053             {
1054                 convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
1055             }
1056             else if (refRenderer.getDepthStencilAccess().getFormat().type ==
1057                      tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV)
1058             {
1059                 convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
1060             }
1061 
1062             if (convertedFormat)
1063             {
1064                 convertedReferenceLevel = de::MovePtr<tcu::TextureLevel>(
1065                     new tcu::TextureLevel(*convertedFormat, refRenderer.getDepthStencilAccess().getSize().x(),
1066                                           refRenderer.getDepthStencilAccess().getSize().y()));
1067                 tcu::copy(convertedReferenceLevel->getAccess(), refRenderer.getDepthStencilAccess());
1068             }
1069 
1070             float depthThreshold = 0.0f;
1071 
1072             if (tcu::getTextureChannelClass(result->getFormat().type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
1073             {
1074                 const tcu::IVec4 formatBits = tcu::getTextureFormatBitDepth(result->getFormat());
1075                 depthThreshold              = 1.0f / static_cast<float>((1 << formatBits[0]) - 1);
1076             }
1077             else if (tcu::getTextureChannelClass(result->getFormat().type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
1078             {
1079                 depthThreshold = 0.0000001f;
1080             }
1081             else
1082                 TCU_FAIL("unrecognized format type class");
1083 
1084             depthCompareOk = tcu::floatThresholdCompare(
1085                 m_context.getTestContext().getLog(), "DepthImageCompare", "Depth image comparison",
1086                 convertedReferenceLevel ? convertedReferenceLevel->getAccess() : refRenderer.getDepthStencilAccess(),
1087                 result->getAccess(), tcu::Vec4(depthThreshold, 0.0f, 0.0f, 0.0f), tcu::COMPARE_LOG_RESULT);
1088         }
1089     }
1090 
1091     if (colorCompareOk && depthCompareOk)
1092         return tcu::TestStatus::pass("Result image matches reference");
1093     else
1094         return tcu::TestStatus::fail("Image mismatch");
1095 }
1096 
getFormatCaseName(const VkFormat format)1097 std::string getFormatCaseName(const VkFormat format)
1098 {
1099     const std::string fullName = getFormatName(format);
1100 
1101     DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
1102 
1103     return de::toLower(fullName.substr(10));
1104 }
1105 
getTopologyName(const VkPrimitiveTopology topology)1106 std::string getTopologyName(const VkPrimitiveTopology topology)
1107 {
1108     const std::string fullName = getPrimitiveTopologyName(topology);
1109 
1110     DE_ASSERT(de::beginsWith(fullName, "VK_PRIMITIVE_TOPOLOGY_"));
1111 
1112     return de::toLower(fullName.substr(22));
1113 }
1114 
getCompareOpsName(const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])1115 std::string getCompareOpsName(const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])
1116 {
1117     std::ostringstream name;
1118 
1119     for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
1120     {
1121         const std::string fullOpName = getCompareOpName(quadDepthOps[quadNdx]);
1122 
1123         DE_ASSERT(de::beginsWith(fullOpName, "VK_COMPARE_OP_"));
1124 
1125         name << de::toLower(fullOpName.substr(14));
1126 
1127         if (quadNdx < DepthTest::QUAD_COUNT - 1)
1128             name << "_";
1129     }
1130 
1131     return name.str();
1132 }
1133 
1134 } // namespace
1135 
createDepthTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)1136 tcu::TestCaseGroup *createDepthTests(tcu::TestContext &testCtx, PipelineConstructionType pipelineConstructionType)
1137 {
1138     const auto genFormatTests =
1139         (!vk::isConstructionTypeShaderObject(pipelineConstructionType) ||
1140          pipelineConstructionType == vk::PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_UNLINKED_SPIRV);
1141 
1142     const VkFormat depthFormats[] = {VK_FORMAT_D16_UNORM,         VK_FORMAT_X8_D24_UNORM_PACK32,
1143                                      VK_FORMAT_D32_SFLOAT,        VK_FORMAT_D16_UNORM_S8_UINT,
1144                                      VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT};
1145 
1146     // Each entry configures the depth compare operators of QUAD_COUNT quads.
1147     // All entries cover pair-wise combinations of compare operators.
1148     const VkCompareOp depthOps[][DepthTest::QUAD_COUNT] = {
1149         {VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL},
1150         {VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER},
1151         {VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS_OR_EQUAL},
1152         {VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL,
1153          VK_COMPARE_OP_GREATER_OR_EQUAL},
1154         {VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_ALWAYS},
1155         {VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS},
1156         {VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER},
1157         {VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_EQUAL},
1158         {VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS},
1159         {VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL},
1160         {VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER},
1161         {VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS_OR_EQUAL},
1162         {VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_EQUAL},
1163         {VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_ALWAYS},
1164         {VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL},
1165         {VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS},
1166         {VK_COMPARE_OP_GREATER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_ALWAYS},
1167         {VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER},
1168         {VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL},
1169         {VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER_OR_EQUAL},
1170         {VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NEVER},
1171         {VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL,
1172          VK_COMPARE_OP_GREATER},
1173         {VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS_OR_EQUAL},
1174         {VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NOT_EQUAL},
1175         {VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL},
1176         {VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL,
1177          VK_COMPARE_OP_LESS_OR_EQUAL},
1178         {VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS},
1179         {VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_EQUAL},
1180         {VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_NEVER},
1181         {VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL,
1182          VK_COMPARE_OP_LESS_OR_EQUAL},
1183         {VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_EQUAL},
1184         {VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS},
1185         {VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_ALWAYS},
1186         {VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL},
1187         {VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER},
1188         {VK_COMPARE_OP_LESS, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER_OR_EQUAL},
1189         {VK_COMPARE_OP_LESS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS_OR_EQUAL},
1190         {VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NEVER},
1191         {VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_EQUAL},
1192         {VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NOT_EQUAL},
1193         {VK_COMPARE_OP_LESS, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_ALWAYS},
1194         {VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_ALWAYS},
1195         {VK_COMPARE_OP_LESS, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS},
1196         {VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_EQUAL},
1197         {VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER},
1198         {VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NOT_EQUAL},
1199         {VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL},
1200         {VK_COMPARE_OP_NEVER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER_OR_EQUAL},
1201         {VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NEVER},
1202         {VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS},
1203         {VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_ALWAYS},
1204         {VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER},
1205         {VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_EQUAL},
1206         {VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NOT_EQUAL},
1207         {VK_COMPARE_OP_NEVER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS},
1208         {VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NEVER},
1209         {VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_NOT_EQUAL},
1210         {VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_EQUAL},
1211         {VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL},
1212         {VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER},
1213         {VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NEVER},
1214         {VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER},
1215         {VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NOT_EQUAL},
1216         {VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_ALWAYS},
1217         {VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER},
1218         {VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER},
1219         {VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL},
1220         {VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL,
1221          VK_COMPARE_OP_LESS_OR_EQUAL},
1222         {VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS},
1223         {VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NEVER},
1224         {VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_EQUAL},
1225         {VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER_OR_EQUAL},
1226         {VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS},
1227         {VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER}};
1228 
1229     const bool colorAttachmentEnabled[] = {true, false};
1230 
1231     const VkPrimitiveTopology primitiveTopologies[] = {
1232         VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST};
1233 
1234     de::MovePtr<tcu::TestCaseGroup> depthTests(new tcu::TestCaseGroup(testCtx, "depth"));
1235     de::MovePtr<tcu::TestCaseGroup> noColorAttachmentTests(new tcu::TestCaseGroup(testCtx, "nocolor"));
1236 
1237     // Tests for format features
1238     if (!isConstructionTypeLibrary(pipelineConstructionType) &&
1239         !isConstructionTypeShaderObject(pipelineConstructionType))
1240     {
1241         de::MovePtr<tcu::TestCaseGroup> formatFeaturesTests(new tcu::TestCaseGroup(testCtx, "format_features"));
1242 
1243         // Formats that must be supported in all implementations
1244         addFunctionCase(formatFeaturesTests.get(), "support_d16_unorm", testSupportsDepthStencilFormat,
1245                         VK_FORMAT_D16_UNORM);
1246 
1247         // Sets where at least one of the formats must be supported
1248         const VkFormat depthOnlyFormats[]    = {VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT};
1249         const VkFormat depthStencilFormats[] = {VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT};
1250 
1251         addFunctionCase(
1252             formatFeaturesTests.get(), "support_d24_unorm_or_d32_sfloat", testSupportsAtLeastOneDepthStencilFormat,
1253             std::vector<VkFormat>(depthOnlyFormats, depthOnlyFormats + DE_LENGTH_OF_ARRAY(depthOnlyFormats)));
1254 
1255         addFunctionCase(
1256             formatFeaturesTests.get(), "support_d24_unorm_s8_uint_or_d32_sfloat_s8_uint",
1257             testSupportsAtLeastOneDepthStencilFormat,
1258             std::vector<VkFormat>(depthStencilFormats, depthStencilFormats + DE_LENGTH_OF_ARRAY(depthStencilFormats)));
1259 
1260         depthTests->addChild(formatFeaturesTests.release());
1261     }
1262 
1263     for (uint32_t colorAttachmentEnabledIdx = 0; colorAttachmentEnabledIdx < DE_LENGTH_OF_ARRAY(colorAttachmentEnabled);
1264          colorAttachmentEnabledIdx++)
1265     {
1266         const bool colorEnabled = colorAttachmentEnabled[colorAttachmentEnabledIdx];
1267 
1268         // Tests for format and compare operators
1269         if (genFormatTests)
1270         {
1271             // Uses different depth formats
1272             de::MovePtr<tcu::TestCaseGroup> formatTests(new tcu::TestCaseGroup(testCtx, "format"));
1273 
1274             for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthFormats); formatNdx++)
1275             {
1276                 const bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(depthFormats[formatNdx]).order);
1277                 const bool hasStencil = tcu::hasStencilComponent(mapVkFormat(depthFormats[formatNdx]).order);
1278                 const int separateLayoutsLoopCount = (hasDepth && hasStencil) ? 2 : 1;
1279 
1280                 for (int separateDepthStencilLayouts = 0; separateDepthStencilLayouts < separateLayoutsLoopCount;
1281                      ++separateDepthStencilLayouts)
1282                 {
1283                     const bool useSeparateDepthStencilLayouts = bool(separateDepthStencilLayouts);
1284 
1285                     de::MovePtr<tcu::TestCaseGroup> formatTest(
1286                         new tcu::TestCaseGroup(testCtx, (getFormatCaseName(depthFormats[formatNdx]) +
1287                                                          ((useSeparateDepthStencilLayouts) ? "_separate_layouts" : ""))
1288                                                             .c_str()));
1289                     // Combines depth compare operators
1290                     de::MovePtr<tcu::TestCaseGroup> compareOpsTests(new tcu::TestCaseGroup(testCtx, "compare_ops"));
1291 
1292                     for (size_t topologyNdx = 0; topologyNdx < DE_LENGTH_OF_ARRAY(primitiveTopologies); topologyNdx++)
1293                     {
1294                         const std::string topologyName = getTopologyName(primitiveTopologies[topologyNdx]) + "_";
1295                         for (size_t opsNdx = 0; opsNdx < DE_LENGTH_OF_ARRAY(depthOps); opsNdx++)
1296                         {
1297                             compareOpsTests->addChild(new DepthTest(
1298                                 testCtx, topologyName + getCompareOpsName(depthOps[opsNdx]), pipelineConstructionType,
1299                                 depthFormats[formatNdx], depthOps[opsNdx], useSeparateDepthStencilLayouts,
1300                                 primitiveTopologies[topologyNdx], false, 0.0f, 1.0f));
1301 
1302                             compareOpsTests->addChild(new DepthTest(
1303                                 testCtx, topologyName + getCompareOpsName(depthOps[opsNdx]) + "_depth_bounds_test",
1304                                 pipelineConstructionType, depthFormats[formatNdx], depthOps[opsNdx],
1305                                 useSeparateDepthStencilLayouts, primitiveTopologies[topologyNdx], true, 0.1f, 0.25f,
1306                                 true, false, colorEnabled));
1307                         }
1308                     }
1309                     // Special VkPipelineDepthStencilStateCreateInfo known to have issues
1310                     {
1311                         const VkCompareOp depthOpsSpecial[DepthTest::QUAD_COUNT] = {
1312                             VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER};
1313 
1314                         compareOpsTests->addChild(new DepthTest(
1315                             testCtx, "never_zerodepthbounds_depthdisabled_stencilenabled", pipelineConstructionType,
1316                             depthFormats[formatNdx], depthOpsSpecial, useSeparateDepthStencilLayouts,
1317                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, true, 0.0f, 0.0f, false, true, colorEnabled));
1318                     }
1319                     formatTest->addChild(compareOpsTests.release());
1320 
1321                     // Test case with depth test enabled, but depth write disabled
1322                     de::MovePtr<tcu::TestCaseGroup> depthTestDisabled(
1323                         new tcu::TestCaseGroup(testCtx, "depth_test_disabled"));
1324                     {
1325                         const VkCompareOp depthOpsDepthTestDisabled[DepthTest::QUAD_COUNT] = {
1326                             VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS};
1327                         depthTestDisabled->addChild(new DepthTest(
1328                             testCtx, "depth_write_enabled", pipelineConstructionType, depthFormats[formatNdx],
1329                             depthOpsDepthTestDisabled, useSeparateDepthStencilLayouts,
1330                             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false, /* depthBoundsTestEnable */
1331                             0.0f,                                       /* depthBoundMin*/
1332                             1.0f,                                       /* depthBoundMax*/
1333                             false,                                      /* depthTestEnable */
1334                             false,                                      /* stencilTestEnable */
1335                             colorEnabled /* colorAttachmentEnable */));
1336                     }
1337                     formatTest->addChild(depthTestDisabled.release());
1338 
1339                     // Test case with depth buffer placed in local memory
1340                     de::MovePtr<tcu::TestCaseGroup> hostVisibleTests(new tcu::TestCaseGroup(testCtx, "host_visible"));
1341                     {
1342                         const VkCompareOp hostVisibleOps[DepthTest::QUAD_COUNT] = {
1343                             VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS};
1344 
1345                         // Depth buffer placed in local memory
1346                         hostVisibleTests->addChild(
1347                             new DepthTest(testCtx, "local_memory_depth_buffer", pipelineConstructionType,
1348                                           depthFormats[formatNdx], hostVisibleOps, useSeparateDepthStencilLayouts,
1349                                           VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false, /* depthBoundsTestEnable */
1350                                           0.0f,                                       /* depthBoundMin*/
1351                                           1.0f,                                       /* depthBoundMax*/
1352                                           true,                                       /* depthTestEnable */
1353                                           false,                                      /* stencilTestEnable */
1354                                           colorEnabled,                               /* colorAttachmentEnable */
1355                                           true,                                       /* hostVisible */
1356                                           tcu::UVec2(256, 256) /*renderSize*/));
1357                     }
1358 
1359                     formatTest->addChild(hostVisibleTests.release());
1360                     formatTests->addChild(formatTest.release());
1361                 }
1362             }
1363             if (colorEnabled)
1364                 depthTests->addChild(formatTests.release());
1365             else
1366                 noColorAttachmentTests->addChild(formatTests.release());
1367         }
1368     }
1369     if (genFormatTests)
1370         depthTests->addChild(noColorAttachmentTests.release());
1371 
1372 #ifndef CTS_USES_VULKANSC
1373     de::MovePtr<tcu::TestCaseGroup> depthClipControlTests(new tcu::TestCaseGroup(testCtx, "depth_clip_control"));
1374     {
1375         const VkCompareOp compareOps[] = {VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS};
1376 
1377         const struct
1378         {
1379             const DepthClipControlCase viewportCase;
1380             const std::string suffix;
1381         } kViewportCases[] = {
1382             {DepthClipControlCase::NORMAL, ""},
1383             {DepthClipControlCase::NORMAL_W, "_different_w"},
1384             {DepthClipControlCase::BEFORE_STATIC, "_viewport_before_static"},
1385             {DepthClipControlCase::BEFORE_DYNAMIC, "_viewport_before_dynamic"},
1386             {DepthClipControlCase::BEFORE_TWO_DYNAMICS, "_viewport_before_two_dynamic"},
1387             {DepthClipControlCase::AFTER_DYNAMIC, "_viewport_after_dynamic"},
1388         };
1389 
1390         for (const auto &viewportCase : kViewportCases)
1391             for (const auto &format : depthFormats)
1392                 for (const auto &compareOp : compareOps)
1393                 {
1394                     std::string testName = getFormatCaseName(format) + "_" +
1395                                            de::toLower(std::string(getCompareOpName(compareOp)).substr(14)) +
1396                                            viewportCase.suffix;
1397 
1398                     const VkCompareOp ops[DepthTest::QUAD_COUNT] = {compareOp, compareOp, compareOp, compareOp};
1399                     depthClipControlTests->addChild(new DepthTest(testCtx, testName, pipelineConstructionType, format,
1400                                                                   ops, false, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
1401                                                                   false, 0.0f, 1.0f, true, false, true, false,
1402                                                                   tcu::UVec2(32, 32), viewportCase.viewportCase));
1403                 }
1404     }
1405     depthTests->addChild(depthClipControlTests.release());
1406 #endif // CTS_USES_VULKANSC
1407 
1408     return depthTests.release();
1409 }
1410 
1411 } // namespace pipeline
1412 } // namespace vkt
1413