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