1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Intel 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 Dynamic Raster State Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktDynamicStateRSTests.hpp"
26
27 #include "vktDynamicStateBaseClass.hpp"
28 #include "vktDynamicStateTestCaseUtil.hpp"
29
30 #include "vkImageUtil.hpp"
31 #include "vkTypeUtil.hpp"
32 #include "vkCmdUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35
36 #include "tcuTextureUtil.hpp"
37 #include "tcuImageCompare.hpp"
38 #include "tcuRGBA.hpp"
39
40 #include "deMath.h"
41
42 #include <vector>
43 #include <string>
44 #include <sstream>
45 #include <iomanip>
46
47 namespace vkt
48 {
49 namespace DynamicState
50 {
51
52 using namespace Draw;
53
54 namespace
55 {
56
57 class DepthBiasBaseCase : public TestInstance
58 {
59 public:
DepthBiasBaseCase(Context & context,vk::PipelineConstructionType pipelineConstructionType,const char * vertexShaderName,const char * fragmentShaderName,const char * meshShaderName)60 DepthBiasBaseCase (Context& context, vk::PipelineConstructionType pipelineConstructionType, const char* vertexShaderName, const char* fragmentShaderName, const char* meshShaderName)
61 : TestInstance (context)
62 , m_colorAttachmentFormat (vk::VK_FORMAT_R8G8B8A8_UNORM)
63 , m_depthStencilAttachmentFormat (vk::VK_FORMAT_UNDEFINED)
64 , m_topology (vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
65 , m_vk (context.getDeviceInterface())
66 , m_pipeline (m_vk, context.getDevice(), pipelineConstructionType)
67 , m_vertexShaderName (vertexShaderName ? vertexShaderName : "")
68 , m_fragmentShaderName (fragmentShaderName)
69 , m_meshShaderName (meshShaderName ? meshShaderName : "")
70 , m_isMesh (meshShaderName != nullptr)
71 {
72 // Either mesh or vertex shader, but not both or none.
73 DE_ASSERT((vertexShaderName != nullptr) != (meshShaderName != nullptr));
74 }
75
76 protected:
77
78 enum
79 {
80 WIDTH = 128,
81 HEIGHT = 128
82 };
83
84 vk::VkFormat m_colorAttachmentFormat;
85 vk::VkFormat m_depthStencilAttachmentFormat;
86
87 vk::VkPrimitiveTopology m_topology;
88
89 const vk::DeviceInterface& m_vk;
90
91 vk::Move<vk::VkDescriptorPool> m_descriptorPool;
92 vk::Move<vk::VkDescriptorSetLayout> m_setLayout;
93 vk::Move<vk::VkPipelineLayout> m_pipelineLayout;
94 vk::Move<vk::VkDescriptorSet> m_descriptorSet;
95 vk::GraphicsPipelineWrapper m_pipeline;
96
97 de::SharedPtr<Image> m_colorTargetImage;
98 vk::Move<vk::VkImageView> m_colorTargetView;
99
100 de::SharedPtr<Image> m_depthStencilImage;
101 vk::Move<vk::VkImageView> m_attachmentView;
102
103 PipelineCreateInfo::VertexInputState m_vertexInputState;
104 de::SharedPtr<Buffer> m_vertexBuffer;
105
106 vk::Move<vk::VkCommandPool> m_cmdPool;
107 vk::Move<vk::VkCommandBuffer> m_cmdBuffer;
108
109 vk::Move<vk::VkFramebuffer> m_framebuffer;
110 vk::Move<vk::VkRenderPass> m_renderPass;
111
112 std::string m_vertexShaderName;
113 std::string m_fragmentShaderName;
114 std::string m_meshShaderName;
115
116 std::vector<PositionColorVertex> m_data;
117
118 PipelineCreateInfo::DepthStencilState m_depthStencilState;
119
120 const bool m_isMesh;
121
initialize(void)122 void initialize (void)
123 {
124 const vk::VkDevice device = m_context.getDevice();
125 const auto vertDescType = (m_isMesh ? vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER : vk::VK_DESCRIPTOR_TYPE_MAX_ENUM);
126 std::vector<vk::VkPushConstantRange> pcRanges;
127
128 vk::VkFormatProperties formatProperties;
129 // check for VK_FORMAT_D24_UNORM_S8_UINT support
130 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D24_UNORM_S8_UINT, &formatProperties);
131 if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
132 {
133 m_depthStencilAttachmentFormat = vk::VK_FORMAT_D24_UNORM_S8_UINT;
134 }
135 else
136 {
137 // check for VK_FORMAT_D32_SFLOAT_S8_UINT support
138 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProperties);
139 if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
140 {
141 m_depthStencilAttachmentFormat = vk::VK_FORMAT_D32_SFLOAT_S8_UINT;
142 }
143 else
144 throw tcu::NotSupportedError("No valid depth stencil attachment available");
145 }
146
147 // The mesh shading pipeline will contain a set with vertex data.
148 #ifndef CTS_USES_VULKANSC
149 if (m_isMesh)
150 {
151 vk::DescriptorSetLayoutBuilder setLayoutBuilder;
152 vk::DescriptorPoolBuilder poolBuilder;
153
154 setLayoutBuilder.addSingleBinding(vertDescType, vk::VK_SHADER_STAGE_MESH_BIT_EXT);
155 m_setLayout = setLayoutBuilder.build(m_vk, device);
156
157 poolBuilder.addType(vertDescType);
158 m_descriptorPool = poolBuilder.build(m_vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
159
160 m_descriptorSet = vk::makeDescriptorSet(m_vk, device, m_descriptorPool.get(), m_setLayout.get());
161 pcRanges.push_back(vk::makePushConstantRange(vk::VK_SHADER_STAGE_MESH_BIT_EXT, 0u, static_cast<uint32_t>(sizeof(uint32_t))));
162 }
163 #endif // CTS_USES_VULKANSC
164
165 m_pipelineLayout = vk::makePipelineLayout(m_vk, device, m_setLayout.get(), de::dataOrNull(pcRanges));
166
167 const vk::VkExtent3D imageExtent = { WIDTH, HEIGHT, 1 };
168 ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
169 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
170
171 m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
172
173 const ImageCreateInfo depthStencilImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_depthStencilAttachmentFormat, imageExtent,
174 1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
175 vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
176
177 m_depthStencilImage = Image::createAndAlloc(m_vk, device, depthStencilImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
178
179 const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
180 m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
181
182 const ImageViewCreateInfo attachmentViewInfo(m_depthStencilImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthStencilAttachmentFormat);
183 m_attachmentView = vk::createImageView(m_vk, device, &attachmentViewInfo);
184
185 RenderPassCreateInfo renderPassCreateInfo;
186 renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
187 vk::VK_SAMPLE_COUNT_1_BIT,
188 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
189 vk::VK_ATTACHMENT_STORE_OP_STORE,
190 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
191 vk::VK_ATTACHMENT_STORE_OP_STORE,
192 vk::VK_IMAGE_LAYOUT_GENERAL,
193 vk::VK_IMAGE_LAYOUT_GENERAL));
194
195 renderPassCreateInfo.addAttachment(AttachmentDescription(m_depthStencilAttachmentFormat,
196 vk::VK_SAMPLE_COUNT_1_BIT,
197 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
198 vk::VK_ATTACHMENT_STORE_OP_STORE,
199 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
200 vk::VK_ATTACHMENT_STORE_OP_STORE,
201 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
202 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
203
204 const vk::VkAttachmentReference colorAttachmentReference =
205 {
206 0,
207 vk::VK_IMAGE_LAYOUT_GENERAL
208 };
209
210 const vk::VkAttachmentReference depthAttachmentReference =
211 {
212 1,
213 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
214 };
215
216 renderPassCreateInfo.addSubpass(SubpassDescription(vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
217 0,
218 0,
219 DE_NULL,
220 1,
221 &colorAttachmentReference,
222 DE_NULL,
223 depthAttachmentReference,
224 0,
225 DE_NULL));
226
227 m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
228
229 const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
230 {
231 0,
232 (deUint32)sizeof(tcu::Vec4) * 2,
233 vk::VK_VERTEX_INPUT_RATE_VERTEX,
234 };
235
236 const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
237 {
238 {
239 0u,
240 0u,
241 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
242 0u
243 },
244 {
245 1u,
246 0u,
247 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
248 (deUint32)(sizeof(float)* 4),
249 }
250 };
251
252 m_vertexInputState = PipelineCreateInfo::VertexInputState(1,
253 &vertexInputBindingDescription,
254 2,
255 vertexInputAttributeDescriptions);
256
257 std::vector<vk::VkViewport> viewports { { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } };
258 std::vector<vk::VkRect2D> scissors { { { 0u, 0u }, { 0u, 0u } } };
259
260 // Shader modules.
261 const auto& binaries = m_context.getBinaryCollection();
262 const vk::Move<vk::VkShaderModule> vs = (m_isMesh ? vk::Move<vk::VkShaderModule>() : vk::createShaderModule(m_vk, device, binaries.get(m_vertexShaderName)));
263 const vk::Move<vk::VkShaderModule> ms = (m_isMesh ? vk::createShaderModule(m_vk, device, binaries.get(m_meshShaderName)) : vk::Move<vk::VkShaderModule>());
264 const vk::Move<vk::VkShaderModule> fs = vk::createShaderModule(m_vk, device, binaries.get(m_fragmentShaderName));
265
266 const PipelineCreateInfo::ColorBlendState::Attachment attachmentState;
267 const PipelineCreateInfo::ColorBlendState colorBlendState(1u, static_cast<const vk::VkPipelineColorBlendAttachmentState*>(&attachmentState));
268 const PipelineCreateInfo::RasterizerState rasterizerState;
269 PipelineCreateInfo::DynamicState dynamicState;
270
271 m_pipeline.setDefaultTopology(m_topology)
272 .setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicState))
273 .setDefaultMultisampleState();
274
275 #ifndef CTS_USES_VULKANSC
276 if (m_isMesh)
277 {
278 m_pipeline
279 .setupPreRasterizationMeshShaderState(viewports,
280 scissors,
281 *m_pipelineLayout,
282 *m_renderPass,
283 0u,
284 DE_NULL,
285 *ms,
286 static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState));
287 }
288 else
289 #endif // CTS_USES_VULKANSC
290 {
291 m_pipeline
292 .setupVertexInputState(&m_vertexInputState)
293 .setupPreRasterizationShaderState(viewports,
294 scissors,
295 *m_pipelineLayout,
296 *m_renderPass,
297 0u,
298 *vs,
299 static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState));
300 }
301
302 m_pipeline.setupFragmentShaderState(*m_pipelineLayout, *m_renderPass, 0u, *fs, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&m_depthStencilState))
303 .setupFragmentOutputState(*m_renderPass, 0u, static_cast<const vk::VkPipelineColorBlendStateCreateInfo*>(&colorBlendState))
304 .setMonolithicPipelineLayout(*m_pipelineLayout)
305 .buildPipeline();
306
307
308 std::vector<vk::VkImageView> attachments(2);
309 attachments[0] = *m_colorTargetView;
310 attachments[1] = *m_attachmentView;
311
312 const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
313
314 m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
315
316 const vk::VkDeviceSize dataSize = m_data.size() * sizeof(PositionColorVertex);
317 const vk::VkBufferUsageFlags bufferUsage = (m_isMesh ? vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
318 m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, bufferUsage),
319 m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
320
321 deUint8* ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
322 deMemcpy(ptr, &m_data[0], static_cast<size_t>(dataSize));
323
324 vk::flushAlloc(m_vk, device, m_vertexBuffer->getBoundMemory());
325
326 // Update descriptor set for mesh shaders.
327 if (m_isMesh)
328 {
329 vk::DescriptorSetUpdateBuilder updateBuilder;
330 const auto location = vk::DescriptorSetUpdateBuilder::Location::binding(0u);
331 const auto bufferInfo = vk::makeDescriptorBufferInfo(m_vertexBuffer->object(), 0ull, dataSize);
332
333 updateBuilder.writeSingle(m_descriptorSet.get(), location, vertDescType, &bufferInfo);
334 updateBuilder.update(m_vk, device);
335 }
336
337 const CmdPoolCreateInfo cmdPoolCreateInfo(m_context.getUniversalQueueFamilyIndex());
338 m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
339 m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
340 }
341
iterate(void)342 virtual tcu::TestStatus iterate (void)
343 {
344 DE_ASSERT(false);
345 return tcu::TestStatus::fail("Should reimplement iterate() method");
346 }
347
beginRenderPass(void)348 void beginRenderPass (void)
349 {
350 const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
351 beginRenderPassWithClearColor(clearColor);
352 }
353
beginRenderPassWithClearColor(const vk::VkClearColorValue & clearColor)354 void beginRenderPassWithClearColor (const vk::VkClearColorValue &clearColor)
355 {
356 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
357
358 initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
359 vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
360 initialTransitionDepthStencil2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
361 vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
362
363 const ImageSubresourceRange subresourceRangeImage(vk::VK_IMAGE_ASPECT_COLOR_BIT);
364 m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
365 vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRangeImage);
366
367 const vk::VkClearDepthStencilValue depthStencilClearValue = { 0.0f, 0 };
368
369 const ImageSubresourceRange subresourceRangeDepthStencil[2] = { vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_ASPECT_STENCIL_BIT };
370
371 m_vk.cmdClearDepthStencilImage(*m_cmdBuffer, m_depthStencilImage->object(),
372 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencilClearValue, 2, subresourceRangeDepthStencil);
373
374 const vk::VkMemoryBarrier memBarrier =
375 {
376 vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,
377 DE_NULL,
378 vk::VK_ACCESS_TRANSFER_WRITE_BIT,
379 vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
380 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
381 };
382
383 m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
384 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
385 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
386 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
387
388 transition2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT,
389 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
390 vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
391 vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
392
393 vk::beginRenderPass(m_vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, vk::makeRect2D(0, 0, WIDTH, HEIGHT));
394 }
395
setDynamicViewportState(const deUint32 width,const deUint32 height)396 void setDynamicViewportState (const deUint32 width, const deUint32 height)
397 {
398 vk::VkViewport viewport = vk::makeViewport(tcu::UVec2(width, height));
399 m_vk.cmdSetViewport(*m_cmdBuffer, 0, 1, &viewport);
400
401 vk::VkRect2D scissor = vk::makeRect2D(tcu::UVec2(width, height));
402 m_vk.cmdSetScissor(*m_cmdBuffer, 0, 1, &scissor);
403 }
404
setDynamicViewportState(const deUint32 viewportCount,const vk::VkViewport * pViewports,const vk::VkRect2D * pScissors)405 void setDynamicViewportState (const deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
406 {
407 m_vk.cmdSetViewport(*m_cmdBuffer, 0, viewportCount, pViewports);
408 m_vk.cmdSetScissor(*m_cmdBuffer, 0, viewportCount, pScissors);
409 }
410
setDynamicRasterizationState(const float lineWidth=1.0f,const float depthBiasConstantFactor=0.0f,const float depthBiasClamp=0.0f,const float depthBiasSlopeFactor=0.0f)411 void setDynamicRasterizationState (const float lineWidth = 1.0f,
412 const float depthBiasConstantFactor = 0.0f,
413 const float depthBiasClamp = 0.0f,
414 const float depthBiasSlopeFactor = 0.0f)
415 {
416 m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
417 m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
418 }
419
setDynamicBlendState(const float const1=0.0f,const float const2=0.0f,const float const3=0.0f,const float const4=0.0f)420 void setDynamicBlendState (const float const1 = 0.0f, const float const2 = 0.0f,
421 const float const3 = 0.0f, const float const4 = 0.0f)
422 {
423 float blendConstantsants[4] = { const1, const2, const3, const4 };
424 m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstantsants);
425 }
426
setDynamicDepthStencilState(const float minDepthBounds=0.0f,const float maxDepthBounds=1.0f,const deUint32 stencilFrontCompareMask=0xffffffffu,const deUint32 stencilFrontWriteMask=0xffffffffu,const deUint32 stencilFrontReference=0,const deUint32 stencilBackCompareMask=0xffffffffu,const deUint32 stencilBackWriteMask=0xffffffffu,const deUint32 stencilBackReference=0)427 void setDynamicDepthStencilState (const float minDepthBounds = 0.0f, const float maxDepthBounds = 1.0f,
428 const deUint32 stencilFrontCompareMask = 0xffffffffu, const deUint32 stencilFrontWriteMask = 0xffffffffu,
429 const deUint32 stencilFrontReference = 0, const deUint32 stencilBackCompareMask = 0xffffffffu,
430 const deUint32 stencilBackWriteMask = 0xffffffffu, const deUint32 stencilBackReference = 0)
431 {
432 m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
433 m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
434 m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
435 m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
436 m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
437 m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
438 m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
439 }
440
441 #ifndef CTS_USES_VULKANSC
pushVertexOffset(const uint32_t vertexOffset,const vk::VkShaderStageFlags stageFlags=vk::VK_SHADER_STAGE_MESH_BIT_EXT)442 void pushVertexOffset (const uint32_t vertexOffset,
443 const vk::VkShaderStageFlags stageFlags = vk::VK_SHADER_STAGE_MESH_BIT_EXT)
444 {
445 m_vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, stageFlags, 0u, static_cast<uint32_t>(sizeof(uint32_t)), &vertexOffset);
446 }
447 #endif // CTS_USES_VULKANSC
448 };
449
450 class DepthBiasParamTestInstance : public DepthBiasBaseCase
451 {
452 public:
DepthBiasParamTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)453 DepthBiasParamTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
454 : DepthBiasBaseCase (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
455 {
456 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
457 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
458 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
459 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec()));
460
461 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
462 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
463 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
464 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
465
466 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
467 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
468 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
469 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec()));
470
471 // enable depth test
472 m_depthStencilState = PipelineCreateInfo::DepthStencilState(
473 VK_TRUE, VK_TRUE, vk::VK_COMPARE_OP_GREATER_OR_EQUAL);
474
475 DepthBiasBaseCase::initialize();
476 }
477
iterate(void)478 virtual tcu::TestStatus iterate (void)
479 {
480 tcu::TestLog& log = m_context.getTestContext().getLog();
481 const vk::VkQueue queue = m_context.getUniversalQueue();
482 const vk::VkDevice device = m_context.getDevice();
483
484 beginRenderPass();
485
486 // set states here
487 setDynamicViewportState(WIDTH, HEIGHT);
488 setDynamicBlendState();
489 setDynamicDepthStencilState();
490
491 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline.getPipeline());
492
493 #ifndef CTS_USES_VULKANSC
494 if (m_isMesh)
495 {
496 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
497
498 setDynamicRasterizationState(1.0f, 0.0f);
499 pushVertexOffset(0u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
500 pushVertexOffset(4u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
501
502 setDynamicRasterizationState(1.0f, -1.0f);
503 pushVertexOffset(8u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
504 }
505 else
506 #endif // CTS_USES_VULKANSC
507 {
508 const vk::VkDeviceSize vertexBufferOffset = 0;
509 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
510 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
511
512 setDynamicRasterizationState(1.0f, 0.0f);
513 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
514 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
515
516 setDynamicRasterizationState(1.0f, -1.0f);
517 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 8, 0);
518 }
519
520 endRenderPass(m_vk, *m_cmdBuffer);
521 endCommandBuffer(m_vk, *m_cmdBuffer);
522
523 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
524
525 // validation
526 {
527 VK_CHECK(m_vk.queueWaitIdle(queue));
528
529 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
530 referenceFrame.allocLevel(0);
531
532 const deInt32 frameWidth = referenceFrame.getWidth();
533 const deInt32 frameHeight = referenceFrame.getHeight();
534
535 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
536
537 for (int y = 0; y < frameHeight; y++)
538 {
539 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
540
541 for (int x = 0; x < frameWidth; x++)
542 {
543 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
544
545 if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
546 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
547 else
548 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
549 }
550 }
551
552 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
553 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
554 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
555
556 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
557 referenceFrame.getLevel(0), renderedFrame, 0.05f,
558 tcu::COMPARE_LOG_RESULT))
559 {
560 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
561 }
562
563 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
564 }
565 }
566 };
567
568 class DepthBiasClampParamTestInstance : public DepthBiasBaseCase
569 {
570 public:
DepthBiasClampParamTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)571 DepthBiasClampParamTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
572 : DepthBiasBaseCase (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
573 {
574 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
575 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
576 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
577 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec()));
578
579 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
580 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
581 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
582 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec()));
583
584 // enable depth test
585 m_depthStencilState = PipelineCreateInfo::DepthStencilState(VK_TRUE, VK_TRUE, vk::VK_COMPARE_OP_GREATER_OR_EQUAL);
586
587 DepthBiasBaseCase::initialize();
588 }
589
iterate(void)590 virtual tcu::TestStatus iterate (void)
591 {
592 tcu::TestLog& log = m_context.getTestContext().getLog();
593 const vk::VkQueue queue = m_context.getUniversalQueue();
594 const vk::VkDevice device = m_context.getDevice();
595
596 beginRenderPass();
597
598 // set states here
599 setDynamicViewportState(WIDTH, HEIGHT);
600 setDynamicBlendState();
601 setDynamicDepthStencilState();
602
603 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline.getPipeline());
604
605 #ifndef CTS_USES_VULKANSC
606 if (m_isMesh)
607 {
608 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
609
610 setDynamicRasterizationState(1.0f, 1000.0f, 0.005f);
611 pushVertexOffset(0u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
612
613 setDynamicRasterizationState(1.0f, 0.0f);
614 pushVertexOffset(4u); m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
615 }
616 else
617 #endif // CTS_USES_VULKANSC
618 {
619 const vk::VkDeviceSize vertexBufferOffset = 0;
620 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
621 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
622
623 setDynamicRasterizationState(1.0f, 1000.0f, 0.005f);
624 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
625
626 setDynamicRasterizationState(1.0f, 0.0f);
627 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
628 }
629
630 endRenderPass(m_vk, *m_cmdBuffer);
631 endCommandBuffer(m_vk, *m_cmdBuffer);
632
633 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
634
635 // validation
636 {
637 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
638 referenceFrame.allocLevel(0);
639
640 const deInt32 frameWidth = referenceFrame.getWidth();
641 const deInt32 frameHeight = referenceFrame.getHeight();
642
643 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
644
645 for (int y = 0; y < frameHeight; y++)
646 {
647 float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
648
649 for (int x = 0; x < frameWidth; x++)
650 {
651 float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
652
653 if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
654 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
655 else
656 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
657 }
658 }
659
660 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
661 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
662 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
663
664 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
665 referenceFrame.getLevel(0), renderedFrame, 0.05f,
666 tcu::COMPARE_LOG_RESULT))
667 {
668 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
669 }
670
671 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
672 }
673 }
674 };
675
676 class LineWidthParamTestInstance : public DynamicStateBaseClass
677 {
678 public:
LineWidthParamTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)679 LineWidthParamTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
680 : DynamicStateBaseClass (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
681 {
682 m_topology = vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
683
684 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), tcu::RGBA::green().toVec()));
685 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::RGBA::green().toVec()));
686
687 DynamicStateBaseClass::initialize();
688 }
689
iterate(void)690 virtual tcu::TestStatus iterate (void)
691 {
692 tcu::TestLog& log = m_context.getTestContext().getLog();
693 const vk::VkQueue queue = m_context.getUniversalQueue();
694 const vk::VkDevice device = m_context.getDevice();
695
696 beginRenderPass();
697
698 // set states here
699 vk::VkPhysicalDeviceProperties deviceProperties;
700 m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties);
701
702 setDynamicViewportState(WIDTH, HEIGHT);
703 setDynamicBlendState();
704 setDynamicDepthStencilState();
705 setDynamicRasterizationState(deFloatFloor(deviceProperties.limits.lineWidthRange[1]));
706
707 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline.getPipeline());
708
709 #ifndef CTS_USES_VULKANSC
710 if (m_isMesh)
711 {
712 const auto numVert = static_cast<uint32_t>(m_data.size());
713 DE_ASSERT(numVert >= 1u);
714
715 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
716 pushVertexOffset(0u, *m_pipelineLayout);
717 m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 1u, 1u, 1u);
718 }
719 else
720 #endif // CTS_USES_VULKANSC
721 {
722 const vk::VkDeviceSize vertexBufferOffset = 0;
723 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
724 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
725
726 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
727 }
728
729 endRenderPass(m_vk, *m_cmdBuffer);
730 endCommandBuffer(m_vk, *m_cmdBuffer);
731
732 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
733
734 // validation
735 {
736 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
737 referenceFrame.allocLevel(0);
738
739 const deInt32 frameWidth = referenceFrame.getWidth();
740 const deInt32 frameHeight = referenceFrame.getHeight();
741
742 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
743
744 for (int y = 0; y < frameHeight; y++)
745 {
746 float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
747
748 for (int x = 0; x < frameWidth; x++)
749 {
750 float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
751 float lineHalfWidth = (float)(deFloor(deviceProperties.limits.lineWidthRange[1]) / frameHeight);
752
753 if (xCoord >= -1.0f && xCoord <= 1.0f && yCoord >= -lineHalfWidth && yCoord <= lineHalfWidth)
754 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
755 }
756 }
757
758 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
759 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
760 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT,
761 vk::VK_IMAGE_ASPECT_COLOR_BIT);
762
763 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
764 referenceFrame.getLevel(0), renderedFrame, 0.05f,
765 tcu::COMPARE_LOG_RESULT))
766 {
767 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
768 }
769
770 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
771 }
772 }
773 };
774
775 // Tests that fail if both the depth bias clamp or depth constant factor stay at 0.0f instead of applying the real values.
776 struct DepthBiasNonZeroPushConstants
777 {
778 float geometryDepth;
779 float minDepth;
780 float maxDepth;
781 };
782
783 struct DepthBiasNonZeroParams
784 {
785 vk::PipelineConstructionType pipelineConstructionType;
786 float depthBiasConstant;
787 float depthBiasClamp;
788 DepthBiasNonZeroPushConstants pushConstants;
789 bool useMeshShaders;
790 };
791
792 class DepthBiasNonZeroCase : public vkt::TestCase
793 {
794 private:
795 DepthBiasNonZeroParams m_params;
796
797 public:
798 DepthBiasNonZeroCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const DepthBiasNonZeroParams& params);
~DepthBiasNonZeroCase(void)799 virtual ~DepthBiasNonZeroCase (void) {}
800
801 void checkSupport (Context& context) const override;
802 void initPrograms (vk::SourceCollections& programCollection) const override;
803 TestInstance* createInstance (Context& context) const override;
804
getExpectedColor()805 static tcu::Vec4 getExpectedColor () { return tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f); }
806 };
807
808 class DepthBiasNonZeroInstance : public vkt::TestInstance
809 {
810 private:
811 DepthBiasNonZeroParams m_params;
812
813 public:
814 DepthBiasNonZeroInstance (Context& context, const DepthBiasNonZeroParams& params);
~DepthBiasNonZeroInstance(void)815 virtual ~DepthBiasNonZeroInstance (void) {}
816
817 tcu::TestStatus iterate (void) override;
818 };
819
DepthBiasNonZeroCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const DepthBiasNonZeroParams & params)820 DepthBiasNonZeroCase::DepthBiasNonZeroCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const DepthBiasNonZeroParams& params)
821 : vkt::TestCase (testCtx, name, description)
822 , m_params (params)
823 {}
824
createInstance(Context & context) const825 TestInstance* DepthBiasNonZeroCase::createInstance (Context& context) const
826 {
827 return new DepthBiasNonZeroInstance(context, m_params);
828 }
829
DepthBiasNonZeroInstance(Context & context,const DepthBiasNonZeroParams & params)830 DepthBiasNonZeroInstance::DepthBiasNonZeroInstance (Context& context, const DepthBiasNonZeroParams& params)
831 : vkt::TestInstance (context)
832 , m_params (params)
833 {}
834
checkSupport(Context & context) const835 void DepthBiasNonZeroCase::checkSupport (Context& context) const
836 {
837 if (m_params.depthBiasClamp != 0.0f)
838 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP);
839
840 if (m_params.useMeshShaders)
841 context.requireDeviceFunctionality("VK_EXT_mesh_shader");
842
843 checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_params.pipelineConstructionType);
844 }
845
initPrograms(vk::SourceCollections & programCollection) const846 void DepthBiasNonZeroCase::initPrograms (vk::SourceCollections& programCollection) const
847 {
848 if (m_params.useMeshShaders)
849 {
850 std::ostringstream mesh;
851 mesh
852 << "#version 450\n"
853 << "#extension GL_EXT_mesh_shader : enable\n"
854 << "\n"
855 << "layout (push_constant, std430) uniform PushConstantBlock {\n"
856 << " float geometryDepth;\n"
857 << " float minDepth;\n"
858 << " float maxDepth;\n"
859 << "} pc;\n"
860 << "\n"
861 << "vec2 positions[3] = vec2[](\n"
862 << " vec2(-1.0, -1.0),\n"
863 << " vec2(3.0, -1.0),\n"
864 << " vec2(-1.0, 3.0)\n"
865 << ");\n"
866 << "\n"
867 << "layout(local_size_x=3) in;\n"
868 << "layout(triangles) out;\n"
869 << "layout(max_vertices=3, max_primitives=1) out;\n"
870 << "\n"
871 << "void main() {\n"
872 << " SetMeshOutputsEXT(3u, 1u);\n"
873 << " gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = vec4(positions[gl_LocalInvocationIndex], pc.geometryDepth, 1.0);\n"
874 << " gl_PrimitiveTriangleIndicesEXT[0] = uvec3(0, 1, 2);\n"
875 << "}\n"
876 ;
877
878 const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
879 programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str()) << buildOptions;
880 }
881 else
882 {
883 std::ostringstream vert;
884 vert
885 << "#version 450\n"
886 << "\n"
887 << "layout (push_constant, std430) uniform PushConstantBlock {\n"
888 << " float geometryDepth;\n"
889 << " float minDepth;\n"
890 << " float maxDepth;\n"
891 << "} pc;\n"
892 << "\n"
893 << "vec2 positions[3] = vec2[](\n"
894 << " vec2(-1.0, -1.0),\n"
895 << " vec2(3.0, -1.0),\n"
896 << " vec2(-1.0, 3.0)\n"
897 << ");\n"
898 << "\n"
899 << "void main() {\n"
900 << " gl_Position = vec4(positions[gl_VertexIndex], pc.geometryDepth, 1.0);\n"
901 << "}\n"
902 ;
903 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
904 }
905
906 const auto outColor = getExpectedColor();
907 std::ostringstream frag;
908 frag
909 << std::fixed << std::setprecision(1)
910 << "#version 450\n"
911 << "\n"
912 << "layout (push_constant, std430) uniform PushConstantBlock {\n"
913 << " float geometryDepth;\n"
914 << " float minDepth;\n"
915 << " float maxDepth;\n"
916 << "} pc;\n"
917 << "\n"
918 << "layout (location=0) out vec4 outColor;\n"
919 << "\n"
920 << "void main() {\n"
921 << " const float depth = gl_FragCoord.z;\n"
922 << " if (depth >= pc.minDepth && depth <= pc.maxDepth) {\n"
923 << " outColor = vec4(" << outColor.x() << ", " << outColor.y() << ", " << outColor.z() << ", " << outColor.w() << ");\n"
924 << " }\n"
925 << "}\n"
926 ;
927
928 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
929 }
930
iterate(void)931 tcu::TestStatus DepthBiasNonZeroInstance::iterate (void)
932 {
933 const auto& vkd = m_context.getDeviceInterface();
934 const auto device = m_context.getDevice();
935 auto& alloc = m_context.getDefaultAllocator();
936 const auto qIndex = m_context.getUniversalQueueFamilyIndex();
937 const auto queue = m_context.getUniversalQueue();
938
939 const auto depthFormat = vk::VK_FORMAT_D16_UNORM;
940 const auto colorFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
941 const auto colorUsage = (vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
942 const auto depthUsage = (vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
943 const auto extent = vk::makeExtent3D(8u, 8u, 1u);
944 const auto& pcData = m_params.pushConstants;
945 const auto pcDataSize = static_cast<deUint32>(sizeof(pcData));
946 const auto pcStages = ((m_params.useMeshShaders
947 #ifndef CTS_USES_VULKANSC
948 ? vk::VK_SHADER_STAGE_MESH_BIT_EXT
949 #else
950 ? 0
951 #endif // CTS_USES_VULKANSC
952 : vk::VK_SHADER_STAGE_VERTEX_BIT)
953 | vk::VK_SHADER_STAGE_FRAGMENT_BIT);
954 const auto pcRange = vk::makePushConstantRange(pcStages, 0u, pcDataSize);
955 const auto renderPass = vk::makeRenderPass(vkd, device, colorFormat, depthFormat, vk::VK_ATTACHMENT_LOAD_OP_CLEAR, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
956 const auto stencilOp = vk::makeStencilOpState(vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_NEVER, 0u, 0u, 0u);
957
958 // Color buffer.
959 const vk::VkImageCreateInfo colorBufferInfo =
960 {
961 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
962 nullptr, // const void* pNext;
963 0u, // VkImageCreateFlags flags;
964 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType;
965 colorFormat, // VkFormat format;
966 extent, // VkExtent3D extent;
967 1u, // deUint32 mipLevels;
968 1u, // deUint32 arrayLayers;
969 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
970 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
971 colorUsage, // VkImageUsageFlags usage;
972 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
973 0u, // deUint32 queueFamilyIndexCount;
974 nullptr, // const deUint32* pQueueFamilyIndices;
975 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
976 };
977 const auto colorBuffer = Image::createAndAlloc(vkd, device, colorBufferInfo, alloc, qIndex);
978
979 // Depth buffer.
980 const vk::VkImageCreateInfo depthBufferInfo =
981 {
982 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
983 nullptr, // const void* pNext;
984 0u, // VkImageCreateFlags flags;
985 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType;
986 depthFormat, // VkFormat format;
987 extent, // VkExtent3D extent;
988 1u, // deUint32 mipLevels;
989 1u, // deUint32 arrayLayers;
990 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
991 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
992 depthUsage, // VkImageUsageFlags usage;
993 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
994 0u, // deUint32 queueFamilyIndexCount;
995 nullptr, // const deUint32* pQueueFamilyIndices;
996 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
997 };
998 const auto depthBuffer = Image::createAndAlloc(vkd, device, depthBufferInfo, alloc, qIndex);
999
1000 const auto colorSubresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1001 const auto colorView = vk::makeImageView(vkd, device, colorBuffer->object(), vk::VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange);
1002
1003 const auto depthSubresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u);
1004 const auto depthView = vk::makeImageView(vkd, device, depthBuffer->object(), vk::VK_IMAGE_VIEW_TYPE_2D, depthFormat, depthSubresourceRange);
1005
1006 // Create framebuffer.
1007 const std::vector<vk::VkImageView> attachments { colorView.get(), depthView.get() };
1008 const auto framebuffer = vk::makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(attachments.size()), de::dataOrNull(attachments), extent.width, extent.height);
1009
1010 // Descriptor set and pipeline layout.
1011 vk::DescriptorSetLayoutBuilder setLayoutBuilder;
1012 const auto dsLayout = setLayoutBuilder.build(vkd, device);
1013 const auto pipelineLayout = vk::makePipelineLayout(vkd, device, 1u, &dsLayout.get(), 1u, &pcRange);
1014
1015 // Shader modules.
1016 vk::Move<vk::VkShaderModule> vertModule;
1017 vk::Move<vk::VkShaderModule> meshModule;
1018 vk::Move<vk::VkShaderModule> fragModule;
1019 const auto& binaries = m_context.getBinaryCollection();
1020
1021 if (binaries.contains("vert"))
1022 vertModule = vk::createShaderModule(vkd, device, binaries.get("vert"));
1023 if (binaries.contains("mesh"))
1024 meshModule = vk::createShaderModule(vkd, device, binaries.get("mesh"));
1025 fragModule = vk::createShaderModule(vkd, device, binaries.get("frag"), 0u);
1026
1027 const std::vector<vk::VkViewport> viewports { vk::makeViewport(extent) };
1028 const std::vector<vk::VkRect2D> scissors { vk::makeRect2D(extent) };
1029
1030 // Vertex input state without bindings and attributes.
1031 const vk::VkPipelineVertexInputStateCreateInfo vertexInputInfo =
1032 {
1033 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
1034 nullptr, // const void* pNext
1035 0u, // VkPipelineVertexInputStateCreateFlags flags
1036 0u, // deUint32 vertexBindingDescriptionCount
1037 nullptr, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
1038 0u, // deUint32 vertexAttributeDescriptionCount
1039 nullptr, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
1040 };
1041
1042 // Depth/stencil state, with depth test and writes enabled.
1043 const vk::VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo =
1044 {
1045 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
1046 nullptr, // const void* pNext
1047 0u, // VkPipelineDepthStencilStateCreateFlags flags
1048 VK_TRUE, // VkBool32 depthTestEnable
1049 VK_TRUE, // VkBool32 depthWriteEnable
1050 vk::VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp
1051 VK_FALSE, // VkBool32 depthBoundsTestEnable
1052 VK_FALSE, // VkBool32 stencilTestEnable
1053 stencilOp, // VkStencilOpState front
1054 stencilOp, // VkStencilOpState back
1055 0.0f, // float minDepthBounds
1056 1.0f, // float maxDepthBounds
1057 };
1058
1059 // Rasterization state with depth bias enabled.
1060 const vk::VkPipelineRasterizationStateCreateInfo rasterizationInfo =
1061 {
1062 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType
1063 nullptr, // const void* pNext
1064 0u, // VkPipelineRasterizationStateCreateFlags flags
1065 VK_FALSE, // VkBool32 depthClampEnable
1066 VK_FALSE, // VkBool32 rasterizerDiscardEnable
1067 vk::VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode
1068 vk::VK_CULL_MODE_NONE, // VkCullModeFlags cullMode
1069 vk::VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace
1070 VK_TRUE, // VkBool32 depthBiasEnable
1071 0.0f, // float depthBiasConstantFactor
1072 0.0f, // float depthBiasClamp
1073 0.0f, // float depthBiasSlopeFactor
1074 1.0f // float lineWidth
1075 };
1076
1077 // Dynamic state.
1078 const std::vector<vk::VkDynamicState> dynamicStates (1u, vk::VK_DYNAMIC_STATE_DEPTH_BIAS);
1079
1080 const vk::VkPipelineDynamicStateCreateInfo dynamicStateInfo =
1081 {
1082 vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
1083 nullptr, // const void* pNext;
1084 0u, // VkPipelineDynamicStateCreateFlags flags;
1085 static_cast<deUint32>(dynamicStates.size()), // deUint32 dynamicStateCount;
1086 de::dataOrNull(dynamicStates), // const VkDynamicState* pDynamicStates;
1087 };
1088
1089 // Graphics pipeline.
1090 vk::Move<vk::VkPipeline> pipeline;
1091
1092 #ifndef CTS_USES_VULKANSC
1093 if (m_params.useMeshShaders)
1094 {
1095 pipeline = vk::makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
1096 DE_NULL, meshModule.get(), fragModule.get(),
1097 renderPass.get(), viewports, scissors, 0u /*subpass*/,
1098 &rasterizationInfo, nullptr, &depthStencilStateInfo, nullptr, &dynamicStateInfo);
1099 }
1100 else
1101 #endif // CTS_USES_VULKANSC
1102 {
1103 pipeline = vk::makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
1104 vertModule.get(), DE_NULL, DE_NULL, DE_NULL, fragModule.get(), // shaders
1105 renderPass.get(), viewports, scissors, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0u/*subpass*/, 0u/*patchControlPoints*/,
1106 &vertexInputInfo, &rasterizationInfo, nullptr, &depthStencilStateInfo, nullptr, &dynamicStateInfo);
1107 }
1108
1109 // Command pool and buffer.
1110 const auto cmdPool = vk::makeCommandPool(vkd, device, qIndex);
1111 const auto cmdBufferPtr = vk::allocateCommandBuffer(vkd, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1112 const auto cmdBuffer = cmdBufferPtr.get();
1113
1114 // Clear colors.
1115 const std::vector<vk::VkClearValue> clearColors =
1116 {
1117 vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f),
1118 vk::makeClearValueDepthStencil(0.0f, 0u),
1119 };
1120
1121 vk::beginCommandBuffer(vkd, cmdBuffer);
1122 vk::beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), scissors.at(0), static_cast<deUint32>(clearColors.size()), de::dataOrNull(clearColors));
1123 vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
1124 vkd.cmdSetDepthBias(cmdBuffer, m_params.depthBiasConstant, m_params.depthBiasClamp, 0.0f);
1125 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pcStages, 0u, pcDataSize, &pcData);
1126 #ifndef CTS_USES_VULKANSC
1127 if (m_params.useMeshShaders)
1128 {
1129 vkd.cmdDrawMeshTasksEXT(cmdBuffer, 1u, 1u, 1u);
1130 }
1131 else
1132 #endif // CTS_USES_VULKANSC
1133 {
1134 vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
1135 }
1136 vk::endRenderPass(vkd, cmdBuffer);
1137 vk::endCommandBuffer(vkd, cmdBuffer);
1138 vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
1139
1140 // Check color buffer contents.
1141 const auto offset = vk::makeOffset3D(0, 0, 0);
1142 const auto iWidth = static_cast<int>(extent.width);
1143 const auto iHeight = static_cast<int>(extent.height);
1144 const auto colorPixels = colorBuffer->readSurface(queue, alloc, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, offset, iWidth, iHeight, vk::VK_IMAGE_ASPECT_COLOR_BIT);
1145 const auto expected = DepthBiasNonZeroCase::getExpectedColor();
1146 const tcu::Vec4 threshold (0.0f);
1147 auto& log = m_context.getTestContext().getLog();
1148
1149 if (!tcu::floatThresholdCompare(log, "Result", "Result", expected, colorPixels, threshold, tcu::COMPARE_LOG_ON_ERROR))
1150 return tcu::TestStatus::fail("Unexpected color buffer value; check log for details");
1151
1152 return tcu::TestStatus::pass("Pass");
1153 }
1154
checkDepthBiasClampSupport(Context & context)1155 void checkDepthBiasClampSupport (Context& context)
1156 {
1157 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BIAS_CLAMP);
1158 }
1159
checkWideLinesSupport(Context & context)1160 void checkWideLinesSupport (Context& context)
1161 {
1162 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_WIDE_LINES);
1163 }
1164
checkMeshShaderSupport(Context & context)1165 void checkMeshShaderSupport (Context& context)
1166 {
1167 context.requireDeviceFunctionality("VK_EXT_mesh_shader");
1168 }
1169
checkMeshAndBiasClampSupport(Context & context)1170 void checkMeshAndBiasClampSupport(Context& context)
1171 {
1172 checkMeshShaderSupport(context);
1173 checkDepthBiasClampSupport(context);
1174 }
1175
checkMeshAndWideLinesSupport(Context & context)1176 void checkMeshAndWideLinesSupport(Context& context)
1177 {
1178 checkMeshShaderSupport(context);
1179 checkWideLinesSupport(context);
1180 }
1181
checkNothing(Context &)1182 void checkNothing (Context&)
1183 {}
1184
1185 } //anonymous
1186
DynamicStateRSTests(tcu::TestContext & testCtx,vk::PipelineConstructionType pipelineConstructionType)1187 DynamicStateRSTests::DynamicStateRSTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)
1188 : TestCaseGroup (testCtx, "rs_state", "Tests for rasterizer state")
1189 , m_pipelineConstructionType (pipelineConstructionType)
1190 {
1191 /* Left blank on purpose */
1192 }
1193
~DynamicStateRSTests()1194 DynamicStateRSTests::~DynamicStateRSTests ()
1195 {
1196 }
1197
init(void)1198 void DynamicStateRSTests::init (void)
1199 {
1200 ShaderMap basePaths;
1201 basePaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
1202 basePaths[glu::SHADERTYPE_VERTEX] = nullptr;
1203 basePaths[glu::SHADERTYPE_MESH] = nullptr;
1204
1205 for (int i = 0; i < 2; ++i)
1206 {
1207 ShaderMap shaderPaths(basePaths);
1208 const bool isMesh = (i > 0);
1209 std::string nameSuffix;
1210 std::string descSuffix;
1211
1212 if (isMesh)
1213 {
1214 #ifndef CTS_USES_VULKANSC
1215 nameSuffix = "_mesh";
1216 descSuffix = " using mesh shaders";
1217 shaderPaths[glu::SHADERTYPE_MESH] = "vulkan/dynamic_state/VertexFetch.mesh";
1218 #else
1219 continue;
1220 #endif // CTS_USES_VULKANSC
1221 }
1222 else
1223 {
1224 shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
1225 }
1226
1227 addChild(new InstanceFactory<DepthBiasParamTestInstance, FunctionSupport0>(m_testCtx, "depth_bias" + nameSuffix, "Test depth bias functionality" + descSuffix, m_pipelineConstructionType, shaderPaths, (isMesh ? checkMeshShaderSupport : checkNothing)));
1228 addChild(new InstanceFactory<DepthBiasClampParamTestInstance, FunctionSupport0>(m_testCtx, "depth_bias_clamp" + nameSuffix, "Test depth bias clamp functionality" + descSuffix, m_pipelineConstructionType, shaderPaths, (isMesh ? checkMeshAndBiasClampSupport : checkDepthBiasClampSupport)));
1229 if (isMesh)
1230 shaderPaths[glu::SHADERTYPE_MESH] = "vulkan/dynamic_state/VertexFetchLines.mesh";
1231 addChild(new InstanceFactory<LineWidthParamTestInstance, FunctionSupport0>(m_testCtx, "line_width" + nameSuffix, "Draw a line with width set to max defined by physical device" + descSuffix, m_pipelineConstructionType, shaderPaths, (isMesh ? checkMeshAndWideLinesSupport : checkWideLinesSupport)));
1232
1233 {
1234 const DepthBiasNonZeroParams params =
1235 {
1236 m_pipelineConstructionType,
1237 16384.0f, // float depthBiasConstant;
1238 0.0f, // float depthBiasClamp;
1239 { // DepthBiasNonZeroPushConstants pushConstants;
1240 0.375f, // float geometryDepth;
1241 0.5f, // float minDepth;
1242 1.0f, // float maxDepth;
1243 },
1244 isMesh,
1245 };
1246 addChild(new DepthBiasNonZeroCase(m_testCtx, "nonzero_depth_bias_constant" + nameSuffix, "", params));
1247 }
1248 {
1249 const DepthBiasNonZeroParams params =
1250 {
1251 m_pipelineConstructionType,
1252 16384.0f, // float depthBiasConstant;
1253 0.125f, // float depthBiasClamp;
1254 { // DepthBiasNonZeroPushConstants pushConstants;
1255 0.375f, // float geometryDepth;
1256 0.46875f, // float minDepth;
1257 0.53125f, // float maxDepth;
1258 },
1259 isMesh,
1260 };
1261 addChild(new DepthBiasNonZeroCase(m_testCtx, "nonzero_depth_bias_clamp" + nameSuffix, "", params));
1262 }
1263 }
1264 }
1265
1266 } // DynamicState
1267 } // vkt
1268