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