Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / draw / vktDrawDepthClampTests.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 Depth clamp tests.
23  *//*--------------------------------------------------------------------*/
24
25 #include "vkDefs.hpp"
26 #include "vktDrawDepthClampTests.hpp"
27 #include "vktTestGroupUtil.hpp"
28 #include "vktTestCaseUtil.hpp"
29 #include "vktDrawCreateInfoUtil.hpp"
30 #include "vktDrawBufferObjectUtil.hpp"
31 #include "vktDrawImageObjectUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkCmdUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkQueryUtil.hpp"
39 #include "tcuTextureUtil.hpp"
40 #include "tcuTestLog.hpp"
41
42 #include <cmath>
43 #include <limits>
44 #include "deMath.h"
45
46 namespace vkt
47 {
48 namespace Draw
49 {
50 namespace {
51 using namespace vk;
52 using namespace de;
53 using std::string;
54 using tcu::Vec4;
55
56 static const int                                        WIDTH                           = 256;
57 static const int                                        HEIGHT                          = 256;
58
59 struct ViewportData
60 {
61         float minDepth;
62         float maxDepth;
63         float depthValue;
64         float expectedValue;
65 };
66
67 struct TestParams
68 {
69         string                                                  testNameSuffix;
70         std::vector<ViewportData>               viewportData;
71         bool                                                    enableDepthBias;
72         float                                                   depthBiasConstantFactor;
73         bool                                                    skipUNorm;
74         bool                                                    skipSNorm;
75         std::vector<const char*>                requiredExtensions;
76 };
77
78 const VkFormat          depthStencilImageFormatsToTest[]        =
79 {
80         VK_FORMAT_D16_UNORM,
81         VK_FORMAT_X8_D24_UNORM_PACK32,
82         VK_FORMAT_D32_SFLOAT,
83         VK_FORMAT_D16_UNORM_S8_UINT,
84         VK_FORMAT_D24_UNORM_S8_UINT,
85         VK_FORMAT_D32_SFLOAT_S8_UINT
86 };
87 const float                     depthEpsilonValuesByFormat[]            =
88 {
89         1e-5f,
90         std::numeric_limits<float>::epsilon(),
91         std::numeric_limits<float>::epsilon(),
92         1e-5f,
93         std::numeric_limits<float>::epsilon(),
94         std::numeric_limits<float>::epsilon()
95 };
96
97 const float                     initialClearDepth                                       = 0.5f;
98 const TestParams        depthClearValuesToTest[]                        =
99 {
100         {
101                 "",                                                                                     // testNameSuffix
102                 { {                                                                                     // viewportData
103                         0.0f,                                                                   //   minDepth
104                         1.0f,                                                                   //   maxDepth
105                         0.3f,                                                                   //   depthValue
106                         0.3f,                                                                   //   expectedValue
107                 } },
108                 false,                                                                          // enableDepthBias
109                 0.0f,                                                                           // depthBiasConstantFactor
110                 false,                                                                          // skipUNorm
111                 false,                                                                          // skipSNorm
112                 {},                                                                                     // requiredExtensions
113         },
114         {
115                 "_clamp_input_negative",                                        // testNameSuffix
116                 { {                                                                                     // viewportData
117                         0.0f,                                                                   //   minDepth
118                         1.0f,                                                                   //   maxDepth
119                    -1e6f,                                                                       //   depthValue
120                         0.0f,                                                                   //   expectedValue
121                 } },
122                 false,                                                                          // enableDepthBias
123                 0.0f,                                                                           // depthBiasConstantFactor
124                 false,                                                                          // skipUNorm
125                 false,                                                                          // skipSNorm
126                 {},                                                                                     // requiredExtensions
127         },
128         {
129                 "_clamp_input_positive",                                        // testNameSuffix
130                 { {                                                                                     // viewportData
131                         0.0f,                                                                   //   minDepth
132                         1.0f,                                                                   //   maxDepth
133                         1.e6f,                                                                  //   depthValue
134                         1.0f,                                                                   //   expectedValue
135                 } },
136                 false,                                                                          // enableDepthBias
137                 0.0f,                                                                           // depthBiasConstantFactor
138                 false,                                                                          // skipUNorm
139                 false,                                                                          // skipSNorm
140                 {},                                                                                     // requiredExtensions
141         },
142         {
143                 "_depth_bias_clamp_input_negative",                     // testNameSuffix
144                 { {                                                                                     // viewportData
145                         0.0f,                                                                   //   minDepth
146                         1.0f,                                                                   //   maxDepth
147                         0.3f,                                                                   //   depthValue
148                         0.0f,                                                                   //   expectedValue
149                 } },
150                 true,                                                                           // enableDepthBias
151                 -2e11f,                                                                         // depthBiasConstantFactor
152                 false,                                                                          // skipUNorm
153                 false,                                                                          // skipSNorm
154                 {},                                                                                     // requiredExtensions
155         },
156         {
157                 "_depth_bias_clamp_input_positive",                     // testNameSuffix
158                 { {                                                                                     // viewportData
159                         0.0f,                                                                   //   minDepth
160                         1.0f,                                                                   //   maxDepth
161                         0.7f,                                                                   //   depthValue
162                         1.0f,                                                                   //   expectedValue
163                 } },
164                 true,                                                                           // enableDepthBias
165                 2e11f,                                                                          // depthBiasConstantFactor
166                 false,                                                                          // skipUNorm
167                 false,                                                                          // skipSNorm
168                 {},                                                                                     // requiredExtensions
169         },
170         {
171                 "_depth_range_unrestricted_negative",           // testNameSuffix
172                 { {                                                                                     // viewportData
173                    -1.5f,                                                                       //   minDepth
174                         1.0f,                                                                   //   maxDepth
175                    -1.5f,                                                                       //   depthValue
176                    -1.5f,                                                                       //   expectedValue
177                 } },
178                 false,                                                                          // enableDepthBias
179                 0.0f,                                                                           // depthBiasConstantFactor
180                 true,                                                                           // skipUNorm
181                 true,                                                                           // skipSNorm
182                 {
183                         "VK_EXT_depth_range_unrestricted"               // requiredExtensions[0]
184                 },
185         },
186         {
187                 "_depth_range_unrestricted_positive",           // testNameSuffix
188                 { {                                                                                     // viewportData
189                         0.0f,                                                                   //   minDepth
190                         1.5f,                                                                   //   maxDepth
191                         1.5f,                                                                   //   depthValue
192                         1.5f,                                                                   //   expectedValue
193                 } },
194                 false,                                                                          // enableDepthBias
195                 0.0f,                                                                           // depthBiasConstantFactor
196                 true,                                                                           // skipUNorm
197                 true,                                                                           // skipSNorm
198                 {
199                         "VK_EXT_depth_range_unrestricted"               // requiredExtensions[0]
200                 },
201         },
202         {
203                 "_clamp_four_viewports",                                        // testNameSuffix
204                 {                                                                                       // viewportData
205                         {
206                                 0.0f,                                                           //   minDepth
207                                 0.5f,                                                           //   maxDepth
208                                 0.7f,                                                           //   depthValue
209                                 0.35f,                                                          //   expectedValue: 0.7 * 0.5 + (1.0 - 0.7) * 0.0) = 0.35
210                         },
211                         {
212                                 0.9f,                                                           //   minDepth
213                                 1.0f,                                                           //   maxDepth
214                                 1.0f,                                                           //   depthValue
215                                 1.0f,                                                           //   expectedValue: 1.0 * 1.0 + (1.0 - 1.0) * 0.9 = 1.0
216                         },
217                         {
218                                 0.5f,                                                           //   minDepth
219                                 1.0f,                                                           //   maxDepth
220                                 0.9f,                                                           //   depthValue
221                                 0.95f,                                                          //   expectedValue: 0.9 * 1.0 + (1.0 - 0.9) * 0.5 = 0.95
222                         },
223                         {
224                                 0.5f,                                                           //   minDepth
225                                 0.9f,                                                           //   maxDepth
226                                 0.4f,                                                           //   depthValue
227                                 0.66f,                                                          //   expectedValue: 0.4 * 0.9 + (1.0 - 0.4) * 0.5 = 0.66
228                         },
229                 },
230                 false,                                                                          // enableDepthBias
231                 0.0f,                                                                           // depthBiasConstantFactor
232                 true,                                                                           // skipUNorm
233                 true,                                                                           // skipSNorm
234                 {},
235         }
236 };
237
238 bool isUnormDepthFormat(VkFormat format)
239 {
240         switch (format)
241         {
242                 case VK_FORMAT_D24_UNORM_S8_UINT:
243                 case VK_FORMAT_X8_D24_UNORM_PACK32:
244                 case VK_FORMAT_D16_UNORM_S8_UINT:
245                         /* Special case for combined depth-stencil-unorm modes for which tcu::getTextureChannelClass()
246                            returns TEXTURECHANNELCLASS_LAST */
247                         return true;
248                 default:
249                         return vk::isUnormFormat(format);
250         }
251 }
252
253 class DepthClampTestInstance : public TestInstance {
254 public:
255                                                                 DepthClampTestInstance  (Context& context, const TestParams& params, const VkFormat format, const float epsilon, const SharedGroupParams groupParams);
256         tcu::TestStatus                         iterate                                 ();
257
258 private:
259         tcu::ConstPixelBufferAccess draw                                        ();
260
261         void                                            preRenderCommands               (VkCommandBuffer cmdBuffer, const VkImageAspectFlagBits aspectBits, const VkClearValue& clearValue) const;
262         void                                            drawCommands                    (VkCommandBuffer cmdBuffer) const;
263
264 #ifndef CTS_USES_VULKANSC
265         void                                            beginSecondaryCmdBuffer (VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags = 0u) const;
266         void                                            beginDynamicRender              (VkCommandBuffer cmdBuffer, VkClearValue clearValue, VkRenderingFlagsKHR renderingFlags = 0u) const;
267 #endif // CTS_USES_VULKANSC
268
269         const TestParams                                                                        m_params;
270         const VkFormat                                                                          m_format;
271         const float                                                                                     m_epsilon;
272         std::vector<VkViewport>                                                         m_viewportVect;
273         std::vector<VkRect2D>                                                           m_scissorVect;
274         const SharedGroupParams                                                         m_groupParams;
275         SharedPtr<Image>                                                                        m_depthTargetImage;
276         Move<VkImageView>                                                                       m_depthTargetView;
277         SharedPtr<Buffer>                                                                       m_vertexBuffer;
278         Move<VkRenderPass>                                                                      m_renderPass;
279         Move<VkFramebuffer>                                                                     m_framebuffer;
280         Move<VkPipelineLayout>                                                          m_pipelineLayout;
281         Move<VkPipeline>                                                                        m_pipeline;
282 };
283
284 static const Vec4                                       vertices[]                      = {
285         Vec4(-1.0f, -1.0f,  0.5f, 1.0f),        // 0 -- 2
286         Vec4(-1.0f,  1.0f,  0.5f, 1.0f),        // |  / |
287         Vec4( 1.0f, -1.0f,  0.5f, 1.0f),        // | /  |
288         Vec4( 1.0f,  1.0f,  0.5f, 1.0f)         // 1 -- 3
289 };
290 static const VkPrimitiveTopology        verticesTopology        = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
291
292 DepthClampTestInstance::DepthClampTestInstance (Context& context, const TestParams& params, const VkFormat format, const float epsilon, const SharedGroupParams groupParams)
293         : TestInstance          (context)
294         , m_params                      (params)
295         , m_format                      (format)
296         , m_epsilon                     (epsilon)
297         , m_viewportVect        (params.viewportData.size(), VkViewport())
298         , m_scissorVect         (params.viewportData.size(), VkRect2D())
299         , m_groupParams         (groupParams)
300 {
301         const DeviceInterface&          vk                                                              = m_context.getDeviceInterface();
302         const VkDevice                          device                                                  = m_context.getDevice();
303         const deUint32                          queueFamilyIndex                                = m_context.getUniversalQueueFamilyIndex();
304         const deUint32                          viewportCount                                   = static_cast<deUint32>(m_params.viewportData.size());
305
306         // create viewport grid
307         {
308                 const deUint32  columnCount             = deCeilFloatToInt32(deFloatSqrt(static_cast<float>(viewportCount)));
309                 const deUint32  rowCount                = deCeilFloatToInt32(static_cast<float>(viewportCount) / static_cast<float>(columnCount));
310                 const deUint32  rectWidth               = WIDTH / columnCount;
311                 const deUint32  rectHeight              = HEIGHT / rowCount;
312
313                 VkOffset2D              pos                             { 0, 0 };
314
315                 for (deUint32 viewportIndex = 0; viewportIndex < viewportCount; ++viewportIndex)
316                 {
317                         // move to next row
318                         if ((viewportIndex != 0) && (viewportIndex % columnCount == 0))
319                         {
320                                 pos.x = 0;
321                                 pos.y += rectHeight;
322                         }
323
324                         m_viewportVect[viewportIndex] =
325                         {
326                                 static_cast<float>(pos.x),                                                      // float        x;
327                                 static_cast<float>(pos.y),                                                      // float        y;
328                                 static_cast<float>(rectWidth),                                          // float        width;
329                                 static_cast<float>(rectHeight),                                         // float        height;
330                                 m_params.viewportData[viewportIndex].minDepth,          // float        minDepth;
331                                 m_params.viewportData[viewportIndex].maxDepth,          // float        maxDepth;
332                         };
333
334                         m_scissorVect[viewportIndex] =
335                         {
336                                 pos,
337                                 {rectWidth, rectHeight}
338                         };
339
340                         pos.x += rectWidth;
341                 }
342         }
343
344         DescriptorPoolBuilder           descriptorPoolBuilder;
345         DescriptorSetLayoutBuilder      descriptorSetLayoutBuilder;
346         // Vertex data
347         {
348                 const size_t                    verticesCount                                   = DE_LENGTH_OF_ARRAY(vertices);
349                 const VkDeviceSize              dataSize                                                = verticesCount * sizeof(Vec4);
350                 m_vertexBuffer                                                                                  = Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
351                                                                                                                                 m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
352
353                 Vec4 testVertices[verticesCount];
354                 deMemcpy(testVertices, vertices, dataSize);
355                 for(size_t i = 0; i < verticesCount; ++i)
356                         testVertices[i][2] = params.viewportData[0].depthValue;
357                 deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), testVertices, static_cast<std::size_t>(dataSize));
358                 flushMappedMemoryRange(vk, device, m_vertexBuffer->getBoundMemory().getMemory(), m_vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
359         }
360
361         const VkImageUsageFlags         targetImageUsageFlags                                           = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
362         const ImageCreateInfo           targetImageCreateInfo                                           (VK_IMAGE_TYPE_2D, m_format, { WIDTH, HEIGHT, 1u }, 1u, 1u,     VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, targetImageUsageFlags);
363         m_depthTargetImage                                                                                                              = Image::createAndAlloc(vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), queueFamilyIndex);
364
365         const ImageViewCreateInfo       depthTargetViewInfo                                                     (m_depthTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, m_format);
366         m_depthTargetView = createImageView(vk, device, &depthTargetViewInfo);
367
368         // Render pass and framebuffer
369         if (!m_groupParams->useDynamicRendering)
370         {
371                 RenderPassCreateInfo            renderPassCreateInfo;
372                 renderPassCreateInfo.addAttachment(AttachmentDescription(
373                         m_format,                                                                                               // format
374                         VK_SAMPLE_COUNT_1_BIT,                                                                  // samples
375                         VK_ATTACHMENT_LOAD_OP_LOAD,                                                             // loadOp
376                         VK_ATTACHMENT_STORE_OP_STORE,                                                   // storeOp
377                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                                // stencilLoadOp
378                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                               // stencilStoreOp
379                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,               // initialLayout
380                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));             // finalLayout
381                 const VkAttachmentReference depthAttachmentReference                                    = makeAttachmentReference(0u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
382                 renderPassCreateInfo.addSubpass(SubpassDescription(
383                         VK_PIPELINE_BIND_POINT_GRAPHICS,        // pipelineBindPoint
384                         (VkSubpassDescriptionFlags)0,           // flags
385                         0u,                                                                     // inputAttachmentCount
386                         DE_NULL,                                                        // inputAttachments
387                         0u,                                                                     // colorAttachmentCount
388                         DE_NULL,                                                        // colorAttachments
389                         DE_NULL,                                                        // resolveAttachments
390                         depthAttachmentReference,                       // depthStencilAttachment
391                         0u,                                                                     // preserveAttachmentCount
392                         DE_NULL));                                                      // preserveAttachments
393                 m_renderPass                                                                                                                    = createRenderPass(vk, device, &renderPassCreateInfo);
394
395                 const std::vector<VkImageView>                          depthAttachments                        { *m_depthTargetView };
396                 FramebufferCreateInfo                                           framebufferCreateInfo           (*m_renderPass, depthAttachments, WIDTH, HEIGHT, 1);
397                 m_framebuffer                                                                                                                   = createFramebuffer(vk, device, &framebufferCreateInfo);
398         }
399
400         // Vertex input
401         const VkVertexInputBindingDescription           vertexInputBindingDescription   =
402         {
403                 0u,                                                                             // uint32_t             binding;
404                 sizeof(Vec4),                                                   // uint32_t             stride;
405                 VK_VERTEX_INPUT_RATE_VERTEX,                    // VkVertexInputRate    inputRate;
406         };
407
408         const VkVertexInputAttributeDescription         vertexInputAttributeDescription =
409         {
410                 0u,                                                                             // uint32_t    location;
411                 0u,                                                                             // uint32_t    binding;
412                 VK_FORMAT_R32G32B32A32_SFLOAT,                  // VkFormat    format;
413                 0u                                                                              // uint32_t    offset;
414         };
415
416         const PipelineCreateInfo::VertexInputState      vertexInputState                                = PipelineCreateInfo::VertexInputState(1, &vertexInputBindingDescription,
417                                                                                                                                                                                                                                            1, &vertexInputAttributeDescription);
418
419         // Graphics pipeline
420         const Unique<VkShaderModule>    vertexModule                                                            (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
421         Move<VkShaderModule>                    geometryModule;
422         const Unique<VkShaderModule>    fragmentModule                                                          (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
423
424         if (viewportCount > 1)
425                 geometryModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("geom"), 0);
426
427         const PipelineLayoutCreateInfo  pipelineLayoutCreateInfo                                        (0u, DE_NULL, 0u, DE_NULL);
428         m_pipelineLayout                                                                                                                        = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
429         std::vector<VkDynamicState>             dynamicStates                                                           { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
430
431         PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
432         pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vertexModule,   "main", VK_SHADER_STAGE_VERTEX_BIT));
433         if (*geometryModule != 0)
434                 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*geometryModule, "main", VK_SHADER_STAGE_GEOMETRY_BIT));
435         pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fragmentModule, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
436         pipelineCreateInfo.addState (PipelineCreateInfo::VertexInputState       (vertexInputState));
437         pipelineCreateInfo.addState (PipelineCreateInfo::InputAssemblerState(verticesTopology));
438         pipelineCreateInfo.addState (PipelineCreateInfo::ViewportState          (viewportCount, m_viewportVect, m_scissorVect));
439         pipelineCreateInfo.addState (PipelineCreateInfo::DepthStencilState      (VK_TRUE, VK_TRUE, VK_COMPARE_OP_ALWAYS, VK_FALSE, VK_FALSE));
440         pipelineCreateInfo.addState (PipelineCreateInfo::RasterizerState        (
441                 VK_TRUE,                                                                                // depthClampEnable
442                 VK_FALSE,                                                                               // rasterizerDiscardEnable
443                 VK_POLYGON_MODE_FILL,                                                   // polygonMode
444                 VK_CULL_MODE_NONE,                                                              // cullMode
445                 VK_FRONT_FACE_CLOCKWISE,                                                // frontFace
446                 m_params.enableDepthBias ? VK_TRUE : VK_FALSE,  // depthBiasEnable
447                 m_params.depthBiasConstantFactor,                               // depthBiasConstantFactor
448                 0.0f,                                                                                   // depthBiasClamp
449                 0.0f,                                                                                   // depthBiasSlopeFactor
450                 1.0f));                                                                                 // lineWidth
451         pipelineCreateInfo.addState (PipelineCreateInfo::MultiSampleState       ());
452         pipelineCreateInfo.addState (PipelineCreateInfo::DynamicState           (dynamicStates));
453
454 #ifndef CTS_USES_VULKANSC
455         VkPipelineRenderingCreateInfoKHR renderingCreateInfo
456         {
457                 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
458                 DE_NULL,
459                 0u,
460                 0u,
461                 DE_NULL,
462                 m_format,
463                 m_format
464         };
465
466         if (m_groupParams->useDynamicRendering)
467                 pipelineCreateInfo.pNext = &renderingCreateInfo;
468 #endif // CTS_USES_VULKANSC
469
470         m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
471 }
472
473 tcu::ConstPixelBufferAccess DepthClampTestInstance::draw ()
474 {
475         const DeviceInterface&                          vk                                      = m_context.getDeviceInterface();
476         const VkDevice                                          device                          = m_context.getDevice();
477         const VkQueue                                           queue                           = m_context.getUniversalQueue();
478         const deUint32                                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
479
480         const CmdPoolCreateInfo                         cmdPoolCreateInfo       (queueFamilyIndex);
481         const Unique<VkCommandPool>                     cmdPool                         (createCommandPool(vk, device, &cmdPoolCreateInfo));
482         const Unique<VkCommandBuffer>           cmdBuffer                       (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
483         Move<VkCommandBuffer>                           secCmdBuffer;
484         const VkClearValue                                      clearDepth                      = makeClearValueDepthStencil(initialClearDepth, 0u);
485         const bool                                                      isCombinedType          = tcu::isCombinedDepthStencilType(mapVkFormat(m_format).type) && m_format != VK_FORMAT_X8_D24_UNORM_PACK32;
486         const VkImageAspectFlagBits                     aspectBits                      = (VkImageAspectFlagBits)(isCombinedType ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT);
487
488 #ifndef CTS_USES_VULKANSC
489         if (m_groupParams->useSecondaryCmdBuffer)
490         {
491                 secCmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
492
493                 // record secondary command buffer
494                 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
495                 {
496                         beginSecondaryCmdBuffer(*secCmdBuffer, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
497                         beginDynamicRender(*secCmdBuffer, clearDepth);
498                 }
499                 else
500                         beginSecondaryCmdBuffer(*secCmdBuffer);
501
502                 drawCommands(*secCmdBuffer);
503
504                 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
505                         endRendering(vk, *secCmdBuffer);
506
507                 endCommandBuffer(vk, *secCmdBuffer);
508
509                 // record primary command buffer
510                 beginCommandBuffer(vk, *cmdBuffer, 0u);
511                 preRenderCommands(*cmdBuffer, aspectBits, clearDepth);
512
513                 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
514                         beginDynamicRender(*cmdBuffer, clearDepth, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
515
516                 vk.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer);
517
518                 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
519                         endRendering(vk, *cmdBuffer);
520         }
521         else if (m_groupParams->useDynamicRendering)
522         {
523                 beginCommandBuffer(vk, *cmdBuffer);
524                 preRenderCommands(*cmdBuffer, aspectBits, clearDepth);
525                 beginDynamicRender(*cmdBuffer, clearDepth);
526                 drawCommands(*cmdBuffer);
527                 endRendering(vk, *cmdBuffer);
528         }
529 #endif // CTS_USES_VULKANSC
530
531         if (!m_groupParams->useDynamicRendering)
532         {
533                 const VkRect2D renderArea = makeRect2D(0, 0, WIDTH, HEIGHT);
534
535                 beginCommandBuffer(vk, *cmdBuffer);
536                 preRenderCommands(*cmdBuffer, aspectBits, clearDepth);
537                 beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, renderArea);
538                 drawCommands(*cmdBuffer);
539                 endRenderPass(vk, *cmdBuffer);
540         }
541
542         transition2DImage(vk, *cmdBuffer, m_depthTargetImage->object(), aspectBits,
543                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
544                 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
545                 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
546
547         endCommandBuffer(vk, *cmdBuffer);
548
549         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
550
551         VK_CHECK(vk.queueWaitIdle(queue));
552
553         return m_depthTargetImage->readDepth(queue, m_context.getDefaultAllocator(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { 0, 0, 0 }, WIDTH, HEIGHT, VK_IMAGE_ASPECT_DEPTH_BIT);
554 }
555
556 void DepthClampTestInstance::preRenderCommands(VkCommandBuffer cmdBuffer, const VkImageAspectFlagBits aspectBits, const VkClearValue& clearValue) const
557 {
558         const DeviceInterface&  vk                              = m_context.getDeviceInterface();
559         const bool                              isCombinedType  = tcu::isCombinedDepthStencilType(mapVkFormat(m_format).type) && m_format != VK_FORMAT_X8_D24_UNORM_PACK32;
560
561         if (isCombinedType)
562                 initialTransitionDepthStencil2DImage(vk, cmdBuffer, m_depthTargetImage->object(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
563         else
564                 initialTransitionDepth2DImage(vk, cmdBuffer, m_depthTargetImage->object(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
565
566         const ImageSubresourceRange subresourceRange (aspectBits);
567
568         vk.cmdClearDepthStencilImage(cmdBuffer, m_depthTargetImage->object(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.depthStencil, 1, &subresourceRange);
569
570         transition2DImage(vk, cmdBuffer, m_depthTargetImage->object(), aspectBits,
571                                           VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
572                                           VK_ACCESS_TRANSFER_WRITE_BIT            , VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
573                                           VK_PIPELINE_STAGE_TRANSFER_BIT          , VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
574
575         {
576                 const VkMemoryBarrier memBarrier                                        = { VK_STRUCTURE_TYPE_MEMORY_BARRIER, DE_NULL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT };
577                 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
578         }
579 }
580
581 void DepthClampTestInstance::drawCommands(VkCommandBuffer cmdBuffer) const
582 {
583         const DeviceInterface&  vk              = m_context.getDeviceInterface();
584         const VkDeviceSize              offset  = 0;
585         const VkBuffer                  buffer  = m_vertexBuffer->object();
586
587         // if there is more then one viewport we are also checking
588         // proper behaviour of cmdSetViewport/Scissor - there was
589         // a driver bug that caused invalid behaviour of those
590         // functions when firstViewport/Scissor had a non 0 value
591         deUint32 indexCount = static_cast<deUint32>(m_viewportVect.size());
592         for (deUint32 index = 0; index < indexCount; ++index)
593         {
594                 vk.cmdSetViewport(cmdBuffer, index, 1u, &m_viewportVect[index]);
595                 vk.cmdSetScissor(cmdBuffer, index, 1u, &m_scissorVect[index]);
596         }
597
598         vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
599         vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &buffer, &offset);
600         vk.cmdDraw(cmdBuffer, DE_LENGTH_OF_ARRAY(vertices), 1, 0, 0);
601 }
602
603 #ifndef CTS_USES_VULKANSC
604 void DepthClampTestInstance::beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags) const
605 {
606         VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
607         {
608                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR,                // VkStructureType                                      sType;
609                 DE_NULL,                                                                                                                                // const void*                                          pNext;
610                 renderingFlags,                                                                                                                 // VkRenderingFlagsKHR                          flags;
611                 0u,                                                                                                                                             // uint32_t                                                     viewMask;
612                 0u,                                                                                                                                             // uint32_t                                                     colorAttachmentCount;
613                 DE_NULL,                                                                                                                                // const VkFormat*                                      pColorAttachmentFormats;
614                 m_format,                                                                                                                               // VkFormat                                                     depthAttachmentFormat;
615                 VK_FORMAT_UNDEFINED,                                                                                                    // VkFormat                                                     stencilAttachmentFormat;
616                 VK_SAMPLE_COUNT_1_BIT,                                                                                                  // VkSampleCountFlagBits                        rasterizationSamples;
617         };
618
619         const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
620
621         VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
622         if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
623                 usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
624
625         const VkCommandBufferBeginInfo commandBufBeginParams
626         {
627                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                                                    // VkStructureType                                      sType;
628                 DE_NULL,                                                                                                                                // const void*                                          pNext;
629                 usageFlags,                                                                                                                             // VkCommandBufferUsageFlags            flags;
630                 &bufferInheritanceInfo
631         };
632
633         const DeviceInterface& vk = m_context.getDeviceInterface();
634         VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &commandBufBeginParams));
635 }
636
637 void DepthClampTestInstance::beginDynamicRender(VkCommandBuffer cmdBuffer, VkClearValue clearValue, VkRenderingFlagsKHR renderingFlags) const
638 {
639         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
640         const VkRect2D                  renderArea      = makeRect2D(0, 0, WIDTH, HEIGHT);
641
642         VkRenderingAttachmentInfoKHR depthAttachment
643         {
644                 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,                // VkStructureType                                              sType;
645                 DE_NULL,                                                                                                // const void*                                                  pNext;
646                 *m_depthTargetView,                                                                             // VkImageView                                                  imageView;
647                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,               // VkImageLayout                                                imageLayout;
648                 VK_RESOLVE_MODE_NONE,                                                                   // VkResolveModeFlagBits                                resolveMode;
649                 DE_NULL,                                                                                                // VkImageView                                                  resolveImageView;
650                 VK_IMAGE_LAYOUT_UNDEFINED,                                                              // VkImageLayout                                                resolveImageLayout;
651                 VK_ATTACHMENT_LOAD_OP_LOAD,                                                             // VkAttachmentLoadOp                                   loadOp;
652                 VK_ATTACHMENT_STORE_OP_STORE,                                                   // VkAttachmentStoreOp                                  storeOp;
653                 clearValue                                                                                              // VkClearValue                                                 clearValue;
654         };
655
656         VkRenderingInfoKHR renderingInfo
657         {
658                 VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
659                 DE_NULL,
660                 renderingFlags,                                                                                 // VkRenderingFlagsKHR                                  flags;
661                 renderArea,                                                                                             // VkRect2D                                                             renderArea;
662                 1u,                                                                                                             // deUint32                                                             layerCount;
663                 0u,                                                                                                             // deUint32                                                             viewMask;
664                 0u,                                                                                                             // deUint32                                                             colorAttachmentCount;
665                 DE_NULL,                                                                                                // const VkRenderingAttachmentInfoKHR*  pColorAttachments;
666                 &depthAttachment,                                                                               // const VkRenderingAttachmentInfoKHR*  pDepthAttachment;
667                 DE_NULL,                                                                                                // const VkRenderingAttachmentInfoKHR*  pStencilAttachment;
668         };
669
670         vk.cmdBeginRendering(cmdBuffer, &renderingInfo);
671 }
672 #endif // CTS_USES_VULKANSC
673
674 tcu::TestStatus DepthClampTestInstance::iterate (void)
675 {
676         const tcu::ConstPixelBufferAccess resultImage = draw();
677
678         DE_ASSERT((isUnormDepthFormat(m_format) == false) ||
679                 (m_params.viewportData[0].expectedValue >= 0.0f && m_params.viewportData[0].expectedValue <= 1.0f));
680
681         for(deUint32 viewportIndex = 0 ; viewportIndex < m_scissorVect.size() ; ++viewportIndex)
682         {
683                 const float             expectedValue   = m_params.viewportData[viewportIndex].expectedValue;
684                 const VkRect2D& viewRect                = m_scissorVect[viewportIndex];
685
686                 deInt32 xStart  = viewRect.offset.x;
687                 deInt32 xEnd    = xStart + viewRect.extent.width;
688                 deInt32 yStart  = viewRect.offset.y;
689                 deInt32 yEnd    = yStart + viewRect.extent.height;
690
691                 for (int y = yStart; y < yEnd; ++y)
692                 for (int x = xStart; x < xEnd; ++x)
693                 {
694                         if (std::abs(expectedValue - resultImage.getPixDepth(x, y, 0)) >= m_epsilon)
695                         {
696                                 tcu::TestLog& log = m_context.getTestContext().getLog();
697                                 log << tcu::TestLog::ImageSet("Result of rendering", "")
698                                         << tcu::TestLog::Image("Result", "", resultImage)
699                                         << tcu::TestLog::EndImageSet;
700
701                                 std::ostringstream msg;
702                                 msg << "Depth value mismatch, expected: " << expectedValue
703                                         << ", got: " << resultImage.getPixDepth(x, y, 0) << " at (" << x << ", " << y << ", 0)";
704
705                                 return tcu::TestStatus::fail(msg.str());
706                         }
707                 }
708         }
709         return tcu::TestStatus::pass("Pass");
710 }
711
712 class DepthClampTest : public TestCase
713 {
714 public:
715         DepthClampTest (tcu::TestContext &testCtx, const string& name, const string& description, const TestParams &params, const VkFormat format, const float epsilon, const SharedGroupParams groupParams)
716                 : TestCase              (testCtx, name, description)
717                 , m_params              (params)
718                 , m_format              (format)
719                 , m_epsilon             (epsilon)
720                 , m_groupParams (groupParams)
721         {
722         }
723
724         virtual void initPrograms (SourceCollections& programCollection) const
725         {
726                 programCollection.glslSources.add("vert") << glu::VertexSource(
727                         "#version 450\n"
728                         "\n"
729                         "layout(location = 0) in vec4 in_position;\n"
730                         "void main(void)\n"
731                         "{\n"
732                         "    gl_Position = in_position;\n"
733                         "}\n");
734
735                 if (m_params.viewportData.size() > 1)
736                 {
737                         // gl_ViewportIndex built-in variable is available only to the geometry shader
738
739                         std::string depthValues = "";
740                         for (const auto& vd : m_params.viewportData)
741                                 depthValues += std::to_string(vd.depthValue) + ", ";
742
743                         // this geometry shader draws the same quad but with diferent depth to all viewports
744                         programCollection.glslSources.add("geom") << glu::GeometrySource(
745                                 std::string("#version 450\n") +
746                                 "#extension GL_EXT_geometry_shader : require\n"
747                                 "layout(invocations = " + std::to_string(m_params.viewportData.size()) + ") in;\n"
748                                 "layout(triangles) in;\n"
749                                 "layout(triangle_strip, max_vertices = 4) out;\n"
750                                 "void main()\n"
751                                 "{\n"
752                                 "  const float depthValues[] = { " + depthValues + " 0.0 };\n"
753                                 "  for (int i = 0; i < gl_in.length(); i++)\n"
754                                 "  {\n"
755                                 "    gl_ViewportIndex = gl_InvocationID;\n"
756                                 "    gl_Position      = gl_in[i].gl_Position;\n"
757                                 "    gl_Position.z    = depthValues[gl_InvocationID];\n"
758                                 "    EmitVertex();\n"
759                                 "  }\n"
760                                 "  EndPrimitive();\n"
761                                 "}");
762                 }
763
764                 programCollection.glslSources.add("frag") << glu::FragmentSource(
765                         "#version 450\n"
766                         "void main(void)\n"
767                         "{\n"
768                         "}\n");
769         }
770
771         virtual void checkSupport (Context& context) const
772         {
773                 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_CLAMP);
774                 for(const auto& extensionName : m_params.requiredExtensions)
775                         context.requireDeviceFunctionality(extensionName);
776
777                 if (m_params.viewportData.size() > 1)
778                 {
779                         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_MULTI_VIEWPORT);
780                         if (!context.getDeviceFeatures().geometryShader)
781                                 throw tcu::NotSupportedError("Geometry shader is not supported");
782                 }
783
784                 VkImageFormatProperties imageFormatProperties;
785                 const auto&     vki             = context.getInstanceInterface();
786                 const auto&     vkd             = context.getPhysicalDevice();
787                 const auto      usage   = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
788                 if (vki.getPhysicalDeviceImageFormatProperties(vkd, m_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, usage, 0u, &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
789                 {
790                         TCU_THROW(NotSupportedError, "Format not supported");
791                 }
792
793                 if (m_groupParams->useDynamicRendering)
794                         context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
795         }
796
797         virtual TestInstance* createInstance (Context& context) const
798         {
799                 return new DepthClampTestInstance(context, m_params, m_format, m_epsilon, m_groupParams);
800         }
801
802 private:
803         const TestParams                        m_params;
804         const VkFormat                          m_format;
805         const float                                     m_epsilon;
806         const SharedGroupParams         m_groupParams;
807 };
808
809 std::string getFormatCaseName (VkFormat format)
810 {
811         return de::toLower(de::toString(getFormatStr(format)).substr(10));
812 }
813
814 void createTests (tcu::TestCaseGroup* testGroup, const SharedGroupParams groupParams)
815 {
816         for(int i = 0; i < DE_LENGTH_OF_ARRAY(depthStencilImageFormatsToTest); ++i)
817         {
818                 const auto format = depthStencilImageFormatsToTest[i];
819
820                 // reduce number of tests for dynamic rendering cases where secondary command buffer is used
821                 if (groupParams->useSecondaryCmdBuffer && (format != VK_FORMAT_D16_UNORM))
822                         continue;
823
824                 const float             epsilon                 = depthEpsilonValuesByFormat[i];
825                 const auto              formatCaseName  = getFormatCaseName(format);
826                 for(const auto& params : depthClearValuesToTest)
827                 {
828                         if ((params.skipSNorm && vk::isSnormFormat(format)) || (params.skipUNorm && isUnormDepthFormat(format)))
829                                 continue;
830                         const auto      testCaseName    = formatCaseName + params.testNameSuffix;
831                         testGroup->addChild(new DepthClampTest(testGroup->getTestContext(), testCaseName, "Depth clamp", params, format, epsilon, groupParams));
832                 }
833         }
834 }
835 }       // anonymous
836
837 tcu::TestCaseGroup*     createDepthClampTests (tcu::TestContext& testCtx, const SharedGroupParams groupParams)
838 {
839         return createTestGroup(testCtx, "depth_clamp", "Depth Clamp Tests", createTests, groupParams);
840 }
841 }       // Draw
842 }       // vkt