1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Depth Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktPipelineDepthTests.hpp"
26 #include "vktPipelineClearUtil.hpp"
27 #include "vktPipelineImageUtil.hpp"
28 #include "vktPipelineVertexUtil.hpp"
29 #include "vktPipelineReferenceRenderer.hpp"
30 #include "vktTestCase.hpp"
31 #include "vktTestCaseUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkRef.hpp"
37 #include "vkRefUtil.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "deUniquePtr.hpp"
43 #include "deStringUtil.hpp"
44 #include "deMemory.h"
45
46 #include <sstream>
47 #include <vector>
48
49 namespace vkt
50 {
51 namespace pipeline
52 {
53
54 using namespace vk;
55
56 namespace
57 {
58
isSupportedDepthStencilFormat(const InstanceInterface & instanceInterface,VkPhysicalDevice device,VkFormat format)59 bool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
60 {
61 VkFormatProperties formatProps;
62
63 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
64
65 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0u;
66 }
67
testSupportsDepthStencilFormat(Context & context,VkFormat format)68 tcu::TestStatus testSupportsDepthStencilFormat (Context& context, VkFormat format)
69 {
70 DE_ASSERT(vk::isDepthStencilFormat(format));
71
72 if (isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), format))
73 return tcu::TestStatus::pass("Format can be used in depth/stencil attachment");
74 else
75 return tcu::TestStatus::fail("Unsupported depth/stencil attachment format");
76 }
77
testSupportsAtLeastOneDepthStencilFormat(Context & context,const std::vector<VkFormat> formats)78 tcu::TestStatus testSupportsAtLeastOneDepthStencilFormat (Context& context, const std::vector<VkFormat> formats)
79 {
80 std::ostringstream supportedFormatsMsg;
81 bool pass = false;
82
83 DE_ASSERT(!formats.empty());
84
85 for (size_t formatNdx = 0; formatNdx < formats.size(); formatNdx++)
86 {
87 const VkFormat format = formats[formatNdx];
88
89 DE_ASSERT(vk::isDepthStencilFormat(format));
90
91 if (isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), format))
92 {
93 pass = true;
94 supportedFormatsMsg << vk::getFormatName(format);
95
96 if (formatNdx < formats.size() - 1)
97 supportedFormatsMsg << ", ";
98 }
99 }
100
101 if (pass)
102 return tcu::TestStatus::pass(std::string("Supported depth/stencil formats: ") + supportedFormatsMsg.str());
103 else
104 return tcu::TestStatus::fail("All depth/stencil formats are unsupported");
105 }
106
107 class DepthTest : public vkt::TestCase
108 {
109 public:
110 enum
111 {
112 QUAD_COUNT = 4
113 };
114
115 static const float quadDepths[QUAD_COUNT];
116
117 DepthTest (tcu::TestContext& testContext,
118 const std::string& name,
119 const std::string& description,
120 const VkFormat depthFormat,
121 const VkCompareOp depthCompareOps[QUAD_COUNT],
122 const bool separateDepthStencilLayouts,
123 const bool depthBoundsTestEnable = false,
124 const float depthBoundsMin = 0.0f,
125 const float depthBoundsMax = 1.0f,
126 const bool depthTestEnable = true,
127 const bool stencilTestEnable = false,
128 const bool colorAttachmentEnable = true);
129 virtual ~DepthTest (void);
130 virtual void initPrograms (SourceCollections& programCollection) const;
131 virtual void checkSupport (Context& context) const;
132 virtual TestInstance* createInstance (Context& context) const;
133
134 private:
135 const VkFormat m_depthFormat;
136 const bool m_separateDepthStencilLayouts;
137 const bool m_depthBoundsTestEnable;
138 const float m_depthBoundsMin;
139 const float m_depthBoundsMax;
140 const bool m_depthTestEnable;
141 const bool m_stencilTestEnable;
142 const bool m_colorAttachmentEnable;
143 VkCompareOp m_depthCompareOps[QUAD_COUNT];
144 };
145
146 class DepthTestInstance : public vkt::TestInstance
147 {
148 public:
149 DepthTestInstance (Context& context,
150 const VkFormat depthFormat,
151 const VkCompareOp depthCompareOps[DepthTest::QUAD_COUNT],
152 const bool separateDepthStencilLayouts,
153 const bool depthBoundsTestEnable,
154 const float depthBoundsMin,
155 const float depthBoundsMax,
156 const bool depthTestEnable,
157 const bool stencilTestEnable,
158 const bool colorAttachmentEnable);
159 virtual ~DepthTestInstance (void);
160 virtual tcu::TestStatus iterate (void);
161
162 private:
163 tcu::TestStatus verifyImage (void);
164
165 private:
166 VkCompareOp m_depthCompareOps[DepthTest::QUAD_COUNT];
167 const tcu::UVec2 m_renderSize;
168 const VkFormat m_colorFormat;
169 const VkFormat m_depthFormat;
170 const bool m_separateDepthStencilLayouts;
171 const bool m_depthBoundsTestEnable;
172 const float m_depthBoundsMin;
173 const float m_depthBoundsMax;
174 const bool m_depthTestEnable;
175 const bool m_stencilTestEnable;
176 const bool m_colorAttachmentEnable;
177 VkImageSubresourceRange m_depthImageSubresourceRange;
178
179 Move<VkImage> m_colorImage;
180 de::MovePtr<Allocation> m_colorImageAlloc;
181 Move<VkImage> m_depthImage;
182 de::MovePtr<Allocation> m_depthImageAlloc;
183 Move<VkImageView> m_colorAttachmentView;
184 Move<VkImageView> m_depthAttachmentView;
185 Move<VkRenderPass> m_renderPass;
186 Move<VkFramebuffer> m_framebuffer;
187
188 Move<VkShaderModule> m_vertexShaderModule;
189 Move<VkShaderModule> m_fragmentShaderModule;
190
191 Move<VkBuffer> m_vertexBuffer;
192 std::vector<Vertex4RGBA> m_vertices;
193 de::MovePtr<Allocation> m_vertexBufferAlloc;
194
195 Move<VkPipelineLayout> m_pipelineLayout;
196 Move<VkPipeline> m_graphicsPipelines[DepthTest::QUAD_COUNT];
197
198 Move<VkCommandPool> m_cmdPool;
199 Move<VkCommandBuffer> m_cmdBuffer;
200 };
201
202 const float DepthTest::quadDepths[QUAD_COUNT] =
203 {
204 0.1f,
205 0.0f,
206 0.3f,
207 0.2f
208 };
209
DepthTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const VkFormat depthFormat,const VkCompareOp depthCompareOps[QUAD_COUNT],const bool separateDepthStencilLayouts,const bool depthBoundsTestEnable,const float depthBoundsMin,const float depthBoundsMax,const bool depthTestEnable,const bool stencilTestEnable,const bool colorAttachmentEnable)210 DepthTest::DepthTest (tcu::TestContext& testContext,
211 const std::string& name,
212 const std::string& description,
213 const VkFormat depthFormat,
214 const VkCompareOp depthCompareOps[QUAD_COUNT],
215 const bool separateDepthStencilLayouts,
216 const bool depthBoundsTestEnable,
217 const float depthBoundsMin,
218 const float depthBoundsMax,
219 const bool depthTestEnable,
220 const bool stencilTestEnable,
221 const bool colorAttachmentEnable)
222 : vkt::TestCase (testContext, name, description)
223 , m_depthFormat (depthFormat)
224 , m_separateDepthStencilLayouts (separateDepthStencilLayouts)
225 , m_depthBoundsTestEnable (depthBoundsTestEnable)
226 , m_depthBoundsMin (depthBoundsMin)
227 , m_depthBoundsMax (depthBoundsMax)
228 , m_depthTestEnable (depthTestEnable)
229 , m_stencilTestEnable (stencilTestEnable)
230 , m_colorAttachmentEnable (colorAttachmentEnable)
231 {
232 deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * QUAD_COUNT);
233 }
234
~DepthTest(void)235 DepthTest::~DepthTest (void)
236 {
237 }
238
checkSupport(Context & context) const239 void DepthTest::checkSupport (Context& context) const
240 {
241 if (m_depthBoundsTestEnable)
242 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BOUNDS);
243
244 if (!isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_depthFormat))
245 throw tcu::NotSupportedError(std::string("Unsupported depth/stencil format: ") + getFormatName(m_depthFormat));
246
247 if (m_separateDepthStencilLayouts && !context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
248 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
249 }
250
createInstance(Context & context) const251 TestInstance* DepthTest::createInstance (Context& context) const
252 {
253 return new DepthTestInstance(context, m_depthFormat, m_depthCompareOps, m_separateDepthStencilLayouts, m_depthBoundsTestEnable, m_depthBoundsMin, m_depthBoundsMax, m_depthTestEnable, m_stencilTestEnable, m_colorAttachmentEnable);
254 }
255
initPrograms(SourceCollections & programCollection) const256 void DepthTest::initPrograms (SourceCollections& programCollection) const
257 {
258 if (m_colorAttachmentEnable)
259 {
260 programCollection.glslSources.add("color_vert") << glu::VertexSource(
261 "#version 310 es\n"
262 "layout(location = 0) in vec4 position;\n"
263 "layout(location = 1) in vec4 color;\n"
264 "layout(location = 0) out highp vec4 vtxColor;\n"
265 "void main (void)\n"
266 "{\n"
267 " gl_Position = position;\n"
268 " vtxColor = color;\n"
269 "}\n");
270
271 programCollection.glslSources.add("color_frag") << glu::FragmentSource(
272 "#version 310 es\n"
273 "layout(location = 0) in highp vec4 vtxColor;\n"
274 "layout(location = 0) out highp vec4 fragColor;\n"
275 "void main (void)\n"
276 "{\n"
277 " fragColor = vtxColor;\n"
278 "}\n");
279 }
280 else
281 {
282 programCollection.glslSources.add("color_vert") << glu::VertexSource(
283 "#version 310 es\n"
284 "layout(location = 0) in vec4 position;\n"
285 "layout(location = 1) in vec4 color;\n"
286 "void main (void)\n"
287 "{\n"
288 " gl_Position = position;\n"
289 "}\n");
290 }
291
292 }
293
DepthTestInstance(Context & context,const VkFormat depthFormat,const VkCompareOp depthCompareOps[DepthTest::QUAD_COUNT],const bool separateDepthStencilLayouts,const bool depthBoundsTestEnable,const float depthBoundsMin,const float depthBoundsMax,const bool depthTestEnable,const bool stencilTestEnable,const bool colorAttachmentEnable)294 DepthTestInstance::DepthTestInstance (Context& context,
295 const VkFormat depthFormat,
296 const VkCompareOp depthCompareOps[DepthTest::QUAD_COUNT],
297 const bool separateDepthStencilLayouts,
298 const bool depthBoundsTestEnable,
299 const float depthBoundsMin,
300 const float depthBoundsMax,
301 const bool depthTestEnable,
302 const bool stencilTestEnable,
303 const bool colorAttachmentEnable)
304 : vkt::TestInstance (context)
305 , m_renderSize (32, 32)
306 , m_colorFormat (colorAttachmentEnable ? VK_FORMAT_R8G8B8A8_UNORM : VK_FORMAT_UNDEFINED)
307 , m_depthFormat (depthFormat)
308 , m_separateDepthStencilLayouts (separateDepthStencilLayouts)
309 , m_depthBoundsTestEnable (depthBoundsTestEnable)
310 , m_depthBoundsMin (depthBoundsMin)
311 , m_depthBoundsMax (depthBoundsMax)
312 , m_depthTestEnable (depthTestEnable)
313 , m_stencilTestEnable (stencilTestEnable)
314 , m_colorAttachmentEnable (colorAttachmentEnable)
315 {
316 const DeviceInterface& vk = context.getDeviceInterface();
317 const VkDevice vkDevice = context.getDevice();
318 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
319 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
320 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
321
322 // Copy depth operators
323 deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * DepthTest::QUAD_COUNT);
324
325 // Create color image
326 if (m_colorAttachmentEnable)
327 {
328 const VkImageCreateInfo colorImageParams =
329 {
330 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
331 DE_NULL, // const void* pNext;
332 0u, // VkImageCreateFlags flags;
333 VK_IMAGE_TYPE_2D, // VkImageType imageType;
334 m_colorFormat, // VkFormat format;
335 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
336 1u, // deUint32 mipLevels;
337 1u, // deUint32 arrayLayers;
338 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
339 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
340 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
341 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
342 1u, // deUint32 queueFamilyIndexCount;
343 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
344 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
345 };
346
347 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
348
349 // Allocate and bind color image memory
350 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
351 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
352 }
353
354 // Create depth image
355 {
356 const VkImageCreateInfo depthImageParams =
357 {
358 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
359 DE_NULL, // const void* pNext;
360 0u, // VkImageCreateFlags flags;
361 VK_IMAGE_TYPE_2D, // VkImageType imageType;
362 m_depthFormat, // VkFormat format;
363 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
364 1u, // deUint32 mipLevels;
365 1u, // deUint32 arrayLayers;
366 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
367 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
368 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
369 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
370 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
371 1u, // deUint32 queueFamilyIndexCount;
372 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
373 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
374 };
375
376 m_depthImage = createImage(vk, vkDevice, &depthImageParams);
377
378 // Allocate and bind depth image memory
379 m_depthImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthImage), MemoryRequirement::Any);
380 VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthImage, m_depthImageAlloc->getMemory(), m_depthImageAlloc->getOffset()));
381
382 const VkImageAspectFlags aspect = (mapVkFormat(m_depthFormat).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT
383 : VK_IMAGE_ASPECT_DEPTH_BIT);
384 m_depthImageSubresourceRange = makeImageSubresourceRange(aspect, 0u, depthImageParams.mipLevels, 0u, depthImageParams.arrayLayers);
385 }
386
387 // Create color attachment view
388 if (m_colorAttachmentEnable)
389 {
390 const VkImageViewCreateInfo colorAttachmentViewParams =
391 {
392 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
393 DE_NULL, // const void* pNext;
394 0u, // VkImageViewCreateFlags flags;
395 *m_colorImage, // VkImage image;
396 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
397 m_colorFormat, // VkFormat format;
398 componentMappingRGBA, // VkComponentMapping components;
399 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
400 };
401
402 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
403 }
404
405 // Create depth attachment view
406 {
407 const VkImageViewCreateInfo depthAttachmentViewParams =
408 {
409 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
410 DE_NULL, // const void* pNext;
411 0u, // VkImageViewCreateFlags flags;
412 *m_depthImage, // VkImage image;
413 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
414 m_depthFormat, // VkFormat format;
415 componentMappingRGBA, // VkComponentMapping components;
416 m_depthImageSubresourceRange, // VkImageSubresourceRange subresourceRange;
417 };
418
419 m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
420 }
421
422 // Create render pass
423 m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat, m_depthFormat);
424
425 // Create framebuffer
426 {
427 std::vector<VkImageView> attachmentBindInfos;
428
429 if (m_colorAttachmentEnable)
430 attachmentBindInfos.push_back(*m_colorAttachmentView);
431
432 attachmentBindInfos.push_back(*m_depthAttachmentView);
433
434 const VkFramebufferCreateInfo framebufferParams =
435 {
436 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
437 DE_NULL, // const void* pNext;
438 0u, // VkFramebufferCreateFlags flags;
439 *m_renderPass, // VkRenderPass renderPass;
440 (deUint32)attachmentBindInfos.size(), // deUint32 attachmentCount;
441 attachmentBindInfos.data(), // const VkImageView* pAttachments;
442 (deUint32)m_renderSize.x(), // deUint32 width;
443 (deUint32)m_renderSize.y(), // deUint32 height;
444 1u // deUint32 layers;
445 };
446
447 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
448 }
449
450 // Create pipeline layout
451 {
452 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
453 {
454 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
455 DE_NULL, // const void* pNext;
456 0u, // VkPipelineLayoutCreateFlags flags;
457 0u, // deUint32 setLayoutCount;
458 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
459 0u, // deUint32 pushConstantRangeCount;
460 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
461 };
462
463 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
464 }
465
466 // Shader modules
467 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
468 if (m_colorAttachmentEnable)
469 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
470
471 // Create pipeline
472 {
473 const std::vector<VkViewport> viewports (1, makeViewport(m_renderSize));
474 const std::vector<VkRect2D> scissors (1, makeRect2D(m_renderSize));
475
476 const VkVertexInputBindingDescription vertexInputBindingDescription =
477 {
478 0u, // deUint32 binding;
479 sizeof(Vertex4RGBA), // deUint32 strideInBytes;
480 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate;
481 };
482
483 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
484 {
485 {
486 0u, // deUint32 location;
487 0u, // deUint32 binding;
488 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
489 0u // deUint32 offset;
490 },
491 {
492 1u, // deUint32 location;
493 0u, // deUint32 binding;
494 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
495 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offset;
496 }
497 };
498
499 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
500 {
501 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
502 DE_NULL, // const void* pNext;
503 0u, // VkPipelineVertexInputStateCreateFlags flags;
504 1u, // deUint32 vertexBindingDescriptionCount;
505 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
506 2u, // deUint32 vertexAttributeDescriptionCount;
507 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
508 };
509
510 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
511 {
512 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
513 DE_NULL, // const void* pNext;
514 0u, // VkPipelineDepthStencilStateCreateFlags flags;
515 m_depthTestEnable, // VkBool32 depthTestEnable;
516 true, // VkBool32 depthWriteEnable;
517 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
518 m_depthBoundsTestEnable, // VkBool32 depthBoundsTestEnable;
519 m_stencilTestEnable, // VkBool32 stencilTestEnable;
520 // VkStencilOpState front;
521 {
522 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
523 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
524 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
525 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
526 0u, // deUint32 compareMask;
527 0u, // deUint32 writeMask;
528 0u, // deUint32 reference;
529 },
530 // VkStencilOpState back;
531 {
532 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
533 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
534 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
535 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
536 0u, // deUint32 compareMask;
537 0u, // deUint32 writeMask;
538 0u, // deUint32 reference;
539 },
540 m_depthBoundsMin, // float minDepthBounds;
541 m_depthBoundsMax, // float maxDepthBounds;
542 };
543
544 // Make sure rasterization is not disabled when the fragment shader is missing.
545 const vk::VkPipelineRasterizationStateCreateInfo rasterizationStateParams =
546 {
547 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
548 nullptr, // const void* pNext;
549 0u, // VkPipelineRasterizationStateCreateFlags flags;
550 VK_FALSE, // VkBool32 depthClampEnable;
551 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
552 vk::VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
553 vk::VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
554 vk::VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
555 VK_FALSE, // VkBool32 depthBiasEnable;
556 0.0f, // float depthBiasConstantFactor;
557 0.0f, // float depthBiasClamp;
558 0.0f, // float depthBiasSlopeFactor;
559 1.0f, // float lineWidth;
560 };
561
562 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
563 {
564 depthStencilStateParams.depthCompareOp = depthCompareOps[quadNdx];
565 m_graphicsPipelines[quadNdx] = makeGraphicsPipeline(vk, // const DeviceInterface& vk
566 vkDevice, // const VkDevice device
567 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
568 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
569 DE_NULL, // const VkShaderModule tessellationControlModule
570 DE_NULL, // const VkShaderModule tessellationEvalModule
571 DE_NULL, // const VkShaderModule geometryShaderModule
572 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
573 *m_renderPass, // const VkRenderPass renderPass
574 viewports, // const std::vector<VkViewport>& viewports
575 scissors, // const std::vector<VkRect2D>& scissors
576 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
577 0u, // const deUint32 subpass
578 0u, // const deUint32 patchControlPoints
579 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
580 &rasterizationStateParams, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
581 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
582 &depthStencilStateParams); // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
583 }
584 }
585
586 // Create vertex buffer
587 {
588 const VkBufferCreateInfo vertexBufferParams =
589 {
590 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
591 DE_NULL, // const void* pNext;
592 0u, // VkBufferCreateFlags flags;
593 1024u, // VkDeviceSize size;
594 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
595 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
596 1u, // deUint32 queueFamilyIndexCount;
597 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
598 };
599
600 m_vertices = createOverlappingQuads();
601 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
602 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
603
604 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
605
606 // Adjust depths
607 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
608 for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++)
609 m_vertices[quadNdx * 6 + vertexNdx].position.z() = DepthTest::quadDepths[quadNdx];
610
611 // Load vertices into vertex buffer
612 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
613 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
614 }
615
616 // Create command pool
617 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
618
619 // Create command buffer
620 {
621 std::vector<VkClearValue> attachmentClearValues;
622
623 if (m_colorAttachmentEnable)
624 attachmentClearValues.push_back(defaultClearValue(m_colorFormat));
625
626 attachmentClearValues.push_back(defaultClearValue(m_depthFormat));
627
628 const VkImageMemoryBarrier colorBarrier =
629 {
630 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
631 DE_NULL, // const void* pNext;
632 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
633 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
634 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
635 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
636 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
637 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
638 *m_colorImage, // VkImage image;
639 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
640 };
641
642 VkImageSubresourceRange depthBarrierSubresourceRange = m_depthImageSubresourceRange;
643 VkImageLayout newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
644 if (m_separateDepthStencilLayouts)
645 {
646 depthBarrierSubresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
647 newLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR;
648 }
649
650 const VkImageMemoryBarrier depthBarrier =
651 {
652 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
653 DE_NULL, // const void* pNext;
654 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
655 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
656 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
657 newLayout , // VkImageLayout newLayout;
658 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
659 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
660 *m_depthImage, // VkImage image;
661 depthBarrierSubresourceRange, // VkImageSubresourceRange subresourceRange;
662 };
663
664 std::vector<VkImageMemoryBarrier> imageLayoutBarriers;
665
666 if (m_colorAttachmentEnable)
667 imageLayoutBarriers.push_back(colorBarrier);
668
669 imageLayoutBarriers.push_back(depthBarrier);
670
671 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
672
673 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
674
675 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
676 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
677 0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), imageLayoutBarriers.data());
678
679 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)attachmentClearValues.size(), attachmentClearValues.data());
680
681 const VkDeviceSize quadOffset = (m_vertices.size() / DepthTest::QUAD_COUNT) * sizeof(Vertex4RGBA);
682
683 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
684 {
685 VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;
686
687 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]);
688 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
689 vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / DepthTest::QUAD_COUNT), 1, 0, 0);
690 }
691
692 endRenderPass(vk, *m_cmdBuffer);
693 endCommandBuffer(vk, *m_cmdBuffer);
694 }
695 }
696
~DepthTestInstance(void)697 DepthTestInstance::~DepthTestInstance (void)
698 {
699 }
700
iterate(void)701 tcu::TestStatus DepthTestInstance::iterate (void)
702 {
703 const DeviceInterface& vk = m_context.getDeviceInterface();
704 const VkDevice vkDevice = m_context.getDevice();
705 const VkQueue queue = m_context.getUniversalQueue();
706
707 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
708
709 return verifyImage();
710 }
711
verifyImage(void)712 tcu::TestStatus DepthTestInstance::verifyImage (void)
713 {
714 const tcu::TextureFormat tcuColorFormat = mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM);
715 const tcu::TextureFormat tcuDepthFormat = mapVkFormat(m_depthFormat);
716 const ColorVertexShader vertexShader;
717 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuDepthFormat);
718 const rr::Program program (&vertexShader, &fragmentShader);
719 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
720 bool colorCompareOk = false;
721 bool depthCompareOk = false;
722
723 // Render reference image
724 {
725 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
726 {
727 // Set depth state
728 rr::RenderState renderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);
729 renderState.fragOps.depthTestEnabled = m_depthTestEnable;
730 renderState.fragOps.depthFunc = mapVkCompareOp(m_depthCompareOps[quadNdx]);
731 if (m_depthBoundsTestEnable)
732 {
733 renderState.fragOps.depthBoundsTestEnabled = true;
734 renderState.fragOps.minDepthBound = m_depthBoundsMin;
735 renderState.fragOps.maxDepthBound = m_depthBoundsMax;
736 }
737
738 refRenderer.draw(renderState,
739 rr::PRIMITIVETYPE_TRIANGLES,
740 std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
741 m_vertices.begin() + (quadNdx + 1) * 6));
742 }
743 }
744
745 // Compare color result with reference image
746 if (m_colorAttachmentEnable)
747 {
748 const DeviceInterface& vk = m_context.getDeviceInterface();
749 const VkDevice vkDevice = m_context.getDevice();
750 const VkQueue queue = m_context.getUniversalQueue();
751 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
752 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
753 de::MovePtr<tcu::TextureLevel> result = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
754
755 colorCompareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
756 "IntImageCompare",
757 "Image comparison",
758 refRenderer.getAccess(),
759 result->getAccess(),
760 tcu::UVec4(2, 2, 2, 2),
761 tcu::IVec3(1, 1, 0),
762 true,
763 tcu::COMPARE_LOG_RESULT);
764 }
765 else
766 {
767 colorCompareOk = true;
768 }
769
770 // Compare depth result with reference image
771 {
772 const DeviceInterface& vk = m_context.getDeviceInterface();
773 const VkDevice vkDevice = m_context.getDevice();
774 const VkQueue queue = m_context.getUniversalQueue();
775 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
776 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
777 de::MovePtr<tcu::TextureLevel> result = readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, m_depthFormat, m_renderSize);
778
779 {
780 de::MovePtr<tcu::TextureLevel> convertedReferenceLevel;
781 tcu::Maybe<tcu::TextureFormat> convertedFormat;
782
783 if (refRenderer.getDepthStencilAccess().getFormat().type == tcu::TextureFormat::UNSIGNED_INT_24_8_REV)
784 {
785 convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT24);
786 }
787 else if (refRenderer.getDepthStencilAccess().getFormat().type == tcu::TextureFormat::UNSIGNED_INT_16_8_8)
788 {
789 convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
790 }
791 else if (refRenderer.getDepthStencilAccess().getFormat().type == tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV)
792 {
793 convertedFormat = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
794 }
795
796 if (convertedFormat)
797 {
798 convertedReferenceLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(*convertedFormat, refRenderer.getDepthStencilAccess().getSize().x(), refRenderer.getDepthStencilAccess().getSize().y()));
799 tcu::copy(convertedReferenceLevel->getAccess(), refRenderer.getDepthStencilAccess());
800 }
801
802 float depthThreshold = 0.0f;
803
804 if (tcu::getTextureChannelClass(result->getFormat().type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
805 {
806 const tcu::IVec4 formatBits = tcu::getTextureFormatBitDepth(result->getFormat());
807 depthThreshold = 1.0f / static_cast<float>((1 << formatBits[0]) - 1);
808 }
809 else if (tcu::getTextureChannelClass(result->getFormat().type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
810 {
811
812 depthThreshold = 0.0000001f;
813 }
814 else
815 TCU_FAIL("unrecognized format type class");
816
817 depthCompareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
818 "DepthImageCompare",
819 "Depth image comparison",
820 convertedReferenceLevel ? convertedReferenceLevel->getAccess() : refRenderer.getDepthStencilAccess(),
821 result->getAccess(),
822 tcu::Vec4(depthThreshold, 0.0f, 0.0f, 0.0f),
823 tcu::COMPARE_LOG_RESULT);
824 }
825 }
826
827 if (colorCompareOk && depthCompareOk)
828 return tcu::TestStatus::pass("Result image matches reference");
829 else
830 return tcu::TestStatus::fail("Image mismatch");
831 }
832
getFormatCaseName(const VkFormat format)833 std::string getFormatCaseName (const VkFormat format)
834 {
835 const std::string fullName = getFormatName(format);
836
837 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
838
839 return de::toLower(fullName.substr(10));
840 }
841
getCompareOpsName(const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])842 std::string getCompareOpsName (const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])
843 {
844 std::ostringstream name;
845
846 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
847 {
848 const std::string fullOpName = getCompareOpName(quadDepthOps[quadNdx]);
849
850 DE_ASSERT(de::beginsWith(fullOpName, "VK_COMPARE_OP_"));
851
852 name << de::toLower(fullOpName.substr(14));
853
854 if (quadNdx < DepthTest::QUAD_COUNT - 1)
855 name << "_";
856 }
857
858 return name.str();
859 }
860
getCompareOpsDescription(const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])861 std::string getCompareOpsDescription (const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])
862 {
863 std::ostringstream desc;
864 desc << "Draws " << DepthTest::QUAD_COUNT << " quads with depth compare ops: ";
865
866 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
867 {
868 desc << getCompareOpName(quadDepthOps[quadNdx]) << " at depth " << DepthTest::quadDepths[quadNdx];
869
870 if (quadNdx < DepthTest::QUAD_COUNT - 1)
871 desc << ", ";
872 }
873 return desc.str();
874 }
875
876
877 } // anonymous
878
createDepthTests(tcu::TestContext & testCtx)879 tcu::TestCaseGroup* createDepthTests (tcu::TestContext& testCtx)
880 {
881 const VkFormat depthFormats[] =
882 {
883 VK_FORMAT_D16_UNORM,
884 VK_FORMAT_X8_D24_UNORM_PACK32,
885 VK_FORMAT_D32_SFLOAT,
886 VK_FORMAT_D16_UNORM_S8_UINT,
887 VK_FORMAT_D24_UNORM_S8_UINT,
888 VK_FORMAT_D32_SFLOAT_S8_UINT
889 };
890
891 // Each entry configures the depth compare operators of QUAD_COUNT quads.
892 // All entries cover pair-wise combinations of compare operators.
893 const VkCompareOp depthOps[][DepthTest::QUAD_COUNT] =
894 {
895 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL },
896 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER },
897 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS_OR_EQUAL },
898 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL },
899 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_ALWAYS },
900 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS },
901 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER },
902 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_EQUAL },
903 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS },
904 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL },
905 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER },
906 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS_OR_EQUAL },
907 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_EQUAL },
908 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_ALWAYS },
909 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL },
910 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS },
911 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_ALWAYS },
912 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER },
913 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL },
914 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER_OR_EQUAL },
915 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NEVER },
916 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER },
917 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS_OR_EQUAL },
918 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NOT_EQUAL },
919 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL },
920 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL },
921 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS },
922 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_EQUAL },
923 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_NEVER },
924 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL },
925 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_EQUAL },
926 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS },
927 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_ALWAYS },
928 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL },
929 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER },
930 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER_OR_EQUAL },
931 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS_OR_EQUAL },
932 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NEVER },
933 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_EQUAL },
934 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NOT_EQUAL },
935 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_ALWAYS },
936 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_ALWAYS },
937 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS },
938 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_EQUAL },
939 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER },
940 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_NOT_EQUAL },
941 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL },
942 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER_OR_EQUAL },
943 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NEVER },
944 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS },
945 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_ALWAYS },
946 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER },
947 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_EQUAL },
948 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NOT_EQUAL },
949 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS },
950 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NEVER },
951 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_NOT_EQUAL },
952 { VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_EQUAL },
953 { VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL },
954 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER },
955 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NEVER },
956 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER },
957 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NOT_EQUAL },
958 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_ALWAYS },
959 { VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER },
960 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER },
961 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL },
962 { VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL },
963 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS },
964 { VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_NEVER },
965 { VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_EQUAL, VK_COMPARE_OP_EQUAL },
966 { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS, VK_COMPARE_OP_GREATER_OR_EQUAL },
967 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS },
968 { VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_GREATER }
969 };
970
971 const bool colorAttachmentEnabled[] = { true, false };
972
973 de::MovePtr<tcu::TestCaseGroup> depthTests (new tcu::TestCaseGroup(testCtx, "depth", "Depth tests"));
974 de::MovePtr<tcu::TestCaseGroup> noColorAttachmentTests (new tcu::TestCaseGroup(testCtx, "nocolor", "Depth tests with no color attachment"));
975
976 // Tests for format features
977 {
978 de::MovePtr<tcu::TestCaseGroup> formatFeaturesTests (new tcu::TestCaseGroup(testCtx, "format_features", "Checks depth format features"));
979
980 // Formats that must be supported in all implementations
981 addFunctionCase(formatFeaturesTests.get(),
982 "support_d16_unorm",
983 "Tests if VK_FORMAT_D16_UNORM is supported as depth/stencil attachment format",
984 testSupportsDepthStencilFormat,
985 VK_FORMAT_D16_UNORM);
986
987 // Sets where at least one of the formats must be supported
988 const VkFormat depthOnlyFormats[] = { VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT };
989 const VkFormat depthStencilFormats[] = { VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT };
990
991 addFunctionCase(formatFeaturesTests.get(),
992 "support_d24_unorm_or_d32_sfloat",
993 "Tests if any of VK_FORMAT_D24_UNORM_X8 or VK_FORMAT_D32_SFLOAT are supported as depth/stencil attachment format",
994 testSupportsAtLeastOneDepthStencilFormat,
995 std::vector<VkFormat>(depthOnlyFormats, depthOnlyFormats + DE_LENGTH_OF_ARRAY(depthOnlyFormats)));
996
997 addFunctionCase(formatFeaturesTests.get(),
998 "support_d24_unorm_s8_uint_or_d32_sfloat_s8_uint",
999 "Tests if any of VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT are supported as depth/stencil attachment format",
1000 testSupportsAtLeastOneDepthStencilFormat,
1001 std::vector<VkFormat>(depthStencilFormats, depthStencilFormats + DE_LENGTH_OF_ARRAY(depthStencilFormats)));
1002
1003 depthTests->addChild(formatFeaturesTests.release());
1004 }
1005
1006 for (deUint32 colorAttachmentEnabledIdx = 0; colorAttachmentEnabledIdx < DE_LENGTH_OF_ARRAY(colorAttachmentEnabled); colorAttachmentEnabledIdx++)
1007 {
1008 const bool colorEnabled = colorAttachmentEnabled[colorAttachmentEnabledIdx];
1009
1010 // Tests for format and compare operators
1011 {
1012 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Uses different depth formats"));
1013
1014 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthFormats); formatNdx++)
1015 {
1016 const bool hasDepth = tcu::hasDepthComponent(mapVkFormat(depthFormats[formatNdx]).order);
1017 const bool hasStencil = tcu::hasStencilComponent(mapVkFormat(depthFormats[formatNdx]).order);
1018 const int separateLayoutsLoopCount = (hasDepth && hasStencil) ? 2 : 1;
1019
1020 for (int separateDepthStencilLayouts = 0; separateDepthStencilLayouts < separateLayoutsLoopCount; ++separateDepthStencilLayouts)
1021 {
1022 const bool useSeparateDepthStencilLayouts = bool(separateDepthStencilLayouts);
1023
1024 de::MovePtr<tcu::TestCaseGroup> formatTest (new tcu::TestCaseGroup(testCtx,
1025 (getFormatCaseName(depthFormats[formatNdx]) + ((useSeparateDepthStencilLayouts) ? "_separate_layouts" : "")).c_str(),
1026 (std::string("Uses format ") + getFormatName(depthFormats[formatNdx]) + ((useSeparateDepthStencilLayouts) ? " with separate depth/stencil layouts" : "")).c_str()));
1027 de::MovePtr<tcu::TestCaseGroup> compareOpsTests (new tcu::TestCaseGroup(testCtx, "compare_ops", "Combines depth compare operators"));
1028
1029 for (size_t opsNdx = 0; opsNdx < DE_LENGTH_OF_ARRAY(depthOps); opsNdx++)
1030 {
1031 compareOpsTests->addChild(new DepthTest(testCtx,
1032 getCompareOpsName(depthOps[opsNdx]),
1033 getCompareOpsDescription(depthOps[opsNdx]),
1034 depthFormats[formatNdx],
1035 depthOps[opsNdx],
1036 useSeparateDepthStencilLayouts));
1037
1038 compareOpsTests->addChild(new DepthTest(testCtx,
1039 getCompareOpsName(depthOps[opsNdx]) + "_depth_bounds_test",
1040 getCompareOpsDescription(depthOps[opsNdx]) + " with depth bounds test enabled",
1041 depthFormats[formatNdx],
1042 depthOps[opsNdx],
1043 useSeparateDepthStencilLayouts,
1044 true,
1045 0.1f,
1046 0.25f,
1047 true,
1048 false,
1049 colorEnabled));
1050 }
1051 // Special VkPipelineDepthStencilStateCreateInfo known to have issues
1052 {
1053 const VkCompareOp depthOpsSpecial[DepthTest::QUAD_COUNT] = { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER };
1054
1055 compareOpsTests->addChild(new DepthTest(testCtx,
1056 "never_zerodepthbounds_depthdisabled_stencilenabled",
1057 "special VkPipelineDepthStencilStateCreateInfo",
1058 depthFormats[formatNdx],
1059 depthOpsSpecial,
1060 useSeparateDepthStencilLayouts,
1061 true,
1062 0.0f,
1063 0.0f,
1064 false,
1065 true,
1066 colorEnabled));
1067 }
1068 formatTest->addChild(compareOpsTests.release());
1069
1070 // Test case with depth test enabled, but depth write disabled
1071 de::MovePtr<tcu::TestCaseGroup> depthTestDisabled(new tcu::TestCaseGroup(testCtx, "depth_test_disabled", "Test for disabled depth test"));
1072 {
1073 const VkCompareOp depthOpsDepthTestDisabled[DepthTest::QUAD_COUNT] = { VK_COMPARE_OP_NEVER, VK_COMPARE_OP_LESS, VK_COMPARE_OP_GREATER, VK_COMPARE_OP_ALWAYS };
1074 depthTestDisabled->addChild(new DepthTest(testCtx,
1075 "depth_write_enabled",
1076 "Depth writes should not occur if depth test is disabled",
1077 depthFormats[formatNdx],
1078 depthOpsDepthTestDisabled,
1079 useSeparateDepthStencilLayouts,
1080 false, /* depthBoundsTestEnable */
1081 0.0f, /* depthBoundMin*/
1082 1.0f, /* depthBoundMax*/
1083 false, /* depthTestEnable */
1084 false, /* stencilTestEnable */
1085 colorEnabled /* colorAttachmentEnable */));
1086 }
1087 formatTest->addChild(depthTestDisabled.release());
1088 formatTests->addChild(formatTest.release());
1089 }
1090 }
1091 if (colorEnabled)
1092 depthTests->addChild(formatTests.release());
1093 else
1094 noColorAttachmentTests->addChild(formatTests.release());
1095 }
1096 }
1097 depthTests->addChild(noColorAttachmentTests.release());
1098
1099 return depthTests.release();
1100 }
1101
1102 } // pipeline
1103 } // vkt
1104