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