• 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 #include "deArrayUtil.hpp"
46 #include "tcuVectorUtil.hpp"
47 #include "../image/vktImageTestsUtil.hpp"
48 
49 namespace vkt
50 {
51 
52 namespace api
53 {
54 
55 using namespace vk;
56 
57 namespace
58 {
59 
60 enum AllocationKind
61 {
62 	ALLOCATION_KIND_SUBALLOCATION										= 0,
63 	ALLOCATION_KIND_DEDICATED											= 1,
64 	ALLOCATION_KIND_LAST
65 };
66 
67 struct BufferViewCaseParams
68 {
69 	deUint32							bufferSize;
70 	deUint32							bufferViewSize;
71 	deUint32							elementOffset;
72 	AllocationKind						bufferAllocationKind;
73 	AllocationKind						imageAllocationKind;
74 
75 	VkFormat							format;
76 	VkBufferUsageFlags					usage;
77 	VkFormatFeatureFlags				feature;
78 	VkDescriptorType					descType;
79 
BufferViewCaseParamsvkt::api::__anon5a9cb4960111::BufferViewCaseParams80 	BufferViewCaseParams (deUint32 bufferSize_,
81 						  deUint32 bufferViewSize_,
82 						  deUint32 elementOffset_,
83 						  AllocationKind bufferAllocKind_,
84 						  AllocationKind imageAllocKind_,
85 						  VkFormat format_ = VK_FORMAT_R32_UINT,
86 						  VkBufferUsageFlags usage_ = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
87 						  VkFormatFeatureFlags feature_ = VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT,
88 						  VkDescriptorType descType_ = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
89 		: bufferSize(bufferSize_)
90 		, bufferViewSize(bufferViewSize_)
91 		, elementOffset(elementOffset_)
92 		, bufferAllocationKind(bufferAllocKind_)
93 		, imageAllocationKind(imageAllocKind_)
94 		, format(format_)
95 		, usage(usage_)
96 		, feature(feature_)
97 		, descType(descType_)
98 	{
99 	}
100 };
101 
102 class BufferViewTestInstance : public vkt::TestInstance
103 {
104 public:
105 										BufferViewTestInstance			(Context&					context,
106 																		 BufferViewCaseParams		testCase);
107 	virtual								~BufferViewTestInstance			(void);
108 	virtual tcu::TestStatus				iterate							(void);
109 
110 private:
111 	void								createQuad						(void);
112 	tcu::TestStatus						checkResult						(deInt8						factor);
113 
114 private:
115 	BufferViewCaseParams				m_testCase;
116 
117 	const tcu::IVec2					m_renderSize;
118 	const VkFormat						m_colorFormat;
119 
120 	const VkDeviceSize					m_pixelDataSize;
121 
122 	Move<VkImage>						m_colorImage;
123 	de::MovePtr<Allocation>				m_colorImageAlloc;
124 	Move<VkImageView>					m_colorAttachmentView;
125 	Move<VkRenderPass>					m_renderPass;
126 	Move<VkFramebuffer>					m_framebuffer;
127 
128 	Move<VkDescriptorSetLayout>			m_descriptorSetLayout;
129 	Move<VkDescriptorPool>				m_descriptorPool;
130 	Move<VkDescriptorSet>				m_descriptorSet;
131 
132 	Move<VkBuffer>						m_uniformBuffer;
133 	de::MovePtr<vk::Allocation>			m_uniformBufferAlloc;
134 	Move<VkBufferView>					m_uniformBufferView;
135 
136 	Move<VkShaderModule>				m_vertexShaderModule;
137 	Move<VkShaderModule>				m_fragmentShaderModule;
138 
139 	Move<VkBuffer>						m_vertexBuffer;
140 	std::vector<tcu::Vec4>				m_vertices;
141 	de::MovePtr<Allocation>				m_vertexBufferAlloc;
142 
143 	Move<VkPipelineLayout>				m_pipelineLayout;
144 	Move<VkPipeline>					m_graphicsPipelines;
145 
146 	Move<VkCommandPool>					m_cmdPool;
147 	Move<VkCommandBuffer>				m_cmdBuffer;
148 
149 	Move<VkBuffer>						m_resultBuffer;
150 	de::MovePtr<Allocation>				m_resultBufferAlloc;
151 };
152 
generateBuffer(std::vector<deUint32> & uniformData,deUint32 bufferSize,deInt8 factor)153 static void generateBuffer												(std::vector<deUint32>&		uniformData,
154 																		 deUint32					bufferSize,
155 																		 deInt8						factor)
156 {
157 	for (deUint32 i = 0; i < bufferSize; ++i)
158 		uniformData.push_back(factor * i);
159 }
160 
createQuad(void)161 void BufferViewTestInstance::createQuad									(void)
162 {
163 	tcu::Vec4							a(-1.0, -1.0, 0.0, 1.0);
164 	tcu::Vec4							b(1.0, -1.0, 0.0, 1.0);
165 	tcu::Vec4							c(1.0, 1.0, 0.0, 1.0);
166 	tcu::Vec4							d(-1.0, 1.0, 0.0, 1.0);
167 
168 	// Triangle 1
169 	m_vertices.push_back(a);
170 	m_vertices.push_back(c);
171 	m_vertices.push_back(b);
172 
173 	// Triangle 2
174 	m_vertices.push_back(c);
175 	m_vertices.push_back(a);
176 	m_vertices.push_back(d);
177 }
178 
~BufferViewTestInstance(void)179 BufferViewTestInstance::~BufferViewTestInstance							(void)
180 {
181 }
182 
BufferViewTestInstance(Context & context,BufferViewCaseParams testCase)183 BufferViewTestInstance::BufferViewTestInstance							(Context&					context,
184 																		 BufferViewCaseParams		testCase)
185 										: vkt::TestInstance				(context)
186 										, m_testCase					(testCase)
187 										, m_renderSize					(testCase.bufferViewSize, testCase.bufferViewSize)
188 										, m_colorFormat					(VK_FORMAT_R32_UINT)
189 										, m_pixelDataSize				(m_renderSize.x() * m_renderSize.y() * mapVkFormat(m_colorFormat).getPixelSize())
190 {
191 	const DeviceInterface&				vk								= context.getDeviceInterface();
192 	const VkDevice						vkDevice						= context.getDevice();
193 	const deUint32						queueFamilyIndex				= context.getUniversalQueueFamilyIndex();
194 	SimpleAllocator						memAlloc						(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
195 	const VkComponentMapping			channelMappingRGBA				= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
196 
197 	// Create color image
198 	if (m_testCase.imageAllocationKind == ALLOCATION_KIND_DEDICATED)
199 	{
200 		ImageDedicatedAllocation().createTestImage(m_renderSize, m_colorFormat, context, memAlloc, m_colorImage, MemoryRequirement::Any, m_colorImageAlloc);
201 	}
202 	else
203 	{
204 		ImageSuballocation().createTestImage(m_renderSize, m_colorFormat, context, memAlloc, m_colorImage, MemoryRequirement::Any, m_colorImageAlloc);
205 	}
206 
207 	// Create destination buffer
208 	if (m_testCase.bufferAllocationKind == ALLOCATION_KIND_DEDICATED)
209 	{
210 		BufferDedicatedAllocation().createTestBuffer(m_pixelDataSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, m_context, memAlloc, m_resultBuffer, MemoryRequirement::HostVisible, m_resultBufferAlloc);
211 	}
212 	else
213 	{
214 		BufferSuballocation().createTestBuffer(m_pixelDataSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, m_context, memAlloc, m_resultBuffer, MemoryRequirement::HostVisible, m_resultBufferAlloc);
215 	}
216 
217 	// Create color attachment view
218 	{
219 		const VkImageViewCreateInfo		colorAttachmentViewParams		=
220 		{
221 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,					// VkStructureType			sType;
222 			DE_NULL,													// const void*				pNext;
223 			0u,															// VkImageViewCreateFlags	flags;
224 			*m_colorImage,												// VkImage					image;
225 			VK_IMAGE_VIEW_TYPE_2D,										// VkImageViewType			viewType;
226 			m_colorFormat,												// VkFormat					format;
227 			channelMappingRGBA,											// VkChannelMapping			channels;
228 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },				// VkImageSubresourceRange	subresourceRange;
229 		};
230 
231 		m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
232 	}
233 
234 	// Create render pass
235 	m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat);
236 
237 	// Create framebuffer
238 	{
239 		const VkImageView				attachmentBindInfos[1]			=
240 		{
241 			*m_colorAttachmentView,
242 		};
243 
244 		const VkFramebufferCreateInfo	framebufferParams				=
245 		{
246 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,					// VkStructureType			sType;
247 			DE_NULL,													// const void*				pNext;
248 			(VkFramebufferCreateFlags)0,
249 			*m_renderPass,												// VkRenderPass				renderPass;
250 			1u,															// deUint32					attachmentCount;
251 			attachmentBindInfos,										// const VkImageView*		pAttachments;
252 			(deUint32)m_renderSize.x(),									// deUint32					width;
253 			(deUint32)m_renderSize.y(),									// deUint32					height;
254 			1u															// deUint32					layers;
255 		};
256 
257 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
258 	}
259 
260 	// Create descriptors
261 	{
262 		const VkDescriptorSetLayoutBinding
263 										layoutBindings[1]				=
264 		{
265 			{
266 				0u,														// deUint32					binding;
267 				VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,				// VkDescriptorType			descriptorType;
268 				1u,														// deUint32					arraySize;
269 				VK_SHADER_STAGE_ALL,									// VkShaderStageFlags		stageFlags;
270 				DE_NULL													// const VkSampler*			pImmutableSamplers;
271 			},
272 		};
273 
274 		const VkDescriptorSetLayoutCreateInfo
275 										descriptorLayoutParams			=
276 		{
277 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType			sType;
278 			DE_NULL,													// const void*				pNext;
279 			(VkDescriptorSetLayoutCreateFlags)0,
280 			DE_LENGTH_OF_ARRAY(layoutBindings),							// deUint32					count;
281 			layoutBindings												// const VkDescriptorSetLayoutBinding pBinding;
282 		};
283 
284 		m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorLayoutParams);
285 
286 		// Generate buffer
287 		std::vector<deUint32>			uniformData;
288 		generateBuffer(uniformData, testCase.bufferSize, 1);
289 
290 		const VkDeviceSize				uniformSize						= testCase.bufferSize * sizeof(deUint32);
291 
292 		BufferSuballocation().createTestBuffer(uniformSize, testCase.usage, m_context, memAlloc, m_uniformBuffer, MemoryRequirement::HostVisible, m_uniformBufferAlloc);
293 		deMemcpy(m_uniformBufferAlloc->getHostPtr(), uniformData.data(), (size_t)uniformSize);
294 		flushAlloc(vk, vkDevice, *m_uniformBufferAlloc);
295 
296 		const VkBufferViewCreateInfo	viewInfo						=
297 		{
298 			VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,					// VkStructureType			sType;
299 			DE_NULL,													// void*					pNext;
300 			(VkBufferViewCreateFlags)0,
301 			*m_uniformBuffer,											// VkBuffer					buffer;
302 			m_colorFormat,												// VkFormat					format;
303 			m_testCase.elementOffset * sizeof(deUint32),				// VkDeviceSize				offset;
304 			m_testCase.bufferViewSize * sizeof(deUint32)				// VkDeviceSize				range;
305 		};
306 
307 		m_uniformBufferView = createBufferView(vk, vkDevice, &viewInfo);
308 
309 		const VkDescriptorPoolSize		descriptorTypes[1]				=
310 		{
311 			{
312 				VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,				// VkDescriptorType			type;
313 				1														// deUint32					count;
314 			}
315 		};
316 
317 		const VkDescriptorPoolCreateInfo
318 										descriptorPoolParams			=
319 		{
320 			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,				// VkStructureType			sType;
321 			DE_NULL,													// void*					pNext;
322 			VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,			// VkDescriptorPoolCreateFlags flags;
323 			1u,															// uint32_t					maxSets;
324 			DE_LENGTH_OF_ARRAY(descriptorTypes),						// deUint32					count;
325 			descriptorTypes												// const VkDescriptorTypeCount* pTypeCount
326 		};
327 
328 		m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolParams);
329 
330 		const VkDescriptorSetAllocateInfo
331 										descriptorSetParams				=
332 		{
333 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
334 			DE_NULL,
335 			*m_descriptorPool,
336 			1u,
337 			&m_descriptorSetLayout.get(),
338 		};
339 		m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetParams);
340 
341 		const VkWriteDescriptorSet		writeDescritporSets[]			=
342 		{
343 			{
344 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,					// VkStructureType			sType;
345 				DE_NULL,												// const void*				pNext;
346 				*m_descriptorSet,										// VkDescriptorSet			destSet;
347 				0,														// deUint32					destBinding;
348 				0,														// deUint32					destArrayElement;
349 				1u,														// deUint32					count;
350 				VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,				// VkDescriptorType			descriptorType;
351 				(const VkDescriptorImageInfo*)DE_NULL,
352 				(const VkDescriptorBufferInfo*)DE_NULL,
353 				&m_uniformBufferView.get(),
354 			}
355 		};
356 
357 		vk.updateDescriptorSets(vkDevice, DE_LENGTH_OF_ARRAY(writeDescritporSets), writeDescritporSets, 0u, DE_NULL);
358 	}
359 
360 	// Create pipeline layout
361 	{
362 		const VkPipelineLayoutCreateInfo
363 										pipelineLayoutParams			=
364 		{
365 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// VkStructureType			sType;
366 			DE_NULL,													// const void*				pNext;
367 			(VkPipelineLayoutCreateFlags)0,
368 			1u,															// deUint32					descriptorSetCount;
369 			&*m_descriptorSetLayout,									// const VkDescriptorSetLayout* pSetLayouts;
370 			0u,															// deUint32					pushConstantRangeCount;
371 			DE_NULL														// const VkPushConstantRange* pPushConstantRanges;
372 		};
373 
374 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
375 	}
376 
377 	// Create shaders
378 	{
379 		m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
380 		m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
381 	}
382 
383 	// Create pipeline
384 	{
385 		const std::vector<VkViewport>	viewports	(1, makeViewport(m_renderSize));
386 		const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_renderSize));
387 
388 		m_graphicsPipelines = makeGraphicsPipeline(vk,						// const DeviceInterface&            vk
389 												   vkDevice,				// const VkDevice                    device
390 												   *m_pipelineLayout,		// const VkPipelineLayout            pipelineLayout
391 												   *m_vertexShaderModule,	// const VkShaderModule              vertexShaderModule
392 												   DE_NULL,					// const VkShaderModule              tessellationControlModule
393 												   DE_NULL,					// const VkShaderModule              tessellationEvalModule
394 												   DE_NULL,					// const VkShaderModule              geometryShaderModule
395 												   *m_fragmentShaderModule,	// const VkShaderModule              fragmentShaderModule
396 												   *m_renderPass,			// const VkRenderPass                renderPass
397 												   viewports,				// const std::vector<VkViewport>&    viewports
398 												   scissors);				// const std::vector<VkRect2D>&      scissors
399 	}
400 
401 	// Create vertex buffer
402 	{
403 		createQuad();
404 		const VkDeviceSize				vertexDataSize					= m_vertices.size() * sizeof(tcu::Vec4);
405 
406 		BufferSuballocation().createTestBuffer(vertexDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, m_context, memAlloc, m_vertexBuffer, MemoryRequirement::HostVisible, m_vertexBufferAlloc);
407 
408 		// Load vertices into vertex buffer
409 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), (size_t)vertexDataSize);
410 		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
411 	}
412 
413 	// Create command pool
414 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
415 
416 	// Create command buffer
417 	{
418 		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
419 
420 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
421 
422 		const VkImageMemoryBarrier		initialImageBarrier				=
423 		{
424 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,						// VkStructureType			sType;
425 			DE_NULL,													// const void*				pNext;
426 			0,															// VkAccessFlags			srcAccessMask;
427 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,						// VkAccessFlags			dstAccessMask;
428 			VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout			oldLayout;
429 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,					// VkImageLayout			newLayout;
430 			VK_QUEUE_FAMILY_IGNORED,									// deUint32					srcQueueFamilyIndex;
431 			VK_QUEUE_FAMILY_IGNORED,									// deUint32					destQueueFamilyIndex;
432 			*m_colorImage,												// VkImage					image;
433 			{															// VkImageSubresourceRange	subresourceRange;
434 				VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags		aspectMask;
435 				0u,														// deUint32					baseMipLevel;
436 				1u,														// deUint32					mipLevels;
437 				0u,														// deUint32					baseArraySlice;
438 				1u														// deUint32					arraySize;
439 			}
440 		};
441 
442 		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);
443 
444 		beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), tcu::Vec4(0.0f));
445 
446 		const VkDeviceSize				vertexBufferOffset[1]			= { 0 };
447 
448 		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
449 		vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL);
450 		vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), vertexBufferOffset);
451 		vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
452 		endRenderPass(vk, *m_cmdBuffer);
453 		copyImageToBuffer(vk, *m_cmdBuffer, *m_colorImage, *m_resultBuffer, m_renderSize);
454 		endCommandBuffer(vk, *m_cmdBuffer);
455 	}
456 }
457 
checkResult(deInt8 factor)458 tcu::TestStatus BufferViewTestInstance::checkResult						(deInt8						factor)
459 {
460 	const DeviceInterface&				vk								= m_context.getDeviceInterface();
461 	const VkDevice						vkDevice						= m_context.getDevice();
462 	const tcu::TextureFormat			tcuFormat						= mapVkFormat(m_colorFormat);
463 	de::MovePtr<tcu::TextureLevel>		resultLevel						(new tcu::TextureLevel(tcuFormat, m_renderSize.x(), m_renderSize.y()));
464 
465 	invalidateAlloc(vk, vkDevice, *m_resultBufferAlloc);
466 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_resultBufferAlloc->getHostPtr()));
467 
468 	tcu::ConstPixelBufferAccess			pixelBuffer						= resultLevel->getAccess();
469 	for (deInt32 i = 0; i < (deInt32) m_renderSize.x(); ++i)
470 	{
471 		tcu::IVec4						pixel							= pixelBuffer.getPixelInt(i, i);
472 		deInt32							expected						= factor * (m_testCase.elementOffset + i);
473 		deInt32							actual							= pixel[0];
474 		if (expected != actual)
475 		{
476 			std::ostringstream			errorMessage;
477 			errorMessage << "BufferView test failed. expected: " << expected << " actual: " << actual;
478 			return tcu::TestStatus::fail(errorMessage.str());
479 		}
480 	}
481 
482 	return tcu::TestStatus::pass("BufferView test");
483 }
484 
iterate(void)485 tcu::TestStatus BufferViewTestInstance::iterate							(void)
486 {
487 	const DeviceInterface&				vk								= m_context.getDeviceInterface();
488 	const VkDevice						vkDevice						= m_context.getDevice();
489 	const VkQueue						queue							= m_context.getUniversalQueue();
490 
491 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
492 
493 	tcu::TestStatus						testStatus						= checkResult(1);
494 	if (testStatus.getCode() != QP_TEST_RESULT_PASS)
495 		return testStatus;
496 
497 	// Generate and bind another buffer
498 	std::vector<deUint32>				uniformData;
499 	const VkDeviceSize					uniformSize						= m_testCase.bufferSize * sizeof(deUint32);
500 	const deInt8						factor							= 2;
501 
502 	generateBuffer(uniformData, m_testCase.bufferSize, factor);
503 	deMemcpy(m_uniformBufferAlloc->getHostPtr(), uniformData.data(), (size_t)uniformSize);
504 	flushAlloc(vk, vkDevice, *m_uniformBufferAlloc);
505 
506 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
507 
508 	return checkResult(factor);
509 }
510 
511 class BufferViewTestCase : public vkt::TestCase
512 {
513 public:
BufferViewTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,BufferViewCaseParams bufferViewTestInfo)514 									BufferViewTestCase					(tcu::TestContext&			testCtx,
515 																		 const std::string&			name,
516 																		 const std::string&			description,
517 																		 BufferViewCaseParams		bufferViewTestInfo)
518 									: vkt::TestCase						(testCtx, name, description)
519 									, m_bufferViewTestInfo				(bufferViewTestInfo)
520 	{}
521 
~BufferViewTestCase(void)522 	virtual							~BufferViewTestCase					(void)
523 	{}
524 	virtual	void					initPrograms						(SourceCollections&			programCollection) const;
525 
createInstance(Context & context) const526 	virtual TestInstance*			createInstance						(Context&					context) const
527 	{
528 		return new BufferViewTestInstance(context, m_bufferViewTestInfo);
529 	}
530 private:
531 	BufferViewCaseParams			m_bufferViewTestInfo;
532 };
533 
initPrograms(SourceCollections & programCollection) const534 void BufferViewTestCase::initPrograms									(SourceCollections&			programCollection) const
535 {
536 	programCollection.glslSources.add("vert") << glu::VertexSource(
537 		"#version 310 es\n"
538 		"layout (location = 0) in highp vec4 a_position;\n"
539 		"void main()\n"
540 		"{\n"
541 		"	gl_Position = a_position;\n"
542 		"}\n");
543 
544 
545 	programCollection.glslSources.add("frag") << glu::FragmentSource(
546 		"#version 310 es\n"
547 		"#extension GL_EXT_texture_buffer : enable\n"
548 		"layout (set=0, binding=0) uniform highp utextureBuffer u_buffer;\n"
549 		"layout (location = 0) out highp uint o_color;\n"
550 		"void main()\n"
551 		"{\n"
552 		"	o_color = texelFetch(u_buffer, int(gl_FragCoord.x)).x;\n"
553 		"}\n");
554 }
555 
556 class BufferViewAllFormatsTestInstance : public vkt::TestInstance
557 {
558 public:
559 										BufferViewAllFormatsTestInstance		(Context&					context,
560 																				 BufferViewCaseParams		testCase);
561 	virtual								~BufferViewAllFormatsTestInstance		(void);
562 	virtual tcu::TestStatus				iterate									(void);
563 
564 private:
565 	void								checkTexelBufferSupport					(Context&					context,
566 																				 VkFormat					format,
567 																				 VkFormatFeatureFlags		feature);
568 	int									getFetchPos								(int fetchPosNdx);
569 	tcu::TestStatus						checkResult								();
570 	tcu::TestStatus						checkResultFloat						();
571 	void								populateSourceBuffer					(const tcu::PixelBufferAccess& access, deUint32 bufferNdx);
572 
573 private:
574 	enum
575 	{
576 		// some arbitrary points
577 		SAMPLE_POINT_0 = 6,
578 		SAMPLE_POINT_1 = 51,
579 		SAMPLE_POINT_2 = 42,
580 		SAMPLE_POINT_3 = 25,
581 	};
582 
583 	BufferViewCaseParams				m_testCase;
584 	const VkFormat						m_bufferFormat;
585 
586 	Move<VkDescriptorSetLayout>			m_descriptorSetLayout;
587 	Move<VkDescriptorPool>				m_descriptorPool;
588 	Move<VkDescriptorSet>				m_descriptorSet;
589 
590 	Move<VkBuffer>						m_uniformBuffer;
591 	de::MovePtr<vk::Allocation>			m_uniformBufferAlloc;
592 	Move<VkBufferView>					m_uniformBufferView;
593 	Move<VkShaderModule>				m_computeShaderModule;
594 	Move<VkPipelineLayout>				m_pipelineLayout;
595 	Move<VkPipeline>					m_computePipeline;
596 
597 	Move<VkCommandPool>					m_cmdPool;
598 	Move<VkCommandBuffer>				m_cmdBuffer;
599 
600 	Move<VkBuffer>						m_resultBuffer;
601 	de::MovePtr<Allocation>				m_resultBufferAlloc;
602 
603 	de::ArrayBuffer<deUint8>			m_sourceBuffer;
604 	tcu::ConstPixelBufferAccess			m_sourceView;
605 };
606 
checkTexelBufferSupport(Context & context,VkFormat format,VkFormatFeatureFlags feature)607 void BufferViewAllFormatsTestInstance::checkTexelBufferSupport			(Context& context, VkFormat format, VkFormatFeatureFlags feature)
608 {
609 	const InstanceInterface&	vki				= context.getInstanceInterface();
610 	const VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();
611 
612 	VkFormatProperties					properties;
613 	properties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format);
614 
615 	if (!(properties.bufferFeatures & feature))
616 		TCU_THROW(NotSupportedError, "Format not supported");
617 }
618 
~BufferViewAllFormatsTestInstance(void)619 BufferViewAllFormatsTestInstance::~BufferViewAllFormatsTestInstance		(void)
620 {
621 }
622 
623 /* Taken from BindingShaderAccessTests.cpp */
populateSourceBuffer(const tcu::PixelBufferAccess & access,deUint32 bufferNdx)624 void BufferViewAllFormatsTestInstance::populateSourceBuffer				(const tcu::PixelBufferAccess& access, deUint32 bufferNdx)
625 {
626 	DE_ASSERT(access.getHeight() == 1);
627 	DE_ASSERT(access.getDepth() == 1);
628 
629 	const deInt32 width = access.getWidth();
630 
631 	for (int x = 0; x < width; ++x)
632 	{
633 		int	red		= 255 * x / width;												//!< gradient from 0 -> max (detects large offset errors)
634 		int	green	= ((x % 2 == 0) ? (127) : (0)) + ((x % 4 < 3) ? (128) : (0));	//!< 3-level M pattern (detects small offset errors)
635 		int	blue	= 16 * (x % 16);												//!< 16-long triangle wave
636 
637 		DE_ASSERT(de::inRange(red, 0, 255));
638 		DE_ASSERT(de::inRange(green, 0, 255));
639 		DE_ASSERT(de::inRange(blue, 0, 255));
640 
641 		if (bufferNdx % 2 == 0) red		= 255 - red;
642 		if (bufferNdx % 3 == 0) green	= 255 - green;
643 		if (bufferNdx % 4 == 0) blue	= 255 - blue;
644 
645 		access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0);
646 	}
647 }
648 
BufferViewAllFormatsTestInstance(Context & context,BufferViewCaseParams testCase)649 BufferViewAllFormatsTestInstance::BufferViewAllFormatsTestInstance		(Context&					context,
650 																		 BufferViewCaseParams		testCase)
651 										: vkt::TestInstance				(context)
652 										, m_testCase					(testCase)
653 										, m_bufferFormat				(testCase.format)
654 {
655 	const DeviceInterface&				vk								= context.getDeviceInterface();
656 	const VkDevice						vkDevice						= context.getDevice();
657 	const deUint32						queueFamilyIndex				= context.getUniversalQueueFamilyIndex();
658 	SimpleAllocator						memAlloc						(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
659 	checkTexelBufferSupport(context, m_bufferFormat, testCase.feature);
660 
661 	// Create a result buffer
662 	BufferSuballocation().createTestBuffer(sizeof(tcu::Vec4[4]), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, m_context, memAlloc, m_resultBuffer, MemoryRequirement::HostVisible, m_resultBufferAlloc);
663 
664 	// Create descriptors
665 	{
666 		const VkDescriptorSetLayoutBinding layoutBindings[2]			=
667 		{
668 			{
669 				0u,														// deUint32					binding;
670 				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,						// VkDescriptorType			descriptorType;
671 				1u,														// deUint32					arraySize;
672 				VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlags		stageFlags;
673 				DE_NULL													// const VkSampler*			pImmutableSamplers;
674 			},
675 			{
676 				1u,														// deUint32					binding;
677 				testCase.descType,										// VkDescriptorType			descriptorType;
678 				1u,														// deUint32					arraySize;
679 				VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlags		stageFlags;
680 				DE_NULL													// const VkSampler*			pImmutableSamplers;
681 			},
682 		};
683 
684 		const VkDescriptorSetLayoutCreateInfo descriptorLayoutParams	=
685 		{
686 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType			sType;
687 			DE_NULL,													// const void*				pNext;
688 			(VkDescriptorSetLayoutCreateFlags)0,
689 			DE_LENGTH_OF_ARRAY(layoutBindings),							// deUint32					count;
690 			layoutBindings												// const VkDescriptorSetLayoutBinding pBinding;
691 		};
692 
693 		m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorLayoutParams);
694 
695 
696 		// Generate buffer
697 		const tcu::TextureFormat tcuFormat	= mapVkFormat(m_bufferFormat);
698 
699 		de::ArrayBuffer<deUint8> sourceBuffer(testCase.bufferSize);
700 		populateSourceBuffer(tcu::PixelBufferAccess(tcuFormat, tcu::IVec3(testCase.bufferSize / tcuFormat.getPixelSize(), 1, 1), sourceBuffer.getPtr()), 0);
701 
702 		m_sourceBuffer = sourceBuffer;
703 		m_sourceView = tcu::ConstPixelBufferAccess(tcuFormat, tcu::IVec3(64, 1, 1), m_sourceBuffer.getPtr());
704 
705 		BufferSuballocation().createTestBuffer(sourceBuffer.size(), testCase.usage, m_context, memAlloc, m_uniformBuffer, MemoryRequirement::HostVisible, m_uniformBufferAlloc);
706 		deMemcpy(m_uniformBufferAlloc->getHostPtr(), sourceBuffer.getPtr(), sourceBuffer.size());
707 		flushAlloc(vk, vkDevice, *m_uniformBufferAlloc);
708 
709 		const VkBufferViewCreateInfo	viewInfo						=
710 		{
711 			VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,					// VkStructureType			sType;
712 			DE_NULL,													// void*					pNext;
713 			(VkBufferViewCreateFlags)0,
714 			*m_uniformBuffer,											// VkBuffer					buffer;
715 			m_bufferFormat,												// VkFormat					format;
716 			m_testCase.elementOffset,									// VkDeviceSize				offset;
717 			VK_WHOLE_SIZE												// VkDeviceSize				range;
718 		};
719 
720 		m_uniformBufferView = createBufferView(vk, vkDevice, &viewInfo);
721 
722 		const VkDescriptorPoolSize		descriptorTypes[2]				=
723 		{
724 			{
725 				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,						// VkDescriptorType			type;
726 				1														// deUint32					count;
727 			},
728 			{
729 				testCase.descType,										// VkDescriptorType			type;
730 				1														// deUint32					count;
731 			}
732 		};
733 
734 		const VkDescriptorPoolCreateInfo
735 										descriptorPoolParams			=
736 		{
737 			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,				// VkStructureType			sType;
738 			DE_NULL,													// void*					pNext;
739 			VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,			// VkDescriptorPoolCreateFlags flags;
740 			1u,															// uint32_t					maxSets;
741 			DE_LENGTH_OF_ARRAY(descriptorTypes),						// deUint32					count;
742 			descriptorTypes												// const VkDescriptorTypeCount* pTypeCount
743 		};
744 
745 		m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolParams);
746 
747 		const VkDescriptorSetAllocateInfo
748 										descriptorSetParams				=
749 		{
750 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
751 			DE_NULL,
752 			*m_descriptorPool,
753 			1u,
754 			&m_descriptorSetLayout.get(),
755 		};
756 		m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetParams);
757 
758 		const VkDescriptorBufferInfo	outBufferInfo					=
759 		{
760 			m_resultBuffer.get(),
761 			0,
762 			sizeof(tcu::Vec4[4])
763 		};
764 
765 		const VkWriteDescriptorSet		writeDescritporSets[]			=
766 		{
767 			{
768 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,					// VkStructureType			sType;
769 				DE_NULL,												// const void*				pNext;
770 				*m_descriptorSet,										// VkDescriptorSet			destSet;
771 				0,														// deUint32					destBinding;
772 				0,														// deUint32					destArrayElement;
773 				1u,														// deUint32					count;
774 				VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,						// VkDescriptorType			descriptorType;
775 				(const VkDescriptorImageInfo*)DE_NULL,
776 				&outBufferInfo,
777 				(const VkBufferView*)DE_NULL,
778 			},
779 			{
780 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,					// VkStructureType			sType;
781 				DE_NULL,												// const void*				pNext;
782 				*m_descriptorSet,										// VkDescriptorSet			destSet;
783 				1,														// deUint32					destBinding;
784 				0,														// deUint32					destArrayElement;
785 				1u,														// deUint32					count;
786 				testCase.descType,										// VkDescriptorType			descriptorType;
787 				(const VkDescriptorImageInfo*)DE_NULL,
788 				(const VkDescriptorBufferInfo*)DE_NULL,
789 				&m_uniformBufferView.get(),
790 			}
791 		};
792 
793 		vk.updateDescriptorSets(vkDevice, DE_LENGTH_OF_ARRAY(writeDescritporSets), writeDescritporSets, 0u, DE_NULL);
794 	}
795 
796 	// Create pipeline layout
797 	{
798 		const VkPipelineLayoutCreateInfo pipelineLayoutParams			=
799 		{
800 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,				// VkStructureType			sType;
801 			DE_NULL,													// const void*				pNext;
802 			(VkPipelineLayoutCreateFlags)0,
803 			1u,															// deUint32					descriptorSetCount;
804 			&*m_descriptorSetLayout,									// const VkDescriptorSetLayout* pSetLayouts;
805 			0u,															// deUint32					pushConstantRangeCount;
806 			DE_NULL														// const VkPushConstantRange* pPushConstantRanges;
807 		};
808 
809 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
810 	}
811 
812 	// Create shaders
813 	{
814 		m_computeShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("comp"), 0);
815 	}
816 
817 	// Create pipeline
818 	{
819 		m_computePipeline         = makeComputePipeline(vk, vkDevice, m_pipelineLayout.get(), m_computeShaderModule.get());
820 	}
821 
822 	// Create command pool
823 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
824 
825 	// Create and record a command buffer
826 	{
827 		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
828 
829 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
830 
831 		vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
832 		vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &*m_descriptorSet, 0u, nullptr);
833 
834 		const vk::VkBufferMemoryBarrier	barrier		=
835 		{
836 			vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
837 			DE_NULL,
838 			vk::VK_ACCESS_HOST_WRITE_BIT,			// srcAccessMask
839 			vk::VK_ACCESS_UNIFORM_READ_BIT,			// dstAccessMask
840 			VK_QUEUE_FAMILY_IGNORED,				// srcQueueFamilyIndex
841 			VK_QUEUE_FAMILY_IGNORED,				// destQueueFamilyIndex
842 			*m_resultBuffer,						// buffer
843 			0u,										// offset
844 			sizeof(tcu::Vec4[4]),					// size
845 		};
846 		const vk::VkBufferMemoryBarrier bufferBarrier =
847 		{
848 			vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
849 			DE_NULL,
850 			vk::VK_ACCESS_SHADER_WRITE_BIT,			// srcAccessMask
851 			vk::VK_ACCESS_HOST_READ_BIT,			// dstAccessMask
852 			VK_QUEUE_FAMILY_IGNORED,				// srcQueueFamilyIndex
853 			VK_QUEUE_FAMILY_IGNORED,				// destQueueFamilyIndex
854 			*m_resultBuffer,						// buffer
855 			(vk::VkDeviceSize)0u,					// offset
856 			sizeof(tcu::Vec4[4]),					// size
857 		};
858 
859 		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, nullptr, 0u, &barrier, 0u, nullptr);
860 		//vk.cmdDispatch(*m_cmdBuffer, 1u, 1u, 1u);
861 		vk.cmdDispatch(*m_cmdBuffer, 4u, 1u, 1u);
862 		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 0u, &bufferBarrier, 0u, nullptr);
863 		endCommandBuffer(vk, *m_cmdBuffer);
864 	}
865 }
866 
getFetchPos(int fetchPosNdx)867 int BufferViewAllFormatsTestInstance::getFetchPos (int fetchPosNdx)
868 {
869 	static const int fetchPositions[4] =
870 	{
871 		SAMPLE_POINT_0,
872 		SAMPLE_POINT_1,
873 		SAMPLE_POINT_2,
874 		SAMPLE_POINT_3,
875 	};
876 
877 	return fetchPositions[fetchPosNdx];
878 }
879 
checkResult()880 tcu::TestStatus BufferViewAllFormatsTestInstance::checkResult						()
881 {
882 	const DeviceInterface&				vk					= m_context.getDeviceInterface();
883 	const VkDevice						vkDevice			= m_context.getDevice();
884 	bool								allResultsOk		= true;
885 
886 	tcu::UVec4							results[4];
887 	invalidateAlloc(vk, vkDevice, *m_resultBufferAlloc);
888 	deMemcpy(results, m_resultBufferAlloc->getHostPtr(), sizeof(tcu::UVec4[4]));
889 
890 	// verify
891 	for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
892 	{
893 		const tcu::UVec4	result				= results[resultNdx];
894 		const tcu::UVec4	conversionThreshold	= tcu::UVec4(0);
895 		tcu::UVec4			reference			= tcu::UVec4(0);
896 
897 		reference	+= m_sourceView.getPixelUint(getFetchPos(resultNdx), 0, 0);
898 
899 		if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
900 		{
901 			allResultsOk = false;
902 
903 			m_context.getTestContext().getLog()
904 				<< tcu::TestLog::Message
905 				<< "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
906 				<< tcu::TestLog::EndMessage;
907 		}
908 	}
909 
910 	if (allResultsOk)
911 		return tcu::TestStatus::pass("Pass");
912 	else
913 		return tcu::TestStatus::fail("Invalid result values");
914 }
915 
checkResultFloat()916 tcu::TestStatus BufferViewAllFormatsTestInstance::checkResultFloat					()
917 {
918 	const DeviceInterface&				vk					= m_context.getDeviceInterface();
919 	const VkDevice						vkDevice			= m_context.getDevice();
920 	bool								allResultsOk		= true;
921 
922 	tcu::Vec4							results[4];
923 	invalidateAlloc(vk, vkDevice, *m_resultBufferAlloc);
924 	deMemcpy(results, m_resultBufferAlloc->getHostPtr(), sizeof(tcu::Vec4[4]));
925 
926 	// verify
927 	for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
928 	{
929 		const tcu::Vec4	result				= results[resultNdx];
930 		const tcu::Vec4	conversionThreshold	= tcu::Vec4(1.0f / 255.0f);
931 		tcu::Vec4		reference			= tcu::Vec4(0.0f);
932 
933 		reference	+= m_sourceView.getPixel(getFetchPos(resultNdx), 0, 0);
934 
935 		if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
936 		{
937 			allResultsOk = false;
938 
939 			m_context.getTestContext().getLog()
940 				<< tcu::TestLog::Message
941 				<< "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
942 				<< tcu::TestLog::EndMessage;
943 		}
944 	}
945 
946 	if (allResultsOk)
947 		return tcu::TestStatus::pass("Pass");
948 	else
949 		return tcu::TestStatus::fail("Invalid result values");
950 }
951 
iterate(void)952 tcu::TestStatus BufferViewAllFormatsTestInstance::iterate							(void)
953 {
954 	const DeviceInterface&				vk					= m_context.getDeviceInterface();
955 	const VkDevice						vkDevice			= m_context.getDevice();
956 	const VkQueue						queue				= m_context.getUniversalQueue();
957 
958 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
959 
960 	if (isIntFormat(m_bufferFormat) || isUintFormat(m_bufferFormat))
961 		return checkResult();
962 	else
963 		return checkResultFloat();
964 }
965 
966 
967 class BufferViewAllFormatsTestCase : public vkt::TestCase
968 {
969 public:
BufferViewAllFormatsTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,BufferViewCaseParams bufferViewTestInfo)970 									BufferViewAllFormatsTestCase		(tcu::TestContext&			testCtx,
971 																		 const std::string&			name,
972 																		 const std::string&			description,
973 																		 BufferViewCaseParams		bufferViewTestInfo)
974 									: vkt::TestCase						(testCtx, name, description)
975 									, m_bufferViewTestInfo				(bufferViewTestInfo)
976 	{}
977 
~BufferViewAllFormatsTestCase(void)978 	virtual							~BufferViewAllFormatsTestCase		(void)
979 	{}
980 	virtual	void					initPrograms						(SourceCollections&			programCollection) const;
981 
createInstance(Context & context) const982 	virtual TestInstance*			createInstance						(Context&					context) const
983 	{
984 		return new BufferViewAllFormatsTestInstance(context, m_bufferViewTestInfo);
985 	}
986 
987 private:
988 	BufferViewCaseParams			m_bufferViewTestInfo;
989 };
990 
strLayoutFormat(VkFormat format)991 const std::string strLayoutFormat										(VkFormat format)
992 {
993 	std::ostringstream	buf;
994 
995 	buf << ", " << image::getShaderImageFormatQualifier(mapVkFormat(format)).c_str();
996 
997 	return buf.str();
998 }
999 
initPrograms(SourceCollections & programCollection) const1000 void BufferViewAllFormatsTestCase::initPrograms							(SourceCollections&			programCollection) const
1001 {
1002 	std::ostringstream	buf;
1003 
1004 	const bool			isIntFmt		= isIntFormat(m_bufferViewTestInfo.format);
1005 	const bool			isUintFmt		= isUintFormat(m_bufferViewTestInfo.format);
1006 
1007 	const bool			isUniform		= m_bufferViewTestInfo.usage == VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT ? true : false;
1008 	const char* const	storageType		= isUniform ? "textureBuffer " : "imageBuffer ";
1009 	const char* const	extraOption		= isUniform ? "" : "readonly ";
1010 	const std::string	stringFmtLayout = isUniform ? "" : strLayoutFormat(m_bufferViewTestInfo.format);
1011 	const char* const	fmtLayout		= isUniform ? "" : stringFmtLayout.c_str();
1012 	const char* const	opName			= isUniform ? "texelFetch" : "imageLoad";
1013 	const char* const	outFormat		= isIntFmt  ? "i"			   : isUintFmt ? "u" : "";
1014 	const char* const	inFormat		= vk::isScaledFormat(m_bufferViewTestInfo.format)? "" : outFormat;
1015 
1016 	buf << "#version 440\n"
1017 		<< "#extension GL_EXT_texture_buffer : require\n"
1018 		<< "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1019 		<< "layout(set = 0, binding = 1" << fmtLayout << ") uniform highp " << extraOption << inFormat << storageType << " texelBuffer;\n"
1020 		<< "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
1021 		<< "{\n"
1022 		<< "	highp " << outFormat << "vec4 read_colors[4];\n"
1023 		<< "} b_out;\n"
1024 		<< "void main (void)\n"
1025 		<< "{\n"
1026 		<< "	highp int quadrant_id = int(gl_WorkGroupID.x);\n"
1027 		<< "	highp " << outFormat << "vec4 result_color;\n"
1028 		<< "	result_color = " << outFormat << "vec4(0);\n"
1029 		<< "	if (quadrant_id == 0)\n"
1030 		<< "		result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 6));\n"
1031 		<< "	else if (quadrant_id == 1)\n"
1032 		<< "		result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 51));\n"
1033 		<< "	else if (quadrant_id == 2)\n"
1034 		<< "		result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 42));\n"
1035 		<< "	else\n"
1036 		<< "		result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 25));\n"
1037 		<< "	b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
1038 		<< "}\n";
1039 
1040 	programCollection.glslSources.add("comp") << glu::ComputeSource(buf.str());
1041 }
1042 
1043 } // anonymous
1044 
isSupportedImageLoadStore(const tcu::TextureFormat & format)1045 bool isSupportedImageLoadStore (const tcu::TextureFormat& format)
1046 {
1047 	if (!image::isPackedType(mapTextureFormat(format)))
1048 	{
1049 		switch (format.order)
1050 		{
1051 			case tcu::TextureFormat::RGBA:
1052 				break;
1053 			default:
1054 				return false;
1055 		}
1056 
1057 		switch (format.type)
1058 		{
1059 			case tcu::TextureFormat::FLOAT:
1060 			case tcu::TextureFormat::HALF_FLOAT:
1061 
1062 			case tcu::TextureFormat::UNSIGNED_INT32:
1063 			case tcu::TextureFormat::UNSIGNED_INT16:
1064 			case tcu::TextureFormat::UNSIGNED_INT8:
1065 
1066 			case tcu::TextureFormat::SIGNED_INT32:
1067 			case tcu::TextureFormat::SIGNED_INT16:
1068 			case tcu::TextureFormat::SIGNED_INT8:
1069 
1070 			case tcu::TextureFormat::UNORM_INT16:
1071 			case tcu::TextureFormat::UNORM_INT8:
1072 
1073 			case tcu::TextureFormat::SNORM_INT16:
1074 			case tcu::TextureFormat::SNORM_INT8:
1075 				break;
1076 
1077 			default:
1078 				return false;
1079 		}
1080 	}
1081 	else
1082 	{
1083 		switch (mapTextureFormat(format))
1084 		{
1085 			case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1086 			case VK_FORMAT_A2B10G10R10_UINT_PACK32:
1087 				break;
1088 
1089 			default:
1090 				return false;
1091 		}
1092 	}
1093 
1094 	return true;
1095 }
1096 
createBufferViewAccessTests(tcu::TestContext & testCtx)1097 tcu::TestCaseGroup* createBufferViewAccessTests							(tcu::TestContext&			testCtx)
1098 {
1099 	const char* const				bufferTexts[ALLOCATION_KIND_LAST]	=
1100 	{
1101 		"buffer_suballocated",
1102 		"buffer_dedicated_alloc"
1103 	};
1104 
1105 	const char* const				imageTexts[ALLOCATION_KIND_LAST]	=
1106 	{
1107 		"image_suballocated",
1108 		"image_dedicated_alloc"
1109 	};
1110 
1111 	de::MovePtr<tcu::TestCaseGroup>	bufferViewTests						(new tcu::TestCaseGroup(testCtx, "access", "BufferView Access Tests"));
1112 	de::MovePtr<tcu::TestCaseGroup>	bufferViewAllocationGroupTests[]	=
1113 	{
1114 		de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "suballocation", "BufferView Access Tests for Suballocated Objects")),
1115 		de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "dedicated_alloc", "BufferView Access Tests for Dedicatedly Allocated Objects"))
1116 	};
1117 
1118 	for (deUint32 buffersAllocationNdx = 0u; buffersAllocationNdx < ALLOCATION_KIND_LAST; ++buffersAllocationNdx)
1119 	for (deUint32 imageAllocationNdx = 0u; imageAllocationNdx < ALLOCATION_KIND_LAST; ++imageAllocationNdx)
1120 	{
1121 		const deUint32				testCaseGroupNdx					= (buffersAllocationNdx == 0u && imageAllocationNdx == 0u) ? 0u : 1u;
1122 		de::MovePtr<tcu::TestCaseGroup>&
1123 									currentTestsGroup					= bufferViewAllocationGroupTests[testCaseGroupNdx];
1124 		{
1125 			const BufferViewCaseParams	info							=
1126 			{
1127 				512,													// deUint32					bufferSize
1128 				512,													// deUint32					bufferViewSize
1129 				0,														// deUint32					elementOffset
1130 				static_cast<AllocationKind>(buffersAllocationNdx),
1131 				static_cast<AllocationKind>(imageAllocationNdx)
1132 			};
1133 			std::ostringstream		name;
1134 			name << "buffer_view_memory_test_complete";
1135 			if (testCaseGroupNdx != 0)
1136 				name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx];
1137 			std::ostringstream		description;
1138 			description << "bufferSize: " << info.bufferSize << " bufferViewSize: " << info.bufferViewSize << " bufferView element offset: " << info.elementOffset;
1139 			currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), description.str(), info));
1140 		}
1141 
1142 		{
1143 			const BufferViewCaseParams	info							=
1144 			{
1145 				4096,													// deUint32					bufferSize
1146 				512,													// deUint32					bufferViewSize
1147 				0,														// deUint32					elementOffset
1148 				static_cast<AllocationKind>(buffersAllocationNdx),
1149 				static_cast<AllocationKind>(imageAllocationNdx)
1150 			};
1151 			std::ostringstream		name;
1152 			name << "buffer_view_memory_test_partial_offset0";
1153 			if (testCaseGroupNdx != 0)
1154 				name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx];
1155 			std::ostringstream		description;
1156 			description << "bufferSize: " << info.bufferSize << " bufferViewSize: " << info.bufferViewSize << " bufferView element offset: " << info.elementOffset;
1157 			currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), description.str(), info));
1158 		}
1159 
1160 		{
1161 			const BufferViewCaseParams	info							=
1162 			{
1163 				4096,													// deUint32					bufferSize
1164 				512,													// deUint32					bufferViewSize
1165 				128,													// deUint32					elementOffset
1166 				static_cast<AllocationKind>(buffersAllocationNdx),
1167 				static_cast<AllocationKind>(imageAllocationNdx)
1168 			};
1169 			std::ostringstream		name;
1170 			name << "buffer_view_memory_test_partial_offset1";
1171 			if (testCaseGroupNdx != 0)
1172 				name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx];
1173 			std::ostringstream		description;
1174 			description << "bufferSize: " << info.bufferSize << " bufferViewSize: " << info.bufferViewSize << " bufferView element offset: " << info.elementOffset;
1175 			currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), description.str(), info));
1176 		}
1177 	}
1178 
1179 	for (deUint32 subgroupNdx = 0u; subgroupNdx < DE_LENGTH_OF_ARRAY(bufferViewAllocationGroupTests); ++subgroupNdx)
1180 	{
1181 		bufferViewTests->addChild(bufferViewAllocationGroupTests[subgroupNdx].release());
1182 	}
1183 
1184 	VkFormat testFormats[] =
1185 	{
1186 		VK_FORMAT_R4G4_UNORM_PACK8,
1187 		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1188 		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1189 		VK_FORMAT_R5G6B5_UNORM_PACK16,
1190 		VK_FORMAT_B5G6R5_UNORM_PACK16,
1191 		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1192 		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1193 		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1194 		VK_FORMAT_R8_UNORM,
1195 		VK_FORMAT_R8_SNORM,
1196 		VK_FORMAT_R8_USCALED,
1197 		VK_FORMAT_R8_SSCALED,
1198 		VK_FORMAT_R8_UINT,
1199 		VK_FORMAT_R8_SINT,
1200 		VK_FORMAT_R8G8_UNORM,
1201 		VK_FORMAT_R8G8_SNORM,
1202 		VK_FORMAT_R8G8_USCALED,
1203 		VK_FORMAT_R8G8_SSCALED,
1204 		VK_FORMAT_R8G8_UINT,
1205 		VK_FORMAT_R8G8_SINT,
1206 		VK_FORMAT_R8G8B8_UNORM,
1207 		VK_FORMAT_R8G8B8_SNORM,
1208 		VK_FORMAT_R8G8B8_USCALED,
1209 		VK_FORMAT_R8G8B8_SSCALED,
1210 		VK_FORMAT_R8G8B8_UINT,
1211 		VK_FORMAT_R8G8B8_SINT,
1212 		VK_FORMAT_B8G8R8_UNORM,
1213 		VK_FORMAT_B8G8R8_SNORM,
1214 		VK_FORMAT_B8G8R8_USCALED,
1215 		VK_FORMAT_B8G8R8_SSCALED,
1216 		VK_FORMAT_B8G8R8_UINT,
1217 		VK_FORMAT_B8G8R8_SINT,
1218 		VK_FORMAT_R8G8B8A8_UNORM,
1219 		VK_FORMAT_R8G8B8A8_SNORM,
1220 		VK_FORMAT_R8G8B8A8_USCALED,
1221 		VK_FORMAT_R8G8B8A8_SSCALED,
1222 		VK_FORMAT_R8G8B8A8_UINT,
1223 		VK_FORMAT_R8G8B8A8_SINT,
1224 		VK_FORMAT_B8G8R8A8_UNORM,
1225 		VK_FORMAT_B8G8R8A8_SNORM,
1226 		VK_FORMAT_B8G8R8A8_USCALED,
1227 		VK_FORMAT_B8G8R8A8_SSCALED,
1228 		VK_FORMAT_B8G8R8A8_UINT,
1229 		VK_FORMAT_B8G8R8A8_SINT,
1230 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1231 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1232 		VK_FORMAT_A8B8G8R8_USCALED_PACK32,
1233 		VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
1234 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
1235 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
1236 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1237 		VK_FORMAT_A2R10G10B10_SNORM_PACK32,
1238 		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1239 		VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
1240 		VK_FORMAT_A2R10G10B10_UINT_PACK32,
1241 		VK_FORMAT_A2R10G10B10_SINT_PACK32,
1242 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1243 		VK_FORMAT_A2B10G10R10_SNORM_PACK32,
1244 		VK_FORMAT_A2B10G10R10_USCALED_PACK32,
1245 		VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
1246 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
1247 		VK_FORMAT_A2B10G10R10_SINT_PACK32,
1248 		VK_FORMAT_R16_UNORM,
1249 		VK_FORMAT_R16_SNORM,
1250 		VK_FORMAT_R16_USCALED,
1251 		VK_FORMAT_R16_SSCALED,
1252 		VK_FORMAT_R16_UINT,
1253 		VK_FORMAT_R16_SINT,
1254 		VK_FORMAT_R16_SFLOAT,
1255 		VK_FORMAT_R16G16_UNORM,
1256 		VK_FORMAT_R16G16_SNORM,
1257 		VK_FORMAT_R16G16_USCALED,
1258 		VK_FORMAT_R16G16_SSCALED,
1259 		VK_FORMAT_R16G16_UINT,
1260 		VK_FORMAT_R16G16_SINT,
1261 		VK_FORMAT_R16G16_SFLOAT,
1262 		VK_FORMAT_R16G16B16_UNORM,
1263 		VK_FORMAT_R16G16B16_SNORM,
1264 		VK_FORMAT_R16G16B16_USCALED,
1265 		VK_FORMAT_R16G16B16_SSCALED,
1266 		VK_FORMAT_R16G16B16_UINT,
1267 		VK_FORMAT_R16G16B16_SINT,
1268 		VK_FORMAT_R16G16B16_SFLOAT,
1269 		VK_FORMAT_R16G16B16A16_UNORM,
1270 		VK_FORMAT_R16G16B16A16_SNORM,
1271 		VK_FORMAT_R16G16B16A16_USCALED,
1272 		VK_FORMAT_R16G16B16A16_SSCALED,
1273 		VK_FORMAT_R16G16B16A16_UINT,
1274 		VK_FORMAT_R16G16B16A16_SINT,
1275 		VK_FORMAT_R16G16B16A16_SFLOAT,
1276 		VK_FORMAT_R32_UINT,
1277 		VK_FORMAT_R32_SINT,
1278 		VK_FORMAT_R32_SFLOAT,
1279 		VK_FORMAT_R32G32_UINT,
1280 		VK_FORMAT_R32G32_SINT,
1281 		VK_FORMAT_R32G32_SFLOAT,
1282 	};
1283 
1284 	const char* const					usageName[]						= { "uniform_texel_buffer", "storage_texel_buffer"};
1285 	const vk::VkBufferUsageFlags		usage[]							= { vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT };
1286 	const vk::VkFormatFeatureFlags		feature[]						= { vk::VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, vk::VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT };
1287 	const vk::VkDescriptorType			descType[]					= { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER };
1288 
1289 	for (deUint32 usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usage); ++usageNdx)
1290 	{
1291 		de::MovePtr<tcu::TestCaseGroup>	usageGroup		(new tcu::TestCaseGroup(testCtx, usageName[usageNdx], ""));
1292 
1293 		for (deUint32 formatIdx = 0; formatIdx < DE_LENGTH_OF_ARRAY(testFormats); formatIdx++)
1294 		{
1295 			const auto			skip		= strlen("VK_FORMAT_");
1296 			const std::string	fmtName	= de::toLower(std::string(getFormatName(testFormats[formatIdx])).substr(skip));
1297 			de::MovePtr<tcu::TestCaseGroup>	formatGroup		(new tcu::TestCaseGroup(testCtx, fmtName.c_str(), ""));
1298 
1299 			if (usage[usageNdx] == VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT && !isSupportedImageLoadStore(mapVkFormat(testFormats[formatIdx])))
1300 				continue;
1301 
1302 			const BufferViewCaseParams	info							=
1303 			{
1304 				512,													// deUint32					bufferSize
1305 				128,													// deUint32					bufferViewSize
1306 				0,														// deUint32					elementOffset
1307 				ALLOCATION_KIND_SUBALLOCATION,							// AllocationKind			bufferAllocationKind
1308 				ALLOCATION_KIND_SUBALLOCATION,							// AllocationKind			imageAllocationKind
1309 
1310 				testFormats[formatIdx],									// VkFormat					format
1311 				usage[usageNdx],										// VkBufferUsageFlags		usage
1312 				feature[usageNdx],										// VkFormatFeatureFlags		feature
1313 				descType[usageNdx],										// VkDescriptorType			descType
1314 			};
1315 
1316 			std::ostringstream		description;
1317 			description << "bufferFormat: " << getFormatName(testFormats[formatIdx]) << " bufferSize: " << info.bufferSize << " bufferViewSize: " << info.bufferViewSize << " bufferView element offset: " << info.elementOffset;
1318 
1319 			usageGroup->addChild(new BufferViewAllFormatsTestCase(testCtx, fmtName.c_str(), description.str(), info));
1320 		}
1321 
1322 		bufferViewTests->addChild(usageGroup.release());
1323 	}
1324 
1325 	return bufferViewTests.release();
1326 }
1327 
1328 } // api
1329 } // vkt
1330