Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / draw / vktDrawSimpleTest.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 Simple Draw Tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktDrawSimpleTest.hpp"
26
27 #include "vktTestCaseUtil.hpp"
28 #include "vktDrawTestCaseUtil.hpp"
29
30 #include "vktDrawBaseClass.hpp"
31
32 #include "tcuTestLog.hpp"
33 #include "tcuResource.hpp"
34 #include "tcuImageCompare.hpp"
35 #include "tcuTextureUtil.hpp"
36 #include "tcuRGBA.hpp"
37
38 #include "vkDefs.hpp"
39 #include "vkCmdUtil.hpp"
40
41 namespace vkt
42 {
43 namespace Draw
44 {
45 namespace
46 {
47 class SimpleDraw : public DrawTestsBaseClass
48 {
49 public:
50         typedef TestSpecBase    TestSpec;
51                                                         SimpleDraw                              (Context &context, TestSpec testSpec);
52         virtual tcu::TestStatus iterate                                 (void);
53         void                                    draw                                    (vk::VkCommandBuffer cmdBuffer, deUint32 instanceCount = 1u, deUint32 firstInstance = 0u);
54 };
55
56 class SimpleDrawInstanced : public SimpleDraw
57 {
58 public:
59         typedef TestSpec                TestSpec;
60                                                         SimpleDrawInstanced             (Context &context, TestSpec testSpec);
61         tcu::TestStatus                 iterate                                 (void);
62 };
63
64 SimpleDraw::SimpleDraw (Context &context, TestSpec testSpec)
65         : DrawTestsBaseClass(context, testSpec.shaders[glu::SHADERTYPE_VERTEX], testSpec.shaders[glu::SHADERTYPE_FRAGMENT], testSpec.groupParams, testSpec.topology)
66 {
67         m_data.push_back(VertexElementData(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), -1));
68         m_data.push_back(VertexElementData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), -1));
69
70         int refVertexIndex = 2;
71
72         switch (m_topology)
73         {
74                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
75                         m_data.push_back(VertexElementData(tcu::Vec4(-0.3f,     -0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
76                         m_data.push_back(VertexElementData(tcu::Vec4(-0.3f,      0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
77                         m_data.push_back(VertexElementData(tcu::Vec4( 0.3f,     -0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
78                         m_data.push_back(VertexElementData(tcu::Vec4( 0.3f,     -0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
79                         m_data.push_back(VertexElementData(tcu::Vec4( 0.3f,      0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
80                         m_data.push_back(VertexElementData(tcu::Vec4(-0.3f,      0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
81                         break;
82                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
83                         m_data.push_back(VertexElementData(tcu::Vec4(-0.3f,     -0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
84                         m_data.push_back(VertexElementData(tcu::Vec4(-0.3f,      0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
85                         m_data.push_back(VertexElementData(tcu::Vec4( 0.3f,     -0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
86                         m_data.push_back(VertexElementData(tcu::Vec4( 0.3f,      0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
87                         m_data.push_back(VertexElementData(tcu::Vec4(-0.3f,      0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), refVertexIndex++));
88                         break;
89                 case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
90                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
91                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
92                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
93                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
94                 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
95                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
96                 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
97                 case vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
98                 case vk::VK_PRIMITIVE_TOPOLOGY_LAST:
99                         DE_FATAL("Topology not implemented");
100                         break;
101                 default:
102                         DE_FATAL("Unknown topology");
103                         break;
104         }
105
106         m_data.push_back(VertexElementData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), -1));
107
108         initialize();
109 }
110
111 tcu::TestStatus SimpleDraw::iterate (void)
112 {
113         tcu::TestLog&                   log                                     = m_context.getTestContext().getLog();
114         const vk::VkQueue               queue                           = m_context.getUniversalQueue();
115         const vk::VkDevice              device                          = m_context.getDevice();
116         const vk::VkDeviceSize  vertexBufferOffset      = 0;
117         const vk::VkBuffer              vertexBuffer            = m_vertexBuffer->object();
118
119 #ifndef CTS_USES_VULKANSC
120         if (m_groupParams->useSecondaryCmdBuffer)
121         {
122                 // record secondary command buffer
123                 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
124                 {
125                         beginSecondaryCmdBuffer(m_vk, vk::VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
126                         beginDynamicRender(*m_secCmdBuffer);
127                 }
128                 else
129                         beginSecondaryCmdBuffer(m_vk);
130
131                 m_vk.cmdBindVertexBuffers(*m_secCmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
132                 m_vk.cmdBindPipeline(*m_secCmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
133                 draw(*m_secCmdBuffer);
134
135                 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
136                         endDynamicRender(*m_secCmdBuffer);
137
138                 endCommandBuffer(m_vk, *m_secCmdBuffer);
139
140                 // record primary command buffer
141                 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
142                 preRenderBarriers();
143
144                 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
145                         beginDynamicRender(*m_cmdBuffer, vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
146
147                 m_vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer);
148
149                 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
150                         endDynamicRender(*m_cmdBuffer);
151
152                 endCommandBuffer(m_vk, *m_cmdBuffer);
153         }
154         else if (m_groupParams->useDynamicRendering)
155         {
156                 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
157                 preRenderBarriers();
158                 beginDynamicRender(*m_cmdBuffer);
159
160                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
161                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
162                 draw(*m_cmdBuffer);
163
164                 endDynamicRender(*m_cmdBuffer);
165                 endCommandBuffer(m_vk, *m_cmdBuffer);
166         }
167 #endif // CTS_USES_VULKANSC
168
169         if (!m_groupParams->useDynamicRendering)
170         {
171                 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
172                 preRenderBarriers();
173                 beginLegacyRender(*m_cmdBuffer);
174
175                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
176                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
177                 draw(*m_cmdBuffer);
178
179                 endLegacyRender(*m_cmdBuffer);
180                 endCommandBuffer(m_vk, *m_cmdBuffer);
181         }
182
183         submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
184
185         // Validation
186         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
187
188         referenceFrame.allocLevel(0);
189
190         const deInt32 frameWidth        = referenceFrame.getWidth();
191         const deInt32 frameHeight       = referenceFrame.getHeight();
192
193         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
194
195         ReferenceImageCoordinates refCoords;
196
197         for (int y = 0; y < frameHeight; y++)
198         {
199                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
200
201                 for (int x = 0; x < frameWidth; x++)
202                 {
203                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
204
205                         if ((yCoord >= refCoords.bottom &&
206                                  yCoord <= refCoords.top        &&
207                                  xCoord >= refCoords.left       &&
208                                  xCoord <= refCoords.right))
209                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
210                 }
211         }
212
213         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
214         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
215                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
216
217         qpTestResult res = QP_TEST_RESULT_PASS;
218
219         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
220                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
221                 tcu::COMPARE_LOG_RESULT)) {
222                 res = QP_TEST_RESULT_FAIL;
223         }
224
225         return tcu::TestStatus(res, qpGetTestResultName(res));
226
227 }
228
229 void SimpleDraw::draw(vk::VkCommandBuffer cmdBuffer, deUint32 instanceCount, deUint32 firstInstance)
230 {
231         switch (m_topology)
232         {
233         case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
234                 m_vk.cmdDraw(cmdBuffer, 6, instanceCount, 2, firstInstance);
235                 break;
236         case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
237                 m_vk.cmdDraw(cmdBuffer, 4, instanceCount, 2, firstInstance);
238                 break;
239         case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
240         case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
241         case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
242         case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
243         case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
244         case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
245         case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
246         case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
247         case vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
248         case vk::VK_PRIMITIVE_TOPOLOGY_LAST:
249                 DE_FATAL("Topology not implemented");
250                 break;
251         default:
252                 DE_FATAL("Unknown topology");
253                 break;
254         }
255 }
256
257 SimpleDrawInstanced::SimpleDrawInstanced (Context &context, TestSpec testSpec)
258         : SimpleDraw    (context, testSpec) {}
259
260 tcu::TestStatus SimpleDrawInstanced::iterate (void)
261 {
262         tcu::TestLog&                   log                                             = m_context.getTestContext().getLog();
263         const vk::VkQueue               queue                                   = m_context.getUniversalQueue();
264         const vk::VkDevice              device                                  = m_context.getDevice();
265         const vk::VkDeviceSize  vertexBufferOffset              = 0;
266         const vk::VkBuffer              vertexBuffer                    = m_vertexBuffer->object();
267
268 #ifndef CTS_USES_VULKANSC
269         if (m_groupParams->useSecondaryCmdBuffer)
270         {
271                 // record secondary command buffer
272                 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
273                 {
274                         beginSecondaryCmdBuffer(m_vk, vk::VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
275                         beginDynamicRender(*m_secCmdBuffer);
276                 }
277                 else
278                         beginSecondaryCmdBuffer(m_vk);
279
280                 m_vk.cmdBindVertexBuffers(*m_secCmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
281                 m_vk.cmdBindPipeline(*m_secCmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
282                 draw(*m_secCmdBuffer, 4u, 2u);
283
284                 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
285                         endDynamicRender(*m_secCmdBuffer);
286
287                 endCommandBuffer(m_vk, *m_secCmdBuffer);
288
289                 // record primary command buffer
290                 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
291                 preRenderBarriers();
292
293                 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
294                         beginDynamicRender(*m_cmdBuffer, vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
295
296                 m_vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer);
297
298                 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
299                         endDynamicRender(*m_cmdBuffer);
300
301                 endCommandBuffer(m_vk, *m_cmdBuffer);
302         }
303         else if (m_groupParams->useDynamicRendering)
304         {
305                 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
306                 preRenderBarriers();
307
308                 beginDynamicRender(*m_cmdBuffer);
309                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
310                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
311                 draw(*m_cmdBuffer, 4u, 2u);
312                 endDynamicRender(*m_cmdBuffer);
313
314                 endCommandBuffer(m_vk, *m_cmdBuffer);
315         }
316 #endif // CTS_USES_VULKANSC
317
318         if (!m_groupParams->useDynamicRendering)
319         {
320                 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
321                 preRenderBarriers();
322
323                 beginLegacyRender(*m_cmdBuffer);
324                 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
325                 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
326                 draw(*m_cmdBuffer, 4u, 2u);
327                 endLegacyRender(*m_cmdBuffer);
328
329                 endCommandBuffer(m_vk, *m_cmdBuffer);
330         }
331
332         submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
333
334         // Validation
335         VK_CHECK(m_vk.queueWaitIdle(queue));
336
337         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
338
339         referenceFrame.allocLevel(0);
340
341         const deInt32 frameWidth        = referenceFrame.getWidth();
342         const deInt32 frameHeight       = referenceFrame.getHeight();
343
344         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
345
346         ReferenceImageInstancedCoordinates refInstancedCoords;
347
348         for (int y = 0; y < frameHeight; y++)
349         {
350                 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
351
352                 for (int x = 0; x < frameWidth; x++)
353                 {
354                         const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
355
356                         if ((yCoord >= refInstancedCoords.bottom        &&
357                                  yCoord <= refInstancedCoords.top               &&
358                                  xCoord >= refInstancedCoords.left              &&
359                                  xCoord <= refInstancedCoords.right))
360                                 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
361                 }
362         }
363
364         const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
365         const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
366                 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
367
368         qpTestResult res = QP_TEST_RESULT_PASS;
369
370         if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
371                 referenceFrame.getLevel(0), renderedFrame, 0.05f,
372                 tcu::COMPARE_LOG_RESULT)) {
373                 res = QP_TEST_RESULT_FAIL;
374         }
375
376         return tcu::TestStatus(res, qpGetTestResultName(res));
377 }
378
379 void checkSupport(Context& context, SimpleDraw::TestSpec testSpec)
380 {
381         if (testSpec.groupParams->useDynamicRendering)
382                 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
383 }
384
385 }       // anonymous
386
387 SimpleDrawTests::SimpleDrawTests (tcu::TestContext &testCtx, const SharedGroupParams groupParams)
388         : TestCaseGroup                 (testCtx, "simple_draw", "drawing simple geometry")
389         , m_groupParams                 (groupParams)
390 {
391         /* Left blank on purpose */
392 }
393
394 SimpleDrawTests::~SimpleDrawTests (void) {}
395
396 void SimpleDrawTests::init (void)
397 {
398         {
399                 SimpleDraw::TestSpec testSpec
400                 {
401                         {                                                                                                       // ShaderMap                                    shaders;
402                                 { glu::SHADERTYPE_VERTEX, "vulkan/draw/VertexFetch.vert" },
403                                 { glu::SHADERTYPE_FRAGMENT, "vulkan/draw/VertexFetch.frag" }
404                         },
405                         vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                        // vk::VkPrimitiveTopology              topology;
406                         m_groupParams                                                                           // const SharedGroupParams              groupParams;
407                 };
408
409                 addChild(new InstanceFactory<SimpleDraw, FunctionSupport1<SimpleDraw::TestSpec> >
410                         (m_testCtx, "simple_draw_triangle_list", "Draws triangle list", testSpec, FunctionSupport1<SimpleDraw::TestSpec>::Args(checkSupport, testSpec)));
411                 testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
412                 addChild(new InstanceFactory<SimpleDraw, FunctionSupport1<SimpleDraw::TestSpec> >
413                         (m_testCtx, "simple_draw_triangle_strip", "Draws triangle strip", testSpec, FunctionSupport1<SimpleDraw::TestSpec>::Args(checkSupport, testSpec)));
414         }
415         {
416                 SimpleDrawInstanced::TestSpec testSpec
417                 {
418                         {
419                                 { glu::SHADERTYPE_VERTEX, "vulkan/draw/VertexFetchInstancedFirstInstance.vert" },
420                                 { glu::SHADERTYPE_FRAGMENT, "vulkan/draw/VertexFetch.frag" }
421                         },
422                         vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
423                         m_groupParams
424                 };
425
426                 addChild(new InstanceFactory<SimpleDrawInstanced, FunctionSupport1<SimpleDrawInstanced::TestSpec> >
427                         (m_testCtx, "simple_draw_instanced_triangle_list", "Draws an instanced triangle list", testSpec, FunctionSupport1<SimpleDrawInstanced::TestSpec>::Args(checkSupport, testSpec)));
428                 testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
429                 addChild(new InstanceFactory<SimpleDrawInstanced, FunctionSupport1<SimpleDrawInstanced::TestSpec> >
430                         (m_testCtx, "simple_draw_instanced_triangle_strip", "Draws an instanced triangle strip", testSpec, FunctionSupport1<SimpleDrawInstanced::TestSpec>::Args(checkSupport, testSpec)));
431         }
432 }
433
434 }       // DrawTests
435 }       // vkt