Remove unused function from es31fSRGBDecodeTests.cpp am: 1ee59ff986 am: 2e80d40a0b...
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / geometry / vktGeometryBasicGeometryShaderTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 The Android Open Source Project
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Basic Geometry Shader Tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktGeometryBasicGeometryShaderTests.hpp"
26 #include "vktGeometryBasicClass.hpp"
27 #include "vktGeometryTestsUtil.hpp"
28
29 #include "gluTextureUtil.hpp"
30 #include "glwEnums.hpp"
31 #include "vkDefs.hpp"
32 #include "vktTestCase.hpp"
33 #include "vktTestCaseUtil.hpp"
34 #include "vkImageUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkPrograms.hpp"
37 #include "vkBuilderUtil.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkQueryUtil.hpp"
40 #include "vkMemUtil.hpp"
41 #include "tcuTextureUtil.hpp"
42
43 #include <string>
44
45 using namespace vk;
46
47 namespace vkt
48 {
49 namespace geometry
50 {
51 namespace
52 {
53 using tcu::TestStatus;
54 using tcu::TestContext;
55 using tcu::TestCaseGroup;
56 using de::MovePtr;
57 using std::string;
58 using std::vector;
59
60 enum VaryingSource
61 {
62         READ_ATTRIBUTE = 0,
63         READ_UNIFORM,
64         READ_TEXTURE,
65
66         READ_LAST
67 };
68 enum ShaderInstancingMode
69 {
70         MODE_WITHOUT_INSTANCING = 0,
71         MODE_WITH_INSTANCING,
72
73         MODE_LAST
74 };
75 enum
76 {
77         EMIT_COUNT_VERTEX_0 = 6,
78         EMIT_COUNT_VERTEX_1 = 0,
79         EMIT_COUNT_VERTEX_2 = -1,
80         EMIT_COUNT_VERTEX_3 = 10,
81 };
82 enum VariableTest
83 {
84         TEST_POINT_SIZE = 0,
85         TEST_PRIMITIVE_ID_IN,
86         TEST_PRIMITIVE_ID,
87         TEST_LAST
88 };
89
90 void uploadImage (Context&                                                              context,
91                                   const tcu::ConstPixelBufferAccess&    access,
92                                   VkImage                                                               destImage)
93 {
94         const DeviceInterface&                  vk                                      = context.getDeviceInterface();
95         const VkDevice                                  device                          = context.getDevice();
96         const deUint32                                  queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
97         const VkQueue                                   queue                           = context.getUniversalQueue();
98         Allocator&                                              memAlloc                        = context.getDefaultAllocator();
99         const VkImageAspectFlags                aspectMask                      = VK_IMAGE_ASPECT_COLOR_BIT;
100         const deUint32                                  bufferSize                      = access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
101         Move<VkBuffer>                                  buffer;
102         de::MovePtr<Allocation>                 bufferAlloc;
103         Move<VkCommandPool>                             cmdPool;
104         Move<VkCommandBuffer>                   cmdBuffer;
105         Move<VkFence>                                   fence;
106
107         // Create source buffer
108         {
109                 const VkBufferCreateInfo bufferParams =
110                 {
111                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
112                         DE_NULL,                                                                        // const void*                  pNext;
113                         0u,                                                                                     // VkBufferCreateFlags  flags;
114                         bufferSize,                                                                     // VkDeviceSize                 size;
115                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
116                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
117                         0u,                                                                                     // deUint32                             queueFamilyIndexCount;
118                         DE_NULL,                                                                        // const deUint32*              pQueueFamilyIndices;
119                 };
120                 buffer          = createBuffer(vk, device, &bufferParams);
121                 bufferAlloc     = memAlloc.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
122                 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
123         }
124
125         // Create command pool and buffer
126         {
127                 cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
128
129                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
130                 {
131                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
132                         DE_NULL,                                                                                // const void*                          pNext;
133                         *cmdPool,                                                                               // VkCommandPool                        commandPool;
134                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
135                         1u,                                                                                             // deUint32                                     bufferCount;
136                 };
137                 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
138         }
139
140         // Create fence
141         fence = createFence(vk, device);
142
143         // Barriers for copying buffer to image
144         const VkBufferMemoryBarrier preBufferBarrier =
145         {
146                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
147                 DE_NULL,                                                                        // const void*          pNext;
148                 VK_ACCESS_HOST_WRITE_BIT,                                       // VkAccessFlags        srcAccessMask;
149                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags        dstAccessMask;
150                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
151                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
152                 *buffer,                                                                        // VkBuffer                     buffer;
153                 0u,                                                                                     // VkDeviceSize         offset;
154                 bufferSize                                                                      // VkDeviceSize         size;
155         };
156
157         const VkImageMemoryBarrier preImageBarrier =
158         {
159                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
160                 DE_NULL,                                                                        // const void*                          pNext;
161                 0u,                                                                                     // VkAccessFlags                        srcAccessMask;
162                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
163                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
164                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
165                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
166                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
167                 destImage,                                                                      // VkImage                                      image;
168                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
169                         aspectMask,                                                             // VkImageAspect        aspect;
170                         0u,                                                                             // deUint32                     baseMipLevel;
171                         1u,                                                                             // deUint32                     mipLevels;
172                         0u,                                                                             // deUint32                     baseArraySlice;
173                         1u                                                                              // deUint32                     arraySize;
174                 }
175         };
176
177         const VkImageMemoryBarrier postImageBarrier =
178         {
179                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
180                 DE_NULL,                                                                        // const void*                          pNext;
181                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
182                 VK_ACCESS_SHADER_READ_BIT,                                      // VkAccessFlags                        dstAccessMask;
183                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
184                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,       // VkImageLayout                        newLayout;
185                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
186                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
187                 destImage,                                                                      // VkImage                                      image;
188                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
189                         aspectMask,                                                             // VkImageAspect        aspect;
190                         0u,                                                                             // deUint32                     baseMipLevel;
191                         1u,                                                                             // deUint32                     mipLevels;
192                         0u,                                                                             // deUint32                     baseArraySlice;
193                         1u                                                                              // deUint32                     arraySize;
194                 }
195         };
196
197         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
198         {
199                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
200                 DE_NULL,                                                                                // const void*                                          pNext;
201                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags;
202                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
203         };
204
205         // Get copy regions and write buffer data
206         const VkBufferImageCopy                 copyRegions     =
207         {
208                 0u,                                                             // VkDeviceSize                         bufferOffset;
209                 (deUint32)access.getWidth(),    // deUint32                                     bufferRowLength;
210                 (deUint32)access.getHeight(),   // deUint32                                     bufferImageHeight;
211                 {                                                               // VkImageSubresourceLayers     imageSubresource;
212                                 aspectMask,                             // VkImageAspectFlags           aspectMask;
213                                 (deUint32)0u,                   // uint32_t                                     mipLevel;
214                                 (deUint32)0u,                   // uint32_t                                     baseArrayLayer;
215                                 1u                                              // uint32_t                                     layerCount;
216                 },
217                 { 0u, 0u, 0u },                                 // VkOffset3D                   imageOffset;
218                 {                                                               // VkExtent3D                   imageExtent;
219                         (deUint32)access.getWidth(),
220                         (deUint32)access.getHeight(),
221                         (deUint32)access.getDepth()
222                 }
223         };
224
225         {
226                 const tcu::PixelBufferAccess    destAccess      (access.getFormat(), access.getSize(), bufferAlloc->getHostPtr());
227                 tcu::copy(destAccess, access);
228                 flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
229         }
230
231         // Copy buffer to image
232         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
233         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
234         vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegions);
235         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
236         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
237
238         const VkSubmitInfo submitInfo =
239         {
240                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                              sType;
241                 DE_NULL,                                                // const void*                                  pNext;
242                 0u,                                                             // deUint32                                             waitSemaphoreCount;
243                 DE_NULL,                                                // const VkSemaphore*                   pWaitSemaphores;
244                 DE_NULL,                                                // const VkPipelineStageFlags*  pWaitDstStageMask;
245                 1u,                                                             // deUint32                                             commandBufferCount;
246                 &cmdBuffer.get(),                               // const VkCommandBuffer*               pCommandBuffers;
247                 0u,                                                             // deUint32                                             signalSemaphoreCount;
248                 DE_NULL                                                 // const VkSemaphore*                   pSignalSemaphores;
249         };
250
251         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
252         VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
253 }
254
255 class GeometryOutputCountTestInstance : public GeometryExpanderRenderTestInstance
256 {
257 public:
258                                                                 GeometryOutputCountTestInstance (Context&                                       context,
259                                                                                                                                  const VkPrimitiveTopology      primitiveType,
260                                                                                                                                  const int                                      primitiveCount,
261                                                                                                                                  const char*                            name);
262         void                                            genVertexAttribData                             (void);
263 private:
264         const int                                       m_primitiveCount;
265 };
266
267 GeometryOutputCountTestInstance::GeometryOutputCountTestInstance (Context&                                      context,
268                                                                                                                                   const VkPrimitiveTopology     primitiveType,
269                                                                                                                                   const int                                     primitiveCount,
270                                                                                                                                   const char*                           name)
271         : GeometryExpanderRenderTestInstance    (context, primitiveType, name)
272         , m_primitiveCount                                              (primitiveCount)
273
274 {
275         genVertexAttribData();
276 }
277
278 void GeometryOutputCountTestInstance::genVertexAttribData (void)
279 {
280         m_vertexPosData.resize(m_primitiveCount);
281         m_vertexAttrData.resize(m_primitiveCount);
282
283         for (int ndx = 0; ndx < m_primitiveCount; ++ndx)
284         {
285                 m_vertexPosData[ndx] = tcu::Vec4(-1.0f, ((float)ndx) / (float)m_primitiveCount * 2.0f - 1.0f, 0.0f, 1.0f);
286                 m_vertexAttrData[ndx] = (ndx % 2 == 0) ? tcu::Vec4(1, 1, 1, 1) : tcu::Vec4(1, 0, 0, 1);
287         }
288         m_numDrawVertices = m_primitiveCount;
289 }
290
291 class VaryingOutputCountTestInstance : public GeometryExpanderRenderTestInstance
292 {
293 public:
294                                                                 VaryingOutputCountTestInstance  (Context&                                       context,
295                                                                                                                                  const char*                            name,
296                                                                                                                                  const VkPrimitiveTopology      primitiveType,
297                                                                                                                                  const VaryingSource            test,
298                                                                                                                                  const ShaderInstancingMode     mode);
299         void                                            genVertexAttribData                             (void);
300 protected:
301         Move<VkPipelineLayout>          createPipelineLayout                    (const DeviceInterface& vk, const VkDevice device);
302         void                                            bindDescriptorSets                              (const DeviceInterface&         vk,
303                                                                                                                                  const VkDevice                         device,
304                                                                                                                                  Allocator&                                     memAlloc,
305                                                                                                                                  const VkCommandBuffer&         cmdBuffer,
306                                                                                                                                  const VkPipelineLayout&        pipelineLayout);
307 private:
308         void                                            genVertexDataWithoutInstancing  (void);
309         void                                            genVertexDataWithInstancing             (void);
310
311         const VaryingSource                     m_test;
312         const ShaderInstancingMode      m_mode;
313         const deInt32                           m_maxEmitCount;
314         Move<VkDescriptorPool>          m_descriptorPool;
315         Move<VkDescriptorSetLayout>     m_descriptorSetLayout;
316         Move<VkDescriptorSet>           m_descriptorSet;
317         Move<VkBuffer>                          m_buffer;
318         Move<VkImage>                           m_texture;
319         Move<VkImageView>                       m_imageView;
320         Move<VkSampler>                         m_sampler;
321         de::MovePtr<Allocation>         m_allocation;
322 };
323
324 VaryingOutputCountTestInstance::VaryingOutputCountTestInstance (Context&                                        context,
325                                                                                                                                 const char*                                     name,
326                                                                                                                                 const VkPrimitiveTopology       primitiveType,
327                                                                                                                                 const VaryingSource                     test,
328                                                                                                                                 const ShaderInstancingMode      mode)
329         : GeometryExpanderRenderTestInstance    (context, primitiveType, name)
330         , m_test                                                                (test)
331         , m_mode                                                                (mode)
332         , m_maxEmitCount                                                (128)
333 {
334         genVertexAttribData ();
335 }
336
337 void VaryingOutputCountTestInstance::genVertexAttribData (void)
338 {
339         if (m_mode == MODE_WITHOUT_INSTANCING)
340                 genVertexDataWithoutInstancing();
341         else if (m_mode == MODE_WITH_INSTANCING)
342                 genVertexDataWithInstancing();
343         else
344                 DE_ASSERT(false);
345 }
346
347 Move<VkPipelineLayout> VaryingOutputCountTestInstance::createPipelineLayout (const DeviceInterface& vk, const VkDevice device)
348 {
349         if (m_test == READ_UNIFORM)
350         {
351                 m_descriptorSetLayout   =       DescriptorSetLayoutBuilder()
352                                                                         .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_GEOMETRY_BIT)
353                                                                         .build(vk, device);
354                 m_descriptorPool                =       DescriptorPoolBuilder()
355                                                                         .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
356                                                                         .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
357                 m_descriptorSet                 =       makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
358
359                 return makePipelineLayout(vk, device, *m_descriptorSetLayout);
360         }
361         else if (m_test == READ_TEXTURE)
362         {
363                 const tcu::Vec4                         data[4]                         =
364                                                                                                                 {
365                                                                                                                         tcu::Vec4(255, 0, 0, 0),
366                                                                                                                         tcu::Vec4(0, 255, 0, 0),
367                                                                                                                         tcu::Vec4(0, 0, 255, 0),
368                                                                                                                         tcu::Vec4(0, 0, 0, 255)
369                                                                                                                 };
370                 const tcu::UVec2                        viewportSize            (4, 1);
371                 const tcu::TextureFormat        texFormat                       = glu::mapGLInternalFormat(GL_RGBA8);
372                 const VkFormat                          format                          = mapTextureFormat(texFormat);
373                 const VkImageUsageFlags         imageUsageFlags         = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
374                 Allocator&                                      memAlloc                        = m_context.getDefaultAllocator();
375                 tcu::TextureLevel                       texture                         (texFormat, static_cast<int>(viewportSize.x()), static_cast<int>(viewportSize.y()));
376
377                 // Fill with data
378                 {
379                         tcu::PixelBufferAccess access = texture.getAccess();
380                         for (int x = 0; x < texture.getWidth(); ++x)
381                                 access.setPixel(data[x], x, 0);
382                 }
383                 // Create image
384                 const VkImageCreateInfo                 imageParams =
385                 {
386                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType                      sType;
387                         DE_NULL,                                                                // const void*                          pNext;
388                         0,                                                                              // VkImageCreateFlags           flags;
389                         VK_IMAGE_TYPE_2D,                                               // VkImageType                          imageType;
390                         format,                                                                 // VkFormat                                     format;
391                         {                                                                               // VkExtent3D                           extent;
392                                         viewportSize.x(),
393                                         viewportSize.y(),
394                                         1u,
395                         },
396                         1u,                                                     // deUint32                                     mipLevels;
397                         1u,                                                     // deUint32                                     arrayLayers;
398                         VK_SAMPLE_COUNT_1_BIT,          // VkSampleCountFlagBits        samples;
399                         VK_IMAGE_TILING_OPTIMAL,        // VkImageTiling                        tiling;
400                         imageUsageFlags,                        // VkImageUsageFlags            usage;
401                         VK_SHARING_MODE_EXCLUSIVE,      // VkSharingMode                        sharingMode;
402                         0u,                                                     // deUint32                                     queueFamilyIndexCount;
403                         DE_NULL,                                        // const deUint32*                      pQueueFamilyIndices;
404                         VK_IMAGE_LAYOUT_UNDEFINED       // VkImageLayout                        initialLayout;
405                 };
406
407                 m_texture               = createImage(vk, device, &imageParams);
408                 m_allocation    = memAlloc.allocate(getImageMemoryRequirements(vk, device, *m_texture), MemoryRequirement::Any);
409                 VK_CHECK(vk.bindImageMemory(device, *m_texture, m_allocation->getMemory(), m_allocation->getOffset()));
410                 uploadImage(m_context, texture.getAccess(), *m_texture);
411
412                 m_descriptorSetLayout   =       DescriptorSetLayoutBuilder()
413                                                                         .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_GEOMETRY_BIT)
414                                                                         .build(vk, device);
415                 m_descriptorPool                =       DescriptorPoolBuilder()
416                                                                         .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
417                                                                         .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
418                 m_descriptorSet                 =       makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
419
420                 return makePipelineLayout(vk, device, *m_descriptorSetLayout);
421         }
422         else
423                 return makePipelineLayout(vk, device);
424 }
425
426 void VaryingOutputCountTestInstance::bindDescriptorSets (const DeviceInterface& vk, const VkDevice device, Allocator& memAlloc,
427                                                                                                                  const VkCommandBuffer& cmdBuffer, const VkPipelineLayout& pipelineLayout)
428 {
429         if (m_test == READ_UNIFORM)
430         {
431                 const deInt32                           emitCount[4]            = { 6, 0, m_maxEmitCount, 10 };
432                 const VkBufferCreateInfo        bufferCreateInfo        = makeBufferCreateInfo(sizeof(emitCount), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
433                 m_buffer                                                                                = createBuffer(vk, device, &bufferCreateInfo);
434                 m_allocation                                                                    = memAlloc.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), MemoryRequirement::HostVisible);
435
436                 VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset()));
437                 {
438                         deMemcpy(m_allocation->getHostPtr(), &emitCount[0], sizeof(emitCount));
439                         flushMappedMemoryRange(vk, device, m_allocation->getMemory(), m_allocation->getOffset(), sizeof(emitCount));
440
441                         const VkDescriptorBufferInfo bufferDescriptorInfo = makeDescriptorBufferInfo(*m_buffer, 0ull, sizeof(emitCount));
442
443                         DescriptorSetUpdateBuilder()
444                                 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferDescriptorInfo)
445                                 .update(vk, device);
446                         vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0u, 1u, &*m_descriptorSet, 0u, DE_NULL);
447                 }
448         }
449         else if (m_test == READ_TEXTURE)
450         {
451                 const tcu::TextureFormat        texFormat                       = glu::mapGLInternalFormat(GL_RGBA8);
452                 const VkFormat                          format                          = mapTextureFormat(texFormat);
453                 const VkSamplerCreateInfo       samplerParams           =
454                                                                                                                 {
455                                                                                                                         VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,          // VkStructureType                      sType;
456                                                                                                                         DE_NULL,                                                                        // const void*                          pNext;
457                                                                                                                         0u,                                                                                     // VkSamplerCreateFlags         flags;
458                                                                                                                         VK_FILTER_NEAREST,                                                      // VkFilter                                     magFilter;
459                                                                                                                         VK_FILTER_NEAREST,                                                      // VkFilter                                     minFilter;
460                                                                                                                         VK_SAMPLER_MIPMAP_MODE_NEAREST,                         // VkSamplerMipmapMode          mipmapMode;
461                                                                                                                         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          // VkSamplerAddressMode         addressModeU;
462                                                                                                                         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          // VkSamplerAddressMode         addressModeV;
463                                                                                                                         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,          // VkSamplerAddressMode         addressModeW;
464                                                                                                                         0.0f,                                                                           // float                                        mipLodBias;
465                                                                                                                         VK_FALSE,                                                                       // VkBool32                                     anisotropyEnable;
466                                                                                                                         1.0f,                                                                           // float                                        maxAnisotropy;
467                                                                                                                         false,                                                                          // VkBool32                                     compareEnable;
468                                                                                                                         VK_COMPARE_OP_NEVER,                                            // VkCompareOp                          compareOp;
469                                                                                                                         0.0f,                                                                           // float                                        minLod;
470                                                                                                                         0.0f,                                                                           // float                                        maxLod;
471                                                                                                                         VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,        // VkBorderColor                        borderColor;
472                                                                                                                         false                                                                           // VkBool32                                     unnormalizedCoordinates;
473                                                                                                                 };
474                 m_sampler                                                                               = createSampler(vk, device, &samplerParams);
475                 const VkImageViewCreateInfo     viewParams                      =
476                                                                                                                 {
477                                                                                                                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                      sType;
478                                                                                                                         NULL,                                                                           // const voide*                         pNext;
479                                                                                                                         0u,                                                                                     // VkImageViewCreateFlags       flags;
480                                                                                                                         *m_texture,                                                                     // VkImage                                      image;
481                                                                                                                         VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType                      viewType;
482                                                                                                                         format,                                                                         // VkFormat                                     format;
483                                                                                                                         makeComponentMappingRGBA(),                                     // VkChannelMapping                     channels;
484                                                                                                                         {
485                                                                                                                                 VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask;
486                                                                                                                                 0u,                                                                             // deUint32                             baseMipLevel;
487                                                                                                                                 1u,                                                                             // deUint32                             mipLevels;
488                                                                                                                                 0,                                                                              // deUint32                             baseArraySlice;
489                                                                                                                                 1u                                                                              // deUint32                             arraySize;
490                                                                                                                         },                                                                                      // VkImageSubresourceRange      subresourceRange;
491                                                                                                                 };
492                 m_imageView                                                                             = createImageView(vk, device, &viewParams);
493                 const VkDescriptorImageInfo descriptorImageInfo = makeDescriptorImageInfo (*m_sampler, *m_imageView, VK_IMAGE_LAYOUT_GENERAL);
494                 DescriptorSetUpdateBuilder()
495                         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfo)
496                         .update(vk, device);
497                 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0u, 1u, &*m_descriptorSet, 0u, DE_NULL);
498         }
499 }
500
501 void VaryingOutputCountTestInstance::genVertexDataWithoutInstancing (void)
502 {
503         m_numDrawVertices = 4;
504         m_vertexPosData.resize(m_numDrawVertices);
505         m_vertexAttrData.resize(m_numDrawVertices);
506
507         m_vertexPosData[0] = tcu::Vec4( 0.5f,  0.0f, 0.0f, 1.0f);
508         m_vertexPosData[1] = tcu::Vec4( 0.0f,  0.5f, 0.0f, 1.0f);
509         m_vertexPosData[2] = tcu::Vec4(-0.7f, -0.1f, 0.0f, 1.0f);
510         m_vertexPosData[3] = tcu::Vec4(-0.1f, -0.7f, 0.0f, 1.0f);
511
512         if (m_test == READ_ATTRIBUTE)
513         {
514                 m_vertexAttrData[0] = tcu::Vec4(((EMIT_COUNT_VERTEX_0 == -1) ? ((float)m_maxEmitCount) : ((float)EMIT_COUNT_VERTEX_0)), 0.0f, 0.0f, 0.0f);
515                 m_vertexAttrData[1] = tcu::Vec4(((EMIT_COUNT_VERTEX_1 == -1) ? ((float)m_maxEmitCount) : ((float)EMIT_COUNT_VERTEX_1)), 0.0f, 0.0f, 0.0f);
516                 m_vertexAttrData[2] = tcu::Vec4(((EMIT_COUNT_VERTEX_2 == -1) ? ((float)m_maxEmitCount) : ((float)EMIT_COUNT_VERTEX_2)), 0.0f, 0.0f, 0.0f);
517                 m_vertexAttrData[3] = tcu::Vec4(((EMIT_COUNT_VERTEX_3 == -1) ? ((float)m_maxEmitCount) : ((float)EMIT_COUNT_VERTEX_3)), 0.0f, 0.0f, 0.0f);
518         }
519         else
520         {
521                 m_vertexAttrData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
522                 m_vertexAttrData[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f);
523                 m_vertexAttrData[2] = tcu::Vec4(2.0f, 0.0f, 0.0f, 0.0f);
524                 m_vertexAttrData[3] = tcu::Vec4(3.0f, 0.0f, 0.0f, 0.0f);
525         }
526 }
527
528 void VaryingOutputCountTestInstance::genVertexDataWithInstancing (void)
529 {
530         m_numDrawVertices = 1;
531         m_vertexPosData.resize(m_numDrawVertices);
532         m_vertexAttrData.resize(m_numDrawVertices);
533
534         m_vertexPosData[0] = tcu::Vec4(0.0f,  0.0f, 0.0f, 1.0f);
535
536         if (m_test == READ_ATTRIBUTE)
537         {
538                 const int emitCounts[] =
539                 {
540                         (EMIT_COUNT_VERTEX_0 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_0),
541                         (EMIT_COUNT_VERTEX_1 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_1),
542                         (EMIT_COUNT_VERTEX_2 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_2),
543                         (EMIT_COUNT_VERTEX_3 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_3),
544                 };
545
546                 m_vertexAttrData[0] = tcu::Vec4((float)emitCounts[0], (float)emitCounts[1], (float)emitCounts[2], (float)emitCounts[3]);
547         }
548         else
549         {
550                 // not used
551                 m_vertexAttrData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
552         }
553 }
554
555 class BuiltinVariableRenderTestInstance: public GeometryExpanderRenderTestInstance
556 {
557 public:
558                         BuiltinVariableRenderTestInstance       (Context&                               context,
559                                                                                                  const char*                    name,
560                                                                                                  const VariableTest             test,
561                                                                                                  const bool                             indicesTest);
562         void    genVertexAttribData                                     (void);
563         void    createIndicesBuffer                                     (void);
564
565 protected:
566         void    drawCommand                                                     (const VkCommandBuffer& cmdBuffer);
567
568 private:
569         const bool                              m_indicesTest;
570         std::vector<deUint16>   m_indices;
571         Move<vk::VkBuffer>              m_indicesBuffer;
572         MovePtr<Allocation>             m_allocation;
573 };
574
575 BuiltinVariableRenderTestInstance::BuiltinVariableRenderTestInstance (Context& context, const char* name, const VariableTest test, const bool indicesTest)
576         : GeometryExpanderRenderTestInstance    (context, (test == TEST_PRIMITIVE_ID_IN) ? VK_PRIMITIVE_TOPOLOGY_LINE_STRIP : VK_PRIMITIVE_TOPOLOGY_POINT_LIST, name)
577         , m_indicesTest                                                 (indicesTest)
578 {
579         genVertexAttribData();
580 }
581
582 void BuiltinVariableRenderTestInstance::genVertexAttribData (void)
583 {
584         m_numDrawVertices = 5;
585
586         m_vertexPosData.resize(m_numDrawVertices);
587         m_vertexPosData[0] = tcu::Vec4( 0.5f,  0.0f, 0.0f, 1.0f);
588         m_vertexPosData[1] = tcu::Vec4( 0.0f,  0.5f, 0.0f, 1.0f);
589         m_vertexPosData[2] = tcu::Vec4(-0.7f, -0.1f, 0.0f, 1.0f);
590         m_vertexPosData[3] = tcu::Vec4(-0.1f, -0.7f, 0.0f, 1.0f);
591         m_vertexPosData[4] = tcu::Vec4( 0.5f,  0.0f, 0.0f, 1.0f);
592
593         m_vertexAttrData.resize(m_numDrawVertices);
594         m_vertexAttrData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
595         m_vertexAttrData[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f);
596         m_vertexAttrData[2] = tcu::Vec4(2.0f, 0.0f, 0.0f, 0.0f);
597         m_vertexAttrData[3] = tcu::Vec4(3.0f, 0.0f, 0.0f, 0.0f);
598         m_vertexAttrData[4] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
599
600         if (m_indicesTest)
601         {
602                 // Only used by primitive ID restart test
603                 m_indices.resize(m_numDrawVertices);
604                 m_indices[0] = 1;
605                 m_indices[1] = 4;
606                 m_indices[2] = 0xFFFF; // restart
607                 m_indices[3] = 2;
608                 m_indices[4] = 1;
609                 createIndicesBuffer();
610         }
611 }
612
613 void BuiltinVariableRenderTestInstance::createIndicesBuffer (void)
614 {
615         // Create vertex indices buffer
616         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
617         const VkDevice                                  device                          = m_context.getDevice();
618         Allocator&                                              memAlloc                        = m_context.getDefaultAllocator();
619         const VkDeviceSize                              indexBufferSize         = m_indices.size() * sizeof(deUint16);
620         const VkBufferCreateInfo                indexBufferParams       =
621                                                                                                                 {
622                                                                                                                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
623                                                                                                                         DE_NULL,                                                                // const void*                  pNext;
624                                                                                                                         0u,                                                                             // VkBufferCreateFlags  flags;
625                                                                                                                         indexBufferSize,                                                // VkDeviceSize                 size;
626                                                                                                                         VK_BUFFER_USAGE_INDEX_BUFFER_BIT,               // VkBufferUsageFlags   usage;
627                                                                                                                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
628                                                                                                                         0u,                                                                             // deUint32                             queueFamilyCount;
629                                                                                                                         DE_NULL                                                                 // const deUint32*              pQueueFamilyIndices;
630                                                                                                                 };
631
632         m_indicesBuffer = createBuffer(vk, device, &indexBufferParams);
633         m_allocation = memAlloc.allocate(getBufferMemoryRequirements(vk, device, *m_indicesBuffer), MemoryRequirement::HostVisible);
634         VK_CHECK(vk.bindBufferMemory(device, *m_indicesBuffer, m_allocation->getMemory(), m_allocation->getOffset()));
635         // Load indices into buffer
636         deMemcpy(m_allocation->getHostPtr(), &m_indices[0], (size_t)indexBufferSize);
637         flushMappedMemoryRange(vk, device, m_allocation->getMemory(), m_allocation->getOffset(), indexBufferSize);
638 }
639
640 void BuiltinVariableRenderTestInstance::drawCommand (const VkCommandBuffer&     cmdBuffer)
641 {
642         const DeviceInterface&  vk = m_context.getDeviceInterface();
643         if (m_indicesTest)
644         {
645                 vk.cmdBindIndexBuffer(cmdBuffer, *m_indicesBuffer, 0, VK_INDEX_TYPE_UINT16);
646                 vk.cmdDrawIndexed(cmdBuffer, static_cast<deUint32>(m_indices.size()), 1, 0, 0, 0);
647         }
648         else
649                 vk.cmdDraw(cmdBuffer, static_cast<deUint32>(m_numDrawVertices), 1u, 0u, 0u);
650 }
651
652 class GeometryOutputCountTest : public TestCase
653 {
654 public:
655                                                         GeometryOutputCountTest (TestContext&           testCtx,
656                                                                                                          const char*            name,
657                                                                                                          const char*            description,
658                                                                                                          const vector<int>      pattern);
659
660         void                                    initPrograms                    (SourceCollections&                     sourceCollections) const;
661         virtual TestInstance*   createInstance                  (Context&                                       context) const;
662
663 protected:
664         const vector<int> m_pattern;
665 };
666
667 GeometryOutputCountTest::GeometryOutputCountTest (TestContext& testCtx, const char* name, const char* description, const vector<int> pattern)
668         : TestCase      (testCtx, name, description)
669         , m_pattern     (pattern)
670 {
671
672 }
673
674 void GeometryOutputCountTest::initPrograms (SourceCollections& sourceCollections) const
675 {
676         {
677                 std::ostringstream src;
678                 src     << "#version 310 es\n"
679                         <<"layout(location = 0) in highp vec4 a_position;\n"
680                         <<"layout(location = 1) in highp vec4 a_color;\n"
681                         <<"layout(location = 0) out highp vec4 v_geom_FragColor;\n"
682                         <<"void main (void)\n"
683                         <<"{\n"
684                         <<"     gl_Position = a_position;\n"
685                         <<"     v_geom_FragColor = a_color;\n"
686                         <<"}\n";
687                 sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
688         }
689
690         {
691                 const int max_vertices = m_pattern.size() == 2 ? std::max(m_pattern[0], m_pattern[1]) : m_pattern[0];
692
693                 std::ostringstream src;
694                 src     << "#version 310 es\n"
695                         << "#extension GL_EXT_geometry_shader : require\n"
696                         << "#extension GL_OES_texture_storage_multisample_2d_array : require\n"
697                         << "layout(points) in;\n"
698                         << "layout(triangle_strip, max_vertices = " << max_vertices << ") out;\n"
699                         << "layout(location = 0) in highp vec4 v_geom_FragColor[];\n"
700                         << "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
701                         << "void main (void)\n"
702                         << "{\n"
703                         << "    const highp float rowHeight = 2.0 / float(" << m_pattern.size() << ");\n"
704                         << "    const highp float colWidth = 2.0 / float(" << max_vertices << ");\n";
705
706                 if (m_pattern.size() == 2)
707                         src     << "    highp int emitCount = (gl_PrimitiveIDIn == 0) ? (" << m_pattern[0] << ") : (" << m_pattern[1] << ");\n";
708                 else
709                         src     << "    highp int emitCount = " << m_pattern[0] << ";\n";
710                 src     << "    for (highp int ndx = 0; ndx < emitCount / 2; ndx++)\n"
711                         << "    {\n"
712                         << "            gl_Position = gl_in[0].gl_Position + vec4(float(ndx) * 2.0 * colWidth, 0.0, 0.0, 0.0);\n"
713                         << "            v_frag_FragColor = v_geom_FragColor[0];\n"
714                         << "            EmitVertex();\n"
715
716                         << "            gl_Position = gl_in[0].gl_Position + vec4(float(ndx) * 2.0 * colWidth, rowHeight, 0.0, 0.0);\n"
717                         << "            v_frag_FragColor = v_geom_FragColor[0];\n"
718                         << "            EmitVertex();\n"
719
720                         << "    }\n"
721                         << "}\n";
722                 sourceCollections.glslSources.add("geometry") << glu::GeometrySource(src.str());
723         }
724
725         {
726                 std::ostringstream src;
727                 src     << "#version 310 es\n"
728                         <<"layout(location = 0) out mediump vec4 fragColor;\n"
729                         <<"layout(location = 0) in highp vec4 v_frag_FragColor;\n"
730                         <<"void main (void)\n"
731                         <<"{\n"
732                         <<"     fragColor = v_frag_FragColor;\n"
733                         <<"}\n";
734                 sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
735         }
736 }
737
738 TestInstance* GeometryOutputCountTest::createInstance (Context& context) const
739 {
740         return new GeometryOutputCountTestInstance (context, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, static_cast<int>(m_pattern.size()), getName());
741 }
742
743 class VaryingOutputCountCase : public TestCase
744 {
745 public:
746                                                         VaryingOutputCountCase  (TestContext&                           testCtx,
747                                                                                                          const char*                            name,
748                                                                                                          const char*                            description,
749                                                                                                          const VaryingSource            test,
750                                                                                                          const ShaderInstancingMode     mode);
751         void                                    initPrograms                    (SourceCollections&                     sourceCollections) const;
752         virtual TestInstance*   createInstance                  (Context&                                       context) const;
753 protected:
754         const VaryingSource                     m_test;
755         const ShaderInstancingMode      m_mode;
756 };
757
758 VaryingOutputCountCase::VaryingOutputCountCase (TestContext& testCtx, const char* name, const char* description, const VaryingSource test, const ShaderInstancingMode mode)
759         : TestCase      (testCtx, name, description)
760         , m_test        (test)
761         , m_mode        (mode)
762 {
763 }
764
765 void VaryingOutputCountCase::initPrograms (SourceCollections& sourceCollections) const
766 {
767         {
768                 std::ostringstream src;
769                 switch(m_test)
770                 {
771                         case READ_ATTRIBUTE:
772                         case READ_TEXTURE:
773                                 src     << "#version 310 es\n"
774                                         << "layout(location = 0) in highp vec4 a_position;\n"
775                                         << "layout(location = 1) in highp vec4 a_emitCount;\n"
776                                         << "layout(location = 0) out highp vec4 v_geom_emitCount;\n"
777                                         << "void main (void)\n"
778                                         << "{\n"
779                                         << "    gl_Position = a_position;\n"
780                                         << "    v_geom_emitCount = a_emitCount;\n"
781                                         << "}\n";
782                                 break;
783                         case READ_UNIFORM:
784                                 src     << "#version 310 es\n"
785                                         << "layout(location = 0) in highp vec4 a_position;\n"
786                                         << "layout(location = 1) in highp vec4 a_vertexNdx;\n"
787                                         << "layout(location = 0) out highp vec4 v_geom_vertexNdx;\n"
788                                         << "void main (void)\n"
789                                         << "{\n"
790                                         << "    gl_Position = a_position;\n"
791                                         << "    v_geom_vertexNdx = a_vertexNdx;\n"
792                                         << "}\n";
793                                 break;
794                         default:
795                                 DE_ASSERT(0);
796                                 break;
797                 }
798                 sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
799         }
800
801         {
802                 const bool instanced = MODE_WITH_INSTANCING == m_mode;
803                 std::ostringstream src;
804                 src     << "#version 310 es\n"
805                         << "#extension GL_EXT_geometry_shader : require\n"
806                         << "#extension GL_OES_texture_storage_multisample_2d_array : require\n";
807                 if (instanced)
808                         src     << "layout(points, invocations=4) in;\n";
809                 else
810                         src     << "layout(points) in;\n";
811
812                 switch(m_test)
813                 {
814                         case READ_ATTRIBUTE:
815                                 src     << "layout(triangle_strip, max_vertices = 128) out;\n"
816                                         << "layout(location = 0) in highp vec4 v_geom_emitCount[];\n"
817                                         << "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
818                                         << "void main (void)\n"
819                                         << "{\n"
820                                         << "    highp vec4 attrEmitCounts = v_geom_emitCount[0];\n"
821                                         << "    mediump int emitCount = int(attrEmitCounts[" << ((instanced) ? ("gl_InvocationID") : ("0")) << "]);\n"
822                                         << "    highp vec4 color = vec4((emitCount < 10) ? (0.0) : (1.0), (emitCount > 10) ? (0.0) : (1.0), 1.0, 1.0);\n"
823                                         << "    highp vec4 basePos = " << ((instanced) ? ("gl_in[0].gl_Position + 0.5 * vec4(cos(float(gl_InvocationID)), sin(float(gl_InvocationID)), 0.0, 0.0)") : ("gl_in[0].gl_Position")) << ";\n"
824                                         << "    for (mediump int i = 0; i < emitCount / 2; i++)\n"
825                                         << "    {\n"
826                                         << "            highp float angle = (float(i) + 0.5) / float(emitCount / 2) * 3.142;\n"
827                                         << "            gl_Position = basePos + vec4(cos(angle),  sin(angle), 0.0, 0.0) * 0.15;\n"
828                                         << "            v_frag_FragColor = color;\n"
829                                         << "            EmitVertex();\n"
830                                         << "            gl_Position = basePos + vec4(cos(angle), -sin(angle), 0.0, 0.0) * 0.15;\n"
831                                         << "            v_frag_FragColor = color;\n"
832                                         << "            EmitVertex();\n"
833                                         << "    }\n"
834                                         <<"}\n";
835                                 break;
836                         case READ_UNIFORM:
837                                 src     << "layout(triangle_strip, max_vertices = 128) out;\n"
838                                         << "layout(location = 0) in highp vec4 v_geom_vertexNdx[];\n"
839                                         << "layout(binding = 0) readonly uniform Input {\n"
840                                         << "    ivec4 u_emitCount;\n"
841                                         << "} emit;\n"
842                                         << "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
843                                         << "void main (void)\n"
844                                         << "{\n"
845                                         << "    mediump int primitiveNdx = " << ((instanced) ? ("gl_InvocationID") : ("int(v_geom_vertexNdx[0].x)")) << ";\n"
846                                         << "    mediump int emitCount = emit.u_emitCount[primitiveNdx];\n"
847                                         << "\n"
848                                         << "    const highp vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
849                                         << "    const highp vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
850                                         << "    const highp vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);\n"
851                                         << "    const highp vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
852                                         << "    const highp vec4 colors[4] = vec4[4](red, green, blue, yellow);\n"
853                                         << "    highp vec4 color = colors[int(primitiveNdx)];\n"
854                                         << "\n"
855                                         << "    highp vec4 basePos = " << ((instanced) ? ("gl_in[0].gl_Position + 0.5 * vec4(cos(float(gl_InvocationID)), sin(float(gl_InvocationID)), 0.0, 0.0)") : ("gl_in[0].gl_Position")) << ";\n"
856                                         << "    for (mediump int i = 0; i < emitCount / 2; i++)\n"
857                                         << "    {\n"
858                                         << "            highp float angle = (float(i) + 0.5) / float(emitCount / 2) * 3.142;\n"
859                                         << "            gl_Position = basePos + vec4(cos(angle),  sin(angle), 0.0, 0.0) * 0.15;\n"
860                                         << "            v_frag_FragColor = color;\n"
861                                         << "            EmitVertex();\n"
862                                         << "            gl_Position = basePos + vec4(cos(angle), -sin(angle), 0.0, 0.0) * 0.15;\n"
863                                         << "            v_frag_FragColor = color;\n"
864                                         << "            EmitVertex();\n"
865                                         << "    }\n"
866                                         <<"}\n";
867                                 break;
868                         case READ_TEXTURE:
869                                 src     << "layout(triangle_strip, max_vertices = 128) out;\n"
870                                         << "layout(location = 0) in highp vec4 v_geom_vertexNdx[];\n"
871                                         << "layout(binding = 0) uniform highp sampler2D u_sampler;\n"
872                                         << "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
873                                         << "void main (void)\n"
874                                         << "{\n"
875                                         << "    highp float primitiveNdx = " << ((instanced) ? ("float(gl_InvocationID)") : ("v_geom_vertexNdx[0].x")) << ";\n"
876                                         << "    highp vec2 texCoord = vec2(1.0 / 8.0 + primitiveNdx / 4.0, 0.5);\n"
877                                         << "    highp vec4 texColor = texture(u_sampler, texCoord);\n"
878                                         << "    mediump int emitCount = 0;\n"
879                                         << "    if (texColor.x > 0.0)\n"
880                                         << "            emitCount += 6;\n"
881                                         << "    if (texColor.y > 0.0)\n"
882                                         << "            emitCount += 0;\n"
883                                         << "    if (texColor.z > 0.0)\n"
884                                         << "            emitCount += 128;\n"
885                                         << "    if (texColor.w > 0.0)\n"
886                                         << "            emitCount += 10;\n"
887                                         << "    const highp vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
888                                         << "    const highp vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
889                                         << "    const highp vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);\n"
890                                         << "    const highp vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
891                                         << "    const highp vec4 colors[4] = vec4[4](red, green, blue, yellow);\n"
892                                         << "    highp vec4 color = colors[int(primitiveNdx)];\n"
893                                         << "    highp vec4 basePos = "<< ((instanced) ? ("gl_in[0].gl_Position + 0.5 * vec4(cos(float(gl_InvocationID)), sin(float(gl_InvocationID)), 0.0, 0.0)") : ("gl_in[0].gl_Position")) << ";\n"
894                                         << "    for (mediump int i = 0; i < emitCount / 2; i++)\n"
895                                         << "    {\n"
896                                         << "            highp float angle = (float(i) + 0.5) / float(emitCount / 2) * 3.142;\n"
897                                         << "            gl_Position = basePos + vec4(cos(angle),  sin(angle), 0.0, 0.0) * 0.15;\n"
898                                         << "            v_frag_FragColor = color;\n"
899                                         << "            EmitVertex();\n"
900                                         << "            gl_Position = basePos + vec4(cos(angle), -sin(angle), 0.0, 0.0) * 0.15;\n"
901                                         << "            v_frag_FragColor = color;\n"
902                                         << "            EmitVertex();\n"
903                                         << "    }\n"
904                                         <<"}\n";
905                                 break;
906                         default:
907                                 DE_ASSERT(0);
908                                 break;
909                 }
910                 sourceCollections.glslSources.add("geometry") << glu::GeometrySource(src.str());
911         }
912
913         {
914                 std::ostringstream src;
915                 src     << "#version 310 es\n"
916                         << "layout(location = 0) out mediump vec4 fragColor;\n"
917                         << "layout(location = 0) in highp vec4 v_frag_FragColor;\n"
918                         << "void main (void)\n"
919                         << "{\n"
920                         << "    fragColor = v_frag_FragColor;\n"
921                         << "}\n";
922                 sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
923         }
924 }
925
926 TestInstance* VaryingOutputCountCase::createInstance (Context& context) const
927 {
928         return new VaryingOutputCountTestInstance (context, getName(), VK_PRIMITIVE_TOPOLOGY_POINT_LIST, m_test, m_mode);
929 }
930
931 class BuiltinVariableRenderTest : public TestCase
932 {
933 public:
934                                                         BuiltinVariableRenderTest       (TestContext&           testCtx,
935                                                                                                                 const char*                     name,
936                                                                                                                 const char*                     desc,
937                                                                                                                 const VariableTest      test,
938                                                                                                                 const bool                      flag = false);
939         void                                    initPrograms                            (SourceCollections&     sourceCollections) const;
940         virtual TestInstance*   createInstance                          (Context&                       context) const;
941 protected:
942         const VariableTest      m_test;
943         const bool                      m_flag;
944 };
945
946 BuiltinVariableRenderTest::BuiltinVariableRenderTest (TestContext& testCtx, const char* name, const char* description, const VariableTest test, const bool flag)
947         : TestCase      (testCtx, name, description)
948         , m_test        (test)
949         , m_flag        (flag)
950 {
951 }
952
953 void BuiltinVariableRenderTest::initPrograms (SourceCollections& sourceCollections) const
954 {
955         {
956                 std::ostringstream src;
957                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
958                         << "out gl_PerVertex\n"
959                         <<" {\n"
960                         << "    vec4 gl_Position;\n"
961                         << "    float gl_PointSize;\n"
962                         << "};\n"
963                         << "layout(location = 0) in vec4 a_position;\n";
964                 switch(m_test)
965                 {
966                         case TEST_POINT_SIZE:
967                                 src     << "layout(location = 1) in vec4 a_pointSize;\n"
968                                         << "layout(location = 0) out vec4 v_geom_pointSize;\n"
969                                         << "void main (void)\n"
970                                         << "{\n"
971                                         << "    gl_Position = a_position;\n"
972                                         << "    gl_PointSize = 1.0;\n"
973                                         << "    v_geom_pointSize = a_pointSize;\n"
974                                         << "}\n";
975                                 break;
976                         case TEST_PRIMITIVE_ID_IN:
977                                 src     << "void main (void)\n"
978                                         << "{\n"
979                                         << "    gl_Position = a_position;\n"
980                                         << "}\n";
981                                 break;
982                         case TEST_PRIMITIVE_ID:
983                                 src     << "layout(location = 1) in vec4 a_primitiveID;\n"
984                                         << "layout(location = 0) out vec4 v_geom_primitiveID;\n"
985                                         << "void main (void)\n"
986                                         << "{\n"
987                                         << "    gl_Position = a_position;\n"
988                                         << "    v_geom_primitiveID = a_primitiveID;\n"
989                                         << "}\n";
990                                 break;
991                         default:
992                                 DE_ASSERT(0);
993                                 break;
994                 }
995                 sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
996         }
997
998         {
999                 std::ostringstream src;
1000                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1001                         << "in gl_PerVertex\n"
1002                         <<"{\n"
1003                         << "    vec4 gl_Position;\n"
1004                         << "    float gl_PointSize;\n"
1005                         << "} gl_in[];\n"
1006                         << "out gl_PerVertex\n"
1007                         <<"{\n"
1008                         << "    vec4 gl_Position;\n"
1009                         << "    float gl_PointSize;\n"
1010                         << "};\n";
1011                 switch(m_test)
1012                 {
1013                         case TEST_POINT_SIZE:
1014                                 src     << "#extension GL_EXT_geometry_point_size : require\n"
1015                                         << "layout(points) in;\n"
1016                                         << "layout(points, max_vertices = 1) out;\n"
1017                                         << "layout(location = 0) in vec4 v_geom_pointSize[];\n"
1018                                         << "layout(location = 0) out vec4 v_frag_FragColor;\n"
1019                                         << "void main (void)\n"
1020                                         << "{\n"
1021                                         << "    gl_Position = gl_in[0].gl_Position;\n"
1022                                         << "    gl_PointSize = v_geom_pointSize[0].x + 1.0;\n"
1023                                         << "    v_frag_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
1024                                         << "    EmitVertex();\n"
1025                                         << "}\n";
1026                                 break;
1027                         case TEST_PRIMITIVE_ID_IN:
1028                                 src     << "layout(lines) in;\n"
1029                                         << "layout(triangle_strip, max_vertices = 10) out;\n"
1030                                         << "layout(location = 0) out vec4 v_frag_FragColor;\n"
1031                                         << "void main (void)\n"
1032                                         << "{\n"
1033                                         << "    const vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
1034                                         << "    const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
1035                                         << "    const vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);\n"
1036                                         << "    const vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
1037                                         << "    const vec4 colors[4] = vec4[4](red, green, blue, yellow);\n"
1038                                         << "    for (float percent=0.00; percent < 0.30; percent+=0.10)\n"
1039                                                         "{\n"
1040                                         << "            gl_Position = gl_in[0].gl_Position * vec4(1.0+percent, 1.0+percent, 1.0, 1.0);\n"
1041                                         << "            v_frag_FragColor = colors[gl_PrimitiveIDIn % 4];\n"
1042                                         << "            EmitVertex();\n"
1043                                         << "            gl_Position = gl_in[1].gl_Position * vec4(1.0+percent, 1.0+percent, 1.0, 1.0);\n"
1044                                         << "            v_frag_FragColor = colors[gl_PrimitiveIDIn % 4];\n"
1045                                         << "            EmitVertex();\n"
1046                                         << "    }\n"
1047                                         << "}\n";
1048                                 break;
1049                         case TEST_PRIMITIVE_ID:
1050                                 src     << "layout(points, invocations=1) in;\n"
1051                                         << "layout(triangle_strip, max_vertices = 3) out;\n"
1052                                         << "layout(location = 0) in vec4 v_geom_primitiveID[];\n"
1053                                         << "void main (void)\n"
1054                                         << "{\n"
1055                                         << "    gl_Position = gl_in[0].gl_Position + vec4(0.05, 0.0, 0.0, 0.0);\n"
1056                                         << "    gl_PrimitiveID = int(floor(v_geom_primitiveID[0].x)) + 3;\n"
1057                                         << "    EmitVertex();\n"
1058                                         << "    gl_Position = gl_in[0].gl_Position - vec4(0.05, 0.0, 0.0, 0.0);\n"
1059                                         << "    gl_PrimitiveID = int(floor(v_geom_primitiveID[0].x)) + 3;\n"
1060                                         << "    EmitVertex();\n"
1061                                         << "    gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.05, 0.0, 0.0);\n"
1062                                         << "    gl_PrimitiveID = int(floor(v_geom_primitiveID[0].x)) + 3;\n"
1063                                         << "    EmitVertex();\n"
1064                                         << "}\n";
1065                                 break;
1066                         default:
1067                                 DE_ASSERT(0);
1068                                 break;
1069                 }
1070                 sourceCollections.glslSources.add("geometry") << glu::GeometrySource(src.str());
1071         }
1072
1073         {
1074                 std::ostringstream src;
1075                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n";
1076                 switch(m_test)
1077                 {
1078                         case TEST_POINT_SIZE:
1079                                 src     << "layout(location = 0) out vec4 fragColor;\n"
1080                                         << "layout(location = 0) in vec4 v_frag_FragColor;\n"
1081                                         << "void main (void)\n"
1082                                         << "{\n"
1083                                         << "    fragColor = v_frag_FragColor;\n"
1084                                         << "}\n";
1085                                 break;
1086                         case TEST_PRIMITIVE_ID_IN:
1087                                 src     << "layout(location = 0) out vec4 fragColor;\n"
1088                                         << "layout(location = 0) in vec4 v_frag_FragColor;\n"
1089                                         << "void main (void)\n"
1090                                         << "{\n"
1091                                         << "    fragColor = v_frag_FragColor;\n"
1092                                         << "}\n";
1093                                 break;
1094                         case TEST_PRIMITIVE_ID:
1095                                 src     << "layout(location = 0) out vec4 fragColor;\n"
1096                                         << "void main (void)\n"
1097                                         << "{\n"
1098                                         << "    const vec4 red                  = vec4(1.0, 0.0, 0.0, 1.0);\n"
1099                                         << "    const vec4 green                = vec4(0.0, 1.0, 0.0, 1.0);\n"
1100                                         << "    const vec4 blue                 = vec4(0.0, 0.0, 1.0, 1.0);\n"
1101                                         << "    const vec4 yellow               = vec4(1.0, 1.0, 0.0, 1.0);\n"
1102                                         << "    const vec4 colors[4]    = vec4[4](yellow, red, green, blue);\n"
1103                                         << "    fragColor = colors[gl_PrimitiveID % 4];\n"
1104                                         << "}\n";
1105                                 break;
1106                         default:
1107                                 DE_ASSERT(0);
1108                                 break;
1109                 }
1110                 sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
1111         }
1112 }
1113
1114 TestInstance* BuiltinVariableRenderTest::createInstance (Context& context) const
1115 {
1116         if (m_test == TEST_POINT_SIZE && !checkPointSize(context.getInstanceInterface(), context.getPhysicalDevice()))
1117                         TCU_THROW(NotSupportedError, "Missing feature: pointSize");
1118         return new BuiltinVariableRenderTestInstance(context, getName(), m_test, m_flag);
1119 }
1120
1121 inline vector<int> createPattern (int count)
1122 {
1123         vector<int>     pattern;
1124         pattern.push_back(count);
1125         return pattern;
1126 }
1127
1128 inline vector<int> createPattern (int count0, int count1)
1129 {
1130         vector<int>     pattern;
1131         pattern.push_back(count0);
1132         pattern.push_back(count1);
1133         return pattern;
1134 }
1135
1136 } // anonymous
1137
1138 TestCaseGroup* createBasicGeometryShaderTests (TestContext& testCtx)
1139 {
1140         MovePtr<TestCaseGroup> basicGroup       (new tcu::TestCaseGroup(testCtx, "basic", "Basic tests."));
1141
1142         basicGroup->addChild(new GeometryOutputCountTest        (testCtx,       "output_10",                            "Output 10 vertices",                                                           createPattern(10)));
1143         basicGroup->addChild(new GeometryOutputCountTest        (testCtx,       "output_128",                           "Output 128 vertices",                                                          createPattern(128)));
1144         basicGroup->addChild(new GeometryOutputCountTest        (testCtx,       "output_10_and_100",            "Output 10 and 100 vertices in two invocations",        createPattern(10, 100)));
1145         basicGroup->addChild(new GeometryOutputCountTest        (testCtx,       "output_100_and_10",            "Output 100 and 10 vertices in two invocations",        createPattern(100, 10)));
1146         basicGroup->addChild(new GeometryOutputCountTest        (testCtx,       "output_0_and_128",                     "Output 0 and 128 vertices in two invocations",         createPattern(0, 128)));
1147         basicGroup->addChild(new GeometryOutputCountTest        (testCtx,       "output_128_and_0",                     "Output 128 and 0 vertices in two invocations",         createPattern(128, 0)));
1148
1149         basicGroup->addChild(new VaryingOutputCountCase         (testCtx,       "output_vary_by_attribute",                             "Output varying number of vertices",    READ_ATTRIBUTE, MODE_WITHOUT_INSTANCING));
1150         basicGroup->addChild(new VaryingOutputCountCase         (testCtx,       "output_vary_by_uniform",                               "Output varying number of vertices",    READ_UNIFORM,   MODE_WITHOUT_INSTANCING));
1151         basicGroup->addChild(new VaryingOutputCountCase         (testCtx,       "output_vary_by_texture",                               "Output varying number of vertices",    READ_TEXTURE,   MODE_WITHOUT_INSTANCING));
1152         basicGroup->addChild(new VaryingOutputCountCase         (testCtx,       "output_vary_by_attribute_instancing",  "Output varying number of vertices",    READ_ATTRIBUTE, MODE_WITH_INSTANCING));
1153         basicGroup->addChild(new VaryingOutputCountCase         (testCtx,       "output_vary_by_uniform_instancing",    "Output varying number of vertices",    READ_UNIFORM,   MODE_WITH_INSTANCING));
1154         basicGroup->addChild(new VaryingOutputCountCase         (testCtx,       "output_vary_by_texture_instancing",    "Output varying number of vertices",    READ_TEXTURE,   MODE_WITH_INSTANCING));
1155
1156         basicGroup->addChild(new BuiltinVariableRenderTest      (testCtx,       "point_size",                                   "test gl_PointSize",                                                            TEST_POINT_SIZE));
1157         basicGroup->addChild(new BuiltinVariableRenderTest      (testCtx,       "primitive_id_in",                              "test gl_PrimitiveIDIn",                                                        TEST_PRIMITIVE_ID_IN));
1158         basicGroup->addChild(new BuiltinVariableRenderTest      (testCtx,       "primitive_id_in_restarted",    "test gl_PrimitiveIDIn with primitive restart",         TEST_PRIMITIVE_ID_IN, true));
1159         basicGroup->addChild(new BuiltinVariableRenderTest      (testCtx,       "primitive_id",                                 "test gl_PrimitiveID",                                                          TEST_PRIMITIVE_ID));
1160
1161         return basicGroup.release();
1162 }
1163
1164 } // geometry
1165 } // vkt