14dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch/*------------------------------------------------------------------------
24dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch * Vulkan Conformance Tests
34dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch * ------------------------
44dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch *
54dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch * Copyright (c) 2016 The Khronos Group Inc.
64dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch *
7978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License");
8978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * you may not use this file except in compliance with the License.
9978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * You may obtain a copy of the License at
104dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch *
11978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos *      http://www.apache.org/licenses/LICENSE-2.0
124dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch *
13978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * Unless required by applicable law or agreed to in writing, software
14978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS,
15978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * See the License for the specific language governing permissions and
17978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos * limitations under the License.
184dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch *
194dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch *//*!
204dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch * \file  vktSparseResourcesBufferSparseResidency.cpp
214dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch * \brief Sparse partially resident buffers tests
224dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch *//*--------------------------------------------------------------------*/
234dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
244dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "vktSparseResourcesBufferSparseResidency.hpp"
254dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "vktSparseResourcesTestsUtil.hpp"
264dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "vktSparseResourcesBase.hpp"
274dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "vktTestCaseUtil.hpp"
284dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
294dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "vkDefs.hpp"
304dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "vkRef.hpp"
314dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "vkRefUtil.hpp"
324dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "vkPlatform.hpp"
334dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "vkPrograms.hpp"
344dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "vkRefUtil.hpp"
354dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "vkMemUtil.hpp"
364dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "vkQueryUtil.hpp"
374dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "vkBuilderUtil.hpp"
384dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "vkTypeUtil.hpp"
394dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
404dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "deStringUtil.hpp"
414dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include "deUniquePtr.hpp"
424dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
434dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include <string>
444dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch#include <vector>
454dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
464dd3ea3dead37d80a50291f80f4a7055511735a9Kantochusing namespace vk;
474dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
484dd3ea3dead37d80a50291f80f4a7055511735a9Kantochnamespace vkt
494dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch{
504dd3ea3dead37d80a50291f80f4a7055511735a9Kantochnamespace sparse
514dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch{
524dd3ea3dead37d80a50291f80f4a7055511735a9Kantochnamespace
534dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch{
544dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
554dd3ea3dead37d80a50291f80f4a7055511735a9Kantochenum ShaderParameters
564dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch{
574dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	SIZE_OF_UINT_IN_SHADER = 4u,
584dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch};
594dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
604dd3ea3dead37d80a50291f80f4a7055511735a9Kantochclass BufferSparseResidencyCase : public TestCase
614dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch{
624dd3ea3dead37d80a50291f80f4a7055511735a9Kantochpublic:
634dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch					BufferSparseResidencyCase	(tcu::TestContext&		testCtx,
644dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch												 const std::string&		name,
654dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch												 const std::string&		description,
664dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch												 const deUint32			bufferSize,
677c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha												 const glu::GLSLVersion	glslVersion,
687c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha												 const bool				useDeviceGroups);
697c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
704dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
714dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	void			initPrograms				(SourceCollections&		sourceCollections) const;
724dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	TestInstance*	createInstance				(Context&				context) const;
734dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
744dd3ea3dead37d80a50291f80f4a7055511735a9Kantochprivate:
754dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	const deUint32			m_bufferSize;
764dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	const glu::GLSLVersion	m_glslVersion;
777c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	const bool				m_useDeviceGroups;
787c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
794dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch};
804dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
814dd3ea3dead37d80a50291f80f4a7055511735a9KantochBufferSparseResidencyCase::BufferSparseResidencyCase (tcu::TestContext&			testCtx,
824dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch													  const std::string&		name,
834dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch													  const std::string&		description,
844dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch													  const deUint32			bufferSize,
857c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha													  const glu::GLSLVersion	glslVersion,
867c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha													  const bool				useDeviceGroups)
877c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
884dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	: TestCase			(testCtx, name, description)
894dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	, m_bufferSize		(bufferSize)
904dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	, m_glslVersion		(glslVersion)
917c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	, m_useDeviceGroups	(useDeviceGroups)
924dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch{
934dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch}
944dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
954dd3ea3dead37d80a50291f80f4a7055511735a9Kantochvoid BufferSparseResidencyCase::initPrograms (SourceCollections& sourceCollections) const
964dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch{
974dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	const char* const	versionDecl		= glu::getGLSLVersionDeclaration(m_glslVersion);
984dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	const deUint32		iterationsCount = m_bufferSize / SIZE_OF_UINT_IN_SHADER;
994dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
1004dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	std::ostringstream src;
1014dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
1024dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	src << versionDecl << "\n"
1034dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1044dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "layout(set = 0, binding = 0, std430) readonly buffer Input\n"
1054dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "{\n"
1064dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "	uint data[];\n"
1074dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "} sb_in;\n"
1084dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "\n"
1094dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "layout(set = 0, binding = 1, std430) writeonly buffer Output\n"
1104dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "{\n"
1114dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "	uint result[];\n"
1124dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "} sb_out;\n"
1134dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "\n"
1144dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "void main (void)\n"
1154dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "{\n"
1164dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "	for(int i=0; i<" << iterationsCount << "; ++i) \n"
1174dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "	{\n"
1184dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "		sb_out.result[i] = sb_in.data[i];"
1194dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "	}\n"
1204dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		<< "}\n";
1214dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
1224dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	sourceCollections.glslSources.add("comp") << glu::ComputeSource(src.str());
1234dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch}
1244dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
1254dd3ea3dead37d80a50291f80f4a7055511735a9Kantochclass BufferSparseResidencyInstance : public SparseResourcesBaseInstance
1264dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch{
1274dd3ea3dead37d80a50291f80f4a7055511735a9Kantochpublic:
1284dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch					BufferSparseResidencyInstance	(Context&			context,
1297c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha													 const deUint32		bufferSize,
1307c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha													 const bool			useDeviceGroups);
1314dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
1324dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	tcu::TestStatus	iterate							(void);
1334dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
1344dd3ea3dead37d80a50291f80f4a7055511735a9Kantochprivate:
1354dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	const deUint32	m_bufferSize;
1367c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	const deUint32	m_useDeviceGroups;
1374dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch};
1384dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
1394dd3ea3dead37d80a50291f80f4a7055511735a9KantochBufferSparseResidencyInstance::BufferSparseResidencyInstance (Context&			context,
1407c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha															  const deUint32	bufferSize,
1417c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha															  const bool		useDeviceGroups)
1424dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	: SparseResourcesBaseInstance	(context)
1434dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	, m_bufferSize					(bufferSize)
1447c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	, m_useDeviceGroups				(useDeviceGroups)
1454dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch{
1464dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch}
1474dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
1484dd3ea3dead37d80a50291f80f4a7055511735a9Kantochtcu::TestStatus BufferSparseResidencyInstance::iterate (void)
1494dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch{
150199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch	const InstanceInterface&		 instance					= m_context.getInstanceInterface();
1514dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	{
152199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		// Create logical device supporting both sparse and compute operations
153199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		QueueRequirementsVec queueRequirements;
154199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		queueRequirements.push_back(QueueRequirements(VK_QUEUE_SPARSE_BINDING_BIT, 1u));
155199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		queueRequirements.push_back(QueueRequirements(VK_QUEUE_COMPUTE_BIT, 1u));
1564dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
157199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		createDeviceSupportingQueues(queueRequirements);
1584dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	}
1597c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	const VkPhysicalDevice			 physicalDevice				= getPhysicalDevice();
1607c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	const VkPhysicalDeviceProperties physicalDeviceProperties	= getPhysicalDeviceProperties(instance, physicalDevice);
1617c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
1627c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	if (!getPhysicalDeviceFeatures(instance, physicalDevice).sparseResidencyBuffer)
1637c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		TCU_THROW(NotSupportedError, "Sparse partially resident buffers not supported");
1644dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
1650d621e6dd1cce20b9d5d2826b996d923a2305f4cMaciej Jesionowski	const DeviceInterface&	deviceInterface	= getDeviceInterface();
1660d621e6dd1cce20b9d5d2826b996d923a2305f4cMaciej Jesionowski	const Queue&			sparseQueue		= getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
1670d621e6dd1cce20b9d5d2826b996d923a2305f4cMaciej Jesionowski	const Queue&			computeQueue	= getQueue(VK_QUEUE_COMPUTE_BIT, 0);
1684dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
1697c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	// Go through all physical devices
1707c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	for (deUint32 physDevID = 0; physDevID < m_numPhysicalDevices; physDevID++)
1714dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	{
1727c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const deUint32	firstDeviceID	= physDevID;
1737c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const deUint32	secondDeviceID	= (firstDeviceID + 1) % m_numPhysicalDevices;
1744dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
1757c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		VkBufferCreateInfo bufferCreateInfo =
1767c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		{
1777c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
1787c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			DE_NULL,								// const void*			pNext;
1797c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			VK_BUFFER_CREATE_SPARSE_BINDING_BIT |
1807c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,	// VkBufferCreateFlags	flags;
1817c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			m_bufferSize,							// VkDeviceSize			size;
1827c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
1837c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,		// VkBufferUsageFlags	usage;
1847c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1857c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			0u,										// deUint32				queueFamilyIndexCount;
1867c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			DE_NULL									// const deUint32*		pQueueFamilyIndices;
1877c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		};
1884dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
1897c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const deUint32 queueFamilyIndices[] = { sparseQueue.queueFamilyIndex, computeQueue.queueFamilyIndex };
1904dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
1917c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		if (sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex)
1927c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		{
1937c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			bufferCreateInfo.sharingMode			= VK_SHARING_MODE_CONCURRENT;
1947c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			bufferCreateInfo.queueFamilyIndexCount	= 2u;
1957c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			bufferCreateInfo.pQueueFamilyIndices	= queueFamilyIndices;
1967c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		}
1974dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
1987c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		// Create sparse buffer
1997c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const Unique<VkBuffer> sparseBuffer(createBuffer(deviceInterface, getDevice(), &bufferCreateInfo));
2004dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2017c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		// Create sparse buffer memory bind semaphore
2027c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const Unique<VkSemaphore> bufferMemoryBindSemaphore(createSemaphore(deviceInterface, getDevice()));
2034dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2047c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const VkMemoryRequirements bufferMemRequirements = getBufferMemoryRequirements(deviceInterface, getDevice(), *sparseBuffer);
2054dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2067c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		if (bufferMemRequirements.size > physicalDeviceProperties.limits.sparseAddressSpaceSize)
2077c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			TCU_THROW(NotSupportedError, "Required memory size for sparse resources exceeds device limits");
2084dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2097c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		DE_ASSERT((bufferMemRequirements.size % bufferMemRequirements.alignment) == 0);
2104dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2117c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const deUint32				numSparseSlots = static_cast<deUint32>(bufferMemRequirements.size / bufferMemRequirements.alignment);
2127c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		std::vector<DeviceMemorySp>	deviceMemUniquePtrVec;
2134dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
214199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch		{
2157c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			std::vector<VkSparseMemoryBind>		sparseMemoryBinds;
2167c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			const deUint32						memoryType		= findMatchingMemoryType(instance, physicalDevice, bufferMemRequirements, MemoryRequirement::Any);
2177c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
2187c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			if (memoryType == NO_MATCH_FOUND)
2197c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				return tcu::TestStatus::fail("No matching memory type found");
2207c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
2217c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			for (deUint32 sparseBindNdx = 0; sparseBindNdx < numSparseSlots; sparseBindNdx += 2)
2227c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			{
2237c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				const VkSparseMemoryBind sparseMemoryBind = makeSparseMemoryBind(deviceInterface, getDevice(), bufferMemRequirements.alignment, memoryType, bufferMemRequirements.alignment * sparseBindNdx);
2247c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
2257c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				deviceMemUniquePtrVec.push_back(makeVkSharedPtr(Move<VkDeviceMemory>(check<VkDeviceMemory>(sparseMemoryBind.memory), Deleter<VkDeviceMemory>(deviceInterface, getDevice(), DE_NULL))));
2267c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
2277c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				sparseMemoryBinds.push_back(sparseMemoryBind);
2287c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			}
2297c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
2307c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			const VkSparseBufferMemoryBindInfo sparseBufferBindInfo = makeSparseBufferMemoryBindInfo(*sparseBuffer, static_cast<deUint32>(sparseMemoryBinds.size()), &sparseMemoryBinds[0]);
2317c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
23233b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			const VkDeviceGroupBindSparseInfo devGroupBindSparseInfo =
2337c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			{
2347c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR,	//VkStructureType							sType;
2357c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				DE_NULL,												//const void*								pNext;
2367c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				firstDeviceID,											//deUint32									resourceDeviceIndex;
2377c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				secondDeviceID,											//deUint32									memoryDeviceIndex;
2387c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			};
2397c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			const VkBindSparseInfo bindSparseInfo =
2407c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			{
2417c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,						//VkStructureType							sType;
2427c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				m_useDeviceGroups ? &devGroupBindSparseInfo : DE_NULL,	//const void*								pNext;
2437c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				0u,														//deUint32									waitSemaphoreCount;
2447c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				DE_NULL,												//const VkSemaphore*						pWaitSemaphores;
2457c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				1u,														//deUint32									bufferBindCount;
2467c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				&sparseBufferBindInfo,									//const VkSparseBufferMemoryBindInfo*		pBufferBinds;
2477c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				0u,														//deUint32									imageOpaqueBindCount;
2487c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				DE_NULL,												//const VkSparseImageOpaqueMemoryBindInfo*	pImageOpaqueBinds;
2497c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				0u,														//deUint32									imageBindCount;
2507c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				DE_NULL,												//const VkSparseImageMemoryBindInfo*		pImageBinds;
2517c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				1u,														//deUint32									signalSemaphoreCount;
2527c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				&bufferMemoryBindSemaphore.get()						//const VkSemaphore*						pSignalSemaphores;
2537c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			};
2547c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
2557c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			VK_CHECK(deviceInterface.queueBindSparse(sparseQueue.queueHandle, 1u, &bindSparseInfo, DE_NULL));
2567c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		}
2574dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2587c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		// Create input buffer
2597c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const VkBufferCreateInfo		inputBufferCreateInfo	= makeBufferCreateInfo(m_bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2607c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const Unique<VkBuffer>			inputBuffer				(createBuffer(deviceInterface, getDevice(), &inputBufferCreateInfo));
2617c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const de::UniquePtr<Allocation>	inputBufferAlloc		(bindBuffer(deviceInterface, getDevice(), getAllocator(), *inputBuffer, MemoryRequirement::HostVisible));
262a6fbec3926163fbfc0ad45b21f7b7e2f8aae7adfMaciej Jesionowski
2634dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2647c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		std::vector<deUint8> referenceData;
2657c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		referenceData.resize(m_bufferSize);
2664dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2677c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		for (deUint32 valueNdx = 0; valueNdx < m_bufferSize; ++valueNdx)
2687c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		{
2697c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			referenceData[valueNdx] = static_cast<deUint8>((valueNdx % bufferMemRequirements.alignment) + 1u);
2707c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		}
2714dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2727c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		deMemcpy(inputBufferAlloc->getHostPtr(), &referenceData[0], m_bufferSize);
2734dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2747c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		flushMappedMemoryRange(deviceInterface, getDevice(), inputBufferAlloc->getMemory(), inputBufferAlloc->getOffset(), m_bufferSize);
2754dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2767c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		// Create output buffer
2777c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const VkBufferCreateInfo		outputBufferCreateInfo	= makeBufferCreateInfo(m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
2787c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const Unique<VkBuffer>			outputBuffer			(createBuffer(deviceInterface, getDevice(), &outputBufferCreateInfo));
2797c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const de::UniquePtr<Allocation>	outputBufferAlloc		(bindBuffer(deviceInterface, getDevice(), getAllocator(), *outputBuffer, MemoryRequirement::HostVisible));
2804dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2817c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		// Create command buffer for compute and data transfer oparations
2827c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const Unique<VkCommandPool>	  commandPool(makeCommandPool(deviceInterface, getDevice(), computeQueue.queueFamilyIndex));
2837c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const Unique<VkCommandBuffer> commandBuffer(allocateCommandBuffer(deviceInterface, getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2844dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2857c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		// Start recording compute and transfer commands
2867c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		beginCommandBuffer(deviceInterface, *commandBuffer);
2874dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2887c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		// Create descriptor set
2897c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const Unique<VkDescriptorSetLayout> descriptorSetLayout(
2907c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			DescriptorSetLayoutBuilder()
2917c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
2927c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
2937c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			.build(deviceInterface, getDevice()));
2944dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
2957c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		// Create compute pipeline
2967c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const Unique<VkShaderModule>	shaderModule(createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("comp"), DE_NULL));
2977c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const Unique<VkPipelineLayout>	pipelineLayout(makePipelineLayout(deviceInterface, getDevice(), *descriptorSetLayout));
2987c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const Unique<VkPipeline>		computePipeline(makeComputePipeline(deviceInterface, getDevice(), *pipelineLayout, *shaderModule));
2994dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3007c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
3014dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3027c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const Unique<VkDescriptorPool> descriptorPool(
3037c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			DescriptorPoolBuilder()
3047c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2u)
3057c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			.build(deviceInterface, getDevice(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
3064dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3077c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(deviceInterface, getDevice(), *descriptorPool, *descriptorSetLayout));
3084dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3097c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		{
3107c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			const VkDescriptorBufferInfo inputBufferInfo = makeDescriptorBufferInfo(*inputBuffer, 0ull, m_bufferSize);
3117c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			const VkDescriptorBufferInfo sparseBufferInfo = makeDescriptorBufferInfo(*sparseBuffer, 0ull, m_bufferSize);
3124dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3137c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			DescriptorSetUpdateBuilder()
3147c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputBufferInfo)
3157c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &sparseBufferInfo)
3167c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				.update(deviceInterface, getDevice());
3177c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		}
3184dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3197c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		deviceInterface.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
320a15e7d7f566d93c76ca90171eb728e3d1cd82378Pyry Haulos
3217c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		{
3227c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			const VkBufferMemoryBarrier inputBufferBarrier
3237c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				= makeBufferMemoryBarrier(	VK_ACCESS_HOST_WRITE_BIT,
3247c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha											VK_ACCESS_SHADER_READ_BIT,
3257c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha											*inputBuffer,
3267c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha											0ull,
3277c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha											m_bufferSize);
3287c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
3297c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, DE_NULL, 1u, &inputBufferBarrier, 0u, DE_NULL);
3307c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		}
3314dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3327c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		deviceInterface.cmdDispatch(*commandBuffer, 1u, 1u, 1u);
3334dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3347c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		{
3357c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			const VkBufferMemoryBarrier sparseBufferBarrier
3367c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				= makeBufferMemoryBarrier(	VK_ACCESS_SHADER_WRITE_BIT,
3377c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha											VK_ACCESS_TRANSFER_READ_BIT,
3387c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha											*sparseBuffer,
3397c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha											0ull,
3407c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha											m_bufferSize);
3417c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
3427c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 1u, &sparseBufferBarrier, 0u, DE_NULL);
3437c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		}
3444dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3457c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		{
3467c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			const VkBufferCopy bufferCopy = makeBufferCopy(0u, 0u, m_bufferSize);
3474dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3487c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			deviceInterface.cmdCopyBuffer(*commandBuffer, *sparseBuffer, *outputBuffer, 1u, &bufferCopy);
3497c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		}
3504dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3517c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		{
3527c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			const VkBufferMemoryBarrier outputBufferBarrier
3537c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				= makeBufferMemoryBarrier(	VK_ACCESS_TRANSFER_WRITE_BIT,
3547c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha											VK_ACCESS_HOST_READ_BIT,
3557c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha											*outputBuffer,
3567c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha											0ull,
3577c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha											m_bufferSize);
3587c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
3597c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &outputBufferBarrier, 0u, DE_NULL);
3607c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		}
3614dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3627c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		// End recording compute and transfer commands
3637c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		endCommandBuffer(deviceInterface, *commandBuffer);
3644dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3657c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const VkPipelineStageFlags waitStageBits[] = { VK_PIPELINE_STAGE_TRANSFER_BIT };
3664dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3677c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		// Submit transfer commands for execution and wait for completion
3687c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		submitCommandsAndWait(deviceInterface, getDevice(), computeQueue.queueHandle, *commandBuffer, 1u, &bufferMemoryBindSemaphore.get(),
3697c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			waitStageBits, 0, DE_NULL, m_useDeviceGroups, firstDeviceID);
3704dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3717c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		// Retrieve data from output buffer to host memory
3727c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		invalidateMappedMemoryRange(deviceInterface, getDevice(), outputBufferAlloc->getMemory(), outputBufferAlloc->getOffset(), m_bufferSize);
373199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch
3747c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		const deUint8* outputData = static_cast<const deUint8*>(outputBufferAlloc->getHostPtr());
3754dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
3767c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		// Wait for sparse queue to become idle
3777c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		deviceInterface.queueWaitIdle(sparseQueue.queueHandle);
378199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch
3797c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		// Compare output data with reference data
3807c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha		for (deUint32 sparseBindNdx = 0; sparseBindNdx < numSparseSlots; ++sparseBindNdx)
3814dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		{
3827c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			const deUint32 alignment = static_cast<deUint32>(bufferMemRequirements.alignment);
3837c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			const deUint32 offset	 = alignment * sparseBindNdx;
3847c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			const deUint32 size		 = sparseBindNdx == (numSparseSlots - 1) ? m_bufferSize % alignment : alignment;
3857c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
3867c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			if (sparseBindNdx % 2u == 0u)
3877c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			{
3887c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				if (deMemCmp(&referenceData[offset], outputData + offset, size) != 0)
3897c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha					return tcu::TestStatus::fail("Failed");
3907c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			}
3917c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			else if (physicalDeviceProperties.sparseProperties.residencyNonResidentStrict)
3927c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			{
3937c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				deMemset(&referenceData[offset], 0u, size);
3947c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha
3957c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha				if (deMemCmp(&referenceData[offset], outputData + offset, size) != 0)
3967c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha					return tcu::TestStatus::fail("Failed");
3977c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha			}
3984dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch		}
3994dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch	}
4004dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
401199c73a9eb28e6ef553e30bdf6b766198a65e796Kantoch	return tcu::TestStatus::pass("Passed");
4024dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch}
4034dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
4044dd3ea3dead37d80a50291f80f4a7055511735a9KantochTestInstance* BufferSparseResidencyCase::createInstance (Context& context) const
4054dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch{
4067c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	return new BufferSparseResidencyInstance(context, m_bufferSize, m_useDeviceGroups);
4074dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch}
4084dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
4094dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch} // anonymous ns
4104dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
4117c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwahavoid addBufferSparseResidencyTests(tcu::TestCaseGroup* group, const bool useDeviceGroups)
4124dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch{
4137c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	group->addChild(new BufferSparseResidencyCase(group->getTestContext(), "buffer_size_2_10", "", 1 << 10, glu::GLSL_VERSION_440, useDeviceGroups));
4147c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	group->addChild(new BufferSparseResidencyCase(group->getTestContext(), "buffer_size_2_12", "", 1 << 12, glu::GLSL_VERSION_440, useDeviceGroups));
4157c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	group->addChild(new BufferSparseResidencyCase(group->getTestContext(), "buffer_size_2_16", "", 1 << 16, glu::GLSL_VERSION_440, useDeviceGroups));
4167c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	group->addChild(new BufferSparseResidencyCase(group->getTestContext(), "buffer_size_2_17", "", 1 << 17, glu::GLSL_VERSION_440, useDeviceGroups));
4177c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	group->addChild(new BufferSparseResidencyCase(group->getTestContext(), "buffer_size_2_20", "", 1 << 20, glu::GLSL_VERSION_440, useDeviceGroups));
4187c0af777b06f12a3f0bbf703f71850303726e3dfVikram Kushwaha	group->addChild(new BufferSparseResidencyCase(group->getTestContext(), "buffer_size_2_24", "", 1 << 24, glu::GLSL_VERSION_440, useDeviceGroups));
4194dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch}
4204dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch
4214dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch} // sparse
4224dd3ea3dead37d80a50291f80f4a7055511735a9Kantoch} // vkt
423