• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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