dEQP-VK.renderpass: Set IMAGE_USAGE_TRANSFER_SRC_BIT when needed
[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  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and/or associated documentation files (the
10  * "Materials"), to deal in the Materials without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Materials, and to
13  * permit persons to whom the Materials are furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
19  * The Materials are Confidential Information as defined by the
20  * Khronos Membership Agreement until designated non-confidential by Khronos,
21  * at which point this condition clause shall be removed.
22  *
23  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
30  *
31  *//*!
32  * \file
33  * \brief Dynamic State Tests - General
34  *//*--------------------------------------------------------------------*/
35
36 #include "vktDynamicStateGeneralTests.hpp"
37
38 #include "vktTestCaseUtil.hpp"
39 #include "vktDynamicStateTestCaseUtil.hpp"
40 #include "vktDynamicStateBaseClass.hpp"
41 #include "vktDynamicStateCreateInfoUtil.hpp"
42 #include "vktDynamicStateImageObjectUtil.hpp"
43 #include "vktDynamicStateBufferObjectUtil.hpp"
44
45 #include "vkImageUtil.hpp"
46
47 #include "tcuTestLog.hpp"
48 #include "tcuResource.hpp"
49 #include "tcuImageCompare.hpp"
50 #include "tcuTextureUtil.hpp"
51 #include "tcuRGBA.hpp"
52
53 #include "vkDefs.hpp"
54
55 namespace vkt
56 {
57 namespace DynamicState
58 {
59 namespace
60 {
61
62 class StateSwitchTestInstance : public DynamicStateBaseClass
63 {
64 public:
65         StateSwitchTestInstance (Context &context, ShaderMap shaders)
66                 : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
67         {
68                 m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
69
70                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
71                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
72                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
73                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
74
75                 DynamicStateBaseClass::initialize();
76         }
77
78         virtual tcu::TestStatus iterate (void)
79         {
80                 tcu::TestLog& log               = m_context.getTestContext().getLog();
81                 const vk::VkQueue queue = m_context.getUniversalQueue();
82
83                 beginRenderPass();
84
85                 // bind states here
86                 vk::VkViewport viewport = { 0, 0, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
87                 vk::VkRect2D scissor_1  = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
88                 vk::VkRect2D scissor_2  = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
89
90                 setDynamicRasterizationState();
91                 setDynamicBlendState();
92                 setDynamicDepthStencilState();
93
94                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
95
96                 const vk::VkDeviceSize vertexBufferOffset       = 0;
97                 const vk::VkBuffer vertexBuffer                         = m_vertexBuffer->object();
98                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
99
100                 // bind first state
101                 setDynamicViewportState(1, &viewport, &scissor_1);
102                 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
103
104                 // bind second state
105                 setDynamicViewportState(1, &viewport, &scissor_2);
106                 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
107
108                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
109                 m_vk.endCommandBuffer(*m_cmdBuffer);
110
111                 vk::VkSubmitInfo submitInfo =
112                 {
113                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
114                         DE_NULL,                                                        // const void*                          pNext;
115                         0,                                                                      // deUint32                                     waitSemaphoreCount;
116                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
117                         1,                                                                      // deUint32                                     commandBufferCount;
118                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
119                         0,                                                                      // deUint32                                     signalSemaphoreCount;
120                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
121                 };
122                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
123
124                 //validation
125                 VK_CHECK(m_vk.queueWaitIdle(queue));
126
127                 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
128                 referenceFrame.allocLevel(0);
129
130                 const deInt32 frameWidth        = referenceFrame.getWidth();
131                 const deInt32 frameHeight       = referenceFrame.getHeight();
132
133                 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
134
135                 for (int y = 0; y < frameHeight; y++)
136                 {
137                         const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
138
139                         for (int x = 0; x < frameWidth; x++)
140                         {
141                                 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
142
143                                 if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) ||
144                                         (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f))
145                                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
146                         }
147                 }
148
149                 const vk::VkOffset3D zeroOffset                                 = { 0, 0, 0 };
150                 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
151                                                                                                                                                                                   vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT,
152                                                                                                                                                                                   vk::VK_IMAGE_ASPECT_COLOR_BIT);
153
154                 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
155                         referenceFrame.getLevel(0), renderedFrame, 0.05f,
156                         tcu::COMPARE_LOG_RESULT))
157                 {
158
159                         return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
160                 }
161
162                 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
163         }
164 };
165
166 class BindOrderTestInstance : public DynamicStateBaseClass
167 {
168 public:
169         BindOrderTestInstance (Context& context, ShaderMap shaders)
170                 : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
171         {
172                 m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
173
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                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
178
179                 DynamicStateBaseClass::initialize();
180         }
181
182         virtual tcu::TestStatus iterate (void)
183         {
184                 tcu::TestLog &log               = m_context.getTestContext().getLog();
185                 const vk::VkQueue queue = m_context.getUniversalQueue();
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);
200
201                 const vk::VkDeviceSize vertexBufferOffset = 0;
202                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
203                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
204
205                 // rebind in different order
206                 setDynamicBlendState();
207                 setDynamicRasterizationState();
208                 setDynamicDepthStencilState();
209
210                 // bind first state
211                 setDynamicViewportState(1, &viewport, &scissor_1);
212                 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
213
214                 setDynamicViewportState(1, &viewport, &scissor_2);
215                 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
216
217                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
218                 m_vk.endCommandBuffer(*m_cmdBuffer);
219
220                 vk::VkSubmitInfo submitInfo =
221                 {
222                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
223                         DE_NULL,                                                        // const void*                          pNext;
224                         0,                                                                      // deUint32                                     waitSemaphoreCount;
225                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
226                         1,                                                                      // deUint32                                     commandBufferCount;
227                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
228                         0,                                                                      // deUint32                                     signalSemaphoreCount;
229                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
230                 };
231                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
232
233                 //validation
234                 VK_CHECK(m_vk.queueWaitIdle(queue));
235
236                 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
237                 referenceFrame.allocLevel(0);
238
239                 const deInt32 frameWidth = referenceFrame.getWidth();
240                 const deInt32 frameHeight = referenceFrame.getHeight();
241
242                 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
243
244                 for (int y = 0; y < frameHeight; y++)
245                 {
246                         const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
247
248                         for (int x = 0; x < frameWidth; x++)
249                         {
250                                 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
251
252                                 if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) ||
253                                         (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f))
254                                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
255                         }
256                 }
257
258                 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
259                 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
260                         vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
261
262                 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
263                         referenceFrame.getLevel(0), renderedFrame, 0.05f,
264                         tcu::COMPARE_LOG_RESULT))
265                 {
266                         return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
267                 }
268
269                 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
270         }
271 };
272
273 class StatePersistenceTestInstance : public DynamicStateBaseClass
274 {
275 protected:
276         vk::Move<vk::VkPipeline> m_pipelineAdditional;
277
278 public:
279         StatePersistenceTestInstance (Context& context, ShaderMap shaders)
280                 : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
281         {
282                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
283                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
284                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
285                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
286
287                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
288                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
289                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
290                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
291                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
292                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
293
294                 DynamicStateBaseClass::initialize();
295         }
296         virtual void initPipeline (const vk::VkDevice device)
297         {
298                 // shaders
299                 const vk::Unique<vk::VkShaderModule> vs (createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
300                 const vk::Unique<vk::VkShaderModule> fs (createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
301
302                 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
303
304                 PipelineCreateInfo pipelineCreateInfo_1(*m_pipelineLayout, *m_renderPass, 0, 0);
305                 pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
306                 pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
307                 pipelineCreateInfo_1.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
308                 pipelineCreateInfo_1.addState(PipelineCreateInfo::InputAssemblerState(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP));
309                 pipelineCreateInfo_1.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
310                 pipelineCreateInfo_1.addState(PipelineCreateInfo::ViewportState(1));
311                 pipelineCreateInfo_1.addState(PipelineCreateInfo::DepthStencilState());
312                 pipelineCreateInfo_1.addState(PipelineCreateInfo::RasterizerState());
313                 pipelineCreateInfo_1.addState(PipelineCreateInfo::MultiSampleState());
314                 pipelineCreateInfo_1.addState(PipelineCreateInfo::DynamicState());
315
316                 PipelineCreateInfo pipelineCreateInfo_2(*m_pipelineLayout, *m_renderPass, 0, 0);
317                 pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
318                 pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
319                 pipelineCreateInfo_2.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
320                 pipelineCreateInfo_2.addState(PipelineCreateInfo::InputAssemblerState(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
321                 pipelineCreateInfo_2.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
322                 pipelineCreateInfo_2.addState(PipelineCreateInfo::ViewportState(1));
323                 pipelineCreateInfo_2.addState(PipelineCreateInfo::DepthStencilState());
324                 pipelineCreateInfo_2.addState(PipelineCreateInfo::RasterizerState());
325                 pipelineCreateInfo_2.addState(PipelineCreateInfo::MultiSampleState());
326                 pipelineCreateInfo_2.addState(PipelineCreateInfo::DynamicState());
327
328                 m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_1);
329                 m_pipelineAdditional = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_2);
330         }
331
332         virtual tcu::TestStatus iterate(void)
333         {
334                 tcu::TestLog &log                               = m_context.getTestContext().getLog();
335                 const vk::VkQueue queue                 = m_context.getUniversalQueue();
336
337                 beginRenderPass();
338
339                 // bind states here
340                 const vk::VkViewport viewport   = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
341                 const vk::VkRect2D scissor_1    = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
342                 const vk::VkRect2D scissor_2    = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
343
344                 setDynamicRasterizationState();
345                 setDynamicBlendState();
346                 setDynamicDepthStencilState();
347
348                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
349
350                 const vk::VkDeviceSize vertexBufferOffset = 0;
351                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
352                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
353
354                 // bind first state
355                 setDynamicViewportState(1, &viewport, &scissor_1);
356                 // draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
357                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
358
359                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineAdditional);
360
361                 // bind second state
362                 setDynamicViewportState(1, &viewport, &scissor_2);
363                 // draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
364                 m_vk.cmdDraw(*m_cmdBuffer, 6, 1, 4, 0);
365
366                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
367                 m_vk.endCommandBuffer(*m_cmdBuffer);
368
369                 vk::VkSubmitInfo submitInfo =
370                 {
371                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
372                         DE_NULL,                                                        // const void*                          pNext;
373                         0,                                                                      // deUint32                                     waitSemaphoreCount;
374                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
375                         1,                                                                      // deUint32                                     commandBufferCount;
376                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
377                         0,                                                                      // deUint32                                     signalSemaphoreCount;
378                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
379                 };
380                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
381
382                 //validation
383                 VK_CHECK(m_vk.queueWaitIdle(queue));
384
385                 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
386                 referenceFrame.allocLevel(0);
387
388                 const deInt32 frameWidth        = referenceFrame.getWidth();
389                 const deInt32 frameHeight       = referenceFrame.getHeight();
390
391                 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
392
393                 for (int y = 0; y < frameHeight; y++)
394                 {
395                         const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
396
397                         for (int x = 0; x < frameWidth; x++)
398                         {
399                                 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
400
401                                 if (yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f)
402                                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
403                                 else if (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f)
404                                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
405                         }
406                 }
407
408                 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
409                 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
410                         vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
411
412                 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
413                         referenceFrame.getLevel(0), renderedFrame, 0.05f,
414                         tcu::COMPARE_LOG_RESULT))
415                 {
416                         return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
417                 }
418
419                 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
420         }
421 };
422
423 } //anonymous
424
425 DynamicStateGeneralTests::DynamicStateGeneralTests (tcu::TestContext& testCtx)
426         : TestCaseGroup (testCtx, "general_state", "General tests for dynamic states")
427 {
428         /* Left blank on purpose */
429 }
430
431 DynamicStateGeneralTests::~DynamicStateGeneralTests (void) {}
432
433 void DynamicStateGeneralTests::init (void)
434 {
435         ShaderMap shaderPaths;
436         shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
437         shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
438
439         addChild(new InstanceFactory<StateSwitchTestInstance>(m_testCtx, "state_switch", "Perform multiple draws with different VP states (scissor test)", shaderPaths));
440         addChild(new InstanceFactory<BindOrderTestInstance>(m_testCtx, "bind_order", "Check if binding order is not important for pipeline configuration", shaderPaths));
441         addChild(new InstanceFactory<StatePersistenceTestInstance>(m_testCtx, "state_persistence", "Check if bound states are persistent across pipelines", shaderPaths));
442 }
443
444 } // DynamicState
445 } // vkt