Merge branch 'jekstrand_renderpass_transfer_bit_fix' into '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  * 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                         (const vk::VkPipelineStageFlags*)DE_NULL,
118                         1,                                                                      // deUint32                                     commandBufferCount;
119                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
120                         0,                                                                      // deUint32                                     signalSemaphoreCount;
121                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
122                 };
123                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
124
125                 //validation
126                 VK_CHECK(m_vk.queueWaitIdle(queue));
127
128                 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + 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:
170         BindOrderTestInstance (Context& context, ShaderMap shaders)
171                 : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
172         {
173                 m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
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
183         virtual tcu::TestStatus iterate (void)
184         {
185                 tcu::TestLog &log               = m_context.getTestContext().getLog();
186                 const vk::VkQueue queue = m_context.getUniversalQueue();
187
188                 beginRenderPass();
189
190                 // bind states here
191                 vk::VkViewport viewport = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
192                 vk::VkRect2D scissor_1  = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
193                 vk::VkRect2D scissor_2  = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
194
195                 setDynamicRasterizationState();
196                 setDynamicBlendState();
197                 setDynamicDepthStencilState();
198                 setDynamicViewportState(1, &viewport, &scissor_1);
199
200                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
201
202                 const vk::VkDeviceSize vertexBufferOffset = 0;
203                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
204                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
205
206                 // rebind in different order
207                 setDynamicBlendState();
208                 setDynamicRasterizationState();
209                 setDynamicDepthStencilState();
210
211                 // bind first state
212                 setDynamicViewportState(1, &viewport, &scissor_1);
213                 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
214
215                 setDynamicViewportState(1, &viewport, &scissor_2);
216                 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
217
218                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
219                 m_vk.endCommandBuffer(*m_cmdBuffer);
220
221                 vk::VkSubmitInfo submitInfo =
222                 {
223                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
224                         DE_NULL,                                                        // const void*                          pNext;
225                         0,                                                                      // deUint32                                     waitSemaphoreCount;
226                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
227                         (const vk::VkPipelineStageFlags*)DE_NULL,
228                         1,                                                                      // deUint32                                     commandBufferCount;
229                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
230                         0,                                                                      // deUint32                                     signalSemaphoreCount;
231                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
232                 };
233                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
234
235                 //validation
236                 VK_CHECK(m_vk.queueWaitIdle(queue));
237
238                 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
239                 referenceFrame.allocLevel(0);
240
241                 const deInt32 frameWidth = referenceFrame.getWidth();
242                 const deInt32 frameHeight = referenceFrame.getHeight();
243
244                 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
245
246                 for (int y = 0; y < frameHeight; y++)
247                 {
248                         const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
249
250                         for (int x = 0; x < frameWidth; x++)
251                         {
252                                 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
253
254                                 if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) ||
255                                         (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f))
256                                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
257                         }
258                 }
259
260                 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
261                 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
262                         vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
263
264                 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
265                         referenceFrame.getLevel(0), renderedFrame, 0.05f,
266                         tcu::COMPARE_LOG_RESULT))
267                 {
268                         return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
269                 }
270
271                 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
272         }
273 };
274
275 class StatePersistenceTestInstance : public DynamicStateBaseClass
276 {
277 protected:
278         vk::Move<vk::VkPipeline> m_pipelineAdditional;
279
280 public:
281         StatePersistenceTestInstance (Context& context, ShaderMap shaders)
282                 : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
283         {
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                 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
287                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
288
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                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
294                 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
295
296                 DynamicStateBaseClass::initialize();
297         }
298         virtual void initPipeline (const vk::VkDevice device)
299         {
300                 // shaders
301                 const vk::Unique<vk::VkShaderModule> vs (createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
302                 const vk::Unique<vk::VkShaderModule> fs (createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
303
304                 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
305
306                 PipelineCreateInfo pipelineCreateInfo_1(*m_pipelineLayout, *m_renderPass, 0, 0);
307                 pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
308                 pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
309                 pipelineCreateInfo_1.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
310                 pipelineCreateInfo_1.addState(PipelineCreateInfo::InputAssemblerState(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP));
311                 pipelineCreateInfo_1.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
312                 pipelineCreateInfo_1.addState(PipelineCreateInfo::ViewportState(1));
313                 pipelineCreateInfo_1.addState(PipelineCreateInfo::DepthStencilState());
314                 pipelineCreateInfo_1.addState(PipelineCreateInfo::RasterizerState());
315                 pipelineCreateInfo_1.addState(PipelineCreateInfo::MultiSampleState());
316                 pipelineCreateInfo_1.addState(PipelineCreateInfo::DynamicState());
317
318                 PipelineCreateInfo pipelineCreateInfo_2(*m_pipelineLayout, *m_renderPass, 0, 0);
319                 pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
320                 pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
321                 pipelineCreateInfo_2.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
322                 pipelineCreateInfo_2.addState(PipelineCreateInfo::InputAssemblerState(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
323                 pipelineCreateInfo_2.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
324                 pipelineCreateInfo_2.addState(PipelineCreateInfo::ViewportState(1));
325                 pipelineCreateInfo_2.addState(PipelineCreateInfo::DepthStencilState());
326                 pipelineCreateInfo_2.addState(PipelineCreateInfo::RasterizerState());
327                 pipelineCreateInfo_2.addState(PipelineCreateInfo::MultiSampleState());
328                 pipelineCreateInfo_2.addState(PipelineCreateInfo::DynamicState());
329
330                 m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_1);
331                 m_pipelineAdditional = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_2);
332         }
333
334         virtual tcu::TestStatus iterate(void)
335         {
336                 tcu::TestLog &log                               = m_context.getTestContext().getLog();
337                 const vk::VkQueue queue                 = m_context.getUniversalQueue();
338
339                 beginRenderPass();
340
341                 // bind states here
342                 const vk::VkViewport viewport   = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
343                 const vk::VkRect2D scissor_1    = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
344                 const vk::VkRect2D scissor_2    = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
345
346                 setDynamicRasterizationState();
347                 setDynamicBlendState();
348                 setDynamicDepthStencilState();
349
350                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
351
352                 const vk::VkDeviceSize vertexBufferOffset = 0;
353                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
354                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
355
356                 // bind first state
357                 setDynamicViewportState(1, &viewport, &scissor_1);
358                 // draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
359                 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
360
361                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineAdditional);
362
363                 // bind second state
364                 setDynamicViewportState(1, &viewport, &scissor_2);
365                 // draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
366                 m_vk.cmdDraw(*m_cmdBuffer, 6, 1, 4, 0);
367
368                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
369                 m_vk.endCommandBuffer(*m_cmdBuffer);
370
371                 vk::VkSubmitInfo submitInfo =
372                 {
373                         vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,      // VkStructureType                      sType;
374                         DE_NULL,                                                        // const void*                          pNext;
375                         0,                                                                      // deUint32                                     waitSemaphoreCount;
376                         DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
377                         (const vk::VkPipelineStageFlags*)DE_NULL,
378                         1,                                                                      // deUint32                                     commandBufferCount;
379                         &m_cmdBuffer.get(),                                     // const VkCommandBuffer*       pCommandBuffers;
380                         0,                                                                      // deUint32                                     signalSemaphoreCount;
381                         DE_NULL                                                         // const VkSemaphore*           pSignalSemaphores;
382                 };
383                 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
384
385                 //validation
386                 VK_CHECK(m_vk.queueWaitIdle(queue));
387
388                 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
389                 referenceFrame.allocLevel(0);
390
391                 const deInt32 frameWidth        = referenceFrame.getWidth();
392                 const deInt32 frameHeight       = referenceFrame.getHeight();
393
394                 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
395
396                 for (int y = 0; y < frameHeight; y++)
397                 {
398                         const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
399
400                         for (int x = 0; x < frameWidth; x++)
401                         {
402                                 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
403
404                                 if (yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f)
405                                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
406                                 else if (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f)
407                                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
408                         }
409                 }
410
411                 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
412                 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
413                         vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
414
415                 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
416                         referenceFrame.getLevel(0), renderedFrame, 0.05f,
417                         tcu::COMPARE_LOG_RESULT))
418                 {
419                         return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
420                 }
421
422                 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
423         }
424 };
425
426 } //anonymous
427
428 DynamicStateGeneralTests::DynamicStateGeneralTests (tcu::TestContext& testCtx)
429         : TestCaseGroup (testCtx, "general_state", "General tests for dynamic states")
430 {
431         /* Left blank on purpose */
432 }
433
434 DynamicStateGeneralTests::~DynamicStateGeneralTests (void) {}
435
436 void DynamicStateGeneralTests::init (void)
437 {
438         ShaderMap shaderPaths;
439         shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
440         shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
441
442         addChild(new InstanceFactory<StateSwitchTestInstance>(m_testCtx, "state_switch", "Perform multiple draws with different VP states (scissor test)", shaderPaths));
443         addChild(new InstanceFactory<BindOrderTestInstance>(m_testCtx, "bind_order", "Check if binding order is not important for pipeline configuration", shaderPaths));
444         addChild(new InstanceFactory<StatePersistenceTestInstance>(m_testCtx, "state_persistence", "Check if bound states are persistent across pipelines", shaderPaths));
445 }
446
447 } // DynamicState
448 } // vkt