xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/dynamic_state/vktDynamicStateDSTests.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 State Depth Stencil Tests
25  *//*--------------------------------------------------------------------*/
26 
27 #include "vktDynamicStateDSTests.hpp"
28 
29 #include "vktTestCaseUtil.hpp"
30 #include "vktDynamicStateTestCaseUtil.hpp"
31 #include "vktDynamicStateBaseClass.hpp"
32 
33 #include "tcuTestLog.hpp"
34 #include "tcuResource.hpp"
35 #include "tcuImageCompare.hpp"
36 #include "tcuCommandLine.hpp"
37 #include "tcuTextureUtil.hpp"
38 #include "tcuRGBA.hpp"
39 
40 #include "vkRefUtil.hpp"
41 #include "vkImageUtil.hpp"
42 #include "vkTypeUtil.hpp"
43 #include "vkCmdUtil.hpp"
44 #include "vkBuilderUtil.hpp"
45 #include "vkObjUtil.hpp"
46 
47 #include "vktDrawCreateInfoUtil.hpp"
48 #include "vktDrawImageObjectUtil.hpp"
49 #include "vktDrawBufferObjectUtil.hpp"
50 #include "vkPrograms.hpp"
51 
52 namespace vkt
53 {
54 namespace DynamicState
55 {
56 
57 using namespace Draw;
58 
59 namespace
60 {
61 
62 class DepthStencilBaseCase : public TestInstance
63 {
64 public:
DepthStencilBaseCase(Context & context,vk::PipelineConstructionType pipelineConstructionType,const char * vertexShaderName,const char * fragmentShaderName,const char * meshShaderName=nullptr)65     DepthStencilBaseCase(Context &context, vk::PipelineConstructionType pipelineConstructionType,
66                          const char *vertexShaderName, const char *fragmentShaderName,
67                          const char *meshShaderName = nullptr)
68         : TestInstance(context)
69         , m_pipelineConstructionType(pipelineConstructionType)
70         , m_colorAttachmentFormat(vk::VK_FORMAT_R8G8B8A8_UNORM)
71         , m_depthStencilAttachmentFormat(vk::VK_FORMAT_UNDEFINED)
72         , m_topology(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
73         , m_vk(context.getDeviceInterface())
74         , m_pipeline_1(context.getInstanceInterface(), m_vk, context.getPhysicalDevice(), context.getDevice(),
75                        context.getDeviceExtensions(), pipelineConstructionType)
76         , m_pipeline_2(context.getInstanceInterface(), m_vk, context.getPhysicalDevice(), context.getDevice(),
77                        context.getDeviceExtensions(), pipelineConstructionType)
78         , m_vertexShaderName(vertexShaderName ? vertexShaderName : "")
79         , m_fragmentShaderName(fragmentShaderName)
80         , m_meshShaderName(meshShaderName ? meshShaderName : "")
81         , m_isMesh(meshShaderName != nullptr)
82     {
83         // Either a classic or mesh pipeline, but not both or none.
84         DE_ASSERT((vertexShaderName != nullptr) != (meshShaderName != nullptr));
85     }
86 
87 protected:
88     enum
89     {
90         WIDTH  = 128,
91         HEIGHT = 128
92     };
93 
94     vk::PipelineConstructionType m_pipelineConstructionType;
95     vk::VkFormat m_colorAttachmentFormat;
96     vk::VkFormat m_depthStencilAttachmentFormat;
97 
98     vk::VkPrimitiveTopology m_topology;
99 
100     const vk::DeviceInterface &m_vk;
101 
102     vk::Move<vk::VkDescriptorPool> m_descriptorPool;
103     vk::Move<vk::VkDescriptorSetLayout> m_setLayout;
104     vk::PipelineLayoutWrapper m_pipelineLayout;
105     vk::Move<vk::VkDescriptorSet> m_descriptorSet;
106     vk::GraphicsPipelineWrapper m_pipeline_1;
107     vk::GraphicsPipelineWrapper m_pipeline_2;
108 
109     de::SharedPtr<Image> m_colorTargetImage;
110     vk::Move<vk::VkImageView> m_colorTargetView;
111 
112     de::SharedPtr<Image> m_depthStencilImage;
113     vk::Move<vk::VkImageView> m_attachmentView;
114 
115     PipelineCreateInfo::VertexInputState m_vertexInputState;
116     de::SharedPtr<Buffer> m_vertexBuffer;
117 
118     vk::Move<vk::VkCommandPool> m_cmdPool;
119     vk::Move<vk::VkCommandBuffer> m_cmdBuffer;
120 
121     vk::RenderPassWrapper m_renderPass;
122 
123     const std::string m_vertexShaderName;
124     const std::string m_fragmentShaderName;
125     const std::string m_meshShaderName;
126 
127     std::vector<PositionColorVertex> m_data;
128 
129     PipelineCreateInfo::DepthStencilState m_depthStencilState_1;
130     PipelineCreateInfo::DepthStencilState m_depthStencilState_2;
131 
132     const bool m_isMesh;
133 
initialize(void)134     void initialize(void)
135     {
136         const vk::VkDevice device = m_context.getDevice();
137 
138         vk::VkFormatProperties formatProperties;
139         // check for VK_FORMAT_D24_UNORM_S8_UINT support
140         m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(
141             m_context.getPhysicalDevice(), vk::VK_FORMAT_D24_UNORM_S8_UINT, &formatProperties);
142         if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
143         {
144             m_depthStencilAttachmentFormat = vk::VK_FORMAT_D24_UNORM_S8_UINT;
145         }
146         else
147         {
148             // check for VK_FORMAT_D32_SFLOAT_S8_UINT support
149             m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(
150                 m_context.getPhysicalDevice(), vk::VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProperties);
151             if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
152             {
153                 m_depthStencilAttachmentFormat = vk::VK_FORMAT_D32_SFLOAT_S8_UINT;
154             }
155             else
156                 throw tcu::NotSupportedError("No valid depth stencil attachment available");
157         }
158         const auto vertDescType = (m_isMesh ? vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER : vk::VK_DESCRIPTOR_TYPE_MAX_ENUM);
159         std::vector<vk::VkPushConstantRange> pcRanges;
160 
161 #ifndef CTS_USES_VULKANSC
162         // The mesh shading pipeline will contain a set with vertex data.
163         if (m_isMesh)
164         {
165             vk::DescriptorSetLayoutBuilder setLayoutBuilder;
166             vk::DescriptorPoolBuilder poolBuilder;
167 
168             setLayoutBuilder.addSingleBinding(vertDescType, vk::VK_SHADER_STAGE_MESH_BIT_EXT);
169             m_setLayout = setLayoutBuilder.build(m_vk, device);
170 
171             poolBuilder.addType(vertDescType);
172             m_descriptorPool =
173                 poolBuilder.build(m_vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
174 
175             m_descriptorSet = vk::makeDescriptorSet(m_vk, device, m_descriptorPool.get(), m_setLayout.get());
176             pcRanges.push_back(vk::makePushConstantRange(vk::VK_SHADER_STAGE_MESH_BIT_EXT, 0u,
177                                                          static_cast<uint32_t>(sizeof(uint32_t))));
178         }
179 #endif // CTS_USES_VULKANSC
180 
181         m_pipelineLayout = vk::PipelineLayoutWrapper(m_pipelineConstructionType, m_vk, device, m_setLayout.get(),
182                                                      de::dataOrNull(pcRanges));
183 
184         const vk::VkExtent3D imageExtent = {WIDTH, HEIGHT, 1};
185         const ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1,
186                                                     vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
187                                                     vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
188                                                         vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
189                                                         vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
190 
191         m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(),
192                                                    m_context.getUniversalQueueFamilyIndex());
193 
194         const ImageCreateInfo depthStencilImageCreateInfo(
195             vk::VK_IMAGE_TYPE_2D, m_depthStencilAttachmentFormat, imageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
196             vk::VK_IMAGE_TILING_OPTIMAL,
197             vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
198 
199         m_depthStencilImage =
200             Image::createAndAlloc(m_vk, device, depthStencilImageCreateInfo, m_context.getDefaultAllocator(),
201                                   m_context.getUniversalQueueFamilyIndex());
202 
203         const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D,
204                                                       m_colorAttachmentFormat);
205         m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
206 
207         const ImageViewCreateInfo attachmentViewInfo(m_depthStencilImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D,
208                                                      m_depthStencilAttachmentFormat);
209         m_attachmentView = vk::createImageView(m_vk, device, &attachmentViewInfo);
210 
211         RenderPassCreateInfo renderPassCreateInfo;
212         renderPassCreateInfo.addAttachment(AttachmentDescription(
213             m_colorAttachmentFormat, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_ATTACHMENT_LOAD_OP_LOAD,
214             vk::VK_ATTACHMENT_STORE_OP_STORE, vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, vk::VK_ATTACHMENT_STORE_OP_STORE,
215             vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL));
216 
217         renderPassCreateInfo.addAttachment(AttachmentDescription(
218             m_depthStencilAttachmentFormat, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_ATTACHMENT_LOAD_OP_LOAD,
219             vk::VK_ATTACHMENT_STORE_OP_STORE, vk::VK_ATTACHMENT_LOAD_OP_LOAD, vk::VK_ATTACHMENT_STORE_OP_STORE,
220             vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
221             vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
222 
223         const vk::VkAttachmentReference colorAttachmentReference = {0, vk::VK_IMAGE_LAYOUT_GENERAL};
224 
225         const vk::VkAttachmentReference depthAttachmentReference = {
226             1, vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
227 
228         renderPassCreateInfo.addSubpass(SubpassDescription(vk::VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 0, DE_NULL, 1,
229                                                            &colorAttachmentReference, DE_NULL, depthAttachmentReference,
230                                                            0, DE_NULL));
231 
232         m_renderPass = vk::RenderPassWrapper(m_pipelineConstructionType, m_vk, device, &renderPassCreateInfo);
233 
234         const vk::VkVertexInputBindingDescription vertexInputBindingDescription = {
235             0,
236             (uint32_t)sizeof(tcu::Vec4) * 2,
237             vk::VK_VERTEX_INPUT_RATE_VERTEX,
238         };
239 
240         const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = {
241             {0u, 0u, vk::VK_FORMAT_R32G32B32A32_SFLOAT, 0u},
242             {
243                 1u,
244                 0u,
245                 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
246                 (uint32_t)(sizeof(float) * 4),
247             }};
248 
249         m_vertexInputState = PipelineCreateInfo::VertexInputState(1, &vertexInputBindingDescription, 2,
250                                                                   vertexInputAttributeDescriptions);
251 
252         std::vector<vk::VkViewport> viewports{{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}};
253         std::vector<vk::VkRect2D> scissors{{{0u, 0u}, {0u, 0u}}};
254 
255         // Shaders.
256         const auto &binaries       = m_context.getBinaryCollection();
257         const vk::ShaderWrapper fs = vk::ShaderWrapper(m_vk, device, binaries.get(m_fragmentShaderName));
258         const vk::ShaderWrapper vs =
259             (m_isMesh ? vk::ShaderWrapper() : vk::ShaderWrapper(m_vk, device, binaries.get(m_vertexShaderName)));
260         const vk::ShaderWrapper ms =
261             (m_isMesh ? vk::ShaderWrapper(m_vk, device, binaries.get(m_meshShaderName)) : vk::ShaderWrapper());
262 
263         const PipelineCreateInfo::ColorBlendState::Attachment attachmentState;
264         const PipelineCreateInfo::ColorBlendState colorBlendState(
265             1u, static_cast<const vk::VkPipelineColorBlendAttachmentState *>(&attachmentState));
266         const PipelineCreateInfo::RasterizerState rasterizerState;
267         PipelineCreateInfo::DynamicState dynamicState;
268 
269         m_pipeline_1.setDefaultTopology(m_topology)
270             .setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo *>(&dynamicState))
271             .setDefaultMultisampleState();
272 
273 #ifndef CTS_USES_VULKANSC
274         if (m_isMesh)
275         {
276             m_pipeline_1.setupPreRasterizationMeshShaderState(
277                 viewports, scissors, m_pipelineLayout, *m_renderPass, 0u, vk::ShaderWrapper(), ms,
278                 static_cast<const vk::VkPipelineRasterizationStateCreateInfo *>(&rasterizerState));
279         }
280         else
281 #endif // CTS_USES_VULKANSC
282         {
283             m_pipeline_1.setupVertexInputState(&m_vertexInputState)
284                 .setupPreRasterizationShaderState(
285                     viewports, scissors, m_pipelineLayout, *m_renderPass, 0u, vs,
286                     static_cast<const vk::VkPipelineRasterizationStateCreateInfo *>(&rasterizerState));
287         }
288 
289         m_pipeline_1
290             .setupFragmentShaderState(
291                 m_pipelineLayout, *m_renderPass, 0u, fs,
292                 static_cast<const vk::VkPipelineDepthStencilStateCreateInfo *>(&m_depthStencilState_1))
293             .setupFragmentOutputState(*m_renderPass, 0u,
294                                       static_cast<const vk::VkPipelineColorBlendStateCreateInfo *>(&colorBlendState))
295             .setMonolithicPipelineLayout(m_pipelineLayout)
296             .buildPipeline();
297 
298         m_pipeline_2.setDefaultTopology(m_topology)
299             .setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo *>(&dynamicState))
300             .setDefaultMultisampleState();
301 
302 #ifndef CTS_USES_VULKANSC
303         if (m_isMesh)
304         {
305             m_pipeline_2.setupPreRasterizationMeshShaderState(
306                 viewports, scissors, m_pipelineLayout, *m_renderPass, 0u, vk::ShaderWrapper(), ms,
307                 static_cast<const vk::VkPipelineRasterizationStateCreateInfo *>(&rasterizerState));
308         }
309         else
310 #endif // CTS_USES_VULKANSC
311         {
312             m_pipeline_2.setupVertexInputState(&m_vertexInputState)
313                 .setupPreRasterizationShaderState(
314                     viewports, scissors, m_pipelineLayout, *m_renderPass, 0u, vs,
315                     static_cast<const vk::VkPipelineRasterizationStateCreateInfo *>(&rasterizerState));
316         }
317 
318         m_pipeline_2
319             .setupFragmentShaderState(
320                 m_pipelineLayout, *m_renderPass, 0u, fs,
321                 static_cast<const vk::VkPipelineDepthStencilStateCreateInfo *>(&m_depthStencilState_2))
322             .setupFragmentOutputState(*m_renderPass, 0u,
323                                       static_cast<const vk::VkPipelineColorBlendStateCreateInfo *>(&colorBlendState))
324             .setMonolithicPipelineLayout(m_pipelineLayout)
325             .buildPipeline();
326 
327         std::vector<vk::VkImageView> attachments(2);
328         attachments[0] = *m_colorTargetView;
329         attachments[1] = *m_attachmentView;
330 
331         const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
332 
333         m_renderPass.createFramebuffer(m_vk, device, &framebufferCreateInfo,
334                                        {m_colorTargetImage->object(), m_depthStencilImage->object()});
335 
336         const vk::VkDeviceSize dataSize = m_data.size() * sizeof(PositionColorVertex);
337         const auto bufferUsage =
338             (m_isMesh ? vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
339         m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, bufferUsage),
340                                                 m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
341 
342         uint8_t *ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
343         deMemcpy(ptr, &m_data[0], (size_t)dataSize);
344 
345         vk::flushAlloc(m_vk, device, m_vertexBuffer->getBoundMemory());
346 
347         // Update descriptor set for mesh shaders.
348         if (m_isMesh)
349         {
350             vk::DescriptorSetUpdateBuilder updateBuilder;
351             const auto location   = vk::DescriptorSetUpdateBuilder::Location::binding(0u);
352             const auto bufferInfo = vk::makeDescriptorBufferInfo(m_vertexBuffer->object(), 0ull, dataSize);
353 
354             updateBuilder.writeSingle(m_descriptorSet.get(), location, vertDescType, &bufferInfo);
355             updateBuilder.update(m_vk, device);
356         }
357 
358         const CmdPoolCreateInfo cmdPoolCreateInfo(m_context.getUniversalQueueFamilyIndex());
359         m_cmdPool   = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
360         m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
361     }
362 
iterate(void)363     virtual tcu::TestStatus iterate(void)
364     {
365         DE_ASSERT(false);
366         return tcu::TestStatus::fail("Implement iterate() method!");
367     }
368 
beginRenderPass(void)369     void beginRenderPass(void)
370     {
371         const vk::VkClearColorValue clearColor = {{0.0f, 0.0f, 0.0f, 1.0f}};
372         beginRenderPassWithClearColor(clearColor);
373     }
374 
beginRenderPassWithClearColor(const vk::VkClearColorValue & clearColor)375     void beginRenderPassWithClearColor(const vk::VkClearColorValue &clearColor)
376     {
377         beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
378 
379         initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
380                                       vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
381         initialTransitionDepthStencil2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(),
382                                              vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::VK_ACCESS_TRANSFER_WRITE_BIT,
383                                              vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
384 
385         const ImageSubresourceRange subresourceRangeImage(vk::VK_IMAGE_ASPECT_COLOR_BIT);
386         m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1,
387                                 &subresourceRangeImage);
388 
389         const vk::VkClearDepthStencilValue depthStencilClearValue = {0.0f, 0};
390 
391         const ImageSubresourceRange subresourceRangeDepthStencil[2] = {vk::VK_IMAGE_ASPECT_DEPTH_BIT,
392                                                                        vk::VK_IMAGE_ASPECT_STENCIL_BIT};
393         m_vk.cmdClearDepthStencilImage(*m_cmdBuffer, m_depthStencilImage->object(),
394                                        vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencilClearValue, 2,
395                                        subresourceRangeDepthStencil);
396 
397         vk::VkMemoryBarrier memBarrier;
398         memBarrier.sType         = vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER;
399         memBarrier.pNext         = NULL;
400         memBarrier.srcAccessMask = vk::VK_ACCESS_TRANSFER_WRITE_BIT;
401         memBarrier.dstAccessMask = vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
402                                    vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
403                                    vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
404 
405         m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
406                                 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
407                                     vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
408                                     vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
409                                 0, 1, &memBarrier, 0, NULL, 0, NULL);
410 
411         transition2DImage(
412             m_vk, *m_cmdBuffer, m_depthStencilImage->object(),
413             vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
414             vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, vk::VK_ACCESS_TRANSFER_WRITE_BIT,
415             vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
416             vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
417             vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
418 
419         m_renderPass.begin(m_vk, *m_cmdBuffer, vk::makeRect2D(0, 0, WIDTH, HEIGHT));
420     }
421 
setDynamicViewportState(const uint32_t width,const uint32_t height)422     void setDynamicViewportState(const uint32_t width, const uint32_t height)
423     {
424         vk::VkViewport viewport = vk::makeViewport(tcu::UVec2(width, height));
425         vk::VkRect2D scissor    = vk::makeRect2D(tcu::UVec2(width, height));
426         if (vk::isConstructionTypeShaderObject(m_pipelineConstructionType))
427         {
428 #ifndef CTS_USES_VULKANSC
429             m_vk.cmdSetViewportWithCount(*m_cmdBuffer, 1, &viewport);
430             m_vk.cmdSetScissorWithCount(*m_cmdBuffer, 1, &scissor);
431 #else
432             m_vk.cmdSetViewportWithCountEXT(*m_cmdBuffer, 1, &viewport);
433             m_vk.cmdSetScissorWithCountEXT(*m_cmdBuffer, 1, &scissor);
434 #endif
435         }
436         else
437         {
438             m_vk.cmdSetViewport(*m_cmdBuffer, 0, 1, &viewport);
439             m_vk.cmdSetScissor(*m_cmdBuffer, 0, 1, &scissor);
440         }
441     }
442 
setDynamicViewportState(const uint32_t viewportCount,const vk::VkViewport * pViewports,const vk::VkRect2D * pScissors)443     void setDynamicViewportState(const uint32_t viewportCount, const vk::VkViewport *pViewports,
444                                  const vk::VkRect2D *pScissors)
445     {
446         if (vk::isConstructionTypeShaderObject(m_pipelineConstructionType))
447         {
448 #ifndef CTS_USES_VULKANSC
449             m_vk.cmdSetViewportWithCount(*m_cmdBuffer, viewportCount, pViewports);
450             m_vk.cmdSetScissorWithCount(*m_cmdBuffer, viewportCount, pScissors);
451 #else
452             m_vk.cmdSetViewportWithCountEXT(*m_cmdBuffer, viewportCount, pViewports);
453             m_vk.cmdSetScissorWithCountEXT(*m_cmdBuffer, viewportCount, pScissors);
454 #endif
455         }
456         else
457         {
458             m_vk.cmdSetViewport(*m_cmdBuffer, 0, viewportCount, pViewports);
459             m_vk.cmdSetScissor(*m_cmdBuffer, 0, viewportCount, pScissors);
460         }
461     }
462 
setDynamicRasterizationState(const float lineWidth=1.0f,const float depthBiasConstantFactor=0.0f,const float depthBiasClamp=0.0f,const float depthBiasSlopeFactor=0.0f)463     void setDynamicRasterizationState(const float lineWidth = 1.0f, const float depthBiasConstantFactor = 0.0f,
464                                       const float depthBiasClamp = 0.0f, const float depthBiasSlopeFactor = 0.0f)
465     {
466         m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
467         m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
468     }
469 
setDynamicBlendState(const float const1=0.0f,const float const2=0.0f,const float const3=0.0f,const float const4=0.0f)470     void setDynamicBlendState(const float const1 = 0.0f, const float const2 = 0.0f, const float const3 = 0.0f,
471                               const float const4 = 0.0f)
472     {
473         float blendConstantsants[4] = {const1, const2, const3, const4};
474         m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstantsants);
475     }
476 
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)477     void setDynamicDepthStencilState(const float minDepthBounds = 0.0f, const float maxDepthBounds = 1.0f,
478                                      const uint32_t stencilFrontCompareMask = 0xffffffffu,
479                                      const uint32_t stencilFrontWriteMask   = 0xffffffffu,
480                                      const uint32_t stencilFrontReference   = 0,
481                                      const uint32_t stencilBackCompareMask  = 0xffffffffu,
482                                      const uint32_t stencilBackWriteMask    = 0xffffffffu,
483                                      const uint32_t stencilBackReference    = 0)
484     {
485         m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
486         m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
487         m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
488         m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
489         m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
490         m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
491         m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
492     }
493 
494 #ifndef CTS_USES_VULKANSC
pushVertexOffset(const uint32_t vertexOffset,const vk::VkShaderStageFlags stageFlags=vk::VK_SHADER_STAGE_MESH_BIT_EXT)495     void pushVertexOffset(const uint32_t vertexOffset,
496                           const vk::VkShaderStageFlags stageFlags = vk::VK_SHADER_STAGE_MESH_BIT_EXT)
497     {
498         m_vk.cmdPushConstants(*m_cmdBuffer, *m_pipelineLayout, stageFlags, 0u, static_cast<uint32_t>(sizeof(uint32_t)),
499                               &vertexOffset);
500     }
501 #endif // CTS_USES_VULKANSC
502 };
503 
504 class DepthBoundsParamTestInstance : public DepthStencilBaseCase
505 {
506 public:
DepthBoundsParamTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)507     DepthBoundsParamTestInstance(Context &context, vk::PipelineConstructionType pipelineConstructionType,
508                                  const ShaderMap &shaders)
509         : DepthStencilBaseCase(context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX),
510                                shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
511     {
512         m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
513         m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, 1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
514         m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
515         m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, -1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
516 
517         m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, 1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
518         m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
519         m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, -1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
520         m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
521 
522         m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
523         m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
524         m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
525         m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
526 
527         m_depthStencilState_1 =
528             PipelineCreateInfo::DepthStencilState(VK_TRUE, VK_TRUE, vk::VK_COMPARE_OP_ALWAYS, VK_FALSE);
529 
530         // enable depth bounds test
531         m_depthStencilState_2 =
532             PipelineCreateInfo::DepthStencilState(VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER, VK_TRUE);
533 
534         DepthStencilBaseCase::initialize();
535     }
536 
iterate(void)537     virtual tcu::TestStatus iterate(void)
538     {
539         tcu::TestLog &log         = m_context.getTestContext().getLog();
540         const vk::VkQueue queue   = m_context.getUniversalQueue();
541         const vk::VkDevice device = m_context.getDevice();
542 
543         beginRenderPass();
544 
545         // set states here
546         setDynamicViewportState(WIDTH, HEIGHT);
547         setDynamicRasterizationState();
548         setDynamicBlendState();
549         setDynamicDepthStencilState(0.5f, 0.75f);
550 
551 #ifndef CTS_USES_VULKANSC
552         if (m_isMesh)
553         {
554             m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u,
555                                        1u, &m_descriptorSet.get(), 0u, nullptr);
556 
557             m_pipeline_1.bind(*m_cmdBuffer);
558             pushVertexOffset(0u);
559             m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
560             pushVertexOffset(4u);
561             m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
562 
563             m_pipeline_2.bind(*m_cmdBuffer);
564             pushVertexOffset(8u);
565             m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
566         }
567         else
568 #endif // CTS_USES_VULKANSC
569         {
570             const vk::VkDeviceSize vertexBufferOffset = 0;
571             const vk::VkBuffer vertexBuffer           = m_vertexBuffer->object();
572             m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
573 
574             m_pipeline_1.bind(*m_cmdBuffer);
575             m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
576             m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
577 
578             m_pipeline_2.bind(*m_cmdBuffer);
579             m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 8, 0);
580         }
581 
582         m_renderPass.end(m_vk, *m_cmdBuffer);
583         endCommandBuffer(m_vk, *m_cmdBuffer);
584 
585         submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
586 
587         // validation
588         {
589             tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat),
590                                           (int)(0.5f + static_cast<float>(WIDTH)),
591                                           (int)(0.5f + static_cast<float>(HEIGHT)));
592             referenceFrame.allocLevel(0);
593 
594             const int32_t frameWidth  = referenceFrame.getWidth();
595             const int32_t frameHeight = referenceFrame.getHeight();
596 
597             tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
598 
599             for (int y = 0; y < frameHeight; y++)
600             {
601                 const float yCoord = (float)(y / (0.5 * frameHeight)) - 1.0f;
602 
603                 for (int x = 0; x < frameWidth; x++)
604                 {
605                     const float xCoord = (float)(x / (0.5 * frameWidth)) - 1.0f;
606 
607                     if (xCoord >= 0.0f && xCoord <= 1.0f && yCoord >= -1.0f && yCoord <= 1.0f)
608                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
609                     else
610                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
611                 }
612             }
613 
614             const vk::VkOffset3D zeroOffset = {0, 0, 0};
615             const tcu::ConstPixelBufferAccess renderedFrame =
616                 m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), vk::VK_IMAGE_LAYOUT_GENERAL,
617                                                 zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
618 
619             if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame.getLevel(0), renderedFrame,
620                                    0.05f, tcu::COMPARE_LOG_RESULT))
621             {
622                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
623             }
624 
625             return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
626         }
627     }
628 };
629 
630 class DepthBoundsTestInstance : public DynamicStateBaseClass
631 {
632 public:
633     enum
634     {
635         DEPTH_BOUNDS_MIN   = 0,
636         DEPTH_BOUNDS_MAX   = 1,
637         DEPTH_BOUNDS_COUNT = 2
638     };
639     static const float depthBounds[DEPTH_BOUNDS_COUNT];
640 
641     DepthBoundsTestInstance(Context &context, vk::PipelineConstructionType pipelineConstructionType,
642                             const ShaderMap &shaders);
643     virtual void initRenderPass(const vk::VkDevice device);
644     virtual void initFramebuffer(const vk::VkDevice device);
645     virtual void initPipeline(const vk::VkDevice device);
646     virtual tcu::TestStatus iterate(void);
647 
648 private:
649     const vk::VkFormat m_depthAttachmentFormat;
650 
651     de::SharedPtr<Draw::Image> m_depthImage;
652     vk::Move<vk::VkImageView> m_depthView;
653 };
654 
655 const float DepthBoundsTestInstance::depthBounds[DEPTH_BOUNDS_COUNT] = {0.3f, 0.9f};
656 
DepthBoundsTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)657 DepthBoundsTestInstance::DepthBoundsTestInstance(Context &context,
658                                                  vk::PipelineConstructionType pipelineConstructionType,
659                                                  const ShaderMap &shaders)
660     : DynamicStateBaseClass(context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX),
661                             shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
662     , m_depthAttachmentFormat(vk::VK_FORMAT_D16_UNORM)
663 {
664     const vk::VkDevice device             = m_context.getDevice();
665     const vk::VkExtent3D depthImageExtent = {WIDTH, HEIGHT, 1};
666     const ImageCreateInfo depthImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_depthAttachmentFormat, depthImageExtent, 1, 1,
667                                                vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
668                                                vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
669                                                    vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
670 
671     m_depthImage = Image::createAndAlloc(m_vk, device, depthImageCreateInfo, m_context.getDefaultAllocator(),
672                                          m_context.getUniversalQueueFamilyIndex());
673 
674     const ImageViewCreateInfo depthViewInfo(m_depthImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthAttachmentFormat);
675     m_depthView = vk::createImageView(m_vk, device, &depthViewInfo);
676 
677     m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
678     m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
679     m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
680     m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
681 
682     DynamicStateBaseClass::initialize();
683 }
684 
initRenderPass(const vk::VkDevice device)685 void DepthBoundsTestInstance::initRenderPass(const vk::VkDevice device)
686 {
687     RenderPassCreateInfo renderPassCreateInfo;
688     renderPassCreateInfo.addAttachment(AttachmentDescription(
689         m_colorAttachmentFormat, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_ATTACHMENT_LOAD_OP_LOAD,
690         vk::VK_ATTACHMENT_STORE_OP_STORE, vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, vk::VK_ATTACHMENT_STORE_OP_STORE,
691         vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL));
692     renderPassCreateInfo.addAttachment(AttachmentDescription(
693         m_depthAttachmentFormat, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_ATTACHMENT_LOAD_OP_LOAD,
694         vk::VK_ATTACHMENT_STORE_OP_STORE, vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, vk::VK_ATTACHMENT_STORE_OP_STORE,
695         vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL));
696 
697     const vk::VkAttachmentReference colorAttachmentReference = {0, vk::VK_IMAGE_LAYOUT_GENERAL};
698 
699     const vk::VkAttachmentReference depthAttachmentReference = {1, vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL};
700 
701     renderPassCreateInfo.addSubpass(SubpassDescription(vk::VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 0, DE_NULL, 1,
702                                                        &colorAttachmentReference, DE_NULL, depthAttachmentReference, 0,
703                                                        DE_NULL));
704 
705     m_renderPass = vk::RenderPassWrapper(m_pipelineConstructionType, m_vk, device, &renderPassCreateInfo);
706 }
707 
initFramebuffer(const vk::VkDevice device)708 void DepthBoundsTestInstance::initFramebuffer(const vk::VkDevice device)
709 {
710     std::vector<vk::VkImageView> attachments(2);
711     attachments[0] = *m_colorTargetView;
712     attachments[1] = *m_depthView;
713 
714     const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
715 
716     m_renderPass.createFramebuffer(m_vk, device, &framebufferCreateInfo,
717                                    {m_colorTargetImage->object(), m_depthImage->object()});
718 }
719 
initPipeline(const vk::VkDevice device)720 void DepthBoundsTestInstance::initPipeline(const vk::VkDevice device)
721 {
722     // Shaders.
723     const auto &binaries       = m_context.getBinaryCollection();
724     const vk::ShaderWrapper fs = vk::ShaderWrapper(m_vk, device, binaries.get(m_fragmentShaderName));
725     const vk::ShaderWrapper vs =
726         (m_isMesh ? vk::ShaderWrapper() : vk::ShaderWrapper(m_vk, device, binaries.get(m_vertexShaderName)));
727     const vk::ShaderWrapper ms =
728         (m_isMesh ? vk::ShaderWrapper(m_vk, device, binaries.get(m_meshShaderName)) : vk::ShaderWrapper());
729     std::vector<vk::VkViewport> viewports{{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}};
730     std::vector<vk::VkRect2D> scissors{{{0u, 0u}, {0u, 0u}}};
731 
732     const PipelineCreateInfo::ColorBlendState::Attachment attachmentState;
733     const PipelineCreateInfo::ColorBlendState colorBlendState(
734         1u, static_cast<const vk::VkPipelineColorBlendAttachmentState *>(&attachmentState));
735     const PipelineCreateInfo::RasterizerState rasterizerState;
736     const PipelineCreateInfo::DepthStencilState::StencilOpState stencilOpState(
737         vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP);
738     const PipelineCreateInfo::DepthStencilState depthStencilState(false, false, vk::VK_COMPARE_OP_NEVER, true, 0u,
739                                                                   stencilOpState, stencilOpState);
740     const PipelineCreateInfo::DynamicState dynamicState;
741 
742     m_pipeline.setDefaultTopology(m_topology)
743         .setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo *>(&dynamicState))
744         .setDefaultMultisampleState();
745 
746 #ifndef CTS_USES_VULKANSC
747     if (m_isMesh)
748     {
749         m_pipeline.setupPreRasterizationMeshShaderState(
750             viewports, scissors, m_pipelineLayout, *m_renderPass, 0u, vk::ShaderWrapper(), ms,
751             static_cast<const vk::VkPipelineRasterizationStateCreateInfo *>(&rasterizerState));
752     }
753     else
754 #endif // CTS_USES_VULKANSC
755     {
756         m_pipeline.setupVertexInputState(&m_vertexInputState)
757             .setupPreRasterizationShaderState(
758                 viewports, scissors, m_pipelineLayout, *m_renderPass, 0u, vs,
759                 static_cast<const vk::VkPipelineRasterizationStateCreateInfo *>(&rasterizerState));
760     }
761 
762     m_pipeline
763         .setupFragmentShaderState(m_pipelineLayout, *m_renderPass, 0u, fs,
764                                   static_cast<const vk::VkPipelineDepthStencilStateCreateInfo *>(&depthStencilState))
765         .setupFragmentOutputState(*m_renderPass, 0u,
766                                   static_cast<const vk::VkPipelineColorBlendStateCreateInfo *>(&colorBlendState))
767         .setMonolithicPipelineLayout(m_pipelineLayout)
768         .buildPipeline();
769 }
770 
iterate(void)771 tcu::TestStatus DepthBoundsTestInstance::iterate(void)
772 {
773     tcu::TestLog &log         = m_context.getTestContext().getLog();
774     const vk::VkQueue queue   = m_context.getUniversalQueue();
775     const vk::VkDevice device = m_context.getDevice();
776 
777     // Prepare depth image
778     tcu::Texture2D depthData(vk::mapVkFormat(m_depthAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)),
779                              (int)(0.5f + static_cast<float>(HEIGHT)));
780     depthData.allocLevel(0);
781 
782     const int32_t depthDataWidth  = depthData.getWidth();
783     const int32_t depthDataHeight = depthData.getHeight();
784 
785     for (int y = 0; y < depthDataHeight; ++y)
786         for (int x = 0; x < depthDataWidth; ++x)
787             depthData.getLevel(0).setPixDepth((float)(y * depthDataWidth + x % 11) / 10, x, y);
788 
789     const vk::VkDeviceSize dataSize = depthData.getLevel(0).getWidth() * depthData.getLevel(0).getHeight() *
790                                       tcu::getPixelSize(mapVkFormat(m_depthAttachmentFormat));
791     de::SharedPtr<Draw::Buffer> stageBuffer =
792         Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
793                                m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
794 
795     uint8_t *ptr = reinterpret_cast<unsigned char *>(stageBuffer->getBoundMemory().getHostPtr());
796     deMemcpy(ptr, depthData.getLevel(0).getDataPtr(), (size_t)dataSize);
797 
798     vk::flushAlloc(m_vk, device, stageBuffer->getBoundMemory());
799 
800     beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
801 
802     initialTransitionDepth2DImage(m_vk, *m_cmdBuffer, m_depthImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
803                                   vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
804 
805     const vk::VkBufferImageCopy bufferImageCopy = {
806         (vk::VkDeviceSize)0, // VkDeviceSize bufferOffset;
807         0u,                  // uint32_t bufferRowLength;
808         0u,                  // uint32_t bufferImageHeight;
809         vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u,
810                                        1u), // VkImageSubresourceLayers imageSubresource;
811         vk::makeOffset3D(0, 0, 0),          // VkOffset3D imageOffset;
812         vk::makeExtent3D(WIDTH, HEIGHT, 1u) // VkExtent3D imageExtent;
813     };
814     m_vk.cmdCopyBufferToImage(*m_cmdBuffer, stageBuffer->object(), m_depthImage->object(),
815                               vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopy);
816 
817     transition2DImage(m_vk, *m_cmdBuffer, m_depthImage->object(), vk::VK_IMAGE_ASPECT_DEPTH_BIT,
818                       vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
819                       vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
820                       vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
821                       vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
822 
823     const vk::VkClearColorValue clearColor = {{1.0f, 1.0f, 1.0f, 1.0f}};
824     beginRenderPassWithClearColor(clearColor, true);
825 
826     // Bind states
827     setDynamicViewportState(WIDTH, HEIGHT);
828     setDynamicRasterizationState();
829     setDynamicBlendState();
830     setDynamicDepthStencilState(depthBounds[DEPTH_BOUNDS_MIN], depthBounds[DEPTH_BOUNDS_MAX]);
831 
832     m_pipeline.bind(*m_cmdBuffer);
833 
834 #ifndef CTS_USES_VULKANSC
835     if (m_isMesh)
836     {
837         const auto numVert = static_cast<uint32_t>(m_data.size());
838         DE_ASSERT(numVert >= 2u);
839 
840         m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u,
841                                    &m_descriptorSet.get(), 0u, nullptr);
842         pushVertexOffset(0u, *m_pipelineLayout);
843         m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u);
844     }
845     else
846 #endif // CTS_USES_VULKANSC
847     {
848 
849         const vk::VkDeviceSize vertexBufferOffset = 0;
850         const vk::VkBuffer vertexBuffer           = m_vertexBuffer->object();
851         m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
852 
853         m_vk.cmdDraw(*m_cmdBuffer, static_cast<uint32_t>(m_data.size()), 1, 0, 0);
854     }
855 
856     m_renderPass.end(m_vk, *m_cmdBuffer);
857     endCommandBuffer(m_vk, *m_cmdBuffer);
858 
859     submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
860 
861     // Validation
862     {
863         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)),
864                                       (int)(0.5f + static_cast<float>(HEIGHT)));
865         referenceFrame.allocLevel(0);
866 
867         const int32_t frameWidth  = referenceFrame.getWidth();
868         const int32_t frameHeight = referenceFrame.getHeight();
869 
870         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
871 
872         for (int y = 0; y < frameHeight; ++y)
873             for (int x = 0; x < frameWidth; ++x)
874                 if (depthData.getLevel(0).getPixDepth(x, y) >= depthBounds[DEPTH_BOUNDS_MIN] &&
875                     depthData.getLevel(0).getPixDepth(x, y) <= depthBounds[DEPTH_BOUNDS_MAX])
876                     referenceFrame.getLevel(0).setPixel(tcu::RGBA::green().toVec(), x, y);
877 
878         const vk::VkOffset3D zeroOffset = {0, 0, 0};
879         const tcu::ConstPixelBufferAccess renderedFrame =
880             m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), vk::VK_IMAGE_LAYOUT_GENERAL,
881                                             zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
882 
883         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame.getLevel(0), renderedFrame,
884                                0.05f, tcu::COMPARE_LOG_RESULT))
885         {
886             return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
887         }
888 
889         return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
890     }
891 }
892 
893 class StencilParamsBasicTestInstance : public DepthStencilBaseCase
894 {
895 protected:
896     uint32_t m_writeMask;
897     uint32_t m_readMask;
898     uint32_t m_expectedValue;
899     tcu::Vec4 m_expectedColor;
900 
901 public:
StencilParamsBasicTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const char * vertexShaderName,const char * fragmentShaderName,const char * meshShaderName,const uint32_t writeMask,const uint32_t readMask,const uint32_t expectedValue,const tcu::Vec4 expectedColor)902     StencilParamsBasicTestInstance(Context &context, vk::PipelineConstructionType pipelineConstructionType,
903                                    const char *vertexShaderName, const char *fragmentShaderName,
904                                    const char *meshShaderName, const uint32_t writeMask, const uint32_t readMask,
905                                    const uint32_t expectedValue, const tcu::Vec4 expectedColor)
906         : DepthStencilBaseCase(context, pipelineConstructionType, vertexShaderName, fragmentShaderName, meshShaderName)
907         , m_expectedColor(1.0f, 1.0f, 1.0f, 1.0f)
908     {
909         m_writeMask     = writeMask;
910         m_readMask      = readMask;
911         m_expectedValue = expectedValue;
912         m_expectedColor = expectedColor;
913 
914         m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
915         m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
916         m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
917         m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
918 
919         m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
920         m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
921         m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
922         m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
923 
924         const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_1 =
925             PipelineCreateInfo::DepthStencilState::StencilOpState(vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_REPLACE,
926                                                                   vk::VK_STENCIL_OP_REPLACE, vk::VK_COMPARE_OP_ALWAYS);
927 
928         const PipelineCreateInfo::DepthStencilState::StencilOpState backState_1 =
929             PipelineCreateInfo::DepthStencilState::StencilOpState(vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_REPLACE,
930                                                                   vk::VK_STENCIL_OP_REPLACE, vk::VK_COMPARE_OP_ALWAYS);
931 
932         const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_2 =
933             PipelineCreateInfo::DepthStencilState::StencilOpState(vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_REPLACE,
934                                                                   vk::VK_STENCIL_OP_REPLACE, vk::VK_COMPARE_OP_EQUAL);
935 
936         const PipelineCreateInfo::DepthStencilState::StencilOpState backState_2 =
937             PipelineCreateInfo::DepthStencilState::StencilOpState(vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_REPLACE,
938                                                                   vk::VK_STENCIL_OP_REPLACE, vk::VK_COMPARE_OP_EQUAL);
939 
940         // enable stencil test
941         m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER,
942                                                                       VK_FALSE, VK_TRUE, frontState_1, backState_1);
943 
944         m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER,
945                                                                       VK_FALSE, VK_TRUE, frontState_2, backState_2);
946 
947         DepthStencilBaseCase::initialize();
948     }
949 
iterate(void)950     virtual tcu::TestStatus iterate(void)
951     {
952         tcu::TestLog &log         = m_context.getTestContext().getLog();
953         const vk::VkQueue queue   = m_context.getUniversalQueue();
954         const vk::VkDevice device = m_context.getDevice();
955 
956         beginRenderPass();
957 
958         // set states here
959         setDynamicViewportState(WIDTH, HEIGHT);
960         setDynamicRasterizationState();
961         setDynamicBlendState();
962 
963 #ifndef CTS_USES_VULKANSC
964         if (m_isMesh)
965         {
966             m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u,
967                                        1u, &m_descriptorSet.get(), 0u, nullptr);
968 
969             m_pipeline_1.bind(*m_cmdBuffer);
970             setDynamicDepthStencilState(0.0f, 1.0f, 0xFF, m_writeMask, 0x0F, 0xFF, m_writeMask, 0x0F);
971             pushVertexOffset(0u);
972             m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
973 
974             m_pipeline_2.bind(*m_cmdBuffer);
975             setDynamicDepthStencilState(0.0f, 1.0f, m_readMask, 0xFF, m_expectedValue, m_readMask, 0xFF,
976                                         m_expectedValue);
977             pushVertexOffset(4u);
978             m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
979         }
980         else
981 #endif // CTS_USES_VULKANSC
982         {
983             const vk::VkDeviceSize vertexBufferOffset = 0;
984             const vk::VkBuffer vertexBuffer           = m_vertexBuffer->object();
985             m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
986 
987             m_pipeline_1.bind(*m_cmdBuffer);
988             setDynamicDepthStencilState(0.0f, 1.0f, 0xFF, m_writeMask, 0x0F, 0xFF, m_writeMask, 0x0F);
989             m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
990 
991             m_pipeline_2.bind(*m_cmdBuffer);
992             setDynamicDepthStencilState(0.0f, 1.0f, m_readMask, 0xFF, m_expectedValue, m_readMask, 0xFF,
993                                         m_expectedValue);
994             m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
995         }
996 
997         m_renderPass.end(m_vk, *m_cmdBuffer);
998         endCommandBuffer(m_vk, *m_cmdBuffer);
999 
1000         submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
1001 
1002         // validation
1003         {
1004             tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat),
1005                                           (int)(0.5f + static_cast<float>(WIDTH)),
1006                                           (int)(0.5f + static_cast<float>(HEIGHT)));
1007             referenceFrame.allocLevel(0);
1008 
1009             const int32_t frameWidth  = referenceFrame.getWidth();
1010             const int32_t frameHeight = referenceFrame.getHeight();
1011 
1012             for (int y = 0; y < frameHeight; y++)
1013             {
1014                 const float yCoord = (float)(y / (0.5 * frameHeight)) - 1.0f;
1015 
1016                 for (int x = 0; x < frameWidth; x++)
1017                 {
1018                     const float xCoord = (float)(x / (0.5 * frameWidth)) - 1.0f;
1019 
1020                     if (xCoord >= -1.0f && xCoord <= 1.0f && yCoord >= -1.0f && yCoord <= 1.0f)
1021                         referenceFrame.getLevel(0).setPixel(m_expectedColor, x, y);
1022                 }
1023             }
1024 
1025             const vk::VkOffset3D zeroOffset = {0, 0, 0};
1026             const tcu::ConstPixelBufferAccess renderedFrame =
1027                 m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), vk::VK_IMAGE_LAYOUT_GENERAL,
1028                                                 zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
1029 
1030             if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame.getLevel(0), renderedFrame,
1031                                    0.05f, tcu::COMPARE_LOG_RESULT))
1032             {
1033                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
1034             }
1035 
1036             return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
1037         }
1038     }
1039 };
1040 
checkNothing(Context &)1041 void checkNothing(Context &)
1042 {
1043 }
1044 
checkMeshShaderSupport(Context & context)1045 void checkMeshShaderSupport(Context &context)
1046 {
1047     context.requireDeviceFunctionality("VK_EXT_mesh_shader");
1048 }
1049 
1050 class StencilParamsBasicTestCase : public TestCase
1051 {
1052 protected:
createInstance(Context & context) const1053     TestInstance *createInstance(Context &context) const
1054     {
1055         return new StencilParamsBasicTestInstance(
1056             context, m_pipelineConstructionType, (m_isMesh ? nullptr : "VertexFetch.vert"), "VertexFetch.frag",
1057             (m_isMesh ? "VertexFetch.mesh" : nullptr), m_writeMask, m_readMask, m_expectedValue, m_expectedColor);
1058     }
1059 
initPrograms(vk::SourceCollections & programCollection) const1060     virtual void initPrograms(vk::SourceCollections &programCollection) const
1061     {
1062         programCollection.glslSources.add("VertexFetch.frag") << glu::FragmentSource(
1063             ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.frag"));
1064 
1065         if (m_isMesh)
1066         {
1067             programCollection.glslSources.add("VertexFetch.mesh")
1068                 << glu::MeshSource(
1069                        ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.mesh"))
1070                 << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1071         }
1072         else
1073         {
1074             programCollection.glslSources.add("VertexFetch.vert") << glu::VertexSource(
1075                 ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.vert"));
1076         }
1077     }
1078 
checkSupport(Context & context) const1079     virtual void checkSupport(Context &context) const
1080     {
1081         checkMeshShaderSupport(context);
1082         checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(),
1083                                               m_pipelineConstructionType);
1084     }
1085 
1086     vk::PipelineConstructionType m_pipelineConstructionType;
1087     uint32_t m_writeMask;
1088     uint32_t m_readMask;
1089     uint32_t m_expectedValue;
1090     tcu::Vec4 m_expectedColor;
1091     const bool m_isMesh;
1092 
1093 public:
StencilParamsBasicTestCase(tcu::TestContext & context,const std::string & name,const vk::PipelineConstructionType pipelineConstructionType,const uint32_t writeMask,const uint32_t readMask,const uint32_t expectedValue,const tcu::Vec4 expectedColor,const bool isMesh)1094     StencilParamsBasicTestCase(tcu::TestContext &context, const std::string &name,
1095                                const vk::PipelineConstructionType pipelineConstructionType, const uint32_t writeMask,
1096                                const uint32_t readMask, const uint32_t expectedValue, const tcu::Vec4 expectedColor,
1097                                const bool isMesh)
1098         : TestCase(context, name)
1099         , m_pipelineConstructionType(pipelineConstructionType)
1100         , m_writeMask(writeMask)
1101         , m_readMask(readMask)
1102         , m_expectedValue(expectedValue)
1103         , m_expectedColor(expectedColor)
1104         , m_isMesh(isMesh)
1105     {
1106     }
1107 };
1108 
1109 class StencilParamsAdvancedTestInstance : public DepthStencilBaseCase
1110 {
1111 public:
StencilParamsAdvancedTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)1112     StencilParamsAdvancedTestInstance(Context &context, vk::PipelineConstructionType pipelineConstructionType,
1113                                       const ShaderMap &shaders)
1114         : DepthStencilBaseCase(context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX),
1115                                shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
1116     {
1117         m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
1118         m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
1119         m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
1120         m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
1121 
1122         m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
1123         m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
1124         m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
1125         m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
1126 
1127         const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_1 =
1128             PipelineCreateInfo::DepthStencilState::StencilOpState(vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_REPLACE,
1129                                                                   vk::VK_STENCIL_OP_REPLACE, vk::VK_COMPARE_OP_ALWAYS);
1130 
1131         const PipelineCreateInfo::DepthStencilState::StencilOpState backState_1 =
1132             PipelineCreateInfo::DepthStencilState::StencilOpState(vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_REPLACE,
1133                                                                   vk::VK_STENCIL_OP_REPLACE, vk::VK_COMPARE_OP_ALWAYS);
1134 
1135         const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_2 =
1136             PipelineCreateInfo::DepthStencilState::StencilOpState(vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_REPLACE,
1137                                                                   vk::VK_STENCIL_OP_REPLACE,
1138                                                                   vk::VK_COMPARE_OP_NOT_EQUAL);
1139 
1140         const PipelineCreateInfo::DepthStencilState::StencilOpState backState_2 =
1141             PipelineCreateInfo::DepthStencilState::StencilOpState(vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_REPLACE,
1142                                                                   vk::VK_STENCIL_OP_REPLACE,
1143                                                                   vk::VK_COMPARE_OP_NOT_EQUAL);
1144 
1145         // enable stencil test
1146         m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER,
1147                                                                       VK_FALSE, VK_TRUE, frontState_1, backState_1);
1148 
1149         m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER,
1150                                                                       VK_FALSE, VK_TRUE, frontState_2, backState_2);
1151 
1152         DepthStencilBaseCase::initialize();
1153     }
1154 
iterate(void)1155     virtual tcu::TestStatus iterate(void)
1156     {
1157         tcu::TestLog &log         = m_context.getTestContext().getLog();
1158         const vk::VkQueue queue   = m_context.getUniversalQueue();
1159         const vk::VkDevice device = m_context.getDevice();
1160 
1161         beginRenderPass();
1162 
1163         // set states here
1164         setDynamicViewportState(WIDTH, HEIGHT);
1165         setDynamicRasterizationState();
1166         setDynamicBlendState();
1167 
1168 #ifndef CTS_USES_VULKANSC
1169         if (m_isMesh)
1170         {
1171             m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u,
1172                                        1u, &m_descriptorSet.get(), 0u, nullptr);
1173 
1174             m_pipeline_1.bind(*m_cmdBuffer);
1175             setDynamicDepthStencilState(0.0f, 1.0f, 0xFF, 0x0E, 0x0F, 0xFF, 0x0E, 0x0F);
1176             pushVertexOffset(0u);
1177             m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
1178 
1179             m_pipeline_2.bind(*m_cmdBuffer);
1180             setDynamicDepthStencilState(0.0f, 1.0f, 0xFF, 0xFF, 0x0E, 0xFF, 0xFF, 0x0E);
1181             pushVertexOffset(4u);
1182             m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, 2u, 1u, 1u);
1183         }
1184         else
1185 #endif // CTS_USES_VULKANSC
1186         {
1187             const vk::VkDeviceSize vertexBufferOffset = 0;
1188             const vk::VkBuffer vertexBuffer           = m_vertexBuffer->object();
1189             m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
1190 
1191             m_pipeline_1.bind(*m_cmdBuffer);
1192             setDynamicDepthStencilState(0.0f, 1.0f, 0xFF, 0x0E, 0x0F, 0xFF, 0x0E, 0x0F);
1193             m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
1194 
1195             m_pipeline_2.bind(*m_cmdBuffer);
1196             setDynamicDepthStencilState(0.0f, 1.0f, 0xFF, 0xFF, 0x0E, 0xFF, 0xFF, 0x0E);
1197             m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
1198         }
1199 
1200         m_renderPass.end(m_vk, *m_cmdBuffer);
1201         endCommandBuffer(m_vk, *m_cmdBuffer);
1202 
1203         submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
1204 
1205         // validation
1206         {
1207             tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat),
1208                                           (int)(0.5f + static_cast<float>(WIDTH)),
1209                                           (int)(0.5f + static_cast<float>(HEIGHT)));
1210             referenceFrame.allocLevel(0);
1211 
1212             const int32_t frameWidth  = referenceFrame.getWidth();
1213             const int32_t frameHeight = referenceFrame.getHeight();
1214 
1215             for (int y = 0; y < frameHeight; y++)
1216             {
1217                 const float yCoord = (float)(y / (0.5 * frameHeight)) - 1.0f;
1218 
1219                 for (int x = 0; x < frameWidth; x++)
1220                 {
1221                     const float xCoord = (float)(x / (0.5 * frameWidth)) - 1.0f;
1222 
1223                     if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
1224                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
1225                     else
1226                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
1227                 }
1228             }
1229 
1230             const vk::VkOffset3D zeroOffset = {0, 0, 0};
1231             const tcu::ConstPixelBufferAccess renderedFrame =
1232                 m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), vk::VK_IMAGE_LAYOUT_GENERAL,
1233                                                 zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
1234 
1235             if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame.getLevel(0), renderedFrame,
1236                                    0.05f, tcu::COMPARE_LOG_RESULT))
1237             {
1238                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
1239             }
1240 
1241             return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
1242         }
1243     }
1244 };
1245 
checkDepthBoundsSupport(Context & context)1246 void checkDepthBoundsSupport(Context &context)
1247 {
1248     context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BOUNDS);
1249 }
1250 
1251 #ifndef CTS_USES_VULKANSC
checkDepthBoundsAndMeshShaderSupport(Context & context)1252 void checkDepthBoundsAndMeshShaderSupport(Context &context)
1253 {
1254     checkDepthBoundsSupport(context);
1255     checkMeshShaderSupport(context);
1256 }
1257 #endif // CTS_USES_VULKANSC
1258 
1259 } // namespace
1260 
1261 // Tests for depth stencil state
DynamicStateDSTests(tcu::TestContext & testCtx,vk::PipelineConstructionType pipelineConstructionType)1262 DynamicStateDSTests::DynamicStateDSTests(tcu::TestContext &testCtx,
1263                                          vk::PipelineConstructionType pipelineConstructionType)
1264     : TestCaseGroup(testCtx, "ds_state")
1265     , m_pipelineConstructionType(pipelineConstructionType)
1266 {
1267     /* Left blank on purpose */
1268 }
1269 
~DynamicStateDSTests()1270 DynamicStateDSTests::~DynamicStateDSTests()
1271 {
1272 }
1273 
init(void)1274 void DynamicStateDSTests::init(void)
1275 {
1276     ShaderMap basePaths;
1277     basePaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
1278     basePaths[glu::SHADERTYPE_MESH]     = nullptr;
1279     basePaths[glu::SHADERTYPE_VERTEX]   = nullptr;
1280 
1281     for (int useMeshIdx = 0; useMeshIdx < 2; ++useMeshIdx)
1282     {
1283         const bool useMesh = (useMeshIdx > 0);
1284         ShaderMap shaderPaths(basePaths);
1285         FunctionSupport0::Function depthBoundsCheck = nullptr;
1286         FunctionSupport0::Function meshSupportCheck = (useMesh ? checkMeshShaderSupport : checkNothing);
1287         std::string nameSuffix;
1288 
1289         if (useMesh)
1290         {
1291 #ifndef CTS_USES_VULKANSC
1292             shaderPaths[glu::SHADERTYPE_MESH] = "vulkan/dynamic_state/VertexFetch.mesh";
1293             depthBoundsCheck                  = checkDepthBoundsAndMeshShaderSupport;
1294             nameSuffix                        = "_mesh";
1295 #else
1296             continue;
1297 #endif // CTS_USES_VULKANSC
1298         }
1299         else
1300         {
1301             shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
1302             depthBoundsCheck                    = checkDepthBoundsSupport;
1303         }
1304 
1305         addChild(new InstanceFactory<DepthBoundsParamTestInstance, FunctionSupport0>(
1306             m_testCtx, "depth_bounds_1" + nameSuffix, m_pipelineConstructionType, shaderPaths, depthBoundsCheck));
1307         addChild(new InstanceFactory<DepthBoundsTestInstance, FunctionSupport0>(
1308             m_testCtx, "depth_bounds_2" + nameSuffix, m_pipelineConstructionType, shaderPaths, depthBoundsCheck));
1309 #ifndef CTS_USES_VULKANSC
1310         addChild(new StencilParamsBasicTestCase(m_testCtx, "stencil_params_basic_1" + nameSuffix,
1311                                                 m_pipelineConstructionType, 0x0D, 0x06, 0x05,
1312                                                 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), useMesh));
1313         addChild(new StencilParamsBasicTestCase(m_testCtx, "stencil_params_basic_2" + nameSuffix,
1314                                                 m_pipelineConstructionType, 0x06, 0x02, 0x05,
1315                                                 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), useMesh));
1316 #endif // CTS_USES_VULKANSC
1317         addChild(new InstanceFactory<StencilParamsAdvancedTestInstance, FunctionSupport0>(
1318             m_testCtx, "stencil_params_advanced" + nameSuffix, m_pipelineConstructionType, shaderPaths,
1319             meshSupportCheck));
1320     }
1321 }
1322 
1323 } // namespace DynamicState
1324 } // namespace vkt
1325