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