Merge vk-gl-cts/opengl-cts-4.6.0 into vk-gl-cts/master
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / dynamic_state / vktDynamicStateGeneralTests.cpp
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
36 #include "tcuTestLog.hpp"
37 #include "tcuResource.hpp"
38 #include "tcuImageCompare.hpp"
39 #include "tcuTextureUtil.hpp"
40 #include "tcuRGBA.hpp"
41
42 #include "vkDefs.hpp"
43
44 namespace vkt
45 {
46 namespace DynamicState
47 {
48
49 using namespace Draw;
50
51 namespace
52 {
53
54 class StateSwitchTestInstance : public DynamicStateBaseClass
55 {
56 public:
57         StateSwitchTestInstance (Context &context, ShaderMap shaders)
58                 : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
59         {
60                 m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
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
70         virtual tcu::TestStatus iterate (void)
71         {
72                 tcu::TestLog& log               = m_context.getTestContext().getLog();
73                 const vk::VkQueue queue = m_context.getUniversalQueue();
74
75                 beginRenderPass();
76
77                 // bind states here
78                 vk::VkViewport viewport = { 0, 0, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
79                 vk::VkRect2D scissor_1  = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
80                 vk::VkRect2D scissor_2  = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
81
82                 setDynamicRasterizationState();
83                 setDynamicBlendState();
84                 setDynamicDepthStencilState();
85
86                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
87
88                 const vk::VkDeviceSize vertexBufferOffset       = 0;
89                 const vk::VkBuffer vertexBuffer                         = m_vertexBuffer->object();
90                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
91
92                 // bind first state
93                 setDynamicViewportState(1, &viewport, &scissor_1);
94                 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
95
96                 // bind second state
97                 setDynamicViewportState(1, &viewport, &scissor_2);
98                 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
99
100                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
101                 m_vk.endCommandBuffer(*m_cmdBuffer);
102
103                 vk::VkSubmitInfo submitInfo =
104                 {
105                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
106                         DE_NULL,                                                        // const void*                          pNext;
107                         0,                                                                      // deUint32                                     waitSemaphoreCount;
108                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
109                         (const vk::VkPipelineStageFlags*)DE_NULL,
110                         1,                                                                      // deUint32                                     commandBufferCount;
111                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
112                         0,                                                                      // deUint32                                     signalSemaphoreCount;
113                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
114                 };
115                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
116
117                 //validation
118                 VK_CHECK(m_vk.queueWaitIdle(queue));
119
120                 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
121                 referenceFrame.allocLevel(0);
122
123                 const deInt32 frameWidth        = referenceFrame.getWidth();
124                 const deInt32 frameHeight       = referenceFrame.getHeight();
125
126                 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
127
128                 for (int y = 0; y < frameHeight; y++)
129                 {
130                         const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
131
132                         for (int x = 0; x < frameWidth; x++)
133                         {
134                                 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
135
136                                 if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) ||
137                                         (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f))
138                                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
139                         }
140                 }
141
142                 const vk::VkOffset3D zeroOffset                                 = { 0, 0, 0 };
143                 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
144                                                                                                                                                                                   vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT,
145                                                                                                                                                                                   vk::VK_IMAGE_ASPECT_COLOR_BIT);
146
147                 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
148                         referenceFrame.getLevel(0), renderedFrame, 0.05f,
149                         tcu::COMPARE_LOG_RESULT))
150                 {
151
152                         return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
153                 }
154
155                 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
156         }
157 };
158
159 class BindOrderTestInstance : public DynamicStateBaseClass
160 {
161 public:
162         BindOrderTestInstance (Context& context, ShaderMap shaders)
163                 : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
164         {
165                 m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
166
167                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
168                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
169                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
170                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
171
172                 DynamicStateBaseClass::initialize();
173         }
174
175         virtual tcu::TestStatus iterate (void)
176         {
177                 tcu::TestLog &log               = m_context.getTestContext().getLog();
178                 const vk::VkQueue queue = m_context.getUniversalQueue();
179
180                 beginRenderPass();
181
182                 // bind states here
183                 vk::VkViewport viewport = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
184                 vk::VkRect2D scissor_1  = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
185                 vk::VkRect2D scissor_2  = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
186
187                 setDynamicRasterizationState();
188                 setDynamicBlendState();
189                 setDynamicDepthStencilState();
190                 setDynamicViewportState(1, &viewport, &scissor_1);
191
192                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
193
194                 const vk::VkDeviceSize vertexBufferOffset = 0;
195                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
196                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
197
198                 // rebind in different order
199                 setDynamicBlendState();
200                 setDynamicRasterizationState();
201                 setDynamicDepthStencilState();
202
203                 // bind first state
204                 setDynamicViewportState(1, &viewport, &scissor_1);
205                 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
206
207                 setDynamicViewportState(1, &viewport, &scissor_2);
208                 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
209
210                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
211                 m_vk.endCommandBuffer(*m_cmdBuffer);
212
213                 vk::VkSubmitInfo submitInfo =
214                 {
215                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
216                         DE_NULL,                                                        // const void*                          pNext;
217                         0,                                                                      // deUint32                                     waitSemaphoreCount;
218                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
219                         (const vk::VkPipelineStageFlags*)DE_NULL,
220                         1,                                                                      // deUint32                                     commandBufferCount;
221                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
222                         0,                                                                      // deUint32                                     signalSemaphoreCount;
223                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
224                 };
225                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
226
227                 //validation
228                 VK_CHECK(m_vk.queueWaitIdle(queue));
229
230                 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
231                 referenceFrame.allocLevel(0);
232
233                 const deInt32 frameWidth = referenceFrame.getWidth();
234                 const deInt32 frameHeight = referenceFrame.getHeight();
235
236                 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
237
238                 for (int y = 0; y < frameHeight; y++)
239                 {
240                         const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
241
242                         for (int x = 0; x < frameWidth; x++)
243                         {
244                                 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
245
246                                 if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) ||
247                                         (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f))
248                                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
249                         }
250                 }
251
252                 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
253                 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
254                         vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
255
256                 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
257                         referenceFrame.getLevel(0), renderedFrame, 0.05f,
258                         tcu::COMPARE_LOG_RESULT))
259                 {
260                         return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
261                 }
262
263                 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
264         }
265 };
266
267 class StatePersistenceTestInstance : public DynamicStateBaseClass
268 {
269 protected:
270         vk::Move<vk::VkPipeline> m_pipelineAdditional;
271
272 public:
273         StatePersistenceTestInstance (Context& context, ShaderMap shaders)
274                 : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
275         {
276                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
277                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
278                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
279                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
280
281                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
282                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
283                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
284                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
285                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
286                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
287
288                 DynamicStateBaseClass::initialize();
289         }
290         virtual void initPipeline (const vk::VkDevice device)
291         {
292                 // shaders
293                 const vk::Unique<vk::VkShaderModule> vs (createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
294                 const vk::Unique<vk::VkShaderModule> fs (createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
295
296                 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
297
298                 PipelineCreateInfo pipelineCreateInfo_1(*m_pipelineLayout, *m_renderPass, 0, 0);
299                 pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
300                 pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
301                 pipelineCreateInfo_1.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
302                 pipelineCreateInfo_1.addState(PipelineCreateInfo::InputAssemblerState(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP));
303                 pipelineCreateInfo_1.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
304                 pipelineCreateInfo_1.addState(PipelineCreateInfo::ViewportState(1));
305                 pipelineCreateInfo_1.addState(PipelineCreateInfo::DepthStencilState());
306                 pipelineCreateInfo_1.addState(PipelineCreateInfo::RasterizerState());
307                 pipelineCreateInfo_1.addState(PipelineCreateInfo::MultiSampleState());
308                 pipelineCreateInfo_1.addState(PipelineCreateInfo::DynamicState());
309
310                 PipelineCreateInfo pipelineCreateInfo_2(*m_pipelineLayout, *m_renderPass, 0, 0);
311                 pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
312                 pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
313                 pipelineCreateInfo_2.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
314                 pipelineCreateInfo_2.addState(PipelineCreateInfo::InputAssemblerState(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
315                 pipelineCreateInfo_2.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
316                 pipelineCreateInfo_2.addState(PipelineCreateInfo::ViewportState(1));
317                 pipelineCreateInfo_2.addState(PipelineCreateInfo::DepthStencilState());
318                 pipelineCreateInfo_2.addState(PipelineCreateInfo::RasterizerState());
319                 pipelineCreateInfo_2.addState(PipelineCreateInfo::MultiSampleState());
320                 pipelineCreateInfo_2.addState(PipelineCreateInfo::DynamicState());
321
322                 m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_1);
323                 m_pipelineAdditional = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_2);
324         }
325
326         virtual tcu::TestStatus iterate(void)
327         {
328                 tcu::TestLog &log                               = m_context.getTestContext().getLog();
329                 const vk::VkQueue queue                 = m_context.getUniversalQueue();
330
331                 beginRenderPass();
332
333                 // bind states here
334                 const vk::VkViewport viewport   = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
335                 const vk::VkRect2D scissor_1    = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
336                 const vk::VkRect2D scissor_2    = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
337
338                 setDynamicRasterizationState();
339                 setDynamicBlendState();
340                 setDynamicDepthStencilState();
341
342                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
343
344                 const vk::VkDeviceSize vertexBufferOffset = 0;
345                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
346                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
347
348                 // bind first state
349                 setDynamicViewportState(1, &viewport, &scissor_1);
350                 // draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
351                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
352
353                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineAdditional);
354
355                 // bind second state
356                 setDynamicViewportState(1, &viewport, &scissor_2);
357                 // draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
358                 m_vk.cmdDraw(*m_cmdBuffer, 6, 1, 4, 0);
359
360                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
361                 m_vk.endCommandBuffer(*m_cmdBuffer);
362
363                 vk::VkSubmitInfo submitInfo =
364                 {
365                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
366                         DE_NULL,                                                        // const void*                          pNext;
367                         0,                                                                      // deUint32                                     waitSemaphoreCount;
368                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
369                         (const vk::VkPipelineStageFlags*)DE_NULL,
370                         1,                                                                      // deUint32                                     commandBufferCount;
371                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
372                         0,                                                                      // deUint32                                     signalSemaphoreCount;
373                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
374                 };
375                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
376
377                 //validation
378                 VK_CHECK(m_vk.queueWaitIdle(queue));
379
380                 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
381                 referenceFrame.allocLevel(0);
382
383                 const deInt32 frameWidth        = referenceFrame.getWidth();
384                 const deInt32 frameHeight       = referenceFrame.getHeight();
385
386                 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
387
388                 for (int y = 0; y < frameHeight; y++)
389                 {
390                         const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
391
392                         for (int x = 0; x < frameWidth; x++)
393                         {
394                                 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
395
396                                 if (yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f)
397                                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
398                                 else if (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f)
399                                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
400                         }
401                 }
402
403                 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
404                 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
405                         vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
406
407                 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
408                         referenceFrame.getLevel(0), renderedFrame, 0.05f,
409                         tcu::COMPARE_LOG_RESULT))
410                 {
411                         return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
412                 }
413
414                 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
415         }
416 };
417
418 } //anonymous
419
420 DynamicStateGeneralTests::DynamicStateGeneralTests (tcu::TestContext& testCtx)
421         : TestCaseGroup (testCtx, "general_state", "General tests for dynamic states")
422 {
423         /* Left blank on purpose */
424 }
425
426 DynamicStateGeneralTests::~DynamicStateGeneralTests (void) {}
427
428 void DynamicStateGeneralTests::init (void)
429 {
430         ShaderMap shaderPaths;
431         shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
432         shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
433
434         addChild(new InstanceFactory<StateSwitchTestInstance>(m_testCtx, "state_switch", "Perform multiple draws with different VP states (scissor test)", shaderPaths));
435         addChild(new InstanceFactory<BindOrderTestInstance>(m_testCtx, "bind_order", "Check if binding order is not important for pipeline configuration", shaderPaths));
436         addChild(new InstanceFactory<StatePersistenceTestInstance>(m_testCtx, "state_persistence", "Check if bound states are persistent across pipelines", shaderPaths));
437 }
438
439 } // DynamicState
440 } // vkt