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