1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2019 The Khronos Group Inc.
6 * Copyright (c) 2019 Valve Corporation.
7 * Copyright (c) 2023 LunarG, Inc.
8 * Copyright (c) 2023 Nintendo
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 *
22 *//*!
23 * \file
24 * \brief VK_EXT_depth_range_unrestricted Tests
25 *//*--------------------------------------------------------------------*/
26
27 #include "vktPipelineDepthRangeUnrestrictedTests.hpp"
28 #include "vktPipelineVertexUtil.hpp"
29 #include "vktPipelineClearUtil.hpp"
30 #include "vktPipelineImageUtil.hpp"
31 #include "vktPipelineReferenceRenderer.hpp"
32 #include "vktTestCase.hpp"
33 #include "vktTestCaseUtil.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkCmdUtil.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkBuilderUtil.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkQueryUtil.hpp"
40 #include "vkTypeUtil.hpp"
41 #include "vkObjUtil.hpp"
42
43 #include "tcuTestLog.hpp"
44 #include "tcuTextureUtil.hpp"
45 #include "tcuImageCompare.hpp"
46 #include "tcuCommandLine.hpp"
47
48 #include <sstream>
49 #include <vector>
50
51 namespace vkt
52 {
53 namespace pipeline
54 {
55
56 using namespace vk;
57
58 namespace
59 {
60
61 enum testDynamicStaticMode
62 {
63 TEST_MODE_VIEWPORT_DEPTH_BOUNDS_STATIC = 0,
64 TEST_MODE_VIEWPORT_DYNAMIC = 1,
65 TEST_MODE_DEPTH_BOUNDS_DYNAMIC = 2,
66 TEST_MODE_VIEWPORT_DEPTH_BOUNDS_DYNAMIC = 3,
67 };
68
69 struct DepthRangeUnrestrictedParam
70 {
71 PipelineConstructionType pipelineConstructionType;
72 VkFormat depthFormat;
73 VkBool32 testClearValueOnly;
74 VkClearValue depthBufferClearValue;
75 VkBool32 depthClampEnable;
76 float wc; // Component W of the vertices
77 deUint32 viewportDepthBoundsMode;
78 float viewportMinDepth;
79 float viewportMaxDepth;
80 VkBool32 depthBoundsTestEnable;
81 float minDepthBounds;
82 float maxDepthBounds;
83 VkCompareOp depthCompareOp;
84 };
85
86 // helper functions
getFormatCaseName(vk::VkFormat format)87 std::string getFormatCaseName (vk::VkFormat format)
88 {
89 return de::toLower(de::toString(getFormatStr(format)).substr(10));
90 }
91
getCompareOpStringName(VkCompareOp compare)92 std::string getCompareOpStringName (VkCompareOp compare)
93 {
94 return de::toLower(de::toString(getCompareOpStr(compare)).substr(3));
95 }
96
generateTestName(struct DepthRangeUnrestrictedParam param)97 const std::string generateTestName (struct DepthRangeUnrestrictedParam param)
98 {
99 std::ostringstream result;
100
101 result << getFormatCaseName(param.depthFormat).c_str();
102 result << "_" << getCompareOpStringName(param.depthCompareOp).c_str();
103 result << "_clear_value_" << (int) param.depthBufferClearValue.depthStencil.depth;
104
105 if (param.depthClampEnable == VK_FALSE)
106 result << "_wc_" << (int) param.wc;
107
108 if (param.viewportDepthBoundsMode & TEST_MODE_VIEWPORT_DYNAMIC)
109 result << "_dynamic";
110 result << "_viewport_min_" << (int)param.viewportMinDepth << "_max_" << (int)param.viewportMaxDepth;
111
112 if (param.depthBoundsTestEnable)
113 {
114 if (param.viewportDepthBoundsMode & TEST_MODE_DEPTH_BOUNDS_DYNAMIC)
115 result << "_dynamic";
116 result << "_boundstest_min" << (int)param.minDepthBounds << "_max_" << (int)param.maxDepthBounds;
117 }
118
119 return result.str();
120 }
121
isSupportedDepthStencilFormat(const InstanceInterface & instanceInterface,VkPhysicalDevice device,VkFormat format)122 deBool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
123 {
124 VkFormatProperties formatProps;
125
126 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
127
128 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0u;
129 }
130
isFloatingPointDepthFormat(VkFormat format)131 deBool isFloatingPointDepthFormat (VkFormat format)
132 {
133 switch (format)
134 {
135 case VK_FORMAT_D32_SFLOAT:
136 case VK_FORMAT_D32_SFLOAT_S8_UINT:
137 return DE_TRUE;
138 case VK_FORMAT_D24_UNORM_S8_UINT:
139 case VK_FORMAT_D16_UNORM_S8_UINT:
140 case VK_FORMAT_D16_UNORM:
141 return DE_FALSE;
142 default:
143 DE_FATAL("No depth format");
144 }
145 return DE_FALSE;
146 }
147
depthFormatHasStencilComponent(VkFormat format)148 deBool depthFormatHasStencilComponent (VkFormat format)
149 {
150 switch (format)
151 {
152 case VK_FORMAT_D32_SFLOAT_S8_UINT:
153 case VK_FORMAT_D24_UNORM_S8_UINT:
154 case VK_FORMAT_D16_UNORM_S8_UINT:
155 return DE_TRUE;
156 case VK_FORMAT_D32_SFLOAT:
157 case VK_FORMAT_D16_UNORM:
158 return DE_FALSE;
159 default:
160 DE_FATAL("No depth format");
161 }
162 return DE_FALSE;
163 }
164
compareDepthResult(VkCompareOp compare,float depth,float clearValue)165 deBool compareDepthResult (VkCompareOp compare, float depth, float clearValue)
166 {
167 deBool result = DE_FALSE;
168
169 DE_ASSERT(compare <= VK_COMPARE_OP_ALWAYS && compare >= VK_COMPARE_OP_NEVER);
170
171 switch (compare)
172 {
173 case VK_COMPARE_OP_ALWAYS:
174 result = DE_TRUE;
175 break;
176 case VK_COMPARE_OP_NEVER:
177 result = DE_FALSE;
178 break;
179 case VK_COMPARE_OP_EQUAL:
180 result = depth == clearValue;
181 break;
182 case VK_COMPARE_OP_NOT_EQUAL:
183 result = depth != clearValue;
184 break;
185 case VK_COMPARE_OP_GREATER:
186 result = depth > clearValue;
187 break;
188 case VK_COMPARE_OP_GREATER_OR_EQUAL:
189 result = depth >= clearValue;
190 break;
191 case VK_COMPARE_OP_LESS:
192 result = depth < clearValue;
193 break;
194 case VK_COMPARE_OP_LESS_OR_EQUAL:
195 result = depth <= clearValue;
196 break;
197 default:
198 result = false;
199 break;
200 }
201 return result;
202 }
203
createPoints(float wc)204 static inline std::vector<Vertex4RGBA> createPoints (float wc)
205 {
206 using tcu::Vec2;
207 using tcu::Vec4;
208
209 std::vector<Vertex4RGBA> vertices;
210
211 // Vertices are in the following positions of the image:
212 //
213 // ----------------------------------
214 // | |
215 // | |
216 // | 5 6 |
217 // | |
218 // | 1 2 |
219 // | |
220 // | |
221 // | 3 0 |
222 // | |
223 // | 7 4 |
224 // | |
225 // | |
226 // ----------------------------------
227 //
228 // Vertex Depth Color
229 // 0 0.0 white
230 // 1 0.25 magenta
231 // 2 -2.0 yellow
232 // 3 2.0 red
233 // 4 -5.0 black
234 // 5 5.0 cyan
235 // 6 10.0 blue
236 // 7 -10.0 green
237 // Depth values are constant, they don't depend on wc.
238 const Vertex4RGBA vertex0 =
239 {
240 Vec4(0.25f * wc, 0.25f * wc, 0.0f, wc),
241 Vec4(1.0f, 1.0f, 1.0f, 1.0)
242 };
243 const Vertex4RGBA vertex1 =
244 {
245 Vec4(-0.25f * wc, -0.25f * wc, 0.25f, wc),
246 Vec4(1.0f, 0.0f, 1.0f, 1.0)
247 };
248 const Vertex4RGBA vertex2 =
249 {
250 Vec4(0.25f * wc, -0.25f * wc, -2.0f, wc),
251 Vec4(1.0f, 1.0f, 0.0f, 1.0)
252 };
253 const Vertex4RGBA vertex3 =
254 {
255 Vec4(-0.25f * wc, 0.25f * wc, 2.0f, wc),
256 Vec4(1.0f, 0.0f, 0.0f, 1.0)
257 };
258 const Vertex4RGBA vertex4 =
259 {
260 Vec4(0.5f * wc, 0.5f * wc, -5.0f, wc),
261 Vec4(0.0f, 0.0f, 0.0f, 1.0)
262 };
263 const Vertex4RGBA vertex5 =
264 {
265 Vec4(-0.5f * wc, -0.5f * wc, 5.0f, wc),
266 Vec4(0.0f, 1.0f, 1.0f, 1.0)
267 };
268 const Vertex4RGBA vertex6 =
269 {
270 Vec4(0.5f * wc, -0.5f * wc, 10.0f, wc),
271 Vec4(0.0f, 0.0f, 1.0f, 1.0)
272 };
273
274 const Vertex4RGBA vertex7 =
275 {
276 Vec4(-0.5f * wc, 0.5f * wc, -10.0f, wc),
277 Vec4(0.0f, 1.0f, 0.0f, 1.0)
278 };
279
280 vertices.push_back(vertex0);
281 vertices.push_back(vertex1);
282 vertices.push_back(vertex2);
283 vertices.push_back(vertex3);
284 vertices.push_back(vertex4);
285 vertices.push_back(vertex5);
286 vertices.push_back(vertex6);
287 vertices.push_back(vertex7);
288
289 return vertices;
290 }
291
292 template <class Test>
newTestCase(tcu::TestContext & testContext,const DepthRangeUnrestrictedParam testParam)293 vkt::TestCase* newTestCase (tcu::TestContext& testContext,
294 const DepthRangeUnrestrictedParam testParam)
295 {
296 return new Test(testContext,
297 generateTestName(testParam).c_str(),
298 testParam);
299 }
300
createBufferAndBindMemory(Context & context,VkDeviceSize size,VkBufferUsageFlags usage,de::MovePtr<Allocation> * pAlloc)301 Move<VkBuffer> createBufferAndBindMemory (Context& context, VkDeviceSize size, VkBufferUsageFlags usage, de::MovePtr<Allocation>* pAlloc)
302 {
303 const DeviceInterface& vk = context.getDeviceInterface();
304 const VkDevice vkDevice = context.getDevice();
305 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
306
307 const VkBufferCreateInfo vertexBufferParams =
308 {
309 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
310 DE_NULL, // const void* pNext;
311 0u, // VkBufferCreateFlags flags;
312 size, // VkDeviceSize size;
313 usage, // VkBufferUsageFlags usage;
314 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
315 1u, // deUint32 queueFamilyCount;
316 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
317 };
318
319 Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
320
321 *pAlloc = context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
322 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));
323
324 return vertexBuffer;
325 }
326
createImage2DAndBindMemory(Context & context,VkFormat format,deUint32 width,deUint32 height,VkImageUsageFlags usage,VkSampleCountFlagBits sampleCount,de::details::MovePtr<Allocation> * pAlloc)327 Move<VkImage> createImage2DAndBindMemory (Context& context,
328 VkFormat format,
329 deUint32 width,
330 deUint32 height,
331 VkImageUsageFlags usage,
332 VkSampleCountFlagBits sampleCount,
333 de::details::MovePtr<Allocation>* pAlloc)
334 {
335 const DeviceInterface& vk = context.getDeviceInterface();
336 const VkDevice vkDevice = context.getDevice();
337 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
338
339 const VkImageCreateInfo colorImageParams =
340 {
341 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
342 DE_NULL, // const void* pNext;
343 0u, // VkImageCreateFlags flags;
344 VK_IMAGE_TYPE_2D, // VkImageType imageType;
345 format, // VkFormat format;
346 { width, height, 1u }, // VkExtent3D extent;
347 1u, // deUint32 mipLevels;
348 1u, // deUint32 arraySize;
349 sampleCount, // deUint32 samples;
350 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
351 usage, // VkImageUsageFlags usage;
352 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
353 1u, // deUint32 queueFamilyCount;
354 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
355 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
356 };
357
358 Move<VkImage> image = createImage(vk, vkDevice, &colorImageParams);
359
360 *pAlloc = context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any);
361 VK_CHECK(vk.bindImageMemory(vkDevice, *image, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));
362
363 return image;
364 }
makeRenderPass(const DeviceInterface & vk,const VkDevice device,const PipelineConstructionType pipelineConstructionType,const VkFormat colorFormat,const VkFormat depthStencilFormat,const VkAttachmentLoadOp loadOperationColor,const VkAttachmentLoadOp loadOperationDepthStencil)365 RenderPassWrapper makeRenderPass (const DeviceInterface& vk,
366 const VkDevice device,
367 const PipelineConstructionType pipelineConstructionType,
368 const VkFormat colorFormat,
369 const VkFormat depthStencilFormat,
370 const VkAttachmentLoadOp loadOperationColor,
371 const VkAttachmentLoadOp loadOperationDepthStencil)
372 {
373 const bool hasColor = colorFormat != VK_FORMAT_UNDEFINED;
374 const bool hasDepthStencil = depthStencilFormat != VK_FORMAT_UNDEFINED;
375 const VkImageLayout initialLayoutColor = loadOperationColor == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
376 const VkImageLayout initialLayoutDepthStencil = loadOperationDepthStencil == VK_ATTACHMENT_LOAD_OP_LOAD ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
377
378 const VkAttachmentDescription colorAttachmentDescription =
379 {
380 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
381 colorFormat, // VkFormat format
382 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
383 loadOperationColor, // VkAttachmentLoadOp loadOp
384 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
385 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
386 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
387 initialLayoutColor, // VkImageLayout initialLayout
388 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
389 };
390
391 const VkAttachmentDescription depthStencilAttachmentDescription =
392 {
393 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
394 depthStencilFormat, // VkFormat format
395 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
396 loadOperationDepthStencil, // VkAttachmentLoadOp loadOp
397 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
398 loadOperationDepthStencil, // VkAttachmentLoadOp stencilLoadOp
399 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp
400 initialLayoutDepthStencil, // VkImageLayout initialLayout
401 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
402 };
403
404 std::vector<VkAttachmentDescription> attachmentDescriptions;
405
406 if (hasColor)
407 attachmentDescriptions.push_back(colorAttachmentDescription);
408 if (hasDepthStencil)
409 attachmentDescriptions.push_back(depthStencilAttachmentDescription);
410
411 const VkAttachmentReference colorAttachmentRef =
412 {
413 0u, // deUint32 attachment
414 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
415 };
416
417 const VkAttachmentReference depthStencilAttachmentRef =
418 {
419 hasColor ? 1u : 0u, // deUint32 attachment
420 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout
421 };
422
423 const VkSubpassDescription subpassDescription =
424 {
425 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
426 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
427 0u, // deUint32 inputAttachmentCount
428 DE_NULL, // const VkAttachmentReference* pInputAttachments
429 hasColor ? 1u : 0u, // deUint32 colorAttachmentCount
430 hasColor ? &colorAttachmentRef : DE_NULL, // const VkAttachmentReference* pColorAttachments
431 DE_NULL, // const VkAttachmentReference* pResolveAttachments
432 hasDepthStencil ? &depthStencilAttachmentRef : DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment
433 0u, // deUint32 preserveAttachmentCount
434 DE_NULL // const deUint32* pPreserveAttachments
435 };
436
437 const VkRenderPassCreateInfo renderPassInfo =
438 {
439 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType
440 DE_NULL, // const void* pNext
441 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
442 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount
443 attachmentDescriptions.size() > 0 ? &attachmentDescriptions[0] : DE_NULL, // const VkAttachmentDescription* pAttachments
444 1u, // deUint32 subpassCount
445 &subpassDescription, // const VkSubpassDescription* pSubpasses
446 0u, // deUint32 dependencyCount
447 DE_NULL // const VkSubpassDependency* pDependencies
448 };
449
450 return RenderPassWrapper(pipelineConstructionType, vk, device, &renderPassInfo);
451 }
452
453 // Test Classes
454 class DepthRangeUnrestrictedTestInstance : public vkt::TestInstance
455 {
456 public:
457 DepthRangeUnrestrictedTestInstance (Context& context,
458 const DepthRangeUnrestrictedParam param);
459 virtual ~DepthRangeUnrestrictedTestInstance (void);
460 virtual tcu::TestStatus iterate (void);
461 protected:
462 void prepareRenderPass (RenderPassWrapper& renderPass, GraphicsPipelineWrapper& pipeline);
463 void prepareCommandBuffer (void);
464 void preparePipelineWrapper (GraphicsPipelineWrapper& gpw, VkRenderPass renderpass);
465 tcu::TestStatus verifyTestResult (void);
466 protected:
467 const DepthRangeUnrestrictedParam m_param;
468 deBool m_extensions;
469 const tcu::UVec2 m_renderSize;
470 const VkFormat m_colorFormat;
471 PipelineLayoutWrapper m_pipelineLayout;
472
473 Move<VkImage> m_depthImage;
474 de::MovePtr<Allocation> m_depthImageAlloc;
475 de::MovePtr<Allocation> m_colorImageAlloc;
476 Move<VkImageView> m_depthAttachmentView;
477 VkImageMemoryBarrier m_imageLayoutBarriers[2];
478
479 Move<VkBuffer> m_vertexBuffer;
480 de::MovePtr<Allocation> m_vertexBufferMemory;
481 std::vector<Vertex4RGBA> m_vertices;
482
483 RenderPassWrapper m_renderPass;
484 Move<VkCommandPool> m_cmdPool;
485 Move<VkCommandBuffer> m_cmdBuffer;
486 Move<VkImage> m_colorImage;
487 Move<VkImageView> m_colorAttachmentView;
488 GraphicsPipelineWrapper m_pipeline;
489
490 ShaderWrapper m_vertModule;
491 ShaderWrapper m_fragModule;
492 };
493
preparePipelineWrapper(GraphicsPipelineWrapper & gpw,VkRenderPass renderpass)494 void DepthRangeUnrestrictedTestInstance::preparePipelineWrapper (GraphicsPipelineWrapper& gpw, VkRenderPass renderpass)
495 {
496 // Create pipeline
497 const VkVertexInputBindingDescription vertexInputBindingDescription
498 {
499 0u, // deUint32 binding;
500 sizeof(Vertex4RGBA), // deUint32 strideInBytes;
501 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
502 };
503
504 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2]
505 {
506 {
507 0u, // deUint32 location;
508 0u, // deUint32 binding;
509 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
510 0u // deUint32 offsetInBytes;
511 },
512 {
513 1u, // deUint32 location;
514 0u, // deUint32 binding;
515 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
516 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offsetInBytes;
517 }
518 };
519
520 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams
521 {
522 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
523 DE_NULL, // const void* pNext;
524 0u, // VkPipelineVertexInputStateCreateFlags flags;
525 1u, // deUint32 vertexBindingDescriptionCount;
526 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
527 2u, // deUint32 vertexAttributeDescriptionCount;
528 vertexInputAttributeDescriptions, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
529 };
530
531 const std::vector<VkRect2D> scissor { makeRect2D(m_renderSize) };
532 std::vector<VkViewport> viewport { makeViewport(m_renderSize) };
533
534 if (!(m_param.viewportDepthBoundsMode & TEST_MODE_VIEWPORT_DYNAMIC))
535 {
536 viewport[0].minDepth = m_param.viewportMinDepth;
537 viewport[0].maxDepth = m_param.viewportMaxDepth;
538 }
539
540 const VkPipelineRasterizationStateCreateInfo rasterStateParams
541 {
542 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
543 DE_NULL, // const void* pNext;
544 0u, // VkPipelineRasterizationStateCreateFlags flags;
545 m_param.depthClampEnable, // VkBool32 depthClampEnable;
546 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
547 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
548 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
549 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
550 VK_FALSE, // VkBool32 depthBiasEnable;
551 0.0f, // float depthBiasConstantFactor;
552 0.0f, // float depthBiasClamp;
553 0.0f, // float depthBiasSlopeFactor;
554 1.0f, // float lineWidth;
555 };
556
557 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
558 {
559 VK_FALSE, // VkBool32 blendEnable;
560 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
561 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
562 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
563 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
564 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
565 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
566 VK_COLOR_COMPONENT_R_BIT |
567 VK_COLOR_COMPONENT_G_BIT |
568 VK_COLOR_COMPONENT_B_BIT |
569 VK_COLOR_COMPONENT_A_BIT // VkColorComponentFlags colorWriteMask;
570 };
571
572 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
573 {
574 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
575 DE_NULL, // const void* pNext;
576 0u, // VkPipelineColorBlendStateCreateFlags flags;
577 VK_FALSE, // VkBool32 logicOpEnable;
578 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
579 1u, // deUint32 attachmentCount;
580 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
581 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
582 };
583
584 float minDepthBounds = m_param.minDepthBounds;
585 float maxDepthBounds = m_param.maxDepthBounds;
586
587 if (m_param.viewportDepthBoundsMode & TEST_MODE_DEPTH_BOUNDS_DYNAMIC)
588 {
589 minDepthBounds = 0.0f;
590 maxDepthBounds = 1.0f;
591 }
592
593 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
594 {
595 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
596 DE_NULL, // const void* pNext;
597 0u, // VkPipelineDepthStencilStateCreateFlags flags;
598 VK_TRUE, // VkBool32 depthTestEnable;
599 VK_TRUE, // VkBool32 depthWriteEnable;
600 m_param.depthCompareOp, // VkCompareOp depthCompareOp;
601 m_param.depthBoundsTestEnable, // VkBool32 depthBoundsTestEnable;
602 VK_FALSE, // VkBool32 stencilTestEnable;
603 // VkStencilOpState front;
604 {
605 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
606 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
607 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
608 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
609 0u, // deUint32 compareMask;
610 0u, // deUint32 writeMask;
611 0u, // deUint32 reference;
612 },
613 // VkStencilOpState back;
614 {
615 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
616 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
617 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
618 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
619 0u, // deUint32 compareMask;
620 0u, // deUint32 writeMask;
621 0u, // deUint32 reference;
622 },
623 minDepthBounds, // float minDepthBounds;
624 maxDepthBounds, // float maxDepthBounds;
625 };
626
627 std::vector<VkDynamicState> dynamicStates;
628 if (m_param.viewportDepthBoundsMode & TEST_MODE_VIEWPORT_DYNAMIC)
629 dynamicStates.push_back(VK_DYNAMIC_STATE_VIEWPORT);
630 if (m_param.viewportDepthBoundsMode & TEST_MODE_DEPTH_BOUNDS_DYNAMIC)
631 dynamicStates.push_back(VK_DYNAMIC_STATE_DEPTH_BOUNDS);
632
633 const VkPipelineDynamicStateCreateInfo dynamicStateParams =
634 {
635 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
636 DE_NULL, // const void* pNext;
637 (VkPipelineDynamicStateCreateFlags)0u, // VkPipelineDynamicStateCreateFlags flags;
638 (deUint32)dynamicStates.size(), // deUint32 dynamicStateCount;
639 (const VkDynamicState*)dynamicStates.data() // const VkDynamicState* pDynamicStates;
640 };
641
642 gpw.setDefaultTopology(VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
643 .setDefaultMultisampleState()
644 .setDynamicState(&dynamicStateParams)
645 .setupVertexInputState(&vertexInputStateParams)
646 .setupPreRasterizationShaderState(viewport,
647 scissor,
648 m_pipelineLayout,
649 renderpass,
650 0u,
651 m_vertModule,
652 &rasterStateParams)
653 .setupFragmentShaderState(m_pipelineLayout, renderpass, 0u, m_fragModule, &depthStencilStateParams)
654 .setupFragmentOutputState(renderpass, 0u, &colorBlendStateParams)
655 .setMonolithicPipelineLayout(m_pipelineLayout)
656 .buildPipeline();
657 }
658
prepareRenderPass(RenderPassWrapper & renderPass,GraphicsPipelineWrapper & pipeline)659 void DepthRangeUnrestrictedTestInstance::prepareRenderPass (RenderPassWrapper& renderPass, GraphicsPipelineWrapper& pipeline)
660 {
661 const DeviceInterface& vk = m_context.getDeviceInterface();
662
663 const VkClearValue attachmentClearValues[2] =
664 {
665 defaultClearValue(m_colorFormat),
666 m_param.depthBufferClearValue,
667 };
668
669 renderPass.begin(vk, *m_cmdBuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), 2u, attachmentClearValues);
670
671 pipeline.bind(*m_cmdBuffer);
672 VkDeviceSize offsets = 0u;
673 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
674
675 if (m_param.viewportDepthBoundsMode & TEST_MODE_VIEWPORT_DYNAMIC)
676 {
677 VkViewport viewport = makeViewport(m_renderSize);
678 viewport.minDepth = m_param.viewportMinDepth;
679 viewport.maxDepth = m_param.viewportMaxDepth;
680 if (vk::isConstructionTypeShaderObject(m_param.pipelineConstructionType))
681 {
682 #ifndef CTS_USES_VULKANSC
683 vk.cmdSetViewportWithCount(*m_cmdBuffer, 1u, &viewport);
684 #else
685 vk.cmdSetViewportWithCountEXT(*m_cmdBuffer, 1u, &viewport);
686 #endif
687 }
688 else
689 {
690 vk.cmdSetViewport(*m_cmdBuffer, 0u, 1u, &viewport);
691 }
692 }
693
694 if (m_param.viewportDepthBoundsMode & TEST_MODE_DEPTH_BOUNDS_DYNAMIC)
695 vk.cmdSetDepthBounds(*m_cmdBuffer, m_param.minDepthBounds, m_param.maxDepthBounds);
696
697 if (!m_vertices.empty() && !m_param.testClearValueOnly)
698 vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1u, 0u, 0u);
699
700 renderPass.end(vk, *m_cmdBuffer);
701 }
702
prepareCommandBuffer(void)703 void DepthRangeUnrestrictedTestInstance::prepareCommandBuffer (void)
704 {
705 const DeviceInterface& vk = m_context.getDeviceInterface();
706
707 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
708
709 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
710 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(m_imageLayoutBarriers), m_imageLayoutBarriers);
711
712 prepareRenderPass(m_renderPass, m_pipeline);
713
714 endCommandBuffer(vk, *m_cmdBuffer);
715 }
716
DepthRangeUnrestrictedTestInstance(Context & context,const DepthRangeUnrestrictedParam param)717 DepthRangeUnrestrictedTestInstance::DepthRangeUnrestrictedTestInstance (Context& context,
718 const DepthRangeUnrestrictedParam param)
719 : TestInstance (context)
720 , m_param (param)
721 , m_extensions (m_context.requireDeviceFunctionality("VK_EXT_depth_range_unrestricted"))
722 , m_renderSize (tcu::UVec2(32,32))
723 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
724 , m_pipeline (m_context.getInstanceInterface(), m_context.getDeviceInterface(), m_context.getPhysicalDevice(), m_context.getDevice(), m_context.getDeviceExtensions(), param.pipelineConstructionType)
725 {
726 const DeviceInterface& vk = m_context.getDeviceInterface();
727 const VkDevice vkDevice = m_context.getDevice();
728 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
729
730 if (!isSupportedDepthStencilFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), param.depthFormat))
731 {
732 throw tcu::NotSupportedError("Unsupported depth format");
733 }
734
735 VkPhysicalDeviceFeatures features = m_context.getDeviceFeatures();
736 if (param.depthClampEnable && features.depthClamp == DE_FALSE)
737 {
738 throw tcu::NotSupportedError("Unsupported feature: depthClamp");
739 }
740
741 if (param.depthBoundsTestEnable && features.depthBounds == DE_FALSE)
742 {
743 throw tcu::NotSupportedError("Unsupported feature: depthBounds");
744 }
745
746 // Create vertex buffer
747 {
748 m_vertexBuffer = createBufferAndBindMemory(m_context, 1024u, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &m_vertexBufferMemory);
749 m_vertices = createPoints(m_param.wc);
750 // Load vertices into vertex buffer
751 deMemcpy(m_vertexBufferMemory->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
752 flushAlloc(vk, vkDevice, *m_vertexBufferMemory);
753 }
754
755 // Create render pass
756 m_renderPass = makeRenderPass(vk, vkDevice, m_param.pipelineConstructionType, m_colorFormat, m_param.depthFormat, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR);
757
758 const VkComponentMapping ComponentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
759 // Create color image
760 {
761 m_colorImage = createImage2DAndBindMemory(m_context,
762 m_colorFormat,
763 m_renderSize.x(),
764 m_renderSize.y(),
765 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
766 VK_SAMPLE_COUNT_1_BIT,
767 &m_colorImageAlloc);
768 }
769
770 // Create depth image
771 {
772 m_depthImage = createImage2DAndBindMemory(m_context,
773 m_param.depthFormat,
774 m_renderSize.x(),
775 m_renderSize.y(),
776 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
777 VK_SAMPLE_COUNT_1_BIT,
778 &m_depthImageAlloc);
779 }
780
781 deUint32 depthAspectBits = VK_IMAGE_ASPECT_DEPTH_BIT;
782 if (depthFormatHasStencilComponent(param.depthFormat))
783 depthAspectBits |= VK_IMAGE_ASPECT_STENCIL_BIT;
784
785 // Set up image layout transition barriers
786 {
787 VkImageMemoryBarrier colorImageBarrier =
788 {
789 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
790 DE_NULL, // const void* pNext;
791 0u, // VkAccessFlags srcAccessMask;
792 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
793 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
794 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
795 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
796 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
797 *m_colorImage, // VkImage image;
798 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
799 };
800
801 m_imageLayoutBarriers[0] = colorImageBarrier;
802
803 VkImageMemoryBarrier depthImageBarrier =
804 {
805 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
806 DE_NULL, // const void* pNext;
807 0u, // VkAccessFlags srcAccessMask;
808 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
809 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
810 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
811 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
812 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
813 *m_depthImage, // VkImage image;
814 { depthAspectBits, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
815 };
816
817 m_imageLayoutBarriers[1] = depthImageBarrier;
818 }
819 // Create color attachment view
820 {
821 VkImageViewCreateInfo colorAttachmentViewParams =
822 {
823 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
824 DE_NULL, // const void* pNext;
825 0u, // VkImageViewCreateFlags flags;
826 *m_colorImage, // VkImage image;
827 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
828 m_colorFormat, // VkFormat format;
829 ComponentMappingRGBA, // VkComponentMapping components;
830 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
831 };
832
833 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
834 }
835
836 // Create depth attachment view
837 {
838 const VkImageViewCreateInfo depthAttachmentViewParams =
839 {
840 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
841 DE_NULL, // const void* pNext;
842 0u, // VkImageViewCreateFlags flags;
843 *m_depthImage, // VkImage image;
844 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
845 m_param.depthFormat, // VkFormat format;
846 ComponentMappingRGBA, // VkComponentMapping components;
847 { depthAspectBits, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
848 };
849
850 m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
851 }
852
853 // Create framebuffer
854 {
855 std::vector<VkImage> images = {
856 *m_colorImage,
857 *m_depthImage,
858 };
859 VkImageView attachmentBindInfos[2] =
860 {
861 *m_colorAttachmentView,
862 *m_depthAttachmentView,
863 };
864
865 const VkFramebufferCreateInfo framebufferParams =
866 {
867 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
868 DE_NULL, // const void* pNext;
869 0u, // VkFramebufferCreateFlags flags;
870 *m_renderPass, // VkRenderPass renderPass;
871 2u, // deUint32 attachmentCount;
872 attachmentBindInfos, // const VkImageView* pAttachments;
873 (deUint32)m_renderSize.x(), // deUint32 width;
874 (deUint32)m_renderSize.y(), // deUint32 height;
875 1u, // deUint32 layers;
876 };
877
878 m_renderPass.createFramebuffer(vk, vkDevice, &framebufferParams, images);
879 }
880
881 // Create shader modules
882 m_vertModule = ShaderWrapper(vk, vkDevice, context.getBinaryCollection().get("vert"), 0);
883 m_fragModule = ShaderWrapper(vk, vkDevice, context.getBinaryCollection().get("frag"), 0);
884
885 // Create pipeline layout
886 {
887 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
888 {
889 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
890 DE_NULL, // const void* pNext;
891 0u, // VkPipelineLayoutCreateFlags flags;
892 0u, // deUint32 setLayoutCount;
893 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
894 0u, // deUint32 pushConstantRangeCount;
895 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
896 };
897
898 m_pipelineLayout = PipelineLayoutWrapper(m_param.pipelineConstructionType, vk, vkDevice, &pipelineLayoutParams);
899 }
900
901 // Create pipeline
902 preparePipelineWrapper(m_pipeline, *m_renderPass);
903
904 // Create command pool
905 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
906
907 // Create command buffer
908 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
909 }
910
~DepthRangeUnrestrictedTestInstance(void)911 DepthRangeUnrestrictedTestInstance::~DepthRangeUnrestrictedTestInstance (void)
912 {
913 }
914
iterate(void)915 tcu::TestStatus DepthRangeUnrestrictedTestInstance::iterate (void)
916 {
917 const DeviceInterface& vk = m_context.getDeviceInterface();
918 const VkDevice vkDevice = m_context.getDevice();
919 const VkQueue queue = m_context.getUniversalQueue();
920
921 prepareCommandBuffer();
922
923 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
924 return verifyTestResult();
925 }
926
verifyTestResult(void)927 tcu::TestStatus DepthRangeUnrestrictedTestInstance::verifyTestResult (void)
928 {
929 deBool compareOk = DE_TRUE;
930 const DeviceInterface& vk = m_context.getDeviceInterface();
931 const VkDevice vkDevice = m_context.getDevice();
932 const VkQueue queue = m_context.getUniversalQueue();
933 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
934 tcu::TestLog& log = m_context.getTestContext().getLog();
935 Allocator& allocator = m_context.getDefaultAllocator();
936 tcu::TextureLevel refImage (vk::mapVkFormat(m_colorFormat), 32, 32);
937 float clearValue = m_param.depthBufferClearValue.depthStencil.depth;
938 double epsilon = 1e-5;
939
940 // For non-float depth formats, the value in the depth buffer is already clampled to the range [0, 1], which
941 // includes the clear depth value.
942 if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
943 clearValue = de::min(de::max(clearValue, 0.0f), 1.0f);
944
945 // Generate reference image
946 {
947 VkClearValue clearColor = defaultClearValue(m_colorFormat);
948 tcu::Vec4 clearColorVec4 (clearColor.color.float32[0], clearColor.color.float32[1],
949 clearColor.color.float32[2], clearColor.color.float32[3]);
950
951 tcu::clear(refImage.getAccess(), clearColorVec4);
952 for (std::vector<Vertex4RGBA>::const_iterator vertex = m_vertices.begin(); vertex != m_vertices.end(); ++vertex)
953 {
954 if (m_param.depthClampEnable == VK_FALSE && (vertex->position.z() < 0.0f || vertex->position.z() > vertex->position.w()))
955 continue;
956
957 if (m_param.testClearValueOnly)
958 continue;
959
960 // Depth Clamp is enabled, then we clamp point depth to viewport's maxDepth and minDepth values, or [0.0f, 1.0f] is depth format is fixed-point.
961 float scaling = ((vertex->position.z() / vertex->position.w()) * (m_param.viewportMaxDepth - m_param.viewportMinDepth)) + m_param.viewportMinDepth;
962 float depth = de::min(de::max(scaling, m_param.viewportMinDepth), m_param.viewportMaxDepth);
963
964 // For non-float depth formats, depth value is clampled to the range [0, 1].
965 if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
966 depth = de::min(de::max(depth, 0.0f), 1.0f);
967
968 if (compareDepthResult(m_param.depthCompareOp, depth, clearValue))
969 {
970 deInt32 x = static_cast<deInt32>((((vertex->position.x() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.x() - 1));
971 deInt32 y = static_cast<deInt32>((((vertex->position.y() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.y() - 1));
972 refImage.getAccess().setPixel(vertex->color, x, y);
973 }
974 }
975 }
976
977 // Check the rendered image
978 {
979 de::MovePtr<tcu::TextureLevel> result = vkt::pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
980
981 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
982 "IntImageCompare",
983 "Image comparison",
984 refImage.getAccess(),
985 result->getAccess(),
986 tcu::UVec4(2, 2, 2, 2),
987 tcu::IVec3(1, 1, 0),
988 true,
989 tcu::COMPARE_LOG_RESULT);
990 #ifdef CTS_USES_VULKANSC
991 if (m_context.getTestContext().getCommandLine().isSubProcess())
992 #endif // CTS_USES_VULKANSC
993 {
994 if (!compareOk)
995 return tcu::TestStatus::fail("Image mismatch");
996 }
997 }
998
999 // Check depth buffer contents
1000 {
1001 de::MovePtr<tcu::TextureLevel> depthResult = readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, m_param.depthFormat, m_renderSize);
1002
1003 if (m_param.testClearValueOnly) {
1004 compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
1005 "DepthImagecompare",
1006 "Depth image comparison",
1007 tcu::Vec4(clearValue, 0.0f, 0.0f, 1.0f),
1008 depthResult->getAccess(),
1009 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
1010 tcu::COMPARE_LOG_RESULT);
1011 if (!compareOk)
1012 return tcu::TestStatus::fail("Depth buffer mismatch");
1013 else
1014 return tcu::TestStatus::pass("Result images matches references");
1015 }
1016
1017 log << tcu::TestLog::Message;
1018 for (std::vector<Vertex4RGBA>::const_iterator vertex = m_vertices.begin(); vertex != m_vertices.end(); ++vertex)
1019 {
1020 deInt32 x = static_cast<deInt32>((((vertex->position.x() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.x() - 1));
1021 deInt32 y = static_cast<deInt32>((((vertex->position.y() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.y() - 1));
1022 tcu::Vec4 depth = depthResult->getAccess().getPixel(x, y);
1023
1024 // Check depth values are valid
1025 if (depth.y() != 0.0f || depth.z() != 0.0f || depth.w() != 1.0f)
1026 {
1027 log << tcu::TestLog::Message << "Invalid depth buffer values for pixel (" << x << ", " << y << ") = ("
1028 << depth.x() << ", " << depth.y() << ", " << depth.z() << ", " << depth.w() << "." << tcu::TestLog::EndMessage;
1029 compareOk = DE_FALSE;
1030 }
1031
1032 // Check the case where depth clamping is disabled.
1033 if (m_param.depthClampEnable == VK_FALSE)
1034 {
1035 if ((vertex->position.z() < 0.0f || vertex->position.z() > vertex->position.w()) &&
1036 fabs(clearValue - depth.x()) > epsilon)
1037 {
1038 log << tcu::TestLog::Message << "Error pixel (" << x << ", " << y << "). Depth value = " << depth
1039 << ", expected " << clearValue << "." << tcu::TestLog::EndMessage;
1040 compareOk = DE_FALSE;
1041 }
1042
1043 float expectedDepth = clearValue;
1044
1045 if (vertex->position.z() <= vertex->position.w() && vertex->position.z() >= 0.0f)
1046 {
1047 // Assert we have a symmetric range around zero.
1048 DE_ASSERT(m_param.viewportMinDepth == (-m_param.viewportMaxDepth));
1049
1050 // Calculate the expected depth value: first translate the value to from [0.0f, 1.0f] to [-1.0f, 1.0f].
1051 expectedDepth = 2 * (vertex->position.z() / vertex->position.w()) - 1.0f;
1052 // Now multiply by m_param.viewportMaxDepth to get the expected value.
1053 expectedDepth *= m_param.viewportMaxDepth;
1054 }
1055
1056 // For non-float depth formats, depth value is clampled to the range [0, 1].
1057 if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
1058 expectedDepth = de::min(de::max(expectedDepth, 0.0f), 1.0f);
1059
1060 expectedDepth = compareDepthResult(m_param.depthCompareOp, expectedDepth, clearValue) ? expectedDepth : clearValue;
1061
1062 if (fabs(expectedDepth - depth.x()) > epsilon)
1063 {
1064 log << tcu::TestLog::Message << "Error pixel (" << x << ", " << y
1065 << "). Depth value " << depth.x() << ", expected " << expectedDepth << ", error " << fabs(expectedDepth - depth.x()) << tcu::TestLog::EndMessage;
1066 compareOk = DE_FALSE;
1067 }
1068
1069 continue;
1070 }
1071
1072 // Depth Clamp is enabled, then we clamp point depth to viewport's maxDepth and minDepth values, or 0.0f and 1.0f is format is not float.
1073 float scaling = (vertex->position.z() / vertex->position.w()) * (m_param.viewportMaxDepth - m_param.viewportMinDepth) + m_param.viewportMinDepth;
1074 float expectedDepth = de::min(de::max(scaling, m_param.viewportMinDepth), m_param.viewportMaxDepth);
1075
1076 // For non-float depth formats, depth value is clampled to the range [0, 1].
1077 if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
1078 expectedDepth = de::min(de::max(expectedDepth, 0.0f), 1.0f);
1079
1080 expectedDepth = compareDepthResult(m_param.depthCompareOp, expectedDepth, clearValue) ? expectedDepth : clearValue;
1081
1082 if (fabs(expectedDepth - depth.x()) > epsilon)
1083 {
1084 log << tcu::TestLog::Message << "Error pixel (" << x << ", " << y
1085 << "). Depth value " << depth.x() << ", expected " << expectedDepth << ", error " << fabs(expectedDepth - depth.x()) << tcu::TestLog::EndMessage;
1086 compareOk = DE_FALSE;
1087 }
1088 }
1089 if (!compareOk)
1090 return tcu::TestStatus::fail("Depth buffer mismatch");
1091 }
1092
1093 return tcu::TestStatus::pass("Result images matches references");
1094 }
1095
1096 // Test Classes
1097 class DepthBoundsRangeUnrestrictedTestInstance : public DepthRangeUnrestrictedTestInstance
1098 {
1099 public:
1100 DepthBoundsRangeUnrestrictedTestInstance (Context& context,
1101 const DepthRangeUnrestrictedParam param);
1102 virtual ~DepthBoundsRangeUnrestrictedTestInstance (void);
1103 virtual tcu::TestStatus iterate (void);
1104
1105 protected:
1106 tcu::TestStatus verifyTestResult (bool firstDraw);
1107 void prepareCommandBuffer (bool firstDraw);
1108
1109 protected:
1110 RenderPassWrapper m_renderPassSecondDraw;
1111 GraphicsPipelineWrapper m_pipelineSecondDraw;
1112 std::vector<bool> m_vertexWasRendered;
1113
1114 };
1115
DepthBoundsRangeUnrestrictedTestInstance(Context & context,const DepthRangeUnrestrictedParam param)1116 DepthBoundsRangeUnrestrictedTestInstance::DepthBoundsRangeUnrestrictedTestInstance (Context& context,
1117 const DepthRangeUnrestrictedParam param)
1118 : DepthRangeUnrestrictedTestInstance(context, param)
1119 , m_pipelineSecondDraw (m_context.getInstanceInterface(), m_context.getDeviceInterface(), m_context.getPhysicalDevice(), m_context.getDevice(), m_context.getDeviceExtensions(), param.pipelineConstructionType)
1120 {
1121 const DeviceInterface& vk = m_context.getDeviceInterface();
1122 const VkDevice vkDevice = m_context.getDevice();
1123
1124 // Create render pass for second draw, we keep the first draw's contents of the depth buffer.
1125 m_renderPassSecondDraw = makeRenderPass(vk, vkDevice, param.pipelineConstructionType, m_colorFormat, m_param.depthFormat, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_LOAD);
1126
1127 // Create framebuffer for second draw.
1128 {
1129 std::vector<VkImage> images = {
1130 *m_colorImage,
1131 *m_depthImage,
1132 };
1133 VkImageView attachmentBindInfos[2] =
1134 {
1135 *m_colorAttachmentView,
1136 *m_depthAttachmentView,
1137 };
1138
1139 const VkFramebufferCreateInfo framebufferParams =
1140 {
1141 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1142 DE_NULL, // const void* pNext;
1143 0u, // VkFramebufferCreateFlags flags;
1144 *m_renderPassSecondDraw, // VkRenderPass renderPass;
1145 2u, // deUint32 attachmentCount;
1146 attachmentBindInfos, // const VkImageView* pAttachments;
1147 (deUint32)m_renderSize.x(), // deUint32 width;
1148 (deUint32)m_renderSize.y(), // deUint32 height;
1149 1u, // deUint32 layers;
1150 };
1151
1152 m_renderPassSecondDraw.createFramebuffer(vk, vkDevice, &framebufferParams, images);
1153 }
1154
1155 // Create pipeline
1156 preparePipelineWrapper(m_pipelineSecondDraw, *m_renderPassSecondDraw);
1157 }
1158
~DepthBoundsRangeUnrestrictedTestInstance(void)1159 DepthBoundsRangeUnrestrictedTestInstance::~DepthBoundsRangeUnrestrictedTestInstance (void)
1160 {
1161 }
1162
iterate(void)1163 tcu::TestStatus DepthBoundsRangeUnrestrictedTestInstance::iterate (void)
1164 {
1165 const DeviceInterface& vk = m_context.getDeviceInterface();
1166 const VkDevice vkDevice = m_context.getDevice();
1167 const VkQueue queue = m_context.getUniversalQueue();
1168
1169 // This test will draw the same scene two times.
1170 // First one will render the points depending on if the pass the depth test and if clear depth value passes the
1171 // depthBounds test.
1172 //
1173 // The second one, will render the same scene but the the point positions will have depth buffer values from
1174 // the first draw. If they pass the depth test, the depthBounds test will check the content of the depth buffer,
1175 // which is most cases, will make that the second result differs from the first one, hence the need to split
1176 // the verification in two steps.
1177 prepareCommandBuffer(true);
1178 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1179 tcu::TestStatus status = verifyTestResult(true);
1180
1181 #ifdef CTS_USES_VULKANSC
1182 if (m_context.getTestContext().getCommandLine().isSubProcess())
1183 #endif // CTS_USES_VULKANSC
1184 {
1185 if (status.getCode() != QP_TEST_RESULT_PASS)
1186 return status;
1187 }
1188
1189 prepareCommandBuffer(false);
1190 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1191 return verifyTestResult(false);
1192 }
1193
prepareCommandBuffer(bool firstDraw)1194 void DepthBoundsRangeUnrestrictedTestInstance::prepareCommandBuffer (bool firstDraw)
1195 {
1196 const DeviceInterface& vk = m_context.getDeviceInterface();
1197
1198 if (!firstDraw)
1199 {
1200 VK_CHECK(vk.resetCommandBuffer(*m_cmdBuffer, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT));
1201 // Color image layout changed after verifying the first draw call, restore it.
1202 m_imageLayoutBarriers[0].srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1203 m_imageLayoutBarriers[0].oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1204 // Depth image layout changed after verifying the first draw call, restore it.
1205 m_imageLayoutBarriers[1].srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1206 m_imageLayoutBarriers[1].oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1207 }
1208
1209 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1210
1211 vk.cmdPipelineBarrier(*m_cmdBuffer, (firstDraw ? VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT : VK_PIPELINE_STAGE_TRANSFER_BIT), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
1212 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(m_imageLayoutBarriers), m_imageLayoutBarriers);
1213
1214 prepareRenderPass((firstDraw ? m_renderPass : m_renderPassSecondDraw),
1215 (firstDraw ? m_pipeline : m_pipelineSecondDraw));
1216
1217 endCommandBuffer(vk, *m_cmdBuffer);
1218 }
1219
verifyTestResult(bool firstDraw)1220 tcu::TestStatus DepthBoundsRangeUnrestrictedTestInstance::verifyTestResult (bool firstDraw)
1221 {
1222 deBool compareOk = DE_TRUE;
1223 const DeviceInterface& vk = m_context.getDeviceInterface();
1224 const VkDevice vkDevice = m_context.getDevice();
1225 const VkQueue queue = m_context.getUniversalQueue();
1226 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1227 tcu::TestLog& log = m_context.getTestContext().getLog();
1228 Allocator& allocator = m_context.getDefaultAllocator();
1229 tcu::TextureLevel refImage (vk::mapVkFormat(m_colorFormat), 32, 32);
1230 float clearValue = m_param.depthBufferClearValue.depthStencil.depth;
1231 double epsilon = 1e-5;
1232
1233 // For non-float depth formats, depth value is clampled to the range [0, 1].
1234 if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
1235 clearValue = de::min(de::max(clearValue, 0.0f), 1.0f);
1236
1237 // Generate reference image
1238 {
1239 VkClearValue clearColor = defaultClearValue(m_colorFormat);
1240 tcu::Vec4 clearColorVec4 (clearColor.color.float32[0], clearColor.color.float32[1],
1241 clearColor.color.float32[2], clearColor.color.float32[3]);
1242 tcu::clear(refImage.getAccess(), clearColorVec4);
1243 for (std::vector<Vertex4RGBA>::const_iterator vertex = m_vertices.begin(); vertex != m_vertices.end(); ++vertex)
1244 {
1245 // Depth Clamp is enabled, then we clamp point depth to viewport's maxDepth and minDepth values and later check if it is inside depthBounds volume.
1246 float scaling = ((vertex->position.z() / vertex->position.w()) * (m_param.viewportMaxDepth - m_param.viewportMinDepth)) + m_param.viewportMinDepth;
1247 float depth = de::min(de::max(scaling, m_param.viewportMinDepth), m_param.viewportMaxDepth);
1248 if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
1249 depth = de::min(de::max(depth, 0.0f), 1.0f);
1250
1251 auto i = vertex - m_vertices.begin();
1252
1253 // Depending if the first draw call succeed, we need to know if the second draw call will render the points because the depth buffer content
1254 // will determine if it passes the depth test and the depth bounds test.
1255 bool firstDrawHasPassedDepthBoundsTest = !firstDraw && m_vertexWasRendered[i];
1256 float depthBufferValue = firstDrawHasPassedDepthBoundsTest ? depth : clearValue;
1257
1258 // For non-float depth formats, depth value is clampled to the range [0, 1].
1259 if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
1260 depthBufferValue = de::min(de::max(depthBufferValue, 0.0f), 1.0f);
1261
1262 // Check that the point passes the depth test and the depth bounds test.
1263 if (compareDepthResult(m_param.depthCompareOp, depth, depthBufferValue) &&
1264 depthBufferValue >= m_param.minDepthBounds && depthBufferValue <= m_param.maxDepthBounds)
1265 {
1266 deInt32 x = static_cast<deInt32>((((vertex->position.x() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.x() - 1));
1267 deInt32 y = static_cast<deInt32>((((vertex->position.y() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.y() - 1));
1268 refImage.getAccess().setPixel(vertex->color, x, y);
1269 if (firstDraw)
1270 m_vertexWasRendered.push_back(true);
1271 continue;
1272 }
1273
1274 if (firstDraw)
1275 m_vertexWasRendered.push_back(false);
1276 }
1277 }
1278
1279 // Check the rendered image
1280 {
1281 de::MovePtr<tcu::TextureLevel> result = vkt::pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
1282 std::string description = "Image comparison draw ";
1283 description += (firstDraw ? "1" : "2");
1284
1285 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
1286 "IntImageCompare",
1287 description.c_str(),
1288 refImage.getAccess(),
1289 result->getAccess(),
1290 tcu::UVec4(2, 2, 2, 2),
1291 tcu::IVec3(1, 1, 0),
1292 true,
1293 tcu::COMPARE_LOG_RESULT);
1294 #ifdef CTS_USES_VULKANSC
1295 if (m_context.getTestContext().getCommandLine().isSubProcess())
1296 #endif // CTS_USES_VULKANSC
1297 {
1298 if (!compareOk)
1299 return tcu::TestStatus::fail("Image mismatch");
1300 }
1301 }
1302
1303 // Check depth buffer contents
1304 {
1305 de::MovePtr<tcu::TextureLevel> depthResult = readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, m_param.depthFormat, m_renderSize);
1306
1307 log << tcu::TestLog::Message;
1308 for (std::vector<Vertex4RGBA>::const_iterator vertex = m_vertices.begin(); vertex != m_vertices.end(); ++vertex)
1309 {
1310 deInt32 x = static_cast<deInt32>((((vertex->position.x() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.x() - 1));
1311 deInt32 y = static_cast<deInt32>((((vertex->position.y() / vertex->position.w()) + 1.0f) / 2.0f) * static_cast<float>(m_renderSize.y() - 1));
1312 tcu::Vec4 depth = depthResult->getAccess().getPixel(x, y);
1313
1314 // Check depth values are valid
1315 if (depth.y() != 0.0f || depth.z() != 0.0f || depth.w() != 1.0f)
1316 {
1317 log << tcu::TestLog::Message << "Draw " << (firstDraw ? "1" : "2") << ": Invalid depth buffer values for pixel (" << x << ", " << y << ") = ("
1318 << depth.x() << ", " << depth.y() << ", " << depth.z() << ", " << depth.w() << "." << tcu::TestLog::EndMessage;
1319 compareOk = DE_FALSE;
1320 }
1321
1322 // Depth Clamp is enabled, so we clamp point depth to viewport's maxDepth and minDepth values, or 0.0f and 1.0f is format is not float.
1323 float scaling = (vertex->position.z() / vertex->position.w()) * (m_param.viewportMaxDepth - m_param.viewportMinDepth) + m_param.viewportMinDepth;
1324 float expectedDepth = de::min(de::max(scaling, m_param.viewportMinDepth), m_param.viewportMaxDepth);
1325
1326 auto i = vertex - m_vertices.begin();
1327
1328 // Depending if the first draw call succeed, we need to know if the second draw call will render the points because the depth buffer content
1329 // will determine if it passes the depth test and the depth bounds test.
1330 bool firstDrawHasPassedDepthBoundsTest = !firstDraw && m_vertexWasRendered[i];
1331
1332 // If we are in the first draw call, the depth buffer content is clearValue. If we are in the second draw call, it is going to be depth.x() if the first
1333 // succeeded.
1334 float depthBufferValue = firstDrawHasPassedDepthBoundsTest ? depth.x() : clearValue;
1335
1336 // For non-float depth formats, depth value is clampled to the range [0, 1].
1337 if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
1338 depthBufferValue = de::min(de::max(depthBufferValue, 0.0f), 1.0f);
1339
1340 // Calculate the expectd depth depending on the depth test and the depth bounds test results.
1341 expectedDepth =
1342 (compareDepthResult(m_param.depthCompareOp, expectedDepth, depthBufferValue) && depthBufferValue <= m_param.maxDepthBounds && depthBufferValue >= m_param.minDepthBounds)
1343 ? expectedDepth : depthBufferValue;
1344
1345 // For non-float depth formats, depth value is clampled to the range [0, 1].
1346 if (isFloatingPointDepthFormat(m_param.depthFormat) == VK_FALSE)
1347 expectedDepth = de::min(de::max(expectedDepth, 0.0f), 1.0f);
1348
1349 if (fabs(expectedDepth - depth.x()) > epsilon)
1350 {
1351 log << tcu::TestLog::Message << "Draw " << (firstDraw ? "1" : "2") << ": Error pixel (" << x << ", " << y
1352 << "). Depth value " << depth.x() << ", expected " << expectedDepth << ", error " << fabs(expectedDepth - depth.x()) << tcu::TestLog::EndMessage;
1353 compareOk = DE_FALSE;
1354 }
1355 }
1356
1357 if (!compareOk)
1358 return tcu::TestStatus::fail("Depth buffer mismatch");
1359 }
1360
1361 return tcu::TestStatus::pass("Result images matches references");
1362 }
1363
1364 class DepthRangeUnrestrictedTest : public vkt::TestCase
1365 {
1366 public:
DepthRangeUnrestrictedTest(tcu::TestContext & testContext,const std::string & name,const DepthRangeUnrestrictedParam param)1367 DepthRangeUnrestrictedTest (tcu::TestContext& testContext,
1368 const std::string& name,
1369 const DepthRangeUnrestrictedParam param)
1370 : vkt::TestCase (testContext, name)
1371 , m_param (param)
1372 { }
~DepthRangeUnrestrictedTest(void)1373 virtual ~DepthRangeUnrestrictedTest (void) { }
1374 virtual void initPrograms (SourceCollections& programCollection) const;
1375 virtual TestInstance* createInstance (Context& context) const;
1376 void checkSupport (Context& context) const;
1377
1378 protected:
1379 const DepthRangeUnrestrictedParam m_param;
1380 };
1381
initPrograms(SourceCollections & programCollection) const1382 void DepthRangeUnrestrictedTest::initPrograms (SourceCollections& programCollection) const
1383 {
1384 programCollection.glslSources.add("vert") << glu::VertexSource(
1385 "#version 310 es\n"
1386 "layout(location = 0) in vec4 position;\n"
1387 "layout(location = 1) in vec4 color;\n"
1388 "layout(location = 0) out highp vec4 vtxColor;\n"
1389 "void main (void)\n"
1390 "{\n"
1391 " gl_Position = position;\n"
1392 " gl_PointSize = 1.0f;\n"
1393 " vtxColor = color;\n"
1394
1395 "}\n");
1396
1397
1398 programCollection.glslSources.add("frag") << glu::FragmentSource(
1399 "#version 310 es\n"
1400 "layout(location = 0) in highp vec4 vtxColor;\n"
1401 "layout(location = 0) out highp vec4 fragColor;\n"
1402 "void main (void)\n"
1403 "{\n"
1404 " fragColor = vtxColor;\n"
1405 "}\n");
1406
1407 }
1408
createInstance(Context & context) const1409 TestInstance* DepthRangeUnrestrictedTest::createInstance (Context& context) const
1410 {
1411 if (m_param.depthBoundsTestEnable)
1412 return new DepthBoundsRangeUnrestrictedTestInstance(context, m_param);
1413 return new DepthRangeUnrestrictedTestInstance(context, m_param);
1414 }
1415
checkSupport(Context & context) const1416 void DepthRangeUnrestrictedTest::checkSupport(Context& context) const
1417 {
1418 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_param.pipelineConstructionType);
1419 }
1420 } // anonymous
1421
createDepthRangeUnrestrictedTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)1422 tcu::TestCaseGroup* createDepthRangeUnrestrictedTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
1423 {
1424 de::MovePtr<tcu::TestCaseGroup> depthTests (new tcu::TestCaseGroup(testCtx, "depth_range_unrestricted"));
1425 const VkFormat depthFormats[] =
1426 {
1427 VK_FORMAT_D32_SFLOAT,
1428 VK_FORMAT_D24_UNORM_S8_UINT,
1429 VK_FORMAT_D16_UNORM,
1430 };
1431
1432 const VkCompareOp compareOps[] =
1433 {
1434 VK_COMPARE_OP_GREATER,
1435 VK_COMPARE_OP_GREATER_OR_EQUAL,
1436 VK_COMPARE_OP_LESS,
1437 VK_COMPARE_OP_LESS_OR_EQUAL,
1438 };
1439
1440 float viewportValues[] = {2.0f, 6.0f, 12.0f};
1441 float depthBoundsValues[] = {2.0f, 4.0f, 8.0f};
1442 float wcValues[] = {2.0f, 6.0f, 12.0f};
1443 float clearValues[] = {2.0f, -3.0f, 6.0f, -7.0f};
1444
1445 // Depth clear values outside range [0.0f, 1.0f].
1446 {
1447 de::MovePtr<tcu::TestCaseGroup> depthClearValueTests (new tcu::TestCaseGroup(testCtx, "clear_value"));
1448 DepthRangeUnrestrictedParam testParams;
1449 testParams.pipelineConstructionType = pipelineConstructionType;
1450 testParams.testClearValueOnly = VK_TRUE;
1451 testParams.depthClampEnable = VK_FALSE;
1452 testParams.wc = 1.0f;
1453 testParams.viewportMinDepth = 0.0f;
1454 testParams.viewportMaxDepth = 1.0f;
1455 testParams.minDepthBounds = 0.0f;
1456 testParams.maxDepthBounds = 1.0f;
1457 testParams.depthBoundsTestEnable = VK_FALSE;
1458 testParams.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
1459 testParams.viewportDepthBoundsMode = TEST_MODE_VIEWPORT_DEPTH_BOUNDS_STATIC;
1460
1461 for (int format = 0; format < DE_LENGTH_OF_ARRAY(depthFormats); ++format)
1462 {
1463 testParams.depthFormat = depthFormats[format];
1464 testParams.depthBufferClearValue = defaultClearValue(depthFormats[format]);
1465 for (int val = 0; val < DE_LENGTH_OF_ARRAY(clearValues); val++)
1466 {
1467 testParams.depthBufferClearValue.depthStencil.depth = clearValues[val];
1468 depthClearValueTests->addChild(newTestCase<DepthRangeUnrestrictedTest>(testCtx, testParams));
1469 }
1470 }
1471 depthTests->addChild(depthClearValueTests.release());
1472 }
1473
1474 // Viewport's depth unrestricted range
1475 {
1476 de::MovePtr<tcu::TestCaseGroup> viewportTests (new tcu::TestCaseGroup(testCtx, "viewport"));
1477 DepthRangeUnrestrictedParam testParams;
1478 testParams.pipelineConstructionType = pipelineConstructionType;
1479 testParams.testClearValueOnly = VK_FALSE;
1480 testParams.wc = 1.0f;
1481 testParams.depthClampEnable = VK_TRUE;
1482 testParams.minDepthBounds = 0.0f;
1483 testParams.maxDepthBounds = 1.0f;
1484 testParams.depthBoundsTestEnable = VK_FALSE;
1485
1486 for (int format = 0; format < DE_LENGTH_OF_ARRAY(depthFormats); ++format)
1487 {
1488 testParams.depthFormat = depthFormats[format];
1489 testParams.depthBufferClearValue = defaultClearValue(testParams.depthFormat);
1490 for (int compareOp = 0; compareOp < DE_LENGTH_OF_ARRAY(compareOps); compareOp++)
1491 {
1492 testParams.depthCompareOp = compareOps[compareOp];
1493 for (int clearValue = 0; clearValue < DE_LENGTH_OF_ARRAY(clearValues); clearValue++)
1494 {
1495 testParams.depthBufferClearValue.depthStencil.depth = clearValues[clearValue];
1496 for (int viewportValue = 0; viewportValue < DE_LENGTH_OF_ARRAY(viewportValues); viewportValue++)
1497 {
1498 testParams.viewportMinDepth = -viewportValues[viewportValue];
1499 testParams.viewportMaxDepth = viewportValues[viewportValue];
1500 testParams.viewportDepthBoundsMode = TEST_MODE_VIEWPORT_DEPTH_BOUNDS_STATIC;
1501 viewportTests->addChild(newTestCase<DepthRangeUnrestrictedTest>(testCtx, testParams));
1502 testParams.viewportDepthBoundsMode = TEST_MODE_VIEWPORT_DYNAMIC;
1503 viewportTests->addChild(newTestCase<DepthRangeUnrestrictedTest>(testCtx, testParams));
1504 }
1505 }
1506 }
1507 }
1508
1509 depthTests->addChild(viewportTests.release());
1510 }
1511
1512 // DepthBounds's depth unrestricted range
1513 {
1514 de::MovePtr<tcu::TestCaseGroup> depthBoundsTests (new tcu::TestCaseGroup(testCtx, "depthbounds"));
1515 DepthRangeUnrestrictedParam testParams;
1516 testParams.pipelineConstructionType = pipelineConstructionType;
1517 testParams.testClearValueOnly = VK_FALSE;
1518 testParams.wc = 1.0f;
1519 testParams.depthClampEnable = VK_TRUE;
1520 testParams.depthBoundsTestEnable = VK_TRUE;
1521
1522 for (int format = 0; format < DE_LENGTH_OF_ARRAY(depthFormats); ++format)
1523 {
1524 testParams.depthFormat = depthFormats[format];
1525 testParams.depthBufferClearValue = defaultClearValue(testParams.depthFormat);
1526 for (int compareOp = 0; compareOp < DE_LENGTH_OF_ARRAY(compareOps); compareOp++)
1527 {
1528 testParams.depthCompareOp = compareOps[compareOp];
1529 for (int clearValue = 0; clearValue < DE_LENGTH_OF_ARRAY(clearValues); clearValue++)
1530 {
1531 testParams.depthBufferClearValue.depthStencil.depth = clearValues[clearValue];
1532 for (int viewportValue = 0; viewportValue < DE_LENGTH_OF_ARRAY(viewportValues); viewportValue++)
1533 {
1534 testParams.viewportMinDepth = -viewportValues[viewportValue];
1535 testParams.viewportMaxDepth = viewportValues[viewportValue];
1536 for (int depthValue = 0; depthValue < DE_LENGTH_OF_ARRAY(depthBoundsValues); depthValue++)
1537 {
1538 testParams.minDepthBounds = -depthBoundsValues[depthValue];
1539 testParams.maxDepthBounds = depthBoundsValues[depthValue];
1540
1541 testParams.viewportDepthBoundsMode = TEST_MODE_VIEWPORT_DEPTH_BOUNDS_STATIC;
1542 depthBoundsTests->addChild(newTestCase<DepthRangeUnrestrictedTest>(testCtx, testParams));
1543 testParams.viewportDepthBoundsMode = TEST_MODE_DEPTH_BOUNDS_DYNAMIC;
1544 depthBoundsTests->addChild(newTestCase<DepthRangeUnrestrictedTest>(testCtx, testParams));
1545 testParams.viewportDepthBoundsMode = TEST_MODE_VIEWPORT_DEPTH_BOUNDS_DYNAMIC;
1546 depthBoundsTests->addChild(newTestCase<DepthRangeUnrestrictedTest>(testCtx, testParams));
1547 }
1548 }
1549 }
1550 }
1551 }
1552
1553 depthTests->addChild(depthBoundsTests.release());
1554 }
1555
1556 // Depth clamping disabled
1557 {
1558 de::MovePtr<tcu::TestCaseGroup> noDepthClampingTests (new tcu::TestCaseGroup(testCtx, "depthclampingdisabled"));
1559 DepthRangeUnrestrictedParam testParams;
1560 testParams.pipelineConstructionType = pipelineConstructionType;
1561 testParams.testClearValueOnly = VK_FALSE;
1562 testParams.depthClampEnable = VK_FALSE;
1563 testParams.minDepthBounds = 0.0f;
1564 testParams.maxDepthBounds = 1.0f;
1565 testParams.depthBoundsTestEnable = VK_FALSE;
1566 testParams.viewportDepthBoundsMode = TEST_MODE_VIEWPORT_DEPTH_BOUNDS_STATIC;
1567
1568 for (int format = 0; format < DE_LENGTH_OF_ARRAY(depthFormats); ++format)
1569 {
1570 testParams.depthFormat = depthFormats[format];
1571 testParams.depthBufferClearValue = defaultClearValue(testParams.depthFormat);
1572 for (int compareOp = 0; compareOp < DE_LENGTH_OF_ARRAY(compareOps); compareOp++)
1573 {
1574 testParams.depthCompareOp = compareOps[compareOp];
1575 for (int clearValue = 0; clearValue < DE_LENGTH_OF_ARRAY(clearValues); clearValue++)
1576 {
1577 testParams.depthBufferClearValue.depthStencil.depth = clearValues[clearValue];
1578 for (int viewportValue = 0; viewportValue < DE_LENGTH_OF_ARRAY(viewportValues); viewportValue++)
1579 {
1580 testParams.viewportMinDepth = -viewportValues[viewportValue];
1581 testParams.viewportMaxDepth = viewportValues[viewportValue];
1582 for (int wc = 0; wc < DE_LENGTH_OF_ARRAY(wcValues); wc++)
1583 {
1584 testParams.wc = wcValues[wc];
1585 noDepthClampingTests->addChild(newTestCase<DepthRangeUnrestrictedTest>(testCtx, testParams));
1586 }
1587 }
1588 }
1589 }
1590 }
1591
1592 depthTests->addChild(noDepthClampingTests.release());
1593 }
1594
1595 return depthTests.release();
1596 }
1597
1598 } // pipeline
1599
1600 } // vkt
1601