1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2016 The Android Open Source Project
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * \brief Basic Geometry Shader Tests
23 *//*--------------------------------------------------------------------*/
25 #include "vktGeometryBasicGeometryShaderTests.hpp"
26 #include "vktGeometryBasicClass.hpp"
27 #include "vktGeometryTestsUtil.hpp"
29 #include "gluTextureUtil.hpp"
30 #include "glwEnums.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"
53 using tcu::TestStatus;
54 using tcu::TestContext;
55 using tcu::TestCaseGroup;
68 enum ShaderInstancingMode
70 MODE_WITHOUT_INSTANCING = 0,
77 EMIT_COUNT_VERTEX_0 = 6,
78 EMIT_COUNT_VERTEX_1 = 0,
79 EMIT_COUNT_VERTEX_2 = -1,
80 EMIT_COUNT_VERTEX_3 = 10,
90 void uploadImage (Context& context,
91 const tcu::ConstPixelBufferAccess& access,
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;
107 // Create source buffer
109 const VkBufferCreateInfo bufferParams =
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;
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()));
125 // Create command pool and buffer
127 const VkCommandPoolCreateInfo cmdPoolParams =
129 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
130 DE_NULL, // const void* pNext;
131 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
132 queueFamilyIndex, // deUint32 queueFamilyIndex;
134 cmdPool = createCommandPool(vk, device, &cmdPoolParams);
136 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
138 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
139 DE_NULL, // const void* pNext;
140 *cmdPool, // VkCommandPool commandPool;
141 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
142 1u, // deUint32 bufferCount;
144 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
149 const VkFenceCreateInfo fenceParams =
151 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
152 DE_NULL, // const void* pNext;
153 0u // VkFenceCreateFlags flags;
156 fence = createFence(vk, device, &fenceParams);
159 // Barriers for copying buffer to image
160 const VkBufferMemoryBarrier preBufferBarrier =
162 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
163 DE_NULL, // const void* pNext;
164 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
165 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
166 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
167 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
168 *buffer, // VkBuffer buffer;
169 0u, // VkDeviceSize offset;
170 bufferSize // VkDeviceSize size;
173 const VkImageMemoryBarrier preImageBarrier =
175 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
176 DE_NULL, // const void* pNext;
177 0u, // VkAccessFlags srcAccessMask;
178 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
179 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
180 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
181 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
182 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
183 destImage, // VkImage image;
184 { // VkImageSubresourceRange subresourceRange;
185 aspectMask, // VkImageAspect aspect;
186 0u, // deUint32 baseMipLevel;
187 1u, // deUint32 mipLevels;
188 0u, // deUint32 baseArraySlice;
189 1u // deUint32 arraySize;
193 const VkImageMemoryBarrier postImageBarrier =
195 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
196 DE_NULL, // const void* pNext;
197 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
198 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
199 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
200 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
201 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
202 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
203 destImage, // VkImage image;
204 { // VkImageSubresourceRange subresourceRange;
205 aspectMask, // VkImageAspect aspect;
206 0u, // deUint32 baseMipLevel;
207 1u, // deUint32 mipLevels;
208 0u, // deUint32 baseArraySlice;
209 1u // deUint32 arraySize;
213 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
215 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
216 DE_NULL, // const void* pNext;
217 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
218 (const VkCommandBufferInheritanceInfo*)DE_NULL,
221 // Get copy regions and write buffer data
222 const VkBufferImageCopy copyRegions =
224 0u, // VkDeviceSize bufferOffset;
225 (deUint32)access.getWidth(), // deUint32 bufferRowLength;
226 (deUint32)access.getHeight(), // deUint32 bufferImageHeight;
227 { // VkImageSubresourceLayers imageSubresource;
228 aspectMask, // VkImageAspectFlags aspectMask;
229 (deUint32)0u, // uint32_t mipLevel;
230 (deUint32)0u, // uint32_t baseArrayLayer;
231 1u // uint32_t layerCount;
233 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
234 { // VkExtent3D imageExtent;
235 (deUint32)access.getWidth(),
236 (deUint32)access.getHeight(),
237 (deUint32)access.getDepth()
242 const tcu::PixelBufferAccess destAccess (access.getFormat(), access.getSize(), bufferAlloc->getHostPtr());
243 tcu::copy(destAccess, access);
244 flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
247 // Copy buffer to image
248 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
249 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);
250 vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Regions);
251 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);
252 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
254 const VkSubmitInfo submitInfo =
256 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
257 DE_NULL, // const void* pNext;
258 0u, // deUint32 waitSemaphoreCount;
259 DE_NULL, // const VkSemaphore* pWaitSemaphores;
260 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
261 1u, // deUint32 commandBufferCount;
262 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
263 0u, // deUint32 signalSemaphoreCount;
264 DE_NULL // const VkSemaphore* pSignalSemaphores;
267 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
268 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
271 class GeometryOutputCountTestInstance : public GeometryExpanderRenderTestInstance
274 GeometryOutputCountTestInstance (Context& context,
275 const VkPrimitiveTopology primitiveType,
276 const int primitiveCount,
278 void genVertexAttribData (void);
280 const int m_primitiveCount;
283 GeometryOutputCountTestInstance::GeometryOutputCountTestInstance (Context& context,
284 const VkPrimitiveTopology primitiveType,
285 const int primitiveCount,
287 : GeometryExpanderRenderTestInstance (context, primitiveType, name)
288 , m_primitiveCount (primitiveCount)
291 genVertexAttribData();
294 void GeometryOutputCountTestInstance::genVertexAttribData (void)
296 m_vertexPosData.resize(m_primitiveCount);
297 m_vertexAttrData.resize(m_primitiveCount);
299 for (int ndx = 0; ndx < m_primitiveCount; ++ndx)
301 m_vertexPosData[ndx] = tcu::Vec4(-1.0f, ((float)ndx) / (float)m_primitiveCount * 2.0f - 1.0f, 0.0f, 1.0f);
302 m_vertexAttrData[ndx] = (ndx % 2 == 0) ? tcu::Vec4(1, 1, 1, 1) : tcu::Vec4(1, 0, 0, 1);
304 m_numDrawVertices = m_primitiveCount;
307 class VaryingOutputCountTestInstance : public GeometryExpanderRenderTestInstance
310 VaryingOutputCountTestInstance (Context& context,
312 const VkPrimitiveTopology primitiveType,
313 const VaryingSource test,
314 const ShaderInstancingMode mode);
315 void genVertexAttribData (void);
317 Move<VkPipelineLayout> createPipelineLayout (const DeviceInterface& vk, const VkDevice device);
318 void bindDescriptorSets (const DeviceInterface& vk,
319 const VkDevice device,
321 const VkCommandBuffer& cmdBuffer,
322 const VkPipelineLayout& pipelineLayout);
324 void genVertexDataWithoutInstancing (void);
325 void genVertexDataWithInstancing (void);
327 const VaryingSource m_test;
328 const ShaderInstancingMode m_mode;
329 const deInt32 m_maxEmitCount;
330 Move<VkDescriptorPool> m_descriptorPool;
331 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
332 Move<VkDescriptorSet> m_descriptorSet;
333 Move<VkBuffer> m_buffer;
334 Move<VkImage> m_texture;
335 Move<VkImageView> m_imageView;
336 Move<VkSampler> m_sampler;
337 de::MovePtr<Allocation> m_allocation;
340 VaryingOutputCountTestInstance::VaryingOutputCountTestInstance (Context& context,
342 const VkPrimitiveTopology primitiveType,
343 const VaryingSource test,
344 const ShaderInstancingMode mode)
345 : GeometryExpanderRenderTestInstance (context, primitiveType, name)
348 , m_maxEmitCount (128)
350 genVertexAttribData ();
353 void VaryingOutputCountTestInstance::genVertexAttribData (void)
355 if (m_mode == MODE_WITHOUT_INSTANCING)
356 genVertexDataWithoutInstancing();
357 else if (m_mode == MODE_WITH_INSTANCING)
358 genVertexDataWithInstancing();
363 Move<VkPipelineLayout> VaryingOutputCountTestInstance::createPipelineLayout (const DeviceInterface& vk, const VkDevice device)
365 if (m_test == READ_UNIFORM)
367 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
368 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_GEOMETRY_BIT)
370 m_descriptorPool = DescriptorPoolBuilder()
371 .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
372 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
373 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
375 return makePipelineLayout(vk, device, *m_descriptorSetLayout);
377 else if (m_test == READ_TEXTURE)
379 const tcu::Vec4 data[4] =
381 tcu::Vec4(255, 0, 0, 0),
382 tcu::Vec4(0, 255, 0, 0),
383 tcu::Vec4(0, 0, 255, 0),
384 tcu::Vec4(0, 0, 0, 255)
386 const tcu::UVec2 viewportSize (4, 1);
387 const tcu::TextureFormat texFormat = glu::mapGLInternalFormat(GL_RGBA8);
388 const VkFormat format = mapTextureFormat(texFormat);
389 const VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
390 Allocator& memAlloc = m_context.getDefaultAllocator();
391 tcu::TextureLevel texture (texFormat, static_cast<int>(viewportSize.x()), static_cast<int>(viewportSize.y()));
395 tcu::PixelBufferAccess access = texture.getAccess();
396 for (int x = 0; x < texture.getWidth(); ++x)
397 access.setPixel(data[x], x, 0);
400 const VkImageCreateInfo imageParams =
402 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
403 DE_NULL, // const void* pNext;
404 0, // VkImageCreateFlags flags;
405 VK_IMAGE_TYPE_2D, // VkImageType imageType;
406 format, // VkFormat format;
407 { // VkExtent3D extent;
412 1u, // deUint32 mipLevels;
413 1u, // deUint32 arrayLayers;
414 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
415 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
416 imageUsageFlags, // VkImageUsageFlags usage;
417 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
418 0u, // deUint32 queueFamilyIndexCount;
419 DE_NULL, // const deUint32* pQueueFamilyIndices;
420 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
423 m_texture = createImage(vk, device, &imageParams);
424 m_allocation = memAlloc.allocate(getImageMemoryRequirements(vk, device, *m_texture), MemoryRequirement::Any);
425 VK_CHECK(vk.bindImageMemory(device, *m_texture, m_allocation->getMemory(), m_allocation->getOffset()));
426 uploadImage(m_context, texture.getAccess(), *m_texture);
428 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
429 .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_GEOMETRY_BIT)
431 m_descriptorPool = DescriptorPoolBuilder()
432 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
433 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
434 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
436 return makePipelineLayout(vk, device, *m_descriptorSetLayout);
439 return makePipelineLayout(vk, device);
442 void VaryingOutputCountTestInstance::bindDescriptorSets (const DeviceInterface& vk, const VkDevice device, Allocator& memAlloc,
443 const VkCommandBuffer& cmdBuffer, const VkPipelineLayout& pipelineLayout)
445 if (m_test == READ_UNIFORM)
447 const deInt32 emitCount[4] = { 6, 0, m_maxEmitCount, 10 };
448 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(sizeof(emitCount), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
449 m_buffer = createBuffer(vk, device, &bufferCreateInfo);
450 m_allocation = memAlloc.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), MemoryRequirement::HostVisible);
452 VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset()));
454 deMemcpy(m_allocation->getHostPtr(), &emitCount[0], sizeof(emitCount));
455 flushMappedMemoryRange(vk, device, m_allocation->getMemory(), m_allocation->getOffset(), sizeof(emitCount));
457 const VkDescriptorBufferInfo bufferDescriptorInfo = makeDescriptorBufferInfo(*m_buffer, 0ull, sizeof(emitCount));
459 DescriptorSetUpdateBuilder()
460 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferDescriptorInfo)
462 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0u, 1u, &*m_descriptorSet, 0u, DE_NULL);
465 else if (m_test == READ_TEXTURE)
467 const tcu::TextureFormat texFormat = glu::mapGLInternalFormat(GL_RGBA8);
468 const VkFormat format = mapTextureFormat(texFormat);
469 const VkSamplerCreateInfo samplerParams =
471 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
472 DE_NULL, // const void* pNext;
473 0u, // VkSamplerCreateFlags flags;
474 VK_FILTER_NEAREST, // VkFilter magFilter;
475 VK_FILTER_NEAREST, // VkFilter minFilter;
476 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
477 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
478 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
479 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
480 0.0f, // float mipLodBias;
481 VK_FALSE, // VkBool32 anisotropyEnable;
482 1.0f, // float maxAnisotropy;
483 false, // VkBool32 compareEnable;
484 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
485 0.0f, // float minLod;
486 0.0f, // float maxLod;
487 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
488 false // VkBool32 unnormalizedCoordinates;
490 m_sampler = createSampler(vk, device, &samplerParams);
491 const VkImageViewCreateInfo viewParams =
493 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
494 NULL, // const voide* pNext;
495 0u, // VkImageViewCreateFlags flags;
496 *m_texture, // VkImage image;
497 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
498 format, // VkFormat format;
499 makeComponentMappingRGBA(), // VkChannelMapping channels;
501 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
502 0u, // deUint32 baseMipLevel;
503 1u, // deUint32 mipLevels;
504 0, // deUint32 baseArraySlice;
505 1u // deUint32 arraySize;
506 }, // VkImageSubresourceRange subresourceRange;
508 m_imageView = createImageView(vk, device, &viewParams);
509 const VkDescriptorImageInfo descriptorImageInfo = makeDescriptorImageInfo (*m_sampler, *m_imageView, VK_IMAGE_LAYOUT_GENERAL);
510 DescriptorSetUpdateBuilder()
511 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfo)
513 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0u, 1u, &*m_descriptorSet, 0u, DE_NULL);
517 void VaryingOutputCountTestInstance::genVertexDataWithoutInstancing (void)
519 m_numDrawVertices = 4;
520 m_vertexPosData.resize(m_numDrawVertices);
521 m_vertexAttrData.resize(m_numDrawVertices);
523 m_vertexPosData[0] = tcu::Vec4( 0.5f, 0.0f, 0.0f, 1.0f);
524 m_vertexPosData[1] = tcu::Vec4( 0.0f, 0.5f, 0.0f, 1.0f);
525 m_vertexPosData[2] = tcu::Vec4(-0.7f, -0.1f, 0.0f, 1.0f);
526 m_vertexPosData[3] = tcu::Vec4(-0.1f, -0.7f, 0.0f, 1.0f);
528 if (m_test == READ_ATTRIBUTE)
530 m_vertexAttrData[0] = tcu::Vec4(((EMIT_COUNT_VERTEX_0 == -1) ? ((float)m_maxEmitCount) : ((float)EMIT_COUNT_VERTEX_0)), 0.0f, 0.0f, 0.0f);
531 m_vertexAttrData[1] = tcu::Vec4(((EMIT_COUNT_VERTEX_1 == -1) ? ((float)m_maxEmitCount) : ((float)EMIT_COUNT_VERTEX_1)), 0.0f, 0.0f, 0.0f);
532 m_vertexAttrData[2] = tcu::Vec4(((EMIT_COUNT_VERTEX_2 == -1) ? ((float)m_maxEmitCount) : ((float)EMIT_COUNT_VERTEX_2)), 0.0f, 0.0f, 0.0f);
533 m_vertexAttrData[3] = tcu::Vec4(((EMIT_COUNT_VERTEX_3 == -1) ? ((float)m_maxEmitCount) : ((float)EMIT_COUNT_VERTEX_3)), 0.0f, 0.0f, 0.0f);
537 m_vertexAttrData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
538 m_vertexAttrData[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f);
539 m_vertexAttrData[2] = tcu::Vec4(2.0f, 0.0f, 0.0f, 0.0f);
540 m_vertexAttrData[3] = tcu::Vec4(3.0f, 0.0f, 0.0f, 0.0f);
544 void VaryingOutputCountTestInstance::genVertexDataWithInstancing (void)
546 m_numDrawVertices = 1;
547 m_vertexPosData.resize(m_numDrawVertices);
548 m_vertexAttrData.resize(m_numDrawVertices);
550 m_vertexPosData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
552 if (m_test == READ_ATTRIBUTE)
554 const int emitCounts[] =
556 (EMIT_COUNT_VERTEX_0 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_0),
557 (EMIT_COUNT_VERTEX_1 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_1),
558 (EMIT_COUNT_VERTEX_2 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_2),
559 (EMIT_COUNT_VERTEX_3 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_3),
562 m_vertexAttrData[0] = tcu::Vec4((float)emitCounts[0], (float)emitCounts[1], (float)emitCounts[2], (float)emitCounts[3]);
567 m_vertexAttrData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
571 class BuiltinVariableRenderTestInstance: public GeometryExpanderRenderTestInstance
574 BuiltinVariableRenderTestInstance (Context& context,
576 const VariableTest test,
577 const bool indicesTest);
578 void genVertexAttribData (void);
579 void createIndicesBuffer (void);
582 void drawCommand (const VkCommandBuffer& cmdBuffer);
585 const bool m_indicesTest;
586 std::vector<deUint16> m_indices;
587 Move<vk::VkBuffer> m_indicesBuffer;
588 MovePtr<Allocation> m_allocation;
591 BuiltinVariableRenderTestInstance::BuiltinVariableRenderTestInstance (Context& context, const char* name, const VariableTest test, const bool indicesTest)
592 : GeometryExpanderRenderTestInstance (context, (test == TEST_PRIMITIVE_ID_IN) ? VK_PRIMITIVE_TOPOLOGY_LINE_STRIP : VK_PRIMITIVE_TOPOLOGY_POINT_LIST, name)
593 , m_indicesTest (indicesTest)
595 genVertexAttribData();
598 void BuiltinVariableRenderTestInstance::genVertexAttribData (void)
600 m_numDrawVertices = 5;
602 m_vertexPosData.resize(m_numDrawVertices);
603 m_vertexPosData[0] = tcu::Vec4( 0.5f, 0.0f, 0.0f, 1.0f);
604 m_vertexPosData[1] = tcu::Vec4( 0.0f, 0.5f, 0.0f, 1.0f);
605 m_vertexPosData[2] = tcu::Vec4(-0.7f, -0.1f, 0.0f, 1.0f);
606 m_vertexPosData[3] = tcu::Vec4(-0.1f, -0.7f, 0.0f, 1.0f);
607 m_vertexPosData[4] = tcu::Vec4( 0.5f, 0.0f, 0.0f, 1.0f);
609 m_vertexAttrData.resize(m_numDrawVertices);
610 m_vertexAttrData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
611 m_vertexAttrData[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f);
612 m_vertexAttrData[2] = tcu::Vec4(2.0f, 0.0f, 0.0f, 0.0f);
613 m_vertexAttrData[3] = tcu::Vec4(3.0f, 0.0f, 0.0f, 0.0f);
614 m_vertexAttrData[4] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
618 // Only used by primitive ID restart test
619 m_indices.resize(m_numDrawVertices);
622 m_indices[2] = 0xFFFF; // restart
625 createIndicesBuffer();
629 void BuiltinVariableRenderTestInstance::createIndicesBuffer (void)
631 // Create vertex indices buffer
632 const DeviceInterface& vk = m_context.getDeviceInterface();
633 const VkDevice device = m_context.getDevice();
634 Allocator& memAlloc = m_context.getDefaultAllocator();
635 const VkDeviceSize indexBufferSize = m_indices.size() * sizeof(deUint16);
636 const VkBufferCreateInfo indexBufferParams =
638 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
639 DE_NULL, // const void* pNext;
640 0u, // VkBufferCreateFlags flags;
641 indexBufferSize, // VkDeviceSize size;
642 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage;
643 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
644 0u, // deUint32 queueFamilyCount;
645 DE_NULL // const deUint32* pQueueFamilyIndices;
648 m_indicesBuffer = createBuffer(vk, device, &indexBufferParams);
649 m_allocation = memAlloc.allocate(getBufferMemoryRequirements(vk, device, *m_indicesBuffer), MemoryRequirement::HostVisible);
650 VK_CHECK(vk.bindBufferMemory(device, *m_indicesBuffer, m_allocation->getMemory(), m_allocation->getOffset()));
651 // Load indices into buffer
652 deMemcpy(m_allocation->getHostPtr(), &m_indices[0], (size_t)indexBufferSize);
653 flushMappedMemoryRange(vk, device, m_allocation->getMemory(), m_allocation->getOffset(), indexBufferSize);
656 void BuiltinVariableRenderTestInstance::drawCommand (const VkCommandBuffer& cmdBuffer)
658 const DeviceInterface& vk = m_context.getDeviceInterface();
661 vk.cmdBindIndexBuffer(cmdBuffer, *m_indicesBuffer, 0, VK_INDEX_TYPE_UINT16);
662 vk.cmdDrawIndexed(cmdBuffer, static_cast<deUint32>(m_indices.size()), 1, 0, 0, 0);
665 vk.cmdDraw(cmdBuffer, static_cast<deUint32>(m_numDrawVertices), 1u, 0u, 0u);
668 class GeometryOutputCountTest : public TestCase
671 GeometryOutputCountTest (TestContext& testCtx,
673 const char* description,
674 const vector<int> pattern);
676 void initPrograms (SourceCollections& sourceCollections) const;
677 virtual TestInstance* createInstance (Context& context) const;
680 const vector<int> m_pattern;
683 GeometryOutputCountTest::GeometryOutputCountTest (TestContext& testCtx, const char* name, const char* description, const vector<int> pattern)
684 : TestCase (testCtx, name, description)
685 , m_pattern (pattern)
690 void GeometryOutputCountTest::initPrograms (SourceCollections& sourceCollections) const
693 std::ostringstream src;
694 src << "#version 310 es\n"
695 <<"layout(location = 0) in highp vec4 a_position;\n"
696 <<"layout(location = 1) in highp vec4 a_color;\n"
697 <<"layout(location = 0) out highp vec4 v_geom_FragColor;\n"
698 <<"void main (void)\n"
700 <<" gl_Position = a_position;\n"
701 <<" v_geom_FragColor = a_color;\n"
703 sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
707 const int max_vertices = m_pattern.size() == 2 ? std::max(m_pattern[0], m_pattern[1]) : m_pattern[0];
709 std::ostringstream src;
710 src << "#version 310 es\n"
711 << "#extension GL_EXT_geometry_shader : require\n"
712 << "#extension GL_OES_texture_storage_multisample_2d_array : require\n"
713 << "layout(points) in;\n"
714 << "layout(triangle_strip, max_vertices = " << max_vertices << ") out;\n"
715 << "layout(location = 0) in highp vec4 v_geom_FragColor[];\n"
716 << "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
717 << "void main (void)\n"
719 << " const highp float rowHeight = 2.0 / float(" << m_pattern.size() << ");\n"
720 << " const highp float colWidth = 2.0 / float(" << max_vertices << ");\n";
722 if (m_pattern.size() == 2)
723 src << " highp int emitCount = (gl_PrimitiveIDIn == 0) ? (" << m_pattern[0] << ") : (" << m_pattern[1] << ");\n";
725 src << " highp int emitCount = " << m_pattern[0] << ";\n";
726 src << " for (highp int ndx = 0; ndx < emitCount / 2; ndx++)\n"
728 << " gl_Position = gl_in[0].gl_Position + vec4(float(ndx) * 2.0 * colWidth, 0.0, 0.0, 0.0);\n"
729 << " v_frag_FragColor = v_geom_FragColor[0];\n"
730 << " EmitVertex();\n"
732 << " gl_Position = gl_in[0].gl_Position + vec4(float(ndx) * 2.0 * colWidth, rowHeight, 0.0, 0.0);\n"
733 << " v_frag_FragColor = v_geom_FragColor[0];\n"
734 << " EmitVertex();\n"
738 sourceCollections.glslSources.add("geometry") << glu::GeometrySource(src.str());
742 std::ostringstream src;
743 src << "#version 310 es\n"
744 <<"layout(location = 0) out mediump vec4 fragColor;\n"
745 <<"layout(location = 0) in highp vec4 v_frag_FragColor;\n"
746 <<"void main (void)\n"
748 <<" fragColor = v_frag_FragColor;\n"
750 sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
754 TestInstance* GeometryOutputCountTest::createInstance (Context& context) const
756 return new GeometryOutputCountTestInstance (context, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, static_cast<int>(m_pattern.size()), getName());
759 class VaryingOutputCountCase : public TestCase
762 VaryingOutputCountCase (TestContext& testCtx,
764 const char* description,
765 const VaryingSource test,
766 const ShaderInstancingMode mode);
767 void initPrograms (SourceCollections& sourceCollections) const;
768 virtual TestInstance* createInstance (Context& context) const;
770 const VaryingSource m_test;
771 const ShaderInstancingMode m_mode;
774 VaryingOutputCountCase::VaryingOutputCountCase (TestContext& testCtx, const char* name, const char* description, const VaryingSource test, const ShaderInstancingMode mode)
775 : TestCase (testCtx, name, description)
781 void VaryingOutputCountCase::initPrograms (SourceCollections& sourceCollections) const
784 std::ostringstream src;
789 src << "#version 310 es\n"
790 << "layout(location = 0) in highp vec4 a_position;\n"
791 << "layout(location = 1) in highp vec4 a_emitCount;\n"
792 << "layout(location = 0) out highp vec4 v_geom_emitCount;\n"
793 << "void main (void)\n"
795 << " gl_Position = a_position;\n"
796 << " v_geom_emitCount = a_emitCount;\n"
800 src << "#version 310 es\n"
801 << "layout(location = 0) in highp vec4 a_position;\n"
802 << "layout(location = 1) in highp vec4 a_vertexNdx;\n"
803 << "layout(location = 0) out highp vec4 v_geom_vertexNdx;\n"
804 << "void main (void)\n"
806 << " gl_Position = a_position;\n"
807 << " v_geom_vertexNdx = a_vertexNdx;\n"
814 sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
818 const bool instanced = MODE_WITH_INSTANCING == m_mode;
819 std::ostringstream src;
820 src << "#version 310 es\n"
821 << "#extension GL_EXT_geometry_shader : require\n"
822 << "#extension GL_OES_texture_storage_multisample_2d_array : require\n";
824 src << "layout(points, invocations=4) in;\n";
826 src << "layout(points) in;\n";
831 src << "layout(triangle_strip, max_vertices = 128) out;\n"
832 << "layout(location = 0) in highp vec4 v_geom_emitCount[];\n"
833 << "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
834 << "void main (void)\n"
836 << " highp vec4 attrEmitCounts = v_geom_emitCount[0];\n"
837 << " mediump int emitCount = int(attrEmitCounts[" << ((instanced) ? ("gl_InvocationID") : ("0")) << "]);\n"
838 << " highp vec4 color = vec4((emitCount < 10) ? (0.0) : (1.0), (emitCount > 10) ? (0.0) : (1.0), 1.0, 1.0);\n"
839 << " 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"
840 << " for (mediump int i = 0; i < emitCount / 2; i++)\n"
842 << " highp float angle = (float(i) + 0.5) / float(emitCount / 2) * 3.142;\n"
843 << " gl_Position = basePos + vec4(cos(angle), sin(angle), 0.0, 0.0) * 0.15;\n"
844 << " v_frag_FragColor = color;\n"
845 << " EmitVertex();\n"
846 << " gl_Position = basePos + vec4(cos(angle), -sin(angle), 0.0, 0.0) * 0.15;\n"
847 << " v_frag_FragColor = color;\n"
848 << " EmitVertex();\n"
853 src << "layout(triangle_strip, max_vertices = 128) out;\n"
854 << "layout(location = 0) in highp vec4 v_geom_vertexNdx[];\n"
855 << "layout(binding = 0) readonly uniform Input {\n"
856 << " ivec4 u_emitCount;\n"
858 << "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
859 << "void main (void)\n"
861 << " mediump int primitiveNdx = " << ((instanced) ? ("gl_InvocationID") : ("int(v_geom_vertexNdx[0].x)")) << ";\n"
862 << " mediump int emitCount = emit.u_emitCount[primitiveNdx];\n"
864 << " const highp vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
865 << " const highp vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
866 << " const highp vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);\n"
867 << " const highp vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
868 << " const highp vec4 colors[4] = vec4[4](red, green, blue, yellow);\n"
869 << " highp vec4 color = colors[int(primitiveNdx)];\n"
871 << " 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"
872 << " for (mediump int i = 0; i < emitCount / 2; i++)\n"
874 << " highp float angle = (float(i) + 0.5) / float(emitCount / 2) * 3.142;\n"
875 << " gl_Position = basePos + vec4(cos(angle), sin(angle), 0.0, 0.0) * 0.15;\n"
876 << " v_frag_FragColor = color;\n"
877 << " EmitVertex();\n"
878 << " gl_Position = basePos + vec4(cos(angle), -sin(angle), 0.0, 0.0) * 0.15;\n"
879 << " v_frag_FragColor = color;\n"
880 << " EmitVertex();\n"
885 src << "layout(triangle_strip, max_vertices = 128) out;\n"
886 << "layout(location = 0) in highp vec4 v_geom_vertexNdx[];\n"
887 << "layout(binding = 0) uniform highp sampler2D u_sampler;\n"
888 << "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
889 << "void main (void)\n"
891 << " highp float primitiveNdx = " << ((instanced) ? ("float(gl_InvocationID)") : ("v_geom_vertexNdx[0].x")) << ";\n"
892 << " highp vec2 texCoord = vec2(1.0 / 8.0 + primitiveNdx / 4.0, 0.5);\n"
893 << " highp vec4 texColor = texture(u_sampler, texCoord);\n"
894 << " mediump int emitCount = 0;\n"
895 << " if (texColor.x > 0.0)\n"
896 << " emitCount += 6;\n"
897 << " if (texColor.y > 0.0)\n"
898 << " emitCount += 0;\n"
899 << " if (texColor.z > 0.0)\n"
900 << " emitCount += 128;\n"
901 << " if (texColor.w > 0.0)\n"
902 << " emitCount += 10;\n"
903 << " const highp vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
904 << " const highp vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
905 << " const highp vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);\n"
906 << " const highp vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
907 << " const highp vec4 colors[4] = vec4[4](red, green, blue, yellow);\n"
908 << " highp vec4 color = colors[int(primitiveNdx)];\n"
909 << " 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"
910 << " for (mediump int i = 0; i < emitCount / 2; i++)\n"
912 << " highp float angle = (float(i) + 0.5) / float(emitCount / 2) * 3.142;\n"
913 << " gl_Position = basePos + vec4(cos(angle), sin(angle), 0.0, 0.0) * 0.15;\n"
914 << " v_frag_FragColor = color;\n"
915 << " EmitVertex();\n"
916 << " gl_Position = basePos + vec4(cos(angle), -sin(angle), 0.0, 0.0) * 0.15;\n"
917 << " v_frag_FragColor = color;\n"
918 << " EmitVertex();\n"
926 sourceCollections.glslSources.add("geometry") << glu::GeometrySource(src.str());
930 std::ostringstream src;
931 src << "#version 310 es\n"
932 << "layout(location = 0) out mediump vec4 fragColor;\n"
933 << "layout(location = 0) in highp vec4 v_frag_FragColor;\n"
934 << "void main (void)\n"
936 << " fragColor = v_frag_FragColor;\n"
938 sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
942 TestInstance* VaryingOutputCountCase::createInstance (Context& context) const
944 return new VaryingOutputCountTestInstance (context, getName(), VK_PRIMITIVE_TOPOLOGY_POINT_LIST, m_test, m_mode);
947 class BuiltinVariableRenderTest : public TestCase
950 BuiltinVariableRenderTest (TestContext& testCtx,
953 const VariableTest test,
954 const bool flag = false);
955 void initPrograms (SourceCollections& sourceCollections) const;
956 virtual TestInstance* createInstance (Context& context) const;
958 const VariableTest m_test;
962 BuiltinVariableRenderTest::BuiltinVariableRenderTest (TestContext& testCtx, const char* name, const char* description, const VariableTest test, const bool flag)
963 : TestCase (testCtx, name, description)
969 void BuiltinVariableRenderTest::initPrograms (SourceCollections& sourceCollections) const
972 std::ostringstream src;
973 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
974 << "out gl_PerVertex\n"
976 << " vec4 gl_Position;\n"
977 << " float gl_PointSize;\n"
979 << "layout(location = 0) in vec4 a_position;\n";
982 case TEST_POINT_SIZE:
983 src << "layout(location = 1) in vec4 a_pointSize;\n"
984 << "layout(location = 0) out vec4 v_geom_pointSize;\n"
985 << "void main (void)\n"
987 << " gl_Position = a_position;\n"
988 << " gl_PointSize = 1.0;\n"
989 << " v_geom_pointSize = a_pointSize;\n"
992 case TEST_PRIMITIVE_ID_IN:
993 src << "void main (void)\n"
995 << " gl_Position = a_position;\n"
998 case TEST_PRIMITIVE_ID:
999 src << "layout(location = 1) in vec4 a_primitiveID;\n"
1000 << "layout(location = 0) out vec4 v_geom_primitiveID;\n"
1001 << "void main (void)\n"
1003 << " gl_Position = a_position;\n"
1004 << " v_geom_primitiveID = a_primitiveID;\n"
1011 sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
1015 std::ostringstream src;
1016 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1017 << "in gl_PerVertex\n"
1019 << " vec4 gl_Position;\n"
1020 << " float gl_PointSize;\n"
1022 << "out gl_PerVertex\n"
1024 << " vec4 gl_Position;\n"
1025 << " float gl_PointSize;\n"
1029 case TEST_POINT_SIZE:
1030 src << "#extension GL_EXT_geometry_point_size : require\n"
1031 << "layout(points) in;\n"
1032 << "layout(points, max_vertices = 1) out;\n"
1033 << "layout(location = 0) in vec4 v_geom_pointSize[];\n"
1034 << "layout(location = 0) out vec4 v_frag_FragColor;\n"
1035 << "void main (void)\n"
1037 << " gl_Position = gl_in[0].gl_Position;\n"
1038 << " gl_PointSize = v_geom_pointSize[0].x + 1.0;\n"
1039 << " v_frag_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
1040 << " EmitVertex();\n"
1043 case TEST_PRIMITIVE_ID_IN:
1044 src << "layout(lines) in;\n"
1045 << "layout(triangle_strip, max_vertices = 10) out;\n"
1046 << "layout(location = 0) out vec4 v_frag_FragColor;\n"
1047 << "void main (void)\n"
1049 << " const vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
1050 << " const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
1051 << " const vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);\n"
1052 << " const vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
1053 << " const vec4 colors[4] = vec4[4](red, green, blue, yellow);\n"
1054 << " for (float percent=0.00; percent < 0.30; percent+=0.10)\n"
1056 << " gl_Position = gl_in[0].gl_Position * vec4(1.0+percent, 1.0+percent, 1.0, 1.0);\n"
1057 << " v_frag_FragColor = colors[gl_PrimitiveIDIn % 4];\n"
1058 << " EmitVertex();\n"
1059 << " gl_Position = gl_in[1].gl_Position * vec4(1.0+percent, 1.0+percent, 1.0, 1.0);\n"
1060 << " v_frag_FragColor = colors[gl_PrimitiveIDIn % 4];\n"
1061 << " EmitVertex();\n"
1065 case TEST_PRIMITIVE_ID:
1066 src << "layout(points, invocations=1) in;\n"
1067 << "layout(triangle_strip, max_vertices = 3) out;\n"
1068 << "layout(location = 0) in vec4 v_geom_primitiveID[];\n"
1069 << "void main (void)\n"
1071 << " gl_Position = gl_in[0].gl_Position + vec4(0.05, 0.0, 0.0, 0.0);\n"
1072 << " gl_PrimitiveID = int(floor(v_geom_primitiveID[0].x)) + 3;\n"
1073 << " EmitVertex();\n"
1074 << " gl_Position = gl_in[0].gl_Position - vec4(0.05, 0.0, 0.0, 0.0);\n"
1075 << " gl_PrimitiveID = int(floor(v_geom_primitiveID[0].x)) + 3;\n"
1076 << " EmitVertex();\n"
1077 << " gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.05, 0.0, 0.0);\n"
1078 << " gl_PrimitiveID = int(floor(v_geom_primitiveID[0].x)) + 3;\n"
1079 << " EmitVertex();\n"
1086 sourceCollections.glslSources.add("geometry") << glu::GeometrySource(src.str());
1090 std::ostringstream src;
1091 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n";
1094 case TEST_POINT_SIZE:
1095 src << "layout(location = 0) out vec4 fragColor;\n"
1096 << "layout(location = 0) in vec4 v_frag_FragColor;\n"
1097 << "void main (void)\n"
1099 << " fragColor = v_frag_FragColor;\n"
1102 case TEST_PRIMITIVE_ID_IN:
1103 src << "layout(location = 0) out vec4 fragColor;\n"
1104 << "layout(location = 0) in vec4 v_frag_FragColor;\n"
1105 << "void main (void)\n"
1107 << " fragColor = v_frag_FragColor;\n"
1110 case TEST_PRIMITIVE_ID:
1111 src << "layout(location = 0) out vec4 fragColor;\n"
1112 << "void main (void)\n"
1114 << " const vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
1115 << " const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
1116 << " const vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);\n"
1117 << " const vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
1118 << " const vec4 colors[4] = vec4[4](yellow, red, green, blue);\n"
1119 << " fragColor = colors[gl_PrimitiveID % 4];\n"
1126 sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
1130 TestInstance* BuiltinVariableRenderTest::createInstance (Context& context) const
1132 if (m_test == TEST_POINT_SIZE && !checkPointSize(context.getInstanceInterface(), context.getPhysicalDevice()))
1133 TCU_THROW(NotSupportedError, "Missing feature: pointSize");
1134 return new BuiltinVariableRenderTestInstance(context, getName(), m_test, m_flag);
1137 inline vector<int> createPattern (int count)
1139 vector<int> pattern;
1140 pattern.push_back(count);
1144 inline vector<int> createPattern (int count0, int count1)
1146 vector<int> pattern;
1147 pattern.push_back(count0);
1148 pattern.push_back(count1);
1154 TestCaseGroup* createBasicGeometryShaderTests (TestContext& testCtx)
1156 MovePtr<TestCaseGroup> basicGroup (new tcu::TestCaseGroup(testCtx, "basic", "Basic tests."));
1158 basicGroup->addChild(new GeometryOutputCountTest (testCtx, "output_10", "Output 10 vertices", createPattern(10)));
1159 basicGroup->addChild(new GeometryOutputCountTest (testCtx, "output_128", "Output 128 vertices", createPattern(128)));
1160 basicGroup->addChild(new GeometryOutputCountTest (testCtx, "output_10_and_100", "Output 10 and 100 vertices in two invocations", createPattern(10, 100)));
1161 basicGroup->addChild(new GeometryOutputCountTest (testCtx, "output_100_and_10", "Output 100 and 10 vertices in two invocations", createPattern(100, 10)));
1162 basicGroup->addChild(new GeometryOutputCountTest (testCtx, "output_0_and_128", "Output 0 and 128 vertices in two invocations", createPattern(0, 128)));
1163 basicGroup->addChild(new GeometryOutputCountTest (testCtx, "output_128_and_0", "Output 128 and 0 vertices in two invocations", createPattern(128, 0)));
1165 basicGroup->addChild(new VaryingOutputCountCase (testCtx, "output_vary_by_attribute", "Output varying number of vertices", READ_ATTRIBUTE, MODE_WITHOUT_INSTANCING));
1166 basicGroup->addChild(new VaryingOutputCountCase (testCtx, "output_vary_by_uniform", "Output varying number of vertices", READ_UNIFORM, MODE_WITHOUT_INSTANCING));
1167 basicGroup->addChild(new VaryingOutputCountCase (testCtx, "output_vary_by_texture", "Output varying number of vertices", READ_TEXTURE, MODE_WITHOUT_INSTANCING));
1168 basicGroup->addChild(new VaryingOutputCountCase (testCtx, "output_vary_by_attribute_instancing", "Output varying number of vertices", READ_ATTRIBUTE, MODE_WITH_INSTANCING));
1169 basicGroup->addChild(new VaryingOutputCountCase (testCtx, "output_vary_by_uniform_instancing", "Output varying number of vertices", READ_UNIFORM, MODE_WITH_INSTANCING));
1170 basicGroup->addChild(new VaryingOutputCountCase (testCtx, "output_vary_by_texture_instancing", "Output varying number of vertices", READ_TEXTURE, MODE_WITH_INSTANCING));
1172 basicGroup->addChild(new BuiltinVariableRenderTest (testCtx, "point_size", "test gl_PointSize", TEST_POINT_SIZE));
1173 basicGroup->addChild(new BuiltinVariableRenderTest (testCtx, "primitive_id_in", "test gl_PrimitiveIDIn", TEST_PRIMITIVE_ID_IN));
1174 basicGroup->addChild(new BuiltinVariableRenderTest (testCtx, "primitive_id_in_restarted", "test gl_PrimitiveIDIn with primitive restart", TEST_PRIMITIVE_ID_IN, true));
1175 basicGroup->addChild(new BuiltinVariableRenderTest (testCtx, "primitive_id", "test gl_PrimitiveID", TEST_PRIMITIVE_ID));
1177 return basicGroup.release();