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