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 
34 namespace vkt
35 {
36 
37 using namespace vk;
38 
39 namespace api
40 {
41 
42 namespace
43 {
44 
45 struct BufferViewCaseParameters
46 {
47 	VkFormat				format;
48 	VkDeviceSize			offset;
49 	VkDeviceSize			range;
50 	VkBufferUsageFlags		usage;
51 	VkFormatFeatureFlags	features;
52 };
53 
54 class BufferViewTestInstance : public TestInstance
55 {
56 public:
57 								BufferViewTestInstance		(Context&					ctx,
58 															 BufferViewCaseParameters	createInfo);
59 	virtual tcu::TestStatus		iterate						(void);
60 
61 private:
62 	BufferViewCaseParameters		m_testCase;
63 };
64 
65 class BufferViewTestCase : public TestCase
66 {
67 public:
BufferViewTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,BufferViewCaseParameters createInfo)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 
~BufferViewTestCase(void)76 	virtual					~BufferViewTestCase		(void) {}
createInstance(Context & ctx) const77 	virtual TestInstance*	createInstance			(Context&	ctx) const
78 							{
79 								return new BufferViewTestInstance(ctx, m_testCase);
80 							}
81 
82 private:
83 	BufferViewCaseParameters	m_testCase;
84 };
85 
BufferViewTestInstance(Context & ctx,BufferViewCaseParameters createInfo)86 BufferViewTestInstance::BufferViewTestInstance (Context&					ctx,
87 												BufferViewCaseParameters	createInfo)
88 	: TestInstance	(ctx)
89 	, m_testCase	(createInfo)
90 {
91 }
92 
iterate(void)93 tcu::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 
createBufferViewCreateTests(tcu::TestContext & testCtx)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