128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa/*------------------------------------------------------------------------
228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa * Vulkan Conformance Tests
328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa * ------------------------
428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa *
528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa * Copyright (c) 2016 The Khronos Group Inc.
628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa *
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
1028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa *
11978d3d585aa549eb1e729b51e9d85fc6477240f9Pyry Haulos *      http://www.apache.org/licenses/LICENSE-2.0
1228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa *
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.
1828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa *
1928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa *//*!
2028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa * \file  vktSparseResourcesBufferMemoryAliasing.cpp
2128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa * \brief Sparse buffer memory aliasing tests
2228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa *//*--------------------------------------------------------------------*/
2328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
2428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "vktSparseResourcesBufferMemoryAliasing.hpp"
2528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "vktSparseResourcesTestsUtil.hpp"
2628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "vktSparseResourcesBase.hpp"
2728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "vktTestCaseUtil.hpp"
2828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
2928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "vkDefs.hpp"
3028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "vkRef.hpp"
3128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "vkRefUtil.hpp"
3228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "vkPlatform.hpp"
3328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "vkPrograms.hpp"
3428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "vkRefUtil.hpp"
3528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "vkMemUtil.hpp"
3628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "vkQueryUtil.hpp"
3728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "vkBuilderUtil.hpp"
3828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "vkTypeUtil.hpp"
3928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
4028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "deStringUtil.hpp"
4128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include "deUniquePtr.hpp"
4228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
4328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include <string>
4428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa#include <vector>
4528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
4628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwausing namespace vk;
4728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
4828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwanamespace vkt
4928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa{
5028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwanamespace sparse
5128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa{
5228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwanamespace
5328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa{
5428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
5528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwaenum ShaderParameters
5628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa{
5728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	SIZE_OF_UINT_IN_SHADER	= 4u,
5828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	MODULO_DIVISOR			= 1024u
5928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa};
6028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
6128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwatcu::UVec3 computeWorkGroupSize (const deUint32 numInvocations)
6228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa{
6328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint32		maxComputeWorkGroupInvocations	= 128u;
6428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const tcu::UVec3	maxComputeWorkGroupSize			= tcu::UVec3(128u, 128u, 64u);
6528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	deUint32			numInvocationsLeft				= numInvocations;
6628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
6728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint32 xWorkGroupSize = std::min(std::min(numInvocationsLeft, maxComputeWorkGroupSize.x()), maxComputeWorkGroupInvocations);
6828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	numInvocationsLeft = numInvocationsLeft / xWorkGroupSize + ((numInvocationsLeft % xWorkGroupSize) ? 1u : 0u);
6928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
7028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint32 yWorkGroupSize = std::min(std::min(numInvocationsLeft, maxComputeWorkGroupSize.y()), maxComputeWorkGroupInvocations / xWorkGroupSize);
7128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	numInvocationsLeft = numInvocationsLeft / yWorkGroupSize + ((numInvocationsLeft % yWorkGroupSize) ? 1u : 0u);
7228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
7328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint32 zWorkGroupSize = std::min(std::min(numInvocationsLeft, maxComputeWorkGroupSize.z()), maxComputeWorkGroupInvocations / (xWorkGroupSize*yWorkGroupSize));
7428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	numInvocationsLeft = numInvocationsLeft / zWorkGroupSize + ((numInvocationsLeft % zWorkGroupSize) ? 1u : 0u);
7528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
7628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	return tcu::UVec3(xWorkGroupSize, yWorkGroupSize, zWorkGroupSize);
7728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa}
7828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
7928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwaclass BufferSparseMemoryAliasingCase : public TestCase
8028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa{
8128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwapublic:
8228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa					BufferSparseMemoryAliasingCase	(tcu::TestContext&		testCtx,
8328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa													 const std::string&		name,
8428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa													 const std::string&		description,
8528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa													 const deUint32			bufferSize,
8628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa													 const glu::GLSLVersion	glslVersion);
8728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
8828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	void			initPrograms					(SourceCollections&		sourceCollections) const;
8928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	TestInstance*	createInstance					(Context&				context) const;
9028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
9128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwaprivate:
9228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const	deUint32			m_bufferSizeInBytes;
9328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const	glu::GLSLVersion	m_glslVersion;
9428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa};
9528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
9628211119da9f35d211e1c51959dce5835054fc1aArkadiusz SarwaBufferSparseMemoryAliasingCase::BufferSparseMemoryAliasingCase (tcu::TestContext&		testCtx,
9728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa																const std::string&		name,
9828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa																const std::string&		description,
9928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa																const deUint32			bufferSize,
10028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa																const glu::GLSLVersion	glslVersion)
10128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	: TestCase				(testCtx, name, description)
10228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	, m_bufferSizeInBytes	(bufferSize)
10328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	, m_glslVersion			(glslVersion)
10428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa{
10528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa}
10628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
10728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwavoid BufferSparseMemoryAliasingCase::initPrograms (SourceCollections& sourceCollections) const
10828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa{
10928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Create compute program
11028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const char* const versionDecl		= glu::getGLSLVersionDeclaration(m_glslVersion);
11128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint32	  numInvocations	= m_bufferSizeInBytes / SIZE_OF_UINT_IN_SHADER;
11228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const tcu::UVec3  workGroupSize		= computeWorkGroupSize(numInvocations);
11328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
11428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	std::ostringstream src;
11528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	src << versionDecl << "\n"
11628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		<< "layout (local_size_x = " << workGroupSize.x() << ", local_size_y = " << workGroupSize.y() << ", local_size_z = " << workGroupSize.z() << ") in;\n"
11728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		<< "layout(set = 0, binding = 0, std430) writeonly buffer Output\n"
11828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		<< "{\n"
11928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		<< "	uint result[];\n"
12028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		<< "} sb_out;\n"
12128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		<< "\n"
12228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		<< "void main (void)\n"
12328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		<< "{\n"
12428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		<< "	uint index = gl_GlobalInvocationID.x + (gl_GlobalInvocationID.y + gl_GlobalInvocationID.z*gl_NumWorkGroups.y*gl_WorkGroupSize.y)*gl_NumWorkGroups.x*gl_WorkGroupSize.x;\n"
12528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		<< "	if ( index < " << m_bufferSizeInBytes / SIZE_OF_UINT_IN_SHADER << "u )\n"
12628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		<< "	{\n"
12728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		<< "		sb_out.result[index] = index % " << MODULO_DIVISOR << "u;\n"
12828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		<< "	}\n"
12928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		<< "}\n";
13028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
13128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	sourceCollections.glslSources.add("comp") << glu::ComputeSource(src.str());
13228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa}
13328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
13428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwaclass BufferSparseMemoryAliasingInstance : public SparseResourcesBaseInstance
13528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa{
13628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwapublic:
13728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa					BufferSparseMemoryAliasingInstance	(Context&					context,
13828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa														 const deUint32				bufferSize);
13928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
14028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	tcu::TestStatus	iterate								(void);
14128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
14228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwaprivate:
14328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint32			m_bufferSizeInBytes;
14428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa};
14528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
14628211119da9f35d211e1c51959dce5835054fc1aArkadiusz SarwaBufferSparseMemoryAliasingInstance::BufferSparseMemoryAliasingInstance (Context&					context,
14728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa																		const deUint32			bufferSize)
14828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	: SparseResourcesBaseInstance	(context)
14928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	, m_bufferSizeInBytes			(bufferSize)
15028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa{
15128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa}
15228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
15328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwatcu::TestStatus BufferSparseMemoryAliasingInstance::iterate (void)
15428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa{
15528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const InstanceInterface&		instance		= m_context.getInstanceInterface();
15628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const DeviceInterface&			deviceInterface	= m_context.getDeviceInterface();
15728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkPhysicalDevice			physicalDevice	= m_context.getPhysicalDevice();
15828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkPhysicalDeviceFeatures	deviceFeatures	= getPhysicalDeviceFeatures(instance, physicalDevice);
15928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
16028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	if (deviceFeatures.sparseBinding == false)
16128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	{
16228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Sparse binding not supported");
16328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	}
16428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
16528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	if (deviceFeatures.sparseResidencyAliased == false)
16628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	{
16728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Sparse memory aliasing not supported");
16828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	}
16928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
17028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	QueueRequirementsVec queueRequirements;
17128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	queueRequirements.push_back(QueueRequirements(VK_QUEUE_SPARSE_BINDING_BIT, 1u));
17228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	queueRequirements.push_back(QueueRequirements(VK_QUEUE_COMPUTE_BIT, 1u));
17328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
17428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Create logical device supporting both sparse and compute oprations
17528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	if (!createDeviceSupportingQueues(queueRequirements))
17628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	{
17728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Could not create device supporting sparse and compute queue");
17828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	}
17928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
18028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
18128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
18228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Create memory allocator for device
18328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const de::UniquePtr<Allocator> allocator(new SimpleAllocator(deviceInterface, *m_logicalDevice, deviceMemoryProperties));
18428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
18528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Create queue supporting sparse binding operations
18628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const Queue& sparseQueue = getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
18728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
18828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Create queue supporting compute and transfer operations
18928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const Queue& computeQueue = getQueue(VK_QUEUE_COMPUTE_BIT, 0);
19028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
19128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	VkBufferCreateInfo bufferCreateInfo =
19228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	{
19328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
19428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		DE_NULL,								// const void*			pNext;
19528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		VK_BUFFER_CREATE_SPARSE_BINDING_BIT |
19628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,	// VkBufferCreateFlags	flags;
19728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		m_bufferSizeInBytes,					// VkDeviceSize			size;
19828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
19928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		VK_BUFFER_USAGE_TRANSFER_SRC_BIT,		// VkBufferUsageFlags	usage;
20028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
20128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		0u,										// deUint32				queueFamilyIndexCount;
20228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		DE_NULL									// const deUint32*		pQueueFamilyIndices;
20328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	};
20428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
20528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint32 queueFamilyIndices[] = { sparseQueue.queueFamilyIndex, computeQueue.queueFamilyIndex };
20628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
20728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	if (sparseQueue.queueFamilyIndex != computeQueue.queueFamilyIndex)
20828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	{
20928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		bufferCreateInfo.sharingMode			= VK_SHARING_MODE_CONCURRENT;
21028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		bufferCreateInfo.queueFamilyIndexCount	= 2u;
21128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		bufferCreateInfo.pQueueFamilyIndices	= queueFamilyIndices;
21228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	}
21328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
21428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Create sparse buffers
21528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const Unique<VkBuffer> sparseBufferWrite(createBuffer(deviceInterface, *m_logicalDevice, &bufferCreateInfo));
21628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const Unique<VkBuffer> sparseBufferRead	(createBuffer(deviceInterface, *m_logicalDevice, &bufferCreateInfo));
21728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
21828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkMemoryRequirements		 bufferMemRequirements = getBufferMemoryRequirements(deviceInterface, *m_logicalDevice, *sparseBufferWrite);
21928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkPhysicalDeviceProperties deviceProperties	   = getPhysicalDeviceProperties(instance, physicalDevice);
22028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
22128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	if (bufferMemRequirements.size > deviceProperties.limits.sparseAddressSpaceSize)
22228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	{
22328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Required memory size for sparse resources exceeds device limits");
22428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	}
22528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
22628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	DE_ASSERT((bufferMemRequirements.size % bufferMemRequirements.alignment) == 0);
22728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
22828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint32 memoryType = findMatchingMemoryType(deviceMemoryProperties, bufferMemRequirements, MemoryRequirement::Any);
22928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
23028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	if (memoryType == NO_MATCH_FOUND)
23128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	{
23228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		return tcu::TestStatus(QP_TEST_RESULT_FAIL, "No matching memory type found");
23328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	}
23428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
23528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkMemoryAllocateInfo allocInfo =
23628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	{
23728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,	//	VkStructureType			sType;
23828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		DE_NULL,								//	const void*				pNext;
23928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		bufferMemRequirements.size,				//	VkDeviceSize			allocationSize;
24028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		memoryType,								//	deUint32				memoryTypeIndex;
24128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	};
24228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
24328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	VkDeviceMemory deviceMemory;
24428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	VK_CHECK(deviceInterface.allocateMemory(*m_logicalDevice, &allocInfo, DE_NULL, &deviceMemory));
24528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
24628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	Move<VkDeviceMemory> deviceMemoryPtr(check<VkDeviceMemory>(deviceMemory), Deleter<VkDeviceMemory>(deviceInterface, *m_logicalDevice, DE_NULL));
24728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
24828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkSparseMemoryBind sparseMemoryBind = makeSparseMemoryBind
24928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	(
25028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		0u,							//VkDeviceSize				resourceOffset
25128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		bufferMemRequirements.size,	//VkDeviceSize				size
25228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		deviceMemory,				//VkDeviceMemory			memory
25328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		0u,							//VkDeviceSize				memoryOffset
25428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		0u							//VkSparseMemoryBindFlags	flags
25528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	);
25628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
25728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkSparseBufferMemoryBindInfo sparseBufferMemoryBindInfo[2] =
25828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	{
25928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		makeSparseBufferMemoryBindInfo
26028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		(*sparseBufferWrite,	//VkBuffer					buffer;
26128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		1u,						//deUint32					bindCount;
26228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		&sparseMemoryBind		//const VkSparseMemoryBind*	Binds;
26328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		),
26428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
26528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		makeSparseBufferMemoryBindInfo
26628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		(*sparseBufferRead,		//VkBuffer					buffer;
26728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		1u,						//deUint32					bindCount;
26828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		&sparseMemoryBind		//const VkSparseMemoryBind*	Binds;
26928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		)
27028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	};
27128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
27228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const Unique<VkSemaphore> bufferMemoryBindSemaphore(makeSemaphore(deviceInterface, *m_logicalDevice));
27328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
27428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkBindSparseInfo bindSparseInfo =
27528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	{
27628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,			//VkStructureType							sType;
27728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		DE_NULL,									//const void*								pNext;
27828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		0u,											//deUint32									waitSemaphoreCount;
27928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		DE_NULL,									//const VkSemaphore*						pWaitSemaphores;
28028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		2u,											//deUint32									bufferBindCount;
28128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		sparseBufferMemoryBindInfo,					//const VkSparseBufferMemoryBindInfo*		pBufferBinds;
28228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		0u,											//deUint32									imageOpaqueBindCount;
28328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		DE_NULL,									//const VkSparseImageOpaqueMemoryBindInfo*	pImageOpaqueBinds;
28428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		0u,											//deUint32									imageBindCount;
28528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		DE_NULL,									//const VkSparseImageMemoryBindInfo*		pImageBinds;
28628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		1u,											//deUint32									signalSemaphoreCount;
28728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		&bufferMemoryBindSemaphore.get()			//const VkSemaphore*						pSignalSemaphores;
28828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	};
28928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
29028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Submit sparse bind commands for execution
29128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	VK_CHECK(deviceInterface.queueBindSparse(sparseQueue.queueHandle, 1u, &bindSparseInfo, DE_NULL));
29228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
29328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Create output buffer
29428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkBufferCreateInfo outputBufferCreateInfo = makeBufferCreateInfo(m_bufferSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
29528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	de::UniquePtr<Buffer>	 outputBuffer(new Buffer(deviceInterface, *m_logicalDevice, *allocator, outputBufferCreateInfo, MemoryRequirement::HostVisible));
29628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
29728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Create command buffer for compute and data transfer oparations
29828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const Unique<VkCommandPool>	  commandPool(makeCommandPool(deviceInterface, *m_logicalDevice, computeQueue.queueFamilyIndex));
29928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, *m_logicalDevice, *commandPool));
30028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
30128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Start recording commands
30228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	beginCommandBuffer(deviceInterface, *commandBuffer);
30328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
30428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Create descriptor set
30528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const Unique<VkDescriptorSetLayout> descriptorSetLayout(
30628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		DescriptorSetLayoutBuilder()
30728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
30828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		.build(deviceInterface, *m_logicalDevice));
30928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
31028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Create compute pipeline
31128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const Unique<VkShaderModule>	shaderModule(createShaderModule(deviceInterface, *m_logicalDevice, m_context.getBinaryCollection().get("comp"), DE_NULL));
31228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const Unique<VkPipelineLayout>	pipelineLayout(makePipelineLayout(deviceInterface, *m_logicalDevice, *descriptorSetLayout));
31328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const Unique<VkPipeline>		computePipeline(makeComputePipeline(deviceInterface, *m_logicalDevice, *pipelineLayout, *shaderModule));
31428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
31528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
31628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
31728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Create descriptor set
31828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const Unique<VkDescriptorPool> descriptorPool(
31928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		DescriptorPoolBuilder()
32028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u)
32128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		.build(deviceInterface, *m_logicalDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
32228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
32328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(deviceInterface, *m_logicalDevice, *descriptorPool, *descriptorSetLayout));
32428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
32528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkDescriptorBufferInfo sparseBufferInfo = makeDescriptorBufferInfo(*sparseBufferWrite, 0u, m_bufferSizeInBytes);
32628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
32728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	DescriptorSetUpdateBuilder()
32828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &sparseBufferInfo)
32928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		.update(deviceInterface, *m_logicalDevice);
33028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
33128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	deviceInterface.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
33228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
33328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	deUint32		 numInvocationsLeft			= m_bufferSizeInBytes / SIZE_OF_UINT_IN_SHADER;
33428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const tcu::UVec3 workGroupSize				= computeWorkGroupSize(numInvocationsLeft);
33528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const tcu::UVec3 maxComputeWorkGroupCount	= tcu::UVec3(65535u, 65535u, 65535u);
33628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
33728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	numInvocationsLeft -= workGroupSize.x()*workGroupSize.y()*workGroupSize.z();
33828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
33928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint32	xWorkGroupCount = std::min(numInvocationsLeft, maxComputeWorkGroupCount.x());
34028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	numInvocationsLeft = numInvocationsLeft / xWorkGroupCount + ((numInvocationsLeft % xWorkGroupCount) ? 1u : 0u);
34128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint32	yWorkGroupCount = std::min(numInvocationsLeft, maxComputeWorkGroupCount.y());
34228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	numInvocationsLeft = numInvocationsLeft / yWorkGroupCount + ((numInvocationsLeft % yWorkGroupCount) ? 1u : 0u);
34328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint32	zWorkGroupCount = std::min(numInvocationsLeft, maxComputeWorkGroupCount.z());
34428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	numInvocationsLeft = numInvocationsLeft / zWorkGroupCount + ((numInvocationsLeft % zWorkGroupCount) ? 1u : 0u);
34528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
34628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	if (numInvocationsLeft != 1u)
34728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	{
34828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED, "Buffer size is not supported");
34928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	}
35028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
35128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	deviceInterface.cmdDispatch(*commandBuffer, xWorkGroupCount, yWorkGroupCount, zWorkGroupCount);
35228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
35328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkBufferMemoryBarrier sparseBufferWriteBarrier
35428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		= makeBufferMemoryBarrier(	VK_ACCESS_SHADER_WRITE_BIT,
35528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa									VK_ACCESS_TRANSFER_READ_BIT,
35628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa									*sparseBufferWrite,
35728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa									0ull,
35828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa									m_bufferSizeInBytes);
35928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
36028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 1u, &sparseBufferWriteBarrier, 0u, DE_NULL);
36128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
36228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkBufferCopy bufferCopy = makeBufferCopy(0u, 0u, m_bufferSizeInBytes);
36328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
36428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	deviceInterface.cmdCopyBuffer(*commandBuffer, *sparseBufferRead, outputBuffer->get(), 1u, &bufferCopy);
36528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
36628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkBufferMemoryBarrier outputBufferHostBarrier
36728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		= makeBufferMemoryBarrier(	VK_ACCESS_TRANSFER_WRITE_BIT,
36828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa									VK_ACCESS_HOST_READ_BIT,
36928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa									outputBuffer->get(),
37028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa									0ull,
37128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa									m_bufferSizeInBytes);
37228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
37328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &outputBufferHostBarrier, 0u, DE_NULL);
37428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
37528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// End recording commands
37628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	endCommandBuffer(deviceInterface, *commandBuffer);
37728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
37828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// The stage at which execution is going to wait for finish of sparse binding operations
37928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const VkPipelineStageFlags waitStageBits[] = { VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT };
38028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
38128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Submit commands for execution and wait for completion
38228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	submitCommandsAndWait(deviceInterface, *m_logicalDevice, computeQueue.queueHandle, *commandBuffer, 1u, &bufferMemoryBindSemaphore.get(), waitStageBits);
38328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
38428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Retrieve data from output buffer to host memory
38528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const Allocation& allocation = outputBuffer->getAllocation();
38628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
38728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	invalidateMappedMemoryRange(deviceInterface, *m_logicalDevice, allocation.getMemory(), allocation.getOffset(), m_bufferSizeInBytes);
38828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
38928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint8*	outputData = static_cast<const deUint8*>(allocation.getHostPtr());
39028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
39128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Prepare reference data
39228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	std::vector<deUint8> referenceData;
39328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	referenceData.resize(m_bufferSizeInBytes);
39428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
39528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	std::vector<deUint32> referenceDataBlock;
39628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	referenceDataBlock.resize(MODULO_DIVISOR);
39728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
39828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	for (deUint32 valueNdx = 0; valueNdx < MODULO_DIVISOR; ++valueNdx)
39928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	{
40028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		referenceDataBlock[valueNdx] = valueNdx % MODULO_DIVISOR;
40128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	}
40228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
40328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint32 fullBlockSizeInBytes = MODULO_DIVISOR * SIZE_OF_UINT_IN_SHADER;
40428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint32 lastBlockSizeInBytes = m_bufferSizeInBytes % fullBlockSizeInBytes;
40528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	const deUint32 numberOfBlocks		= m_bufferSizeInBytes / fullBlockSizeInBytes + (lastBlockSizeInBytes ? 1u : 0u);
40628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
40728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	for (deUint32 blockNdx = 0; blockNdx < numberOfBlocks; ++blockNdx)
40828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	{
40928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		const deUint32 offset = blockNdx * fullBlockSizeInBytes;
41028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		deMemcpy(&referenceData[0] + offset, &referenceDataBlock[0], ((offset + fullBlockSizeInBytes) <= m_bufferSizeInBytes) ? fullBlockSizeInBytes : lastBlockSizeInBytes);
41128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	}
41228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
41328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	tcu::TestStatus testStatus = tcu::TestStatus::pass("Passed");
41428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
41528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Compare reference data with output data
41628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	if (deMemCmp(&referenceData[0], outputData, m_bufferSizeInBytes) != 0)
41728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	{
41828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa		testStatus = tcu::TestStatus::fail("Failed");
41928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	}
42028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
42128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	// Wait for sparse queue to become idle
42228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	deviceInterface.queueWaitIdle(sparseQueue.queueHandle);
42328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
42428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	return testStatus;
42528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa}
42628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
42728211119da9f35d211e1c51959dce5835054fc1aArkadiusz SarwaTestInstance* BufferSparseMemoryAliasingCase::createInstance (Context& context) const
42828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa{
42928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	return new BufferSparseMemoryAliasingInstance(context, m_bufferSizeInBytes);
43028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa}
43128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
43228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa} // anonymous ns
43328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
43428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwatcu::TestCaseGroup* createBufferSparseMemoryAliasingTests (tcu::TestContext& testCtx)
43528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa{
43628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "buffer_sparse_memory_aliasing", "Sparse Buffer Memory Aliasing"));
43728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
43828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	testGroup->addChild(new BufferSparseMemoryAliasingCase(testCtx, "buffer_size_2_10", "", 1 << 10, glu::GLSL_VERSION_440));
43928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	testGroup->addChild(new BufferSparseMemoryAliasingCase(testCtx, "buffer_size_2_12", "", 1 << 12, glu::GLSL_VERSION_440));
44028211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	testGroup->addChild(new BufferSparseMemoryAliasingCase(testCtx, "buffer_size_2_16", "", 1 << 16, glu::GLSL_VERSION_440));
44128211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	testGroup->addChild(new BufferSparseMemoryAliasingCase(testCtx, "buffer_size_2_17", "", 1 << 17, glu::GLSL_VERSION_440));
44228211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	testGroup->addChild(new BufferSparseMemoryAliasingCase(testCtx, "buffer_size_2_20", "", 1 << 20, glu::GLSL_VERSION_440));
44328211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	testGroup->addChild(new BufferSparseMemoryAliasingCase(testCtx, "buffer_size_2_24", "", 1 << 24, glu::GLSL_VERSION_440));
44428211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
44528211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa	return testGroup.release();
44628211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa}
44728211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa
44828211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa} // sparse
44928211119da9f35d211e1c51959dce5835054fc1aArkadiusz Sarwa} // vkt
450