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