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