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