• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2019 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Vulkan Decriptor Indexing Tests
22 *//*--------------------------------------------------------------------*/
23 
24 #include <algorithm>
25 #include <iostream>
26 #include <iterator>
27 #include <functional>
28 #include <sstream>
29 #include <utility>
30 #include <vector>
31 
32 #include "vktDescriptorSetsIndexingTests.hpp"
33 
34 #include "vkBuilderUtil.hpp"
35 #include "vkCmdUtil.hpp"
36 #include "vkDefs.hpp"
37 #include "vkObjUtil.hpp"
38 #include "vkPlatform.hpp"
39 #include "vkPrograms.hpp"
40 #include "vkQueryUtil.hpp"
41 #include "vkTypeUtil.hpp"
42 
43 #include "tcuTestLog.hpp"
44 #include "tcuResource.hpp"
45 #include "tcuImageCompare.hpp"
46 #include "tcuCommandLine.hpp"
47 #include "tcuStringTemplate.hpp"
48 
49 #include "deRandom.hpp"
50 #include "deMath.h"
51 #include "deStringUtil.hpp"
52 
53 namespace vkt
54 {
55 namespace DescriptorIndexing
56 {
57 using namespace vk;
58 namespace ut
59 {
60 
ImageHandleAlloc(Move<VkImage> & image_,AllocMv & alloc_,const VkExtent3D & extent_,VkFormat format_,bool usesMipMaps_)61 ImageHandleAlloc::ImageHandleAlloc	(Move<VkImage>&					image_,
62 									 AllocMv&						alloc_,
63 									 const VkExtent3D&				extent_,
64 									 VkFormat						format_,
65 									 bool							usesMipMaps_)
66 	: image		(image_)
67 	, alloc		(alloc_)
68 	, extent	(extent_)
69 	, format	(format_)
70 	, levels	(usesMipMaps_ ? computeMipMapCount(extent_) : 1)
71 {
72 }
73 
buildShaderName(VkShaderStageFlagBits stage,VkDescriptorType descriptorType,deBool updateAfterBind,bool calculateInLoop,bool minNonUniform,bool performWritesInVertex)74 std::string buildShaderName			(VkShaderStageFlagBits			stage,
75 									 VkDescriptorType				descriptorType,
76 									 deBool							updateAfterBind,
77 									 bool							calculateInLoop,
78 									 bool							minNonUniform,
79 									 bool							performWritesInVertex)
80 {
81 	const char* stageName = DE_NULL;
82 	switch (stage)
83 	{
84 	case VK_SHADER_STAGE_VERTEX_BIT:					stageName = "vert"; break;
85 	case VK_SHADER_STAGE_FRAGMENT_BIT:					stageName = "frag"; break;
86 	case VK_SHADER_STAGE_COMPUTE_BIT:					stageName = "comp"; break;
87 	case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:		stageName = "tesc"; break;
88 	case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:	stageName = "tese";	break;
89 	case VK_SHADER_STAGE_GEOMETRY_BIT:					stageName = "geom"; break;
90 	default:											stageName = "any";	break;
91 	}
92 	DE_ASSERT(stageName);
93 
94 	std::map<std::string, std::string> m;
95 	m["STAGE"]	= stageName;
96 	m["DESC"]	= de::toString(deUint32(descriptorType));
97 	m["ABIND"]	= updateAfterBind		? "_afterBind"		: "";
98 	m["LOOP"]	= calculateInLoop		? "_inLoop"			: "";
99 	m["MINNU"]	= minNonUniform			? "_minNonUniform"	: "";
100 	m["SHWR"]	= performWritesInVertex	? "_shaderWrites"	: "";
101 
102 	return tcu::StringTemplate("descriptorIndexing_${STAGE}${DESC}${ABIND}${LOOP}${MINNU}${SHWR}").specialize(m);
103 }
104 
generatePrimes(deUint32 limit)105 std::vector<deUint32> generatePrimes (deUint32						limit)
106 {
107 	deUint32 i, j, *data;
108 	std::vector<deUint32> v(limit);
109 
110 	data = v.data();
111 
112 	for (i = 0; i < limit; ++i)
113 		data[i] = i;
114 
115 	for (i = 2; i < limit; ++i)
116 	{
117 		if (data[i])
118 		{
119 			for (j = i*2; j < limit; j += i)
120 				data[j] = 0;
121 		}
122 	}
123 
124 	std::vector<deUint32>::iterator x = std::stable_partition(v.begin(), v.end(), [](deUint32 value) { return value >= 2; });
125 
126 	return std::vector<deUint32>(v.begin(), x);
127 }
128 
computePrimeCount(deUint32 limit)129 deUint32 computePrimeCount			(deUint32						limit)
130 {
131 	deUint32 i, j, k, *data;
132 	std::vector<deUint32> v(limit);
133 
134 	data = v.data();
135 
136 	for (i = 0; i < limit; ++i)
137 		data[i] = i;
138 
139 	k = 0;
140 	for (i = 2; i < limit; ++i)
141 	{
142 		if (data[i])
143 		{
144 			++k;
145 			for (j = i*2; j < limit; j += i)
146 				data[j] = 0;
147 		}
148 	}
149 	return k;
150 }
151 
computeMipMapCount(const VkExtent3D & extent)152 deUint32 computeMipMapCount			(const VkExtent3D&				extent)
153 {
154 	return deUint32(floor(log2(std::max(extent.width, extent.height)))) + 1;
155 }
156 
computeImageSize(const VkExtent3D & extent,VkFormat format,bool withMipMaps,deUint32 level)157 deUint32 computeImageSize			(const VkExtent3D&				extent,
158 									 VkFormat						format,
159 									 bool							withMipMaps,
160 									 deUint32						level)
161 {
162 	deUint32 mipSize = extent.width * extent.height * extent.depth * vk::mapVkFormat(format).getPixelSize();
163 	if (withMipMaps)
164 	{
165 		deUint32		mipIdx		= 0u;
166 		deUint32		width		= extent.width;
167 		deUint32		height		= extent.height;
168 		const deUint32	mipCount	= computeMipMapCount(extent) - 1;
169 		do
170 		{
171 			width /= 2;
172 			height /= 2;
173 			deUint32 tmpSize = width * height * extent.depth * vk::mapVkFormat(format).getPixelSize();
174 
175 			if (level == mipIdx)
176 			{
177 				break;
178 			}
179 			else if (level == maxDeUint32)
180 			{
181 				mipSize += tmpSize;
182 			}
183 			else
184 			{
185 				mipSize = tmpSize;
186 			}
187 
188 		} while (++mipIdx < mipCount);
189 	}
190 	return mipSize;
191 }
192 
computeImageSize(const ImageHandleAllocSp & image)193 deUint32 computeImageSize			(const ImageHandleAllocSp&		image)
194 {
195 	return computeImageSize(image->extent, image->format);
196 }
197 
createImageAndBind(ut::ImageHandleAllocSp & output,const vkt::Context & ctx,VkFormat colorFormat,const VkExtent3D & extent,VkImageLayout initialLayout,bool withMipMaps,VkImageType imageType)198 void createImageAndBind				(ut::ImageHandleAllocSp&		output,
199 									 const vkt::Context&			ctx,
200 									 VkFormat						colorFormat,
201 									 const VkExtent3D&				extent,
202 									 VkImageLayout					initialLayout,
203 									 bool							withMipMaps,
204 									 VkImageType					imageType)
205 {
206 	const bool						isDepthStencilFormat = vk::isDepthStencilFormat(colorFormat);
207 
208 	const VkImageUsageFlags			imageUsageFlagsDependent = isDepthStencilFormat
209 		? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
210 		: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
211 
212 	const VkImageUsageFlags			imageUsageFlags = imageUsageFlagsDependent
213 		| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
214 		| VK_IMAGE_USAGE_TRANSFER_DST_BIT
215 		| VK_IMAGE_USAGE_SAMPLED_BIT
216 		| VK_IMAGE_USAGE_STORAGE_BIT
217 		| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
218 
219 	const deUint32 mipLevels = withMipMaps ? computeMipMapCount(extent) : 1;
220 	const VkImageCreateInfo			createInfo =
221 	{
222 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// sType
223 		DE_NULL,								// pNext
224 		(VkImageCreateFlags)0,					// flags
225 		imageType,								// imageType
226 		colorFormat,							// format
227 		extent,									// extent
228 		mipLevels,								// mipLevels
229 		(deUint32)1,							// arrayLayers
230 		VK_SAMPLE_COUNT_1_BIT,					// samples
231 		VK_IMAGE_TILING_OPTIMAL,				// tiling
232 		imageUsageFlags,						// usage
233 		VK_SHARING_MODE_EXCLUSIVE,				// sharingMode
234 		(deUint32)0,							// queueFamilyCount
235 		DE_NULL,								// pQueueFamilyIndices
236 		initialLayout							// initialLayout
237 	};
238 
239 	Allocator&						allocator	= ctx.getDefaultAllocator();
240 	VkDevice						device		= ctx.getDevice();
241 	const DeviceInterface&			dinterface	= ctx.getDeviceInterface();
242 
243 	Move<VkImage>					image		= vk::createImage(dinterface, device, &createInfo);
244 
245 	const VkMemoryRequirements		memReqs		= vk::getImageMemoryRequirements(dinterface, device, *image);
246 	de::MovePtr<Allocation>			allocation	= allocator.allocate(memReqs, MemoryRequirement::Any);
247 
248 	VK_CHECK(dinterface.bindImageMemory(device, *image, allocation->getMemory(), allocation->getOffset()));
249 
250 	output = ImageHandleAllocSp(new ImageHandleAlloc(image, allocation, extent, colorFormat, withMipMaps));
251 }
252 
recordCopyBufferToImage(VkCommandBuffer cmd,const DeviceInterface & interface,VkPipelineStageFlagBits srcStageMask,VkPipelineStageFlagBits dstStageMask,const VkDescriptorBufferInfo & bufferInfo,VkImage image,const VkExtent3D & imageExtent,VkFormat imageFormat,VkImageLayout oldImageLayout,VkImageLayout newImageLayout,deUint32 mipLevelCount)253 void recordCopyBufferToImage		(VkCommandBuffer				cmd,
254 									 const DeviceInterface&			interface,
255 									 VkPipelineStageFlagBits		srcStageMask,
256 									 VkPipelineStageFlagBits		dstStageMask,
257 									 const VkDescriptorBufferInfo&	bufferInfo,
258 									 VkImage						image,
259 									 const VkExtent3D&				imageExtent,
260 									 VkFormat						imageFormat,
261 									 VkImageLayout					oldImageLayout,
262 									 VkImageLayout					newImageLayout,
263 									 deUint32						mipLevelCount)
264 {
265 	const VkImageAspectFlags imageAspect = vk::isDepthStencilFormat(imageFormat)
266 		? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT
267 		: VK_IMAGE_ASPECT_COLOR_BIT;
268 
269 	std::vector<VkBufferImageCopy>	copyRegions;
270 	{
271 		deUint32		width			= imageExtent.width;
272 		deUint32		height			= imageExtent.height;
273 		VkDeviceSize	bufferOffset	= bufferInfo.offset;
274 
275 		for (deUint32 mipIdx = 0; mipIdx < mipLevelCount; ++mipIdx)
276 		{
277 			VkDeviceSize	imageSize = computeImageSize(imageExtent, imageFormat, true, mipIdx);
278 
279 			const VkBufferImageCopy		copyRegion =
280 			{
281 				bufferOffset,							// bufferOffset
282 				width,									// bufferRowLength
283 				height,									// bufferImageHeight
284 				{
285 					imageAspect,						// aspect
286 					mipIdx,								// mipLevel
287 					0u,									// baseArrayLayer
288 					1u,									// layerCount
289 				},										// VkImageSubresourceLayers imageSubresource
290 				{ 0,0,0 },								// VkOffset3D				imageOffset
291 				{ width, height, 1 }					// VkExtent3D				imageExtent
292 			};
293 
294 			copyRegions.push_back(copyRegion);
295 
296 			bufferOffset	+= imageSize;
297 			width			/= 2;
298 			height			/= 2;
299 		}
300 	}
301 
302 	const VkImageSubresourceRange		subresourceRange =
303 	{
304 		imageAspect,									// aspectMask
305 		0u,												// baseMipLevel
306 		mipLevelCount,									// levelCount
307 		0u,												// baseArrayLayer
308 		1u,												// layerCount
309 	};
310 
311 	const VkImageMemoryBarrier	barrierBefore =
312 	{
313 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType;
314 		DE_NULL,										// pNext;
315 		0,												// srcAccessMask;
316 		VK_ACCESS_TRANSFER_WRITE_BIT,					// dstAccessMask;
317 		oldImageLayout,									// oldLayout;
318 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// newLayout;
319 		VK_QUEUE_FAMILY_IGNORED,						// srcQueueFamilyIndex;
320 		VK_QUEUE_FAMILY_IGNORED,						// dstQueueFamilyIndex;
321 		image,											// image
322 		subresourceRange								// subresourceRange
323 	};
324 
325 	const VkBufferMemoryBarrier	bufferBarrier =
326 	{
327 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// sType;
328 		DE_NULL,										// pNext;
329 		pipelineAccessFromStage(srcStageMask, false),	// srcAccessMask;
330 		VK_ACCESS_TRANSFER_READ_BIT,					// dstAccessMask;
331 		VK_QUEUE_FAMILY_IGNORED,						// srcQueueFamilyIndex;
332 		VK_QUEUE_FAMILY_IGNORED,						// dstQueueFamilyIndex;
333 		bufferInfo.buffer,								// buffer;
334 		bufferInfo.offset,								// offset;
335 		bufferInfo.range								// size;
336 	};
337 
338 	const VkImageMemoryBarrier	barrierAfter =
339 	{
340 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType;
341 		DE_NULL,										// pNext;
342 		VK_ACCESS_TRANSFER_WRITE_BIT,					// srcAccessMask;
343 		pipelineAccessFromStage(dstStageMask, true)
344 		| pipelineAccessFromStage(dstStageMask, false),	// dstAccessMask;
345 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// oldLayout;
346 		newImageLayout,									// newLayout;
347 		VK_QUEUE_FAMILY_IGNORED,						// srcQueueFamilyIndex;
348 		VK_QUEUE_FAMILY_IGNORED,						// dstQueueFamilyIndex;
349 		image,											// image
350 		subresourceRange								// subresourceRange
351 	};
352 
353 	interface.cmdPipelineBarrier(cmd,
354 		srcStageMask, VK_PIPELINE_STAGE_TRANSFER_BIT,	// srcStageMask, dstStageMask
355 		(VkDependencyFlags)0,							// dependencyFlags
356 		0u, DE_NULL,									// memoryBarrierCount, pMemoryBarriers
357 		1u, &bufferBarrier,								// bufferBarrierCount, pBufferBarriers
358 		1u, &barrierBefore);							// imageBarrierCount, pImageBarriers
359 
360 	interface.cmdCopyBufferToImage(cmd, bufferInfo.buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(copyRegions.size()), copyRegions.data());
361 
362 	interface.cmdPipelineBarrier(cmd,
363 		VK_PIPELINE_STAGE_TRANSFER_BIT, dstStageMask,	// srcStageMask, dstStageMask
364 		(VkDependencyFlags)0,							// dependencyFlags
365 		0u, DE_NULL,									// memoryBarrierCount, pMemoryBarriers
366 		0u, DE_NULL,									// bufferBarrierCount, pBufferBarriers
367 		1u, &barrierAfter);								// imageBarrierCount, pImageBarriers
368 }
369 
recordCopyImageToBuffer(VkCommandBuffer cmd,const DeviceInterface & interface,VkPipelineStageFlagBits srcStageMask,VkPipelineStageFlagBits dstStageMask,VkImage image,const VkExtent3D & imageExtent,VkFormat imageFormat,VkImageLayout oldImageLayout,VkImageLayout newImageLayout,const VkDescriptorBufferInfo & bufferInfo)370 void recordCopyImageToBuffer		(VkCommandBuffer				cmd,
371 									 const DeviceInterface&			interface,
372 									 VkPipelineStageFlagBits		srcStageMask,
373 									 VkPipelineStageFlagBits		dstStageMask,
374 									 VkImage						image,
375 									 const VkExtent3D&				imageExtent,
376 									 VkFormat						imageFormat,
377 									 VkImageLayout					oldImageLayout,
378 									 VkImageLayout					newImageLayout,
379 									 const VkDescriptorBufferInfo&	bufferInfo)
380 {
381 	const VkImageAspectFlags imageAspect = vk::isDepthStencilFormat(imageFormat)
382 		? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT
383 		: VK_IMAGE_ASPECT_COLOR_BIT;
384 
385 	const VkBufferImageCopy		copyRegion =
386 	{
387 		bufferInfo.offset,								// bufferOffset
388 		imageExtent.width,								// bufferRowLength
389 		imageExtent.height,								// bufferImageHeight
390 		{
391 			imageAspect,								// aspect
392 			0u,											// mipLevel
393 			0u,											// baseArrayLayer
394 			1u,											// layerCount
395 		},												// VkImageSubresourceLayers
396 		{ 0, 0, 0 },									// imageOffset
397 		imageExtent										// imageExtent
398 	};
399 
400 	VkImageSubresourceRange		subresourceRange =
401 	{
402 		VK_IMAGE_ASPECT_COLOR_BIT,						// aspectMask
403 		0u,												// baseMipLevel
404 		1u,												// levelCount
405 		0u,												// baseArrayLayer
406 		1u,												// layerCount
407 	};
408 
409 	const VkImageMemoryBarrier	barrierBefore =
410 	{
411 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType;
412 		DE_NULL,										// pNext;
413 		pipelineAccessFromStage(srcStageMask, false),	// srcAccessMask;
414 		VK_ACCESS_TRANSFER_READ_BIT,					// dstAccessMask;
415 		oldImageLayout,									// oldLayout
416 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,			// newLayout;
417 		VK_QUEUE_FAMILY_IGNORED,						// srcQueueFamilyIndex;
418 		VK_QUEUE_FAMILY_IGNORED,						// dstQueueFamilyIndex;
419 		image,											// image;
420 		subresourceRange,								// subresourceRange;
421 	};
422 
423 	const VkImageMemoryBarrier	barrierAfter =
424 	{
425 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType;
426 		DE_NULL,										// pNext;
427 		VK_ACCESS_TRANSFER_READ_BIT,					// srcAccessMask;
428 		pipelineAccessFromStage(dstStageMask, true)
429 		| pipelineAccessFromStage(dstStageMask, false),	// dstAccessMask;
430 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,			// oldLayout;
431 		newImageLayout,									// newLayout;
432 		VK_QUEUE_FAMILY_IGNORED,						// srcQueueFamilyIndex;
433 		VK_QUEUE_FAMILY_IGNORED,						// dstQueueFamilyIndex;
434 		image,											// image
435 		subresourceRange								// subresourceRange
436 	};
437 
438 	interface.cmdPipelineBarrier(cmd,					// commandBuffer
439 		srcStageMask, VK_PIPELINE_STAGE_TRANSFER_BIT,	// srcStageMask, dstStageMask
440 		(VkDependencyFlags)0,							// dependencyFlags
441 		0u, DE_NULL,									// memoryBarrierCount, pMemoryBarriers
442 		0u, DE_NULL,									// bufferBarrierCount, pBufferBarriers
443 		1u, &barrierBefore);							// imageBarrierCount, pImageBarriers
444 
445 	interface.cmdCopyImageToBuffer(cmd, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferInfo.buffer, 1u, &copyRegion);
446 
447 	interface.cmdPipelineBarrier(cmd,
448 		VK_PIPELINE_STAGE_TRANSFER_BIT, dstStageMask,
449 		(VkDependencyFlags)0,
450 		0u, DE_NULL,
451 		0u, DE_NULL,
452 		0u, &barrierAfter);
453 }
454 
pipelineAccessFromStage(VkPipelineStageFlagBits stage,bool readORwrite)455 VkAccessFlags pipelineAccessFromStage (VkPipelineStageFlagBits stage, bool readORwrite)
456 {
457 	VkAccessFlags access[2];
458 	VkAccessFlags& readAccess = access[1];
459 	VkAccessFlags& writeAccess = access[0];
460 	readAccess = writeAccess = static_cast<VkAccessFlagBits>(0);
461 
462 	switch (stage)
463 	{
464 	case VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT:
465 	case VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT:
466 		readAccess = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
467 		break;
468 
469 	case VK_PIPELINE_STAGE_VERTEX_INPUT_BIT:
470 		readAccess = static_cast<VkAccessFlagBits>(VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT);
471 		break;
472 
473 	case VK_PIPELINE_STAGE_VERTEX_SHADER_BIT:
474 	case VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT:
475 	case VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT:
476 	case VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT:
477 	case VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT:
478 		readAccess = VK_ACCESS_SHADER_READ_BIT;
479 		writeAccess = VK_ACCESS_SHADER_WRITE_BIT;
480 		break;
481 
482 	case VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT:
483 		readAccess = static_cast<VkAccessFlagBits>(VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
484 		writeAccess = VK_ACCESS_SHADER_READ_BIT;
485 		break;
486 
487 	case VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT:
488 		readAccess = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
489 		writeAccess = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
490 		break;
491 
492 	case VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT:
493 	case VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT:
494 		readAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
495 		writeAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
496 		break;
497 
498 	case VK_PIPELINE_STAGE_TRANSFER_BIT:
499 		readAccess = VK_ACCESS_TRANSFER_READ_BIT;
500 		writeAccess = VK_ACCESS_TRANSFER_WRITE_BIT;
501 		break;
502 
503 	case VK_PIPELINE_STAGE_HOST_BIT:
504 		readAccess = VK_ACCESS_HOST_READ_BIT;
505 		writeAccess = VK_ACCESS_HOST_WRITE_BIT;
506 		break;
507 
508 	default:
509 		if (stage == 0)
510 		{
511 			readAccess = VK_ACCESS_MEMORY_READ_BIT;
512 			writeAccess = VK_ACCESS_MEMORY_WRITE_BIT;
513 			break;
514 		}
515 
516 		DE_ASSERT(DE_FALSE);
517 	}
518 	return access[readORwrite ? 1 : 0];
519 }
520 
createFrameBuffer(FrameBufferSp & outputFB,const vkt::Context & context,const VkExtent3D & extent,VkFormat colorFormat,VkRenderPass renderpass,deUint32 additionalAttachmentCount,const VkImageView additionalAttachments[])521 void createFrameBuffer				(FrameBufferSp&					outputFB,
522 									 const vkt::Context&			context,
523 									 const VkExtent3D&				extent,
524 									 VkFormat						colorFormat,
525 									 VkRenderPass					renderpass,
526 									 deUint32						additionalAttachmentCount,
527 									 const VkImageView				additionalAttachments[])
528 {
529 	outputFB						= FrameBufferSp(new ut::FrameBuffer);
530 	VkDevice						device = context.getDevice();
531 	const DeviceInterface&			interface = context.getDeviceInterface();
532 	createImageAndBind(outputFB->image, context, colorFormat, extent, VK_IMAGE_LAYOUT_UNDEFINED);
533 
534 	// create and attachment0
535 	{
536 		const VkImageViewCreateInfo viewCreateInfo =
537 		{
538 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// sType
539 			DE_NULL,									// pNext
540 			(VkImageViewCreateFlags)0,					// flags
541 			*outputFB->image->image,						// image
542 			VK_IMAGE_VIEW_TYPE_2D,						// viewType
543 			colorFormat,								// format
544 			vk::makeComponentMappingRGBA(),				// components
545 			{
546 				VK_IMAGE_ASPECT_COLOR_BIT,	// aspectMask
547 				(deUint32)0,				// baseMipLevel
548 				(deUint32)1,				// mipLevels
549 				(deUint32)0,				// baseArrayLayer
550 				(deUint32)1u,				// arraySize
551 			},
552 		};
553 
554 		outputFB->attachment0 = vk::createImageView(interface, device, &viewCreateInfo);
555 
556 		std::vector<VkImageView>& attachments(outputFB->attachments);
557 		attachments.push_back(*outputFB->attachment0);
558 		if (additionalAttachments && additionalAttachmentCount)
559 		{
560 			attachments.insert(attachments.end(), additionalAttachments, additionalAttachments + additionalAttachmentCount);
561 		}
562 	}
563 
564 	// create a frame buffer
565 	{
566 		std::vector<VkImageView>& attachments(outputFB->attachments);
567 
568 		const VkFramebufferCreateInfo	framebufferCreateInfo =
569 		{
570 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// sType
571 			DE_NULL,									// pNext
572 			(VkFramebufferCreateFlags)0,				// flags
573 			renderpass,									// renderPass
574 			static_cast<deUint32>(attachments.size()),	// attachmentCount
575 			attachments.data(),							// pAttachments
576 			extent.width,								// width
577 			extent.height,								// height
578 			(deUint32)1									// layers
579 		};
580 
581 		outputFB->buffer = vk::createFramebuffer(interface, device, &framebufferCreateInfo);
582 	}
583 }
584 
createBufferAndBind(ut::BufferHandleAllocSp & output,const vkt::Context & ctx,VkBufferUsageFlags usage,VkDeviceSize desiredSize)585 VkDeviceSize createBufferAndBind	(ut::BufferHandleAllocSp&	output,
586 									 const vkt::Context&		ctx,
587 									 VkBufferUsageFlags			usage,
588 									 VkDeviceSize				desiredSize)
589 {
590 	const size_t				nonCoherentAtomSize	(static_cast<size_t>(ctx.getDeviceProperties().limits.nonCoherentAtomSize));
591 	const VkDeviceSize			roundedSize			(deAlignSize(static_cast<size_t>(desiredSize), nonCoherentAtomSize));
592 	Allocator&					allocator			(ctx.getDefaultAllocator());
593 	VkDevice					device				(ctx.getDevice());
594 	const DeviceInterface&		interface			(ctx.getDeviceInterface());
595 
596 	const VkBufferCreateInfo	createInfo =
597 	{
598 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// sType
599 		DE_NULL,									// pNext
600 		(VkBufferCreateFlags)0,						// flags
601 		roundedSize,								// size
602 		usage,										// usage
603 		VK_SHARING_MODE_EXCLUSIVE,					// sharingMode
604 		0u,											// queueFamilyIndexCount
605 		DE_NULL,									// pQueueFamilyIndices
606 	};
607 
608 	Move<VkBuffer>				buffer				= vk::createBuffer(interface, device, &createInfo);
609 
610 	const VkMemoryRequirements	memRequirements		= vk::getBufferMemoryRequirements(interface, device, *buffer);
611 	de::MovePtr<Allocation>		allocation			= allocator.allocate(memRequirements, MemoryRequirement::HostVisible);
612 
613 	VK_CHECK(interface.bindBufferMemory(device, *buffer, allocation->getMemory(), allocation->getOffset()));
614 
615 	output = BufferHandleAllocSp(new BufferHandleAlloc(buffer, allocation));
616 
617 	return roundedSize;
618 }
619 
createVertices(deUint32 width,deUint32 height,float & xSize,float & ySize)620 std::vector<tcu::Vec4> createVertices (deUint32 width, deUint32 height, float& xSize, float& ySize)
621 {
622 	std::vector<tcu::Vec4> result;
623 
624 	const float		xStep = 2.0f / static_cast<float>(width);
625 	const float		yStep = 2.0f / static_cast<float>(height);
626 	const float		xStart = -1.0f + xStep / 2.0f;
627 	const float		yStart = -1.0f + yStep / 2.0f;
628 
629 	xSize = xStep;
630 	ySize = yStep;
631 
632 	float x = xStart;
633 	float y = yStart;
634 
635 	result.reserve(width * height);
636 
637 	for (deUint32 row = 0u; row < height; ++row)
638 	{
639 		for (deUint32 col = 0u; col < width; ++col)
640 		{
641 			result.push_back(tcu::Vec4(x, y, 1.0f, 1.0f));
642 			x += xStep;
643 		}
644 
645 		y += yStep;
646 		x = xStart;
647 	}
648 
649 	return result;
650 }
651 
isDynamicDescriptor(VkDescriptorType descriptorType)652 bool isDynamicDescriptor (VkDescriptorType descriptorType)
653 {
654 	return descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
655 }
656 
DeviceProperties(const DeviceProperties & src)657 DeviceProperties::DeviceProperties (const DeviceProperties& src)
658 {
659 	m_descriptorIndexingFeatures = src.m_descriptorIndexingFeatures;
660 	m_features2 = src.m_features2;
661 
662 	m_descriptorIndexingProperties = src.m_descriptorIndexingProperties;
663 	m_properties2 = src.m_properties2;
664 }
665 
DeviceProperties(const vkt::Context & testContext)666 DeviceProperties::DeviceProperties (const vkt::Context& testContext)
667 {
668 	VkPhysicalDevice device = testContext.getPhysicalDevice();
669 	const InstanceInterface& interface = testContext.getInstanceInterface();
670 
671 	deMemset(&m_descriptorIndexingFeatures, 0, sizeof(m_descriptorIndexingFeatures));
672 	m_descriptorIndexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;
673 	m_descriptorIndexingFeatures.pNext = DE_NULL;
674 
675 	deMemset(&m_features2, 0, sizeof(m_features2));
676 	m_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
677 	m_features2.pNext = &m_descriptorIndexingFeatures;
678 
679 	interface.getPhysicalDeviceFeatures2(device, &m_features2);
680 
681 	deMemset(&m_descriptorIndexingProperties, 0, sizeof(m_descriptorIndexingProperties));
682 	m_descriptorIndexingProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES;
683 	m_descriptorIndexingProperties.pNext = DE_NULL;
684 
685 	deMemset(&m_properties2, 0, sizeof(m_properties2));
686 	m_properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
687 	m_properties2.pNext = &m_descriptorIndexingProperties;
688 
689 	interface.getPhysicalDeviceProperties2(device, &m_properties2);
690 }
691 
computeMaxPerStageDescriptorCount(VkDescriptorType descriptorType,bool enableUpdateAfterBind,bool reserveUniformTexelBuffer) const692 deUint32 DeviceProperties::computeMaxPerStageDescriptorCount	(VkDescriptorType	descriptorType,
693 																 bool				enableUpdateAfterBind,
694 																 bool				reserveUniformTexelBuffer) const
695 {
696 	const VkPhysicalDeviceDescriptorIndexingProperties&		descriptorProps = descriptorIndexingProperties();
697 	const VkPhysicalDeviceProperties&						deviceProps = physicalDeviceProperties();
698 
699 	deUint32		result					= 0;
700 	deUint32		samplers				= 0;
701 	deUint32		uniformBuffers			= 0;
702 	deUint32		uniformBuffersDynamic	= 0;
703 	deUint32		storageBuffers			= 0;
704 	deUint32		storageBuffersDynamic	= 0;
705 	deUint32		sampledImages			= 0;
706 	deUint32		storageImages			= 0;
707 	deUint32		inputAttachments		= 0;
708 	deUint32		inlineUniforms			= 0;
709 
710 	// in_loop tests use an additional single texel buffer, which is calculated against the limits below
711 	const deUint32	reservedCount			= (reserveUniformTexelBuffer ? 1u : 0u);
712 
713 	const deUint32	resources				= deviceProps.limits.maxPerStageResources - reservedCount;
714 
715 	if (enableUpdateAfterBind)
716 	{
717 		samplers				= deMinu32(	descriptorProps.maxPerStageDescriptorUpdateAfterBindSamplers,			descriptorProps.maxDescriptorSetUpdateAfterBindSamplers);				// 1048576
718 		uniformBuffers			= deMinu32(	descriptorProps.maxPerStageDescriptorUpdateAfterBindUniformBuffers,		descriptorProps.maxDescriptorSetUpdateAfterBindUniformBuffers);			// 15
719 		uniformBuffersDynamic	= deMinu32(	descriptorProps.maxPerStageDescriptorUpdateAfterBindUniformBuffers,		descriptorProps.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic);	// 8
720 		storageBuffers			= deMinu32(	descriptorProps.maxPerStageDescriptorUpdateAfterBindStorageBuffers,		descriptorProps.maxDescriptorSetUpdateAfterBindStorageBuffers);			// 1048576
721 		storageBuffersDynamic	= deMinu32(	descriptorProps.maxPerStageDescriptorUpdateAfterBindStorageBuffers,		descriptorProps.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic);	// 8
722 		sampledImages			= deMinu32(	descriptorProps.maxPerStageDescriptorUpdateAfterBindSampledImages,		descriptorProps.maxDescriptorSetUpdateAfterBindSampledImages);			// 1048576
723 		storageImages			= deMinu32(	descriptorProps.maxPerStageDescriptorUpdateAfterBindStorageImages,		descriptorProps.maxDescriptorSetUpdateAfterBindStorageImages);			// 1048576
724 		inputAttachments		= deMinu32(	descriptorProps.maxPerStageDescriptorUpdateAfterBindInputAttachments,	descriptorProps.maxDescriptorSetUpdateAfterBindInputAttachments);		// 1048576
725 	}
726 	else
727 	{
728 		samplers				= deMinu32(	deviceProps.limits.maxPerStageDescriptorSamplers,						deviceProps.limits.maxDescriptorSetSamplers);							// 1048576
729 		uniformBuffers			= deMinu32(	deviceProps.limits.maxPerStageDescriptorUniformBuffers,					deviceProps.limits.maxDescriptorSetUniformBuffers);						// 15
730 		uniformBuffersDynamic	= deMinu32(	deviceProps.limits.maxPerStageDescriptorUniformBuffers,					deviceProps.limits.maxDescriptorSetUniformBuffersDynamic);				// 8
731 		storageBuffers			= deMinu32(	deviceProps.limits.maxPerStageDescriptorStorageBuffers,					deviceProps.limits.maxDescriptorSetStorageBuffers);						// 1048576
732 		storageBuffersDynamic	= deMinu32(	deviceProps.limits.maxPerStageDescriptorStorageBuffers,					deviceProps.limits.maxDescriptorSetStorageBuffersDynamic);				// 8
733 		sampledImages			= deMinu32(	deviceProps.limits.maxPerStageDescriptorSampledImages - reservedCount,	deviceProps.limits.maxDescriptorSetSampledImages - reservedCount);		// 1048576.
734 		storageImages			= deMinu32(	deviceProps.limits.maxPerStageDescriptorStorageImages,					deviceProps.limits.maxDescriptorSetStorageImages);						// 1048576
735 		inputAttachments		= deMinu32(	deviceProps.limits.maxPerStageDescriptorInputAttachments - 1,			deviceProps.limits.maxDescriptorSetInputAttachments - 1);				// 1048576. -1 because tests use a prime number + 1 to reference subpass input attachment in shader
736 	}
737 
738 	// adding arbitrary upper bound limits to restrain the size of the test ( we are testing big arrays, not the maximum size arrays )
739 	samplers					= deMinu32(	samplers,				4096);
740 	uniformBuffers				= deMinu32(	uniformBuffers,			16);
741 	uniformBuffersDynamic		= deMinu32( uniformBuffersDynamic,	16);
742 	storageBuffers				= deMinu32(	storageBuffers,			8192);
743 	storageBuffersDynamic		= deMinu32(	storageBuffersDynamic,	8192);
744 	sampledImages				= deMinu32(	sampledImages,			8192);
745 	storageImages				= deMinu32(	storageImages,			8192);
746 	inputAttachments			= deMinu32(	inputAttachments,		16);
747 
748 	switch (descriptorType)
749 	{
750 	case VK_DESCRIPTOR_TYPE_SAMPLER:					result = samplers;													break;
751 	case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:		result = deMinu32(resources, deMinu32(samplers, sampledImages));	break;
752 	case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:				result = deMinu32(resources, sampledImages);						break;
753 	case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:				result = deMinu32(resources, storageImages);						break;
754 	case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:		result = deMinu32(resources, sampledImages);						break;
755 	case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:		result = deMinu32(resources, storageImages);						break;
756 	case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:				result = deMinu32(resources, uniformBuffers);						break;
757 	case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:				result = deMinu32(resources, storageBuffers);						break;
758 	case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:		result = deMinu32(resources, uniformBuffersDynamic);				break;
759 	case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:		result = deMinu32(resources, storageBuffersDynamic);				break;
760 	case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:			result = deMinu32(resources, inputAttachments);						break;
761 	case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:	result = deMinu32(resources, inlineUniforms);						break;
762 	default: DE_ASSERT(0);
763 	}
764 
765 	DE_ASSERT(result);
766 
767 	return result;
768 }
769 
770 } // - namespace ut
771 } // - namespace DescriptorIndexing
772 } // - namespace vkt
773