Check supported features and properties for transform feedback tests
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / transform_feedback / vktTransformFeedbackSimpleTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Vulkan Transform Feedback Simple Tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktTransformFeedbackSimpleTests.hpp"
25 #include "vktTestGroupUtil.hpp"
26 #include "vktTestCase.hpp"
27
28 #include "vkBuilderUtil.hpp"
29 #include "vkCmdUtil.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkObjUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkRefUtil.hpp"
34 #include "vkTypeUtil.hpp"
35
36 #include "deUniquePtr.hpp"
37 #include "deRandom.hpp"
38
39 #include "tcuTextureUtil.hpp"
40 #include "tcuVectorUtil.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuRGBA.hpp"
43
44 #include <iostream>
45
46 namespace vkt
47 {
48 namespace TransformFeedback
49 {
50 namespace
51 {
52 using namespace vk;
53 using de::MovePtr;
54 using de::UniquePtr;
55 using de::SharedPtr;
56
57 #define VALIDATE_MINIMUM(A,B) if ((A) < (B)) TCU_FAIL(#A "==" + de::toString(A) + " which is less than required by specification (" + de::toString(B) + ")")
58 #define VALIDATE_BOOL(A) if (! ( (A) == VK_TRUE || (A) == VK_FALSE) ) TCU_FAIL(#A " expected to be VK_TRUE or VK_FALSE. Received " + de::toString((deUint64)(A)))
59
60 enum TestType
61 {
62         TEST_TYPE_BASIC,
63         TEST_TYPE_RESUME,
64         TEST_TYPE_STREAMS,
65         TEST_TYPE_XFB_POINTSIZE,
66         TEST_TYPE_XFB_CLIPDISTANCE,
67         TEST_TYPE_XFB_CULLDISTANCE,
68         TEST_TYPE_XFB_CLIP_AND_CULL,
69         TEST_TYPE_TRIANGLE_STRIP_ADJACENCY,
70         TEST_TYPE_STREAMS_POINTSIZE,
71         TEST_TYPE_STREAMS_CLIPDISTANCE,
72         TEST_TYPE_STREAMS_CULLDISTANCE,
73         TEST_TYPE_MULTISTREAMS,
74         TEST_TYPE_DRAW_INDIRECT,
75         TEST_TYPE_BACKWARD_DEPENDENCY,
76         TEST_TYPE_QUERY,
77         TEST_TYPE_QUERY_RESET,
78         TEST_TYPE_LAST
79 };
80
81 struct TestParameters
82 {
83         TestType        testType;
84         deUint32        bufferSize;
85         deUint32        partCount;
86         deUint32        streamId;
87         deUint32        pointSize;
88         deUint32        vertexStride;
89 };
90
91 const deUint32 MINIMUM_TF_BUFFER_SIZE   = (1<<27);
92 const deUint32 IMAGE_SIZE                               = 64u;
93
94 template<typename T>
95 inline SharedPtr<Unique<T> > makeSharedPtr(Move<T> move)
96 {
97         return SharedPtr<Unique<T> >(new Unique<T>(move));
98 }
99
100 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&               vk,
101                                                                                    const VkDevice                               device)
102 {
103         const VkPushConstantRange                       pushConstantRanges                      =
104         {
105                 VK_SHADER_STAGE_VERTEX_BIT,                                             //  VkShaderStageFlags                          stageFlags;
106                 0u,                                                                                             //  deUint32                                            offset;
107                 sizeof(deUint32)                                                                //  deUint32                                            size;
108         };
109         const VkPipelineLayoutCreateInfo        pipelineLayoutCreateInfo        =
110         {
111                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  //  VkStructureType                                     sType;
112                 DE_NULL,                                                                                //  const void*                                         pNext;
113                 (VkPipelineLayoutCreateFlags)0,                                 //  VkPipelineLayoutCreateFlags         flags;
114                 0u,                                                                                             //  deUint32                                            setLayoutCount;
115                 DE_NULL,                                                                                //  const VkDescriptorSetLayout*        pSetLayouts;
116                 1u,                                                                                             //  deUint32                                            pushConstantRangeCount;
117                 &pushConstantRanges,                                                    //  const VkPushConstantRange*          pPushConstantRanges;
118         };
119         return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
120 }
121
122 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&           vk,
123                                                                            const VkDevice                               device,
124                                                                            const VkPipelineLayout               pipelineLayout,
125                                                                            const VkRenderPass                   renderPass,
126                                                                            const VkShaderModule                 vertexModule,
127                                                                            const VkShaderModule                 geometryModule,
128                                                                            const VkShaderModule                 fragmendModule,
129                                                                            const VkExtent2D                             renderSize,
130                                                                            const deUint32                               subpass,
131                                                                            const deUint32*                              rasterizationStreamPtr  = DE_NULL,
132                                                                            const VkPrimitiveTopology    topology                                = VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
133                                                                            const bool                                   inputVertices                   = false)
134 {
135         const std::vector<VkViewport>                                                   viewports                                                               (1, makeViewport(renderSize));
136         const std::vector<VkRect2D>                                                             scissors                                                                (1, makeRect2D(renderSize));
137         const VkPipelineVertexInputStateCreateInfo                              vertexInputStateCreateInfo                      =
138         {
139                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,                                                                      //  VkStructureType                                                                     sType
140                 DE_NULL,                                                                                                                                                                        //  const void*                                                                         pNext
141                 (VkPipelineVertexInputStateCreateFlags)0,                                                                                                       //  VkPipelineVertexInputStateCreateFlags                       flags
142                 0u,                                                                                                                                                                                     //  deUint32                                                                            vertexBindingDescriptionCount
143                 DE_NULL,                                                                                                                                                                        //  const VkVertexInputBindingDescription*                      pVertexBindingDescriptions
144                 0u,                                                                                                                                                                                     //  deUint32                                                                            vertexAttributeDescriptionCount
145                 DE_NULL,                                                                                                                                                                        //  const VkVertexInputAttributeDescription*            pVertexAttributeDescriptions
146         };
147         const VkPipelineVertexInputStateCreateInfo*                             vertexInputStateCreateInfoPtr           = (inputVertices) ? DE_NULL : &vertexInputStateCreateInfo;
148         const VkBool32                                                                                  disableRasterization                            = (fragmendModule == DE_NULL);
149         const deUint32                                                                                  rasterizationStream                                     = (rasterizationStreamPtr == DE_NULL) ? 0 : *rasterizationStreamPtr;
150         const VkPipelineRasterizationStateStreamCreateInfoEXT   rasterizationStateStreamCreateInfo      =
151         {
152                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT,                                          //  VkStructureType                                                                             sType;
153                 DE_NULL,                                                                                                                                                                        //  const void*                                                                                 pNext;
154                 0,                                                                                                                                                                                      //  VkPipelineRasterizationStateStreamCreateFlagsEXT    flags;
155                 rasterizationStream                                                                                                                                                     //  deUint32                                                                                    rasterizationStream;
156         };
157         const VkPipelineRasterizationStateCreateInfo                    rasterizationStateCreateInfo            =
158         {
159                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,                                                                     //  VkStructureType                                                     sType;
160                 &rasterizationStateStreamCreateInfo,                                                                                                            //  const void*                                                         pNext;
161                 0u,                                                                                                                                                                                     //  VkPipelineRasterizationStateCreateFlags     flags;
162                 VK_FALSE,                                                                                                                                                                       //  VkBool32                                                            depthClampEnable;
163                 disableRasterization,                                                                                                                                           //  VkBool32                                                            rasterizerDiscardEnable;
164                 VK_POLYGON_MODE_FILL,                                                                                                                                           //  VkPolygonMode                                                       polygonMode;
165                 VK_CULL_MODE_NONE,                                                                                                                                                      //  VkCullModeFlags                                                     cullMode;
166                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                                                                        //  VkFrontFace                                                         frontFace;
167                 VK_FALSE,                                                                                                                                                                       //  VkBool32                                                            depthBiasEnable;
168                 0.0f,                                                                                                                                                                           //  float                                                                       depthBiasConstantFactor;
169                 0.0f,                                                                                                                                                                           //  float                                                                       depthBiasClamp;
170                 0.0f,                                                                                                                                                                           //  float                                                                       depthBiasSlopeFactor;
171                 1.0f                                                                                                                                                                            //  float                                                                       lineWidth;
172         };
173         const VkPipelineRasterizationStateCreateInfo*                   rasterizationStateCreateInfoPtr         = (rasterizationStreamPtr == DE_NULL) ? DE_NULL : &rasterizationStateCreateInfo;
174
175         return makeGraphicsPipeline(vk,                                                                 // const DeviceInterface&                                                       vk
176                                                                 device,                                                         // const VkDevice                                                                       device
177                                                                 pipelineLayout,                                         // const VkPipelineLayout                                                       pipelineLayout
178                                                                 vertexModule,                                           // const VkShaderModule                                                         vertexShaderModule
179                                                                 DE_NULL,                                                        // const VkShaderModule                                                         tessellationControlModule
180                                                                 DE_NULL,                                                        // const VkShaderModule                                                         tessellationEvalModule
181                                                                 geometryModule,                                         // const VkShaderModule                                                         geometryShaderModule
182                                                                 fragmendModule,                                         // const VkShaderModule                                                         fragmentShaderModule
183                                                                 renderPass,                                                     // const VkRenderPass                                                           renderPass
184                                                                 viewports,                                                      // const std::vector<VkViewport>&                                       viewports
185                                                                 scissors,                                                       // const std::vector<VkRect2D>&                                         scissors
186                                                                 topology,                                                       // const VkPrimitiveTopology                                            topology
187                                                                 subpass,                                                        // const deUint32                                                                       subpass
188                                                                 0u,                                                                     // const deUint32                                                                       patchControlPoints
189                                                                 vertexInputStateCreateInfoPtr,          // const VkPipelineVertexInputStateCreateInfo*          vertexInputStateCreateInfo
190                                                                 rasterizationStateCreateInfoPtr);       // const VkPipelineRasterizationStateCreateInfo*        rasterizationStateCreateInfo
191 }
192
193 VkImageCreateInfo makeImageCreateInfo (const VkImageCreateFlags flags, const VkImageType type, const VkFormat format, const VkExtent2D size, const deUint32 numLayers, const VkImageUsageFlags usage)
194 {
195         const VkExtent3D                extent          = { size.width, size.height, 1u };
196         const VkImageCreateInfo imageParams =
197         {
198                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                    // VkStructureType                      sType;
199                 DE_NULL,                                                                                // const void*                          pNext;
200                 flags,                                                                                  // VkImageCreateFlags           flags;
201                 type,                                                                                   // VkImageType                          imageType;
202                 format,                                                                                 // VkFormat                                     format;
203                 extent,                                                                                 // VkExtent3D                           extent;
204                 1u,                                                                                             // deUint32                                     mipLevels;
205                 numLayers,                                                                              // deUint32                                     arrayLayers;
206                 VK_SAMPLE_COUNT_1_BIT,                                                  // VkSampleCountFlagBits        samples;
207                 VK_IMAGE_TILING_OPTIMAL,                                                // VkImageTiling                        tiling;
208                 usage,                                                                                  // VkImageUsageFlags            usage;
209                 VK_SHARING_MODE_EXCLUSIVE,                                              // VkSharingMode                        sharingMode;
210                 0u,                                                                                             // deUint32                                     queueFamilyIndexCount;
211                 DE_NULL,                                                                                // const deUint32*                      pQueueFamilyIndices;
212                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        initialLayout;
213         };
214         return imageParams;
215 }
216
217 Move<VkRenderPass> makeRenderPass (const DeviceInterface&               vk,
218                                                                    const VkDevice                               device)
219 {
220         std::vector<VkSubpassDescription>       subpassDescriptions;
221         std::vector<VkSubpassDependency>        subpassDependencies;
222
223         const VkSubpassDescription      description     =
224         {
225                 (VkSubpassDescriptionFlags)0,           //  VkSubpassDescriptionFlags           flags;
226                 VK_PIPELINE_BIND_POINT_GRAPHICS,        //  VkPipelineBindPoint                         pipelineBindPoint;
227                 0u,                                                                     //  deUint32                                            inputAttachmentCount;
228                 DE_NULL,                                                        //  const VkAttachmentReference*        pInputAttachments;
229                 0u,                                                                     //  deUint32                                            colorAttachmentCount;
230                 DE_NULL,                                                        //  const VkAttachmentReference*        pColorAttachments;
231                 DE_NULL,                                                        //  const VkAttachmentReference*        pResolveAttachments;
232                 DE_NULL,                                                        //  const VkAttachmentReference*        pDepthStencilAttachment;
233                 0,                                                                      //  deUint32                                            preserveAttachmentCount;
234                 DE_NULL                                                         //  const deUint32*                                     pPreserveAttachments;
235         };
236         subpassDescriptions.push_back(description);
237
238         const VkSubpassDependency       dependency      =
239         {
240                 0u,                                                                                                     //  deUint32                            srcSubpass;
241                 0u,                                                                                                     //  deUint32                            dstSubpass;
242                 VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,           //  VkPipelineStageFlags        srcStageMask;
243                 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,                            //  VkPipelineStageFlags        dstStageMask;
244                 VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT,     //  VkAccessFlags                       srcAccessMask;
245                 VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT,      //  VkAccessFlags                       dstAccessMask;
246                 0u                                                                                                      //  VkDependencyFlags           dependencyFlags;
247         };
248         subpassDependencies.push_back(dependency);
249
250         const VkRenderPassCreateInfo renderPassInfo =
251         {
252                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                                                      //  VkStructureType                                     sType;
253                 DE_NULL,                                                                                                                        //  const void*                                         pNext;
254                 static_cast<VkRenderPassCreateFlags>(0u),                                                       //  VkRenderPassCreateFlags                     flags;
255                 0u,                                                                                                                                     //  deUint32                                            attachmentCount;
256                 DE_NULL,                                                                                                                        //  const VkAttachmentDescription*      pAttachments;
257                 static_cast<deUint32>(subpassDescriptions.size()),                                      //  deUint32                                            subpassCount;
258                 &subpassDescriptions[0],                                                                                        //  const VkSubpassDescription*         pSubpasses;
259                 static_cast<deUint32>(subpassDependencies.size()),                                      //  deUint32                                            dependencyCount;
260                 subpassDependencies.size() > 0 ? &subpassDependencies[0] : DE_NULL      //  const VkSubpassDependency*          pDependencies;
261         };
262
263         return createRenderPass(vk, device, &renderPassInfo);
264 }
265
266 VkImageMemoryBarrier makeImageMemoryBarrier     (const VkAccessFlags                    srcAccessMask,
267                                                                                          const VkAccessFlags                    dstAccessMask,
268                                                                                          const VkImageLayout                    oldLayout,
269                                                                                          const VkImageLayout                    newLayout,
270                                                                                          const VkImage                                  image,
271                                                                                          const VkImageSubresourceRange  subresourceRange)
272 {
273         const VkImageMemoryBarrier barrier =
274         {
275                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
276                 DE_NULL,                                                                                // const void*                          pNext;
277                 srcAccessMask,                                                                  // VkAccessFlags                        outputMask;
278                 dstAccessMask,                                                                  // VkAccessFlags                        inputMask;
279                 oldLayout,                                                                              // VkImageLayout                        oldLayout;
280                 newLayout,                                                                              // VkImageLayout                        newLayout;
281                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
282                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     destQueueFamilyIndex;
283                 image,                                                                                  // VkImage                                      image;
284                 subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
285         };
286         return barrier;
287 }
288
289 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags      srcAccessMask,
290                                                                                            const VkAccessFlags  dstAccessMask,
291                                                                                            const VkBuffer               buffer,
292                                                                                            const VkDeviceSize   offset,
293                                                                                            const VkDeviceSize   bufferSizeBytes)
294 {
295         const VkBufferMemoryBarrier barrier =
296         {
297                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        //  VkStructureType     sType;
298                 DE_NULL,                                                                        //  const void*         pNext;
299                 srcAccessMask,                                                          //  VkAccessFlags       srcAccessMask;
300                 dstAccessMask,                                                          //  VkAccessFlags       dstAccessMask;
301                 VK_QUEUE_FAMILY_IGNORED,                                        //  deUint32            srcQueueFamilyIndex;
302                 VK_QUEUE_FAMILY_IGNORED,                                        //  deUint32            destQueueFamilyIndex;
303                 buffer,                                                                         //  VkBuffer            buffer;
304                 offset,                                                                         //  VkDeviceSize        offset;
305                 bufferSizeBytes,                                                        //  VkDeviceSize        size;
306         };
307         return barrier;
308 }
309
310 VkMemoryBarrier makeMemoryBarrier (const VkAccessFlags  srcAccessMask,
311                                                                    const VkAccessFlags  dstAccessMask)
312 {
313         const VkMemoryBarrier barrier =
314         {
315                 VK_STRUCTURE_TYPE_MEMORY_BARRIER,       // VkStructureType                      sType;
316                 DE_NULL,                                                        // const void*                          pNext;
317                 srcAccessMask,                                          // VkAccessFlags                        outputMask;
318                 dstAccessMask,                                          // VkAccessFlags                        inputMask;
319         };
320         return barrier;
321 }
322
323 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D                                 extent,
324                                                                            const VkImageSubresourceLayers       subresourceLayers)
325 {
326         const VkBufferImageCopy copyParams =
327         {
328                 0ull,                                                                           //      VkDeviceSize                            bufferOffset;
329                 0u,                                                                                     //      deUint32                                        bufferRowLength;
330                 0u,                                                                                     //      deUint32                                        bufferImageHeight;
331                 subresourceLayers,                                                      //      VkImageSubresourceLayers        imageSubresource;
332                 makeOffset3D(0, 0, 0),                                          //      VkOffset3D                                      imageOffset;
333                 extent,                                                                         //      VkExtent3D                                      imageExtent;
334         };
335         return copyParams;
336 }
337
338 inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkBufferCreateInfo& createInfo)
339 {
340         return createBuffer(vk, device, &createInfo);
341 }
342
343 inline Move<VkImage> makeImage (const DeviceInterface& vk, const VkDevice device, const VkImageCreateInfo& createInfo)
344 {
345         return createImage(vk, device, &createInfo);
346 }
347
348 de::MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
349 {
350         de::MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
351         VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
352         return alloc;
353 }
354
355 de::MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
356 {
357         de::MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
358         VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
359         return alloc;
360 }
361
362 VkQueryPoolCreateInfo makeQueryPoolCreateInfo (const deUint32 queryCountersNumber)
363 {
364         const VkQueryPoolCreateInfo                     queryPoolCreateInfo             =
365         {
366                 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,               //  VkStructureType                                     sType;
367                 DE_NULL,                                                                                //  const void*                                         pNext;
368                 (VkQueryPoolCreateFlags)0,                                              //  VkQueryPoolCreateFlags                      flags;
369                 VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT,    //  VkQueryType                                         queryType;
370                 queryCountersNumber,                                                    //  deUint32                                            queryCount;
371                 0u,                                                                                             //  VkQueryPipelineStatisticFlags       pipelineStatistics;
372         };
373
374         return queryPoolCreateInfo;
375 }
376
377 void fillBuffer (const DeviceInterface& vk, const VkDevice device, Allocation& bufferAlloc, VkDeviceSize bufferSize, const void* data, const VkDeviceSize dataSize)
378 {
379         const VkMappedMemoryRange       memRange                =
380         {
381                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  //  VkStructureType     sType;
382                 DE_NULL,                                                                //  const void*         pNext;
383                 bufferAlloc.getMemory(),                                //  VkDeviceMemory      memory;
384                 bufferAlloc.getOffset(),                                //  VkDeviceSize        offset;
385                 VK_WHOLE_SIZE                                                   //  VkDeviceSize        size;
386         };
387         std::vector<deUint8>            dataVec                 (static_cast<deUint32>(bufferSize), 0u);
388
389         DE_ASSERT(bufferSize >= dataSize);
390
391         deMemcpy(&dataVec[0], data, static_cast<deUint32>(dataSize));
392
393         deMemcpy(bufferAlloc.getHostPtr(), &dataVec[0], dataVec.size());
394         VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &memRange));
395 }
396
397 class TransformFeedbackTestInstance : public TestInstance
398 {
399 public:
400                                                                                                         TransformFeedbackTestInstance   (Context& context, const TestParameters& parameters);
401 protected:
402         void                                                                                    validateLimits                                  ();
403         deUint32                                                                                getNextChunkSize                                (const deUint32 usedBytes, const deUint32 bufBytes);
404         std::vector<VkDeviceSize>                                               generateSizesList                               (const size_t bufBytes, const size_t chunkCount);
405         std::vector<VkDeviceSize>                                               generateOffsetsList                             (const std::vector<VkDeviceSize>& sizesList);
406         void                                                                                    verifyTransformFeedbackBuffer   (const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes);
407
408         const bool                                                                              m_extensions;
409         const VkExtent2D                                                                m_imageExtent2D;
410         const TestParameters                                                    m_parameters;
411         VkPhysicalDeviceTransformFeedbackPropertiesEXT  m_transformFeedbackProperties;
412         de::Random                                                                              m_rnd;
413 };
414
415 TransformFeedbackTestInstance::TransformFeedbackTestInstance (Context& context, const TestParameters& parameters)
416         : TestInstance          (context)
417         , m_extensions          (context.requireDeviceExtension("VK_EXT_transform_feedback"))
418         , m_imageExtent2D       (makeExtent2D(IMAGE_SIZE, IMAGE_SIZE))
419         , m_parameters          (parameters)
420         , m_rnd                         (0)
421 {
422         const VkPhysicalDeviceTransformFeedbackFeaturesEXT&             transformFeedbackFeatures       = m_context.getTransformFeedbackFeatures();
423         VkPhysicalDeviceProperties2                                                             deviceProperties2;
424
425         if (transformFeedbackFeatures.transformFeedback == DE_FALSE)
426                 TCU_THROW(NotSupportedError, "transformFeedback feature is not supported");
427
428         deMemset(&deviceProperties2, 0, sizeof(deviceProperties2));
429         deMemset(&m_transformFeedbackProperties, 0, sizeof(m_transformFeedbackProperties));
430
431         deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
432         deviceProperties2.pNext = &m_transformFeedbackProperties;
433
434         m_transformFeedbackProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT;
435         m_transformFeedbackProperties.pNext = DE_NULL;
436
437         context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &deviceProperties2);
438
439         validateLimits();
440 }
441
442 void TransformFeedbackTestInstance::validateLimits ()
443 {
444         VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackBuffers, 1);
445         VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackBufferSize, MINIMUM_TF_BUFFER_SIZE);
446         VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackStreamDataSize, 512);
447         VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackBufferDataSize, 512);
448         VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackBufferDataStride, 512);
449
450         VALIDATE_BOOL(m_transformFeedbackProperties.transformFeedbackQueries);
451         VALIDATE_BOOL(m_transformFeedbackProperties.transformFeedbackStreamsLinesTriangles);
452         VALIDATE_BOOL(m_transformFeedbackProperties.transformFeedbackRasterizationStreamSelect);
453         VALIDATE_BOOL(m_transformFeedbackProperties.transformFeedbackDraw);
454 }
455
456 std::vector<VkDeviceSize> TransformFeedbackTestInstance::generateSizesList (const size_t bufBytes, const size_t chunkCount)
457 {
458         const int                                       minChunkSlot    = static_cast<int>(1);
459         const int                                       maxChunkSlot    = static_cast<int>(bufBytes / sizeof(deUint32));
460         int                                                     prevOffsetSlot  = 0;
461         std::map<int, bool>                     offsetsSet;
462         std::vector<VkDeviceSize>       result;
463
464         DE_ASSERT(bufBytes <= MINIMUM_TF_BUFFER_SIZE);
465         DE_ASSERT(bufBytes % sizeof(deUint32) == 0);
466         DE_ASSERT(minChunkSlot <= maxChunkSlot);
467         DE_ASSERT(chunkCount > 0);
468         // To be effective this algorithm requires that chunkCount is much less than amount of chunks possible
469         DE_ASSERT(8 * chunkCount <= static_cast<size_t>(maxChunkSlot));
470
471         offsetsSet[0] = true;
472
473         // Create a list of unique offsets first
474         for (size_t chunkNdx = 1; chunkNdx < chunkCount; ++chunkNdx)
475         {
476                 int chunkSlot;
477
478                 do
479                 {
480                         chunkSlot = m_rnd.getInt(minChunkSlot, maxChunkSlot - 1);
481                 } while (offsetsSet.find(chunkSlot) != offsetsSet.end());
482
483                 offsetsSet[chunkSlot] = true;
484         }
485         offsetsSet[maxChunkSlot] = true;
486
487         // Calculate sizes of offsets list
488         result.reserve(chunkCount);
489         for (std::map<int, bool>::iterator mapIt = offsetsSet.begin(); mapIt != offsetsSet.end(); ++mapIt)
490         {
491                 const int offsetSlot = mapIt->first;
492
493                 if (offsetSlot == 0)
494                         continue;
495
496                 DE_ASSERT(prevOffsetSlot < offsetSlot && offsetSlot > 0);
497
498                 result.push_back(static_cast<VkDeviceSize>(static_cast<size_t>(offsetSlot - prevOffsetSlot) * sizeof(deUint32)));
499
500                 prevOffsetSlot = offsetSlot;
501         }
502
503         DE_ASSERT(result.size() == chunkCount);
504
505         return result;
506 }
507
508 std::vector<VkDeviceSize> TransformFeedbackTestInstance::generateOffsetsList (const std::vector<VkDeviceSize>& sizesList)
509 {
510         VkDeviceSize                            offset  = 0ull;
511         std::vector<VkDeviceSize>       result;
512
513         result.reserve(sizesList.size());
514
515         for (size_t chunkNdx = 0; chunkNdx < sizesList.size(); ++chunkNdx)
516         {
517                 result.push_back(offset);
518
519                 offset += sizesList[chunkNdx];
520         }
521
522         DE_ASSERT(sizesList.size() == result.size());
523
524         return result;
525 }
526
527 void TransformFeedbackTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes)
528 {
529         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
530         const VkDevice                  device          = m_context.getDevice();
531
532         invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), bufBytes);
533
534         const deUint32                  numPoints       = static_cast<deUint32>(bufBytes / sizeof(deUint32));
535         const deUint32*                 tfData          = (deUint32*)bufAlloc->getHostPtr();
536
537         for (deUint32 i = 0; i < numPoints; ++i)
538                 if (tfData[i] != i)
539                         TCU_FAIL(std::string("Failed at item ") + de::toString(i) + " received:" + de::toString(tfData[i]) + " expected:" + de::toString(i));
540 }
541
542 class TransformFeedbackBasicTestInstance : public TransformFeedbackTestInstance
543 {
544 public:
545                                                 TransformFeedbackBasicTestInstance      (Context& context, const TestParameters& parameters);
546
547 protected:
548         tcu::TestStatus         iterate                                                         (void);
549 };
550
551 TransformFeedbackBasicTestInstance::TransformFeedbackBasicTestInstance (Context& context, const TestParameters& parameters)
552         : TransformFeedbackTestInstance (context, parameters)
553 {
554 }
555
556 tcu::TestStatus TransformFeedbackBasicTestInstance::iterate (void)
557 {
558         const DeviceInterface&                          vk                                              = m_context.getDeviceInterface();
559         const VkDevice                                          device                                  = m_context.getDevice();
560         const deUint32                                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
561         const VkQueue                                           queue                                   = m_context.getUniversalQueue();
562         Allocator&                                                      allocator                               = m_context.getDefaultAllocator();
563
564         const Unique<VkShaderModule>            vertexModule                    (createShaderModule                                             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
565         const Unique<VkRenderPass>                      renderPass                              (makeRenderPass                                                 (vk, device, VK_FORMAT_UNDEFINED));
566         const Unique<VkFramebuffer>                     framebuffer                             (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
567         const Unique<VkPipelineLayout>          pipelineLayout                  (TransformFeedback::makePipelineLayout  (vk, device));
568         const Unique<VkPipeline>                        pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
569         const Unique<VkCommandPool>                     cmdPool                                 (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
570         const Unique<VkCommandBuffer>           cmdBuffer                               (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
571
572         const VkBufferCreateInfo                        tfBufCreateInfo                 = makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
573         const Move<VkBuffer>                            tfBuf                                   = createBuffer(vk, device, &tfBufCreateInfo);
574         const MovePtr<Allocation>                       tfBufAllocation                 = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
575         const std::vector<VkDeviceSize>         tfBufBindingSizes               = generateSizesList(m_parameters.bufferSize, m_parameters.partCount);
576         const std::vector<VkDeviceSize>         tfBufBindingOffsets             = generateOffsetsList(tfBufBindingSizes);
577
578         VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
579
580         beginCommandBuffer(vk, *cmdBuffer);
581         {
582                 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
583                 {
584                         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
585
586                         for (deUint32 drawNdx = 0; drawNdx < m_parameters.partCount; ++drawNdx)
587                         {
588                                 const deUint32  startValue      = static_cast<deUint32>(tfBufBindingOffsets[drawNdx] / sizeof(deUint32));
589                                 const deUint32  numPoints       = static_cast<deUint32>(tfBufBindingSizes[drawNdx] / sizeof(deUint32));
590
591                                 vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &tfBufBindingOffsets[drawNdx], &tfBufBindingSizes[drawNdx]);
592
593                                 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);
594
595                                 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
596                                 {
597                                         vk.cmdDraw(*cmdBuffer, numPoints, 1u, 0u, 0u);
598                                 }
599                                 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
600                         }
601                 }
602                 endRenderPass(vk, *cmdBuffer);
603         }
604         endCommandBuffer(vk, *cmdBuffer);
605         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
606
607         verifyTransformFeedbackBuffer(tfBufAllocation, m_parameters.bufferSize);
608
609         return tcu::TestStatus::pass("Pass");
610 }
611
612 class TransformFeedbackResumeTestInstance : public TransformFeedbackTestInstance
613 {
614 public:
615                                                 TransformFeedbackResumeTestInstance     (Context& context, const TestParameters& parameters);
616
617 protected:
618         tcu::TestStatus         iterate                                                         (void);
619 };
620
621 TransformFeedbackResumeTestInstance::TransformFeedbackResumeTestInstance (Context& context, const TestParameters& parameters)
622         : TransformFeedbackTestInstance (context, parameters)
623 {
624 }
625
626 tcu::TestStatus TransformFeedbackResumeTestInstance::iterate (void)
627 {
628         const DeviceInterface&                                  vk                                              = m_context.getDeviceInterface();
629         const VkDevice                                                  device                                  = m_context.getDevice();
630         const deUint32                                                  queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
631         const VkQueue                                                   queue                                   = m_context.getUniversalQueue();
632         Allocator&                                                              allocator                               = m_context.getDefaultAllocator();
633
634         const Unique<VkShaderModule>                    vertexModule                    (createShaderModule                                             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
635         const Unique<VkRenderPass>                              renderPass                              (makeRenderPass                                                 (vk, device, VK_FORMAT_UNDEFINED));
636         const Unique<VkFramebuffer>                             framebuffer                             (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
637         const Unique<VkPipelineLayout>                  pipelineLayout                  (TransformFeedback::makePipelineLayout  (vk, device));
638         const Unique<VkPipeline>                                pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
639
640         const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
641         const Unique<VkCommandBuffer>                   cmdBuffer                               (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
642
643         const VkBufferCreateInfo                                tfBufCreateInfo                 = makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
644         const Move<VkBuffer>                                    tfBuf                                   = createBuffer(vk, device, &tfBufCreateInfo);
645         const MovePtr<Allocation>                               tfBufAllocation                 = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
646         const std::vector<VkDeviceSize>                 tfBufBindingSizes               = std::vector<VkDeviceSize>(1, m_parameters.bufferSize);
647         const std::vector<VkDeviceSize>                 tfBufBindingOffsets             = std::vector<VkDeviceSize>(1, 0ull);
648
649         const size_t                                                    tfcBufSize                              = 16 * sizeof(deUint32) * m_parameters.partCount;
650         const VkBufferCreateInfo                                tfcBufCreateInfo                = makeBufferCreateInfo(tfcBufSize, VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT);
651         const Move<VkBuffer>                                    tfcBuf                                  = createBuffer(vk, device, &tfcBufCreateInfo);
652         const MovePtr<Allocation>                               tfcBufAllocation                = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfcBuf), MemoryRequirement::Any);
653         const std::vector<VkDeviceSize>                 tfcBufBindingOffsets    = generateOffsetsList(generateSizesList(tfcBufSize, m_parameters.partCount));
654         const VkBufferMemoryBarrier                             tfcBufBarrier                   = makeBufferMemoryBarrier(VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT, *tfcBuf, 0ull, VK_WHOLE_SIZE);
655
656         const std::vector<VkDeviceSize>                 chunkSizesList                  = generateSizesList(m_parameters.bufferSize, m_parameters.partCount);
657         const std::vector<VkDeviceSize>                 chunkOffsetsList                = generateOffsetsList(chunkSizesList);
658
659         DE_ASSERT(tfBufBindingSizes.size() == 1);
660         DE_ASSERT(tfBufBindingOffsets.size() == 1);
661
662         VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
663         VK_CHECK(vk.bindBufferMemory(device, *tfcBuf, tfcBufAllocation->getMemory(), tfcBufAllocation->getOffset()));
664
665         beginCommandBuffer(vk, *cmdBuffer);
666         {
667                 for (size_t drawNdx = 0; drawNdx < m_parameters.partCount; ++drawNdx)
668                 {
669                         const deUint32  startValue = static_cast<deUint32>(chunkOffsetsList[drawNdx] / sizeof(deUint32));
670                         const deUint32  numPoints = static_cast<deUint32>(chunkSizesList[drawNdx] / sizeof(deUint32));
671                         const deUint32  countBuffersCount = (drawNdx == 0) ? 0 : 1;
672
673                         beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
674                         {
675
676                                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
677
678                                 vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &tfBufBindingOffsets[0], &tfBufBindingSizes[0]);
679
680                                 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);
681
682                                 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, countBuffersCount, (drawNdx == 0) ? DE_NULL : &*tfcBuf, (drawNdx == 0) ? DE_NULL : &tfcBufBindingOffsets[drawNdx - 1]);
683                                 {
684                                         vk.cmdDraw(*cmdBuffer, numPoints, 1u, 0u, 0u);
685                                 }
686                                 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 1, &*tfcBuf, &tfcBufBindingOffsets[drawNdx]);
687                         }
688                         endRenderPass(vk, *cmdBuffer);
689
690                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0u, 0u, DE_NULL, 1u, &tfcBufBarrier, 0u, DE_NULL);
691                 }
692         }
693         endCommandBuffer(vk, *cmdBuffer);
694         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
695
696         verifyTransformFeedbackBuffer(tfBufAllocation, m_parameters.bufferSize);
697
698         return tcu::TestStatus::pass("Pass");
699 }
700
701 class TransformFeedbackTriangleStripWithAdjacencyTestInstance : public TransformFeedbackTestInstance
702 {
703 public:
704                                                 TransformFeedbackTriangleStripWithAdjacencyTestInstance (Context& context, const TestParameters& parameters);
705
706 protected:
707         tcu::TestStatus         iterate                                                                                                 (void);
708         void                            verifyTransformFeedbackBuffer                                                   (const MovePtr<Allocation>& bufAlloc, const VkDeviceSize bufBytes);
709 };
710
711 TransformFeedbackTriangleStripWithAdjacencyTestInstance::TransformFeedbackTriangleStripWithAdjacencyTestInstance (Context& context, const TestParameters& parameters)
712         : TransformFeedbackTestInstance (context, parameters)
713 {
714 }
715
716 tcu::TestStatus TransformFeedbackTriangleStripWithAdjacencyTestInstance::iterate (void)
717 {
718         const DeviceInterface&                          vk                                              = m_context.getDeviceInterface();
719         const VkDevice                                          device                                  = m_context.getDevice();
720         const deUint32                                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
721         const VkQueue                                           queue                                   = m_context.getUniversalQueue();
722         Allocator&                                                      allocator                               = m_context.getDefaultAllocator();
723
724         DE_ASSERT(m_parameters.partCount >= 6);
725
726         const VkPrimitiveTopology                       topology                                (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY);
727         const Unique<VkShaderModule>            vertexModule                    (createShaderModule                                             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
728         const Unique<VkRenderPass>                      renderPass                              (makeRenderPass                                                 (vk, device, VK_FORMAT_UNDEFINED));
729         const Unique<VkFramebuffer>                     framebuffer                             (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
730         const Unique<VkPipelineLayout>          pipelineLayout                  (TransformFeedback::makePipelineLayout  (vk, device));
731         const Unique<VkPipeline>                        pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u, DE_NULL, topology));
732         const Unique<VkCommandPool>                     cmdPool                                 (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
733         const Unique<VkCommandBuffer>           cmdBuffer                               (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
734
735         const deUint32                                          numPrimitives                   = m_parameters.partCount / 2u - 2u;
736         const deUint32                                          numPoints                               = 3u * numPrimitives;
737         const VkDeviceSize                                      bufferSize                              = numPoints * sizeof(deUint32);
738         const VkBufferCreateInfo                        tfBufCreateInfo                 = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
739         const Move<VkBuffer>                            tfBuf                                   = createBuffer(vk, device, &tfBufCreateInfo);
740         const MovePtr<Allocation>                       tfBufAllocation                 = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
741         const VkDeviceSize                                      tfBufBindingSize                = bufferSize;
742         const VkDeviceSize                                      tfBufBindingOffset              = 0u;
743         const deUint32                                          startValue                              = 0u;
744
745         VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
746
747         beginCommandBuffer(vk, *cmdBuffer);
748         {
749                 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
750                 {
751                         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
752
753                         vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &tfBufBindingOffset, &tfBufBindingSize);
754
755                         vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);
756
757                         vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
758                         {
759                                 vk.cmdDraw(*cmdBuffer, m_parameters.partCount, 1u, 0u, 0u);
760                         }
761                         vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
762                 }
763                 endRenderPass(vk, *cmdBuffer);
764         }
765         endCommandBuffer(vk, *cmdBuffer);
766         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
767
768         verifyTransformFeedbackBuffer(tfBufAllocation, bufferSize);
769
770         return tcu::TestStatus::pass("Pass");
771 }
772
773 void TransformFeedbackTriangleStripWithAdjacencyTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const VkDeviceSize bufBytes)
774 {
775         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
776         const VkDevice                  device          = m_context.getDevice();
777
778         invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), VK_WHOLE_SIZE);
779
780         const deUint32                  numPoints       = static_cast<deUint32>(bufBytes / sizeof(deUint32));
781         const deUint32*                 tfData          = (deUint32*)bufAlloc->getHostPtr();
782
783         for (deUint32 dataNdx = 0; dataNdx < numPoints; ++dataNdx)
784         {
785                 const deUint32  i                       = dataNdx / 3;
786                 const deUint32  vertexNdx       = dataNdx % 3;
787                 const bool              even            = (0 == i % 2);
788                 deUint32                expected;
789
790                 if (even)
791                 {
792                         const deUint32  vertexNumbers[3] = { 2 * i + 0, 2 * i + 2, 2 * i + 4 };
793
794                         expected = vertexNumbers[vertexNdx];
795                 }
796                 else
797                 {
798                         const deUint32  vertexNumbers[3] = { 2 * i + 0, 2 * i + 4, 2 * i + 2 };
799
800                         expected = vertexNumbers[vertexNdx];
801                 }
802
803                 if (tfData[dataNdx] != expected)
804                         TCU_FAIL(std::string("Failed at item ") + de::toString(dataNdx) + " received:" + de::toString(tfData[dataNdx]) + " expected:" + de::toString(expected));
805         }
806 }
807
808 class TransformFeedbackBuiltinTestInstance : public TransformFeedbackTestInstance
809 {
810 public:
811                                                 TransformFeedbackBuiltinTestInstance    (Context& context, const TestParameters& parameters);
812
813 protected:
814         tcu::TestStatus         iterate                                                                 (void);
815         void                            verifyTransformFeedbackBuffer                   (const MovePtr<Allocation>& bufAlloc, const VkDeviceSize offset, const deUint32 bufBytes);
816 };
817
818 TransformFeedbackBuiltinTestInstance::TransformFeedbackBuiltinTestInstance (Context& context, const TestParameters& parameters)
819         : TransformFeedbackTestInstance (context, parameters)
820 {
821         const InstanceInterface&                vki                     = m_context.getInstanceInterface();
822         const VkPhysicalDevice                  physDevice      = m_context.getPhysicalDevice();
823         const VkPhysicalDeviceFeatures  features        = getPhysicalDeviceFeatures(vki, physDevice);
824
825         const deUint32 tfBuffersSupported       = m_transformFeedbackProperties.maxTransformFeedbackBuffers;
826         const deUint32 tfBuffersRequired        = m_parameters.partCount;
827
828         if ((m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE || m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) && !features.shaderClipDistance)
829                 TCU_THROW(NotSupportedError, std::string("shaderClipDistance feature is not supported"));
830         if ((m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE || m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) && !features.shaderCullDistance)
831                 TCU_THROW(NotSupportedError, std::string("shaderCullDistance feature is not supported"));
832         if (tfBuffersSupported < tfBuffersRequired)
833                 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBuffers=" + de::toString(tfBuffersSupported) + ", while test requires " + de::toString(tfBuffersRequired)).c_str());
834 }
835
836 void TransformFeedbackBuiltinTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const VkDeviceSize offset, const deUint32 bufBytes)
837 {
838         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
839         const VkDevice                  device          = m_context.getDevice();
840
841         invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), VK_WHOLE_SIZE);
842
843         const deUint32                  numPoints       = static_cast<deUint32>(bufBytes / sizeof(float));
844         const deUint8*                  tfDataBytes     = (deUint8*)bufAlloc->getHostPtr();
845         const float*                    tfData          = (float*)&tfDataBytes[offset];
846
847         for (deUint32 i = 0; i < numPoints; ++i)
848         {
849                 const deUint32  divisor         = 32768u;
850                 const float             epsilon         = 1.0f / float(divisor);
851                 const float             expected        = float(i) / float(divisor);
852
853                 if (deAbs(tfData[i] - expected) > epsilon)
854                         TCU_FAIL(std::string("Failed at item ") + de::toString(i) + " received:" + de::toString(tfData[i]) + " expected:" + de::toString(expected));
855         }
856 }
857
858 tcu::TestStatus TransformFeedbackBuiltinTestInstance::iterate (void)
859 {
860         const DeviceInterface&                          vk                                              = m_context.getDeviceInterface();
861         const VkDevice                                          device                                  = m_context.getDevice();
862         const deUint32                                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
863         const VkQueue                                           queue                                   = m_context.getUniversalQueue();
864         Allocator&                                                      allocator                               = m_context.getDefaultAllocator();
865
866         const Unique<VkShaderModule>            vertexModule                    (createShaderModule                                             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
867         const Unique<VkRenderPass>                      renderPass                              (makeRenderPass                                                 (vk, device, VK_FORMAT_UNDEFINED));
868         const Unique<VkFramebuffer>                     framebuffer                             (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
869         const Unique<VkPipelineLayout>          pipelineLayout                  (TransformFeedback::makePipelineLayout  (vk, device));
870         const Unique<VkPipeline>                        pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
871         const Unique<VkCommandPool>                     cmdPool                                 (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
872         const Unique<VkCommandBuffer>           cmdBuffer                               (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
873
874         const VkDeviceSize                                      tfBufSize                               = m_parameters.bufferSize * m_parameters.partCount;
875         const VkBufferCreateInfo                        tfBufCreateInfo                 = makeBufferCreateInfo(tfBufSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
876         const Move<VkBuffer>                            tfBuf                                   = createBuffer(vk, device, &tfBufCreateInfo);
877         const std::vector<VkBuffer>                     tfBufArray                              = std::vector<VkBuffer>(m_parameters.partCount, *tfBuf);
878         const MovePtr<Allocation>                       tfBufAllocation                 = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
879         const std::vector<VkDeviceSize>         tfBufBindingSizes               = std::vector<VkDeviceSize>(m_parameters.partCount, m_parameters.bufferSize);
880         const std::vector<VkDeviceSize>         tfBufBindingOffsets             = generateOffsetsList(tfBufBindingSizes);
881         const deUint32                                          perVertexDataSize               = (m_parameters.testType == TEST_TYPE_XFB_POINTSIZE)    ? static_cast<deUint32>(sizeof(float))
882                                                                                                                                 : (m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE) ? static_cast<deUint32>(8u * sizeof(float))
883                                                                                                                                 : (m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE) ? static_cast<deUint32>(8u * sizeof(float))
884                                                                                                                                 : (m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) ? static_cast<deUint32>(6u * sizeof(float))
885                                                                                                                                 : 0u;
886         const deUint32                                          numPoints                               = m_parameters.bufferSize / perVertexDataSize;
887
888         VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
889
890         beginCommandBuffer(vk, *cmdBuffer);
891         {
892                 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
893                 {
894                         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
895
896                         vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, m_parameters.partCount, &tfBufArray[0], &tfBufBindingOffsets[0], &tfBufBindingSizes[0]);
897
898                         vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
899                         {
900                                 vk.cmdDraw(*cmdBuffer, numPoints, 1u, 0u, 0u);
901                         }
902                         vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
903                 }
904                 endRenderPass(vk, *cmdBuffer);
905         }
906         endCommandBuffer(vk, *cmdBuffer);
907         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
908
909         verifyTransformFeedbackBuffer(tfBufAllocation, tfBufBindingOffsets[m_parameters.partCount - 1], numPoints * perVertexDataSize);
910
911         return tcu::TestStatus::pass("Pass");
912 }
913
914 class TransformFeedbackMultistreamTestInstance : public TransformFeedbackTestInstance
915 {
916 public:
917                                                                 TransformFeedbackMultistreamTestInstance        (Context& context, const TestParameters& parameters);
918
919 protected:
920         std::vector<VkDeviceSize>       generateSizesList                                                       (const size_t bufBytes, const size_t chunkCount);
921         void                                            verifyTransformFeedbackBuffer                           (const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes);
922         tcu::TestStatus                         iterate                                                                         (void);
923 };
924
925 TransformFeedbackMultistreamTestInstance::TransformFeedbackMultistreamTestInstance (Context& context, const TestParameters& parameters)
926         : TransformFeedbackTestInstance (context, parameters)
927 {
928         const InstanceInterface&                                                                vki                                                     = m_context.getInstanceInterface();
929         const VkPhysicalDevice                                                                  physDevice                                      = m_context.getPhysicalDevice();
930         const VkPhysicalDeviceFeatures                                                  features                                        = getPhysicalDeviceFeatures(vki, physDevice);
931         const VkPhysicalDeviceTransformFeedbackFeaturesEXT&             transformFeedbackFeatures       = m_context.getTransformFeedbackFeatures();
932         const deUint32                                                                                  streamsSupported                        = m_transformFeedbackProperties.maxTransformFeedbackStreams;
933         const deUint32                                                                                  streamsRequired                         = m_parameters.streamId + 1;
934         const deUint32                                                                                  tfBuffersSupported                      = m_transformFeedbackProperties.maxTransformFeedbackBuffers;
935         const deUint32                                                                                  tfBuffersRequired                       = m_parameters.partCount;
936         const deUint32                                                                                  bytesPerVertex                          = m_parameters.bufferSize / m_parameters.partCount;
937         const deUint32                                                                                  tfStreamDataSizeSupported       = m_transformFeedbackProperties.maxTransformFeedbackStreamDataSize;
938         const deUint32                                                                                  tfBufferDataSizeSupported       = m_transformFeedbackProperties.maxTransformFeedbackBufferDataSize;
939         const deUint32                                                                                  tfBufferDataStrideSupported     = m_transformFeedbackProperties.maxTransformFeedbackBufferDataStride;
940
941         DE_ASSERT(m_parameters.partCount == 2u);
942
943         if (!features.geometryShader)
944                 TCU_THROW(NotSupportedError, "Missing feature: geometryShader");
945
946         if (transformFeedbackFeatures.geometryStreams == DE_FALSE)
947                 TCU_THROW(NotSupportedError, "geometryStreams feature is not supported");
948
949         if (streamsSupported < streamsRequired)
950                 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackStreams=" + de::toString(streamsSupported) + ", while test requires " + de::toString(streamsRequired)).c_str());
951
952         if (tfBuffersSupported < tfBuffersRequired)
953                 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBuffers=" + de::toString(tfBuffersSupported) + ", while test requires " + de::toString(tfBuffersRequired)).c_str());
954
955         if (tfStreamDataSizeSupported < bytesPerVertex)
956                 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackStreamDataSize=" + de::toString(tfStreamDataSizeSupported) + ", while test requires " + de::toString(bytesPerVertex)).c_str());
957
958         if (tfBufferDataSizeSupported < bytesPerVertex)
959                 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBufferDataSize=" + de::toString(tfBufferDataSizeSupported) + ", while test requires " + de::toString(bytesPerVertex)).c_str());
960
961         if (tfBufferDataStrideSupported < bytesPerVertex)
962                 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBufferDataStride=" + de::toString(tfBufferDataStrideSupported) + ", while test requires " + de::toString(bytesPerVertex)).c_str());
963 }
964
965 std::vector<VkDeviceSize> TransformFeedbackMultistreamTestInstance::generateSizesList (const size_t bufBytes, const size_t chunkCount)
966 {
967         const VkDeviceSize                      chunkSize       = bufBytes / chunkCount;
968         std::vector<VkDeviceSize>       result          (chunkCount, chunkSize);
969
970         DE_ASSERT(chunkSize * chunkCount == bufBytes);
971         DE_ASSERT(bufBytes <= MINIMUM_TF_BUFFER_SIZE);
972         DE_ASSERT(bufBytes % sizeof(deUint32) == 0);
973         DE_ASSERT(chunkCount > 0);
974         DE_ASSERT(result.size() == chunkCount);
975
976         return result;
977 }
978
979 void TransformFeedbackMultistreamTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes)
980 {
981         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
982         const VkDevice                  device          = m_context.getDevice();
983
984         invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), bufBytes);
985
986         const deUint32                  numPoints       = static_cast<deUint32>(bufBytes / sizeof(deUint32));
987         const float*                    tfData          = (float*)bufAlloc->getHostPtr();
988
989         for (deUint32 i = 0; i < numPoints; ++i)
990                 if (tfData[i] != float(i))
991                         TCU_FAIL(std::string("Failed at item ") + de::toString(float(i)) + " received:" + de::toString(tfData[i]) + " expected:" + de::toString(i));
992 }
993
994 tcu::TestStatus TransformFeedbackMultistreamTestInstance::iterate (void)
995 {
996         const DeviceInterface&                          vk                                              = m_context.getDeviceInterface();
997         const VkDevice                                          device                                  = m_context.getDevice();
998         const deUint32                                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
999         const VkQueue                                           queue                                   = m_context.getUniversalQueue();
1000         Allocator&                                                      allocator                               = m_context.getDefaultAllocator();
1001
1002         const Unique<VkRenderPass>                      renderPass                              (makeRenderPass                                                 (vk, device, VK_FORMAT_UNDEFINED));
1003
1004         const Unique<VkShaderModule>            vertexModule                    (createShaderModule                                             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
1005         const Unique<VkShaderModule>            geomModule                              (createShaderModule                                             (vk, device, m_context.getBinaryCollection().get("geom"), 0u));
1006
1007         const Unique<VkFramebuffer>                     framebuffer                             (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
1008         const Unique<VkPipelineLayout>          pipelineLayout                  (TransformFeedback::makePipelineLayout  (vk, device));
1009         const Unique<VkPipeline>                        pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, *geomModule, DE_NULL, m_imageExtent2D, 0u));
1010         const Unique<VkCommandPool>                     cmdPool                                 (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1011         const Unique<VkCommandBuffer>           cmdBuffer                               (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1012
1013         const VkBufferCreateInfo                        tfBufCreateInfo                 = makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
1014         const Move<VkBuffer>                            tfBuf                                   = createBuffer(vk, device, &tfBufCreateInfo);
1015         const std::vector<VkBuffer>                     tfBufArray                              = std::vector<VkBuffer>(m_parameters.partCount, *tfBuf);
1016         const MovePtr<Allocation>                       tfBufAllocation                 = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
1017         const std::vector<VkDeviceSize>         tfBufBindingSizes               = generateSizesList(m_parameters.bufferSize, m_parameters.partCount);
1018         const std::vector<VkDeviceSize>         tfBufBindingOffsets             = generateOffsetsList(tfBufBindingSizes);
1019
1020         VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
1021
1022         beginCommandBuffer(vk, *cmdBuffer);
1023         {
1024                 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
1025                 {
1026                         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1027
1028                         vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0u, m_parameters.partCount, &tfBufArray[0], &tfBufBindingOffsets[0], &tfBufBindingSizes[0]);
1029
1030                         vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
1031                         {
1032                                 vk.cmdDraw(*cmdBuffer, 1u, 1u, 0u, 0u);
1033                         }
1034                         vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
1035                 }
1036                 endRenderPass(vk, *cmdBuffer);
1037         }
1038         endCommandBuffer(vk, *cmdBuffer);
1039         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1040
1041         verifyTransformFeedbackBuffer(tfBufAllocation, m_parameters.bufferSize);
1042
1043         return tcu::TestStatus::pass("Pass");
1044 }
1045
1046 class TransformFeedbackStreamsTestInstance : public TransformFeedbackTestInstance
1047 {
1048 public:
1049                                                 TransformFeedbackStreamsTestInstance    (Context& context, const TestParameters& parameters);
1050
1051 protected:
1052         tcu::TestStatus         iterate                                                                 (void);
1053         bool                            verifyImage                                                             (const VkFormat imageFormat, const VkExtent2D& size, const void* resultData);
1054 };
1055
1056 TransformFeedbackStreamsTestInstance::TransformFeedbackStreamsTestInstance (Context& context, const TestParameters& parameters)
1057         : TransformFeedbackTestInstance (context, parameters)
1058 {
1059         const InstanceInterface&                                                                vki                                                     = m_context.getInstanceInterface();
1060         const VkPhysicalDevice                                                                  physDevice                                      = m_context.getPhysicalDevice();
1061         const VkPhysicalDeviceFeatures                                                  features                                        = getPhysicalDeviceFeatures(vki, physDevice);
1062         const VkPhysicalDeviceTransformFeedbackFeaturesEXT&             transformFeedbackFeatures       = m_context.getTransformFeedbackFeatures();
1063         const deUint32                                                                                  streamsSupported                        = m_transformFeedbackProperties.maxTransformFeedbackStreams;
1064         const deUint32                                                                                  streamsRequired                         = m_parameters.streamId + 1;
1065         const bool                                                                                              geomPointSizeRequired           = m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE;
1066
1067         if (!features.geometryShader)
1068                 TCU_THROW(NotSupportedError, "Missing feature: geometryShader");
1069
1070         if (transformFeedbackFeatures.geometryStreams == DE_FALSE)
1071                 TCU_THROW(NotSupportedError, "geometryStreams feature is not supported");
1072
1073         if (m_transformFeedbackProperties.transformFeedbackRasterizationStreamSelect == DE_FALSE)
1074                 TCU_THROW(NotSupportedError, "transformFeedbackRasterizationStreamSelect feature is not supported");
1075
1076         if (streamsSupported < streamsRequired)
1077                 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackStreams=" + de::toString(streamsSupported) + ", while test requires " + de::toString(streamsRequired)).c_str());
1078
1079         if (geomPointSizeRequired && !features.shaderTessellationAndGeometryPointSize)
1080                 TCU_THROW(NotSupportedError, "shaderTessellationAndGeometryPointSize feature is not supported");
1081 }
1082
1083 bool TransformFeedbackStreamsTestInstance::verifyImage (const VkFormat imageFormat, const VkExtent2D& size, const void* resultData)
1084 {
1085         const tcu::RGBA                         magentaRGBA             (tcu::RGBA(0xFF, 0x00, 0xFF, 0xFF));
1086         const tcu::Vec4                         magenta                 (magentaRGBA.toVec());
1087         const tcu::Vec4                         black                   (tcu::RGBA::black().toVec());
1088         const tcu::TextureFormat        textureFormat   (mapVkFormat(imageFormat));
1089         const int                                       dataSize                (size.width * size.height * textureFormat.getPixelSize());
1090         tcu::TextureLevel                       referenceImage  (textureFormat, size.width, size.height);
1091         tcu::PixelBufferAccess          referenceAccess (referenceImage.getAccess());
1092
1093         // Generate reference image
1094         if (m_parameters.testType == TEST_TYPE_STREAMS)
1095         {
1096                 for (int y = 0; y < referenceImage.getHeight(); ++y)
1097                 {
1098                         const tcu::Vec4&        validColor = y < referenceImage.getHeight() / 2 ? black : magenta;
1099
1100                         for (int x = 0; x < referenceImage.getWidth(); ++x)
1101                                 referenceAccess.setPixel(validColor, x, y);
1102                 }
1103         }
1104
1105         if (m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE || m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE)
1106         {
1107                 for (int y = 0; y < referenceImage.getHeight(); ++y)
1108                         for (int x = 0; x < referenceImage.getWidth(); ++x)
1109                         {
1110                                 const tcu::Vec4&        validColor      = (y >= referenceImage.getHeight() / 2) && (x >= referenceImage.getWidth() / 2) ? magenta : black;
1111
1112                                 referenceAccess.setPixel(validColor, x, y);
1113                         }
1114         }
1115
1116         if (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE)
1117         {
1118                 const int                       pointSize       = static_cast<int>(m_parameters.pointSize);
1119                 const tcu::Vec4&        validColor      = black;
1120
1121                 for (int y = 0; y < referenceImage.getHeight(); ++y)
1122                         for (int x = 0; x < referenceImage.getWidth(); ++x)
1123                                 referenceAccess.setPixel(validColor, x, y);
1124
1125                 referenceAccess.setPixel(magenta, (1 + referenceImage.getWidth()) / 4 - 1, (referenceImage.getHeight() * 3) / 4 - 1);
1126
1127                 for (int y = 0; y < pointSize; ++y)
1128                         for (int x = 0; x < pointSize; ++x)
1129                                 referenceAccess.setPixel(magenta, x + (referenceImage.getWidth() * 3) / 4 - 1, y + (referenceImage.getHeight() * 3) / 4 - 1);
1130         }
1131
1132         if (deMemCmp(resultData, referenceAccess.getDataPtr(), dataSize) != 0)
1133         {
1134                 const tcu::ConstPixelBufferAccess       resultImage     (textureFormat, size.width, size.height, 1, resultData);
1135                 bool                                                            ok;
1136
1137                 ok = tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Image comparison", "", referenceAccess, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
1138
1139                 return ok;
1140         }
1141
1142         return true;
1143 }
1144
1145 tcu::TestStatus TransformFeedbackStreamsTestInstance::iterate (void)
1146 {
1147         const DeviceInterface&                          vk                                      = m_context.getDeviceInterface();
1148         const VkDevice                                          device                          = m_context.getDevice();
1149         const deUint32                                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
1150         const VkQueue                                           queue                           = m_context.getUniversalQueue();
1151         Allocator&                                                      allocator                       = m_context.getDefaultAllocator();
1152
1153         const Unique<VkRenderPass>                      renderPass                      (makeRenderPass                 (vk, device, VK_FORMAT_R8G8B8A8_UNORM));
1154
1155         const Unique<VkShaderModule>            vertModule                      (createShaderModule             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
1156         const Unique<VkShaderModule>            geomModule                      (createShaderModule             (vk, device, m_context.getBinaryCollection().get("geom"), 0u));
1157         const Unique<VkShaderModule>            fragModule                      (createShaderModule             (vk, device, m_context.getBinaryCollection().get("frag"), 0u));
1158
1159         const VkFormat                                          colorFormat                     = VK_FORMAT_R8G8B8A8_UNORM;
1160         const VkImageUsageFlags                         imageUsageFlags         = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1161         const tcu::RGBA                                         clearColor                      (tcu::RGBA::black());
1162         const VkImageSubresourceRange           colorSubresRange        (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
1163         const VkDeviceSize                                      colorBufferSize         (m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat)));
1164         const Unique<VkImage>                           colorImage                      (makeImage                                                              (vk, device, makeImageCreateInfo(0u, VK_IMAGE_TYPE_2D, colorFormat, m_imageExtent2D, 1u, imageUsageFlags)));
1165         const UniquePtr<Allocation>                     colorImageAlloc         (bindImage                                                              (vk, device, allocator, *colorImage, MemoryRequirement::Any));
1166         const Unique<VkImageView>                       colorAttachment         (makeImageView                                                  (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
1167         const Unique<VkBuffer>                          colorBuffer                     (makeBuffer                                                             (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
1168         const UniquePtr<Allocation>                     colorBufferAlloc        (bindBuffer                                                             (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1169
1170         const Unique<VkFramebuffer>                     framebuffer                     (makeFramebuffer                                                (vk, device, *renderPass, *colorAttachment, m_imageExtent2D.width, m_imageExtent2D.height));
1171         const Unique<VkPipelineLayout>          pipelineLayout          (TransformFeedback::makePipelineLayout  (vk, device));
1172         const Unique<VkPipeline>                        pipeline                        (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertModule, *geomModule, *fragModule, m_imageExtent2D, 0u, &m_parameters.streamId));
1173         const Unique<VkCommandPool>                     cmdPool                         (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1174         const Unique<VkCommandBuffer>           cmdBuffer                       (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1175
1176         const VkImageMemoryBarrier                      preCopyBarrier          = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1177                                                                                                                                                                          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1178                                                                                                                                                                          *colorImage, colorSubresRange);
1179         const VkBufferImageCopy                         region                          = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
1180                                                                                                                                                                   makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
1181         const VkBufferMemoryBarrier                     postCopyBarrier         = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);
1182
1183         beginCommandBuffer(vk, *cmdBuffer);
1184         {
1185                 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor.toVec());
1186                 {
1187                         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1188
1189                         vk.cmdDraw(*cmdBuffer, 2u, 1u, 0u, 0u);
1190                 }
1191                 endRenderPass(vk, *cmdBuffer);
1192
1193                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
1194                 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);
1195                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
1196         }
1197         endCommandBuffer(vk, *cmdBuffer);
1198         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1199
1200         if (!verifyImage(colorFormat, m_imageExtent2D, colorBufferAlloc->getHostPtr()))
1201                 return tcu::TestStatus::fail("Fail");
1202
1203         return tcu::TestStatus::pass("Pass");
1204 }
1205
1206 class TransformFeedbackIndirectDrawTestInstance : public TransformFeedbackTestInstance
1207 {
1208 public:
1209                                                 TransformFeedbackIndirectDrawTestInstance       (Context& context, const TestParameters& parameters);
1210
1211 protected:
1212         tcu::TestStatus         iterate                                                                         (void);
1213         bool                            verifyImage                                                                     (const VkFormat imageFormat, const VkExtent2D& size, const void* resultData);
1214 };
1215
1216 TransformFeedbackIndirectDrawTestInstance::TransformFeedbackIndirectDrawTestInstance (Context& context, const TestParameters& parameters)
1217         : TransformFeedbackTestInstance (context, parameters)
1218 {
1219         const InstanceInterface&                vki                                                     = m_context.getInstanceInterface();
1220         const VkPhysicalDevice                  physDevice                                      = m_context.getPhysicalDevice();
1221         const VkPhysicalDeviceLimits    limits                                          = getPhysicalDeviceProperties(vki, physDevice).limits;
1222         const deUint32                                  tfBufferDataSizeSupported       = m_transformFeedbackProperties.maxTransformFeedbackBufferDataSize;
1223         const deUint32                                  tfBufferDataStrideSupported     = m_transformFeedbackProperties.maxTransformFeedbackBufferDataStride;
1224
1225         if (m_transformFeedbackProperties.transformFeedbackDraw == DE_FALSE)
1226                 TCU_THROW(NotSupportedError, "transformFeedbackDraw feature is not supported");
1227
1228         if (limits.maxVertexInputBindingStride < m_parameters.vertexStride)
1229                 TCU_THROW(NotSupportedError, std::string("maxVertexInputBindingStride=" + de::toString(limits.maxVertexInputBindingStride) + ", while test requires " + de::toString(m_parameters.vertexStride)).c_str());
1230
1231         if (tfBufferDataSizeSupported < m_parameters.vertexStride)
1232                 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBufferDataSize=" + de::toString(tfBufferDataSizeSupported) + ", while test requires " + de::toString(m_parameters.vertexStride)).c_str());
1233
1234         if (tfBufferDataStrideSupported < m_parameters.vertexStride)
1235                 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBufferDataStride=" + de::toString(tfBufferDataStrideSupported) + ", while test requires " + de::toString(m_parameters.vertexStride)).c_str());
1236 }
1237
1238 bool TransformFeedbackIndirectDrawTestInstance::verifyImage (const VkFormat imageFormat, const VkExtent2D& size, const void* resultData)
1239 {
1240         const tcu::Vec4                         white                   (tcu::RGBA::white().toVec());
1241         const tcu::TextureFormat        textureFormat   (mapVkFormat(imageFormat));
1242         const int                                       dataSize                (size.width * size.height * textureFormat.getPixelSize());
1243         tcu::TextureLevel                       referenceImage  (textureFormat, size.width, size.height);
1244         tcu::PixelBufferAccess          referenceAccess (referenceImage.getAccess());
1245
1246         // Generate reference image
1247         for (int y = 0; y < referenceImage.getHeight(); ++y)
1248                 for (int x = 0; x < referenceImage.getWidth(); ++x)
1249                         referenceAccess.setPixel(white, x, y);
1250
1251         if (deMemCmp(resultData, referenceAccess.getDataPtr(), dataSize) != 0)
1252         {
1253                 const tcu::ConstPixelBufferAccess       resultImage     (textureFormat, size.width, size.height, 1, resultData);
1254                 bool                                                            ok;
1255
1256                 ok = tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Image comparison", "", referenceAccess, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
1257
1258                 return ok;
1259         }
1260
1261         return true;
1262 }
1263
1264 tcu::TestStatus TransformFeedbackIndirectDrawTestInstance::iterate (void)
1265 {
1266         const DeviceInterface&                          vk                                      = m_context.getDeviceInterface();
1267         const VkDevice                                          device                          = m_context.getDevice();
1268         const deUint32                                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
1269         const VkQueue                                           queue                           = m_context.getUniversalQueue();
1270         Allocator&                                                      allocator                       = m_context.getDefaultAllocator();
1271
1272         const Unique<VkRenderPass>                      renderPass                      (makeRenderPass                 (vk, device, VK_FORMAT_R8G8B8A8_UNORM));
1273
1274         const Unique<VkShaderModule>            vertModule                      (createShaderModule             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
1275         const Unique<VkShaderModule>            fragModule                      (createShaderModule             (vk, device, m_context.getBinaryCollection().get("frag"), 0u));
1276
1277         const VkFormat                                          colorFormat                     = VK_FORMAT_R8G8B8A8_UNORM;
1278         const VkImageUsageFlags                         imageUsageFlags         = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1279         const tcu::RGBA                                         clearColor                      (tcu::RGBA::black());
1280         const VkImageSubresourceRange           colorSubresRange        (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
1281         const VkDeviceSize                                      colorBufferSize         (m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat)));
1282         const Unique<VkImage>                           colorImage                      (makeImage                              (vk, device, makeImageCreateInfo(0u, VK_IMAGE_TYPE_2D, colorFormat, m_imageExtent2D, 1u, imageUsageFlags)));
1283         const UniquePtr<Allocation>                     colorImageAlloc         (bindImage                              (vk, device, allocator, *colorImage, MemoryRequirement::Any));
1284         const Unique<VkImageView>                       colorAttachment         (makeImageView                  (vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
1285         const Unique<VkBuffer>                          colorBuffer                     (makeBuffer                             (vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
1286         const UniquePtr<Allocation>                     colorBufferAlloc        (bindBuffer                             (vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1287
1288         const deUint32                                          vertexCount                     = 6u;
1289         const VkDeviceSize                                      vertexBufferSize        = vertexCount * m_parameters.vertexStride;
1290         const VkBufferUsageFlags                        vertexBufferUsage       = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1291         const Unique<VkBuffer>                          vertexBuffer            (makeBuffer                             (vk, device, makeBufferCreateInfo(vertexBufferSize, vertexBufferUsage)));
1292         const UniquePtr<Allocation>                     vertexBufferAlloc       (bindBuffer                             (vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
1293         const VkDeviceSize                                      vertexBufferOffset      (0u);
1294         const float                                                     vertexBufferVals[]      =
1295                                                                                                                                 {
1296                                                                                                                                         -1.0f, -1.0f, 0.0f, 1.0f,
1297                                                                                                                                         -1.0f, +1.0f, 0.0f, 1.0f,
1298                                                                                                                                         +1.0f, -1.0f, 0.0f, 1.0f,
1299                                                                                                                                         -1.0f, +1.0f, 0.0f, 1.0f,
1300                                                                                                                                         +1.0f, -1.0f, 0.0f, 1.0f,
1301                                                                                                                                         +1.0f, +1.0f, 0.0f, 1.0f,
1302                                                                                                                                 };
1303
1304         const deUint32                                          counterBufferValue      = m_parameters.vertexStride * vertexCount;
1305         const VkDeviceSize                                      counterBufferSize       = sizeof(counterBufferValue);
1306         const VkBufferUsageFlags                        counterBufferUsage      = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1307         const Unique<VkBuffer>                          counterBuffer           (makeBuffer                                                             (vk, device, makeBufferCreateInfo(counterBufferSize, counterBufferUsage)));
1308         const UniquePtr<Allocation>                     counterBufferAlloc      (bindBuffer                                                             (vk, device, allocator, *counterBuffer, MemoryRequirement::HostVisible));
1309
1310         const Unique<VkFramebuffer>                     framebuffer                     (makeFramebuffer                                                (vk, device, *renderPass, *colorAttachment, m_imageExtent2D.width, m_imageExtent2D.height));
1311         const Unique<VkPipelineLayout>          pipelineLayout          (TransformFeedback::makePipelineLayout  (vk, device));
1312         const Unique<VkPipeline>                        pipeline                        (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertModule, DE_NULL, *fragModule, m_imageExtent2D, 0u, DE_NULL, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, true));
1313         const Unique<VkCommandPool>                     cmdPool                         (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1314         const Unique<VkCommandBuffer>           cmdBuffer                       (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1315
1316         const VkImageMemoryBarrier                      preCopyBarrier          = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1317                                                                                                                                                                          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1318                                                                                                                                                                          *colorImage, colorSubresRange);
1319         const VkBufferImageCopy                         region                          = makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
1320                                                                                                                                                                   makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
1321         const VkBufferMemoryBarrier                     postCopyBarrier         = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);
1322
1323         fillBuffer(vk, device, *counterBufferAlloc, counterBufferSize, &counterBufferValue, counterBufferSize);
1324         fillBuffer(vk, device, *vertexBufferAlloc, vertexBufferSize, vertexBufferVals, sizeof(vertexBufferVals));
1325
1326         beginCommandBuffer(vk, *cmdBuffer);
1327         {
1328                 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor.toVec());
1329                 {
1330                         vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
1331
1332                         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1333
1334                         vk.cmdDrawIndirectByteCountEXT(*cmdBuffer, 1u, 0u, *counterBuffer, 0u, 0u, m_parameters.vertexStride);
1335                 }
1336                 endRenderPass(vk, *cmdBuffer);
1337
1338                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
1339                 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);
1340                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
1341         }
1342         endCommandBuffer(vk, *cmdBuffer);
1343         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1344
1345         if (!verifyImage(colorFormat, m_imageExtent2D, colorBufferAlloc->getHostPtr()))
1346                 return tcu::TestStatus::fail("Fail");
1347
1348         return tcu::TestStatus::pass("Pass");
1349 }
1350
1351 class TransformFeedbackBackwardDependencyTestInstance : public TransformFeedbackTestInstance
1352 {
1353 public:
1354                                                                 TransformFeedbackBackwardDependencyTestInstance (Context& context, const TestParameters& parameters);
1355
1356 protected:
1357         tcu::TestStatus                         iterate                                                                                 (void);
1358         std::vector<VkDeviceSize>       generateSizesList                                                               (const size_t bufBytes, const size_t chunkCount);
1359 };
1360
1361 TransformFeedbackBackwardDependencyTestInstance::TransformFeedbackBackwardDependencyTestInstance (Context& context, const TestParameters& parameters)
1362         : TransformFeedbackTestInstance (context, parameters)
1363 {
1364         if (m_transformFeedbackProperties.transformFeedbackDraw == DE_FALSE)
1365                 TCU_THROW(NotSupportedError, "transformFeedbackDraw feature is not supported");
1366 }
1367
1368 std::vector<VkDeviceSize> TransformFeedbackBackwardDependencyTestInstance::generateSizesList (const size_t bufBytes, const size_t chunkCount)
1369 {
1370         const VkDeviceSize                      chunkSize       = bufBytes / chunkCount;
1371         std::vector<VkDeviceSize>       result          (chunkCount, chunkSize);
1372
1373         DE_ASSERT(chunkSize * chunkCount == bufBytes);
1374         DE_ASSERT(bufBytes <= MINIMUM_TF_BUFFER_SIZE);
1375         DE_ASSERT(bufBytes % sizeof(deUint32) == 0);
1376         DE_ASSERT(chunkCount > 0);
1377         DE_ASSERT(result.size() == chunkCount);
1378
1379         return result;
1380 }
1381
1382 tcu::TestStatus TransformFeedbackBackwardDependencyTestInstance::iterate (void)
1383 {
1384         const DeviceInterface&                          vk                                      = m_context.getDeviceInterface();
1385         const VkDevice                                          device                          = m_context.getDevice();
1386         const deUint32                                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
1387         const VkQueue                                           queue                           = m_context.getUniversalQueue();
1388         Allocator&                                                      allocator                       = m_context.getDefaultAllocator();
1389
1390         const Unique<VkShaderModule>            vertexModule            (createShaderModule                                             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
1391         const Unique<VkRenderPass>                      renderPass                      (TransformFeedback::makeRenderPass              (vk, device));
1392         const Unique<VkFramebuffer>                     framebuffer                     (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
1393         const Unique<VkPipelineLayout>          pipelineLayout          (TransformFeedback::makePipelineLayout  (vk, device));
1394         const Unique<VkPipeline>                        pipeline                        (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
1395         const Unique<VkCommandPool>                     cmdPool                         (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1396         const Unique<VkCommandBuffer>           cmdBuffer                       (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1397
1398         const VkBufferCreateInfo                        tfBufCreateInfo         = makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
1399         const Move<VkBuffer>                            tfBuf                           = createBuffer(vk, device, &tfBufCreateInfo);
1400         const MovePtr<Allocation>                       tfBufAllocation         = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
1401         const VkDeviceSize                                      tfBufBindingSize        = m_parameters.bufferSize;
1402         const VkDeviceSize                                      tfBufBindingOffset      = 0ull;
1403
1404         const size_t                                            tfcBufSize                      = sizeof(deUint32);
1405         const VkBufferCreateInfo                        tfcBufCreateInfo        = makeBufferCreateInfo(tfcBufSize, VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
1406         const Move<VkBuffer>                            tfcBuf                          = createBuffer(vk, device, &tfcBufCreateInfo);
1407         const MovePtr<Allocation>                       tfcBufAllocation        = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfcBuf), MemoryRequirement::Any);
1408         const VkDeviceSize                                      tfcBufBindingOffset     = 0ull;
1409         const VkMemoryBarrier                           tfcMemoryBarrier        = makeMemoryBarrier(VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT);
1410
1411         const std::vector<VkDeviceSize>         chunkSizesList          = generateSizesList(m_parameters.bufferSize, m_parameters.partCount);
1412         const std::vector<VkDeviceSize>         chunkOffsetsList        = generateOffsetsList(chunkSizesList);
1413
1414         VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
1415         VK_CHECK(vk.bindBufferMemory(device, *tfcBuf, tfcBufAllocation->getMemory(), tfcBufAllocation->getOffset()));
1416
1417         DE_ASSERT(m_parameters.partCount == 2u);
1418
1419         beginCommandBuffer(vk, *cmdBuffer);
1420         {
1421                 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
1422                 {
1423                         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1424
1425                         vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &tfBufBindingOffset, &tfBufBindingSize);
1426
1427                         {
1428                                 const deUint32  startValue      = static_cast<deUint32>(chunkOffsetsList[0] / sizeof(deUint32));
1429                                 const deUint32  numPoints       = static_cast<deUint32>(chunkSizesList[0] / sizeof(deUint32));
1430
1431                                 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);
1432
1433                                 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
1434                                 {
1435                                         vk.cmdDraw(*cmdBuffer, numPoints, 1u, 0u, 0u);
1436                                 }
1437                                 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 1, &*tfcBuf, &tfcBufBindingOffset);
1438                         }
1439
1440                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0u, 1u, &tfcMemoryBarrier, 0u, DE_NULL, DE_NULL, 0u);
1441
1442                         {
1443                                 const deUint32  startValue      = static_cast<deUint32>(chunkOffsetsList[1] / sizeof(deUint32));
1444
1445                                 vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);
1446
1447                                 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 1, &*tfcBuf, &tfcBufBindingOffset);
1448                                 {
1449                                         vk.cmdDrawIndirectByteCountEXT(*cmdBuffer, 1u, 0u, *tfcBuf, 0u, 0u, 4u);
1450                                 }
1451                                 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
1452                         }
1453
1454                 }
1455                 endRenderPass(vk, *cmdBuffer);
1456         }
1457         endCommandBuffer(vk, *cmdBuffer);
1458         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1459
1460         verifyTransformFeedbackBuffer(tfBufAllocation, m_parameters.bufferSize);
1461
1462         return tcu::TestStatus::pass("Pass");
1463 }
1464
1465
1466 class TransformFeedbackQueryTestInstance : public TransformFeedbackTestInstance
1467 {
1468 public:
1469                                                 TransformFeedbackQueryTestInstance      (Context& context, const TestParameters& parameters);
1470
1471 protected:
1472         tcu::TestStatus         iterate                                                         (void);
1473 };
1474
1475 TransformFeedbackQueryTestInstance::TransformFeedbackQueryTestInstance (Context& context, const TestParameters& parameters)
1476         : TransformFeedbackTestInstance (context, parameters)
1477 {
1478         const InstanceInterface&                                                                vki                                                     = m_context.getInstanceInterface();
1479         const VkPhysicalDevice                                                                  physDevice                                      = m_context.getPhysicalDevice();
1480         const VkPhysicalDeviceFeatures                                                  features                                        = getPhysicalDeviceFeatures(vki, physDevice);
1481         const VkPhysicalDeviceTransformFeedbackFeaturesEXT&             transformFeedbackFeatures       = m_context.getTransformFeedbackFeatures();
1482         const deUint32                                                                                  streamsSupported                        = m_transformFeedbackProperties.maxTransformFeedbackStreams;
1483         const deUint32                                                                                  streamsRequired                         = m_parameters.streamId + 1;
1484
1485         if (!features.geometryShader)
1486                 TCU_THROW(NotSupportedError, "Missing feature: geometryShader");
1487
1488         if (transformFeedbackFeatures.geometryStreams == DE_FALSE)
1489                 TCU_THROW(NotSupportedError, "geometryStreams feature is not supported");
1490
1491         if (streamsSupported < streamsRequired)
1492                 TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackStreams=" + de::toString(streamsSupported) + ", while test requires " + de::toString(streamsRequired)).c_str());
1493
1494         if (m_transformFeedbackProperties.transformFeedbackQueries == DE_FALSE)
1495                 TCU_THROW(NotSupportedError, "transformFeedbackQueries feature is not supported");
1496
1497         if (m_parameters.testType == TEST_TYPE_QUERY_RESET)
1498         {
1499                 // Check VK_EXT_host_query_reset is supported
1500                 m_context.requireDeviceExtension("VK_EXT_host_query_reset");
1501                 if(m_context.getHostQueryResetFeatures().hostQueryReset == VK_FALSE)
1502                         throw tcu::NotSupportedError(std::string("Implementation doesn't support resetting queries from the host").c_str());
1503         }
1504 }
1505
1506 tcu::TestStatus TransformFeedbackQueryTestInstance::iterate (void)
1507 {
1508         const DeviceInterface&                          vk                                              = m_context.getDeviceInterface();
1509         const VkDevice                                          device                                  = m_context.getDevice();
1510         const deUint32                                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
1511         const VkQueue                                           queue                                   = m_context.getUniversalQueue();
1512         Allocator&                                                      allocator                               = m_context.getDefaultAllocator();
1513
1514         const deUint32                                          overflowVertices                = 3u;
1515         const deUint32                                          bytesPerVertex                  = static_cast<deUint32>(4 * sizeof(float));
1516         const deUint32                                          numVerticesInBuffer             = m_parameters.bufferSize / bytesPerVertex;
1517         const deUint32                                          numVerticesToWrite              = numVerticesInBuffer + overflowVertices;
1518         const Unique<VkRenderPass>                      renderPass                              (makeRenderPass                                                 (vk, device, VK_FORMAT_UNDEFINED));
1519
1520         const Unique<VkShaderModule>            vertModule                              (createShaderModule                                             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
1521         const Unique<VkShaderModule>            geomModule                              (createShaderModule                                             (vk, device, m_context.getBinaryCollection().get("geom"), 0u));
1522
1523         const Unique<VkFramebuffer>                     framebuffer                             (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
1524         const Unique<VkPipelineLayout>          pipelineLayout                  (TransformFeedback::makePipelineLayout  (vk, device));
1525         const Unique<VkPipeline>                        pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertModule, *geomModule, DE_NULL, m_imageExtent2D, 0u));
1526         const Unique<VkCommandPool>                     cmdPool                                 (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1527         const Unique<VkCommandBuffer>           cmdBuffer                               (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1528
1529         const VkBufferCreateInfo                        tfBufCreateInfo                 = makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
1530         const Move<VkBuffer>                            tfBuf                                   = createBuffer(vk, device, &tfBufCreateInfo);
1531         const MovePtr<Allocation>                       tfBufAllocation                 = bindBuffer(vk, device, allocator, *tfBuf, MemoryRequirement::HostVisible);
1532         const VkDeviceSize                                      tfBufBindingSize                = m_parameters.bufferSize;
1533         const VkDeviceSize                                      tfBufBindingOffset              = 0ull;
1534
1535         const deUint32                                          queryCountersNumber             = 1u;
1536         const deUint32                                          queryIndex                              = 0u;
1537         const VkQueryPoolCreateInfo                     queryPoolCreateInfo             = makeQueryPoolCreateInfo(queryCountersNumber);
1538         const Unique<VkQueryPool>                       queryPool                               (createQueryPool(vk, device, &queryPoolCreateInfo));
1539
1540         DE_ASSERT(numVerticesInBuffer * bytesPerVertex == m_parameters.bufferSize);
1541
1542         beginCommandBuffer(vk, *cmdBuffer);
1543         {
1544                 vk.cmdResetQueryPool(*cmdBuffer, *queryPool, queryIndex, queryCountersNumber);
1545
1546                 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
1547                 {
1548                         vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1549
1550                         vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0u, 1u, &*tfBuf, &tfBufBindingOffset, &tfBufBindingSize);
1551
1552                         if (m_parameters.streamId == 0)
1553                                 vk.cmdBeginQuery(*cmdBuffer, *queryPool, queryIndex, 0u);
1554                         else
1555                                 vk.cmdBeginQueryIndexedEXT(*cmdBuffer, *queryPool, queryIndex, 0u, m_parameters.streamId);
1556                         {
1557                                 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
1558                                 {
1559                                         vk.cmdDraw(*cmdBuffer, numVerticesToWrite, 1u, 0u, 0u);
1560                                 }
1561                                 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
1562                         }
1563                         if (m_parameters.streamId == 0)
1564                                 vk.cmdEndQuery(*cmdBuffer, *queryPool, queryIndex);
1565                         else
1566                                 vk.cmdEndQueryIndexedEXT(*cmdBuffer, *queryPool, queryIndex, m_parameters.streamId);
1567                 }
1568                 endRenderPass(vk, *cmdBuffer);
1569         }
1570         endCommandBuffer(vk, *cmdBuffer);
1571
1572         if (m_parameters.testType == TEST_TYPE_QUERY_RESET)
1573                 vk.resetQueryPoolEXT(device, *queryPool, queryIndex, queryCountersNumber);
1574         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1575
1576         {
1577                 const deUint32                  queryDataSize                   (static_cast<deUint32>(2u * sizeof(deUint32)));
1578                 std::vector<deUint8>    queryData                               (queryDataSize, 0u);
1579                 const deUint32*                 numPrimitivesWritten    = reinterpret_cast<deUint32*>(&queryData[0]);
1580                 const deUint32*                 numPrimitivesNeeded             = numPrimitivesWritten + 1;
1581
1582                 vk.getQueryPoolResults(device, *queryPool, queryIndex, queryCountersNumber, queryDataSize, &queryData[0], queryDataSize, 0u);
1583
1584                 if (*numPrimitivesWritten != numVerticesInBuffer)
1585                         return tcu::TestStatus::fail("numPrimitivesWritten=" + de::toString(*numPrimitivesWritten) + " while expected " + de::toString(numVerticesInBuffer));
1586
1587                 if (*numPrimitivesNeeded != numVerticesToWrite)
1588                         return tcu::TestStatus::fail("numPrimitivesNeeded=" + de::toString(*numPrimitivesNeeded) + " while expected " + de::toString(numVerticesToWrite));
1589         }
1590
1591         if (m_parameters.testType == TEST_TYPE_QUERY_RESET)
1592         {
1593
1594                 const deUint32                  queryDataSize                   (static_cast<deUint32>(3u * sizeof(deUint32)));
1595                 std::vector<deUint8>    queryData                               (queryDataSize, 0u);
1596                 deUint32*                       numPrimitivesWritten    = reinterpret_cast<deUint32*>(&queryData[0]);
1597                 deUint32*                       numPrimitivesNeeded             = numPrimitivesWritten + 1;
1598                 deUint32*                       availabilityState               = numPrimitivesNeeded + 1;
1599
1600                 // Initialize values
1601                 *numPrimitivesNeeded    = 1u;
1602                 *numPrimitivesWritten   = 1u;
1603                 *availabilityState              = 1u;
1604
1605                 vk.resetQueryPoolEXT(device, *queryPool, queryIndex, queryCountersNumber);
1606
1607                 vk::VkResult res = vk.getQueryPoolResults(device, *queryPool, queryIndex, queryCountersNumber, queryDataSize, &queryData[0], queryDataSize, VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
1608                 /* From Vulkan spec:
1609                         *
1610                         * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
1611                         * for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
1612                         * However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
1613                         */
1614                 if (res != vk::VK_NOT_READY || *availabilityState != 0u)
1615                         return tcu::TestStatus::fail("QueryPoolResults incorrect reset");
1616             if (*numPrimitivesWritten != 1u || *numPrimitivesNeeded != 1u )
1617                         return tcu::TestStatus::fail("QueryPoolResults data was modified");
1618
1619         }
1620
1621         return tcu::TestStatus::pass("Pass");
1622 }
1623
1624 class TransformFeedbackTestCase : public vkt::TestCase
1625 {
1626 public:
1627                                                 TransformFeedbackTestCase       (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters);
1628
1629 protected:
1630         vkt::TestInstance*      createInstance                          (vkt::Context& context) const;
1631         void                            initPrograms                            (SourceCollections& programCollection) const;
1632
1633         TestParameters          m_parameters;
1634 };
1635
1636 TransformFeedbackTestCase::TransformFeedbackTestCase (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters)
1637         : TestCase              (context, name, description)
1638         , m_parameters  (parameters)
1639 {
1640 }
1641
1642 vkt::TestInstance*      TransformFeedbackTestCase::createInstance (vkt::Context& context) const
1643 {
1644         if (m_parameters.testType == TEST_TYPE_BASIC)
1645                 return new TransformFeedbackBasicTestInstance(context, m_parameters);
1646
1647         if (m_parameters.testType == TEST_TYPE_RESUME)
1648                 return new TransformFeedbackResumeTestInstance(context, m_parameters);
1649
1650         if (m_parameters.testType == TEST_TYPE_XFB_POINTSIZE)
1651                 return new TransformFeedbackBuiltinTestInstance(context, m_parameters);
1652
1653         if (m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE)
1654                 return new TransformFeedbackBuiltinTestInstance(context, m_parameters);
1655
1656         if (m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE)
1657                 return new TransformFeedbackBuiltinTestInstance(context, m_parameters);
1658
1659         if (m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL)
1660                 return new TransformFeedbackBuiltinTestInstance(context, m_parameters);
1661
1662         if (m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP_ADJACENCY)
1663                 return new TransformFeedbackTriangleStripWithAdjacencyTestInstance(context, m_parameters);
1664
1665         if (m_parameters.testType == TEST_TYPE_STREAMS)
1666                 return new TransformFeedbackStreamsTestInstance(context, m_parameters);
1667
1668         if (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE)
1669                 return new TransformFeedbackStreamsTestInstance(context, m_parameters);
1670
1671         if (m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE)
1672                 return new TransformFeedbackStreamsTestInstance(context, m_parameters);
1673
1674         if (m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE)
1675                 return new TransformFeedbackStreamsTestInstance(context, m_parameters);
1676
1677         if (m_parameters.testType == TEST_TYPE_MULTISTREAMS)
1678                 return new TransformFeedbackMultistreamTestInstance(context, m_parameters);
1679
1680         if (m_parameters.testType == TEST_TYPE_DRAW_INDIRECT)
1681                 return new TransformFeedbackIndirectDrawTestInstance(context, m_parameters);
1682
1683         if (m_parameters.testType == TEST_TYPE_BACKWARD_DEPENDENCY)
1684                 return new TransformFeedbackBackwardDependencyTestInstance(context, m_parameters);
1685
1686         if (m_parameters.testType == TEST_TYPE_QUERY || m_parameters.testType == TEST_TYPE_QUERY_RESET)
1687                 return new TransformFeedbackQueryTestInstance(context, m_parameters);
1688
1689         TCU_THROW(InternalError, "Specified test type not found");
1690 }
1691
1692 void TransformFeedbackTestCase::initPrograms (SourceCollections& programCollection) const
1693 {
1694         const bool vertexShaderOnly             =  m_parameters.testType == TEST_TYPE_BASIC
1695                                                                         || m_parameters.testType == TEST_TYPE_RESUME
1696                                                                         || m_parameters.testType == TEST_TYPE_BACKWARD_DEPENDENCY
1697                                                                         || m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP_ADJACENCY;
1698         const bool requiresFullPipeline =  m_parameters.testType == TEST_TYPE_STREAMS
1699                                                                         || m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE
1700                                                                         || m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE
1701                                                                         || m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE;
1702         const bool xfbBuiltinPipeline   =  m_parameters.testType == TEST_TYPE_XFB_POINTSIZE
1703                                                                         || m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE
1704                                                                         || m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE
1705                                                                         || m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL;
1706
1707         if (vertexShaderOnly)
1708         {
1709                 // Vertex shader
1710                 {
1711                         std::ostringstream src;
1712                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1713                                 << "\n"
1714                                 << "layout(push_constant) uniform pushConstants\n"
1715                                 << "{\n"
1716                                 << "    uint start;\n"
1717                                 << "} uInput;\n"
1718                                 << "\n"
1719                                 << "layout(xfb_buffer = 0, xfb_offset = 0, xfb_stride = 4, location = 0) out uint idx_out;\n"
1720                                 << "\n"
1721                                 << "void main(void)\n"
1722                                 << "{\n"
1723                                 << "    idx_out = uInput.start + gl_VertexIndex;\n"
1724                                 << "}\n";
1725
1726                         programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
1727                 }
1728
1729                 return;
1730         }
1731
1732         if (xfbBuiltinPipeline)
1733         {
1734                 const std::string       outputBuiltIn           = (m_parameters.testType == TEST_TYPE_XFB_POINTSIZE)     ? "float gl_PointSize;\n"
1735                                                                                                 : (m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE)  ? "float gl_ClipDistance[8];\n"
1736                                                                                                 : (m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE)  ? "float gl_CullDistance[8];\n"
1737                                                                                                 : (m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) ? "float gl_CullDistance[5];\nfloat gl_ClipDistance[1];\n"
1738                                                                                                 : "";
1739                 const std::string       operationBuiltIn        = (m_parameters.testType == TEST_TYPE_XFB_POINTSIZE)     ? "gl_PointSize = float(gl_VertexIndex) / 32768.0f;"
1740                                                                                                 : (m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE)  ? "for (int i=0; i<8; i++) gl_ClipDistance[i] = float(8 * gl_VertexIndex + i) / 32768.0f;"
1741                                                                                                 : (m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE)  ? "for (int i=0; i<8; i++) gl_CullDistance[i] = float(8 * gl_VertexIndex + i) / 32768.0f;"
1742                                                                                                 : (m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) ? "for (int i=0; i<5; i++) gl_CullDistance[i] = float(6 * gl_VertexIndex + i) / 32768.0f;\n"
1743                                                                                                                                                                                                                    "gl_ClipDistance[0] = float(6 * gl_VertexIndex + 5) / 32768.0f;\n"
1744                                                                                                 : "";
1745
1746                 // Vertex shader
1747                 {
1748                         std::ostringstream src;
1749                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1750                                 << "\n"
1751                                 << "layout(xfb_buffer = " << m_parameters.partCount - 1 << ", xfb_offset = 0) out gl_PerVertex\n"
1752                                 << "{\n"
1753                                 << outputBuiltIn
1754                                 << "};\n"
1755                                 << "\n"
1756                                 << "void main(void)\n"
1757                                 << "{\n"
1758                                 << operationBuiltIn
1759                                 << "}\n";
1760
1761                         programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
1762                 }
1763
1764                 return;
1765         }
1766
1767         if (m_parameters.testType == TEST_TYPE_MULTISTREAMS)
1768         {
1769                 // vertex shader
1770                 {
1771                         std::ostringstream src;
1772                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1773                                 << "\n"
1774                                 << "void main(void)\n"
1775                                 << "{\n"
1776                                 << "}\n";
1777
1778                         programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
1779                 }
1780
1781                 // geometry shader
1782                 {
1783                         const deUint32          s       = m_parameters.streamId;
1784                         std::ostringstream      src;
1785
1786                         DE_ASSERT(s != 0);
1787
1788                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1789                                 << "\n"
1790                                 << "layout(points) in;\n"
1791                                 << "\n"
1792                                 << "layout(points, max_vertices = 32) out;\n"
1793                                 << "layout(stream = " << 0 << ", xfb_buffer = 0, xfb_offset = 0, xfb_stride = 16, location = 0) out vec4 out0;\n"
1794                                 << "layout(stream = " << s << ", xfb_buffer = 1, xfb_offset = 0, xfb_stride = 16, location = 1) out vec4 out1;\n"
1795                                 << "\n"
1796                                 << "const int counts[] = int[](1, 1, 2, 4, 8);\n"
1797                                 << "\n"
1798                                 << "void main(void)\n"
1799                                 << "{\n"
1800                                 << "    int c0 = 0;\n"
1801                                 << "    int c1 = 0;\n"
1802                                 << "\n"
1803                                 << "    // Start 1st buffer from point where 0th buffer ended\n"
1804                                 << "    for (int i = 0; i < counts.length(); i++)\n"
1805                                 << "        c1 = c1 + 4 * counts[i];\n"
1806                                 << "\n"
1807                                 << "    for (int i = 0; i < counts.length(); i++)\n"
1808                                 << "    {\n"
1809                                 << "        const int n0 = counts[i];\n"
1810                                 << "        const int n1 = counts[counts.length() - 1 - i];\n"
1811                                 << "\n"
1812                                 << "        for (int j = 0; j < n0; j++)\n"
1813                                 << "        {\n"
1814                                 << "            out0 = vec4(ivec4(c0, c0 + 1, c0 + 2, c0 + 3));\n"
1815                                 << "            c0 = c0 + 4;\n"
1816                                 << "            EmitStreamVertex(0);\n"
1817                                 << "            EndStreamPrimitive(0);\n"
1818                                 << "        }\n"
1819                                 << "\n"
1820                                 << "        for (int j = 0; j < n1; j++)\n"
1821                                 << "        {\n"
1822                                 << "            out1 = vec4(ivec4(c1, c1 + 1, c1 + 2, c1 + 3));\n"
1823                                 << "            c1 = c1 + 4;\n"
1824                                 << "            EmitStreamVertex(" << s << ");\n"
1825                                 << "            EndStreamPrimitive(" << s << ");\n"
1826                                 << "        }\n"
1827                                 << "    }\n"
1828                                 << "}\n";
1829
1830                         programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
1831                 }
1832
1833                 return;
1834         }
1835
1836         if (requiresFullPipeline)
1837         {
1838                 // vertex shader
1839                 {
1840                         std::ostringstream src;
1841                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1842                                 << "\n"
1843                                 << "void main(void)\n"
1844                                 << "{\n"
1845                                 << "}\n";
1846
1847                         programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
1848                 }
1849
1850                 // geometry shader
1851                 {
1852                         const deUint32          s                                       = m_parameters.streamId;
1853                         const bool                      requirePoints           = (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE || m_parameters.testType == TEST_TYPE_MULTISTREAMS);
1854                         const std::string       outputPrimitiveType     = requirePoints ? "points" : "triangle_strip";
1855                         const std::string       outputBuiltIn           = (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE)    ? "    float gl_PointSize;\n"
1856                                                                                                         : (m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE) ? "    float gl_ClipDistance[];\n"
1857                                                                                                         : (m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE) ? "    float gl_CullDistance[];\n"
1858                                                                                                         : "";
1859                         std::ostringstream      src;
1860
1861                         DE_ASSERT(s != 0);
1862
1863                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1864                                 << "\n"
1865                                 << "layout(points) in;\n"
1866                                 << "layout(" << outputPrimitiveType << ", max_vertices = 16) out;\n"
1867                                 << "layout(stream = " << s << ") out;\n"
1868                                 << "layout(location = 0) out vec4 color;\n"
1869                                 << "\n"
1870                                 << "layout(stream = " << s << ") out gl_PerVertex\n"
1871                                 << "{\n"
1872                                 << "    vec4 gl_Position;\n"
1873                                 << outputBuiltIn
1874                                 << "};\n"
1875                                 << "\n"
1876                                 << "void main(void)\n"
1877                                 << "{\n"
1878                                 << "    // Color constants\n"
1879                                 << "    vec4 g = vec4(0.0, 1.0, 0.0, 1.0);\n"
1880                                 << "    vec4 m = vec4(1.0, 0.0, 1.0, 1.0);\n"
1881                                 << "    // Coordinate constants: leftmost column\n"
1882                                 << "    vec4 a = vec4(-1.0,-1.0, 0.0, 1.0);\n"
1883                                 << "    vec4 b = vec4(-1.0, 0.0, 0.0, 1.0);\n"
1884                                 << "    vec4 c = vec4(-1.0, 1.0, 0.0, 1.0);\n"
1885                                 << "    // Coordinate constants: middle column\n"
1886                                 << "    vec4 i = vec4( 0.0,-1.0, 0.0, 1.0);\n"
1887                                 << "    vec4 j = vec4( 0.0, 0.0, 0.0, 1.0);\n"
1888                                 << "    vec4 k = vec4( 0.0, 1.0, 0.0, 1.0);\n"
1889                                 << "    // Coordinate constants: rightmost column\n"
1890                                 << "    vec4 x = vec4( 1.0,-1.0, 0.0, 1.0);\n"
1891                                 << "    vec4 y = vec4( 1.0, 0.0, 0.0, 1.0);\n"
1892                                 << "    vec4 z = vec4( 1.0, 1.0, 0.0, 1.0);\n"
1893                                 << "\n";
1894
1895                         if (m_parameters.testType == TEST_TYPE_STREAMS)
1896                         {
1897                                 src << "    if (gl_PrimitiveIDIn == 0)\n"
1898                                         << "    {\n"
1899                                         << "        color = m; gl_Position = b; EmitStreamVertex(" << s << ");\n"
1900                                         << "        color = m; gl_Position = y; EmitStreamVertex(" << s << ");\n"
1901                                         << "        color = m; gl_Position = c; EmitStreamVertex(" << s << ");\n"
1902                                         << "        EndStreamPrimitive(" << s << ");\n"
1903                                         << "    }\n"
1904                                         << "    else\n"
1905                                         << "    {\n"
1906                                         << "        color = m; gl_Position = y; EmitStreamVertex(" << s << ");\n"
1907                                         << "        color = m; gl_Position = c; EmitStreamVertex(" << s << ");\n"
1908                                         << "        color = m; gl_Position = z; EmitStreamVertex(" << s << ");\n"
1909                                         << "        EndStreamPrimitive(" << s << ");\n"
1910                                         << "    }\n";
1911                         }
1912
1913                         if (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE)
1914                         {
1915                                 const std::string       pointSize       = "gl_PointSize = " + de::toString(m_parameters.pointSize) + ".0f";
1916
1917                                 src << "    if (gl_PrimitiveIDIn == 0)\n"
1918                                         << "    {\n"
1919                                         << "        color = g; gl_Position = (a + j) / 2.0f; gl_PointSize = 1.0f; EmitStreamVertex(0);\n"
1920                                         << "        EndStreamPrimitive(0);\n"
1921                                         << "        color = m; gl_Position = (b + k) / 2.0f; gl_PointSize = 1.0f; EmitStreamVertex(" << s << ");\n"
1922                                         << "        EndStreamPrimitive(" << s << ");\n"
1923                                         << "    }\n"
1924                                         << "    else\n"
1925                                         << "    {\n"
1926                                         << "        color = g; gl_Position = (j + x) / 2.0f; " << pointSize << "; EmitStreamVertex(0);\n"
1927                                         << "        EndStreamPrimitive(0);\n"
1928                                         << "        color = m; gl_Position = (k + y) / 2.0f; " << pointSize << "; EmitStreamVertex(" << s << ");\n"
1929                                         << "        EndStreamPrimitive(" << s << ");\n"
1930                                         << "    }\n";
1931                         }
1932
1933                         if (m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE)
1934                         {
1935                                 src << "    if (gl_PrimitiveIDIn == 0)\n"
1936                                         << "    {\n"
1937                                         << "        color = m; gl_Position = b; gl_ClipDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1938                                         << "        color = m; gl_Position = c; gl_ClipDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1939                                         << "        color = m; gl_Position = y; gl_ClipDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
1940                                         << "        EndStreamPrimitive(" << s << ");\n"
1941                                         << "    }\n"
1942                                         << "    else\n"
1943                                         << "    {\n"
1944                                         << "        color = m; gl_Position = y; gl_ClipDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
1945                                         << "        color = m; gl_Position = c; gl_ClipDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1946                                         << "        color = m; gl_Position = z; gl_ClipDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
1947                                         << "        EndStreamPrimitive(" << s << ");\n"
1948                                         << "    }\n";
1949                         }
1950
1951                         if (m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE)
1952                         {
1953                                 src << "    if (gl_PrimitiveIDIn == 0)\n"
1954                                         << "    {\n"
1955                                         << "        color = m; gl_Position = b; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1956                                         << "        color = m; gl_Position = c; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1957                                         << "        color = m; gl_Position = j; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1958                                         << "        EndStreamPrimitive(" << s << ");\n"
1959                                         << "        color = m; gl_Position = j; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1960                                         << "        color = m; gl_Position = c; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1961                                         << "        color = m; gl_Position = k; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
1962                                         << "        EndStreamPrimitive(" << s << ");\n"
1963                                         << "    }\n"
1964                                         << "    else\n"
1965                                         << "    {\n"
1966                                         << "        color = m; gl_Position = j; gl_CullDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
1967                                         << "        color = m; gl_Position = k; gl_CullDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
1968                                         << "        color = m; gl_Position = y; gl_CullDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
1969                                         << "        EndStreamPrimitive(" << s << ");\n"
1970                                         << "        color = m; gl_Position = y; gl_CullDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
1971                                         << "        color = m; gl_Position = k; gl_CullDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
1972                                         << "        color = m; gl_Position = z; gl_CullDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
1973                                         << "        EndStreamPrimitive(" << s << ");\n"
1974                                         << "    }\n";
1975                         }
1976
1977                         src << "}\n";
1978
1979                         programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
1980                 }
1981
1982                 // Fragment shader
1983                 {
1984                         std::ostringstream src;
1985                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1986                                 << "\n"
1987                                 << "layout(location = 0) in  vec4 i_color;\n"
1988                                 << "layout(location = 0) out vec4 o_color;\n"
1989                                 << "\n"
1990                                 << "void main(void)\n"
1991                                 << "{\n"
1992                                 << "    o_color = i_color;\n"
1993                                 << "}\n";
1994
1995                         programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
1996                 }
1997
1998                 return;
1999         }
2000
2001         if (m_parameters.testType == TEST_TYPE_DRAW_INDIRECT)
2002         {
2003                 // vertex shader
2004                 {
2005                         std::ostringstream src;
2006                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
2007                                 << "\n"
2008                                 << "layout(location = 0) in vec4 in_position;\n"
2009                                 << "\n"
2010                                 << "void main(void)\n"
2011                                 << "{\n"
2012                                 << "    gl_Position = in_position;\n"
2013                                 << "}\n";
2014
2015                         programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
2016                 }
2017
2018                 // Fragment shader
2019                 {
2020                         std::ostringstream src;
2021                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
2022                                 << "\n"
2023                                 << "layout(location = 0) out vec4 o_color;\n"
2024                                 << "\n"
2025                                 << "void main(void)\n"
2026                                 << "{\n"
2027                                 << "    o_color = vec4(1.0, 1.0, 1.0, 1.0);\n"
2028                                 << "}\n";
2029
2030                         programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
2031                 }
2032
2033                 return;
2034         }
2035
2036         if (m_parameters.testType == TEST_TYPE_QUERY || m_parameters.testType == TEST_TYPE_QUERY_RESET)
2037         {
2038                 // Vertex shader
2039                 {
2040                         std::ostringstream src;
2041                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
2042                                 << "\n"
2043                                 << "layout(location = 0) out vec4 out0;\n"
2044                                 << "\n"
2045                                 << "void main(void)\n"
2046                                 << "{\n"
2047                                 << "    float n = 4.0 * float(gl_VertexIndex);\n"
2048                                 << "    out0 = vec4(n + 0.0, n + 1.0, n + 2.0, n + 3.0);\n"
2049                                 << "}\n";
2050
2051                         programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
2052                 }
2053
2054                 // geometry shader
2055                 {
2056                         const deUint32          s       = m_parameters.streamId;
2057                         std::ostringstream      src;
2058
2059                         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
2060                                 << "\n"
2061                                 << "layout(points) in;\n"
2062                                 << "layout(location = 0) in vec4 in0[];\n"
2063                                 << "\n"
2064                                 << "layout(points, max_vertices = 1) out;\n"
2065                                 << "layout(stream = " << s << ", xfb_buffer = 0, xfb_offset = 0, xfb_stride = 16, location = 0) out vec4 out0;\n"
2066                                 << "\n"
2067                                 << "void main(void)\n"
2068                                 << "{\n"
2069                                 << "    out0 = in0[0];\n"
2070                                 << "    EmitStreamVertex(" << s << ");\n"
2071                                 << "    EndStreamPrimitive(" << s << ");\n"
2072                                 << "}\n";
2073
2074                         programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
2075                 }
2076
2077                 return;
2078         }
2079
2080         DE_ASSERT(0 && "Unknown test");
2081 }
2082
2083 void createTransformFeedbackSimpleTests (tcu::TestCaseGroup* group)
2084 {
2085         {
2086                 const deUint32          bufferCounts[]  = { 1, 2, 4, 8 };
2087                 const deUint32          bufferSizes[]   = { 256, 512, 128*1024 };
2088                 const TestType          testTypes[]             = { TEST_TYPE_BASIC, TEST_TYPE_RESUME, TEST_TYPE_XFB_POINTSIZE, TEST_TYPE_XFB_CLIPDISTANCE, TEST_TYPE_XFB_CULLDISTANCE, TEST_TYPE_XFB_CLIP_AND_CULL };
2089                 const std::string       testTypeNames[] = { "basic",         "resume",         "xfb_pointsize",         "xfb_clipdistance",         "xfb_culldistance",         "xfb_clip_and_cull"         };
2090
2091                 for (deUint32 testTypesNdx = 0; testTypesNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypesNdx)
2092                 {
2093                         const TestType          testType        = testTypes[testTypesNdx];
2094                         const std::string       testName        = testTypeNames[testTypesNdx];
2095
2096                         for (deUint32 bufferCountsNdx = 0; bufferCountsNdx < DE_LENGTH_OF_ARRAY(bufferCounts); ++bufferCountsNdx)
2097                         {
2098                                 const deUint32  partCount       = bufferCounts[bufferCountsNdx];
2099
2100                                 for (deUint32 bufferSizesNdx = 0; bufferSizesNdx < DE_LENGTH_OF_ARRAY(bufferSizes); ++bufferSizesNdx)
2101                                 {
2102                                         const deUint32                  bufferSize      = bufferSizes[bufferSizesNdx];
2103                                         const TestParameters    parameters      = { testType, bufferSize, partCount, 0u, 0u, 0u };
2104
2105                                         group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(partCount) + "_" + de::toString(bufferSize)).c_str(), "Simple Transform Feedback test", parameters));
2106                                 }
2107                         }
2108                 }
2109         }
2110
2111         {
2112                 const deUint32          bufferCounts[]  = { 6, 8, 10, 12 };
2113                 const TestType          testTypes[]             = { TEST_TYPE_TRIANGLE_STRIP_ADJACENCY };
2114                 const std::string       testTypeNames[] = { "triangle_strip_with_adjacency"};
2115
2116                 for (deUint32 testTypesNdx = 0; testTypesNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypesNdx)
2117                 {
2118                         const TestType          testType        = testTypes[testTypesNdx];
2119                         const std::string       testName        = testTypeNames[testTypesNdx];
2120
2121                         for (deUint32 bufferCountsNdx = 0; bufferCountsNdx < DE_LENGTH_OF_ARRAY(bufferCounts); ++bufferCountsNdx)
2122                         {
2123                                 const deUint32                  vertexCount     = bufferCounts[bufferCountsNdx];
2124                                 const TestParameters    parameters      = { testType, 0u, vertexCount, 0u, 0u, 0u };
2125
2126                                 group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(vertexCount)).c_str(), "Triangle Strip With Adjacency Transform Feedback test", parameters));
2127                         }
2128                 }
2129         }
2130
2131         {
2132                 const deUint32          vertexStrides[] = { 4, 61, 127, 251, 509 };
2133                 const TestType          testType                = TEST_TYPE_DRAW_INDIRECT;
2134                 const std::string       testName                = "draw_indirect";
2135
2136                 for (deUint32 vertexStridesNdx = 0; vertexStridesNdx < DE_LENGTH_OF_ARRAY(vertexStrides); ++vertexStridesNdx)
2137                 {
2138                         const deUint32                  vertexStride    = static_cast<deUint32>(sizeof(deUint32) * vertexStrides[vertexStridesNdx]);
2139                         const TestParameters    parameters              = { testType, 0u, 0u, 0u, 0u, vertexStride };
2140
2141                         group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(vertexStride)).c_str(), "Rendering tests with various strides", parameters));
2142                 }
2143         }
2144
2145         {
2146                 const TestType                  testType        = TEST_TYPE_BACKWARD_DEPENDENCY;
2147                 const std::string               testName        = "backward_dependency";
2148                 const TestParameters    parameters      = { testType, 512u, 2u, 0u, 0u, 0u };
2149
2150                 group->addChild(new TransformFeedbackTestCase(group->getTestContext(), testName.c_str(), "Rendering test checks backward pipeline dependency", parameters));
2151         }
2152
2153         {
2154                 const deUint32          usedStreamId[]                  = { 0, 1, 3, 6, 14 };
2155                 const deUint32          vertexCount[]                   = { 4, 61, 127, 251, 509 };
2156                 const TestType          testType                                = TEST_TYPE_QUERY;
2157                 const std::string       testName                                = "query";
2158                 const TestType          testTypeHostQueryReset  = TEST_TYPE_QUERY_RESET;
2159                 const std::string       testNameHostQueryReset  = "host_query_reset";
2160
2161                 for (deUint32 streamCountsNdx = 0; streamCountsNdx < DE_LENGTH_OF_ARRAY(usedStreamId); ++streamCountsNdx)
2162                 {
2163                         const deUint32  streamId        = usedStreamId[streamCountsNdx];
2164
2165                         for (deUint32 vertexCountNdx = 0; vertexCountNdx < DE_LENGTH_OF_ARRAY(vertexCount); ++vertexCountNdx)
2166                         {
2167                                 const deUint32                  bytesPerVertex  = static_cast<deUint32>(4 * sizeof(float));
2168                                 const deUint32                  bufferSize              = bytesPerVertex * vertexCount[vertexCountNdx];
2169                                 const TestParameters    parameters              = { testType, bufferSize, 0u, streamId, 0u, 0u };
2170                                 const std::string               fullTestName    = testName + "_" + de::toString(streamId) + "_" + de::toString(vertexCount[vertexCountNdx]);
2171
2172                                 group->addChild(new TransformFeedbackTestCase(group->getTestContext(), fullTestName.c_str(), "Written primitives query test", parameters));
2173
2174                                 const std::string               fullTestNameHostQueryReset      = testNameHostQueryReset + "_" + de::toString(streamId) + "_" + de::toString(vertexCount[vertexCountNdx]);
2175                                 const TestParameters    parametersHostQueryReset        = { testTypeHostQueryReset, bufferSize, 0u, streamId, 0u, 0u };
2176                                 group->addChild(new TransformFeedbackTestCase(group->getTestContext(), fullTestNameHostQueryReset.c_str(), "Written primitives query test", parametersHostQueryReset));
2177                         }
2178                 }
2179         }
2180 }
2181
2182 void createTransformFeedbackStreamsSimpleTests (tcu::TestCaseGroup* group)
2183 {
2184         const deUint32          usedStreamId[]  = { 1, 3, 6, 14 };
2185         const TestType          testTypes[]             = { TEST_TYPE_STREAMS, TEST_TYPE_STREAMS_POINTSIZE, TEST_TYPE_STREAMS_CLIPDISTANCE, TEST_TYPE_STREAMS_CULLDISTANCE };
2186         const std::string       testTypeNames[] = { "streams",         "streams_pointsize",         "streams_clipdistance",         "streams_culldistance"         };
2187
2188         for (deUint32 testTypesNdx = 0; testTypesNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypesNdx)
2189         {
2190                 const TestType          testType        = testTypes[testTypesNdx];
2191                 const std::string       testName        = testTypeNames[testTypesNdx];
2192                 const deUint32          pointSize       = (testType == TEST_TYPE_STREAMS_POINTSIZE) ? 2u : 0u;
2193
2194                 for (deUint32 streamCountsNdx = 0; streamCountsNdx < DE_LENGTH_OF_ARRAY(usedStreamId); ++streamCountsNdx)
2195                 {
2196                         const deUint32                  streamId        = usedStreamId[streamCountsNdx];
2197                         const TestParameters    parameters      = { testType, 0u, 0u, streamId, pointSize, 0u };
2198
2199                         group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(streamId)).c_str(), "Streams usage test", parameters));
2200                 }
2201         }
2202
2203         {
2204                 const TestType          testType        = TEST_TYPE_MULTISTREAMS;
2205                 const std::string       testName        = "multistreams";
2206
2207                 for (deUint32 bufferCountsNdx = 0; bufferCountsNdx < DE_LENGTH_OF_ARRAY(usedStreamId); ++bufferCountsNdx)
2208                 {
2209                         const deUint32                  streamId                        = usedStreamId[bufferCountsNdx];
2210                         const deUint32                  streamsUsed                     = 2u;
2211                         const deUint32                  maxBytesPerVertex       = 256u;
2212                         const TestParameters    parameters                      = { testType, maxBytesPerVertex * streamsUsed, streamsUsed, streamId, 0u, 0u };
2213
2214                         group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(streamId)).c_str(), "Simultaneous multiple streams usage test", parameters));
2215                 }
2216         }
2217 }
2218
2219 void createTransformFeedbackAndStreamsSimpleTests (tcu::TestCaseGroup* group)
2220 {
2221         createTransformFeedbackSimpleTests(group);
2222         createTransformFeedbackStreamsSimpleTests(group);
2223 }
2224 } // anonymous
2225
2226 tcu::TestCaseGroup* createTransformFeedbackSimpleTests (tcu::TestContext& testCtx)
2227 {
2228         return createTestGroup(testCtx, "simple", "Transform Feedback Simple tests", createTransformFeedbackAndStreamsSimpleTests);
2229 }
2230
2231 } // TransformFeedback
2232 } // vkt