1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2017 Google Inc.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Depth clamp tests.
23 *//*--------------------------------------------------------------------*/
24
25 #include "vkDefs.hpp"
26 #include "vktDrawDepthClampTests.hpp"
27 #include "vktTestGroupUtil.hpp"
28 #include "vktTestCaseUtil.hpp"
29 #include "vktDrawCreateInfoUtil.hpp"
30 #include "vktDrawBufferObjectUtil.hpp"
31 #include "vktDrawImageObjectUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkCmdUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkQueryUtil.hpp"
39 #include "tcuTextureUtil.hpp"
40
41 #include <cmath>
42
43 namespace vkt
44 {
45 namespace Draw
46 {
47 namespace {
48 using namespace vk;
49 using namespace de;
50 using std::string;
51 using tcu::Vec4;
52
53 static const int WIDTH = 256;
54 static const int HEIGHT = 256;
55
56 struct TestParams
57 {
58 string testNameSuffix;
59 float depthValue;
60 float expectedValue;
61 bool enableDepthBias;
62 float depthBiasConstantFactor;
63 bool skipUNorm;
64 bool skipSNorm;
65 std::vector<const char*> requiredExtensions;
66 };
67
68 const VkFormat depthStencilImageFormatsToTest[] =
69 {
70 VK_FORMAT_D16_UNORM,
71 VK_FORMAT_X8_D24_UNORM_PACK32,
72 VK_FORMAT_D32_SFLOAT,
73 VK_FORMAT_D16_UNORM_S8_UINT,
74 VK_FORMAT_D24_UNORM_S8_UINT,
75 VK_FORMAT_D32_SFLOAT_S8_UINT
76 };
77 const float depthEpsilonValuesByFormat[] =
78 {
79 1e-5f,
80 std::numeric_limits<float>::epsilon(),
81 std::numeric_limits<float>::epsilon(),
82 1e-5f,
83 std::numeric_limits<float>::epsilon(),
84 std::numeric_limits<float>::epsilon()
85 };
86
87 const float initialClearDepth = 0.5f;
88 const TestParams depthClearValuesToTest[] =
89 {
90 {
91 "", // testNameSuffix
92 0.3f, // depthValue
93 0.3f, // expectedValue
94 false, // enableDepthBias
95 0.0f, // depthBiasConstantFactor
96 false, // skipUNorm
97 false, // skipSNorm
98 {}, // requiredExtensions
99 },
100 {
101 "_clamp_input_negative", // testNameSuffix
102 -1e6f, // depthValue
103 0.0f, // expectedValue
104 false, // enableDepthBias
105 0.0f, // depthBiasConstantFactor
106 false, // skipUNorm
107 false, // skipSNorm
108 {}, // requiredExtensions
109 },
110 {
111 "_clamp_input_positive", // testNameSuffix
112 1.e6f, // depthValue
113 1.0f, // expectedValue
114 false, // enableDepthBias
115 0.0f, // depthBiasConstantFactor
116 false, // skipUNorm
117 false, // skipSNorm
118 {}, // requiredExtensions
119 },
120 {
121 "_depth_bias_clamp_input_negative", // testNameSuffix
122 0.3f, // depthValue
123 0.0f, // expectedValue
124 true, // enableDepthBias
125 -2e11f, // depthBiasConstantFactor
126 false, // skipUNorm
127 false, // skipSNorm
128 {}, // requiredExtensions
129 },
130 {
131 "_depth_bias_clamp_input_positive", // testNameSuffix
132 0.7f, // depthValue
133 1.0f, // expectedValue
134 true, // enableDepthBias
135 2e11f, // depthBiasConstantFactor
136 false, // skipUNorm
137 false, // skipSNorm
138 {}, // requiredExtensions
139 },
140 {
141 "_depth_range_unrestricted_negative", // testNameSuffix
142 -1.5f, // depthValue
143 -1.5f, // expectedValue
144 false, // enableDepthBias
145 0.0f, // depthBiasConstantFactor
146 true, // skipUNorm
147 true, // skipSNorm
148 {
149 "VK_EXT_depth_range_unrestricted" // requiredExtensions[0]
150 },
151 },
152 {
153 "_depth_range_unrestricted_positive", // testNameSuffix
154 1.5f, // depthValue
155 1.5f, // expectedValue
156 false, // enableDepthBias
157 0.0f, // depthBiasConstantFactor
158 true, // skipUNorm
159 true, // skipSNorm
160 {
161 "VK_EXT_depth_range_unrestricted" // requiredExtensions[0]
162 },
163 }
164 };
165
isUnormDepthFormat(VkFormat format)166 bool isUnormDepthFormat(VkFormat format)
167 {
168 switch (format)
169 {
170 case VK_FORMAT_D24_UNORM_S8_UINT:
171 case VK_FORMAT_X8_D24_UNORM_PACK32:
172 case VK_FORMAT_D16_UNORM_S8_UINT:
173 /* Special case for combined depth-stencil-unorm modes for which tcu::getTextureChannelClass()
174 returns TEXTURECHANNELCLASS_LAST */
175 return true;
176 default:
177 return vk::isUnormFormat(format);
178 }
179 }
180
181 class DepthClampTestInstance : public TestInstance {
182 public:
183 DepthClampTestInstance (Context& context, const TestParams& params, const VkFormat format, const float epsilon);
184 tcu::TestStatus iterate ();
185
186 private:
187 tcu::ConstPixelBufferAccess draw (const VkViewport viewport);
188
189 const TestParams m_params;
190 const VkFormat m_format;
191 const float m_epsilon;
192 SharedPtr<Image> m_depthTargetImage;
193 Move<VkImageView> m_depthTargetView;
194 SharedPtr<Buffer> m_vertexBuffer;
195 Move<VkRenderPass> m_renderPass;
196 Move<VkFramebuffer> m_framebuffer;
197 Move<VkPipelineLayout> m_pipelineLayout;
198 Move<VkPipeline> m_pipeline;
199 };
200
201 static const Vec4 vertices[] = {
202 Vec4(-1.0f, -1.0f, 0.5f, 1.0f), // 0 -- 2
203 Vec4(-1.0f, 1.0f, 0.5f, 1.0f), // | / |
204 Vec4( 1.0f, -1.0f, 0.5f, 1.0f), // | / |
205 Vec4( 1.0f, 1.0f, 0.5f, 1.0f) // 1 -- 3
206 };
207 static const VkPrimitiveTopology verticesTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
208
DepthClampTestInstance(Context & context,const TestParams & params,const VkFormat format,const float epsilon)209 DepthClampTestInstance::DepthClampTestInstance (Context& context, const TestParams& params, const VkFormat format, const float epsilon)
210 : TestInstance(context)
211 , m_params(params)
212 , m_format(format)
213 , m_epsilon(epsilon)
214 {
215 const DeviceInterface& vk = m_context.getDeviceInterface();
216 const VkDevice device = m_context.getDevice();
217 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
218
219 DescriptorPoolBuilder descriptorPoolBuilder;
220 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
221 // Vertex data
222 {
223 const size_t verticesCount = DE_LENGTH_OF_ARRAY(vertices);
224 const VkDeviceSize dataSize = verticesCount * sizeof(Vec4);
225 m_vertexBuffer = Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
226 m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
227
228 Vec4 testVertices[verticesCount];
229 deMemcpy(testVertices, vertices, dataSize);
230 for(size_t i = 0; i < verticesCount; ++i)
231 testVertices[i][2] = params.depthValue;
232 deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), testVertices, static_cast<std::size_t>(dataSize));
233 flushMappedMemoryRange(vk, device, m_vertexBuffer->getBoundMemory().getMemory(), m_vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
234 }
235 // Render pass
236 {
237 const VkImageUsageFlags targetImageUsageFlags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
238 const ImageCreateInfo targetImageCreateInfo (VK_IMAGE_TYPE_2D, m_format, { WIDTH, HEIGHT, 1u }, 1u, 1u, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, targetImageUsageFlags);
239 m_depthTargetImage = Image::createAndAlloc(vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), queueFamilyIndex);
240
241 RenderPassCreateInfo renderPassCreateInfo;
242 renderPassCreateInfo.addAttachment(AttachmentDescription(
243 m_format, // format
244 VK_SAMPLE_COUNT_1_BIT, // samples
245 VK_ATTACHMENT_LOAD_OP_LOAD, // loadOp
246 VK_ATTACHMENT_STORE_OP_STORE, // storeOp
247 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
248 VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
249 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // initialLayout
250 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); // finalLayout
251 const VkAttachmentReference depthAttachmentReference = makeAttachmentReference(0u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
252 renderPassCreateInfo.addSubpass(SubpassDescription(
253 VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
254 (VkSubpassDescriptionFlags)0, // flags
255 0u, // inputAttachmentCount
256 DE_NULL, // inputAttachments
257 0u, // colorAttachmentCount
258 DE_NULL, // colorAttachments
259 DE_NULL, // resolveAttachments
260 depthAttachmentReference, // depthStencilAttachment
261 0u, // preserveAttachmentCount
262 DE_NULL)); // preserveAttachments
263 m_renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
264 }
265
266 const ImageViewCreateInfo depthTargetViewInfo (m_depthTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, m_format);
267 m_depthTargetView = createImageView(vk, device, &depthTargetViewInfo);
268
269 const std::vector<VkImageView> depthAttachments { *m_depthTargetView };
270 FramebufferCreateInfo framebufferCreateInfo (*m_renderPass, depthAttachments, WIDTH, HEIGHT, 1);
271
272 m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
273
274 // Vertex input
275 const VkVertexInputBindingDescription vertexInputBindingDescription =
276 {
277 0u, // uint32_t binding;
278 sizeof(Vec4), // uint32_t stride;
279 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
280 };
281
282 const VkVertexInputAttributeDescription vertexInputAttributeDescription =
283 {
284 0u, // uint32_t location;
285 0u, // uint32_t binding;
286 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
287 0u // uint32_t offset;
288 };
289
290 const PipelineCreateInfo::VertexInputState vertexInputState = PipelineCreateInfo::VertexInputState(1, &vertexInputBindingDescription,
291 1, &vertexInputAttributeDescription);
292
293 // Graphics pipeline
294 const Unique<VkShaderModule> vertexModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
295 const Unique<VkShaderModule> fragmentModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
296
297 const PipelineLayoutCreateInfo pipelineLayoutCreateInfo (0u, DE_NULL, 0u, DE_NULL);
298 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
299
300 const VkRect2D scissor = makeRect2D(WIDTH, HEIGHT);
301 const VkViewport viewport = makeViewport(WIDTH, HEIGHT);
302 std::vector<VkDynamicState> dynamicStates (1, VK_DYNAMIC_STATE_VIEWPORT);
303
304 PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
305 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vertexModule, "main", VK_SHADER_STAGE_VERTEX_BIT));
306 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fragmentModule, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
307 pipelineCreateInfo.addState (PipelineCreateInfo::VertexInputState (vertexInputState));
308 pipelineCreateInfo.addState (PipelineCreateInfo::InputAssemblerState(verticesTopology));
309 pipelineCreateInfo.addState (PipelineCreateInfo::ViewportState (1, std::vector<VkViewport>(1, viewport), std::vector<VkRect2D>(1, scissor)));
310 pipelineCreateInfo.addState (PipelineCreateInfo::DepthStencilState (VK_TRUE, VK_TRUE, VK_COMPARE_OP_ALWAYS, VK_FALSE, VK_FALSE));
311 pipelineCreateInfo.addState (PipelineCreateInfo::RasterizerState (
312 VK_TRUE, // depthClampEnable
313 VK_FALSE, // rasterizerDiscardEnable
314 VK_POLYGON_MODE_FILL, // polygonMode
315 VK_CULL_MODE_NONE, // cullMode
316 VK_FRONT_FACE_CLOCKWISE, // frontFace
317 m_params.enableDepthBias ? VK_TRUE : VK_FALSE, // depthBiasEnable
318 m_params.depthBiasConstantFactor, // depthBiasConstantFactor
319 0.0f, // depthBiasClamp
320 0.0f, // depthBiasSlopeFactor
321 1.0f)); // lineWidth
322 pipelineCreateInfo.addState (PipelineCreateInfo::MultiSampleState ());
323 pipelineCreateInfo.addState (PipelineCreateInfo::DynamicState (dynamicStates));
324 m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
325 }
326
draw(const VkViewport viewport)327 tcu::ConstPixelBufferAccess DepthClampTestInstance::draw (const VkViewport viewport)
328 {
329 const DeviceInterface& vk = m_context.getDeviceInterface();
330 const VkDevice device = m_context.getDevice();
331 const VkQueue queue = m_context.getUniversalQueue();
332 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
333
334 const CmdPoolCreateInfo cmdPoolCreateInfo (queueFamilyIndex);
335 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, &cmdPoolCreateInfo));
336 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
337
338 const bool isCombinedType = tcu::isCombinedDepthStencilType(mapVkFormat(m_format).type) && m_format != VK_FORMAT_X8_D24_UNORM_PACK32;
339
340 beginCommandBuffer(vk, *cmdBuffer);
341 vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &viewport);
342 if (isCombinedType)
343 initialTransitionDepthStencil2DImage(vk, *cmdBuffer, m_depthTargetImage->object(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
344 else
345 initialTransitionDepth2DImage(vk, *cmdBuffer, m_depthTargetImage->object(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
346
347 const VkImageAspectFlagBits aspectBits = (VkImageAspectFlagBits)(isCombinedType ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT);
348 const ImageSubresourceRange subresourceRange (aspectBits);
349 const VkClearDepthStencilValue clearDepth = makeClearDepthStencilValue(initialClearDepth, 0u);
350
351 vk.cmdClearDepthStencilImage(*cmdBuffer, m_depthTargetImage->object(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearDepth, 1, &subresourceRange);
352
353 transition2DImage(vk, *cmdBuffer, m_depthTargetImage->object(), aspectBits,
354 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
355 VK_ACCESS_TRANSFER_WRITE_BIT , VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
356 VK_PIPELINE_STAGE_TRANSFER_BIT , VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
357
358 {
359 const VkMemoryBarrier memBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER, DE_NULL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT };
360 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
361 }
362
363 beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT));
364 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
365 const VkDeviceSize offset = 0;
366 const VkBuffer buffer = m_vertexBuffer->object();
367 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &buffer, &offset);
368 vk.cmdDraw(*cmdBuffer, DE_LENGTH_OF_ARRAY(vertices), 1, 0, 0);
369 endRenderPass(vk, *cmdBuffer);
370
371 transition2DImage(vk, *cmdBuffer, m_depthTargetImage->object(), aspectBits,
372 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
373 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT , VK_ACCESS_MEMORY_READ_BIT,
374 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT , VK_PIPELINE_STAGE_HOST_BIT);
375
376 endCommandBuffer(vk, *cmdBuffer);
377 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
378
379 VK_CHECK(vk.queueWaitIdle(queue));
380
381 return m_depthTargetImage->readDepth(queue, m_context.getDefaultAllocator(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { 0, 0, 0 }, WIDTH, HEIGHT, VK_IMAGE_ASPECT_DEPTH_BIT);
382 }
383
iterate(void)384 tcu::TestStatus DepthClampTestInstance::iterate (void)
385 {
386 // Set up the viewport and draw
387 const VkViewport viewport =
388 {
389 0.0f, // float x;
390 0.0f, // float y;
391 WIDTH, // float width;
392 HEIGHT, // float height;
393 m_params.expectedValue < 0.0f ? m_params.expectedValue : 0.0f, // float minDepth;
394 m_params.expectedValue > 1.0f ? m_params.expectedValue : 1.0f, // float maxDepth;
395 };
396 const tcu::ConstPixelBufferAccess resultImage = draw(viewport);
397
398 DE_ASSERT((isUnormDepthFormat(m_format) == false) ||
399 (m_params.expectedValue >= 0.0f && m_params.expectedValue <= 1.0f));
400
401 for(int z = 0; z < resultImage.getDepth(); ++z)
402 for(int y = 0; y < resultImage.getHeight(); ++y)
403 for(int x = 0; x < resultImage.getWidth(); ++x)
404 {
405 if (std::abs(m_params.expectedValue - resultImage.getPixDepth(x,y,z)) >= m_epsilon)
406 {
407 std::ostringstream msg;
408 msg << "Depth value mismatch, expected: " << m_params.expectedValue << ", got: " << resultImage.getPixDepth(x,y,z) << " at " << "(" << x << ", " << y << ", " << z << ")";
409 return tcu::TestStatus::fail(msg.str());
410 }
411 }
412 return tcu::TestStatus::pass("Pass");
413 }
414
415 class DepthClampTest : public TestCase
416 {
417 public:
DepthClampTest(tcu::TestContext & testCtx,const string & name,const string & description,const TestParams & params,const VkFormat format,const float epsilon)418 DepthClampTest (tcu::TestContext &testCtx, const string& name, const string& description, const TestParams ¶ms, const VkFormat format, const float epsilon)
419 : TestCase (testCtx, name, description)
420 , m_params(params)
421 , m_format(format)
422 , m_epsilon(epsilon)
423 {
424 }
425
initPrograms(SourceCollections & programCollection) const426 virtual void initPrograms (SourceCollections& programCollection) const
427 {
428 {
429 std::ostringstream src;
430 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
431 << "\n"
432 << "layout(location = 0) in vec4 in_position;\n"
433 << "\n"
434 << "out gl_PerVertex {\n"
435 << " vec4 gl_Position;\n"
436 << "};\n"
437 << "\n"
438 << "void main(void)\n"
439 << "{\n"
440 << " gl_Position = in_position;\n"
441 << "}\n";
442 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
443 }
444 {
445 std::ostringstream src;
446 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
447 << "\n"
448 << "void main(void)\n"
449 << "{\n"
450 << "}\n";
451 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
452 }
453 }
454
checkSupport(Context & context) const455 virtual void checkSupport (Context& context) const
456 {
457 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_CLAMP);
458 for(const auto& extensionName : m_params.requiredExtensions)
459 {
460 context.requireDeviceFunctionality(extensionName);
461 }
462 VkImageFormatProperties imageFormatProperties;
463 const auto& vki = context.getInstanceInterface();
464 const auto& vkd = context.getPhysicalDevice();
465 const auto usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
466 if (vki.getPhysicalDeviceImageFormatProperties(vkd, m_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, usage, 0u, &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
467 {
468 TCU_THROW(NotSupportedError, "Format not supported");
469 }
470 }
471
createInstance(Context & context) const472 virtual TestInstance* createInstance (Context& context) const
473 {
474 return new DepthClampTestInstance(context, m_params, m_format, m_epsilon);
475 }
476
477 private:
478 const TestParams m_params;
479 const VkFormat m_format;
480 const float m_epsilon;
481 };
482
getFormatCaseName(VkFormat format)483 std::string getFormatCaseName (VkFormat format)
484 {
485 return de::toLower(de::toString(getFormatStr(format)).substr(10));
486 }
487
createTests(tcu::TestCaseGroup * testGroup)488 void createTests (tcu::TestCaseGroup* testGroup)
489 {
490 for(int i = 0; i < DE_LENGTH_OF_ARRAY(depthStencilImageFormatsToTest); ++i)
491 {
492 const auto format = depthStencilImageFormatsToTest[i];
493 const float epsilon = depthEpsilonValuesByFormat[i];
494 const auto formatCaseName = getFormatCaseName(format);
495 for(const auto& params : depthClearValuesToTest)
496 {
497 if ((params.skipSNorm && vk::isSnormFormat(format)) || (params.skipUNorm && isUnormDepthFormat(format)))
498 continue;
499 const auto testCaseName = formatCaseName + params.testNameSuffix;
500 testGroup->addChild(new DepthClampTest(testGroup->getTestContext(), testCaseName, "Depth clamp", params, format, epsilon));
501 }
502 }
503 }
504 } // anonymous
505
createDepthClampTests(tcu::TestContext & testCtx)506 tcu::TestCaseGroup* createDepthClampTests (tcu::TestContext& testCtx)
507 {
508 return createTestGroup(testCtx, "depth_clamp", "Depth Clamp Tests", createTests);
509 }
510 } // Draw
511 } // vkt
512