Test with depth range greater than 1.0 should require extension
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / draw / vktDrawInvertedDepthRangesTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2017 Google Inc.
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 Inverted depth ranges tests.
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktDrawInvertedDepthRangesTests.hpp"
26 #include "vktDrawCreateInfoUtil.hpp"
27 #include "vktDrawImageObjectUtil.hpp"
28 #include "vktDrawBufferObjectUtil.hpp"
29 #include "vktTestGroupUtil.hpp"
30 #include "vktTestCaseUtil.hpp"
31
32 #include "vkPrograms.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkImageUtil.hpp"
35
36 #include "tcuVector.hpp"
37 #include "tcuTextureUtil.hpp"
38 #include "tcuImageCompare.hpp"
39 #include "tcuTestLog.hpp"
40
41 #include "deSharedPtr.hpp"
42
43 namespace vkt
44 {
45 namespace Draw
46 {
47 namespace
48 {
49 using namespace vk;
50 using tcu::Vec4;
51 using de::SharedPtr;
52 using de::MovePtr;
53
54 struct TestParams
55 {
56         VkBool32        depthClampEnable;
57         float           minDepth;
58         float           maxDepth;
59 };
60
61 class InvertedDepthRangesTestInstance : public TestInstance
62 {
63 public:
64                                                                         InvertedDepthRangesTestInstance (Context& context, const TestParams& params);
65         tcu::TestStatus                                 iterate                                                 (void);
66         tcu::ConstPixelBufferAccess             draw                                                    (const VkViewport viewport);
67         MovePtr<tcu::TextureLevel>              generateReferenceImage                  (void) const;
68
69 private:
70         const TestParams                                m_params;
71         const VkFormat                                  m_colorAttachmentFormat;
72         SharedPtr<Image>                                m_colorTargetImage;
73         Move<VkImageView>                               m_colorTargetView;
74         SharedPtr<Buffer>                               m_vertexBuffer;
75         Move<VkRenderPass>                              m_renderPass;
76         Move<VkFramebuffer>                             m_framebuffer;
77         Move<VkPipelineLayout>                  m_pipelineLayout;
78         Move<VkPipeline>                                m_pipeline;
79 };
80
81 InvertedDepthRangesTestInstance::InvertedDepthRangesTestInstance (Context& context, const TestParams& params)
82         : TestInstance                          (context)
83         , m_params                                      (params)
84         , m_colorAttachmentFormat       (VK_FORMAT_R8G8B8A8_UNORM)
85 {
86         const DeviceInterface&  vk              = m_context.getDeviceInterface();
87         const VkDevice                  device  = m_context.getDevice();
88
89         if (m_params.depthClampEnable && !m_context.getDeviceFeatures().depthClamp)
90                 TCU_THROW(NotSupportedError, "DepthClamp device feature not supported.");
91
92         if (params.minDepth > 1.0f      ||
93                 params.minDepth < 0.0f  ||
94                 params.maxDepth > 1.0f  ||
95                 params.maxDepth < 0.0f)
96         {
97                 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_EXT_depth_range_unrestricted"))
98                         throw tcu::NotSupportedError("Test variant with minDepth/maxDepth outside 0..1 requires the VK_EXT_depth_range_unrestricted extension");
99         }
100
101         // Vertex data
102         {
103                 std::vector<Vec4> vertexData;
104
105                 vertexData.push_back(Vec4(-0.8f, -0.8f, -0.2f, 1.0f));  //  0-----2
106                 vertexData.push_back(Vec4(-0.8f,  0.8f,  0.0f, 1.0f));  //   |  /
107                 vertexData.push_back(Vec4( 0.8f, -0.8f,  1.2f, 1.0f));  //  1|/
108
109                 const VkDeviceSize dataSize = vertexData.size() * sizeof(Vec4);
110                 m_vertexBuffer = Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
111                                                                                                 m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
112
113                 deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), &vertexData[0], static_cast<std::size_t>(dataSize));
114                 flushMappedMemoryRange(vk, device, m_vertexBuffer->getBoundMemory().getMemory(), m_vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
115         }
116
117         // Render pass
118         {
119                 const VkExtent3D                targetImageExtent               = { 256, 256, 1 };
120                 const VkImageUsageFlags targetImageUsageFlags   = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
121
122                 const ImageCreateInfo   targetImageCreateInfo(
123                         VK_IMAGE_TYPE_2D,                                               // imageType,
124                         m_colorAttachmentFormat,                                // format,
125                         targetImageExtent,                                              // extent,
126                         1u,                                                                             // mipLevels,
127                         1u,                                                                             // arrayLayers,
128                         VK_SAMPLE_COUNT_1_BIT,                                  // samples,
129                         VK_IMAGE_TILING_OPTIMAL,                                // tiling,
130                         targetImageUsageFlags);                                 // usage,
131
132                 m_colorTargetImage = Image::createAndAlloc(vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
133
134                 RenderPassCreateInfo    renderPassCreateInfo;
135                 renderPassCreateInfo.addAttachment(AttachmentDescription(
136                         m_colorAttachmentFormat,                                // format
137                         VK_SAMPLE_COUNT_1_BIT,                                  // samples
138                         VK_ATTACHMENT_LOAD_OP_LOAD,                             // loadOp
139                         VK_ATTACHMENT_STORE_OP_STORE,                   // storeOp
140                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                // stencilLoadOp
141                         VK_ATTACHMENT_STORE_OP_DONT_CARE,               // stencilStoreOp
142                         VK_IMAGE_LAYOUT_GENERAL,                                // initialLayout
143                         VK_IMAGE_LAYOUT_GENERAL));                              // finalLayout
144
145                 const VkAttachmentReference colorAttachmentReference =
146                 {
147                         0u,
148                         VK_IMAGE_LAYOUT_GENERAL
149                 };
150
151                 renderPassCreateInfo.addSubpass(SubpassDescription(
152                         VK_PIPELINE_BIND_POINT_GRAPHICS,                // pipelineBindPoint
153                         (VkSubpassDescriptionFlags)0,                   // flags
154                         0u,                                                                             // inputAttachmentCount
155                         DE_NULL,                                                                // inputAttachments
156                         1u,                                                                             // colorAttachmentCount
157                         &colorAttachmentReference,                              // colorAttachments
158                         DE_NULL,                                                                // resolveAttachments
159                         AttachmentReference(),                                  // depthStencilAttachment
160                         0u,                                                                             // preserveAttachmentCount
161                         DE_NULL));                                                              // preserveAttachments
162
163                 m_renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
164         }
165
166         // Framebuffer
167         {
168                 const ImageViewCreateInfo colorTargetViewInfo (m_colorTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
169                 m_colorTargetView = createImageView(vk, device, &colorTargetViewInfo);
170
171                 std::vector<VkImageView> colorAttachments(1);
172                 colorAttachments[0] = *m_colorTargetView;
173
174                 const FramebufferCreateInfo     framebufferCreateInfo(*m_renderPass, colorAttachments, 256, 256, 1);
175                 m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
176         }
177
178         // Vertex input
179
180         const VkVertexInputBindingDescription           vertexInputBindingDescription =
181         {
182                 0u,                                                                             // uint32_t             binding;
183                 sizeof(Vec4),                                                   // uint32_t             stride;
184                 VK_VERTEX_INPUT_RATE_VERTEX,                    // VkVertexInputRate    inputRate;
185         };
186
187         const VkVertexInputAttributeDescription         vertexInputAttributeDescription =
188         {
189                 0u,                                                                             // uint32_t    location;
190                 0u,                                                                             // uint32_t    binding;
191                 VK_FORMAT_R32G32B32A32_SFLOAT,                  // VkFormat    format;
192                 0u                                                                              // uint32_t    offset;
193         };
194
195         const PipelineCreateInfo::VertexInputState      vertexInputState = PipelineCreateInfo::VertexInputState(1, &vertexInputBindingDescription,
196                                                                                                                                                                                                                 1, &vertexInputAttributeDescription);
197
198         // Graphics pipeline
199
200         const VkRect2D scissor =
201         {
202                 { 0,    0       },      // x, y
203                 { 256,  256     },      // width, height
204         };
205
206         std::vector<VkDynamicState>             dynamicStates;
207         dynamicStates.push_back(VK_DYNAMIC_STATE_VIEWPORT);
208
209         const Unique<VkShaderModule>    vertexModule    (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
210         const Unique<VkShaderModule>    fragmentModule  (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
211
212         const PipelineLayoutCreateInfo  pipelineLayoutCreateInfo;
213         m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
214
215         const PipelineCreateInfo::ColorBlendState::Attachment colorBlendAttachmentState;
216
217         PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
218         pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vertexModule,   "main", VK_SHADER_STAGE_VERTEX_BIT));
219         pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fragmentModule, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
220         pipelineCreateInfo.addState (PipelineCreateInfo::VertexInputState       (vertexInputState));
221         pipelineCreateInfo.addState (PipelineCreateInfo::InputAssemblerState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
222         pipelineCreateInfo.addState (PipelineCreateInfo::ColorBlendState        (1, &colorBlendAttachmentState));
223         pipelineCreateInfo.addState (PipelineCreateInfo::ViewportState          (1, std::vector<VkViewport>(), std::vector<VkRect2D>(1, scissor)));
224         pipelineCreateInfo.addState (PipelineCreateInfo::DepthStencilState      ());
225         pipelineCreateInfo.addState (PipelineCreateInfo::RasterizerState        (
226                 m_params.depthClampEnable,      // depthClampEnable
227                 VK_FALSE,                                       // rasterizerDiscardEnable
228                 VK_POLYGON_MODE_FILL,           // polygonMode
229                 VK_CULL_MODE_NONE,                      // cullMode
230                 VK_FRONT_FACE_CLOCKWISE,        // frontFace
231                 VK_FALSE,                                       // depthBiasEnable
232                 0.0f,                                           // depthBiasConstantFactor
233                 0.0f,                                           // depthBiasClamp
234                 0.0f,                                           // depthBiasSlopeFactor
235                 1.0f));                                         // lineWidth
236         pipelineCreateInfo.addState (PipelineCreateInfo::MultiSampleState       ());
237         pipelineCreateInfo.addState (PipelineCreateInfo::DynamicState           (dynamicStates));
238
239         m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
240 }
241
242 tcu::ConstPixelBufferAccess InvertedDepthRangesTestInstance::draw (const VkViewport viewport)
243 {
244         const DeviceInterface&  vk                                      = m_context.getDeviceInterface();
245         const VkDevice                  device                          = m_context.getDevice();
246         const VkQueue                   queue                           = m_context.getUniversalQueue();
247         const deUint32                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
248
249         // Command buffer
250
251         const CmdPoolCreateInfo                 cmdPoolCreateInfo       (queueFamilyIndex);
252         const Unique<VkCommandPool>             cmdPool                         (createCommandPool(vk, device, &cmdPoolCreateInfo));
253         const Unique<VkCommandBuffer>   cmdBuffer                       (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
254
255         // Draw
256
257         {
258                 const CmdBufferBeginInfo beginInfo;
259                 vk.beginCommandBuffer(*cmdBuffer, &beginInfo);
260         }
261
262         vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &viewport);
263
264         {
265                 const VkClearColorValue         clearColor                      = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f).color;
266                 const ImageSubresourceRange subresourceRange    (VK_IMAGE_ASPECT_COLOR_BIT);
267
268                 initialTransitionColor2DImage(vk, *cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
269                 vk.cmdClearColorImage(*cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRange);
270         }
271         {
272                 const VkMemoryBarrier memBarrier =
273                 {
274                         VK_STRUCTURE_TYPE_MEMORY_BARRIER,                                                                                               // VkStructureType    sType;
275                         DE_NULL,                                                                                                                                                // const void*        pNext;
276                         VK_ACCESS_TRANSFER_WRITE_BIT,                                                                                                   // VkAccessFlags      srcAccessMask;
277                         VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT              // VkAccessFlags      dstAccessMask;
278                 };
279
280                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
281         }
282         {
283                 const VkRect2D                          renderArea              = { { 0, 0 }, { 256, 256 } };
284                 const RenderPassBeginInfo       renderPassBegin (*m_renderPass, *m_framebuffer, renderArea);
285
286                 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBegin, VK_SUBPASS_CONTENTS_INLINE);
287         }
288         {
289                 const VkDeviceSize      offset  = 0;
290                 const VkBuffer          buffer  = m_vertexBuffer->object();
291
292                 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &buffer, &offset);
293         }
294
295         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
296         vk.cmdDraw(*cmdBuffer, 3, 1, 0, 0);
297         vk.cmdEndRenderPass(*cmdBuffer);
298         vk.endCommandBuffer(*cmdBuffer);
299
300         // Submit
301         {
302                 const Unique<VkFence>   fence           (createFence(vk, device));
303                 const VkSubmitInfo              submitInfo      =
304                 {
305                         VK_STRUCTURE_TYPE_SUBMIT_INFO,                          // VkStructureType                sType;
306                         DE_NULL,                                                                        // const void*                    pNext;
307                         0,                                                                                      // uint32_t                       waitSemaphoreCount;
308                         DE_NULL,                                                                        // const VkSemaphore*             pWaitSemaphores;
309                         (const VkPipelineStageFlags*)DE_NULL,           // const VkPipelineStageFlags*    pWaitDstStageMask;
310                         1,                                                                                      // uint32_t                       commandBufferCount;
311                         &cmdBuffer.get(),                                                       // const VkCommandBuffer*         pCommandBuffers;
312                         0,                                                                                      // uint32_t                       signalSemaphoreCount;
313                         DE_NULL                                                                         // const VkSemaphore*             pSignalSemaphores;
314                 };
315
316                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
317                 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), VK_TRUE, ~0ull));
318         }
319
320         // Get result
321         {
322                 const VkOffset3D zeroOffset = { 0, 0, 0 };
323                 return m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), VK_IMAGE_LAYOUT_GENERAL, zeroOffset, 256, 256, VK_IMAGE_ASPECT_COLOR_BIT);
324         }
325 }
326
327 MovePtr<tcu::TextureLevel> InvertedDepthRangesTestInstance::generateReferenceImage (void) const
328 {
329         MovePtr<tcu::TextureLevel>              image                   (new tcu::TextureLevel(mapVkFormat(m_colorAttachmentFormat), 256, 256));
330         const tcu::PixelBufferAccess    access                  (image->getAccess());
331         const Vec4                                              black                   (0.0f, 0.0f, 0.0f, 1.0f);
332         const int                                               p1                              = static_cast<int>(256.0f * 0.2f / 2.0f);
333         const int                                               p2                              = static_cast<int>(256.0f * 1.8f / 2.0f);
334         const float                                             delta                   = 256.0f * 1.6f / 2.0f;
335         const float                                             depthValues[]   = { -0.2f, 0.0f, 1.2f };
336
337         tcu::clear(access, black);
338
339         for (int y = p1; y <= p2; ++y)
340                 for (int x = p1; x <  256 - y;  ++x)
341                 {
342                         const float     a = static_cast<float>(p2 - x + p1 - y) / delta;
343                         const float     b = static_cast<float>(y - p1) / delta;
344                         const float     c = 1.0f - a - b;
345                         const float     depth = a * depthValues[0] + b * depthValues[1] + c * depthValues[2];
346                         const float     depthClamped = de::clamp(depth, 0.0f, 1.0f);
347                         const float     depthFinal = depthClamped * m_params.maxDepth + (1.0f - depthClamped) * m_params.minDepth;
348
349                         if (m_params.depthClampEnable || (depth >= 0.0f && depth <= 1.0f))
350                                 access.setPixel(Vec4(depthFinal, 0.5f, 0.5f, 1.0f), x, y);
351                 }
352
353         return image;
354 }
355
356 tcu::TestStatus InvertedDepthRangesTestInstance::iterate (void)
357 {
358         // Set up the viewport and draw
359
360         const VkViewport viewport =
361         {
362                 0.0f,                           // float    x;
363                 0.0f,                           // float    y;
364                 256.0f,                         // float    width;
365                 256.0f,                         // float    height;
366                 m_params.minDepth,      // float    minDepth;
367                 m_params.maxDepth,      // float    maxDepth;
368         };
369
370         const tcu::ConstPixelBufferAccess       resultImage     = draw(viewport);
371
372         // Verify the results
373
374         tcu::TestLog&                           log                             = m_context.getTestContext().getLog();
375         MovePtr<tcu::TextureLevel>      referenceImage  = generateReferenceImage();
376
377         if (!tcu::fuzzyCompare(log, "Image compare", "Image compare", referenceImage->getAccess(), resultImage, 0.02f, tcu::COMPARE_LOG_RESULT))
378                 return tcu::TestStatus::fail("Rendered image is incorrect");
379         else
380                 return tcu::TestStatus::pass("Pass");
381 }
382
383 class InvertedDepthRangesTest : public TestCase
384 {
385 public:
386         InvertedDepthRangesTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
387                 : TestCase      (testCtx, name, description)
388                 , m_params      (params)
389         {
390         }
391
392         void initPrograms (SourceCollections& programCollection) const
393         {
394                 // Vertex shader
395                 {
396                         std::ostringstream src;
397                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
398                                 << "\n"
399                                 << "layout(location = 0) in vec4 in_position;\n"
400                                 << "\n"
401                                 << "out gl_PerVertex {\n"
402                                 << "    vec4  gl_Position;\n"
403                                 << "};\n"
404                                 << "\n"
405                                 << "void main(void)\n"
406                                 << "{\n"
407                                 << "    gl_Position = in_position;\n"
408                                 << "}\n";
409
410                         programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
411                 }
412
413                 // Fragment shader
414                 {
415                         std::ostringstream src;
416                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
417                                 << "\n"
418                                 << "layout(location = 0) out vec4 out_color;\n"
419                                 << "\n"
420                                 << "void main(void)\n"
421                                 << "{\n"
422                                 << "    out_color = vec4(gl_FragCoord.z, 0.5, 0.5, 1.0);\n"
423                                 << "}\n";
424
425                         programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
426                 }
427         }
428
429         virtual TestInstance* createInstance (Context& context) const
430         {
431                 return new InvertedDepthRangesTestInstance(context, m_params);
432         }
433
434 private:
435         const TestParams        m_params;
436 };
437
438 void populateTestGroup (tcu::TestCaseGroup* testGroup)
439 {
440         const struct
441         {
442                 const char* const       name;
443                 VkBool32                        depthClamp;
444         } depthClamp[] =
445         {
446                 { "depthclamp",         VK_TRUE         },
447                 { "nodepthclamp",       VK_FALSE        },
448         };
449
450         const struct
451         {
452                 const char* const       name;
453                 float                           delta;
454         } delta[] =
455         {
456                 { "deltazero",                                  0.0f    },
457                 { "deltasmall",                                 0.3f    },
458                 { "deltaone",                                   1.0f    },
459
460                 // Range > 1.0 requires VK_EXT_depth_range_unrestricted extension
461                 { "depth_range_unrestricted",   2.7f    },
462         };
463
464         for (int ndxDepthClamp = 0; ndxDepthClamp < DE_LENGTH_OF_ARRAY(depthClamp); ++ndxDepthClamp)
465         for (int ndxDelta = 0; ndxDelta < DE_LENGTH_OF_ARRAY(delta); ++ndxDelta)
466         {
467                 const float minDepth = 0.5f + delta[ndxDelta].delta / 2.0f;
468                 const float maxDepth = minDepth - delta[ndxDelta].delta;
469                 DE_ASSERT(minDepth >= maxDepth);
470
471                 const TestParams params =
472                 {
473                         depthClamp[ndxDepthClamp].depthClamp,
474                         minDepth,
475                         maxDepth
476                 };
477                 std::ostringstream      name;
478                 name << depthClamp[ndxDepthClamp].name << "_" << delta[ndxDelta].name;
479
480                 testGroup->addChild(new InvertedDepthRangesTest(testGroup->getTestContext(), name.str(), "", params));
481         }
482 }
483
484 }       // anonymous
485
486 tcu::TestCaseGroup*     createInvertedDepthRangesTests (tcu::TestContext& testCtx)
487 {
488         return createTestGroup(testCtx, "inverted_depth_ranges", "Inverted depth ranges", populateTestGroup);
489 }
490
491 }       // Draw
492 }       // vkt