• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 Valve Corporation.
6  * Copyright (c) 2019 The Khronos Group Inc.
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 EXT_discard_rectangles tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktDrawDiscardRectanglesTests.hpp"
26 
27 #include "vkDefs.hpp"
28 #include "vkRef.hpp"
29 #include "vkRefUtil.hpp"
30 #include "vkTypeUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vktTestGroupUtil.hpp"
37 #include "vktTestCase.hpp"
38 #include "vktDrawBufferObjectUtil.hpp"
39 #include "vktDrawImageObjectUtil.hpp"
40 
41 #include "tcuTestCase.hpp"
42 #include "tcuVector.hpp"
43 #include "tcuTextureUtil.hpp"
44 #include "tcuTextureUtil.hpp"
45 #include "tcuImageCompare.hpp"
46 
47 #include "deUniquePtr.hpp"
48 #include "deSharedPtr.hpp"
49 
50 namespace vkt
51 {
52 namespace Draw
53 {
54 
55 namespace
56 {
57 using namespace vk;
58 using de::UniquePtr;
59 using de::SharedPtr;
60 using de::MovePtr;
61 using tcu::Vec4;
62 using tcu::Vec2;
63 using tcu::UVec2;
64 using tcu::UVec4;
65 
66 enum TestMode
67 {
68 	TEST_MODE_INCLUSIVE = 0,
69 	TEST_MODE_EXCLUSIVE,
70 	TEST_MODE_COUNT
71 };
72 
73 enum TestScissorMode
74 {
75 	TEST_SCISSOR_MODE_NONE = 0,
76 	TEST_SCISSOR_MODE_STATIC,
77 	TEST_SCISSOR_MODE_DYNAMIC,
78 	TEST_SCISSOR_MODE_COUNT
79 };
80 
81 #define NUM_RECT_TESTS 6
82 #define NUM_DYNAMIC_DISCARD_TYPE_TESTS 2
83 
84 struct TestParams
85 {
86 	TestMode				testMode;
87 	deUint32				numRectangles;
88 	deBool					dynamicDiscardRectangles;
89 	TestScissorMode			scissorMode;
90 	const SharedGroupParams	groupParams;
91 };
92 
93 template<typename T>
sizeInBytes(const std::vector<T> & vec)94 inline VkDeviceSize sizeInBytes(const std::vector<T>& vec)
95 {
96 	return vec.size() * sizeof(vec[0]);
97 }
98 
makeImageCreateInfo(const VkFormat format,const UVec2 & size,VkImageUsageFlags usage)99 VkImageCreateInfo makeImageCreateInfo (const VkFormat format, const UVec2& size, VkImageUsageFlags usage)
100 {
101 	const VkImageCreateInfo imageParams =
102 	{
103 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
104 		DE_NULL,										// const void*				pNext;
105 		(VkImageCreateFlags)0,							// VkImageCreateFlags		flags;
106 		VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
107 		format,											// VkFormat					format;
108 		makeExtent3D(size.x(), size.y(), 1),			// VkExtent3D				extent;
109 		1u,												// deUint32					mipLevels;
110 		1u,												// deUint32					arrayLayers;
111 		VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
112 		VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
113 		usage,											// VkImageUsageFlags		usage;
114 		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
115 		0u,												// deUint32					queueFamilyIndexCount;
116 		DE_NULL,										// const deUint32*			pQueueFamilyIndices;
117 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
118 	};
119 	return imageParams;
120 }
121 
makeDiscardRectangleStateCreateInfo(const deBool dynamicDiscardRectangle,const VkDiscardRectangleModeEXT discardRectangleMode,const deUint32 discardRectangleCount,const VkRect2D * pDiscardRectangles)122 VkPipelineDiscardRectangleStateCreateInfoEXT makeDiscardRectangleStateCreateInfo (const deBool						dynamicDiscardRectangle,
123 																				  const VkDiscardRectangleModeEXT	discardRectangleMode,
124 																				  const deUint32					discardRectangleCount,
125 																				  const VkRect2D					*pDiscardRectangles)
126 {
127 	const VkPipelineDiscardRectangleStateCreateInfoEXT discardRectanglesCreateInfo =
128 	{
129 		VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT,		// VkStructureType									sType;
130 		DE_NULL,																// const void*										pNext;
131 		0u,																		// VkPipelineDiscardRectangleStateCreateFlagsEXT	flags;
132 		discardRectangleMode,													// VkDiscardRectangleModeEXT						discardRectangleMode;
133 		discardRectangleCount,													// deUint32											discardRectangleCount;
134 		dynamicDiscardRectangle ? DE_NULL : pDiscardRectangles					// const VkRect2D*									pDiscardRectangles;
135 	};
136 	return discardRectanglesCreateInfo;
137 }
138 
makeGraphicsPipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkRenderPass renderPass,const VkShaderModule vertexModule,const VkShaderModule fragmentModule,const UVec2 renderSize,const deBool dynamicDiscardRectangle,const VkDiscardRectangleModeEXT discardRectangleMode,const deUint32 discardRectangleCount,const VkRect2D * pDiscardRectangles,const TestScissorMode scissorMode,const VkRect2D rectScissor)139 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&			vk,
140 									   const VkDevice					device,
141 									   const VkPipelineLayout			pipelineLayout,
142 									   const VkRenderPass				renderPass,
143 									   const VkShaderModule				vertexModule,
144 									   const VkShaderModule				fragmentModule,
145 									   const UVec2						renderSize,
146 									   const deBool						dynamicDiscardRectangle,
147 									   const VkDiscardRectangleModeEXT	discardRectangleMode,
148 									   const deUint32					discardRectangleCount,
149 									   const VkRect2D*					pDiscardRectangles,
150 									   const TestScissorMode			scissorMode,
151 									   const VkRect2D					rectScissor)
152 {
153 	const VkVertexInputBindingDescription vertexInputBindingDescription =
154 	{
155 		0u,								// uint32_t				binding;
156 		sizeof(Vec4),					// uint32_t				stride;
157 		VK_VERTEX_INPUT_RATE_VERTEX,	// VkVertexInputRate	inputRate;
158 	};
159 
160 	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
161 	{
162 		{
163 			0u,								// uint32_t			location;
164 			0u,								// uint32_t			binding;
165 			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat			format;
166 			0u,								// uint32_t			offset;
167 		},
168 	};
169 
170 	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
171 	{
172 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType								sType;
173 		DE_NULL,														// const void*									pNext;
174 		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags		flags;
175 		1u,																// uint32_t										vertexBindingDescriptionCount;
176 		&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*		pVertexBindingDescriptions;
177 		DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),			// uint32_t										vertexAttributeDescriptionCount;
178 		vertexInputAttributeDescriptions,								// const VkVertexInputAttributeDescription*		pVertexAttributeDescriptions;
179 	};
180 
181 	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
182 	{
183 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType								sType;
184 		DE_NULL,														// const void*									pNext;
185 		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags		flags;
186 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,							// VkPrimitiveTopology							topology;
187 		VK_FALSE,														// VkBool32										primitiveRestartEnable;
188 	};
189 
190 
191 	VkViewport		viewport				= makeViewport(0.0f, 0.0f, static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()), 0.0f, 1.0f);
192 	const VkRect2D	rectScissorRenderSize	= { { 0, 0 }, { renderSize.x(), renderSize.y() } };
193 
194 	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
195 	{
196 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,							// VkStructureType								sType;
197 		DE_NULL,																		// const void*									pNext;
198 		(VkPipelineViewportStateCreateFlags)0,											// VkPipelineViewportStateCreateFlags			flags;
199 		1u,																				// uint32_t										viewportCount;
200 		&viewport,																		// const VkViewport*							pViewports;
201 		1u,																				// uint32_t										scissorCount;
202 		scissorMode != TEST_SCISSOR_MODE_NONE ? &rectScissor : &rectScissorRenderSize,	// const VkRect2D*								pScissors;
203 	};
204 
205 	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
206 	{
207 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType								sType;
208 		DE_NULL,														// const void*									pNext;
209 		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags		flags;
210 		VK_FALSE,														// VkBool32										depthClampEnable;
211 		VK_FALSE,														// VkBool32										rasterizerDiscardEnable;
212 		VK_POLYGON_MODE_FILL,											// VkPolygonMode								polygonMode;
213 		VK_CULL_MODE_NONE,												// VkCullModeFlags								cullMode;
214 		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace									frontFace;
215 		VK_FALSE,														// VkBool32										depthBiasEnable;
216 		0.0f,															// float										depthBiasConstantFactor;
217 		0.0f,															// float										depthBiasClamp;
218 		0.0f,															// float										depthBiasSlopeFactor;
219 		1.0f,															// float										lineWidth;
220 	};
221 
222 	const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
223 	{
224 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType								sType;
225 		DE_NULL,														// const void*									pNext;
226 		(VkPipelineMultisampleStateCreateFlags)0,						// VkPipelineMultisampleStateCreateFlags		flags;
227 		VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits						rasterizationSamples;
228 		VK_FALSE,														// VkBool32										sampleShadingEnable;
229 		0.0f,															// float										minSampleShading;
230 		DE_NULL,														// const VkSampleMask*							pSampleMask;
231 		VK_FALSE,														// VkBool32										alphaToCoverageEnable;
232 		VK_FALSE														// VkBool32										alphaToOneEnable;
233 	};
234 
235 	const VkStencilOpState stencilOpState = makeStencilOpState(
236 		VK_STENCIL_OP_KEEP,				// stencil fail
237 		VK_STENCIL_OP_KEEP,				// depth & stencil pass
238 		VK_STENCIL_OP_KEEP,				// depth only fail
239 		VK_COMPARE_OP_ALWAYS,			// compare op
240 		0u,								// compare mask
241 		0u,								// write mask
242 		0u);							// reference
243 
244 	VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
245 	{
246 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,		// VkStructureType								sType;
247 		DE_NULL,														// const void*									pNext;
248 		(VkPipelineDepthStencilStateCreateFlags)0,						// VkPipelineDepthStencilStateCreateFlags		flags;
249 		VK_FALSE,														// VkBool32										depthTestEnable;
250 		VK_FALSE,														// VkBool32										depthWriteEnable;
251 		VK_COMPARE_OP_LESS,												// VkCompareOp									depthCompareOp;
252 		VK_FALSE,														// VkBool32										depthBoundsTestEnable;
253 		VK_FALSE,														// VkBool32										stencilTestEnable;
254 		stencilOpState,													// VkStencilOpState								front;
255 		stencilOpState,													// VkStencilOpState								back;
256 		0.0f,															// float										minDepthBounds;
257 		1.0f,															// float										maxDepthBounds;
258 	};
259 
260 	const VkColorComponentFlags					colorComponentsAll					= VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
261 	const VkPipelineColorBlendAttachmentState	pipelineColorBlendAttachmentState	=
262 	{
263 		VK_FALSE,						// VkBool32					blendEnable;
264 		VK_BLEND_FACTOR_ONE,			// VkBlendFactor			srcColorBlendFactor;
265 		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstColorBlendFactor;
266 		VK_BLEND_OP_ADD,				// VkBlendOp				colorBlendOp;
267 		VK_BLEND_FACTOR_ONE,			// VkBlendFactor			srcAlphaBlendFactor;
268 		VK_BLEND_FACTOR_ZERO,			// VkBlendFactor			dstAlphaBlendFactor;
269 		VK_BLEND_OP_ADD,				// VkBlendOp				alphaBlendOp;
270 		colorComponentsAll,				// VkColorComponentFlags	colorWriteMask;
271 	};
272 
273 	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
274 	{
275 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,		// VkStructureType								sType;
276 		DE_NULL,														// const void*									pNext;
277 		(VkPipelineColorBlendStateCreateFlags)0,						// VkPipelineColorBlendStateCreateFlags			flags;
278 		VK_FALSE,														// VkBool32										logicOpEnable;
279 		VK_LOGIC_OP_COPY,												// VkLogicOp									logicOp;
280 		1u,																// deUint32										attachmentCount;
281 		&pipelineColorBlendAttachmentState,								// const VkPipelineColorBlendAttachmentState*	pAttachments;
282 		{ 0.0f, 0.0f, 0.0f, 0.0f },										// float										blendConstants[4];
283 	};
284 
285 	const VkPipelineShaderStageCreateInfo pShaderStages[] =
286 	{
287 		{
288 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType								sType;
289 			DE_NULL,													// const void*									pNext;
290 			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags				flags;
291 			VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBits						stage;
292 			vertexModule,												// VkShaderModule								module;
293 			"main",														// const char*									pName;
294 			DE_NULL,													// const VkSpecializationInfo*					pSpecializationInfo;
295 		},
296 		{
297 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType								sType;
298 			DE_NULL,													// const void*									pNext;
299 			(VkPipelineShaderStageCreateFlags)0,						// VkPipelineShaderStageCreateFlags				flags;
300 			VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBits						stage;
301 			fragmentModule,												// VkShaderModule								module;
302 			"main",														// const char*									pName;
303 			DE_NULL,													// const VkSpecializationInfo*					pSpecializationInfo;
304 		},
305 	};
306 
307 	const VkPipelineDiscardRectangleStateCreateInfoEXT discardRectangleStateCreateInfo = makeDiscardRectangleStateCreateInfo(dynamicDiscardRectangle, discardRectangleMode, discardRectangleCount, pDiscardRectangles);
308 
309 	const VkDynamicState dynamicStateDiscardRectangles	= VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT;
310 	const VkDynamicState dynamicStateScissor			= VK_DYNAMIC_STATE_SCISSOR;
311 	std::vector<VkDynamicState> dynamicStates;
312 
313 	if (dynamicDiscardRectangle)
314 		dynamicStates.push_back(dynamicStateDiscardRectangles);
315 	if (scissorMode == TEST_SCISSOR_MODE_DYNAMIC)
316 		dynamicStates.push_back(dynamicStateScissor);
317 
318 	const VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo =
319 	{
320 		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,			// VkStructureType								sType;
321 		DE_NULL,														// const void*									pNext;
322 		0u,																// VkPipelineDynamicStateCreateFlags			flags;
323 		(deUint32)dynamicStates.size(),									// deUint32										dynamicStateCount;
324 		dynamicStates.data()											// const VkDynamicState*						pDynamicStates;
325 	};
326 
327 	VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
328 	{
329 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,				// VkStructureType									sType;
330 		&discardRectangleStateCreateInfo,								// const void*										pNext;
331 		(VkPipelineCreateFlags)0,										// VkPipelineCreateFlags							flags;
332 		2u,																// deUint32											stageCount;
333 		pShaderStages,													// const VkPipelineShaderStageCreateInfo*			pStages;
334 		&vertexInputStateInfo,											// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
335 		&pipelineInputAssemblyStateInfo,								// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
336 		DE_NULL,														// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
337 		&pipelineViewportStateInfo,										// const VkPipelineViewportStateCreateInfo*			pViewportState;
338 		&pipelineRasterizationStateInfo,								// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
339 		&pipelineMultisampleStateInfo,									// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
340 		&pipelineDepthStencilStateInfo,									// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
341 		&pipelineColorBlendStateInfo,									// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
342 		&pipelineDynamicStateCreateInfo,								// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
343 		pipelineLayout,													// VkPipelineLayout									layout;
344 		renderPass,														// VkRenderPass										renderPass;
345 		0u,																// deUint32											subpass;
346 		DE_NULL,														// VkPipeline										basePipelineHandle;
347 		0,																// deInt32											basePipelineIndex;
348 	};
349 
350 #ifndef CTS_USES_VULKANSC
351 	VkFormat colorAttachmentFormat = VK_FORMAT_R8G8B8A8_UNORM;
352 	vk::VkPipelineRenderingCreateInfoKHR renderingCreateInfo
353 	{
354 		VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
355 		&discardRectangleStateCreateInfo,
356 		0u,
357 		1u,
358 		&colorAttachmentFormat,
359 		VK_FORMAT_UNDEFINED,
360 		VK_FORMAT_UNDEFINED
361 	};
362 
363 	// when pipeline is created without render pass we are using dynamic rendering
364 	if (renderPass == DE_NULL)
365 		graphicsPipelineInfo.pNext = &renderingCreateInfo;
366 #endif // CTS_USES_VULKANSC
367 
368 	return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
369 }
370 
generateDiscardRectangles(const UVec2 & renderSize,deUint32 numRect,std::vector<VkRect2D> & rectangles)371 void generateDiscardRectangles(const UVec2& renderSize, deUint32 numRect, std::vector<VkRect2D>& rectangles)
372 {
373 	deUint32 cellHight = renderSize.y() - 10;
374 	deUint32 cellWidth = (renderSize.x() - 10) / (2 * numRect - 1);
375 
376 	DE_ASSERT(rectangles.size() == 0);
377 
378 	for (deUint32 i = 0; i < numRect; i++)
379 	{
380 		VkRect2D rect;
381 		rect.extent.height = cellHight;
382 		rect.extent.width = cellWidth;
383 		rect.offset.x = 5u + i * 2 * cellWidth;
384 		rect.offset.y = 5u;
385 		rectangles.push_back(rect);
386 	}
387 }
388 
389 //! Renders a colorful grid of rectangles.
generateReferenceImage(const tcu::TextureFormat format,const UVec2 & renderSize,const TestMode testMode,const Vec4 & color,const deUint32 numRectangles,const std::vector<VkRect2D> rectangles,const deBool enableScissor,const VkRect2D scissor)390 tcu::TextureLevel generateReferenceImage (const tcu::TextureFormat		format,
391 										  const UVec2&					renderSize,
392 										  const TestMode				testMode,
393 										  const Vec4&					color,
394 										  const deUint32				numRectangles,
395 										  const std::vector<VkRect2D>	rectangles,
396 										  const deBool					enableScissor,
397 										  const VkRect2D				scissor)
398 {
399 	tcu::TextureLevel	image(format, renderSize.x(), renderSize.y());
400 	const Vec4			rectColor	= testMode == TEST_MODE_INCLUSIVE ? Vec4(0.0f, 1.0f, 0.0f, 1.0f)	: color;
401 	const Vec4			clearColor	= testMode == TEST_MODE_INCLUSIVE ? color							: Vec4(0.0f, 1.0f, 0.0f, 1.0f);
402 
403 	if (!enableScissor)
404 	{
405 		// Clear the image with clearColor
406 		tcu::clear(image.getAccess(), clearColor);
407 
408 		// Now draw the discard rectangles taking into account the selected mode.
409 		for (deUint32 i = 0; i < numRectangles; i++)
410 		{
411 			tcu::clear(tcu::getSubregion(image.getAccess(), rectangles[i].offset.x, rectangles[i].offset.y,
412 										 rectangles[i].extent.width, rectangles[i].extent.height),
413 					   rectColor);
414 		}
415 	}
416 	else
417 	{
418 		// Clear the image with the original clear color
419 		tcu::clear(image.getAccess(), color);
420 		// Clear the scissor are with the clearColor which depends on the selected mode
421 		tcu::clear(tcu::getSubregion(image.getAccess(), scissor.offset.x, scissor.offset.y,
422 									 scissor.extent.width, scissor.extent.height),
423 				   clearColor);
424 
425 		// Now draw the discard rectangles taking into account both the scissor area and
426 		// the selected mode.
427 		for (deUint32 rect = 0; rect < numRectangles; rect++)
428 		{
429 			for (deUint32 x = rectangles[rect].offset.x; x < (rectangles[rect].offset.x + rectangles[rect].extent.width); x++)
430 			{
431 				for(deUint32 y = rectangles[rect].offset.y; y < (rectangles[rect].offset.y + rectangles[rect].extent.height); y++)
432 				{
433 					if ((x >= (deUint32)scissor.offset.x) && (x < (scissor.offset.x + scissor.extent.width)) &&
434 						(y >= (deUint32)scissor.offset.y) && (y < (scissor.offset.y + scissor.extent.height)))
435 					{
436 						image.getAccess().setPixel(rectColor, x, y);
437 					}
438 				}
439 			}
440 		}
441 	}
442 	return image;
443 }
444 
445 class DiscardRectanglesTestInstance : public TestInstance
446 {
447 public:
448 							DiscardRectanglesTestInstance		(Context& context,
449 																 TestParams params);
~DiscardRectanglesTestInstance(void)450 	virtual					~DiscardRectanglesTestInstance		(void) {}
451 	virtual tcu::TestStatus	iterate								(void);
452 
453 protected:
454 
455 	void					preRenderCommands					(VkCommandBuffer cmdBuffer) const;
456 	void					drawCommands						(VkCommandBuffer cmdBuffer, const VkRect2D& rectScissor) const;
457 
458 #ifndef CTS_USES_VULKANSC
459 	void					beginSecondaryCmdBuffer				(VkCommandBuffer cmdBuffer, VkFormat colorFormat, VkRenderingFlagsKHR renderingFlags = 0u) const;
460 #endif // CTS_USES_VULKANSC
461 
462 private:
463 	const TestParams			m_params;
464 	const Vec4					m_clearColor;
465 	const UVec2					m_renderSize;
466 	std::vector<Vec4>			m_vertices;
467 	std::vector<VkRect2D>		m_rectangles;
468 
469 	Move<VkImage>				m_colorImage;
470 	MovePtr<Allocation>			m_colorImageAlloc;
471 	Move<VkImageView>			m_colorAttachment;
472 	SharedPtr<Buffer>			m_colorBuffer;
473 	SharedPtr<Buffer>			m_vertexBuffer;
474 	Move<VkShaderModule>		m_vertexModule;
475 	Move<VkShaderModule>		m_fragmentModule;
476 	Move<VkRenderPass>			m_renderPass;
477 	Move<VkFramebuffer>			m_framebuffer;
478 	Move<VkPipelineLayout>		m_pipelineLayout;
479 	Move<VkPipeline>			m_pipeline;
480 	Move<VkCommandPool>			m_cmdPool;
481 	Move<VkCommandBuffer>		m_cmdBuffer;
482 	Move<VkCommandBuffer>		m_secCmdBuffer;
483 };
484 
DiscardRectanglesTestInstance(Context & context,TestParams params)485 DiscardRectanglesTestInstance::DiscardRectanglesTestInstance (Context& context,
486 															  TestParams params)
487 	: TestInstance	(context)
488 	, m_params		(params)
489 	, m_clearColor	(Vec4(1.0f, 0.0f, 0.0f, 1.0f))
490 	, m_renderSize	(UVec2(340, 100))
491 {
492 }
493 
iterate(void)494 tcu::TestStatus DiscardRectanglesTestInstance::iterate	(void)
495 {
496 	const DeviceInterface&			vk						= m_context.getDeviceInterface();
497 	const InstanceInterface&		vki						= m_context.getInstanceInterface();
498 	const VkPhysicalDevice			physicalDevice			= m_context.getPhysicalDevice();
499 	const VkDevice					device					= m_context.getDevice();
500 	const VkQueue					queue					= m_context.getUniversalQueue();
501 	const deUint32					queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
502 	Allocator&						allocator				= m_context.getDefaultAllocator();
503 	const VkDiscardRectangleModeEXT	discardRectangleMode	= m_params.testMode == TEST_MODE_EXCLUSIVE ? VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT : VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT;
504 	const VkRect2D					rectScissor				= { { 90, 25 }, { 160, 50} };
505 	const VkImageSubresourceRange	colorSubresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
506 	const VkFormat					colorFormat				= VK_FORMAT_R8G8B8A8_UNORM;
507 	const VkDeviceSize				colorBufferSize			= m_renderSize.x() * m_renderSize.y() * tcu::getPixelSize(mapVkFormat(colorFormat));
508 
509 	// Check for VK_EXT_discard_rectangles support and maximum number of active discard rectangles
510 	{
511 		VkPhysicalDeviceDiscardRectanglePropertiesEXT discardRectangleProperties;
512 		deMemset(&discardRectangleProperties, 0, sizeof(VkPhysicalDeviceDiscardRectanglePropertiesEXT));
513 		discardRectangleProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT;
514 
515 		VkPhysicalDeviceProperties2 physicalDeviceProperties;
516 		physicalDeviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
517 		physicalDeviceProperties.pNext = &discardRectangleProperties;
518 
519 		vki.getPhysicalDeviceProperties2(physicalDevice, &physicalDeviceProperties);
520 
521 		if (discardRectangleProperties.maxDiscardRectangles == 0)
522 		{
523 			throw tcu::NotSupportedError("Implementation doesn't support discard rectangles");
524 		}
525 
526 		if (discardRectangleProperties.maxDiscardRectangles < 4)
527 		{
528 			std::ostringstream message;
529 			message << "Implementation doesn't support the minimum value for maxDiscardRectangles: " << discardRectangleProperties.maxDiscardRectangles << " < 4";
530 			return tcu::TestStatus::fail(message.str());
531 		}
532 
533 		if (discardRectangleProperties.maxDiscardRectangles < m_params.numRectangles)
534 		{
535 			std::ostringstream message;
536 			message << "Implementation doesn't support the required number of discard rectangles: " << discardRectangleProperties.maxDiscardRectangles << " < " << m_params.numRectangles;
537 			throw tcu::NotSupportedError(message.str());
538 		}
539 	}
540 
541 	// Color attachment
542 	{
543 		m_colorImage		= makeImage(vk, device, makeImageCreateInfo(colorFormat, m_renderSize, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT));
544 		m_colorImageAlloc	= bindImage(vk, device, allocator, *m_colorImage, MemoryRequirement::Any);
545 		m_colorBuffer		= Buffer::createAndAlloc(vk, device, makeBufferCreateInfo(colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), allocator, MemoryRequirement::HostVisible);
546 		m_colorAttachment	= makeImageView(vk, device, *m_colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange);
547 
548 		// Zero colorBuffer.
549 		const Allocation alloc = m_colorBuffer->getBoundMemory();
550 		deMemset(alloc.getHostPtr(), 0, static_cast<std::size_t>(colorBufferSize));
551 		flushAlloc(vk, device, alloc);
552 	}
553 
554 	// Initialize the pipeline and other variables
555 	{
556 		// Draw a quad covering the whole framebuffer
557 		m_vertices.push_back(Vec4(-1.0f,  1.0f, 0.0f, 1.0f));
558 		m_vertices.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
559 		m_vertices.push_back(Vec4( 1.0f,  1.0f, 0.0f, 1.0f));
560 		m_vertices.push_back(Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
561 		VkDeviceSize vertexBufferSize	= sizeInBytes(m_vertices);
562 		m_vertexBuffer					= Buffer::createAndAlloc	(vk, device, makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), allocator, MemoryRequirement::HostVisible);
563 
564 
565 		deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), m_vertices.data(), static_cast<std::size_t>(vertexBufferSize));
566 		flushAlloc(vk, device, m_vertexBuffer->getBoundMemory());
567 
568 		m_vertexModule				= createShaderModule	(vk, device, m_context.getBinaryCollection().get("vert"), 0u);
569 		m_fragmentModule			= createShaderModule	(vk, device, m_context.getBinaryCollection().get("frag"), 0u);
570 
571 		if (!m_params.groupParams->useDynamicRendering)
572 		{
573 			m_renderPass			= makeRenderPass		(vk, device, colorFormat);
574 			m_framebuffer			= makeFramebuffer		(vk, device, *m_renderPass, m_colorAttachment.get(),
575 															 static_cast<deUint32>(m_renderSize.x()),
576 															 static_cast<deUint32>(m_renderSize.y()));
577 		}
578 
579 		m_pipelineLayout			= makePipelineLayout	(vk, device);
580 
581 		generateDiscardRectangles(m_renderSize, m_params.numRectangles, m_rectangles);
582 		m_pipeline					= makeGraphicsPipeline	(vk, device, *m_pipelineLayout, *m_renderPass, *m_vertexModule, *m_fragmentModule, m_renderSize,
583 															 m_params.dynamicDiscardRectangles, discardRectangleMode, m_params.numRectangles,
584 															 m_rectangles.data(), m_params.scissorMode, rectScissor);
585 		m_cmdPool					= createCommandPool		(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
586 		m_cmdBuffer					= allocateCommandBuffer	(vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
587 	}
588 
589 	const VkClearValue			clearValue = makeClearValueColor(m_clearColor);
590 	const VkRect2D				renderArea
591 	{
592 		makeOffset2D(0, 0),
593 		makeExtent2D(m_renderSize.x(), m_renderSize.y()),
594 	};
595 
596 	// Write command buffers and submit it
597 
598 #ifndef CTS_USES_VULKANSC
599 	if (m_params.groupParams->useSecondaryCmdBuffer)
600 	{
601 		m_secCmdBuffer = allocateCommandBuffer(vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
602 
603 		// record secondary command buffer
604 		if (m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
605 		{
606 			beginSecondaryCmdBuffer(*m_secCmdBuffer, colorFormat, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
607 			beginRendering(vk, *m_secCmdBuffer, *m_colorAttachment, renderArea, clearValue,
608 						   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ATTACHMENT_LOAD_OP_CLEAR);
609 		}
610 		else
611 			beginSecondaryCmdBuffer(*m_secCmdBuffer, colorFormat);
612 
613 		drawCommands(*m_secCmdBuffer, rectScissor);
614 
615 		if (m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
616 			vk.cmdEndRendering(*m_secCmdBuffer);
617 
618 		endCommandBuffer(vk, *m_secCmdBuffer);
619 
620 		// record primary command buffer
621 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
622 		preRenderCommands(*m_cmdBuffer);
623 
624 		if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
625 			beginRendering(vk, *m_cmdBuffer, *m_colorAttachment, renderArea, clearValue, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
626 						   VK_ATTACHMENT_LOAD_OP_CLEAR, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
627 
628 		vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer);
629 
630 		if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
631 			vk.cmdEndRendering(*m_cmdBuffer);
632 	}
633 	else if (m_params.groupParams->useDynamicRendering)
634 	{
635 		beginCommandBuffer(vk, *m_cmdBuffer);
636 
637 		preRenderCommands(*m_cmdBuffer);
638 		beginRendering(vk, *m_cmdBuffer, *m_colorAttachment, renderArea, clearValue,
639 					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ATTACHMENT_LOAD_OP_CLEAR);
640 		drawCommands(*m_cmdBuffer, rectScissor);
641 		vk.cmdEndRendering(*m_cmdBuffer);
642 	}
643 #endif // CTS_USES_VULKANSC
644 
645 	if (!m_params.groupParams->useDynamicRendering)
646 	{
647 		const VkRenderPassBeginInfo renderPassBeginInfo
648 		{
649 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType			sType;
650 			DE_NULL,										// const void*				pNext;
651 			*m_renderPass,									// VkRenderPass				renderPass;
652 			*m_framebuffer,									// VkFramebuffer			framebuffer;
653 			renderArea,										// VkRect2D					renderArea;
654 			1u,												// uint32_t					clearValueCount;
655 			&clearValue,									// const VkClearValue*		pClearValues;
656 		};
657 
658 		beginCommandBuffer(vk, *m_cmdBuffer);
659 
660 		preRenderCommands(*m_cmdBuffer);
661 		vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
662 		drawCommands(*m_cmdBuffer, rectScissor);
663 		vk.cmdEndRenderPass(*m_cmdBuffer);
664 	}
665 
666 	copyImageToBuffer(vk, *m_cmdBuffer, *m_colorImage, m_colorBuffer->object(), tcu::IVec2(m_renderSize.x(), m_renderSize.y()), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, colorSubresourceRange.layerCount);
667 	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
668 
669 	submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
670 
671 	// Verify results
672 	{
673 		const Allocation alloc = m_colorBuffer->getBoundMemory();
674 		invalidateAlloc(vk, device, alloc);
675 
676 		const tcu::ConstPixelBufferAccess	resultImage		(mapVkFormat(colorFormat), m_renderSize.x(), m_renderSize.y(), 1u, alloc.getHostPtr());
677 		const tcu::TextureLevel				referenceImage	= generateReferenceImage(mapVkFormat(colorFormat), m_renderSize, m_params.testMode, m_clearColor,
678 																					 m_params.numRectangles, m_rectangles, m_params.scissorMode != TEST_SCISSOR_MODE_NONE, rectScissor);
679 		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceImage.getAccess(), resultImage, Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
680 			TCU_FAIL("Rendered image is not correct");
681 	}
682 	return tcu::TestStatus::pass("OK");
683 }
684 
preRenderCommands(vk::VkCommandBuffer cmdBuffer) const685 void DiscardRectanglesTestInstance::preRenderCommands(vk::VkCommandBuffer cmdBuffer) const
686 {
687 	if (!m_params.groupParams->useDynamicRendering)
688 		return;
689 
690 	const DeviceInterface& vk = m_context.getDeviceInterface();
691 	initialTransitionColor2DImage(vk, cmdBuffer, *m_colorImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
692 								  VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
693 }
694 
drawCommands(vk::VkCommandBuffer cmdBuffer,const VkRect2D & rectScissor) const695 void DiscardRectanglesTestInstance::drawCommands(vk::VkCommandBuffer cmdBuffer, const VkRect2D& rectScissor) const
696 {
697 	const DeviceInterface& vk = m_context.getDeviceInterface();
698 	vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
699 	{
700 		const VkBuffer vertexBuffer = m_vertexBuffer->object();
701 		const VkDeviceSize vertexBufferOffset = 0ull;
702 		vk.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
703 	}
704 	if (m_params.dynamicDiscardRectangles)
705 	{
706 		vk.cmdSetDiscardRectangleEXT(cmdBuffer, 0u, m_params.numRectangles, m_rectangles.data());
707 	}
708 	if (m_params.scissorMode == TEST_SCISSOR_MODE_DYNAMIC)
709 	{
710 		vk.cmdSetScissor(cmdBuffer, 0u, 1u, &rectScissor);
711 	}
712 	vk.cmdDraw(cmdBuffer, static_cast<deUint32>(m_vertices.size()), 1u, 0u, 0u);	// two triangles
713 }
714 
715 #ifndef CTS_USES_VULKANSC
beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer,VkFormat colorFormat,VkRenderingFlagsKHR renderingFlags) const716 void DiscardRectanglesTestInstance::beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer, VkFormat colorFormat, VkRenderingFlagsKHR renderingFlags) const
717 {
718 	VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
719 	{
720 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR,		// VkStructureType					sType;
721 		DE_NULL,																// const void*						pNext;
722 		renderingFlags,															// VkRenderingFlagsKHR				flags;
723 		0u,																		// uint32_t							viewMask;
724 		1u,																		// uint32_t							colorAttachmentCount;
725 		&colorFormat,															// const VkFormat*					pColorAttachmentFormats;
726 		VK_FORMAT_UNDEFINED,													// VkFormat							depthAttachmentFormat;
727 		VK_FORMAT_UNDEFINED,													// VkFormat							stencilAttachmentFormat;
728 		VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits			rasterizationSamples;
729 	};
730 	const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
731 
732 	VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
733 	if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
734 		usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
735 
736 	const VkCommandBufferBeginInfo commandBufBeginParams
737 	{
738 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,							// VkStructureType					sType;
739 		DE_NULL,																// const void*						pNext;
740 		usageFlags,																// VkCommandBufferUsageFlags		flags;
741 		&bufferInheritanceInfo
742 	};
743 
744 	const DeviceInterface& vk = m_context.getDeviceInterface();
745 	VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &commandBufBeginParams));
746 }
747 #endif // CTS_USES_VULKANSC
748 
749 class DiscardRectanglesTestCase : public TestCase
750 {
751 public:
752 								DiscardRectanglesTestCase	(tcu::TestContext &context,
753 															 const char *name,
754 															 const char *description,
755 															 TestParams params);
~DiscardRectanglesTestCase(void)756 	virtual						~DiscardRectanglesTestCase	(void) {}
757 
758 	virtual TestInstance*		createInstance				(Context& context)	const;
759 	virtual void				initPrograms				(SourceCollections& programCollection) const;
760 	virtual void				checkSupport				(Context& context) const;
761 
762 private:
763 	const TestParams			m_params;
764 };
765 
DiscardRectanglesTestCase(tcu::TestContext & context,const char * name,const char * description,TestParams params)766 DiscardRectanglesTestCase::DiscardRectanglesTestCase	(tcu::TestContext &context,
767 														 const char *name,
768 														 const char *description,
769 														 TestParams params)
770 	: TestCase		(context, name, description)
771 	, m_params		(params)
772 {
773 }
774 
initPrograms(SourceCollections & programCollection) const775 void DiscardRectanglesTestCase::initPrograms(SourceCollections& programCollection) const
776 {
777 	// Vertex
778 	{
779 		std::ostringstream src;
780 		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
781 			<< "\n"
782 			<< "layout(location = 0) in highp vec4 position;\n"
783 			<< "layout(location = 0) out highp vec4 vsColor;\n"
784 			<< "\n"
785 			<< "out gl_PerVertex {\n"
786 			<< "   vec4 gl_Position;\n"
787 			<< "};\n"
788 			<< "\n"
789 			<< "void main (void)\n"
790 			<< "{\n"
791 			<< "    gl_Position = position;\n"
792 			<< "    vsColor     = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
793 			<< "}\n";
794 		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
795 	}
796 
797 	// Fragment
798 	{
799 		std::ostringstream src;
800 		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
801 			<< "\n"
802 			<< "layout(location = 0) in highp vec4 vsColor;\n"
803 			<< "layout(location = 0) out highp vec4 fsColor;\n"
804 			<< "\n"
805 			<< "void main (void)\n"
806 			<< "{\n"
807 			<< "    fsColor     = vsColor;\n"
808 			<< "}\n";
809 		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
810 	}
811 }
812 
checkSupport(Context & context) const813 void DiscardRectanglesTestCase::checkSupport (Context& context) const
814 {
815 	context.requireDeviceFunctionality("VK_EXT_discard_rectangles");
816 	if (m_params.groupParams->useDynamicRendering)
817 		context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
818 }
819 
createInstance(Context & context) const820 TestInstance* DiscardRectanglesTestCase::createInstance (Context& context) const
821 {
822 	return new DiscardRectanglesTestInstance(context, m_params);
823 }
824 
createTests(tcu::TestCaseGroup * testGroup,const SharedGroupParams groupParams)825 void createTests (tcu::TestCaseGroup* testGroup, const SharedGroupParams groupParams)
826 {
827 	tcu::TestContext&	testCtx											= testGroup->getTestContext();
828 	deUint32			numRect [NUM_RECT_TESTS]						= { 1, 2, 3, 4,  8, 16};
829 	std::string			modeName [TEST_MODE_COUNT]						= { "inclusive_", "exclusive_" };
830 	std::string			scissorName [TEST_SCISSOR_MODE_COUNT]			= { "", "scissor_", "dynamic_scissor_" };
831 	std::string			dynamicName [NUM_DYNAMIC_DISCARD_TYPE_TESTS]	= { "", "dynamic_discard_" };
832 
833 	for (deUint32 dynamic = 0 ; dynamic < NUM_DYNAMIC_DISCARD_TYPE_TESTS; dynamic++)
834 	{
835 		for (deUint32 scissor = 0 ; scissor < TEST_SCISSOR_MODE_COUNT; scissor++)
836 		{
837 			for (deUint32 mode = 0; mode < TEST_MODE_COUNT; mode++)
838 			{
839 				for (deUint32 rect = 0; rect < NUM_RECT_TESTS; rect++)
840 				{
841 					std::ostringstream	name;
842 					TestParams			params
843 					{
844 						(TestMode)mode,						// TestMode					testMode;
845 						numRect[rect],						// deUint32					numRectangles;
846 						dynamic ? DE_TRUE : DE_FALSE,		// deBool					dynamicDiscardRectangles;
847 						(TestScissorMode)scissor,			// TestScissorMode			scissorMode;
848 						groupParams,						// const SharedGroupParams	groupParams;
849 					};
850 
851 					name << dynamicName[dynamic] << scissorName[scissor] << modeName[mode] << "rect_" << numRect[rect];
852 
853 					testGroup->addChild(new DiscardRectanglesTestCase(testCtx, name.str().c_str(), "", params));
854 				}
855 			}
856 		}
857 	}
858 }
859 }	// Anonymous
860 
createDiscardRectanglesTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)861 tcu::TestCaseGroup* createDiscardRectanglesTests (tcu::TestContext& testCtx, const SharedGroupParams groupParams)
862 {
863 	return createTestGroup(testCtx, "discard_rectangles", "Discard Rectangles tests", createTests, groupParams);
864 }
865 
866 }	// Draw
867 }	//vkt
868