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