• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Memory Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktApiBufferViewAccessTests.hpp"
26 #include "vktApiBufferAndImageAllocationUtil.hpp"
27 
28 #include "deStringUtil.hpp"
29 #include "deUniquePtr.hpp"
30 #include "vktTestCase.hpp"
31 #include "vktTestCaseUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkRef.hpp"
37 #include "vkRefUtil.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuTexture.hpp"
43 #include "tcuTextureUtil.hpp"
44 #include "deSharedPtr.hpp"
45 
46 namespace vkt
47 {
48 
49 namespace api
50 {
51 
52 using namespace vk;
53 
54 namespace
55 {
56 
57 enum AllocationKind
58 {
59 	ALLOCATION_KIND_SUBALLOCATION										= 0,
60 	ALLOCATION_KIND_DEDICATED											= 1,
61 	ALLOCATION_KIND_LAST
62 };
63 
64 struct BufferViewCaseParams
65 {
66 	deUint32							bufferSize;
67 	deUint32							bufferViewSize;
68 	deUint32							elementOffset;
69 	AllocationKind						bufferAllocationKind;
70 	AllocationKind						imageAllocationKind;
71 };
72 
73 class BufferViewTestInstance : public vkt::TestInstance
74 {
75 public:
76 										BufferViewTestInstance			(Context&					context,
77 																		 BufferViewCaseParams		testCase);
78 	virtual								~BufferViewTestInstance			(void);
79 	virtual tcu::TestStatus				iterate							(void);
80 
81 private:
82 	void								createQuad						(void);
83 	tcu::TestStatus						checkResult						(deInt8						factor);
84 
85 private:
86 	BufferViewCaseParams				m_testCase;
87 
88 	const tcu::IVec2					m_renderSize;
89 	const VkFormat						m_colorFormat;
90 
91 	const VkDeviceSize					m_pixelDataSize;
92 
93 	Move<VkImage>						m_colorImage;
94 	de::MovePtr<Allocation>				m_colorImageAlloc;
95 	Move<VkImageView>					m_colorAttachmentView;
96 	Move<VkRenderPass>					m_renderPass;
97 	Move<VkFramebuffer>					m_framebuffer;
98 
99 	Move<VkDescriptorSetLayout>			m_descriptorSetLayout;
100 	Move<VkDescriptorPool>				m_descriptorPool;
101 	Move<VkDescriptorSet>				m_descriptorSet;
102 
103 	Move<VkBuffer>						m_uniformBuffer;
104 	de::MovePtr<vk::Allocation>			m_uniformBufferAlloc;
105 	Move<VkBufferView>					m_uniformBufferView;
106 
107 	Move<VkShaderModule>				m_vertexShaderModule;
108 	Move<VkShaderModule>				m_fragmentShaderModule;
109 
110 	Move<VkBuffer>						m_vertexBuffer;
111 	std::vector<tcu::Vec4>				m_vertices;
112 	de::MovePtr<Allocation>				m_vertexBufferAlloc;
113 
114 	Move<VkPipelineLayout>				m_pipelineLayout;
115 	Move<VkPipeline>					m_graphicsPipelines;
116 
117 	Move<VkCommandPool>					m_cmdPool;
118 	Move<VkCommandBuffer>				m_cmdBuffer;
119 
120 	Move<VkBuffer>						m_resultBuffer;
121 	de::MovePtr<Allocation>				m_resultBufferAlloc;
122 };
123 
generateBuffer(std::vector<deUint32> & uniformData,deUint32 bufferSize,deInt8 factor)124 static void generateBuffer												(std::vector<deUint32>&		uniformData,
125 																		 deUint32					bufferSize,
126 																		 deInt8						factor)
127 {
128 	for (deUint32 i = 0; i < bufferSize; ++i)
129 		uniformData.push_back(factor * i);
130 }
131 
createQuad(void)132 void BufferViewTestInstance::createQuad									(void)
133 {
134 	tcu::Vec4							a(-1.0, -1.0, 0.0, 1.0);
135 	tcu::Vec4							b(1.0, -1.0, 0.0, 1.0);
136 	tcu::Vec4							c(1.0, 1.0, 0.0, 1.0);
137 	tcu::Vec4							d(-1.0, 1.0, 0.0, 1.0);
138 
139 	// Triangle 1
140 	m_vertices.push_back(a);
141 	m_vertices.push_back(c);
142 	m_vertices.push_back(b);
143 
144 	// Triangle 2
145 	m_vertices.push_back(c);
146 	m_vertices.push_back(a);
147 	m_vertices.push_back(d);
148 }
149 
~BufferViewTestInstance(void)150 BufferViewTestInstance::~BufferViewTestInstance							(void)
151 {
152 }
153 
BufferViewTestInstance(Context & context,BufferViewCaseParams testCase)154 BufferViewTestInstance::BufferViewTestInstance							(Context&					context,
155 																		 BufferViewCaseParams		testCase)
156 										: vkt::TestInstance				(context)
157 										, m_testCase					(testCase)
158 										, m_renderSize					(testCase.bufferViewSize, testCase.bufferViewSize)
159 										, m_colorFormat					(VK_FORMAT_R32_UINT)
160 										, m_pixelDataSize				(m_renderSize.x() * m_renderSize.y() * mapVkFormat(m_colorFormat).getPixelSize())
161 {
162 	const DeviceInterface&				vk								= context.getDeviceInterface();
163 	const VkDevice						vkDevice						= context.getDevice();
164 	const deUint32						queueFamilyIndex				= context.getUniversalQueueFamilyIndex();
165 	SimpleAllocator						memAlloc						(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
166 	const VkComponentMapping			channelMappingRGBA				= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
167 
168 	// Create color image
169 	if (m_testCase.imageAllocationKind == ALLOCATION_KIND_DEDICATED)
170 	{
171 		ImageDedicatedAllocation().createTestImage(m_renderSize, m_colorFormat, context, memAlloc, m_colorImage, MemoryRequirement::Any, m_colorImageAlloc);
172 	}
173 	else
174 	{
175 		ImageSuballocation().createTestImage(m_renderSize, m_colorFormat, context, memAlloc, m_colorImage, MemoryRequirement::Any, m_colorImageAlloc);
176 	}
177 
178 	// Create destination buffer
179 	if (m_testCase.bufferAllocationKind == ALLOCATION_KIND_DEDICATED)
180 	{
181 		BufferDedicatedAllocation().createTestBuffer(m_pixelDataSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, m_context, memAlloc, m_resultBuffer, MemoryRequirement::HostVisible, m_resultBufferAlloc);
182 	}
183 	else
184 	{
185 		BufferSuballocation().createTestBuffer(m_pixelDataSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, m_context, memAlloc, m_resultBuffer, MemoryRequirement::HostVisible, m_resultBufferAlloc);
186 	}
187 
188 	// Create color attachment view
189 	{
190 		const VkImageViewCreateInfo		colorAttachmentViewParams		=
191 		{
192 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,					// VkStructureType			sType;
193 			DE_NULL,													// const void*				pNext;
194 			0u,															// VkImageViewCreateFlags	flags;
195 			*m_colorImage,												// VkImage					image;
196 			VK_IMAGE_VIEW_TYPE_2D,										// VkImageViewType			viewType;
197 			m_colorFormat,												// VkFormat					format;
198 			channelMappingRGBA,											// VkChannelMapping			channels;
199 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },				// VkImageSubresourceRange	subresourceRange;
200 		};
201 
202 		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
203 	}
204 
205 	// Create render pass
206 	m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat);
207 
208 	// Create framebuffer
209 	{
210 		const VkImageView				attachmentBindInfos[1]			=
211 		{
212 			*m_colorAttachmentView,
213 		};
214 
215 		const VkFramebufferCreateInfo	framebufferParams				=
216 		{
217 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,					// VkStructureType			sType;
218 			DE_NULL,													// const void*				pNext;
219 			(VkFramebufferCreateFlags)0,
220 			*m_renderPass,												// VkRenderPass				renderPass;
221 			1u,															// deUint32					attachmentCount;
222 			attachmentBindInfos,										// const VkImageView*		pAttachments;
223 			(deUint32)m_renderSize.x(),									// deUint32					width;
224 			(deUint32)m_renderSize.y(),									// deUint32					height;
225 			1u															// deUint32					layers;
226 		};
227 
228 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
229 	}
230 
231 	// Create descriptors
232 	{
233 		const VkDescriptorSetLayoutBinding
234 										layoutBindings[1]				=
235 		{
236 			{
237 				0u,														// deUint32					binding;
238 				VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,				// VkDescriptorType			descriptorType;
239 				1u,														// deUint32					arraySize;
240 				VK_SHADER_STAGE_ALL,									// VkShaderStageFlags		stageFlags;
241 				DE_NULL													// const VkSampler*			pImmutableSamplers;
242 			},
243 		};
244 
245 		const VkDescriptorSetLayoutCreateInfo
246 										descriptorLayoutParams			=
247 		{
248 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType			sType;
249 			DE_NULL,													// const void*				pNext;
250 			(VkDescriptorSetLayoutCreateFlags)0,
251 			DE_LENGTH_OF_ARRAY(layoutBindings),							// deUint32					count;
252 			layoutBindings												// const VkDescriptorSetLayoutBinding pBinding;
253 		};
254 
255 		m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorLayoutParams);
256 
257 		// Generate buffer
258 		std::vector<deUint32>			uniformData;
259 		generateBuffer(uniformData, testCase.bufferSize, 1);
260 
261 		const VkDeviceSize				uniformSize						= testCase.bufferSize * sizeof(deUint32);
262 
263 		BufferSuballocation().createTestBuffer(uniformSize, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, m_context, memAlloc, m_uniformBuffer, MemoryRequirement::HostVisible, m_uniformBufferAlloc);
264 		deMemcpy(m_uniformBufferAlloc->getHostPtr(), uniformData.data(), (size_t)uniformSize);
265 		flushAlloc(vk, vkDevice, *m_uniformBufferAlloc);
266 
267 		const VkBufferViewCreateInfo	viewInfo						=
268 		{
269 			VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,					// VkStructureType			sType;
270 			DE_NULL,													// void*					pNext;
271 			(VkBufferViewCreateFlags)0,
272 			*m_uniformBuffer,											// VkBuffer					buffer;
273 			m_colorFormat,												// VkFormat					format;
274 			m_testCase.elementOffset * sizeof(deUint32),				// VkDeviceSize				offset;
275 			m_testCase.bufferViewSize * sizeof(deUint32)				// VkDeviceSize				range;
276 		};
277 
278 		m_uniformBufferView = createBufferView(vk, vkDevice, &viewInfo);
279 
280 		const VkDescriptorPoolSize		descriptorTypes[1]				=
281 		{
282 			{
283 				VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,				// VkDescriptorType			type;
284 				1														// deUint32					count;
285 			}
286 		};
287 
288 		const VkDescriptorPoolCreateInfo
289 										descriptorPoolParams			=
290 		{
291 			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,				// VkStructureType			sType;
292 			DE_NULL,													// void*					pNext;
293 			VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,			// VkDescriptorPoolCreateFlags flags;
294 			1u,															// uint32_t					maxSets;
295 			DE_LENGTH_OF_ARRAY(descriptorTypes),						// deUint32					count;
296 			descriptorTypes												// const VkDescriptorTypeCount* pTypeCount
297 		};
298 
299 		m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolParams);
300 
301 		const VkDescriptorSetAllocateInfo
302 										descriptorSetParams				=
303 		{
304 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
305 			DE_NULL,
306 			*m_descriptorPool,
307 			1u,
308 			&m_descriptorSetLayout.get(),
309 		};
310 		m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetParams);
311 
312 		const VkWriteDescriptorSet		writeDescritporSets[]			=
313 		{
314 			{
315 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,					// VkStructureType			sType;
316 				DE_NULL,												// const void*				pNext;
317 				*m_descriptorSet,										// VkDescriptorSet			destSet;
318 				0,														// deUint32					destBinding;
319 				0,														// deUint32					destArrayElement;
320 				1u,														// deUint32					count;
321 				VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,				// VkDescriptorType			descriptorType;
322 				(const VkDescriptorImageInfo*)DE_NULL,
323 				(const VkDescriptorBufferInfo*)DE_NULL,
324 				&m_uniformBufferView.get(),
325 			}
326 		};
327 
328 		vk.updateDescriptorSets(vkDevice, DE_LENGTH_OF_ARRAY(writeDescritporSets), writeDescritporSets, 0u, DE_NULL);
329 	}
330 
331 	// Create pipeline layout
332 	{
333 		const VkPipelineLayoutCreateInfo
334 										pipelineLayoutParams			=
335 		{
336 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// VkStructureType			sType;
337 			DE_NULL,													// const void*				pNext;
338 			(VkPipelineLayoutCreateFlags)0,
339 			1u,															// deUint32					descriptorSetCount;
340 			&*m_descriptorSetLayout,									// const VkDescriptorSetLayout* pSetLayouts;
341 			0u,															// deUint32					pushConstantRangeCount;
342 			DE_NULL														// const VkPushConstantRange* pPushConstantRanges;
343 		};
344 
345 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
346 	}
347 
348 	// Create shaders
349 	{
350 		m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
351 		m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
352 	}
353 
354 	// Create pipeline
355 	{
356 		const std::vector<VkViewport>	viewports	(1, makeViewport(m_renderSize));
357 		const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_renderSize));
358 
359 		m_graphicsPipelines = makeGraphicsPipeline(vk,						// const DeviceInterface&            vk
360 												   vkDevice,				// const VkDevice                    device
361 												   *m_pipelineLayout,		// const VkPipelineLayout            pipelineLayout
362 												   *m_vertexShaderModule,	// const VkShaderModule              vertexShaderModule
363 												   DE_NULL,					// const VkShaderModule              tessellationControlModule
364 												   DE_NULL,					// const VkShaderModule              tessellationEvalModule
365 												   DE_NULL,					// const VkShaderModule              geometryShaderModule
366 												   *m_fragmentShaderModule,	// const VkShaderModule              fragmentShaderModule
367 												   *m_renderPass,			// const VkRenderPass                renderPass
368 												   viewports,				// const std::vector<VkViewport>&    viewports
369 												   scissors);				// const std::vector<VkRect2D>&      scissors
370 	}
371 
372 	// Create vertex buffer
373 	{
374 		createQuad();
375 		const VkDeviceSize				vertexDataSize					= m_vertices.size() * sizeof(tcu::Vec4);
376 
377 		BufferSuballocation().createTestBuffer(vertexDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, m_context, memAlloc, m_vertexBuffer, MemoryRequirement::HostVisible, m_vertexBufferAlloc);
378 
379 		// Load vertices into vertex buffer
380 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), (size_t)vertexDataSize);
381 		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
382 	}
383 
384 	// Create command pool
385 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
386 
387 	// Create command buffer
388 	{
389 		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
390 
391 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
392 
393 		const VkImageMemoryBarrier		initialImageBarrier				=
394 		{
395 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,						// VkStructureType			sType;
396 			DE_NULL,													// const void*				pNext;
397 			0,															// VkAccessFlags			srcAccessMask;
398 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,						// VkAccessFlags			dstAccessMask;
399 			VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout			oldLayout;
400 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,					// VkImageLayout			newLayout;
401 			VK_QUEUE_FAMILY_IGNORED,									// deUint32					srcQueueFamilyIndex;
402 			VK_QUEUE_FAMILY_IGNORED,									// deUint32					destQueueFamilyIndex;
403 			*m_colorImage,												// VkImage					image;
404 			{															// VkImageSubresourceRange	subresourceRange;
405 				VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags		aspectMask;
406 				0u,														// deUint32					baseMipLevel;
407 				1u,														// deUint32					mipLevels;
408 				0u,														// deUint32					baseArraySlice;
409 				1u														// deUint32					arraySize;
410 			}
411 		};
412 
413 		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &initialImageBarrier);
414 
415 		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), tcu::Vec4(0.0f));
416 
417 		const VkDeviceSize				vertexBufferOffset[1]			= { 0 };
418 
419 		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
420 		vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL);
421 		vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), vertexBufferOffset);
422 		vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
423 		endRenderPass(vk, *m_cmdBuffer);
424 		copyImageToBuffer(vk, *m_cmdBuffer, *m_colorImage, *m_resultBuffer, m_renderSize);
425 		endCommandBuffer(vk, *m_cmdBuffer);
426 	}
427 }
428 
checkResult(deInt8 factor)429 tcu::TestStatus BufferViewTestInstance::checkResult						(deInt8						factor)
430 {
431 	const DeviceInterface&				vk								= m_context.getDeviceInterface();
432 	const VkDevice						vkDevice						= m_context.getDevice();
433 	const tcu::TextureFormat			tcuFormat						= mapVkFormat(m_colorFormat);
434 	de::MovePtr<tcu::TextureLevel>		resultLevel						(new tcu::TextureLevel(tcuFormat, m_renderSize.x(), m_renderSize.y()));
435 
436 	invalidateAlloc(vk, vkDevice, *m_resultBufferAlloc);
437 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_resultBufferAlloc->getHostPtr()));
438 
439 	tcu::ConstPixelBufferAccess			pixelBuffer						= resultLevel->getAccess();
440 	for (deInt32 i = 0; i < (deInt32) m_renderSize.x(); ++i)
441 	{
442 		tcu::IVec4						pixel							= pixelBuffer.getPixelInt(i, i);
443 		deInt32							expected						= factor * (m_testCase.elementOffset + i);
444 		deInt32							actual							= pixel[0];
445 		if (expected != actual)
446 		{
447 			std::ostringstream			errorMessage;
448 			errorMessage << "BufferView test failed. expected: " << expected << " actual: " << actual;
449 			return tcu::TestStatus::fail(errorMessage.str());
450 		}
451 	}
452 
453 	return tcu::TestStatus::pass("BufferView test");
454 }
455 
iterate(void)456 tcu::TestStatus BufferViewTestInstance::iterate							(void)
457 {
458 	const DeviceInterface&				vk								= m_context.getDeviceInterface();
459 	const VkDevice						vkDevice						= m_context.getDevice();
460 	const VkQueue						queue							= m_context.getUniversalQueue();
461 
462 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
463 
464 	tcu::TestStatus						testStatus						= checkResult(1);
465 	if (testStatus.getCode() != QP_TEST_RESULT_PASS)
466 		return testStatus;
467 
468 	// Generate and bind another buffer
469 	std::vector<deUint32>				uniformData;
470 	const VkDeviceSize					uniformSize						= m_testCase.bufferSize * sizeof(deUint32);
471 	const deInt8						factor							= 2;
472 
473 	generateBuffer(uniformData, m_testCase.bufferSize, factor);
474 	deMemcpy(m_uniformBufferAlloc->getHostPtr(), uniformData.data(), (size_t)uniformSize);
475 	flushAlloc(vk, vkDevice, *m_uniformBufferAlloc);
476 
477 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
478 
479 	return checkResult(factor);
480 }
481 
482 class BufferViewTestCase : public vkt::TestCase
483 {
484 public:
BufferViewTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,BufferViewCaseParams bufferViewTestInfo)485 									BufferViewTestCase					(tcu::TestContext&			testCtx,
486 																		 const std::string&			name,
487 																		 const std::string&			description,
488 																		 BufferViewCaseParams		bufferViewTestInfo)
489 									: vkt::TestCase						(testCtx, name, description)
490 									, m_bufferViewTestInfo				(bufferViewTestInfo)
491 	{}
492 
~BufferViewTestCase(void)493 	virtual							~BufferViewTestCase					(void)
494 	{}
495 	virtual	void					initPrograms						(SourceCollections&			programCollection) const;
496 
createInstance(Context & context) const497 	virtual TestInstance*			createInstance						(Context&					context) const
498 	{
499 		return new BufferViewTestInstance(context, m_bufferViewTestInfo);
500 	}
501 private:
502 	BufferViewCaseParams			m_bufferViewTestInfo;
503 };
504 
initPrograms(SourceCollections & programCollection) const505 void BufferViewTestCase::initPrograms									(SourceCollections&			programCollection) const
506 {
507 	programCollection.glslSources.add("vert") << glu::VertexSource(
508 		"#version 310 es\n"
509 		"layout (location = 0) in highp vec4 a_position;\n"
510 		"void main()\n"
511 		"{\n"
512 		"	gl_Position = a_position;\n"
513 		"}\n");
514 
515 
516 	programCollection.glslSources.add("frag") << glu::FragmentSource(
517 		"#version 310 es\n"
518 		"#extension GL_EXT_texture_buffer : enable\n"
519 		"layout (set=0, binding=0) uniform highp utextureBuffer u_buffer;\n"
520 		"layout (location = 0) out highp uint o_color;\n"
521 		"void main()\n"
522 		"{\n"
523 		"	o_color = texelFetch(u_buffer, int(gl_FragCoord.x)).x;\n"
524 		"}\n");
525 }
526 
527 } // anonymous
528 
createBufferViewAccessTests(tcu::TestContext & testCtx)529 tcu::TestCaseGroup* createBufferViewAccessTests							(tcu::TestContext&			testCtx)
530 {
531 	const char* const				bufferTexts[ALLOCATION_KIND_LAST]	=
532 	{
533 		"buffer_suballocated",
534 		"buffer_dedicated_alloc"
535 	};
536 
537 	const char* const				imageTexts[ALLOCATION_KIND_LAST]	=
538 	{
539 		"image_suballocated",
540 		"image_dedicated_alloc"
541 	};
542 
543 	de::MovePtr<tcu::TestCaseGroup>	bufferViewTests						(new tcu::TestCaseGroup(testCtx, "access", "BufferView Access Tests"));
544 	de::MovePtr<tcu::TestCaseGroup>	bufferViewAllocationGroupTests[]	=
545 	{
546 		de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "suballocation", "BufferView Access Tests for Suballocated Objects")),
547 		de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "dedicated_alloc", "BufferView Access Tests for Dedicatedly Allocated Objects"))
548 	};
549 
550 	for (deUint32 buffersAllocationNdx = 0u; buffersAllocationNdx < ALLOCATION_KIND_LAST; ++buffersAllocationNdx)
551 	for (deUint32 imageAllocationNdx = 0u; imageAllocationNdx < ALLOCATION_KIND_LAST; ++imageAllocationNdx)
552 	{
553 		const deUint32				testCaseGroupNdx					= (buffersAllocationNdx == 0u && imageAllocationNdx == 0u) ? 0u : 1u;
554 		de::MovePtr<tcu::TestCaseGroup>&
555 									currentTestsGroup					= bufferViewAllocationGroupTests[testCaseGroupNdx];
556 		{
557 			const BufferViewCaseParams	info							=
558 			{
559 				512,													// deUint32					bufferSize
560 				512,													// deUint32					bufferViewSize
561 				0,														// deUint32					elementOffset
562 				static_cast<AllocationKind>(buffersAllocationNdx),
563 				static_cast<AllocationKind>(imageAllocationNdx)
564 			};
565 			std::ostringstream		name;
566 			name << "buffer_view_memory_test_complete";
567 			if (testCaseGroupNdx != 0)
568 				name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx];
569 			std::ostringstream		description;
570 			description << "bufferSize: " << info.bufferSize << " bufferViewSize: " << info.bufferViewSize << " bufferView element offset: " << info.elementOffset;
571 			currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), description.str(), info));
572 		}
573 
574 		{
575 			const BufferViewCaseParams	info							=
576 			{
577 				4096,													// deUint32					bufferSize
578 				512,													// deUint32					bufferViewSize
579 				0,														// deUint32					elementOffset
580 				static_cast<AllocationKind>(buffersAllocationNdx),
581 				static_cast<AllocationKind>(imageAllocationNdx)
582 			};
583 			std::ostringstream		name;
584 			name << "buffer_view_memory_test_partial_offset0";
585 			if (testCaseGroupNdx != 0)
586 				name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx];
587 			std::ostringstream		description;
588 			description << "bufferSize: " << info.bufferSize << " bufferViewSize: " << info.bufferViewSize << " bufferView element offset: " << info.elementOffset;
589 			currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), description.str(), info));
590 		}
591 
592 		{
593 			const BufferViewCaseParams	info							=
594 			{
595 				4096,													// deUint32					bufferSize
596 				512,													// deUint32					bufferViewSize
597 				128,													// deUint32					elementOffset
598 				static_cast<AllocationKind>(buffersAllocationNdx),
599 				static_cast<AllocationKind>(imageAllocationNdx)
600 			};
601 			std::ostringstream		name;
602 			name << "buffer_view_memory_test_partial_offset1";
603 			if (testCaseGroupNdx != 0)
604 				name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx];
605 			std::ostringstream		description;
606 			description << "bufferSize: " << info.bufferSize << " bufferViewSize: " << info.bufferViewSize << " bufferView element offset: " << info.elementOffset;
607 			currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), description.str(), info));
608 		}
609 	}
610 
611 	for (deUint32 subgroupNdx = 0u; subgroupNdx < DE_LENGTH_OF_ARRAY(bufferViewAllocationGroupTests); ++subgroupNdx)
612 	{
613 		bufferViewTests->addChild(bufferViewAllocationGroupTests[subgroupNdx].release());
614 	}
615 	return bufferViewTests.release();
616 }
617 
618 } // api
619 } // vkt
620