161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski/*------------------------------------------------------------------------
261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski * Vulkan Conformance Tests
361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski * ------------------------
461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski *
561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski * Copyright 2014 The Android Open Source Project
661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski * Copyright (c) 2015 The Khronos Group Inc.
761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski *
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
1161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski *
12978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos *      http://www.apache.org/licenses/LICENSE-2.0
1361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski *
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.
1961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski *
2061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski *//*!
2161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski * \file
2261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski * \brief Early fragment tests
2361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski *//*--------------------------------------------------------------------*/
2461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
25367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski#include "vktFragmentOperationsEarlyFragmentTests.hpp"
26367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski#include "vktFragmentOperationsMakeUtil.hpp"
2761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include "vktTestCaseUtil.hpp"
2861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
2961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include "vkDefs.hpp"
3061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include "vkRef.hpp"
3161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include "vkRefUtil.hpp"
3261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include "vkPlatform.hpp"
3361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include "vkPrograms.hpp"
3461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include "vkMemUtil.hpp"
3561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include "vkBuilderUtil.hpp"
3661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include "vkStrUtil.hpp"
3761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include "vkTypeUtil.hpp"
3861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include "vkQueryUtil.hpp"
3961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include "vkImageUtil.hpp"
4061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
4161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include "deUniquePtr.hpp"
4261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include "deStringUtil.hpp"
4361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
4461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski#include <string>
4561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
4661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskinamespace vkt
4761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
48367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowskinamespace FragmentOperations
4961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
5061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskinamespace
5161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
52367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowskiusing namespace vk;
53367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowskiusing de::UniquePtr;
5461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
5561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski//! Basic 2D image.
5661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskiinline VkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& size, const VkFormat format, const VkImageUsageFlags usage)
5761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
5861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkImageCreateInfo imageParams =
5961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
6061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,					// VkStructureType			sType;
6161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,												// const void*				pNext;
6261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		(VkImageCreateFlags)0,									// VkImageCreateFlags		flags;
6361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_IMAGE_TYPE_2D,										// VkImageType				imageType;
6461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		format,													// VkFormat					format;
6561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		makeExtent3D(size.x(), size.y(), 1),					// VkExtent3D				extent;
6661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u,														// deUint32					mipLevels;
6761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u,														// deUint32					arrayLayers;
6861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits	samples;
6961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_IMAGE_TILING_OPTIMAL,								// VkImageTiling			tiling;
7061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		usage,													// VkImageUsageFlags		usage;
7161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_SHARING_MODE_EXCLUSIVE,								// VkSharingMode			sharingMode;
7261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,														// deUint32					queueFamilyIndexCount;
7361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,												// const deUint32*			pQueueFamilyIndices;
7461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			initialLayout;
7561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
7661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	return imageParams;
7761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
7861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
7961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskivoid beginRenderPass (const DeviceInterface&	vk,
8061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski					  const VkCommandBuffer		commandBuffer,
8161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski					  const VkRenderPass		renderPass,
8261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski					  const VkFramebuffer		framebuffer,
8361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski					  const VkRect2D&			renderArea,
8461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski					  const tcu::Vec4&			clearColor,
8561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski					  const float				clearDepth,
8661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski					  const deUint32			clearStencil)
8761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
8861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkClearValue clearValues[] =
8961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
9061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		makeClearValueColor(clearColor),						// attachment 0
9161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		makeClearValueDepthStencil(clearDepth, clearStencil),	// attachment 1
9261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
9361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
9461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkRenderPassBeginInfo renderPassBeginInfo = {
9561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
9661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,										// const void*             pNext;
9761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		renderPass,										// VkRenderPass            renderPass;
9861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		framebuffer,									// VkFramebuffer           framebuffer;
9961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		renderArea,										// VkRect2D                renderArea;
10061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_LENGTH_OF_ARRAY(clearValues),				// uint32_t                clearValueCount;
10161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		clearValues,									// const VkClearValue*     pClearValues;
10261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
10361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
10461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
10561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
10661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
10761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej JesionowskiMove<VkRenderPass> makeRenderPass (const DeviceInterface&	vk,
10861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski								   const VkDevice			device,
10961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski								   const VkFormat			colorFormat,
11061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski								   const bool				useDepthStencilAttachment,
11161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski								   const VkFormat			depthStencilFormat)
11261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
11361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkAttachmentDescription attachments[] =
11461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
11561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		// color
11661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{
11761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
11861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			colorFormat,										// VkFormat							format;
11961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
12061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
12161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
12261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
12361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
12461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
12561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					finalLayout;
12661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		},
12761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		// depth/stencil
12861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{
12961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
13061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			depthStencilFormat,									// VkFormat							format;
13161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
13261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
13361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
13461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				stencilLoadOp;
13561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				stencilStoreOp;
13661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout;
13761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout					finalLayout;
13861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		}
13961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
14061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
14161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkAttachmentReference unusedAttachmentReference =
14261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
14361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_ATTACHMENT_UNUSED,								// deUint32			attachment;
14461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_IMAGE_LAYOUT_UNDEFINED							// VkImageLayout	layout;
14561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
14661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
14761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkAttachmentReference colorAttachmentReference =
14861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
14961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,													// deUint32			attachment;
15061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
15161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
15261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
15361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkAttachmentReference depthStencilAttachmentReference =
15461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
15561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u,													// deUint32			attachment;
15661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout	layout;
15761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
15861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
15961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkAttachmentReference* pDepthStencilAttachment = (useDepthStencilAttachment ? &depthStencilAttachmentReference : &unusedAttachmentReference);
16061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
16161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkSubpassDescription subpassDescription =
16261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
16361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,													// VkSubpassDescriptionFlags		flags;
16461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
16561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,													// deUint32							inputAttachmentCount;
16661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
16761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u,													// deUint32							colorAttachmentCount;
16861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		&colorAttachmentReference,							// const VkAttachmentReference*		pColorAttachments;
16961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
17061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		pDepthStencilAttachment,							// const VkAttachmentReference*		pDepthStencilAttachment;
17161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,													// deUint32							preserveAttachmentCount;
17261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL												// const deUint32*					pPreserveAttachments;
17361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
17461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
17561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkRenderPassCreateInfo renderPassInfo =
17661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
17761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
17861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,											// const void*						pNext;
17961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags;
18061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		(useDepthStencilAttachment ? 2u : 1u),				// deUint32							attachmentCount;
18161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		attachments,										// const VkAttachmentDescription*	pAttachments;
18261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u,													// deUint32							subpassCount;
18361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
18461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,													// deUint32							dependencyCount;
18561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL												// const VkSubpassDependency*		pDependencies;
18661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
18761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
18861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	return createRenderPass(vk, device, &renderPassInfo);
18961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
19061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
19161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej JesionowskiMove<VkFramebuffer> makeFramebuffer (const DeviceInterface&		vk,
19261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									 const VkDevice				device,
19361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									 const VkRenderPass			renderPass,
19461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									 const deUint32				attachmentCount,
19561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									 const VkImageView*			pAttachments,
19661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									 const tcu::IVec2			size)
19761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
19861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkFramebufferCreateInfo framebufferInfo = {
19961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType                             sType;
20061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,										// const void*                                 pNext;
20161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		(VkFramebufferCreateFlags)0,					// VkFramebufferCreateFlags                    flags;
20261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		renderPass,										// VkRenderPass                                renderPass;
20361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		attachmentCount,								// uint32_t                                    attachmentCount;
20461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		pAttachments,									// const VkImageView*                          pAttachments;
20561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		static_cast<deUint32>(size.x()),				// uint32_t                                    width;
20661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		static_cast<deUint32>(size.y()),				// uint32_t                                    height;
20761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u,												// uint32_t                                    layers;
20861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
20961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
21061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	return createFramebuffer(vk, device, &framebufferInfo);
21161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
21261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
21361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej JesionowskiMove<VkPipeline> makeGraphicsPipeline (const DeviceInterface&	vk,
21461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									   const VkDevice			device,
21561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									   const VkPipelineLayout	pipelineLayout,
21661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									   const VkRenderPass		renderPass,
21761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									   const VkShaderModule		vertexModule,
21861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									   const VkShaderModule		fragmentModule,
21961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									   const tcu::IVec2&		renderSize,
22061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									   const bool				enableDepthTest,
22161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									   const bool				enableStencilTest)
22261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
22361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkVertexInputBindingDescription vertexInputBindingDescription =
22461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
22561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,								// uint32_t				binding;
22661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		sizeof(tcu::Vec4),				// uint32_t				stride;		// Vertex is a 4-element vector XYZW, position only
22761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_VERTEX_INPUT_RATE_VERTEX,	// VkVertexInputRate	inputRate;
22861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
22961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
23061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkVertexInputAttributeDescription vertexInputAttributeDescription =
23161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
23261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,									// uint32_t			location;
23361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,									// uint32_t			binding;
23461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat			format;
23561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,									// uint32_t			offset;
23661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
23761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
23861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
23961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
24061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType                             sType;
24161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,													// const void*                                 pNext;
24261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		(VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags       flags;
24361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u,															// uint32_t                                    vertexBindingDescriptionCount;
24461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
24561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u,															// uint32_t                                    vertexAttributeDescriptionCount;
24661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		&vertexInputAttributeDescription,							// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
24761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
24861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
24961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
25061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
25161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
25261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,														// const void*                                 pNext;
25361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags     flags;
25461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology                         topology;
25561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FALSE,														// VkBool32                                    primitiveRestartEnable;
25661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
25761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
25861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkViewport viewport = makeViewport(
25961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0.0f, 0.0f,
26061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()),
26161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0.0f, 1.0f);
26261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
26361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkRect2D scissor = {
26461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		makeOffset2D(0, 0),
26561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		makeExtent2D(renderSize.x(), renderSize.y()),
26661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
26761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
26861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
26961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
27061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType                             sType;
27161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,												// const void*                                 pNext;
27261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		(VkPipelineViewportStateCreateFlags)0,					// VkPipelineViewportStateCreateFlags          flags;
27361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u,														// uint32_t                                    viewportCount;
27461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		&viewport,												// const VkViewport*                           pViewports;
27561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u,														// uint32_t                                    scissorCount;
27661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		&scissor,												// const VkRect2D*                             pScissors;
27761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
27861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
27961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
28061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
28161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
28261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,														// const void*                              pNext;
28361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
28461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FALSE,														// VkBool32                                 depthClampEnable;
28561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FALSE,														// VkBool32                                 rasterizerDiscardEnable;
28661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
28761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
28861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
28961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FALSE,														// VkBool32									depthBiasEnable;
29061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0.0f,															// float									depthBiasConstantFactor;
29161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0.0f,															// float									depthBiasClamp;
29261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0.0f,															// float									depthBiasSlopeFactor;
29361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1.0f,															// float									lineWidth;
29461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
29561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
29661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
29761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
29861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
29961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,													// const void*								pNext;
30061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags	flags;
30161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
30261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FALSE,													// VkBool32									sampleShadingEnable;
30361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0.0f,														// float									minSampleShading;
30461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,													// const VkSampleMask*						pSampleMask;
30561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
30661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FALSE													// VkBool32									alphaToOneEnable;
30761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
30861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
30961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkStencilOpState stencilOpState = makeStencilOpState(
31061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STENCIL_OP_KEEP,		// stencil fail
31161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STENCIL_OP_KEEP,		// depth & stencil pass
31261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STENCIL_OP_KEEP,		// depth only fail
31361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_COMPARE_OP_EQUAL,	// compare op
31461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u,						// compare mask
31561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u,						// write mask
31661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u);					// reference
31761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
31861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
31961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
32061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
32161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,													// const void*								pNext;
32261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
32361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		enableDepthTest,											// VkBool32									depthTestEnable;
32461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_TRUE,													// VkBool32									depthWriteEnable;
32561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
32661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
32761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		enableStencilTest,											// VkBool32									stencilTestEnable;
32861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		stencilOpState,												// VkStencilOpState							front;
32961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		stencilOpState,												// VkStencilOpState							back;
33061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0.0f,														// float									minDepthBounds;
33161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1.0f,														// float									maxDepthBounds;
33261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
33361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
33461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
33561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	// Number of blend attachments must equal the number of color attachments.
33661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
33761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
33861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FALSE,							// VkBool32					blendEnable;
33961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_BLEND_FACTOR_ONE,				// VkBlendFactor			srcColorBlendFactor;
34061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_BLEND_FACTOR_ZERO,				// VkBlendFactor			dstColorBlendFactor;
34161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_BLEND_OP_ADD,					// VkBlendOp				colorBlendOp;
34261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_BLEND_FACTOR_ONE,				// VkBlendFactor			srcAlphaBlendFactor;
34361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_BLEND_FACTOR_ZERO,				// VkBlendFactor			dstAlphaBlendFactor;
34461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_BLEND_OP_ADD,					// VkBlendOp				alphaBlendOp;
34561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		colorComponentsAll,					// VkColorComponentFlags	colorWriteMask;
34661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
34761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
34861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
34961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
35061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
35161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,													// const void*									pNext;
35261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags;
35361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FALSE,													// VkBool32										logicOpEnable;
35461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
35561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u,															// deUint32										attachmentCount;
35661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		&pipelineColorBlendAttachmentState,							// const VkPipelineColorBlendAttachmentState*	pAttachments;
35761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
35861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
35961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
36061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkPipelineShaderStageCreateInfo pShaderStages[] =
36161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
36261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{
36361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
36461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			DE_NULL,												// const void*							pNext;
36561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
36661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits				stage;
36761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			vertexModule,											// VkShaderModule						module;
36861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			"main",													// const char*							pName;
36961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
37061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		},
37161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{
37261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
37361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			DE_NULL,												// const void*							pNext;
37461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
37561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			VK_SHADER_STAGE_FRAGMENT_BIT,							// VkShaderStageFlagBits				stage;
37661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			fragmentModule,											// VkShaderModule						module;
37761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			"main",													// const char*							pName;
37861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
37961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		}
38061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
38161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
38261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
38361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
38461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
38561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,											// const void*										pNext;
38661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags							flags;
38761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_LENGTH_OF_ARRAY(pShaderStages),					// deUint32											stageCount;
38861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		pShaderStages,										// const VkPipelineShaderStageCreateInfo*			pStages;
38961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		&vertexInputStateInfo,								// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
39061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		&pipelineInputAssemblyStateInfo,					// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
39161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
39261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		&pipelineViewportStateInfo,							// const VkPipelineViewportStateCreateInfo*			pViewportState;
39361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		&pipelineRasterizationStateInfo,					// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
39461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		&pipelineMultisampleStateInfo,						// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
39561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		&pipelineDepthStencilStateInfo,						// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
39661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		&pipelineColorBlendStateInfo,						// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
39761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
39861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		pipelineLayout,										// VkPipelineLayout									layout;
39961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		renderPass,											// VkRenderPass										renderPass;
40061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,													// deUint32											subpass;
40161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		DE_NULL,											// VkPipeline										basePipelineHandle;
40261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0,													// deInt32											basePipelineIndex;
40361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
40461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
40561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
40661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
40761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
40861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej JesionowskiVkBufferImageCopy makeBufferImageCopy (const VkImageAspectFlags aspectFlags, const tcu::IVec2& renderSize)
40961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
41061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkBufferImageCopy copyParams =
41161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
41261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0ull,															//	VkDeviceSize				bufferOffset;
41361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,																//	deUint32					bufferRowLength;
41461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,																//	deUint32					bufferImageHeight;
41561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		makeImageSubresourceLayers(aspectFlags, 0u, 0u, 1u),			//	VkImageSubresourceLayers	imageSubresource;
41661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		makeOffset3D(0, 0, 0),											//	VkOffset3D					imageOffset;
41761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		makeExtent3D(renderSize.x(), renderSize.y(), 1u),				//	VkExtent3D					imageExtent;
41861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
41961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	return copyParams;
42061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
42161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
42261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskivoid commandClearStencilAttachment (const DeviceInterface&	vk,
42361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									const VkCommandBuffer	commandBuffer,
42461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									const VkOffset2D&		offset,
42561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									const VkExtent2D&		extent,
42661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski									const deUint32			clearValue)
42761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
42861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkClearAttachment stencilAttachment =
42961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
43061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_IMAGE_ASPECT_STENCIL_BIT,					// VkImageAspectFlags    aspectMask;
43161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,												// uint32_t              colorAttachment;
43261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		makeClearValueDepthStencil(0.0f, clearValue),	// VkClearValue          clearValue;
43361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
43461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
43561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkClearRect rect =
43661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
43761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{ offset, extent },		// VkRect2D    rect;
43861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		0u,						// uint32_t    baseArrayLayer;
43961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		1u,						// uint32_t    layerCount;
44061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
44161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
44261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	vk.cmdClearAttachments(commandBuffer, 1u, &stencilAttachment, 1u, &rect);
44361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
44461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
44561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej JesionowskiVkImageAspectFlags getImageAspectFlags (const VkFormat format)
44661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
44761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const tcu::TextureFormat tcuFormat = mapVkFormat(format);
44861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
44961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	if      (tcuFormat.order == tcu::TextureFormat::DS)		return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
45061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	else if (tcuFormat.order == tcu::TextureFormat::D)		return VK_IMAGE_ASPECT_DEPTH_BIT;
45161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	else if (tcuFormat.order == tcu::TextureFormat::S)		return VK_IMAGE_ASPECT_STENCIL_BIT;
45261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
45361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	DE_ASSERT(false);
45461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	return 0u;
45561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
45661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
45761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskibool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, const VkPhysicalDevice device, const VkFormat format)
45861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
45961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	VkFormatProperties formatProps;
46061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
46161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
46261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
46361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
46461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej JesionowskiVkFormat pickSupportedDepthStencilFormat (const InstanceInterface&	instanceInterface,
46561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski										  const VkPhysicalDevice	device,
46661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski										  const deUint32			numFormats,
46761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski										  const VkFormat*			pFormats)
46861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
46961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	for (deUint32 i = 0; i < numFormats; ++i)
47061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		if (isSupportedDepthStencilFormat(instanceInterface, device, pFormats[i]))
47161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			return pFormats[i];
47261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	return VK_FORMAT_UNDEFINED;
47361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
47461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
47561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskienum Flags
47661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
47761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	FLAG_TEST_DEPTH							= 1u << 0,
47861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	FLAG_TEST_STENCIL						= 1u << 1,
47961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	FLAG_DONT_USE_TEST_ATTACHMENT			= 1u << 2,
48061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	FLAG_DONT_USE_EARLY_FRAGMENT_TESTS		= 1u << 3,
48161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski};
48261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
48361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskiclass EarlyFragmentTest : public TestCase
48461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
48561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskipublic:
48661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski						EarlyFragmentTest	(tcu::TestContext&		testCtx,
48761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski											 const std::string		name,
48861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski											 const deUint32			flags);
48961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
49061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	void				initPrograms		(SourceCollections&		programCollection) const;
49161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	TestInstance*		createInstance		(Context&				context) const;
49261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
49361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskiprivate:
49461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const deUint32		m_flags;
49561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski};
49661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
49761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej JesionowskiEarlyFragmentTest::EarlyFragmentTest (tcu::TestContext& testCtx, const std::string name, const deUint32 flags)
49861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	: TestCase	(testCtx, name, "")
49961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	, m_flags	(flags)
50061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
50161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
50261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
50361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskivoid EarlyFragmentTest::initPrograms (SourceCollections& programCollection) const
50461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
50561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	// Vertex
50661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
50761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		std::ostringstream src;
50861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
50961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "\n"
51061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "layout(location = 0) in highp vec4 position;\n"
51161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "\n"
5120a6fe1448b303a6a4e4ab48712eaf1c0b16d75b1Maciej Jesionowski			<< "out gl_PerVertex {\n"
5130a6fe1448b303a6a4e4ab48712eaf1c0b16d75b1Maciej Jesionowski			<< "   vec4 gl_Position;\n"
5140a6fe1448b303a6a4e4ab48712eaf1c0b16d75b1Maciej Jesionowski			<< "};\n"
5150a6fe1448b303a6a4e4ab48712eaf1c0b16d75b1Maciej Jesionowski			<< "\n"
51661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "void main (void)\n"
51761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "{\n"
51861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "    gl_Position = position;\n"
51961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "}\n";
52061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
52161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
52261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	}
52361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
52461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	// Fragment
52561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
52661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		const bool useEarlyTests = (m_flags & FLAG_DONT_USE_EARLY_FRAGMENT_TESTS) == 0;
52761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		std::ostringstream src;
52861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
52961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "\n"
53061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< (useEarlyTests ? "layout(early_fragment_tests) in;\n" : "")
53161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "layout(location = 0) out highp vec4 fragColor;\n"
53261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "\n"
53361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "layout(binding = 0) coherent buffer Output {\n"
53461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "    uint result;\n"
53561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "} sb_out;\n"
53661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "\n"
53761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "void main (void)\n"
53861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "{\n"
53961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "    atomicAdd(sb_out.result, 1u);\n"
54061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "	fragColor = vec4(1.0, 1.0, 0.0, 1.0);\n"
54161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< "}\n";
54261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
54361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
54461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	}
54561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
54661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
54761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskiclass EarlyFragmentTestInstance : public TestInstance
54861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
54961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskipublic:
55061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski							EarlyFragmentTestInstance (Context& context, const deUint32 flags);
55161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
55261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	tcu::TestStatus			iterate					  (void);
55361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
55461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskiprivate:
55561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	enum TestMode
55661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
55761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		MODE_INVALID,
55861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		MODE_DEPTH,
55961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		MODE_STENCIL,
56061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
56161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
56261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const TestMode			m_testMode;
56361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const bool				m_useTestAttachment;
56461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const bool				m_useEarlyTests;
56561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski};
56661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
56761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej JesionowskiEarlyFragmentTestInstance::EarlyFragmentTestInstance (Context& context, const deUint32 flags)
56861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	: TestInstance			(context)
56961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	, m_testMode			(flags & FLAG_TEST_DEPTH   ? MODE_DEPTH :
57061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski							 flags & FLAG_TEST_STENCIL ? MODE_STENCIL : MODE_INVALID)
57161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	, m_useTestAttachment	((flags & FLAG_DONT_USE_TEST_ATTACHMENT) == 0)
57261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	, m_useEarlyTests		((flags & FLAG_DONT_USE_EARLY_FRAGMENT_TESTS) == 0)
57361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
57461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	DE_ASSERT(m_testMode != MODE_INVALID);
57561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
57661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
57761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskitcu::TestStatus EarlyFragmentTestInstance::iterate (void)
57861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
57961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const DeviceInterface&		vk					= m_context.getDeviceInterface();
58061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const InstanceInterface&	vki					= m_context.getInstanceInterface();
58161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkDevice				device				= m_context.getDevice();
58261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkPhysicalDevice		physDevice			= m_context.getPhysicalDevice();
58361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkQueue				queue				= m_context.getUniversalQueue();
58461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
58561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	Allocator&					allocator			= m_context.getDefaultAllocator();
58661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
58761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	// Color attachment
58861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
589367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const tcu::IVec2				renderSize			= tcu::IVec2(32, 32);
590367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const VkFormat					colorFormat			= VK_FORMAT_R8G8B8A8_UNORM;
591367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const VkImageSubresourceRange	colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
592367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const Unique<VkImage>			colorImage			(makeImage(vk, device, makeImageCreateInfo(renderSize, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)));
593367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const UniquePtr<Allocation>		colorImageAlloc		(bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any));
594367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const Unique<VkImageView>		colorImageView		(makeImageView(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange));
59561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
59661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	// Test attachment (depth or stencil)
59761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	static const VkFormat stencilFormats[] =
59861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
59961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		// One of the following formats must be supported, as per spec requirement.
60061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FORMAT_S8_UINT,
60161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FORMAT_D16_UNORM_S8_UINT,
60261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FORMAT_D24_UNORM_S8_UINT,
60361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VK_FORMAT_D32_SFLOAT_S8_UINT,
60461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
60561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
60661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkFormat testFormat = (m_testMode == MODE_STENCIL ? pickSupportedDepthStencilFormat(vki, physDevice, DE_LENGTH_OF_ARRAY(stencilFormats), stencilFormats)
60761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski															: VK_FORMAT_D16_UNORM);		// spec requires this format to be supported
60861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	if (testFormat == VK_FORMAT_UNDEFINED)
60961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		return tcu::TestStatus::fail("Required depth/stencil format not supported");
61061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
61161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	if (m_useTestAttachment)
61261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Using depth/stencil format " << getFormatName(testFormat) << tcu::TestLog::EndMessage;
61361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
614367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const VkImageSubresourceRange	testSubresourceRange	= makeImageSubresourceRange(getImageAspectFlags(testFormat), 0u, 1u, 0u, 1u);
615367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const Unique<VkImage>			testImage				(makeImage(vk, device, makeImageCreateInfo(renderSize, testFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)));
616367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const UniquePtr<Allocation>		testImageAlloc			(bindImage(vk, device, allocator, *testImage, MemoryRequirement::Any));
617367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const Unique<VkImageView>		testImageView			(makeImageView(vk, device, *testImage, VK_IMAGE_VIEW_TYPE_2D, testFormat, testSubresourceRange));
618367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const VkImageView				attachmentImages[]		= { *colorImageView, *testImageView };
619367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const deUint32					numUsedAttachmentImages = (m_useTestAttachment ? 2u : 1u);
62061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
62161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	// Vertex buffer
62261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
623367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const deUint32					numVertices				= 6;
624367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const VkDeviceSize				vertexBufferSizeBytes	= sizeof(tcu::Vec4) * numVertices;
625367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const Unique<VkBuffer>			vertexBuffer			(makeBuffer(vk, device, makeBufferCreateInfo(vertexBufferSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)));
626367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const UniquePtr<Allocation>		vertexBufferAlloc		(bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
62761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
62861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
629367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski		tcu::Vec4* const pVertices = reinterpret_cast<tcu::Vec4*>(vertexBufferAlloc->getHostPtr());
63061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
63161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		pVertices[0] = tcu::Vec4( 1.0f, -1.0f,  0.5f,  1.0f);
63261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		pVertices[1] = tcu::Vec4(-1.0f, -1.0f,  0.0f,  1.0f);
63361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		pVertices[2] = tcu::Vec4(-1.0f,  1.0f,  0.5f,  1.0f);
63461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
63561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		pVertices[3] = tcu::Vec4(-1.0f,  1.0f,  0.5f,  1.0f);
63661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		pVertices[4] = tcu::Vec4( 1.0f,  1.0f,  1.0f,  1.0f);
63761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		pVertices[5] = tcu::Vec4( 1.0f, -1.0f,  0.5f,  1.0f);
63861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
639367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski		flushMappedMemoryRange(vk, device, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexBufferSizeBytes);
64061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		// No barrier needed, flushed memory is automatically visible
64161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	}
64261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
64361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	// Result buffer
64461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
645367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const VkDeviceSize				resultBufferSizeBytes	= sizeof(deUint32);
646367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const Unique<VkBuffer>			resultBuffer			(makeBuffer(vk, device, makeBufferCreateInfo(resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)));
647367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const UniquePtr<Allocation>		resultBufferAlloc		(bindBuffer(vk, device, allocator, *resultBuffer, MemoryRequirement::HostVisible));
64861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
64961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
650367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski		deUint32* const pData = static_cast<deUint32*>(resultBufferAlloc->getHostPtr());
65161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
65261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		*pData = 0;
653367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski		flushMappedMemoryRange(vk, device, resultBufferAlloc->getMemory(), resultBufferAlloc->getOffset(), resultBufferSizeBytes);
65461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	}
65561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
65661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	// Render result buffer (to retrieve color attachment contents)
65761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
658367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const VkDeviceSize				colorBufferSizeBytes	= tcu::getPixelSize(mapVkFormat(colorFormat)) * renderSize.x() * renderSize.y();
659367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const Unique<VkBuffer>			colorBuffer				(makeBuffer(vk, device, makeBufferCreateInfo(colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT)));
660367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski	const UniquePtr<Allocation>		colorBufferAlloc		(bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
66161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
66261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	// Descriptors
66361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
66461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const Unique<VkDescriptorSetLayout> descriptorSetLayout(DescriptorSetLayoutBuilder()
66561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
66661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		.build(vk, device));
66761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
66861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const Unique<VkDescriptorPool> descriptorPool(DescriptorPoolBuilder()
66961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
67061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
67161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
67261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const Unique<VkDescriptorSet> descriptorSet				 (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
67361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const VkDescriptorBufferInfo  resultBufferDescriptorInfo = makeDescriptorBufferInfo(resultBuffer.get(), 0ull, resultBufferSizeBytes);
67461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
67561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	DescriptorSetUpdateBuilder()
67661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferDescriptorInfo)
67761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		.update(vk, device);
67861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
67961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	// Pipeline
68061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
68161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const Unique<VkShaderModule>	vertexModule  (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
68261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const Unique<VkShaderModule>	fragmentModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
68361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const Unique<VkRenderPass>		renderPass	  (makeRenderPass(vk, device, colorFormat, m_useTestAttachment, testFormat));
68461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const Unique<VkFramebuffer>		framebuffer	  (makeFramebuffer(vk, device, *renderPass, numUsedAttachmentImages, attachmentImages, renderSize));
68561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const Unique<VkPipelineLayout>	pipelineLayout(makePipelineLayout(vk, device, *descriptorSetLayout));
68661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const Unique<VkPipeline>		pipeline	  (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule, renderSize,
68761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski												  (m_testMode == MODE_DEPTH), (m_testMode == MODE_STENCIL)));
68861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const Unique<VkCommandPool>		cmdPool		  (makeCommandPool(vk, device, queueFamilyIndex));
68961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	const Unique<VkCommandBuffer>	cmdBuffer	  (makeCommandBuffer(vk, device, *cmdPool));
69061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
69161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	// Draw commands
69261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
69361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
69461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		const VkRect2D renderArea = {
69561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			makeOffset2D(0, 0),
69661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			makeExtent2D(renderSize.x(), renderSize.y()),
69761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		};
69861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		const tcu::Vec4 clearColor(0.0f, 0.0f, 0.0f, 1.0f);
69961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		const VkDeviceSize vertexBufferOffset = 0ull;
70061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
70161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		beginCommandBuffer(vk, *cmdBuffer);
70261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
70361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{
70461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			const VkImageMemoryBarrier barriers[] = {
70561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski				makeImageMemoryBarrier(
70661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski					0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
70761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski					VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
70861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski					*colorImage, colorSubresourceRange),
70961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski				makeImageMemoryBarrier(
71061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski					0u, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
71161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski					VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
71261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski					*testImage, testSubresourceRange),
71361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			};
71461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
71561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u,
71661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski				0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers);
71761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		}
71861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
71961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		// Will clear the attachments with specified depth and stencil values.
72061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor, 0.5f, 0u);
72161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
72261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
72361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
72461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
72561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
72661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		// Mask half of the attachment image with value that will pass the stencil test.
72761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		if (m_useTestAttachment && m_testMode == MODE_STENCIL)
72861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			commandClearStencilAttachment(vk, *cmdBuffer, makeOffset2D(0, 0), makeExtent2D(renderSize.x()/2, renderSize.y()), 1u);
72961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
73061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		vk.cmdDraw(*cmdBuffer, numVertices, 1u, 0u, 0u);
731acac4e187ea3f08812cd101eba2abd760c602615Maciej Jesionowski		vk.cmdEndRenderPass(*cmdBuffer);
73261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
73361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{
73461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			const VkBufferMemoryBarrier shaderWriteBarrier = makeBufferMemoryBarrier(
73561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski				VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, resultBufferSizeBytes);
73661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
73761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
73861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski				0u, DE_NULL, 1u, &shaderWriteBarrier, 0u, DE_NULL);
73961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
74061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			const VkImageMemoryBarrier preCopyColorImageBarrier = makeImageMemoryBarrier(
74161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
74261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
74361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski				*colorImage, colorSubresourceRange);
74461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
74561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
74661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski				0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyColorImageBarrier);
74761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
74861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			const VkBufferImageCopy copyRegion = makeBufferImageCopy(VK_IMAGE_ASPECT_COLOR_BIT, renderSize);
74961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &copyRegion);
75061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
75161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			const VkBufferMemoryBarrier postCopyColorBufferBarrier = makeBufferMemoryBarrier(
75261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski				VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, colorBufferSizeBytes);
75361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
75461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
75561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski				0u, DE_NULL, 1u, &postCopyColorBufferBarrier, 0u, DE_NULL);
75661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		}
75761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
758acac4e187ea3f08812cd101eba2abd760c602615Maciej Jesionowski		VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
75961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		submitCommandsAndWait(vk, device, queue, *cmdBuffer);
76061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	}
76161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
76261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	// Log result image
76361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
764367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski		invalidateMappedMemoryRange(vk, device, colorBufferAlloc->getMemory(), colorBufferAlloc->getOffset(), colorBufferSizeBytes);
76561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
766367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski		const tcu::ConstPixelBufferAccess imagePixelAccess(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1, colorBufferAlloc->getHostPtr());
76761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
76861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		tcu::TestLog& log = m_context.getTestContext().getLog();
76961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		log << tcu::TestLog::Image("color0", "Rendered image", imagePixelAccess);
77061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	}
77161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
77261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	// Verify results
77361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
774367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski		invalidateMappedMemoryRange(vk, device, resultBufferAlloc->getMemory(), resultBufferAlloc->getOffset(), resultBufferSizeBytes);
77561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
776367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski		const int  actualCounter	   = *static_cast<deInt32*>(resultBufferAlloc->getHostPtr());
77761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		const bool expectPartialResult = (m_useEarlyTests && m_useTestAttachment);
77861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		const int  expectedCounter	   = expectPartialResult ? renderSize.x() * renderSize.y() / 2 : renderSize.x() * renderSize.y();
77961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		const int  tolerance		   = expectPartialResult ? de::max(renderSize.x(), renderSize.y()) * 3	: 0;
78061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		const int  expectedMin         = de::max(0, expectedCounter - tolerance);
78161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		const int  expectedMax		   = expectedCounter + tolerance;
78261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
78361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		tcu::TestLog& log = m_context.getTestContext().getLog();
78461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		log << tcu::TestLog::Message << "Expected value"
78561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< (expectPartialResult ? " in range: [" + de::toString(expectedMin) + ", " + de::toString(expectedMax) + "]" : ": " + de::toString(expectedCounter))
78661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			<< tcu::TestLog::EndMessage;
78761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		log << tcu::TestLog::Message << "Result value: " << de::toString(actualCounter) << tcu::TestLog::EndMessage;
78861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
78961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		if (expectedMin <= actualCounter && actualCounter <= expectedMax)
79061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			return tcu::TestStatus::pass("Success");
79161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		else
79261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			return tcu::TestStatus::fail("Value out of range");
79361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	}
79461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
79561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
79661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej JesionowskiTestInstance* EarlyFragmentTest::createInstance (Context& context) const
79761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
79861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	// Check required features
79961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
80061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		VkPhysicalDeviceFeatures features;
80161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features);
80261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
80361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		// SSBO writes in fragment shader
80461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		if (!features.fragmentStoresAndAtomics)
80561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski			throw tcu::NotSupportedError("Missing required feature: fragmentStoresAndAtomics");
80661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	}
80761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
80861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	return new EarlyFragmentTestInstance(context, m_flags);
80961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
81061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
81161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski} // anonymous ns
81261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
81361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowskitcu::TestCaseGroup* createEarlyFragmentTests (tcu::TestContext& testCtx)
81461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski{
81561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "early_fragment", "early fragment test cases"));
81661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
81761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	static const struct
81861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
81961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		std::string caseName;
82061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		deUint32	flags;
82161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	} cases[] =
82261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	{
82361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{ "no_early_fragment_tests_depth",					FLAG_TEST_DEPTH   | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS									},
82461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{ "no_early_fragment_tests_stencil",				FLAG_TEST_STENCIL | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS									},
82561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{ "early_fragment_tests_depth",						FLAG_TEST_DEPTH																			},
82661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{ "early_fragment_tests_stencil",					FLAG_TEST_STENCIL																		},
82761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{ "no_early_fragment_tests_depth_no_attachment",	FLAG_TEST_DEPTH   | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS | FLAG_DONT_USE_TEST_ATTACHMENT	},
82861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{ "no_early_fragment_tests_stencil_no_attachment",	FLAG_TEST_STENCIL | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS | FLAG_DONT_USE_TEST_ATTACHMENT	},
82961517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{ "early_fragment_tests_depth_no_attachment",		FLAG_TEST_DEPTH   |										 FLAG_DONT_USE_TEST_ATTACHMENT  },
83061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		{ "early_fragment_tests_stencil_no_attachment",		FLAG_TEST_STENCIL |										 FLAG_DONT_USE_TEST_ATTACHMENT	},
83161517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	};
83261517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
83361517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
83461517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski		testGroup->addChild(new EarlyFragmentTest(testCtx, cases[i].caseName, cases[i].flags));
83561517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
83661517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski	return testGroup.release();
83761517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski}
83861517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski
839367618221ecadfacdef5aa50110347bcb8cddef8Maciej Jesionowski} // FragmentOperations
84061517fc7f94bc236aac9d6770c6f86035dcf5de2Maciej Jesionowski} // vkt
841