1/*------------------------------------------------------------------------
2 *  Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Vulkan Buffer View Creation Tests
23 *//*--------------------------------------------------------------------*/
24
25#include "vktApiBufferViewCreateTests.hpp"
26
27#include "deStringUtil.hpp"
28#include "gluVarType.hpp"
29#include "tcuTestLog.hpp"
30#include "vkPrograms.hpp"
31#include "vkRefUtil.hpp"
32#include "vktTestCase.hpp"
33
34namespace vkt
35{
36
37using namespace vk;
38
39namespace api
40{
41
42namespace
43{
44
45struct BufferViewCaseParameters
46{
47	VkFormat				format;
48	VkDeviceSize			offset;
49	VkDeviceSize			range;
50	VkBufferUsageFlags		usage;
51	VkFormatFeatureFlags	features;
52};
53
54class BufferViewTestInstance : public TestInstance
55{
56public:
57								BufferViewTestInstance		(Context&					ctx,
58															 BufferViewCaseParameters	createInfo);
59	virtual tcu::TestStatus		iterate						(void);
60
61private:
62	BufferViewCaseParameters		m_testCase;
63};
64
65class BufferViewTestCase : public TestCase
66{
67public:
68							BufferViewTestCase		(tcu::TestContext&			testCtx,
69													 const std::string&			name,
70													 const std::string&			description,
71													 BufferViewCaseParameters	createInfo)
72								: TestCase			(testCtx, name, description)
73								, m_testCase		(createInfo)
74							{}
75
76	virtual					~BufferViewTestCase		(void) {}
77	virtual TestInstance*	createInstance			(Context&	ctx) const
78							{
79								return new BufferViewTestInstance(ctx, m_testCase);
80							}
81
82private:
83	BufferViewCaseParameters	m_testCase;
84};
85
86BufferViewTestInstance::BufferViewTestInstance (Context&					ctx,
87												BufferViewCaseParameters	createInfo)
88	: TestInstance	(ctx)
89	, m_testCase	(createInfo)
90{
91}
92
93tcu::TestStatus BufferViewTestInstance::iterate (void)
94{
95	// Create buffer
96	const VkDevice				vkDevice				= m_context.getDevice();
97	const DeviceInterface&		vk						= m_context.getDeviceInterface();
98	const deUint32				queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
99	const VkDeviceSize			size					= 3 * 5 * 7 * 64;
100	Move<VkBuffer>				testBuffer;
101	VkMemoryRequirements		memReqs;
102	VkFormatProperties			properties;
103	const VkBufferCreateInfo	bufferParams =
104	{
105		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,													//	VkStructureType			sType;
106		DE_NULL,																				//	const void*				pNext;
107		0u,																						//	VkBufferCreateFlags		flags;
108		size,																					//	VkDeviceSize			size;
109		m_testCase.usage,																		//	VkBufferUsageFlags		usage;
110		VK_SHARING_MODE_EXCLUSIVE,																//	VkSharingMode			sharingMode;
111		1u,																						//	deUint32				queueFamilyCount;
112		&queueFamilyIndex,																		//	const deUint32*			pQueueFamilyIndices;
113	};
114
115	m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), m_testCase.format, &properties);
116	if (!(properties.bufferFeatures & m_testCase.features))
117		TCU_THROW(NotSupportedError, "Format not supported");
118
119	try
120	{
121		testBuffer = createBuffer(vk, vkDevice, &bufferParams, (const VkAllocationCallbacks*)DE_NULL);
122	}
123	catch (const vk::Error& error)
124	{
125		return tcu::TestStatus::fail("Buffer creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
126	}
127
128	vk.getBufferMemoryRequirements(vkDevice, *testBuffer, &memReqs);
129
130	if (size > memReqs.size)
131	{
132		std::ostringstream errorMsg;
133		errorMsg << "Requied memory size (" << memReqs.size << " bytes) smaller than the buffer's size (" << size << " bytes)!";
134		return tcu::TestStatus::fail(errorMsg.str());
135	}
136
137	Move<VkDeviceMemory>		memory;
138	const VkMemoryAllocateInfo	memAlloc				=
139	{
140		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,		//	VkStructureType		sType
141		NULL,										//	const void*			pNext
142		memReqs.size,								//	VkDeviceSize		allocationSize
143		(deUint32)deCtz32(memReqs.memoryTypeBits)	//	deUint32			memoryTypeIndex
144	};
145
146	{
147		// Create buffer view.
148		Move<VkBufferView>				bufferView;
149		const VkBufferViewCreateInfo	bufferViewCreateInfo	=
150		{
151			VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,	//	VkStructureType		sType;
152			NULL,										//	const void*			pNext;
153			(VkBufferViewCreateFlags)0,
154			*testBuffer,								//	VkBuffer			buffer;
155			m_testCase.format,							//	VkFormat			format;
156			m_testCase.offset,							//	VkDeviceSize		offset;
157			m_testCase.range,							//	VkDeviceSize		range;
158		};
159
160		try
161		{
162			memory = allocateMemory(vk, vkDevice, &memAlloc, (const VkAllocationCallbacks*)DE_NULL);
163		}
164		catch (const vk::Error& error)
165		{
166			return tcu::TestStatus::fail("Alloc memory failed! (Error code: " + de::toString(error.getMessage()) + ")");
167		}
168
169		if (vk.bindBufferMemory(vkDevice, *testBuffer, *memory, 0) != VK_SUCCESS)
170			return tcu::TestStatus::fail("Bind buffer memory failed!");
171
172		try
173		{
174			bufferView = createBufferView(vk, vkDevice, &bufferViewCreateInfo, (const VkAllocationCallbacks*)DE_NULL);
175		}
176		catch (const vk::Error& error)
177		{
178			return tcu::TestStatus::fail("Buffer View creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
179		}
180	}
181
182	// Testing complete view size.
183	{
184		Move<VkBufferView>		completeBufferView;
185		VkBufferViewCreateInfo	completeBufferViewCreateInfo	=
186		{
187			VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,	//	VkStructureType		sType;
188			NULL,										//	const void*			pNext;
189			(VkBufferViewCreateFlags)0,
190			*testBuffer,								//	VkBuffer			buffer;
191			m_testCase.format,							//	VkFormat			format;
192			m_testCase.offset,							//	VkDeviceSize		offset;
193			size,										//	VkDeviceSize		range;
194		};
195
196		try
197		{
198			completeBufferView = createBufferView(vk, vkDevice, &completeBufferViewCreateInfo, (const VkAllocationCallbacks*)DE_NULL);
199		}
200		catch (const vk::Error& error)
201		{
202			return tcu::TestStatus::fail("Buffer View creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
203		}
204	}
205
206	return tcu::TestStatus::pass("BufferView test");
207}
208
209} // anonymous
210
211 tcu::TestCaseGroup* createBufferViewCreateTests (tcu::TestContext& testCtx)
212{
213	de::MovePtr<tcu::TestCaseGroup>	bufferViewTests	(new tcu::TestCaseGroup(testCtx, "create", "BufferView Construction Tests"));
214
215	const VkDeviceSize range = VK_WHOLE_SIZE;
216	for (deUint32 format = VK_FORMAT_UNDEFINED + 1; format < VK_FORMAT_LAST; format++)
217	{
218		std::ostringstream	testName;
219		std::ostringstream	testDescription;
220		testName << "createBufferView_" << format;
221		testDescription << "vkBufferView test " << testName.str();
222		{
223			BufferViewCaseParameters testParams	=
224			{
225				(VkFormat)format,							// VkFormat				format;
226				0,											// VkDeviceSize			offset;
227				range,										// VkDeviceSize			range;
228				VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,	// VkBufferUsageFlags	usage;
229				VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, // VkFormatFeatureFlags flags;
230			};
231			bufferViewTests->addChild(new BufferViewTestCase(testCtx, testName.str() + "_uniform", testDescription.str(), testParams));
232		}
233		{
234			BufferViewCaseParameters testParams	=
235			{
236				(VkFormat)format,							// VkFormat				format;
237				0,											// VkDeviceSize			offset;
238				range,										// VkDeviceSize			range;
239				VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,	// VkBufferUsageFlags	usage;
240				VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT, // VkFormatFeatureFlags flags;
241			};
242			bufferViewTests->addChild(new BufferViewTestCase(testCtx, testName.str() + "_storage", testDescription.str(), testParams));
243		}
244	}
245
246	return bufferViewTests.release();
247}
248
249} // api
250} // vk
251