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