1/*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2016 The Android Open Source Project
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 Image load/store utilities
23 *//*--------------------------------------------------------------------*/
24
25#include "vktImageLoadStoreUtil.hpp"
26#include "vkQueryUtil.hpp"
27
28using namespace vk;
29
30namespace vkt
31{
32namespace image
33{
34
35float computeStoreColorScale (const vk::VkFormat format, const tcu::IVec3 imageSize)
36{
37	const int maxImageDimension = de::max(imageSize.x(), de::max(imageSize.y(), imageSize.z()));
38	const float div = static_cast<float>(maxImageDimension - 1);
39
40	if (isUnormFormat(format))
41		return 1.0f / div;
42	else if (isSnormFormat(format))
43		return 2.0f / div;
44	else
45		return 1.0f;
46}
47
48ImageType getImageTypeForSingleLayer (const ImageType imageType)
49{
50	switch (imageType)
51	{
52		case IMAGE_TYPE_1D:
53		case IMAGE_TYPE_1D_ARRAY:
54			return IMAGE_TYPE_1D;
55
56		case IMAGE_TYPE_2D:
57		case IMAGE_TYPE_2D_ARRAY:
58		case IMAGE_TYPE_CUBE:
59		case IMAGE_TYPE_CUBE_ARRAY:
60			// A single layer for cube is a 2d face
61			return IMAGE_TYPE_2D;
62
63		case IMAGE_TYPE_3D:
64			return IMAGE_TYPE_3D;
65
66		case IMAGE_TYPE_BUFFER:
67			return IMAGE_TYPE_BUFFER;
68
69		default:
70			DE_FATAL("Internal test error");
71			return IMAGE_TYPE_LAST;
72	}
73}
74
75VkImageCreateInfo makeImageCreateInfo (const Texture& texture, const VkFormat format, const VkImageUsageFlags usage, const VkImageCreateFlags flags)
76{
77	const VkSampleCountFlagBits samples = static_cast<VkSampleCountFlagBits>(texture.numSamples());	// integer and bit mask are aligned, so we can cast like this
78
79	const VkImageCreateInfo imageParams =
80	{
81		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,														// VkStructureType			sType;
82		DE_NULL,																					// const void*				pNext;
83		(isCube(texture) ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0u) | flags,	// VkImageCreateFlags		flags;
84		mapImageType(texture.type()),																// VkImageType				imageType;
85		format,																						// VkFormat					format;
86		makeExtent3D(texture.layerSize()),															// VkExtent3D				extent;
87		1u,																							// deUint32					mipLevels;
88		(deUint32)texture.numLayers(),																// deUint32					arrayLayers;
89		samples,																					// VkSampleCountFlagBits	samples;
90		VK_IMAGE_TILING_OPTIMAL,																	// VkImageTiling			tiling;
91		usage,																						// VkImageUsageFlags		usage;
92		VK_SHARING_MODE_EXCLUSIVE,																	// VkSharingMode			sharingMode;
93		0u,																							// deUint32					queueFamilyIndexCount;
94		DE_NULL,																					// const deUint32*			pQueueFamilyIndices;
95		VK_IMAGE_LAYOUT_UNDEFINED,																	// VkImageLayout			initialLayout;
96	};
97	return imageParams;
98}
99
100
101//! Minimum chunk size is determined by the offset alignment requirements.
102VkDeviceSize getOptimalUniformBufferChunkSize (const InstanceInterface& vki, const VkPhysicalDevice physDevice, VkDeviceSize minimumRequiredChunkSizeBytes)
103{
104	const VkPhysicalDeviceProperties properties = getPhysicalDeviceProperties(vki, physDevice);
105	const VkDeviceSize alignment = properties.limits.minUniformBufferOffsetAlignment;
106
107	if (minimumRequiredChunkSizeBytes > alignment)
108		return alignment + (minimumRequiredChunkSizeBytes / alignment) * alignment;
109	else
110		return alignment;
111}
112
113bool isStorageImageExtendedFormat (const vk::VkFormat format)
114{
115	switch (format)
116	{
117		case VK_FORMAT_R32G32_SFLOAT:
118		case VK_FORMAT_R32G32_SINT:
119		case VK_FORMAT_R32G32_UINT:
120		case VK_FORMAT_R16G16B16A16_UNORM:
121		case VK_FORMAT_R16G16B16A16_SNORM:
122		case VK_FORMAT_R16G16_SFLOAT:
123		case VK_FORMAT_R16G16_UNORM:
124		case VK_FORMAT_R16G16_SNORM:
125		case VK_FORMAT_R16G16_SINT:
126		case VK_FORMAT_R16G16_UINT:
127		case VK_FORMAT_R16_SFLOAT:
128		case VK_FORMAT_R16_UNORM:
129		case VK_FORMAT_R16_SNORM:
130		case VK_FORMAT_R16_SINT:
131		case VK_FORMAT_R16_UINT:
132		case VK_FORMAT_R8G8_UNORM:
133		case VK_FORMAT_R8G8_SNORM:
134		case VK_FORMAT_R8G8_SINT:
135		case VK_FORMAT_R8G8_UINT:
136		case VK_FORMAT_R8_UNORM:
137		case VK_FORMAT_R8_SNORM:
138		case VK_FORMAT_R8_SINT:
139		case VK_FORMAT_R8_UINT:
140			return true;
141
142		default:
143			return false;
144	}
145}
146
147} // image
148} // vkt
149