Merge remote-tracking branch 'gitlab/master' into dynamic_state_tests
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / dynamic-state / vktDynamicStateVPTests.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 Viewport Tests
34  *//*--------------------------------------------------------------------*/
35
36 #include "vktDynamicStateVPTests.hpp"
37 #include "vktDynamicStateBaseClass.hpp"
38
39 #include "vktDynamicStateTestCaseUtil.hpp"
40 #include "tcuTextureUtil.hpp"
41
42 namespace vkt
43 {
44 namespace DynamicState
45 {
46 namespace
47 {
48
49 class ViewportStateBaseCase : public DynamicStateBaseClass
50 {
51 public:
52         ViewportStateBaseCase (Context &context, const char* vertexShaderName, const char* fragmentShaderName)
53                 : DynamicStateBaseClass (context, vertexShaderName, fragmentShaderName)
54         {}
55
56         void initialize(void)
57         {
58                 m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
59
60                 m_data.push_back(Vec4RGBA(tcu::Vec4(-0.5f, 0.5f, 1.0f, 1.0f), vec4Green()));
61                 m_data.push_back(Vec4RGBA(tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f), vec4Green()));
62                 m_data.push_back(Vec4RGBA(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), vec4Green()));
63                 m_data.push_back(Vec4RGBA(tcu::Vec4(0.5f, -0.5f, 1.0f, 1.0f), vec4Green()));
64
65                 DynamicStateBaseClass::initialize();
66         }
67
68         virtual tcu::Texture2D buildReferenceFrame (void)
69         {
70                 TCU_FAIL("Implement buildReferenceFrame() method and return valid surface!");
71         }
72
73         virtual void setDynamicStates (void)
74         {
75                 TCU_FAIL("Implement setDynamicStates() method!");
76         }
77
78         virtual tcu::TestStatus iterate (void)
79         {
80                 tcu::TestLog &log = m_context.getTestContext().getLog();
81                 const vk::VkDevice device = m_context.getDevice();
82                 const vk::VkQueue queue = m_context.getUniversalQueue();
83
84                 beginRenderPass();
85
86                 // set states here
87                 setDynamicStates();
88
89                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
90
91                 const vk::VkDeviceSize vertexBufferOffset = 0;
92                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
93                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
94
95                 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
96
97                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
98                 m_vk.endCommandBuffer(*m_cmdBuffer);
99
100                 const vk::VkCmdBuffer cmdBuffer = *m_cmdBuffer;
101                 VK_CHECK(m_vk.queueSubmit(queue, 1, &cmdBuffer, DE_NULL));
102
103                 // validation
104                 {
105                         VK_CHECK(m_vk.queueWaitIdle(queue));
106
107                         tcu::Texture2D referenceFrame = buildReferenceFrame();
108
109                         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
110                         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
111                                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR);
112
113                         qpTestResult res = QP_TEST_RESULT_PASS;
114
115                         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
116                                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
117                                 tcu::COMPARE_LOG_RESULT))
118                         {
119                                 res = QP_TEST_RESULT_FAIL;
120                         }
121
122                         return tcu::TestStatus(res, qpGetTestResultName(res));
123                 }
124         }
125 };
126
127 class ViewportParamTestInstane : public ViewportStateBaseCase
128 {
129 public:
130         ViewportParamTestInstane (Context &context, ShaderMap shaders)
131                 : ViewportStateBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
132         {
133                 ViewportStateBaseCase::initialize();
134         }
135
136         virtual void setDynamicStates(void)
137         {
138                 const vk::VkViewport viewport = { 0.0f, 0.0f, (float)WIDTH * 2, (float)HEIGHT * 2, 0.0f, 0.0f };
139                 const vk::VkRect2D scissor = { { 0, 0 }, { WIDTH, HEIGHT } };
140
141                 setDynamicViewportState(1, &viewport, &scissor);
142                 setDynamicRasterState();
143                 setDynamicBlendState();
144                 setDynamicDepthStencilState();
145         }
146
147         virtual tcu::Texture2D buildReferenceFrame (void)
148         {
149                 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
150                 referenceFrame.allocLevel(0);
151
152                 const deInt32 frameWidth = referenceFrame.getWidth();
153                 const deInt32 frameHeight = referenceFrame.getHeight();
154
155                 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
156
157                 for (int y = 0; y < frameHeight; y++)
158                 {
159                         const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
160
161                         for (int x = 0; x < frameWidth; x++)
162                         {
163                                 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
164
165                                 if (xCoord >= 0.0f && xCoord <= 1.0f && yCoord >= 0.0f && yCoord <= 1.0f)
166                                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
167                         }
168                 }
169
170                 return referenceFrame;
171         }
172 };
173
174 class ScissorParamTestInstance : public ViewportStateBaseCase
175 {
176 public:
177         ScissorParamTestInstance (Context &context, ShaderMap shaders)
178                 : ViewportStateBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
179         {
180                 ViewportStateBaseCase::initialize();
181         }
182
183         virtual void setDynamicStates (void)
184         {
185                 const vk::VkViewport viewport = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
186                 const vk::VkRect2D scissor = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
187
188                 setDynamicViewportState(1, &viewport, &scissor);
189                 setDynamicRasterState();
190                 setDynamicBlendState();
191                 setDynamicDepthStencilState();
192         }
193
194         virtual tcu::Texture2D buildReferenceFrame (void)
195         {
196                 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
197                 referenceFrame.allocLevel(0);
198
199                 const deInt32 frameWidth = referenceFrame.getWidth();
200                 const deInt32 frameHeight = referenceFrame.getHeight();
201
202                 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
203
204                 for (int y = 0; y < frameHeight; y++)
205                 {
206                         const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
207
208                         for (int x = 0; x < frameWidth; x++)
209                         {
210                                 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
211
212                                 if (xCoord >= -0.5f && xCoord <= 0.0f && yCoord >= -0.5f && yCoord <= 0.0f)
213                                         referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
214                         }
215                 }
216
217                 return referenceFrame;
218         }
219 };
220
221
222 class ViewportArrayTestInstance : public DynamicStateBaseClass
223 {
224 protected:
225         std::string m_geometryShaderName;
226
227 public:
228
229         ViewportArrayTestInstance (Context &context, ShaderMap shaders)
230                 : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
231                 , m_geometryShaderName  (shaders[glu::SHADERTYPE_GEOMETRY])
232         {
233                 for (int i = 0; i < 4; i++)
234                 {
235                         m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, 1.0f, (float)i, 1.0f), vec4Green()));
236                         m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, 1.0f, (float)i, 1.0f), vec4Green()));
237                         m_data.push_back(Vec4RGBA(tcu::Vec4(-1.0f, -1.0f, (float)i, 1.0f), vec4Green()));
238                         m_data.push_back(Vec4RGBA(tcu::Vec4(1.0f, -1.0f, (float)i, 1.0f), vec4Green()));
239                 }
240
241                 DynamicStateBaseClass::initialize();
242         }
243
244         virtual void initPipeline (const vk::VkDevice device)
245         {
246                 const vk::Unique<vk::VkShader> vs(createShader(m_vk, device,
247                         *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0),
248                         "main", vk::VK_SHADER_STAGE_VERTEX));
249
250                 const vk::Unique<vk::VkShader> gs(createShader(m_vk, device,
251                         *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_geometryShaderName), 0),
252                         "main", vk::VK_SHADER_STAGE_GEOMETRY));
253
254                 const vk::Unique<vk::VkShader> fs(createShader(m_vk, device,
255                         *createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0),
256                         "main", vk::VK_SHADER_STAGE_FRAGMENT));
257
258                 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
259
260                 PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
261                 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, vk::VK_SHADER_STAGE_VERTEX));
262                 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*gs, vk::VK_SHADER_STAGE_GEOMETRY));
263                 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, vk::VK_SHADER_STAGE_FRAGMENT));
264                 pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
265                 pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
266                 pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
267                 pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(4));
268                 pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
269                 pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
270                 pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
271                 pipelineCreateInfo.addState(PipelineCreateInfo::DynamicState());
272
273                 m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
274         }
275
276         virtual tcu::TestStatus iterate (void)
277         {
278                 tcu::TestLog &log = m_context.getTestContext().getLog();
279                 const vk::VkQueue queue = m_context.getUniversalQueue();
280
281                 beginRenderPass();
282
283                 // set states here
284                 const float halfWidth = (float)WIDTH / 2;
285                 const float halfHeight = (float)HEIGHT / 2;
286                 const deInt32 quarterWidth = WIDTH / 4;
287                 const deInt32 quarterHeight = HEIGHT / 4;
288
289                 const vk::VkViewport viewports[4] =
290                 {
291                         { 0.0f, 0.0f, (float)halfWidth, (float)halfHeight, 0.0f, 0.0f },
292                         { halfWidth, 0.0f, (float)halfWidth, (float)halfHeight, 0.0f, 0.0f },
293                         { halfWidth, halfHeight, (float)halfWidth, (float)halfHeight, 0.0f, 0.0f },
294                         { 0.0f, halfHeight, (float)halfWidth, (float)halfHeight, 0.0f, 0.0f }
295                 };
296
297                 const vk::VkRect2D scissors[4] =
298                 {
299                         { { quarterWidth, quarterHeight }, { quarterWidth, quarterHeight } },
300                         { { halfWidth, quarterHeight }, { quarterWidth, quarterHeight } },
301                         { { halfWidth, halfHeight }, { quarterWidth, quarterHeight } },
302                         { { quarterWidth, halfHeight }, { quarterWidth, quarterHeight } },
303                 };
304
305                 setDynamicViewportState(4, viewports, scissors);
306                 setDynamicRasterState();
307                 setDynamicBlendState();
308                 setDynamicDepthStencilState();
309
310                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
311
312                 const vk::VkDeviceSize vertexBufferOffset = 0;
313                 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
314                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
315
316                 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
317
318                 m_vk.cmdEndRenderPass(*m_cmdBuffer);
319                 m_vk.endCommandBuffer(*m_cmdBuffer);
320
321                 const vk::VkCmdBuffer cmdBuffer = *m_cmdBuffer;
322                 VK_CHECK(m_vk.queueSubmit(queue, 1, &cmdBuffer, DE_NULL));
323
324                 // validation
325                 {
326                         VK_CHECK(m_vk.queueWaitIdle(queue));
327
328                         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
329                         referenceFrame.allocLevel(0);
330
331                         const deInt32 frameWidth = referenceFrame.getWidth();
332                         const deInt32 frameHeight = referenceFrame.getHeight();
333
334                         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
335
336                         for (int y = 0; y < frameHeight; y++)
337                         {
338                                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
339
340                                 for (int x = 0; x < frameWidth; x++)
341                                 {
342                                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
343
344                                         if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
345                                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
346                                 }
347                         }
348
349                         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
350                         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
351                                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR);
352                                         
353                         qpTestResult res = QP_TEST_RESULT_PASS;
354
355                         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
356                                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
357                                 tcu::COMPARE_LOG_RESULT))
358                         {
359                                 res = QP_TEST_RESULT_FAIL;
360                         }
361
362                         return tcu::TestStatus(res, qpGetTestResultName(res));
363                 }
364         }
365 };
366
367 } //anonymous
368
369 DynamicStateVPTests::DynamicStateVPTests (tcu::TestContext &testCtx)
370         : TestCaseGroup (testCtx, "vp_state", "Tests for viewport state")
371 {
372         /* Left blank on purpose */
373 }
374
375 DynamicStateVPTests::~DynamicStateVPTests () {}
376
377 void DynamicStateVPTests::init (void)
378 {
379         ShaderMap shaderPaths;
380         shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
381         shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
382                 
383         addChild(new InstanceFactory<ViewportParamTestInstane>(m_testCtx, "viewport", "Set viewport which is twice bigger than screen size", shaderPaths));
384         addChild(new InstanceFactory<ScissorParamTestInstance>(m_testCtx, "scissor", "Perform a scissor test on 1/4 bottom-left part of the surface", shaderPaths));
385
386         shaderPaths[glu::SHADERTYPE_GEOMETRY] = "vulkan/dynamic_state/ViewportArray.geom";
387         addChild(new InstanceFactory<ViewportArrayTestInstance>(m_testCtx, "viewport_array", "Multiple viewports and scissors", shaderPaths));
388 }
389
390 } //DynamicState
391 } //vkt