vktPipelineStencilTests.cpp revision 86a8ae9e0d61bbfe1f1e273fdbb026369bdb5f29
19091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim/*------------------------------------------------------------------------
29091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim * Vulkan Conformance Tests
39091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim * ------------------------
49091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim *
59091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim * Copyright (c) 2015 The Khronos Group Inc.
69091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim * Copyright (c) 2015 Imagination Technologies Ltd.
79091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim *
8978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License");
9978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * you may not use this file except in compliance with the License.
10978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * You may obtain a copy of the License at
119091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim *
12978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos *      http://www.apache.org/licenses/LICENSE-2.0
139091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim *
14978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * Unless required by applicable law or agreed to in writing, software
15978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS,
16978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * See the License for the specific language governing permissions and
18978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * limitations under the License.
199091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim *
209091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim *//*!
219091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim * \file
229091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim * \brief Stencil Tests
239091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim *//*--------------------------------------------------------------------*/
249091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
259091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "vktPipelineStencilTests.hpp"
269091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "vktPipelineClearUtil.hpp"
279091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "vktPipelineImageUtil.hpp"
289091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "vktPipelineVertexUtil.hpp"
299091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "vktPipelineReferenceRenderer.hpp"
309091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "vktPipelineUniqueRandomIterator.hpp"
319091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "vktTestCase.hpp"
329091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "vkImageUtil.hpp"
339091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "vkMemUtil.hpp"
349091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "vkPrograms.hpp"
359091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "vkQueryUtil.hpp"
369091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "vkRef.hpp"
379091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "vkRefUtil.hpp"
389091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "tcuImageCompare.hpp"
399091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "deMemory.h"
409091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "deRandom.hpp"
419091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "deStringUtil.hpp"
429091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include "deUniquePtr.hpp"
439091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
449091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include <algorithm>
459091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include <sstream>
469091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim#include <vector>
479091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
489091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimnamespace vkt
499091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
509091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimnamespace pipeline
519091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
529091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
539091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimusing namespace vk;
549091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
559091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimnamespace
569091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
579091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
589091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimbool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
599091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
609091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VkFormatProperties formatProps;
619091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
62120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
639091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
64682d882fdacf7d4711d23a5ba006f7fb377cf0e3Pyry Haulos	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
659091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
669091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
679091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimclass StencilOpStateUniqueRandomIterator : public UniqueRandomIterator<VkStencilOpState>
689091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
699091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimpublic:
709091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim								StencilOpStateUniqueRandomIterator	(int seed);
719091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	virtual						~StencilOpStateUniqueRandomIterator	(void) {}
729091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	virtual VkStencilOpState	getIndexedValue (deUint32 index);
739091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
749091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimprivate:
759091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const static VkStencilOp	m_stencilOps[];
769091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const static VkCompareOp	m_compareOps[];
779091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
789091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Pre-calculated constants
799091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const static deUint32		m_stencilOpsLength;
809091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const static deUint32		m_stencilOpsLength2;
819091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const static deUint32		m_stencilOpsLength3;
829091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const static deUint32		m_compareOpsLength;
839091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
849091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Total number of cross-combinations of (stencilFailOp x stencilPassOp x stencilDepthFailOp x stencilCompareOp)
859091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const static deUint32		m_totalStencilOpStates;
869091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim};
879091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
889091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
899091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimclass StencilTest : public vkt::TestCase
909091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
919091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimpublic:
929091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	enum
939091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
949091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		QUAD_COUNT = 4
959091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	};
969091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
979091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	struct StencilStateConfig
989091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
999091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		deUint32	frontReadMask;
1009091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		deUint32	frontWriteMask;
1019091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		deUint32	frontRef;
1029091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1039091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		deUint32	backReadMask;
1049091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		deUint32	backWriteMask;
1059091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		deUint32	backRef;
1069091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	};
1079091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1089091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const static StencilStateConfig			s_stencilStateConfigs[QUAD_COUNT];
1099091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const static float						s_quadDepths[QUAD_COUNT];
1109091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1119091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1129091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim											StencilTest				(tcu::TestContext&			testContext,
1139091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim																	 const std::string&			name,
1149091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim																	 const std::string&			description,
1159091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim																	 VkFormat					stencilFormat,
1169091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim																	 const VkStencilOpState&	stencilOpStateFront,
1179091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim																	 const VkStencilOpState&	stencilOpStateBack);
1189091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	virtual									~StencilTest			(void);
1199091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	virtual void							initPrograms			(SourceCollections& sourceCollections) const;
1209091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	virtual TestInstance*					createInstance			(Context& context) const;
1219091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1229091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimprivate:
1239091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VkFormat								m_stencilFormat;
1249091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const VkStencilOpState					m_stencilOpStateFront;
1259091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const VkStencilOpState					m_stencilOpStateBack;
1269091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim};
1279091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1289091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimclass StencilTestInstance : public vkt::TestInstance
1299091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
1309091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimpublic:
1319091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim										StencilTestInstance		(Context&					context,
1329091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim																 VkFormat					stencilFormat,
1339091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim																 const VkStencilOpState&	stencilOpStatesFront,
1349091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim																 const VkStencilOpState&	stencilOpStatesBack);
1359091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	virtual								~StencilTestInstance	(void);
1369091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	virtual tcu::TestStatus				iterate					(void);
1379091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1389091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimprivate:
1399091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	tcu::TestStatus						verifyImage				(void);
1409091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1419091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VkStencilOpState					m_stencilOpStateFront;
1429091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VkStencilOpState					m_stencilOpStateBack;
143689c095f881a410da6a315795452a8e00ad95a9dPyry Haulos	const tcu::UVec2					m_renderSize;
1449091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const VkFormat						m_colorFormat;
1459091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const VkFormat						m_stencilFormat;
1469091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1479091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VkImageCreateInfo					m_colorImageCreateInfo;
1489091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	Move<VkImage>						m_colorImage;
1499091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	de::MovePtr<Allocation>				m_colorImageAlloc;
1509091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	Move<VkImage>						m_stencilImage;
1519091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	de::MovePtr<Allocation>				m_stencilImageAlloc;
1529091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	Move<VkImageView>					m_colorAttachmentView;
1539091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	Move<VkImageView>					m_stencilAttachmentView;
1549091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	Move<VkRenderPass>					m_renderPass;
1559091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	Move<VkFramebuffer>					m_framebuffer;
1569091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1579091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	Move<VkShaderModule>				m_vertexShaderModule;
1589091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	Move<VkShaderModule>				m_fragmentShaderModule;
1599091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1609091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	Move<VkBuffer>						m_vertexBuffer;
1619091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	std::vector<Vertex4RGBA>			m_vertices;
1629091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	de::MovePtr<Allocation>				m_vertexBufferAlloc;
1639091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1649091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	Move<VkPipelineLayout>				m_pipelineLayout;
1659091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	Move<VkPipeline>					m_graphicsPipelines[StencilTest::QUAD_COUNT];
1669091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
167120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	Move<VkCommandPool>					m_cmdPool;
168120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	Move<VkCommandBuffer>				m_cmdBuffer;
1699091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1709091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	Move<VkFence>						m_fence;
1719091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim};
1729091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1739091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1749091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim// StencilOpStateUniqueRandomIterator
1759091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1769091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimconst VkStencilOp StencilOpStateUniqueRandomIterator::m_stencilOps[] =
1779091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
1789091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VK_STENCIL_OP_KEEP,
1799091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VK_STENCIL_OP_ZERO,
1809091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VK_STENCIL_OP_REPLACE,
181120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	VK_STENCIL_OP_INCREMENT_AND_CLAMP,
182120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	VK_STENCIL_OP_DECREMENT_AND_CLAMP,
1839091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VK_STENCIL_OP_INVERT,
184120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	VK_STENCIL_OP_INCREMENT_AND_WRAP,
185120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	VK_STENCIL_OP_DECREMENT_AND_WRAP
1869091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim};
1879091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1889091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimconst VkCompareOp StencilOpStateUniqueRandomIterator::m_compareOps[] =
1899091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
1909091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VK_COMPARE_OP_NEVER,
1919091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VK_COMPARE_OP_LESS,
1929091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VK_COMPARE_OP_EQUAL,
193120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	VK_COMPARE_OP_LESS_OR_EQUAL,
1949091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VK_COMPARE_OP_GREATER,
1959091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VK_COMPARE_OP_NOT_EQUAL,
196120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	VK_COMPARE_OP_GREATER_OR_EQUAL,
1979091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VK_COMPARE_OP_ALWAYS
1989091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim};
1999091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2009091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimconst deUint32 StencilOpStateUniqueRandomIterator::m_stencilOpsLength		= DE_LENGTH_OF_ARRAY(m_stencilOps);
2019091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimconst deUint32 StencilOpStateUniqueRandomIterator::m_stencilOpsLength2		= m_stencilOpsLength * m_stencilOpsLength;
2029091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimconst deUint32 StencilOpStateUniqueRandomIterator::m_stencilOpsLength3		= m_stencilOpsLength2 * m_stencilOpsLength;
2039091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimconst deUint32 StencilOpStateUniqueRandomIterator::m_compareOpsLength		= DE_LENGTH_OF_ARRAY(m_compareOps);
2049091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimconst deUint32 StencilOpStateUniqueRandomIterator::m_totalStencilOpStates	= m_stencilOpsLength3 * m_compareOpsLength;
2059091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2069091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae KimStencilOpStateUniqueRandomIterator::StencilOpStateUniqueRandomIterator (int seed)
2079091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	: UniqueRandomIterator<VkStencilOpState>(m_totalStencilOpStates, m_totalStencilOpStates, seed)
2089091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
2099091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
2109091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2119091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae KimVkStencilOpState StencilOpStateUniqueRandomIterator::getIndexedValue (deUint32 index)
2129091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
2139091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const deUint32 stencilCompareOpIndex = index / m_stencilOpsLength3;
2149091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const deUint32 stencilCompareOpSeqIndex = stencilCompareOpIndex * m_stencilOpsLength3;
2159091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2169091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const deUint32 stencilDepthFailOpIndex = (index - stencilCompareOpSeqIndex) / m_stencilOpsLength2;
2179091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const deUint32 stencilDepthFailOpSeqIndex = stencilDepthFailOpIndex * m_stencilOpsLength2;
2189091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2199091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const deUint32 stencilPassOpIndex = (index - stencilCompareOpSeqIndex - stencilDepthFailOpSeqIndex) / m_stencilOpsLength;
2209091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const deUint32 stencilPassOpSeqIndex = stencilPassOpIndex * m_stencilOpsLength;
2219091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2229091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const deUint32 stencilFailOpIndex = index - stencilCompareOpSeqIndex - stencilDepthFailOpSeqIndex - stencilPassOpSeqIndex;
2239091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2249091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const VkStencilOpState stencilOpState =
2259091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
226120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		m_stencilOps[stencilFailOpIndex],		// VkStencilOp	failOp;
227120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		m_stencilOps[stencilPassOpIndex],		// VkStencilOp	passOp;
228120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		m_stencilOps[stencilDepthFailOpIndex],	// VkStencilOp	depthFailOp;
229120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		m_compareOps[stencilCompareOpIndex],	// VkCompareOp	compareOp;
230120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		0x0,									// deUint32		compareMask;
231120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		0x0,									// deUint32		writeMask;
232120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		0x0										// deUint32		reference;
2339091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	};
2349091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2359091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	return stencilOpState;
2369091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
2379091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2389091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2399091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim// StencilTest
2409091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2419091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimconst StencilTest::StencilStateConfig StencilTest::s_stencilStateConfigs[QUAD_COUNT] =
2429091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
2439091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	//	frontReadMask	frontWriteMask		frontRef		backReadMask	backWriteMask	backRef
2449091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{	0xFF,			0xFF,				0xAB,			0xF0,			0xFF,			0xFF	},
2459091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{	0xFF,			0xF0,				0xCD,			0xF0,			0xF0,			0xEF	},
2469091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{	0xF0,			0x0F,				0xEF,			0xFF,			0x0F,			0xCD	},
2479091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{	0xF0,			0x01,				0xFF,			0xFF,			0x01,			0xAB	}
2489091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim};
2499091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2509091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimconst float StencilTest::s_quadDepths[QUAD_COUNT] =
2519091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
2529091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	0.1f,
2539091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	0.0f,
2549091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	0.3f,
2559091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	0.2f
2569091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim};
2579091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2589091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae KimStencilTest::StencilTest (tcu::TestContext&			testContext,
2599091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim						  const std::string&		name,
2609091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim						  const std::string&		description,
2619091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim						  VkFormat					stencilFormat,
2629091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim						  const VkStencilOpState&	stencilOpStateFront,
2639091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim						  const VkStencilOpState&	stencilOpStateBack)
2649091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	: vkt::TestCase			(testContext, name, description)
2659091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	, m_stencilFormat		(stencilFormat)
2669091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	, m_stencilOpStateFront	(stencilOpStateFront)
2679091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	, m_stencilOpStateBack	(stencilOpStateBack)
2689091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
2699091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
2709091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2719091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae KimStencilTest::~StencilTest (void)
2729091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
2739091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
2749091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2759091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae KimTestInstance* StencilTest::createInstance (Context& context) const
2769091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
2779091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	return new StencilTestInstance(context, m_stencilFormat, m_stencilOpStateFront, m_stencilOpStateBack);
2789091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
2799091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2809091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimvoid StencilTest::initPrograms (SourceCollections& sourceCollections) const
2819091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
2829091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
2839091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"#version 310 es\n"
2849091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"layout(location = 0) in vec4 position;\n"
2859091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"layout(location = 1) in vec4 color;\n"
2869091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"layout(location = 0) out highp vec4 vtxColor;\n"
2879091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"void main (void)\n"
2889091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"{\n"
2899091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"	gl_Position = position;\n"
2909091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"	vtxColor = color;\n"
2919091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"}\n");
2929091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
2939091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(
2949091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"#version 310 es\n"
2959091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"layout(location = 0) in highp vec4 vtxColor;\n"
2969091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"layout(location = 0) out highp vec4 fragColor;\n"
2979091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"void main (void)\n"
2989091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"{\n"
2999091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"	fragColor = vtxColor;\n"
3009091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		"}\n");
3019091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
3029091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
3039091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
3049091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim// StencilTestInstance
3059091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
3069091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae KimStencilTestInstance::StencilTestInstance (Context&					context,
3079091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim										  VkFormat					stencilFormat,
3089091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim										  const VkStencilOpState&	stencilOpStateFront,
3099091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim										  const VkStencilOpState&	stencilOpStateBack)
3109091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	: vkt::TestInstance		(context)
3119091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	, m_stencilOpStateFront	(stencilOpStateFront)
3129091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	, m_stencilOpStateBack	(stencilOpStateBack)
3139091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	, m_renderSize			(32, 32)
3149091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
3159091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	, m_stencilFormat		(stencilFormat)
3169091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
317120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	const DeviceInterface&		vk						= context.getDeviceInterface();
318120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	const VkDevice				vkDevice				= context.getDevice();
319120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	const deUint32				queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
320120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	SimpleAllocator				memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
321120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
3229091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
3239091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Create color image
3249091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
3259091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkImageCreateInfo colorImageParams =
3269091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
327120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
328120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			DE_NULL,																	// const void*				pNext;
329120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,																			// VkImageCreateFlags		flags;
330120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
331120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			m_colorFormat,																// VkFormat					format;
332120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			{ m_renderSize.x(), m_renderSize.y(), 1u },									// VkExtent3D				extent;
333120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			1u,																			// deUint32					mipLevels;
334120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			1u,																			// deUint32					arrayLayers;
335120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples;
336120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
337120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags		usage;
338120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
339120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			1u,																			// deUint32					queueFamilyIndexCount;
340120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			&queueFamilyIndex,															// const deUint32*			pQueueFamilyIndices;
341120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_IMAGE_LAYOUT_UNDEFINED													// VkImageLayout			initialLayout;
3429091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
3439091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
3449091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_colorImageCreateInfo	= colorImageParams;
3459091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_colorImage			= createImage(vk, vkDevice, &m_colorImageCreateInfo);
3469091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
3479091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		// Allocate and bind color image memory
3489091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_colorImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
3499091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
3509091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
3519091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
3529091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Create stencil image
3539091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
3549091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		// Check format support
3559091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		if (!isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_stencilFormat))
3569091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			throw tcu::NotSupportedError(std::string("Unsupported depth/stencil format: ") + getFormatName(m_stencilFormat));
3579091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
3589091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkImageCreateInfo stencilImageParams =
3599091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
360120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
361120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			DE_NULL,										// const void*				pNext;
362120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,												// VkImageCreateFlags		flags;
363120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_IMAGE_TYPE_2D,								// VkImageType				imageType;
364120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			m_stencilFormat,								// VkFormat					format;
365120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			{ m_renderSize.x(), m_renderSize.y(), 1u },		// VkExtent3D				extent;
366120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			1u,												// deUint32					mipLevels;
367120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			1u,												// deUint32					arrayLayers;
368120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
369120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
370120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,	// VkImageUsageFlags		usage;
371120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
372120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			1u,												// deUint32					queueFamilyIndexCount;
373120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			&queueFamilyIndex,								// const deUint32*			pQueueFamilyIndices;
374120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_IMAGE_LAYOUT_UNDEFINED						// VkImageLayout			initialLayout;
3759091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
3769091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
3779091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_stencilImage = createImage(vk, vkDevice, &stencilImageParams);
3789091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
3799091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		// Allocate and bind stencil image memory
3809091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_stencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_stencilImage), MemoryRequirement::Any);
3819091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		VK_CHECK(vk.bindImageMemory(vkDevice, *m_stencilImage, m_stencilImageAlloc->getMemory(), m_stencilImageAlloc->getOffset()));
3829091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
3839091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
3849091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Create color attachment view
3859091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
3869091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkImageViewCreateInfo colorAttachmentViewParams =
3879091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
388120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
389120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			DE_NULL,											// const void*				pNext;
390120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,													// VkImageViewCreateFlags	flags;
391120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			*m_colorImage,										// VkImage					image;
392120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
393120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			m_colorFormat,										// VkFormat					format;
394120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			componentMappingRGBA,								// VkComponentMapping		components;
395120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }		// VkImageSubresourceRange	subresourceRange;
3969091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
3979091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
3989091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
3999091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
4009091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
4019091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Create stencil attachment view
4029091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
4039091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkImageViewCreateInfo stencilAttachmentViewParams =
4049091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
405120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
406120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			DE_NULL,											// const void*				pNext;
407120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,													// VkImageViewCreateFlags	flags;
408120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			*m_stencilImage,									// VkImage					image;
409120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
410120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			m_stencilFormat,									// VkFormat					format;
411120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			componentMappingRGBA,								// VkComponentMapping		components;
412120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			{ VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange	subresourceRange;
4139091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
4149091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
4159091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_stencilAttachmentView = createImageView(vk, vkDevice, &stencilAttachmentViewParams);
4169091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
4179091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
4189091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Create render pass
4199091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
4209091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkAttachmentDescription colorAttachmentDescription =
4219091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
42294128dffb454628346f09bb736e0f4ace9df0b9ePyry Haulos			0u,													// VkAttachmentDescriptionFlags	flags;
4239091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			m_colorFormat,										// VkFormat						format;
424120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits		samples;
4259091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp			loadOp;
4269091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp			storeOp;
4279091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp			stencilLoadOp;
4289091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp			stencilStoreOp;
4299091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout				initialLayout;
4309091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout				finalLayout;
4319091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
4329091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
4339091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkAttachmentDescription stencilAttachmentDescription =
4349091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
435120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,													// VkAttachmentDescriptionFlags	flags;
4369091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			m_stencilFormat,									// VkFormat						format;
437120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits		samples;
4389091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp			loadOp;
4399091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp			storeOp;
4409091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp			stencilLoadOp;
4419091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp			stencilStoreOp;
4429091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout				initialLayout;
4439091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout				finalLayout;
4449091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
4459091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
4469091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkAttachmentDescription attachments[2] =
4479091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
4489091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			colorAttachmentDescription,
4499091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			stencilAttachmentDescription
4509091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
4519091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
4529091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkAttachmentReference colorAttachmentReference =
4539091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
4549091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			0u,													// deUint32			attachment;
4559091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
4569091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
4579091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
4589091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkAttachmentReference stencilAttachmentReference =
4599091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
4609091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			1u,													// deUint32			attachment;
4619091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout	layout;
4629091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
4639091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
4649091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkSubpassDescription subpassDescription =
4659091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
4669091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			0u,													// VkSubpassDescriptionFlags	flags;
467120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint			pipelineBindPoint;
468120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,													// deUint32						inputAttachmentCount;
4699091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_NULL,											// const VkAttachmentReference*	pInputAttachments;
470120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			1u,													// deUint32						colorAttachmentCount;
4719091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			&colorAttachmentReference,							// const VkAttachmentReference*	pColorAttachments;
472120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			DE_NULL,											// const VkAttachmentReference*	pResolveAttachments;
473120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			&stencilAttachmentReference,						// const VkAttachmentReference*	pDepthStencilAttachment;
474120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,													// deUint32						preserveAttachmentCount;
4759091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_NULL												// const VkAttachmentReference*	pPreserveAttachments;
4769091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
4779091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
4789091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkRenderPassCreateInfo renderPassParams =
4799091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
4809091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
4819091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_NULL,											// const void*						pNext;
482120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,													// VkRenderPassCreateFlags			flags;
4839091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			2u,													// deUint32							attachmentCount;
4849091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			attachments,										// const VkAttachmentDescription*	pAttachments;
4859091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			1u,													// deUint32							subpassCount;
4869091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
4879091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			0u,													// deUint32							dependencyCount;
4889091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_NULL												// const VkSubpassDependency*		pDependencies;
4899091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
4909091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
4919091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
4929091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
4939091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
4949091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Create framebuffer
4959091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
4969091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkImageView attachmentBindInfos[2] = { *m_colorAttachmentView, *m_stencilAttachmentView };
4979091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
4989091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkFramebufferCreateInfo framebufferParams =
4999091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
500120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType			sType;
501120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			DE_NULL,											// const void*				pNext;
502120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,													// VkFramebufferCreateFlags	flags;
503120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			*m_renderPass,										// VkRenderPass				renderPass;
504120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			2u,													// deUint32					attachmentCount;
505120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			attachmentBindInfos,								// const VkImageView*		pAttachments;
506120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			(deUint32)m_renderSize.x(),							// deUint32					width;
507120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			(deUint32)m_renderSize.y(),							// deUint32					height;
508120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			1u													// deUint32					layers;
5099091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
5109091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
5119091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
5129091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
5139091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
5149091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Create pipeline layout
5159091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
5169091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
5179091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
5189091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
5199091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_NULL,											// const void*					pNext;
520120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,													// VkPipelineLayoutCreateFlags	flags;
521120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,													// deUint32						setLayoutCount;
5229091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_NULL,											// const VkDescriptorSetLayout*	pSetLayouts;
5239091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			0u,													// deUint32						pushConstantRangeCount;
5249091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
5259091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
5269091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
5279091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
5289091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
5299091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
530120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
531120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
5329091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
5339091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Create pipeline
5349091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
535120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		const VkPipelineShaderStageCreateInfo shaderStages[2] =
5369091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
5379091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			{
538120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
539120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				DE_NULL,													// const void*							pNext;
540120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				0u,															// VkPipelineShaderStageCreateFlags		flags;
541120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBits				stage;
542120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				*m_vertexShaderModule,										// VkShaderModule						module;
543120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				"main",														// const char*							pName;
544120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
5459091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			},
5469091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			{
547120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
548120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				DE_NULL,													// const void*							pNext;
549120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				0u,															// VkPipelineShaderStageCreateFlags		flags;
550120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBits				stage;
551120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				*m_fragmentShaderModule,									// VkShaderModule						module;
552120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				"main",														// const char*							pName;
553120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
5549091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			}
5559091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
5569091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
5579091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkVertexInputBindingDescription vertexInputBindingDescription =
5589091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
5599091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			0u,										// deUint32					binding;
5609091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			sizeof(Vertex4RGBA),					// deUint32					strideInBytes;
561120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_VERTEX_INPUT_RATE_VERTEX				// VkVertexInputStepRate	inputRate;
5629091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
5639091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
5649091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
5659091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
5669091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			{
5679091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				0u,									// deUint32	location;
5689091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				0u,									// deUint32	binding;
5699091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
5709091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				0u									// deUint32	offsetInBytes;
5719091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			},
5729091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			{
5739091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				1u,									// deUint32	location;
5749091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				0u,									// deUint32	binding;
5759091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
5769091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32	offsetInBytes;
5779091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			}
5789091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
5799091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
5809091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
5819091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
5829091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
5839091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_NULL,														// const void*								pNext;
584120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
585120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			1u,																// deUint32									vertexBindingDescriptionCount;
5869091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
587120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			2u,																// deUint32									vertexAttributeDescriptionCount;
5889091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
5899091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
5909091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
5919091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
5929091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
593120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
594120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			DE_NULL,														// const void*								pNext;
595120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,																// VkPipelineInputAssemblyStateCreateFlags	flags;
596120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology						topology;
597120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			false															// VkBool32									primitiveRestartEnable;
5989091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
5999091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
6009091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkViewport viewport =
6019091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
602120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0.0f,						// float	x;
603120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0.0f,						// float	y;
6049091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			(float)m_renderSize.x(),	// float	width;
6059091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			(float)m_renderSize.y(),	// float	height;
6069091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			0.0f,						// float	minDepth;
6079091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			1.0f						// float	maxDepth;
6089091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
6099091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
6109091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkRect2D scissor = { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } };
6119091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
6129091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkPipelineViewportStateCreateInfo viewportStateParams =
6139091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
614120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType						sType;
615120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			DE_NULL,														// const void*							pNext;
616120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,																// VkPipelineViewportStateCreateFlags	flags;
617120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			1u,																// deUint32								viewportCount;
618120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			&viewport,														// const VkViewport*					pViewports;
619120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			1u,																// deUint32								scissorCount;
620120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			&scissor,														// const VkRect2D*						pScissors;
6219091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
6229091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
623120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		const VkPipelineRasterizationStateCreateInfo rasterStateParams =
6249091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
625120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
626120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			DE_NULL,														// const void*								pNext;
627120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,																// VkPipelineRasterizationStateCreateFlags	flags;
628120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			false,															// VkBool32									depthClampEnable;
629120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			false,															// VkBool32									rasterizerDiscardEnable;
630120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
631120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
632120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
633120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			false,															// VkBool32									depthBiasEnable;
634120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0.0f,															// float									depthBiasConstantFactor;
635120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0.0f,															// float									depthBiasClamp;
636120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0.0f,															// float									depthBiasSlopeFactor;
637120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			1.0f															// float									lineWidth;
6389091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
6399091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
6409091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
6419091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
642120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			false,															// VkBool32					blendEnable;
643120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_BLEND_FACTOR_ONE,											// VkBlendFactor			srcColorBlendFactor;
644120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_BLEND_FACTOR_ZERO,											// VkBlendFactor			dstColorBlendFactor;
645120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_BLEND_OP_ADD,												// VkBlendOp				colorBlendOp;
646120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_BLEND_FACTOR_ONE,											// VKBLENDFACTOR			SRCALPHABLENDFACTOR;
647120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_BLEND_FACTOR_ZERO,											// VkBlendFactor			dstAlphaBlendFactor;
648120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_BLEND_OP_ADD,												// VkBlendOp				alphaBlendOp;
649120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |			// VkColorComponentFlags	colorWriteMask;
650120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
6519091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
6529091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
6539091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
6549091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
6559091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
6569091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_NULL,													// const void*									pNext;
657120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,															// VkPipelineColorBlendStateCreateFlags			flags;
6589091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			false,														// VkBool32										logicOpEnable;
6599091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
6609091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			1u,															// deUint32										attachmentCount;
6619091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
662120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
6639091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
6649091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
6659091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
6669091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
667120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
668120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			DE_NULL,													// const void*								pNext;
669120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,															// VkPipelineMultisampleStateCreateFlags	flags;
670120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
671120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			false,														// VkBool32									sampleShadingEnable;
672120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0.0f,														// float									minSampleShading;
673120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			DE_NULL,													// const VkSampleMask*						pSampleMask;
674120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			false,														// VkBool32									alphaToCoverageEnable;
675120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			false														// VkBool32									alphaToOneEnable;
6769091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
6779091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
6789091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const bool isDepthEnabled = (vk::mapVkFormat(m_stencilFormat).order != tcu::TextureFormat::S);
6799091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
6809091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
6819091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
682120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
683120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			DE_NULL,													// const void*								pNext;
684120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
685120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			isDepthEnabled,												// VkBool32									depthTestEnable;
686120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			isDepthEnabled,												// VkBool32									depthWriteEnable;
687120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
688120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			false,														// VkBool32									depthBoundsTestEnable;
689120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			true,														// VkBool32									stencilTestEnable;
690120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			m_stencilOpStateFront,										// VkStencilOpState							front;
691120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			m_stencilOpStateBack,										// VkStencilOpState							back;
692120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			-1.0f,														// float									minDepthBounds;
693120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			+1.0f														// float									maxDepthBounds;
6949091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
6959091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
6969091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
6979091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
6989091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
6999091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_NULL,											// const void*										pNext;
700120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,													// VkPipelineCreateFlags							flags;
7019091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			2u,													// deUint32											stageCount;
702120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			shaderStages,										// const VkPipelineShaderStageCreateInfo*			pStages;
7039091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
7049091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
7059091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
7069091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
707120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			&rasterStateParams,									// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
7089091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
7099091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			&depthStencilStateParams,							// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
7109091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
71186a8ae9e0d61bbfe1f1e273fdbb026369bdb5f29Pyry Haulos			(const VkPipelineDynamicStateCreateInfo*)DE_NULL,	// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
7129091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			*m_pipelineLayout,									// VkPipelineLayout									layout;
7139091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			*m_renderPass,										// VkRenderPass										renderPass;
7149091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			0u,													// deUint32											subpass;
7159091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			0u,													// VkPipeline										basePipelineHandle;
7169091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			0u													// deInt32											basePipelineIndex;
7179091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
7189091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
7199091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		// Setup different stencil masks and refs in each quad
7209091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
7219091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
7229091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			const StencilTest::StencilStateConfig&	config	= StencilTest::s_stencilStateConfigs[quadNdx];
7239091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VkStencilOpState&						front	= depthStencilStateParams.front;
7249091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VkStencilOpState&						back	= depthStencilStateParams.back;
7259091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
726120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			front.compareMask	= config.frontReadMask;
727120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			front.writeMask		= config.frontWriteMask;
728120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			front.reference		= config.frontRef;
7299091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
730120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			back.compareMask	= config.backReadMask;
731120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			back.writeMask		= config.backWriteMask;
732120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			back.reference		= config.backRef;
7339091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
7349091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			m_graphicsPipelines[quadNdx] = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
7359091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		}
7369091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
7379091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
7389091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
7399091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Create vertex buffer
7409091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
7419091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkBufferCreateInfo vertexBufferParams =
7429091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
7439091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
7449091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_NULL,									// const void*			pNext;
745120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,											// VkBufferCreateFlags	flags;
7469091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			1024u,										// VkDeviceSize			size;
7479091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
7489091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
749120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			1u,											// deUint32				queueFamilyIndexCount;
7509091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
7519091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
7529091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
7539091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_vertices			= createOverlappingQuads();
7549091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
7559091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
7569091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
7579091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
7589091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
7599091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		// Adjust depths
7609091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		for (int quadNdx = 0; quadNdx < 4; quadNdx++)
7619091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++)
7629091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				m_vertices[quadNdx * 6 + vertexNdx].position.z() = StencilTest::s_quadDepths[quadNdx];
7639091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
7649091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		// Load vertices into vertex buffer
7659091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
7669091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
7679091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkMappedMemoryRange flushRange =
7689091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
7699091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,	// VkStructureType	sType;
7709091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				DE_NULL,								// const void*		pNext;
771120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim				m_vertexBufferAlloc->getMemory(),		// VkDeviceMemory	memory;
7729091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				m_vertexBufferAlloc->getOffset(),		// VkDeviceSize		offset;
7739091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				vertexBufferParams.size					// VkDeviceSize		size;
7749091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
7759091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
7769091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		vk.flushMappedMemoryRanges(vkDevice, 1, &flushRange);
7779091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
7789091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
7799091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Create command pool
7809091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
781120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		const VkCommandPoolCreateInfo cmdPoolParams =
7829091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
783120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,		// VkStructureType			sType;
784120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			DE_NULL,										// const void*				pNext;
785120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,			// VkCommandPoolCreateFlags	flags;
786120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			queueFamilyIndex,								// deUint32					queueFamilyIndex;
7879091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
7889091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
7899091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
7909091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
7919091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
7929091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Create command buffer
7939091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
794120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
7959091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
79694128dffb454628346f09bb736e0f4ace9df0b9ePyry Haulos			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType		sType;
79794128dffb454628346f09bb736e0f4ace9df0b9ePyry Haulos			DE_NULL,										// const void*			pNext;
79894128dffb454628346f09bb736e0f4ace9df0b9ePyry Haulos			*m_cmdPool,										// VkCommandPool		commandPool;
79994128dffb454628346f09bb736e0f4ace9df0b9ePyry Haulos			VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel	level;
80094128dffb454628346f09bb736e0f4ace9df0b9ePyry Haulos			1u												// deUint32				bufferCount;
8019091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
8029091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
803120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		const VkCommandBufferBeginInfo cmdBufferBeginInfo =
8049091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
805120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
806120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			DE_NULL,										// const void*						pNext;
807120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim			0u,												// VkCommandBufferUsageFlags		flags;
808689c095f881a410da6a315795452a8e00ad95a9dPyry Haulos			(const VkCommandBufferInheritanceInfo*)DE_NULL,
8099091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
8109091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
8119091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkClearValue attachmentClearValues[2] =
8129091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
8139091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			defaultClearValue(m_colorFormat),
8149091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			defaultClearValue(m_stencilFormat)
8159091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
8169091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
8179091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkRenderPassBeginInfo renderPassBeginInfo =
8189091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
8199091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
8209091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_NULL,												// const void*			pNext;
8219091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			*m_renderPass,											// VkRenderPass			renderPass;
8229091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			*m_framebuffer,											// VkFramebuffer		framebuffer;
8239091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			{ { 0, 0 } , { m_renderSize.x(), m_renderSize.y() } },	// VkRect2D				renderArea;
8249091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			2,														// deUint32				clearValueCount;
8259091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			attachmentClearValues									// const VkClearValue*	pClearValues;
8269091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
8279091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
828120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
8299091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
8309091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
831120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
8329091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
8339091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkDeviceSize		quadOffset		= (m_vertices.size() / StencilTest::QUAD_COUNT) * sizeof(Vertex4RGBA);
8349091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
8359091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
8369091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
8379091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;
8389091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
8399091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]);
8409091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
8419091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / StencilTest::QUAD_COUNT), 1, 0, 0);
8429091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		}
8439091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
8449091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		vk.cmdEndRenderPass(*m_cmdBuffer);
8459091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
8469091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
8479091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
8489091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Create fence
8499091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
8509091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkFenceCreateInfo fenceParams =
8519091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
8529091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
8539091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_NULL,								// const void*			pNext;
8549091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			0u										// VkFenceCreateFlags	flags;
8559091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		};
8569091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
8579091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		m_fence = createFence(vk, vkDevice, &fenceParams);
8589091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
8599091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
8609091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
8619091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae KimStencilTestInstance::~StencilTestInstance (void)
8629091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
8639091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
8649091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
8659091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimtcu::TestStatus StencilTestInstance::iterate (void)
8669091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
8679091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const DeviceInterface&		vk			= m_context.getDeviceInterface();
8689091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const VkDevice				vkDevice	= m_context.getDevice();
8699091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const VkQueue				queue		= m_context.getUniversalQueue();
870120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	const VkSubmitInfo			submitInfo	=
871120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	{
872120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
873120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		DE_NULL,						// const void*				pNext;
874120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		0u,								// deUint32					waitSemaphoreCount;
875120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		DE_NULL,						// const VkSemaphore*		pWaitSemaphores;
876689c095f881a410da6a315795452a8e00ad95a9dPyry Haulos		(const VkPipelineStageFlags*)DE_NULL,
877120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		1u,								// deUint32					commandBufferCount;
878120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		&m_cmdBuffer.get(),				// const VkCommandBuffer*	pCommandBuffers;
879120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		0u,								// deUint32					signalSemaphoreCount;
880120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		DE_NULL							// const VkSemaphore*		pSignalSemaphores;
881120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	};
8829091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
8839091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
884120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
8859091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
8869091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
8879091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	return verifyImage();
8889091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
8899091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
8909091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimtcu::TestStatus StencilTestInstance::verifyImage (void)
8919091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
8929091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const tcu::TextureFormat	tcuColorFormat		= mapVkFormat(m_colorFormat);
8939091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const tcu::TextureFormat	tcuStencilFormat	= mapVkFormat(m_stencilFormat);
8949091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const ColorVertexShader		vertexShader;
8959091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const ColorFragmentShader	fragmentShader		(tcuColorFormat, tcuStencilFormat);
8969091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const rr::Program			program				(&vertexShader, &fragmentShader);
8979091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	ReferenceRenderer			refRenderer			(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuStencilFormat, &program);
8989091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	bool						compareOk			= false;
8999091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9009091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Render reference image
9019091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
9029091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		// Set depth state
9039091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		rr::RenderState renderState(refRenderer.getViewportState());
9049091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9059091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		renderState.fragOps.depthTestEnabled	= true;
9069091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		renderState.fragOps.depthFunc			= mapVkCompareOp(VK_COMPARE_OP_LESS);
9079091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		renderState.fragOps.stencilTestEnabled	= true;
9089091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9099091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		rr::StencilState& refStencilFront	= renderState.fragOps.stencilStates[rr::FACETYPE_FRONT];
9109091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		rr::StencilState& refStencilBack	= renderState.fragOps.stencilStates[rr::FACETYPE_BACK];
9119091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
912120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		refStencilFront.sFail		= mapVkStencilOp(m_stencilOpStateFront.failOp);
913120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		refStencilFront.dpFail		= mapVkStencilOp(m_stencilOpStateFront.depthFailOp);
914120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		refStencilFront.dpPass		= mapVkStencilOp(m_stencilOpStateFront.passOp);
915120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		refStencilFront.func		= mapVkCompareOp(m_stencilOpStateFront.compareOp);
9169091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
917120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		refStencilBack.sFail		= mapVkStencilOp(m_stencilOpStateBack.failOp);
918120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		refStencilBack.dpFail		= mapVkStencilOp(m_stencilOpStateBack.depthFailOp);
919120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		refStencilBack.dpPass		= mapVkStencilOp(m_stencilOpStateBack.passOp);
920120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		refStencilBack.func			= mapVkCompareOp(m_stencilOpStateBack.compareOp);
9219091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9229091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		// Reverse winding of vertices, as Vulkan screen coordinates start at upper left
9239091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		std::vector<Vertex4RGBA> cwVertices(m_vertices);
9249091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		for (size_t vertexNdx = 0; vertexNdx < cwVertices.size() - 2; vertexNdx += 3)
9259091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
9269091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			const Vertex4RGBA cwVertex1	= cwVertices[vertexNdx + 1];
9279091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9289091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			cwVertices[vertexNdx + 1]	= cwVertices[vertexNdx + 2];
9299091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			cwVertices[vertexNdx + 2]	= cwVertex1;
9309091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		}
9319091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9329091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
9339091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
9349091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			refStencilFront.ref			= (int)StencilTest::s_stencilStateConfigs[quadNdx].frontRef;
9359091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			refStencilFront.compMask	= StencilTest::s_stencilStateConfigs[quadNdx].frontReadMask;
9369091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			refStencilFront.writeMask	= StencilTest::s_stencilStateConfigs[quadNdx].frontWriteMask;
9379091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9389091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			refStencilBack.ref			= (int)StencilTest::s_stencilStateConfigs[quadNdx].backRef;
9399091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			refStencilBack.compMask		= StencilTest::s_stencilStateConfigs[quadNdx].backReadMask;
9409091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			refStencilBack.writeMask	= StencilTest::s_stencilStateConfigs[quadNdx].backWriteMask;
9419091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9429091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			refRenderer.draw(renderState,
9439091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim							 rr::PRIMITIVETYPE_TRIANGLES,
9449091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim							 std::vector<Vertex4RGBA>(cwVertices.begin() + quadNdx * 6,
9459091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim													  cwVertices.begin() + (quadNdx + 1) * 6));
9469091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		}
9479091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
9489091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9499091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	// Compare result with reference image
9509091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
9519091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const DeviceInterface&				vk					= m_context.getDeviceInterface();
9529091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkDevice						vkDevice			= m_context.getDevice();
9539091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkQueue						queue				= m_context.getUniversalQueue();
9549091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const deUint32						queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
9559091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		SimpleAllocator						allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
9569091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		de::UniquePtr<tcu::TextureLevel>	result				(readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release());
9579091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9589091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
9599091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim															  "IntImageCompare",
9609091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim															  "Image comparison",
9619091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim															  refRenderer.getAccess(),
9629091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim															  result->getAccess(),
9639091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim															  tcu::UVec4(2, 2, 2, 2),
9649091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim															  tcu::IVec3(1, 1, 0),
9659091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim															  true,
9669091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim															  tcu::COMPARE_LOG_RESULT);
9679091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
9689091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9699091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	if (compareOk)
9709091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		return tcu::TestStatus::pass("Result image matches reference");
9719091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	else
9729091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		return tcu::TestStatus::fail("Image mismatch");
9739091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
9749091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9759091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9769091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim// Utilities for test names
9779091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9789091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimstd::string getShortName (VkCompareOp compareOp)
9799091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
9809091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const std::string  fullName = getCompareOpName(compareOp);
9819091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9829091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	DE_ASSERT(de::beginsWith(fullName, "VK_COMPARE_OP_"));
9839091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9849091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	return de::toLower(fullName.substr(14));
9859091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
9869091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
9879091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimconst char* getShortName (VkStencilOp stencilOp)
9889091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
9899091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	switch (stencilOp)
9909091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
991120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		case VK_STENCIL_OP_KEEP:					return "keep";
992120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		case VK_STENCIL_OP_ZERO:					return "zero";
993120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		case VK_STENCIL_OP_REPLACE:					return "repl";
994120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		case VK_STENCIL_OP_INCREMENT_AND_CLAMP:		return "incc";
995120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		case VK_STENCIL_OP_DECREMENT_AND_CLAMP:		return "decc";
996120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		case VK_STENCIL_OP_INVERT:					return "inv";
997120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		case VK_STENCIL_OP_INCREMENT_AND_WRAP:		return "wrap";
998120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		case VK_STENCIL_OP_DECREMENT_AND_WRAP:		return "decw";
9999091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10009091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		default:
10019091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			DE_FATAL("Invalid VkStencilOpState value");
10029091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
10039091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	return DE_NULL;
10049091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
10059091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10069091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimstd::string getStencilName(const VkStencilOpState& stencilOpState)
10079091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
10089091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	std::ostringstream name;
10099091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
1010120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim	name << "fail_" << getShortName(stencilOpState.failOp)
1011120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		 << "_pass_" << getShortName(stencilOpState.passOp)
1012120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		 << "_dfail_" << getShortName(stencilOpState.depthFailOp)
1013120ed2c44030b05409d5b1164a0676389dfe87c3Dae Kim		 << "_comp_" << getShortName(stencilOpState.compareOp);
10149091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10159091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	return name.str();
10169091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
10179091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10189091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimstd::string getStencilStateSetName(const VkStencilOpState& stencilOpStateFront,
10199091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim								   const VkStencilOpState& stencilOpStateBack)
10209091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
10219091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	std::ostringstream name;
10229091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10239091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	name << "front_" << getStencilName(stencilOpStateFront)
10249091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		 << "_back_" << getStencilName(stencilOpStateBack);
10259091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10269091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	return name.str();
10279091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
10289091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10299091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimstd::string getStencilStateSetDescription(const VkStencilOpState& stencilOpStateFront,
10309091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim										  const VkStencilOpState& stencilOpStateBack)
10319091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
10329091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	std::ostringstream desc;
10339091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10349091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	desc << "\nFront faces:\n" << stencilOpStateFront;
10359091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	desc << "Back faces:\n" << stencilOpStateBack;
10369091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10379091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	return desc.str();
10389091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
10399091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10409091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimstd::string getFormatCaseName (VkFormat format)
10419091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
10429091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const std::string fullName = getFormatName(format);
10439091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10449091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
10459091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10469091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	return de::toLower(fullName.substr(10));
10479091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
10489091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10499091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim} // anonymous
10509091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10519091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kimtcu::TestCaseGroup* createStencilTests (tcu::TestContext& testCtx)
10529091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim{
10539091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	const VkFormat stencilFormats[] =
10549091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
10559091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		VK_FORMAT_S8_UINT,
10569091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		VK_FORMAT_D16_UNORM_S8_UINT,
10579091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		VK_FORMAT_D24_UNORM_S8_UINT,
10589091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		VK_FORMAT_D32_SFLOAT_S8_UINT
10599091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	};
10609091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10619091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	de::MovePtr<tcu::TestCaseGroup>		stencilTests	(new tcu::TestCaseGroup(testCtx, "stencil", "Stencil tests"));
10629091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	de::MovePtr<tcu::TestCaseGroup>		formatTests		(new tcu::TestCaseGroup(testCtx, "format", "Uses different stencil formats"));
10639091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	StencilOpStateUniqueRandomIterator	stencilOpItr	(123);
10649091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10659091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(stencilFormats); formatNdx++)
10669091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	{
10679091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkFormat					stencilFormat	= stencilFormats[formatNdx];
10689091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		de::MovePtr<tcu::TestCaseGroup>	formatTest		(new tcu::TestCaseGroup(testCtx,
10699091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim																				getFormatCaseName(stencilFormat).c_str(),
10709091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim																				(std::string("Uses format ") + getFormatName(stencilFormat)).c_str()));
10719091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10729091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		de::MovePtr<tcu::TestCaseGroup>	stencilStateTests;
10739091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
10749091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			std::ostringstream desc;
10759091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			desc << "Draws 4 quads with the following depths and dynamic stencil states: ";
10769091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
10779091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			{
10789091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				const StencilTest::StencilStateConfig& stencilConfig = StencilTest::s_stencilStateConfigs[quadNdx];
10799091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10809091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim				desc << "(" << quadNdx << ") "
10819091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim					 << "z = " << StencilTest::s_quadDepths[quadNdx] << ", "
10829091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim					 << "frontReadMask = " << stencilConfig.frontReadMask << ", "
10839091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim					 << "frontWriteMask = " << stencilConfig.frontWriteMask << ", "
10849091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim					 << "frontRef = " << stencilConfig.frontRef << ", "
10859091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim					 << "backReadMask = " << stencilConfig.backReadMask << ", "
10869091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim					 << "backWriteMask = " << stencilConfig.backWriteMask << ", "
10879091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim					 << "backRef = " << stencilConfig.backRef;
10889091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			}
10899091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10909091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			stencilStateTests = de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "states", desc.str().c_str()));
10919091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		}
10929091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10939091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		stencilOpItr.reset();
10949091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10959091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		VkStencilOpState		prevStencilState	= stencilOpItr.next();
10969091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		const VkStencilOpState	firstStencilState	= prevStencilState;
10979091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
10989091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		while (stencilOpItr.hasNext())
10999091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		{
11009091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			const VkStencilOpState stencilState = stencilOpItr.next();
11019091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
11029091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			// Use current stencil state in front fraces and previous state in back faces
11039091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			stencilStateTests->addChild(new StencilTest(testCtx,
11049091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim														getStencilStateSetName(stencilState, prevStencilState),
11059091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim														getStencilStateSetDescription(stencilState, prevStencilState),
11069091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim														stencilFormat,
11079091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim														stencilState,
11089091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim														prevStencilState));
11099091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
11109091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim			prevStencilState = stencilState;
11119091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		}
11129091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
11139091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		// Use first stencil state with last stencil state. This would make the test suite cover all states in front and back faces.
11149091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		stencilStateTests->addChild(new StencilTest(testCtx,
11159091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim													getStencilStateSetName(firstStencilState, prevStencilState),
11169091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim													getStencilStateSetDescription(firstStencilState, prevStencilState),
11179091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim													stencilFormat,
11189091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim													firstStencilState,
11199091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim													prevStencilState));
11209091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
11219091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		formatTest->addChild(stencilStateTests.release());
11229091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim		formatTests->addChild(formatTest.release());
11239091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	}
11249091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	stencilTests->addChild(formatTests.release());
11259091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
11269091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim	return stencilTests.release();
11279091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim}
11289091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim
11299091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim} // pipeline
11309091e6865c1dff4d5fa0b5345c0d9f1cb080aab1Dae Kim} // vkt
1131