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