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 Tests - General
25 *//*--------------------------------------------------------------------*/
26
27 #include "vktDynamicStateGeneralTests.hpp"
28
29 #include "vktTestCaseUtil.hpp"
30 #include "vktDynamicStateTestCaseUtil.hpp"
31 #include "vktDynamicStateBaseClass.hpp"
32 #include "vktDrawCreateInfoUtil.hpp"
33 #include "vktDrawImageObjectUtil.hpp"
34 #include "vktDrawBufferObjectUtil.hpp"
35
36 #include "vkImageUtil.hpp"
37 #include "vkCmdUtil.hpp"
38
39 #include "tcuTestLog.hpp"
40 #include "tcuResource.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuTextureUtil.hpp"
43 #include "tcuRGBA.hpp"
44
45 #include "vkDefs.hpp"
46 #include "vkCmdUtil.hpp"
47
48 namespace vkt
49 {
50 namespace DynamicState
51 {
52
53 using namespace Draw;
54
55 namespace
56 {
57
58 class StateSwitchTestInstance : public DynamicStateBaseClass
59 {
60 public:
StateSwitchTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)61 StateSwitchTestInstance (Context &context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
62 : DynamicStateBaseClass (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
63 {
64 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
65 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
66 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
67 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
68
69 DynamicStateBaseClass::initialize();
70 }
71
iterate(void)72 virtual tcu::TestStatus iterate (void)
73 {
74 tcu::TestLog& log = m_context.getTestContext().getLog();
75 const vk::VkQueue queue = m_context.getUniversalQueue();
76 const vk::VkDevice device = m_context.getDevice();
77
78 beginRenderPass();
79
80 // bind states here
81 vk::VkViewport viewport = { 0, 0, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
82 vk::VkRect2D scissor_1 = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
83 vk::VkRect2D scissor_2 = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
84
85 setDynamicRasterizationState();
86 setDynamicBlendState();
87 setDynamicDepthStencilState();
88
89 m_pipeline.bind(*m_cmdBuffer);
90
91 #ifndef CTS_USES_VULKANSC
92 if (m_isMesh)
93 {
94 const auto numVert = static_cast<uint32_t>(m_data.size());
95 DE_ASSERT(numVert >= 2u);
96
97 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
98 pushVertexOffset(0u, *m_pipelineLayout);
99
100 // bind first state
101 setDynamicViewportState(1, &viewport, &scissor_1);
102 m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u);
103
104 // bind second state
105 setDynamicViewportState(1, &viewport, &scissor_2);
106 m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u);
107 }
108 else
109 #endif // CTS_USES_VULKANSC
110 {
111 const vk::VkDeviceSize vertexBufferOffset = 0;
112 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
113 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
114
115 // bind first state
116 setDynamicViewportState(1, &viewport, &scissor_1);
117 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
118
119 // bind second state
120 setDynamicViewportState(1, &viewport, &scissor_2);
121 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
122 }
123
124 m_renderPass.end(m_vk, *m_cmdBuffer);
125 endCommandBuffer(m_vk, *m_cmdBuffer);
126
127 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
128
129 //validation
130 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
131 referenceFrame.allocLevel(0);
132
133 const deInt32 frameWidth = referenceFrame.getWidth();
134 const deInt32 frameHeight = referenceFrame.getHeight();
135
136 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
137
138 for (int y = 0; y < frameHeight; y++)
139 {
140 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
141
142 for (int x = 0; x < frameWidth; x++)
143 {
144 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
145
146 if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) ||
147 (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f))
148 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
149 }
150 }
151
152 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
153 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
154 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT,
155 vk::VK_IMAGE_ASPECT_COLOR_BIT);
156
157 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
158 referenceFrame.getLevel(0), renderedFrame, 0.05f,
159 tcu::COMPARE_LOG_RESULT))
160 {
161
162 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
163 }
164
165 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
166 }
167 };
168
169 class BindOrderTestInstance : public DynamicStateBaseClass
170 {
171 public:
BindOrderTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)172 BindOrderTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
173 : DynamicStateBaseClass (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
174 {
175 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
176 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
177 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
178 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
179
180 DynamicStateBaseClass::initialize();
181 }
182
iterate(void)183 virtual tcu::TestStatus iterate (void)
184 {
185 tcu::TestLog &log = m_context.getTestContext().getLog();
186 const vk::VkQueue queue = m_context.getUniversalQueue();
187 const vk::VkDevice device = m_context.getDevice();
188
189 beginRenderPass();
190
191 // bind states here
192 vk::VkViewport viewport = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
193 vk::VkRect2D scissor_1 = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
194 vk::VkRect2D scissor_2 = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
195
196 setDynamicRasterizationState();
197 setDynamicBlendState();
198 setDynamicDepthStencilState();
199 setDynamicViewportState(1, &viewport, &scissor_1);
200
201 m_pipeline.bind(*m_cmdBuffer);
202
203 #ifndef CTS_USES_VULKANSC
204 if (m_isMesh)
205 {
206 const auto numVert = static_cast<uint32_t>(m_data.size());
207 DE_ASSERT(numVert >= 2u);
208
209 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
210 pushVertexOffset(0u, *m_pipelineLayout);
211
212 // rebind in different order
213 setDynamicBlendState();
214 setDynamicRasterizationState();
215 setDynamicDepthStencilState();
216
217 // bind first state
218 setDynamicViewportState(1, &viewport, &scissor_1);
219 m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u);
220
221 setDynamicViewportState(1, &viewport, &scissor_2);
222 m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u);
223 }
224 else
225 #endif // CTS_USES_VULKANSC
226 {
227 const vk::VkDeviceSize vertexBufferOffset = 0;
228 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
229 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
230
231 // rebind in different order
232 setDynamicBlendState();
233 setDynamicRasterizationState();
234 setDynamicDepthStencilState();
235
236 // bind first state
237 setDynamicViewportState(1, &viewport, &scissor_1);
238 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
239
240 setDynamicViewportState(1, &viewport, &scissor_2);
241 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
242 }
243
244 m_renderPass.end(m_vk, *m_cmdBuffer);
245 endCommandBuffer(m_vk, *m_cmdBuffer);
246
247 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
248
249 //validation
250 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
251 referenceFrame.allocLevel(0);
252
253 const deInt32 frameWidth = referenceFrame.getWidth();
254 const deInt32 frameHeight = referenceFrame.getHeight();
255
256 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
257
258 for (int y = 0; y < frameHeight; y++)
259 {
260 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
261
262 for (int x = 0; x < frameWidth; x++)
263 {
264 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
265
266 if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) ||
267 (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f))
268 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
269 }
270 }
271
272 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
273 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
274 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
275
276 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
277 referenceFrame.getLevel(0), renderedFrame, 0.05f,
278 tcu::COMPARE_LOG_RESULT))
279 {
280 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
281 }
282
283 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
284 }
285 };
286
287 class StatePersistenceTestInstance : public DynamicStateBaseClass
288 {
289 protected:
290 vk::GraphicsPipelineWrapper m_pipelineAdditional;
291
292 public:
StatePersistenceTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)293 StatePersistenceTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
294 : DynamicStateBaseClass (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
295 , m_pipelineAdditional (context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType)
296 {
297 // This test does not make sense for mesh shader variants.
298 DE_ASSERT(!m_isMesh);
299
300 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
301 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
302 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
303 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
304
305 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
306 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
307 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
308 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
309 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
310 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
311
312 DynamicStateBaseClass::initialize();
313 }
initPipeline(const vk::VkDevice device)314 virtual void initPipeline (const vk::VkDevice device)
315 {
316 const vk::ShaderWrapper vs (vk::ShaderWrapper(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
317 const vk::ShaderWrapper fs (vk::ShaderWrapper(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
318 std::vector<vk::VkViewport> viewports { { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } };
319 std::vector<vk::VkRect2D> scissors { { { 0u, 0u }, { 0u, 0u } } };
320
321 const PipelineCreateInfo::ColorBlendState::Attachment attachmentState;
322 const PipelineCreateInfo::ColorBlendState colorBlendState(1, static_cast<const vk::VkPipelineColorBlendAttachmentState*>(&attachmentState));
323 const PipelineCreateInfo::RasterizerState rasterizerState;
324 const PipelineCreateInfo::DepthStencilState depthStencilState;
325 const PipelineCreateInfo::DynamicState dynamicState;
326
327 m_pipeline.setDefaultTopology(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
328 .setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicState))
329 .setDefaultMultisampleState()
330 .setupVertexInputState(&m_vertexInputState)
331 .setupPreRasterizationShaderState(viewports,
332 scissors,
333 m_pipelineLayout,
334 *m_renderPass,
335 0u,
336 vs,
337 static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState))
338 .setupFragmentShaderState(m_pipelineLayout, *m_renderPass, 0u, fs, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&depthStencilState))
339 .setupFragmentOutputState(*m_renderPass, 0u, static_cast<const vk::VkPipelineColorBlendStateCreateInfo*>(&colorBlendState))
340 .setMonolithicPipelineLayout(m_pipelineLayout)
341 .buildPipeline();
342
343 m_pipelineAdditional.setDefaultTopology(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
344 .setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicState))
345 .setDefaultMultisampleState()
346 .setupVertexInputState(&m_vertexInputState)
347 .setupPreRasterizationShaderState(viewports,
348 scissors,
349 m_pipelineLayout,
350 *m_renderPass,
351 0u,
352 vs,
353 static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState))
354 .setupFragmentShaderState(m_pipelineLayout, *m_renderPass, 0u, fs, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&depthStencilState))
355 .setupFragmentOutputState(*m_renderPass, 0u, static_cast<const vk::VkPipelineColorBlendStateCreateInfo*>(&colorBlendState))
356 .setMonolithicPipelineLayout(m_pipelineLayout)
357 .buildPipeline();
358 }
359
iterate(void)360 virtual tcu::TestStatus iterate(void)
361 {
362 tcu::TestLog& log = m_context.getTestContext().getLog();
363 const vk::VkQueue queue = m_context.getUniversalQueue();
364 const vk::VkDevice device = m_context.getDevice();
365
366 beginRenderPass();
367
368 // bind states here
369 const vk::VkViewport viewport = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
370 const vk::VkRect2D scissor_1 = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
371 const vk::VkRect2D scissor_2 = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
372
373 setDynamicRasterizationState();
374 setDynamicBlendState();
375 setDynamicDepthStencilState();
376
377 m_pipeline.bind(*m_cmdBuffer);
378
379 const vk::VkDeviceSize vertexBufferOffset = 0;
380 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
381 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
382
383 // bind first state
384 setDynamicViewportState(1, &viewport, &scissor_1);
385 // draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
386 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
387
388 m_pipelineAdditional.bind(*m_cmdBuffer);
389
390 // bind second state
391 setDynamicViewportState(1, &viewport, &scissor_2);
392 // draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
393 m_vk.cmdDraw(*m_cmdBuffer, 6, 1, 4, 0);
394
395 m_renderPass.end(m_vk, *m_cmdBuffer);
396 endCommandBuffer(m_vk, *m_cmdBuffer);
397
398 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
399
400 //validation
401 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
402 referenceFrame.allocLevel(0);
403
404 const deInt32 frameWidth = referenceFrame.getWidth();
405 const deInt32 frameHeight = referenceFrame.getHeight();
406
407 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
408
409 for (int y = 0; y < frameHeight; y++)
410 {
411 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
412
413 for (int x = 0; x < frameWidth; x++)
414 {
415 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
416
417 if (yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f)
418 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
419 else if (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f)
420 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
421 }
422 }
423
424 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
425 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
426 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
427
428 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
429 referenceFrame.getLevel(0), renderedFrame, 0.05f,
430 tcu::COMPARE_LOG_RESULT))
431 {
432 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
433 }
434
435 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
436 }
437 };
438
439 #ifndef CTS_USES_VULKANSC
checkMeshShaderSupport(Context & context)440 void checkMeshShaderSupport (Context& context)
441 {
442 context.requireDeviceFunctionality("VK_EXT_mesh_shader");
443 }
444 #endif // CTS_USES_VULKANSC
445
checkNothing(Context &)446 void checkNothing (Context&)
447 {
448 }
449
450 } //anonymous
451
452 // General tests for dynamic states
DynamicStateGeneralTests(tcu::TestContext & testCtx,vk::PipelineConstructionType pipelineConstructionType)453 DynamicStateGeneralTests::DynamicStateGeneralTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)
454 : TestCaseGroup (testCtx, "general_state")
455 , m_pipelineConstructionType (pipelineConstructionType)
456 {
457 /* Left blank on purpose */
458 }
459
~DynamicStateGeneralTests(void)460 DynamicStateGeneralTests::~DynamicStateGeneralTests (void) {}
461
init(void)462 void DynamicStateGeneralTests::init (void)
463 {
464 ShaderMap basePaths;
465 basePaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
466 basePaths[glu::SHADERTYPE_MESH] = nullptr;
467 basePaths[glu::SHADERTYPE_VERTEX] = nullptr;
468
469 for (int i = 0; i < 2; ++i)
470 {
471 const bool isMesh = (i > 0);
472 ShaderMap shaderPaths (basePaths);
473 std::string nameSuffix;
474 FunctionSupport0::Function checkSupportFunc;
475
476 if (isMesh)
477 {
478 #ifndef CTS_USES_VULKANSC
479 shaderPaths[glu::SHADERTYPE_MESH] = "vulkan/dynamic_state/VertexFetch.mesh";
480 nameSuffix = "_mesh";
481 checkSupportFunc = checkMeshShaderSupport;
482 #else
483 continue;
484 #endif // CTS_USES_VULKANSC
485 }
486 else
487 {
488 shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
489 checkSupportFunc = checkNothing;
490 }
491
492 // Perform multiple draws with different VP states (scissor test)
493 addChild(new InstanceFactory<StateSwitchTestInstance, FunctionSupport0>(m_testCtx, "state_switch" + nameSuffix, m_pipelineConstructionType, shaderPaths, checkSupportFunc));
494 // Check if binding order is not important for pipeline configuration
495 addChild(new InstanceFactory<BindOrderTestInstance, FunctionSupport0>(m_testCtx, "bind_order" + nameSuffix, m_pipelineConstructionType, shaderPaths, checkSupportFunc));
496 if (!isMesh) {
497 // Check if bound states are persistent across pipelines
498 addChild(new InstanceFactory<StatePersistenceTestInstance>(m_testCtx, "state_persistence" + nameSuffix, m_pipelineConstructionType, shaderPaths));
499 }
500 }
501 }
502
503 } // DynamicState
504 } // vkt
505