/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Negative viewport height (part of VK_KHR_maintenance1)
 *//*--------------------------------------------------------------------*/

#include "vktDrawNegativeViewportHeightTests.hpp"
#include "vktDrawCreateInfoUtil.hpp"
#include "vktDrawImageObjectUtil.hpp"
#include "vktDrawBufferObjectUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCaseUtil.hpp"

#include "vkPrograms.hpp"
#include "vkTypeUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkCmdUtil.hpp"

#include "tcuVector.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuTestLog.hpp"

#include "deSharedPtr.hpp"

namespace vkt
{
namespace Draw
{
namespace
{
using namespace vk;
using tcu::Vec4;
using de::SharedPtr;
using de::MovePtr;

enum Constants
{
	WIDTH	= 256,
	HEIGHT	= WIDTH/2,
};

struct TestParams
{
	VkFrontFace			frontFace;
	VkCullModeFlagBits	cullMode;
	bool				zeroViewportHeight;
	bool				useDynamicRendering;
};

class NegativeViewportHeightTestInstance : public TestInstance
{
public:
									NegativeViewportHeightTestInstance	(Context& context, const TestParams& params);
	tcu::TestStatus					iterate								(void);
	tcu::ConstPixelBufferAccess		draw								(const VkViewport viewport);
	MovePtr<tcu::TextureLevel>		generateReferenceImage				(void) const;
	bool							isCulled							(const VkFrontFace triangleFace) const;

private:
	const TestParams				m_params;
	const VkFormat					m_colorAttachmentFormat;
	SharedPtr<Image>				m_colorTargetImage;
	Move<VkImageView>				m_colorTargetView;
	SharedPtr<Buffer>				m_vertexBuffer;
	Move<VkRenderPass>				m_renderPass;
	Move<VkFramebuffer>				m_framebuffer;
	Move<VkPipelineLayout>			m_pipelineLayout;
	Move<VkPipeline>				m_pipeline;
};

NegativeViewportHeightTestInstance::NegativeViewportHeightTestInstance (Context& context, const TestParams& params)
	: TestInstance				(context)
	, m_params					(params)
	, m_colorAttachmentFormat	(VK_FORMAT_R8G8B8A8_UNORM)
{
	const DeviceInterface&	vk		= m_context.getDeviceInterface();
	const VkDevice			device	= m_context.getDevice();

	// Vertex data
	{
		std::vector<Vec4> vertexData;

		// CCW triangle
		vertexData.push_back(Vec4(-0.8f, -0.6f, 0.0f, 1.0f));	//  0-----2
		vertexData.push_back(Vec4(-0.8f,  0.6f, 0.0f, 1.0f));	//   |  /
		vertexData.push_back(Vec4(-0.2f, -0.6f, 0.0f, 1.0f));	//  1|/

		// CW triangle
		vertexData.push_back(Vec4( 0.2f, -0.6f, 0.0f, 1.0f));	//  0-----1
		vertexData.push_back(Vec4( 0.8f, -0.6f, 0.0f, 1.0f));	//    \  |
		vertexData.push_back(Vec4( 0.8f,  0.6f, 0.0f, 1.0f));	//      \|2

		const VkDeviceSize dataSize = vertexData.size() * sizeof(Vec4);
		m_vertexBuffer = Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
												m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);

		deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), &vertexData[0], static_cast<std::size_t>(dataSize));
		flushMappedMemoryRange(vk, device, m_vertexBuffer->getBoundMemory().getMemory(), m_vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
	}

	const VkExtent3D		targetImageExtent		= { WIDTH, HEIGHT, 1 };
	const VkImageUsageFlags	targetImageUsageFlags	= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;

	const ImageCreateInfo	targetImageCreateInfo(
		VK_IMAGE_TYPE_2D,						// imageType,
		m_colorAttachmentFormat,				// format,
		targetImageExtent,						// extent,
		1u,										// mipLevels,
		1u,										// arrayLayers,
		VK_SAMPLE_COUNT_1_BIT,					// samples,
		VK_IMAGE_TILING_OPTIMAL,				// tiling,
		targetImageUsageFlags);					// usage,

	m_colorTargetImage = Image::createAndAlloc(vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());

	const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
	m_colorTargetView = createImageView(vk, device, &colorTargetViewInfo);

	// Render pass and framebuffer
	if (!m_params.useDynamicRendering)
	{
		RenderPassCreateInfo	renderPassCreateInfo;
		renderPassCreateInfo.addAttachment(AttachmentDescription(
			m_colorAttachmentFormat,				// format
			VK_SAMPLE_COUNT_1_BIT,					// samples
			VK_ATTACHMENT_LOAD_OP_LOAD,				// loadOp
			VK_ATTACHMENT_STORE_OP_STORE,			// storeOp
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,		// stencilLoadOp
			VK_ATTACHMENT_STORE_OP_DONT_CARE,		// stencilStoreOp
			VK_IMAGE_LAYOUT_GENERAL,				// initialLayout
			VK_IMAGE_LAYOUT_GENERAL));				// finalLayout

		const VkAttachmentReference colorAttachmentReference =
		{
			0u,
			VK_IMAGE_LAYOUT_GENERAL
		};

		renderPassCreateInfo.addSubpass(SubpassDescription(
			VK_PIPELINE_BIND_POINT_GRAPHICS,		// pipelineBindPoint
			(VkSubpassDescriptionFlags)0,			// flags
			0u,										// inputAttachmentCount
			DE_NULL,								// inputAttachments
			1u,										// colorAttachmentCount
			&colorAttachmentReference,				// colorAttachments
			DE_NULL,								// resolveAttachments
			AttachmentReference(),					// depthStencilAttachment
			0u,										// preserveAttachmentCount
			DE_NULL));								// preserveAttachments

		m_renderPass = createRenderPass(vk, device, &renderPassCreateInfo);

		std::vector<VkImageView>		colorAttachments		{ *m_colorTargetView };
		const FramebufferCreateInfo		framebufferCreateInfo	(*m_renderPass, colorAttachments, WIDTH, HEIGHT, 1);
		m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
	}

	// Vertex input

	const VkVertexInputBindingDescription		vertexInputBindingDescription =
	{
		0u,										// uint32_t             binding;
		sizeof(Vec4),							// uint32_t             stride;
		VK_VERTEX_INPUT_RATE_VERTEX,			// VkVertexInputRate    inputRate;
	};

	const VkVertexInputAttributeDescription		vertexInputAttributeDescription =
	{
		0u,										// uint32_t    location;
		0u,										// uint32_t    binding;
		VK_FORMAT_R32G32B32A32_SFLOAT,			// VkFormat    format;
		0u										// uint32_t    offset;
	};

	const PipelineCreateInfo::VertexInputState	vertexInputState = PipelineCreateInfo::VertexInputState(1, &vertexInputBindingDescription,
																										1, &vertexInputAttributeDescription);

	// Graphics pipeline

	const VkRect2D scissor = makeRect2D(WIDTH, HEIGHT);

	std::vector<VkDynamicState>		dynamicStates;
	dynamicStates.push_back(VK_DYNAMIC_STATE_VIEWPORT);

	const Unique<VkShaderModule>	vertexModule	(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
	const Unique<VkShaderModule>	fragmentModule	(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));

	const PipelineLayoutCreateInfo	pipelineLayoutCreateInfo;
	m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);

	const PipelineCreateInfo::ColorBlendState::Attachment colorBlendAttachmentState;

	PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vertexModule,   "main", VK_SHADER_STAGE_VERTEX_BIT));
	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fragmentModule, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
	pipelineCreateInfo.addState (PipelineCreateInfo::VertexInputState	(vertexInputState));
	pipelineCreateInfo.addState (PipelineCreateInfo::InputAssemblerState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
	pipelineCreateInfo.addState (PipelineCreateInfo::ColorBlendState	(1, &colorBlendAttachmentState));
	pipelineCreateInfo.addState (PipelineCreateInfo::ViewportState		(1, std::vector<VkViewport>(), std::vector<VkRect2D>(1, scissor)));
	pipelineCreateInfo.addState (PipelineCreateInfo::DepthStencilState	());
	pipelineCreateInfo.addState (PipelineCreateInfo::RasterizerState	(
		VK_FALSE,					// depthClampEnable
		VK_FALSE,					// rasterizerDiscardEnable
		VK_POLYGON_MODE_FILL,		// polygonMode
		m_params.cullMode,			// cullMode
		m_params.frontFace,			// frontFace
		VK_FALSE,					// depthBiasEnable
		0.0f,						// depthBiasConstantFactor
		0.0f,						// depthBiasClamp
		0.0f,						// depthBiasSlopeFactor
		1.0f));						// lineWidth
	pipelineCreateInfo.addState (PipelineCreateInfo::MultiSampleState	());
	pipelineCreateInfo.addState (PipelineCreateInfo::DynamicState		(dynamicStates));

	vk::VkPipelineRenderingCreateInfoKHR renderingCreateInfo
	{
		vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
		DE_NULL,
		0u,
		1u,
		&m_colorAttachmentFormat,
		vk::VK_FORMAT_UNDEFINED,
		vk::VK_FORMAT_UNDEFINED
	};

	if (m_params.useDynamicRendering)
		pipelineCreateInfo.pNext = &renderingCreateInfo;

	m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
}

tcu::ConstPixelBufferAccess NegativeViewportHeightTestInstance::draw (const VkViewport viewport)
{
	const DeviceInterface&	vk					= m_context.getDeviceInterface();
	const VkDevice			device				= m_context.getDevice();
	const VkQueue			queue				= m_context.getUniversalQueue();
	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	const VkClearValue		clearColor			= makeClearValueColorF32(0.125f, 0.25f, 0.5f, 1.0f);

	// Command buffer

	const CmdPoolCreateInfo			cmdPoolCreateInfo	(queueFamilyIndex);
	const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, &cmdPoolCreateInfo));
	const Unique<VkCommandBuffer>	cmdBuffer			(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	// Draw

	beginCommandBuffer(vk, *cmdBuffer);

	vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &viewport);

	{
		const ImageSubresourceRange subresourceRange	(VK_IMAGE_ASPECT_COLOR_BIT);

		initialTransitionColor2DImage(vk, *cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_LAYOUT_GENERAL,
									  VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
		vk.cmdClearColorImage(*cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &subresourceRange);
	}

	if (m_params.zeroViewportHeight)
	{
		// Set zero viewport height
		const VkViewport zeroViewportHeight =
		{
			viewport.x,			// float    x;
			viewport.y / 2.0f,	// float    y;
			viewport.width,		// float    width;
			0.0f,				// float    height;
			viewport.minDepth,	// float    minDepth;
			viewport.maxDepth	// float    maxDepth;
		};

		vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &zeroViewportHeight);
	}

	{
		const VkMemoryBarrier memBarrier =
		{
			VK_STRUCTURE_TYPE_MEMORY_BARRIER,												// VkStructureType    sType;
			DE_NULL,																		// const void*        pNext;
			VK_ACCESS_TRANSFER_WRITE_BIT,													// VkAccessFlags      srcAccessMask;
			VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT		// VkAccessFlags      dstAccessMask;
		};

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
	}

	VkRect2D rect = makeRect2D(0, 0, WIDTH, HEIGHT);
	if (m_params.useDynamicRendering)
		beginRendering(vk, *cmdBuffer, *m_colorTargetView, rect, clearColor);
	else
		beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, rect);

	{
		const VkDeviceSize	offset	= 0;
		const VkBuffer		buffer	= m_vertexBuffer->object();

		vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &buffer, &offset);
	}

	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
	vk.cmdDraw(*cmdBuffer, 6, 1, 0, 0);

	if (m_params.useDynamicRendering)
		endRendering(vk, *cmdBuffer);
	else
		endRenderPass(vk, *cmdBuffer);

	endCommandBuffer(vk, *cmdBuffer);

	// Submit
	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());

	// Get result
	{
		const VkOffset3D zeroOffset = { 0, 0, 0 };
		return m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, VK_IMAGE_ASPECT_COLOR_BIT);
	}
}

//! Determine if a triangle with triangleFace orientation will be culled or not
bool NegativeViewportHeightTestInstance::isCulled (const VkFrontFace triangleFace) const
{
	const bool isFrontFacing = (triangleFace == m_params.frontFace);

	if (m_params.cullMode == VK_CULL_MODE_FRONT_BIT && isFrontFacing)
		return true;
	if (m_params.cullMode == VK_CULL_MODE_BACK_BIT  && !isFrontFacing)
		return true;

	return m_params.cullMode == VK_CULL_MODE_FRONT_AND_BACK;
}

MovePtr<tcu::TextureLevel> NegativeViewportHeightTestInstance::generateReferenceImage (void) const
{
	DE_ASSERT(HEIGHT == WIDTH/2);

	MovePtr<tcu::TextureLevel>		image	(new tcu::TextureLevel(mapVkFormat(m_colorAttachmentFormat), WIDTH, HEIGHT));
	const tcu::PixelBufferAccess	access	(image->getAccess());
	const Vec4						blue	(0.125f, 0.25f, 0.5f, 1.0f);
	const Vec4						white	(1.0f);
	const Vec4						gray	(0.5f, 0.5f, 0.5f, 1.0f);

	tcu::clear(access, blue);

	// Zero viewport height
	if (m_params.zeroViewportHeight)
	{
		return image;
	}
	// Negative viewport height
	else
	{
		const int p1 =      static_cast<int>(static_cast<float>(HEIGHT) * (1.0f - 0.6f) / 2.0f);
		const int p2 = p1 + static_cast<int>(static_cast<float>(HEIGHT) * (2.0f * 0.6f) / 2.0f);

		// left triangle (CCW -> CW after y-flip)
		if (!isCulled(VK_FRONT_FACE_CLOCKWISE))
		{
			const Vec4& color = (m_params.frontFace == VK_FRONT_FACE_CLOCKWISE ? white : gray);

			for (int y = p1; y <= p2; ++y)
			for (int x = p1; x <  y;  ++x)
				access.setPixel(color, x, y);
		}

		// right triangle (CW -> CCW after y-flip)
		if (!isCulled(VK_FRONT_FACE_COUNTER_CLOCKWISE))
		{
			const Vec4& color = (m_params.frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE ? white : gray);

			for (int y = p1;        y <= p2;          ++y)
			for (int x = WIDTH - y; x <  p2 + HEIGHT; ++x)
				access.setPixel(color, x, y);
		}

		return image;
	}
}

std::string getCullModeStr (const VkCullModeFlagBits cullMode)
{
	// Cull mode flags are a bit special, because there's a meaning to 0 and or'ed flags.
	// The function getCullModeFlagsStr() doesn't work too well in this case.

	switch (cullMode)
	{
		case VK_CULL_MODE_NONE:				return "VK_CULL_MODE_NONE";
		case VK_CULL_MODE_FRONT_BIT:		return "VK_CULL_MODE_FRONT_BIT";
		case VK_CULL_MODE_BACK_BIT:			return "VK_CULL_MODE_BACK_BIT";
		case VK_CULL_MODE_FRONT_AND_BACK:	return "VK_CULL_MODE_FRONT_AND_BACK";

		default:
			DE_ASSERT(0);
			return std::string();
	}
}

tcu::TestStatus NegativeViewportHeightTestInstance::iterate (void)
{
	// Set up the viewport and draw

	const VkViewport viewport =
	{
		0.0f,							// float    x;
		static_cast<float>(HEIGHT),		// float    y;
		static_cast<float>(WIDTH),		// float    width;
		-static_cast<float>(HEIGHT),	// float    height;
		0.0f,							// float    minDepth;
		1.0f,							// float    maxDepth;
	};

	const tcu::ConstPixelBufferAccess	resultImage	= draw(viewport);

	// Verify the results

	tcu::TestLog&				log				= m_context.getTestContext().getLog();
	MovePtr<tcu::TextureLevel>	referenceImage	= generateReferenceImage();

	// Zero viewport height
	if (m_params.zeroViewportHeight)
	{
		log << tcu::TestLog::Message
			<< "Drawing two triangles with zero viewport height."
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message
			<< "Result image should be empty."
			<< tcu::TestLog::EndMessage;
	}
	// Negative viewport height
	else
	{
		log << tcu::TestLog::Message
			<< "Drawing two triangles with negative viewport height, which will cause a y-flip. This changes the sign of the triangle's area."
			<< tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message
			<< "After the flip, the triangle on the left is CW and the triangle on the right is CCW. Right angles of the both triangles should be at the bottom of the image."
			<< " Front face is white, back face is gray."
			<< tcu::TestLog::EndMessage;
	}

	log << tcu::TestLog::Message
		<< "Front face: " << getFrontFaceName(m_params.frontFace) << "\n"
		<< "Cull mode: "  << getCullModeStr  (m_params.cullMode)  << "\n"
		<< tcu::TestLog::EndMessage;

	if (!tcu::fuzzyCompare(log, "Image compare", "Image compare", referenceImage->getAccess(), resultImage, 0.02f, tcu::COMPARE_LOG_RESULT))
		return tcu::TestStatus::fail("Rendered image is incorrect");
	else
		return tcu::TestStatus::pass("Pass");
}

class NegativeViewportHeightTest : public TestCase
{
public:
	NegativeViewportHeightTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
		: TestCase	(testCtx, name, description)
		, m_params	(params)
	{
	}

	void initPrograms (SourceCollections& programCollection) const
	{
		// Vertex shader
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(location = 0) in vec4 in_position;\n"
				<< "\n"
				<< "out gl_PerVertex {\n"
				<< "    vec4  gl_Position;\n"
				<< "};\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "    gl_Position = in_position;\n"
				<< "}\n";

			programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
		}

		// Fragment shader
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(location = 0) out vec4 out_color;\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "    if (gl_FrontFacing)\n"
				<< "        out_color = vec4(1.0);\n"
				<< "    else\n"
				<< "        out_color = vec4(vec3(0.5), 1.0);\n"
				<< "}\n";

			programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
		}
	}

	virtual void checkSupport (Context& context) const
	{
		if (m_params.useDynamicRendering)
			context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");

		context.requireDeviceFunctionality("VK_KHR_maintenance1");
	}

	virtual TestInstance* createInstance (Context& context) const
	{
		return new NegativeViewportHeightTestInstance(context, m_params);
	}

private:
	const TestParams	m_params;
};

struct GroupParams
{
	bool zeroViewportHeight;
	bool useDynamicRendering;
};

void populateTestGroup (tcu::TestCaseGroup* testGroup, GroupParams groupParams)
{
	const struct
	{
		const char* const	name;
		VkFrontFace			frontFace;
	} frontFace[] =
	{
		{ "front_ccw",	VK_FRONT_FACE_COUNTER_CLOCKWISE	},
		{ "front_cw",	VK_FRONT_FACE_CLOCKWISE			},
	};

	const struct
	{
		const char* const	name;
		VkCullModeFlagBits	cullMode;
	} cullMode[] =
	{
		{ "cull_none",	VK_CULL_MODE_NONE			},
		{ "cull_front",	VK_CULL_MODE_FRONT_BIT		},
		{ "cull_back",	VK_CULL_MODE_BACK_BIT		},
		{ "cull_both",	VK_CULL_MODE_FRONT_AND_BACK	},
	};

	for (int ndxFrontFace = 0; ndxFrontFace < DE_LENGTH_OF_ARRAY(frontFace); ++ndxFrontFace)
	for (int ndxCullMode  = 0; ndxCullMode  < DE_LENGTH_OF_ARRAY(cullMode);  ++ndxCullMode)
	{
		const TestParams params =
		{
			frontFace[ndxFrontFace].frontFace,
			cullMode[ndxCullMode].cullMode,
			groupParams.zeroViewportHeight,
			groupParams.useDynamicRendering
		};
		std::ostringstream	name;
		name << frontFace[ndxFrontFace].name << "_" << cullMode[ndxCullMode].name;

		testGroup->addChild(new NegativeViewportHeightTest(testGroup->getTestContext(), name.str(), "", params));
	}
}

}	// anonymous

tcu::TestCaseGroup*	createNegativeViewportHeightTests (tcu::TestContext& testCtx, bool useDynamicRendering)
{
	GroupParams groupParams { false, useDynamicRendering };
	return createTestGroup(testCtx, "negative_viewport_height", "Negative viewport height (VK_KHR_maintenance1)", populateTestGroup, groupParams);
}

tcu::TestCaseGroup*	createZeroViewportHeightTests (tcu::TestContext& testCtx, bool useDynamicRendering)
{
	GroupParams groupParams{ false, useDynamicRendering };
	return createTestGroup(testCtx, "zero_viewport_height", "Zero viewport height (VK_KHR_maintenance1)", populateTestGroup, groupParams);
}

}	// Draw
}	// vkt
