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