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