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