1 // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "VkPhysicalDevice.hpp"
16 
17 #include "VkConfig.hpp"
18 #include "VkStringify.hpp"
19 #include "Pipeline/SpirvShader.hpp"  // sw::SIMD::Width
20 #include "Reactor/Reactor.hpp"
21 
22 #include <cstring>
23 #include <limits>
24 
25 #ifdef __ANDROID__
26 #	include <android/hardware_buffer.h>
27 #endif
28 
29 namespace vk {
30 
PhysicalDevice(const void *,void * mem)31 PhysicalDevice::PhysicalDevice(const void *, void *mem)
32 {
33 }
34 
getFeatures() const35 const VkPhysicalDeviceFeatures &PhysicalDevice::getFeatures() const
36 {
37 	static const VkPhysicalDeviceFeatures features{
38 		VK_TRUE,   // robustBufferAccess
39 		VK_TRUE,   // fullDrawIndexUint32
40 		VK_TRUE,   // imageCubeArray
41 		VK_TRUE,   // independentBlend
42 		VK_FALSE,  // geometryShader
43 		VK_FALSE,  // tessellationShader
44 		VK_TRUE,   // sampleRateShading
45 		VK_FALSE,  // dualSrcBlend
46 		VK_FALSE,  // logicOp
47 		VK_TRUE,   // multiDrawIndirect
48 		VK_TRUE,   // drawIndirectFirstInstance
49 		VK_FALSE,  // depthClamp
50 		VK_TRUE,   // depthBiasClamp
51 		VK_TRUE,   // fillModeNonSolid
52 		VK_FALSE,  // depthBounds
53 		VK_FALSE,  // wideLines
54 		VK_TRUE,   // largePoints
55 		VK_FALSE,  // alphaToOne
56 		VK_FALSE,  // multiViewport
57 		VK_TRUE,   // samplerAnisotropy
58 		VK_TRUE,   // textureCompressionETC2
59 #ifdef SWIFTSHADER_ENABLE_ASTC
60 		VK_TRUE,  // textureCompressionASTC_LDR
61 #else
62 		VK_FALSE,  // textureCompressionASTC_LDR
63 #endif
64 		VK_TRUE,   // textureCompressionBC
65 		VK_TRUE,   // occlusionQueryPrecise
66 		VK_FALSE,  // pipelineStatisticsQuery
67 		VK_TRUE,   // vertexPipelineStoresAndAtomics
68 		VK_TRUE,   // fragmentStoresAndAtomics
69 		VK_FALSE,  // shaderTessellationAndGeometryPointSize
70 		VK_FALSE,  // shaderImageGatherExtended
71 		VK_TRUE,   // shaderStorageImageExtendedFormats
72 		VK_TRUE,   // shaderStorageImageMultisample
73 		VK_FALSE,  // shaderStorageImageReadWithoutFormat
74 		VK_FALSE,  // shaderStorageImageWriteWithoutFormat
75 		VK_TRUE,   // shaderUniformBufferArrayDynamicIndexing
76 		VK_TRUE,   // shaderSampledImageArrayDynamicIndexing
77 		VK_TRUE,   // shaderStorageBufferArrayDynamicIndexing
78 		VK_TRUE,   // shaderStorageImageArrayDynamicIndexing
79 		VK_TRUE,   // shaderClipDistance
80 		VK_TRUE,   // shaderCullDistance
81 		VK_FALSE,  // shaderFloat64
82 		VK_FALSE,  // shaderInt64
83 		VK_FALSE,  // shaderInt16
84 		VK_FALSE,  // shaderResourceResidency
85 		VK_FALSE,  // shaderResourceMinLod
86 		VK_FALSE,  // sparseBinding
87 		VK_FALSE,  // sparseResidencyBuffer
88 		VK_FALSE,  // sparseResidencyImage2D
89 		VK_FALSE,  // sparseResidencyImage3D
90 		VK_FALSE,  // sparseResidency2Samples
91 		VK_FALSE,  // sparseResidency4Samples
92 		VK_FALSE,  // sparseResidency8Samples
93 		VK_FALSE,  // sparseResidency16Samples
94 		VK_FALSE,  // sparseResidencyAliased
95 		VK_TRUE,   // variableMultisampleRate
96 		VK_FALSE,  // inheritedQueries
97 	};
98 
99 	return features;
100 }
101 
102 template<typename T>
getPhysicalDeviceSamplerYcbcrConversionFeatures(T * features)103 static void getPhysicalDeviceSamplerYcbcrConversionFeatures(T *features)
104 {
105 	features->samplerYcbcrConversion = VK_TRUE;
106 }
107 
108 template<typename T>
getPhysicalDevice16BitStorageFeatures(T * features)109 static void getPhysicalDevice16BitStorageFeatures(T *features)
110 {
111 	features->storageBuffer16BitAccess = VK_FALSE;
112 	features->storageInputOutput16 = VK_FALSE;
113 	features->storagePushConstant16 = VK_FALSE;
114 	features->uniformAndStorageBuffer16BitAccess = VK_FALSE;
115 }
116 
117 template<typename T>
getPhysicalDeviceVariablePointersFeatures(T * features)118 static void getPhysicalDeviceVariablePointersFeatures(T *features)
119 {
120 	features->variablePointersStorageBuffer = VK_FALSE;
121 	features->variablePointers = VK_FALSE;
122 }
123 
124 template<typename T>
getPhysicalDevice8BitStorageFeaturesKHR(T * features)125 static void getPhysicalDevice8BitStorageFeaturesKHR(T *features)
126 {
127 	features->storageBuffer8BitAccess = VK_FALSE;
128 	features->uniformAndStorageBuffer8BitAccess = VK_FALSE;
129 	features->storagePushConstant8 = VK_FALSE;
130 }
131 
132 template<typename T>
getPhysicalDeviceMultiviewFeatures(T * features)133 static void getPhysicalDeviceMultiviewFeatures(T *features)
134 {
135 	features->multiview = VK_TRUE;
136 	features->multiviewGeometryShader = VK_FALSE;
137 	features->multiviewTessellationShader = VK_FALSE;
138 }
139 
140 template<typename T>
getPhysicalDeviceProtectedMemoryFeatures(T * features)141 static void getPhysicalDeviceProtectedMemoryFeatures(T *features)
142 {
143 	features->protectedMemory = VK_FALSE;
144 }
145 
146 template<typename T>
getPhysicalDeviceShaderDrawParameterFeatures(T * features)147 static void getPhysicalDeviceShaderDrawParameterFeatures(T *features)
148 {
149 	features->shaderDrawParameters = VK_FALSE;
150 }
151 
152 template<typename T>
getPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR(T * features)153 static void getPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR(T *features)
154 {
155 	features->separateDepthStencilLayouts = VK_TRUE;
156 }
157 
158 template<typename T>
getPhysicalDeviceLineRasterizationFeaturesEXT(T * features)159 static void getPhysicalDeviceLineRasterizationFeaturesEXT(T *features)
160 {
161 	features->rectangularLines = VK_TRUE;
162 	features->bresenhamLines = VK_TRUE;
163 	features->smoothLines = VK_FALSE;
164 	features->stippledRectangularLines = VK_FALSE;
165 	features->stippledBresenhamLines = VK_FALSE;
166 	features->stippledSmoothLines = VK_FALSE;
167 }
168 
169 template<typename T>
getPhysicalDeviceProvokingVertexFeaturesEXT(T * features)170 static void getPhysicalDeviceProvokingVertexFeaturesEXT(T *features)
171 {
172 	features->provokingVertexLast = VK_TRUE;
173 }
174 
175 template<typename T>
getPhysicalDeviceHostQueryResetFeatures(T * features)176 static void getPhysicalDeviceHostQueryResetFeatures(T *features)
177 {
178 	features->hostQueryReset = VK_TRUE;
179 }
180 
181 template<typename T>
getPhysicalDeviceImageRobustnessFeaturesEXT(T * features)182 static void getPhysicalDeviceImageRobustnessFeaturesEXT(T *features)
183 {
184 	features->robustImageAccess = VK_TRUE;
185 }
186 
187 template<typename T>
getPhysicalDeviceShaderDrawParametersFeatures(T * features)188 static void getPhysicalDeviceShaderDrawParametersFeatures(T *features)
189 {
190 	features->shaderDrawParameters = VK_FALSE;
191 }
192 
193 template<typename T>
getPhysicalDeviceVulkan11Features(T * features)194 static void getPhysicalDeviceVulkan11Features(T *features)
195 {
196 	getPhysicalDevice16BitStorageFeatures(features);
197 	getPhysicalDeviceMultiviewFeatures(features);
198 	getPhysicalDeviceVariablePointersFeatures(features);
199 	getPhysicalDeviceProtectedMemoryFeatures(features);
200 	getPhysicalDeviceSamplerYcbcrConversionFeatures(features);
201 	getPhysicalDeviceShaderDrawParametersFeatures(features);
202 }
203 
204 template<typename T>
getPhysicalDeviceImagelessFramebufferFeatures(T * features)205 static void getPhysicalDeviceImagelessFramebufferFeatures(T *features)
206 {
207 	features->imagelessFramebuffer = VK_TRUE;
208 }
209 
210 template<typename T>
getPhysicalDeviceShaderSubgroupExtendedTypesFeatures(T * features)211 static void getPhysicalDeviceShaderSubgroupExtendedTypesFeatures(T *features)
212 {
213 	features->shaderSubgroupExtendedTypes = VK_TRUE;
214 }
215 
216 template<typename T>
getPhysicalDeviceScalarBlockLayoutFeatures(T * features)217 static void getPhysicalDeviceScalarBlockLayoutFeatures(T *features)
218 {
219 	features->scalarBlockLayout = VK_TRUE;
220 }
221 
222 #ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
223 template<typename T>
getPhysicalDeviceDeviceMemoryReportFeaturesEXT(T * features)224 static void getPhysicalDeviceDeviceMemoryReportFeaturesEXT(T *features)
225 {
226 	features->deviceMemoryReport = VK_TRUE;
227 }
228 #endif  // SWIFTSHADER_DEVICE_MEMORY_REPORT
229 
230 template<typename T>
getPhysicalDeviceUniformBufferStandardLayoutFeatures(T * features)231 static void getPhysicalDeviceUniformBufferStandardLayoutFeatures(T *features)
232 {
233 	features->uniformBufferStandardLayout = VK_TRUE;
234 }
235 
236 template<typename T>
getPhysicalDeviceDescriptorIndexingFeatures(T * features)237 static void getPhysicalDeviceDescriptorIndexingFeatures(T *features)
238 {
239 	features->shaderInputAttachmentArrayDynamicIndexing = VK_FALSE;
240 	features->shaderUniformTexelBufferArrayDynamicIndexing = VK_FALSE;
241 	features->shaderStorageTexelBufferArrayDynamicIndexing = VK_FALSE;
242 	features->shaderUniformBufferArrayNonUniformIndexing = VK_FALSE;
243 	features->shaderSampledImageArrayNonUniformIndexing = VK_FALSE;
244 	features->shaderStorageBufferArrayNonUniformIndexing = VK_FALSE;
245 	features->shaderStorageImageArrayNonUniformIndexing = VK_FALSE;
246 	features->shaderInputAttachmentArrayNonUniformIndexing = VK_FALSE;
247 	features->shaderUniformTexelBufferArrayNonUniformIndexing = VK_FALSE;
248 	features->shaderStorageTexelBufferArrayNonUniformIndexing = VK_FALSE;
249 	features->descriptorBindingUniformBufferUpdateAfterBind = VK_FALSE;
250 	features->descriptorBindingSampledImageUpdateAfterBind = VK_FALSE;
251 	features->descriptorBindingStorageImageUpdateAfterBind = VK_FALSE;
252 	features->descriptorBindingStorageBufferUpdateAfterBind = VK_FALSE;
253 	features->descriptorBindingUniformTexelBufferUpdateAfterBind = VK_FALSE;
254 	features->descriptorBindingStorageTexelBufferUpdateAfterBind = VK_FALSE;
255 	features->descriptorBindingUpdateUnusedWhilePending = VK_FALSE;
256 	features->descriptorBindingPartiallyBound = VK_FALSE;
257 	features->descriptorBindingVariableDescriptorCount = VK_FALSE;
258 	features->runtimeDescriptorArray = VK_FALSE;
259 }
260 
261 template<typename T>
getPhysicalDeviceVulkanMemoryModelFeatures(T * features)262 static void getPhysicalDeviceVulkanMemoryModelFeatures(T *features)
263 {
264 	features->vulkanMemoryModel = VK_FALSE;
265 	features->vulkanMemoryModelDeviceScope = VK_FALSE;
266 	features->vulkanMemoryModelAvailabilityVisibilityChains = VK_FALSE;
267 }
268 
269 template<typename T>
getPhysicalDeviceTimelineSemaphoreFeatures(T * features)270 static void getPhysicalDeviceTimelineSemaphoreFeatures(T *features)
271 {
272 	features->timelineSemaphore = VK_TRUE;
273 }
274 
275 template<typename T>
getPhysicalDeviceShaderAtomicInt64Features(T * features)276 static void getPhysicalDeviceShaderAtomicInt64Features(T *features)
277 {
278 	features->shaderBufferInt64Atomics = VK_FALSE;
279 	features->shaderSharedInt64Atomics = VK_FALSE;
280 }
281 
282 template<typename T>
getPhysicalDeviceShaderFloat16Int8Features(T * features)283 static void getPhysicalDeviceShaderFloat16Int8Features(T *features)
284 {
285 	features->shaderFloat16 = VK_FALSE;
286 	features->shaderInt8 = VK_FALSE;
287 }
288 
289 template<typename T>
getPhysicalDeviceBufferDeviceAddressFeatures(T * features)290 static void getPhysicalDeviceBufferDeviceAddressFeatures(T *features)
291 {
292 	features->bufferDeviceAddress = VK_FALSE;
293 	features->bufferDeviceAddressCaptureReplay = VK_FALSE;
294 	features->bufferDeviceAddressMultiDevice = VK_FALSE;
295 }
296 
297 template<typename T>
getPhysicalDeviceVulkan12Features(T * features)298 static void getPhysicalDeviceVulkan12Features(T *features)
299 {
300 	features->samplerMirrorClampToEdge = VK_FALSE;
301 	features->drawIndirectCount = VK_FALSE;
302 	getPhysicalDevice8BitStorageFeaturesKHR(features);
303 	getPhysicalDeviceShaderAtomicInt64Features(features);
304 	getPhysicalDeviceShaderFloat16Int8Features(features);
305 	features->descriptorIndexing = VK_FALSE;
306 	getPhysicalDeviceDescriptorIndexingFeatures(features);
307 	features->samplerFilterMinmax = VK_FALSE;
308 	getPhysicalDeviceScalarBlockLayoutFeatures(features);
309 	getPhysicalDeviceImagelessFramebufferFeatures(features);
310 	getPhysicalDeviceUniformBufferStandardLayoutFeatures(features);
311 	getPhysicalDeviceShaderSubgroupExtendedTypesFeatures(features);
312 	getPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR(features);
313 	getPhysicalDeviceHostQueryResetFeatures(features);
314 	getPhysicalDeviceTimelineSemaphoreFeatures(features);
315 	getPhysicalDeviceBufferDeviceAddressFeatures(features);
316 	getPhysicalDeviceVulkanMemoryModelFeatures(features);
317 	features->shaderOutputViewportIndex = VK_FALSE;
318 	features->shaderOutputLayer = VK_FALSE;
319 	features->subgroupBroadcastDynamicId = VK_TRUE;
320 }
321 
getFeatures2(VkPhysicalDeviceFeatures2 * features) const322 void PhysicalDevice::getFeatures2(VkPhysicalDeviceFeatures2 *features) const
323 {
324 	features->features = getFeatures();
325 	VkBaseOutStructure *curExtension = reinterpret_cast<VkBaseOutStructure *>(features->pNext);
326 	while(curExtension != nullptr)
327 	{
328 		// Need to switch on an integer since Provoking Vertex isn't a part of the Vulkan spec.
329 		switch((int)curExtension->sType)
330 		{
331 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES:
332 				getPhysicalDeviceVulkan11Features(reinterpret_cast<VkPhysicalDeviceVulkan11Features *>(curExtension));
333 				break;
334 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES:
335 				getPhysicalDeviceVulkan12Features(reinterpret_cast<VkPhysicalDeviceVulkan12Features *>(curExtension));
336 				break;
337 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES:
338 				getPhysicalDeviceMultiviewFeatures(reinterpret_cast<VkPhysicalDeviceMultiviewFeatures *>(curExtension));
339 				break;
340 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES:
341 				getPhysicalDeviceVariablePointersFeatures(reinterpret_cast<VkPhysicalDeviceVariablePointersFeatures *>(curExtension));
342 				break;
343 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES:
344 				getPhysicalDevice16BitStorageFeatures(reinterpret_cast<VkPhysicalDevice16BitStorageFeatures *>(curExtension));
345 				break;
346 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES:
347 				getPhysicalDeviceSamplerYcbcrConversionFeatures(reinterpret_cast<VkPhysicalDeviceSamplerYcbcrConversionFeatures *>(curExtension));
348 				break;
349 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES:
350 				getPhysicalDeviceProtectedMemoryFeatures(reinterpret_cast<VkPhysicalDeviceProtectedMemoryFeatures *>(curExtension));
351 				break;
352 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES:
353 				getPhysicalDeviceShaderDrawParameterFeatures(reinterpret_cast<VkPhysicalDeviceShaderDrawParameterFeatures *>(curExtension));
354 				break;
355 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES:
356 				getPhysicalDeviceHostQueryResetFeatures(reinterpret_cast<VkPhysicalDeviceHostQueryResetFeatures *>(curExtension));
357 				break;
358 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT:
359 				getPhysicalDeviceImageRobustnessFeaturesEXT(reinterpret_cast<VkPhysicalDeviceImageRobustnessFeaturesEXT *>(curExtension));
360 				break;
361 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT:
362 				getPhysicalDeviceLineRasterizationFeaturesEXT(reinterpret_cast<VkPhysicalDeviceLineRasterizationFeaturesEXT *>(curExtension));
363 				break;
364 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES:
365 				getPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR(reinterpret_cast<VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures *>(curExtension));
366 				break;
367 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR:
368 				getPhysicalDevice8BitStorageFeaturesKHR(reinterpret_cast<VkPhysicalDevice8BitStorageFeaturesKHR *>(curExtension));
369 				break;
370 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT:
371 				getPhysicalDeviceProvokingVertexFeaturesEXT(reinterpret_cast<VkPhysicalDeviceProvokingVertexFeaturesEXT *>(curExtension));
372 				break;
373 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES:
374 				getPhysicalDeviceImagelessFramebufferFeatures(reinterpret_cast<VkPhysicalDeviceImagelessFramebufferFeatures *>(curExtension));
375 				break;
376 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR:
377 				getPhysicalDeviceShaderSubgroupExtendedTypesFeatures(reinterpret_cast<VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures *>(curExtension));
378 				break;
379 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES:
380 				getPhysicalDeviceScalarBlockLayoutFeatures(reinterpret_cast<VkPhysicalDeviceScalarBlockLayoutFeatures *>(curExtension));
381 				break;
382 #ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
383 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT:
384 				getPhysicalDeviceDeviceMemoryReportFeaturesEXT(reinterpret_cast<VkPhysicalDeviceDeviceMemoryReportFeaturesEXT *>(curExtension));
385 				break;
386 #endif  // SWIFTSHADER_DEVICE_MEMORY_REPORT
387 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES:
388 				getPhysicalDeviceUniformBufferStandardLayoutFeatures(reinterpret_cast<VkPhysicalDeviceUniformBufferStandardLayoutFeatures *>(curExtension));
389 				break;
390 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES:
391 				getPhysicalDeviceVulkanMemoryModelFeatures(reinterpret_cast<VkPhysicalDeviceVulkanMemoryModelFeatures *>(curExtension));
392 				break;
393 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES:
394 				getPhysicalDeviceTimelineSemaphoreFeatures(reinterpret_cast<VkPhysicalDeviceTimelineSemaphoreFeatures *>(curExtension));
395 				break;
396 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES:
397 				getPhysicalDeviceShaderAtomicInt64Features(reinterpret_cast<VkPhysicalDeviceShaderAtomicInt64Features *>(curExtension));
398 				break;
399 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES:
400 				getPhysicalDeviceShaderFloat16Int8Features(reinterpret_cast<VkPhysicalDeviceShaderFloat16Int8Features *>(curExtension));
401 				break;
402 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES:
403 				getPhysicalDeviceBufferDeviceAddressFeatures(reinterpret_cast<VkPhysicalDeviceBufferDeviceAddressFeatures *>(curExtension));
404 				break;
405 			case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES:
406 				getPhysicalDeviceDescriptorIndexingFeatures(reinterpret_cast<VkPhysicalDeviceDescriptorIndexingFeatures *>(curExtension));
407 				break;
408 			default:
409 				LOG_TRAP("curExtension->pNext->sType = %s", vk::Stringify(curExtension->sType).c_str());
410 				break;
411 		}
412 		curExtension = reinterpret_cast<VkBaseOutStructure *>(curExtension->pNext);
413 	}
414 }
415 
getSampleCounts() const416 VkSampleCountFlags PhysicalDevice::getSampleCounts() const
417 {
418 	return VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT;
419 }
420 
getLimits() const421 const VkPhysicalDeviceLimits &PhysicalDevice::getLimits() const
422 {
423 	VkSampleCountFlags sampleCounts = getSampleCounts();
424 
425 	static const VkPhysicalDeviceLimits limits = {
426 		1 << (vk::MAX_IMAGE_LEVELS_1D - 1),               // maxImageDimension1D
427 		1 << (vk::MAX_IMAGE_LEVELS_2D - 1),               // maxImageDimension2D
428 		1 << (vk::MAX_IMAGE_LEVELS_3D - 1),               // maxImageDimension3D
429 		1 << (vk::MAX_IMAGE_LEVELS_CUBE - 1),             // maxImageDimensionCube
430 		vk::MAX_IMAGE_ARRAY_LAYERS,                       // maxImageArrayLayers
431 		65536,                                            // maxTexelBufferElements
432 		16384,                                            // maxUniformBufferRange
433 		(1ul << 27),                                      // maxStorageBufferRange
434 		vk::MAX_PUSH_CONSTANT_SIZE,                       // maxPushConstantsSize
435 		4096,                                             // maxMemoryAllocationCount
436 		4000,                                             // maxSamplerAllocationCount
437 		131072,                                           // bufferImageGranularity
438 		0,                                                // sparseAddressSpaceSize (unsupported)
439 		MAX_BOUND_DESCRIPTOR_SETS,                        // maxBoundDescriptorSets
440 		16,                                               // maxPerStageDescriptorSamplers
441 		14,                                               // maxPerStageDescriptorUniformBuffers
442 		16,                                               // maxPerStageDescriptorStorageBuffers
443 		16,                                               // maxPerStageDescriptorSampledImages
444 		4,                                                // maxPerStageDescriptorStorageImages
445 		4,                                                // maxPerStageDescriptorInputAttachments
446 		128,                                              // maxPerStageResources
447 		96,                                               // maxDescriptorSetSamplers
448 		72,                                               // maxDescriptorSetUniformBuffers
449 		MAX_DESCRIPTOR_SET_UNIFORM_BUFFERS_DYNAMIC,       // maxDescriptorSetUniformBuffersDynamic
450 		24,                                               // maxDescriptorSetStorageBuffers
451 		MAX_DESCRIPTOR_SET_STORAGE_BUFFERS_DYNAMIC,       // maxDescriptorSetStorageBuffersDynamic
452 		96,                                               // maxDescriptorSetSampledImages
453 		24,                                               // maxDescriptorSetStorageImages
454 		4,                                                // maxDescriptorSetInputAttachments
455 		16,                                               // maxVertexInputAttributes
456 		vk::MAX_VERTEX_INPUT_BINDINGS,                    // maxVertexInputBindings
457 		2047,                                             // maxVertexInputAttributeOffset
458 		2048,                                             // maxVertexInputBindingStride
459 		sw::MAX_INTERFACE_COMPONENTS,                     // maxVertexOutputComponents
460 		0,                                                // maxTessellationGenerationLevel (unsupported)
461 		0,                                                // maxTessellationPatchSize (unsupported)
462 		0,                                                // maxTessellationControlPerVertexInputComponents (unsupported)
463 		0,                                                // maxTessellationControlPerVertexOutputComponents (unsupported)
464 		0,                                                // maxTessellationControlPerPatchOutputComponents (unsupported)
465 		0,                                                // maxTessellationControlTotalOutputComponents (unsupported)
466 		0,                                                // maxTessellationEvaluationInputComponents (unsupported)
467 		0,                                                // maxTessellationEvaluationOutputComponents (unsupported)
468 		0,                                                // maxGeometryShaderInvocations (unsupported)
469 		0,                                                // maxGeometryInputComponents (unsupported)
470 		0,                                                // maxGeometryOutputComponents (unsupported)
471 		0,                                                // maxGeometryOutputVertices (unsupported)
472 		0,                                                // maxGeometryTotalOutputComponents (unsupported)
473 		sw::MAX_INTERFACE_COMPONENTS,                     // maxFragmentInputComponents
474 		4,                                                // maxFragmentOutputAttachments
475 		1,                                                // maxFragmentDualSrcAttachments
476 		4,                                                // maxFragmentCombinedOutputResources
477 		16384,                                            // maxComputeSharedMemorySize
478 		{ 65535, 65535, 65535 },                          // maxComputeWorkGroupCount[3]
479 		128,                                              // maxComputeWorkGroupInvocations
480 		{ 128, 128, 64 },                                 // maxComputeWorkGroupSize[3]
481 		vk::SUBPIXEL_PRECISION_BITS,                      // subPixelPrecisionBits
482 		4,                                                // subTexelPrecisionBits
483 		4,                                                // mipmapPrecisionBits
484 		UINT32_MAX,                                       // maxDrawIndexedIndexValue
485 		UINT32_MAX,                                       // maxDrawIndirectCount
486 		vk::MAX_SAMPLER_LOD_BIAS,                         // maxSamplerLodBias
487 		16,                                               // maxSamplerAnisotropy
488 		16,                                               // maxViewports
489 		{ 4096, 4096 },                                   // maxViewportDimensions[2]
490 		{ -8192, 8191 },                                  // viewportBoundsRange[2]
491 		0,                                                // viewportSubPixelBits
492 		64,                                               // minMemoryMapAlignment
493 		vk::MIN_TEXEL_BUFFER_OFFSET_ALIGNMENT,            // minTexelBufferOffsetAlignment
494 		vk::MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT,          // minUniformBufferOffsetAlignment
495 		vk::MIN_STORAGE_BUFFER_OFFSET_ALIGNMENT,          // minStorageBufferOffsetAlignment
496 		sw::MIN_TEXEL_OFFSET,                             // minTexelOffset
497 		sw::MAX_TEXEL_OFFSET,                             // maxTexelOffset
498 		sw::MIN_TEXEL_OFFSET,                             // minTexelGatherOffset
499 		sw::MAX_TEXEL_OFFSET,                             // maxTexelGatherOffset
500 		-0.5,                                             // minInterpolationOffset
501 		0.5,                                              // maxInterpolationOffset
502 		4,                                                // subPixelInterpolationOffsetBits
503 		4096,                                             // maxFramebufferWidth
504 		4096,                                             // maxFramebufferHeight
505 		256,                                              // maxFramebufferLayers
506 		sampleCounts,                                     // framebufferColorSampleCounts
507 		sampleCounts,                                     // framebufferDepthSampleCounts
508 		sampleCounts,                                     // framebufferStencilSampleCounts
509 		sampleCounts,                                     // framebufferNoAttachmentsSampleCounts
510 		4,                                                // maxColorAttachments
511 		sampleCounts,                                     // sampledImageColorSampleCounts
512 		sampleCounts,                                     // sampledImageIntegerSampleCounts
513 		sampleCounts,                                     // sampledImageDepthSampleCounts
514 		sampleCounts,                                     // sampledImageStencilSampleCounts
515 		sampleCounts,                                     // storageImageSampleCounts
516 		1,                                                // maxSampleMaskWords
517 		VK_TRUE,                                          // timestampComputeAndGraphics
518 		1,                                                // timestampPeriod
519 		sw::MAX_CLIP_DISTANCES,                           // maxClipDistances
520 		sw::MAX_CULL_DISTANCES,                           // maxCullDistances
521 		sw::MAX_CLIP_DISTANCES + sw::MAX_CULL_DISTANCES,  // maxCombinedClipAndCullDistances
522 		2,                                                // discreteQueuePriorities
523 		{ 1.0, vk::MAX_POINT_SIZE },                      // pointSizeRange[2]
524 		{ 1.0, 1.0 },                                     // lineWidthRange[2] (unsupported)
525 		0.0,                                              // pointSizeGranularity (unsupported)
526 		0.0,                                              // lineWidthGranularity (unsupported)
527 		VK_TRUE,                                          // strictLines
528 		VK_TRUE,                                          // standardSampleLocations
529 		64,                                               // optimalBufferCopyOffsetAlignment
530 		64,                                               // optimalBufferCopyRowPitchAlignment
531 		256,                                              // nonCoherentAtomSize
532 	};
533 
534 	return limits;
535 }
536 
getProperties() const537 const VkPhysicalDeviceProperties &PhysicalDevice::getProperties() const
538 {
539 	auto getProperties = [&]() -> VkPhysicalDeviceProperties {
540 		VkPhysicalDeviceProperties properties = {
541 			API_VERSION,
542 			DRIVER_VERSION,
543 			VENDOR_ID,
544 			DEVICE_ID,
545 			VK_PHYSICAL_DEVICE_TYPE_CPU,  // deviceType
546 			"",                           // deviceName
547 			SWIFTSHADER_UUID,             // pipelineCacheUUID
548 			getLimits(),                  // limits
549 			{}                            // sparseProperties
550 		};
551 
552 		// Append Reactor JIT backend name and version
553 		snprintf(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE,
554 		         "%s (%s)", SWIFTSHADER_DEVICE_NAME, rr::BackendName().c_str());
555 
556 		return properties;
557 	};
558 
559 	static const VkPhysicalDeviceProperties properties = getProperties();
560 	return properties;
561 }
562 
563 template<typename T>
getIdProperties(T * properties)564 static void getIdProperties(T *properties)
565 {
566 	memset(properties->deviceUUID, 0, VK_UUID_SIZE);
567 	memset(properties->driverUUID, 0, VK_UUID_SIZE);
568 	memset(properties->deviceLUID, 0, VK_LUID_SIZE);
569 
570 	memcpy(properties->deviceUUID, SWIFTSHADER_UUID, VK_UUID_SIZE);
571 	*((uint64_t *)properties->driverUUID) = DRIVER_VERSION;
572 
573 	properties->deviceNodeMask = 0;
574 	properties->deviceLUIDValid = VK_FALSE;
575 }
576 
getProperties(VkPhysicalDeviceIDProperties * properties) const577 void PhysicalDevice::getProperties(VkPhysicalDeviceIDProperties *properties) const
578 {
579 	getIdProperties(properties);
580 }
581 
582 template<typename T>
getMaintenance3Properties(T * properties)583 static void getMaintenance3Properties(T *properties)
584 {
585 	properties->maxMemoryAllocationSize = MAX_MEMORY_ALLOCATION_SIZE;
586 	properties->maxPerSetDescriptors = 1024;
587 }
588 
getProperties(VkPhysicalDeviceMaintenance3Properties * properties) const589 void PhysicalDevice::getProperties(VkPhysicalDeviceMaintenance3Properties *properties) const
590 {
591 	getMaintenance3Properties(properties);
592 }
593 
594 template<typename T>
getMultiviewProperties(T * properties)595 static void getMultiviewProperties(T *properties)
596 {
597 	properties->maxMultiviewViewCount = 6;
598 	properties->maxMultiviewInstanceIndex = 1u << 27;
599 }
600 
getProperties(VkPhysicalDeviceMultiviewProperties * properties) const601 void PhysicalDevice::getProperties(VkPhysicalDeviceMultiviewProperties *properties) const
602 {
603 	getMultiviewProperties(properties);
604 }
605 
606 template<typename T>
getPointClippingProperties(T * properties)607 static void getPointClippingProperties(T *properties)
608 {
609 	properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
610 }
611 
getProperties(VkPhysicalDevicePointClippingProperties * properties) const612 void PhysicalDevice::getProperties(VkPhysicalDevicePointClippingProperties *properties) const
613 {
614 	getPointClippingProperties(properties);
615 }
616 
617 template<typename T>
getProtectedMemoryProperties(T * properties)618 static void getProtectedMemoryProperties(T *properties)
619 {
620 	properties->protectedNoFault = VK_FALSE;
621 }
622 
getProperties(VkPhysicalDeviceProtectedMemoryProperties * properties) const623 void PhysicalDevice::getProperties(VkPhysicalDeviceProtectedMemoryProperties *properties) const
624 {
625 	getProtectedMemoryProperties(properties);
626 }
627 
getProperties(VkPhysicalDeviceSubgroupProperties * properties) const628 void PhysicalDevice::getProperties(VkPhysicalDeviceSubgroupProperties *properties) const
629 {
630 	properties->subgroupSize = sw::SIMD::Width;
631 	properties->supportedStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
632 	properties->supportedOperations =
633 	    VK_SUBGROUP_FEATURE_BASIC_BIT |
634 	    VK_SUBGROUP_FEATURE_VOTE_BIT |
635 	    VK_SUBGROUP_FEATURE_ARITHMETIC_BIT |
636 	    VK_SUBGROUP_FEATURE_BALLOT_BIT |
637 	    VK_SUBGROUP_FEATURE_SHUFFLE_BIT |
638 	    VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT;
639 	properties->quadOperationsInAllStages = VK_FALSE;
640 }
641 
getProperties(VkPhysicalDeviceVulkan11Properties * properties) const642 void PhysicalDevice::getProperties(VkPhysicalDeviceVulkan11Properties *properties) const
643 {
644 	getIdProperties(properties);
645 
646 	// We can't use templated functions for Vulkan11 & subgroup properties. The names of the
647 	// variables in VkPhysicalDeviceSubgroupProperties differ from the names in the Vulkan11
648 	// struct.
649 	VkPhysicalDeviceSubgroupProperties subgroupProperties = {};
650 	getProperties(&subgroupProperties);
651 	properties->subgroupSize = subgroupProperties.subgroupSize;
652 	properties->subgroupSupportedStages = subgroupProperties.supportedStages;
653 	properties->subgroupSupportedOperations = subgroupProperties.supportedOperations;
654 	properties->subgroupQuadOperationsInAllStages = subgroupProperties.quadOperationsInAllStages;
655 
656 	getPointClippingProperties(properties);
657 	getMultiviewProperties(properties);
658 	getProtectedMemoryProperties(properties);
659 	getMaintenance3Properties(properties);
660 }
661 
getProperties(const VkExternalMemoryHandleTypeFlagBits * handleType,VkExternalImageFormatProperties * properties) const662 void PhysicalDevice::getProperties(const VkExternalMemoryHandleTypeFlagBits *handleType, VkExternalImageFormatProperties *properties) const
663 {
664 	VkExternalMemoryProperties *extMemProperties = &properties->externalMemoryProperties;
665 #if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
666 	if(*handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
667 	{
668 		extMemProperties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
669 		extMemProperties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
670 		extMemProperties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
671 		return;
672 	}
673 #endif
674 #if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
675 	if(*handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
676 	{
677 		extMemProperties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
678 		extMemProperties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
679 		extMemProperties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT;
680 		return;
681 	}
682 #endif
683 #if VK_USE_PLATFORM_FUCHSIA
684 	if(handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA)
685 	{
686 		properties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA;
687 		properties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA;
688 		properties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
689 		return;
690 	}
691 #endif
692 	extMemProperties->compatibleHandleTypes = 0;
693 	extMemProperties->exportFromImportedHandleTypes = 0;
694 	extMemProperties->externalMemoryFeatures = 0;
695 }
696 
getProperties(const VkExternalMemoryHandleTypeFlagBits * handleType,VkExternalBufferProperties * properties) const697 void PhysicalDevice::getProperties(const VkExternalMemoryHandleTypeFlagBits *handleType, VkExternalBufferProperties *properties) const
698 {
699 	VkExternalMemoryProperties *extMemProperties = &properties->externalMemoryProperties;
700 #if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
701 	if(*handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
702 	{
703 		extMemProperties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
704 		extMemProperties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
705 		extMemProperties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
706 		return;
707 	}
708 #endif
709 #if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
710 	if(*handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
711 	{
712 		extMemProperties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
713 		extMemProperties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
714 		extMemProperties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
715 		return;
716 	}
717 #endif
718 #if VK_USE_PLATFORM_FUCHSIA
719 	if(handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA)
720 	{
721 		properties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA;
722 		properties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA;
723 		properties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
724 		return;
725 	}
726 #endif
727 	extMemProperties->compatibleHandleTypes = 0;
728 	extMemProperties->exportFromImportedHandleTypes = 0;
729 	extMemProperties->externalMemoryFeatures = 0;
730 }
731 
getProperties(VkSamplerYcbcrConversionImageFormatProperties * properties) const732 void PhysicalDevice::getProperties(VkSamplerYcbcrConversionImageFormatProperties *properties) const
733 {
734 	properties->combinedImageSamplerDescriptorCount = 1;  // Need only one descriptor for YCbCr sampling.
735 }
736 
737 #ifdef __ANDROID__
getProperties(VkPhysicalDevicePresentationPropertiesANDROID * properties) const738 void PhysicalDevice::getProperties(VkPhysicalDevicePresentationPropertiesANDROID *properties) const
739 {
740 	properties->sharedImage = VK_FALSE;
741 }
742 
getProperties(const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,VkAndroidHardwareBufferUsageANDROID * ahbProperties) const743 void PhysicalDevice::getProperties(const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkAndroidHardwareBufferUsageANDROID *ahbProperties) const
744 {
745 	// Maps VkImageUsageFlags to AHB usage flags using this table from the Vulkan spec
746 	// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#memory-external-android-hardware-buffer-usage
747 
748 	// VK_IMAGE_CREATE_PROTECTED_BIT not currently supported.
749 	ASSERT((pImageFormatInfo->flags & VK_IMAGE_CREATE_PROTECTED_BIT) == 0);
750 
751 	// "It must include at least one GPU usage flag (AHARDWAREBUFFER_USAGE_GPU_*), even if none of the corresponding Vulkan usages or flags are requested."
752 	uint64_t ahbUsage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
753 
754 	// Already covered by the default GPU usage flag above.
755 	//
756 	// if ((vkUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) || (vkUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
757 	// {
758 	// 	 ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
759 	// }
760 
761 	if((pImageFormatInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) || (pImageFormatInfo->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT))
762 	{
763 		ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
764 	}
765 
766 	if(pImageFormatInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
767 	{
768 		ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
769 	}
770 
771 	if(pImageFormatInfo->flags & VK_IMAGE_CREATE_PROTECTED_BIT)
772 	{
773 		ahbUsage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
774 	}
775 
776 	ahbProperties->androidHardwareBufferUsage = ahbUsage;
777 }
778 #endif
779 
getProperties(const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo,VkExternalBufferProperties * pExternalBufferProperties) const780 void PhysicalDevice::getProperties(const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo, VkExternalBufferProperties *pExternalBufferProperties) const
781 {
782 	VkExternalMemoryProperties *properties = &pExternalBufferProperties->externalMemoryProperties;
783 
784 #if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD || SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
785 	const VkExternalMemoryHandleTypeFlagBits *handleType = &pExternalBufferInfo->handleType;
786 #endif
787 
788 #if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
789 	if(*handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
790 	{
791 		properties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
792 		properties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
793 		properties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
794 		return;
795 	}
796 #endif
797 #if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
798 	if(*handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
799 	{
800 		properties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
801 		properties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
802 		properties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
803 		return;
804 	}
805 #endif
806 	properties->compatibleHandleTypes = 0;
807 	properties->exportFromImportedHandleTypes = 0;
808 	properties->externalMemoryFeatures = 0;
809 }
810 
getProperties(const VkPhysicalDeviceExternalFenceInfo * pExternalFenceInfo,VkExternalFenceProperties * pExternalFenceProperties) const811 void PhysicalDevice::getProperties(const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo, VkExternalFenceProperties *pExternalFenceProperties) const
812 {
813 	pExternalFenceProperties->compatibleHandleTypes = 0;
814 	pExternalFenceProperties->exportFromImportedHandleTypes = 0;
815 	pExternalFenceProperties->externalFenceFeatures = 0;
816 }
817 
getProperties(const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo,VkExternalSemaphoreProperties * pExternalSemaphoreProperties) const818 void PhysicalDevice::getProperties(const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo, VkExternalSemaphoreProperties *pExternalSemaphoreProperties) const
819 {
820 	for(const auto *nextInfo = reinterpret_cast<const VkBaseInStructure *>(pExternalSemaphoreInfo->pNext);
821 	    nextInfo != nullptr; nextInfo = nextInfo->pNext)
822 	{
823 		switch(nextInfo->sType)
824 		{
825 			case VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO:
826 			{
827 				const auto *tlsInfo = reinterpret_cast<const VkSemaphoreTypeCreateInfo *>(nextInfo);
828 				// Timeline Semaphore does not support external semaphore
829 				if(tlsInfo->semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE)
830 				{
831 					pExternalSemaphoreProperties->compatibleHandleTypes = 0;
832 					pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
833 					pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
834 					return;
835 				}
836 			}
837 			break;
838 			default:
839 				WARN("nextInfo->sType = %s", vk::Stringify(nextInfo->sType).c_str());
840 				break;
841 		}
842 	}
843 
844 #if SWIFTSHADER_EXTERNAL_SEMAPHORE_OPAQUE_FD
845 	if(pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
846 	{
847 		pExternalSemaphoreProperties->compatibleHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
848 		pExternalSemaphoreProperties->exportFromImportedHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
849 		pExternalSemaphoreProperties->externalSemaphoreFeatures = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
850 		return;
851 	}
852 #endif
853 #if VK_USE_PLATFORM_FUCHSIA
854 	if(pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA)
855 	{
856 		pExternalSemaphoreProperties->compatibleHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA;
857 		pExternalSemaphoreProperties->exportFromImportedHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA;
858 		pExternalSemaphoreProperties->externalSemaphoreFeatures = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
859 		return;
860 	}
861 #endif
862 	pExternalSemaphoreProperties->compatibleHandleTypes = 0;
863 	pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
864 	pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
865 }
866 
getProperties(VkPhysicalDeviceExternalMemoryHostPropertiesEXT * properties) const867 void PhysicalDevice::getProperties(VkPhysicalDeviceExternalMemoryHostPropertiesEXT *properties) const
868 {
869 	properties->minImportedHostPointerAlignment = REQUIRED_MEMORY_ALIGNMENT;
870 }
871 
872 template<typename T>
getDriverProperties(T * properties)873 static void getDriverProperties(T *properties)
874 {
875 	properties->driverID = VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR;
876 	strcpy(properties->driverName, "SwiftShader driver");
877 	strcpy(properties->driverInfo, "");
878 	properties->conformanceVersion = { 1, 1, 3, 3 };
879 }
880 
getProperties(VkPhysicalDeviceDriverPropertiesKHR * properties) const881 void PhysicalDevice::getProperties(VkPhysicalDeviceDriverPropertiesKHR *properties) const
882 {
883 	getDriverProperties(properties);
884 }
885 
getProperties(VkPhysicalDeviceLineRasterizationPropertiesEXT * properties) const886 void PhysicalDevice::getProperties(VkPhysicalDeviceLineRasterizationPropertiesEXT *properties) const
887 {
888 	properties->lineSubPixelPrecisionBits = vk::SUBPIXEL_PRECISION_BITS;
889 }
890 
getProperties(VkPhysicalDeviceProvokingVertexPropertiesEXT * properties) const891 void PhysicalDevice::getProperties(VkPhysicalDeviceProvokingVertexPropertiesEXT *properties) const
892 {
893 	properties->provokingVertexModePerPipeline = VK_TRUE;
894 }
895 
896 template<typename T>
getFloatControlsProperties(T * properties)897 static void getFloatControlsProperties(T *properties)
898 {
899 	// The spec states:
900 	// shaderSignedZeroInfNanPreserveFloat32 is a boolean value indicating whether
901 	// sign of a zero, Nans and ±∞ can be preserved in 32-bit floating-point
902 	// computations. It also indicates whether the SignedZeroInfNanPreserve execution
903 	// mode can be used for 32-bit floating-point types.
904 	//
905 	// There are similar clauses for all the shader* bools present here.
906 	//
907 	// It does not state that an implementation must report its default behavior using
908 	// these variables. At this time SwiftShader does not expose any preserve, denormal,
909 	// or rounding controls.
910 	properties->denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE;
911 	properties->roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE;
912 	properties->shaderSignedZeroInfNanPreserveFloat16 = VK_FALSE;
913 	properties->shaderSignedZeroInfNanPreserveFloat32 = VK_FALSE;
914 	properties->shaderSignedZeroInfNanPreserveFloat64 = VK_FALSE;
915 	properties->shaderDenormPreserveFloat16 = VK_FALSE;
916 	properties->shaderDenormPreserveFloat32 = VK_FALSE;
917 	properties->shaderDenormPreserveFloat64 = VK_FALSE;
918 	properties->shaderDenormFlushToZeroFloat16 = VK_FALSE;
919 	properties->shaderDenormFlushToZeroFloat32 = VK_FALSE;
920 	properties->shaderDenormFlushToZeroFloat64 = VK_FALSE;
921 	properties->shaderRoundingModeRTZFloat16 = VK_FALSE;
922 	properties->shaderRoundingModeRTZFloat32 = VK_FALSE;
923 	properties->shaderRoundingModeRTZFloat64 = VK_FALSE;
924 	properties->shaderRoundingModeRTEFloat16 = VK_FALSE;
925 	properties->shaderRoundingModeRTEFloat32 = VK_FALSE;
926 	properties->shaderRoundingModeRTEFloat64 = VK_FALSE;
927 }
928 
getProperties(VkPhysicalDeviceFloatControlsProperties * properties) const929 void PhysicalDevice::getProperties(VkPhysicalDeviceFloatControlsProperties *properties) const
930 {
931 	getFloatControlsProperties(properties);
932 }
933 
934 template<typename T>
getDescriptorIndexingProperties(T * properties)935 static void getDescriptorIndexingProperties(T *properties)
936 {
937 	properties->maxUpdateAfterBindDescriptorsInAllPools = 0;
938 	properties->shaderUniformBufferArrayNonUniformIndexingNative = VK_FALSE;
939 	properties->shaderSampledImageArrayNonUniformIndexingNative = VK_FALSE;
940 	properties->shaderStorageBufferArrayNonUniformIndexingNative = VK_FALSE;
941 	properties->shaderStorageImageArrayNonUniformIndexingNative = VK_FALSE;
942 	properties->shaderInputAttachmentArrayNonUniformIndexingNative = VK_FALSE;
943 	properties->robustBufferAccessUpdateAfterBind = VK_FALSE;
944 	properties->quadDivergentImplicitLod = VK_FALSE;
945 	properties->maxPerStageDescriptorUpdateAfterBindSamplers = 0;
946 	properties->maxPerStageDescriptorUpdateAfterBindUniformBuffers = 0;
947 	properties->maxPerStageDescriptorUpdateAfterBindStorageBuffers = 0;
948 	properties->maxPerStageDescriptorUpdateAfterBindSampledImages = 0;
949 	properties->maxPerStageDescriptorUpdateAfterBindStorageImages = 0;
950 	properties->maxPerStageDescriptorUpdateAfterBindInputAttachments = 0;
951 	properties->maxPerStageUpdateAfterBindResources = 0;
952 	properties->maxDescriptorSetUpdateAfterBindSamplers = 0;
953 	properties->maxDescriptorSetUpdateAfterBindUniformBuffers = 0;
954 	properties->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = 0;
955 	properties->maxDescriptorSetUpdateAfterBindStorageBuffers = 0;
956 	properties->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = 0;
957 	properties->maxDescriptorSetUpdateAfterBindSampledImages = 0;
958 	properties->maxDescriptorSetUpdateAfterBindStorageImages = 0;
959 	properties->maxDescriptorSetUpdateAfterBindInputAttachments = 0;
960 }
961 
getProperties(VkPhysicalDeviceDescriptorIndexingProperties * properties) const962 void PhysicalDevice::getProperties(VkPhysicalDeviceDescriptorIndexingProperties *properties) const
963 {
964 	getDescriptorIndexingProperties(properties);
965 }
966 
967 template<typename T>
getDepthStencilResolveProperties(T * properties)968 static void getDepthStencilResolveProperties(T *properties)
969 {
970 	properties->supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT | VK_RESOLVE_MODE_NONE;
971 	properties->supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT | VK_RESOLVE_MODE_NONE;
972 	properties->independentResolveNone = VK_TRUE;
973 	properties->independentResolve = VK_TRUE;
974 }
975 
getProperties(VkPhysicalDeviceDepthStencilResolveProperties * properties) const976 void PhysicalDevice::getProperties(VkPhysicalDeviceDepthStencilResolveProperties *properties) const
977 {
978 	getDepthStencilResolveProperties(properties);
979 }
980 
981 template<typename T>
getSamplerFilterMinmaxProperties(T * properties)982 static void getSamplerFilterMinmaxProperties(T *properties)
983 {
984 	properties->filterMinmaxSingleComponentFormats = VK_FALSE;
985 	properties->filterMinmaxImageComponentMapping = VK_FALSE;
986 }
987 
getProperties(VkPhysicalDeviceSamplerFilterMinmaxProperties * properties) const988 void PhysicalDevice::getProperties(VkPhysicalDeviceSamplerFilterMinmaxProperties *properties) const
989 {
990 	getSamplerFilterMinmaxProperties(properties);
991 }
992 
993 template<typename T>
getTimelineSemaphoreProperties(T * properties)994 static void getTimelineSemaphoreProperties(T *properties)
995 {
996 	// Our implementation of Timeline Semaphores allows the timeline to advance to any value from any value.
997 	properties->maxTimelineSemaphoreValueDifference = (uint64_t)-1;
998 }
999 
getProperties(VkPhysicalDeviceTimelineSemaphoreProperties * properties) const1000 void PhysicalDevice::getProperties(VkPhysicalDeviceTimelineSemaphoreProperties *properties) const
1001 {
1002 	getTimelineSemaphoreProperties(properties);
1003 }
1004 
getProperties(VkPhysicalDeviceVulkan12Properties * properties) const1005 void PhysicalDevice::getProperties(VkPhysicalDeviceVulkan12Properties *properties) const
1006 {
1007 	getDriverProperties(properties);
1008 	getFloatControlsProperties(properties);
1009 	getDescriptorIndexingProperties(properties);
1010 	getDepthStencilResolveProperties(properties);
1011 	getSamplerFilterMinmaxProperties(properties);
1012 	getTimelineSemaphoreProperties(properties);
1013 	properties->framebufferIntegerColorSampleCounts = VK_SAMPLE_COUNT_1_BIT;
1014 }
1015 
hasFeatures(const VkPhysicalDeviceFeatures & requestedFeatures) const1016 bool PhysicalDevice::hasFeatures(const VkPhysicalDeviceFeatures &requestedFeatures) const
1017 {
1018 	const VkPhysicalDeviceFeatures &supportedFeatures = getFeatures();
1019 	const VkBool32 *supportedFeature = reinterpret_cast<const VkBool32 *>(&supportedFeatures);
1020 	const VkBool32 *requestedFeature = reinterpret_cast<const VkBool32 *>(&requestedFeatures);
1021 	constexpr auto featureCount = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
1022 
1023 	for(unsigned int i = 0; i < featureCount; i++)
1024 	{
1025 		if((requestedFeature[i] != VK_FALSE) && (supportedFeature[i] == VK_FALSE))
1026 		{
1027 			return false;
1028 		}
1029 	}
1030 
1031 	return true;
1032 }
1033 
GetFormatProperties(Format format,VkFormatProperties * pFormatProperties)1034 void PhysicalDevice::GetFormatProperties(Format format, VkFormatProperties *pFormatProperties)
1035 {
1036 	pFormatProperties->linearTilingFeatures = 0;   // Unsupported format
1037 	pFormatProperties->optimalTilingFeatures = 0;  // Unsupported format
1038 	pFormatProperties->bufferFeatures = 0;         // Unsupported format
1039 
1040 	switch(format)
1041 	{
1042 		// Formats which can be sampled *and* filtered
1043 		case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
1044 		case VK_FORMAT_R5G6B5_UNORM_PACK16:
1045 		case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
1046 		case VK_FORMAT_R8_UNORM:
1047 		case VK_FORMAT_R8_SRGB:
1048 		case VK_FORMAT_R8_SNORM:
1049 		case VK_FORMAT_R8G8_UNORM:
1050 		case VK_FORMAT_R8G8_SRGB:
1051 		case VK_FORMAT_R8G8_SNORM:
1052 		case VK_FORMAT_R8G8B8A8_UNORM:
1053 		case VK_FORMAT_R8G8B8A8_SNORM:
1054 		case VK_FORMAT_R8G8B8A8_SRGB:
1055 		case VK_FORMAT_B8G8R8A8_UNORM:
1056 		case VK_FORMAT_B8G8R8A8_SRGB:
1057 		case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
1058 		case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
1059 		case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
1060 		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1061 		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
1062 		case VK_FORMAT_R16_UNORM:
1063 		case VK_FORMAT_R16_SNORM:
1064 		case VK_FORMAT_R16_SFLOAT:
1065 		case VK_FORMAT_R16G16_UNORM:
1066 		case VK_FORMAT_R16G16_SNORM:
1067 		case VK_FORMAT_R16G16_SFLOAT:
1068 		case VK_FORMAT_R16G16B16A16_UNORM:
1069 		case VK_FORMAT_R16G16B16A16_SNORM:
1070 		case VK_FORMAT_R16G16B16A16_SFLOAT:
1071 		case VK_FORMAT_R32_SFLOAT:
1072 		case VK_FORMAT_R32G32_SFLOAT:
1073 		case VK_FORMAT_R32G32B32A32_SFLOAT:
1074 		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
1075 		case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
1076 		case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
1077 		case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
1078 		case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
1079 		case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
1080 		case VK_FORMAT_BC2_UNORM_BLOCK:
1081 		case VK_FORMAT_BC2_SRGB_BLOCK:
1082 		case VK_FORMAT_BC3_UNORM_BLOCK:
1083 		case VK_FORMAT_BC3_SRGB_BLOCK:
1084 		case VK_FORMAT_BC4_UNORM_BLOCK:
1085 		case VK_FORMAT_BC4_SNORM_BLOCK:
1086 		case VK_FORMAT_BC5_UNORM_BLOCK:
1087 		case VK_FORMAT_BC5_SNORM_BLOCK:
1088 		case VK_FORMAT_BC6H_UFLOAT_BLOCK:
1089 		case VK_FORMAT_BC6H_SFLOAT_BLOCK:
1090 		case VK_FORMAT_BC7_UNORM_BLOCK:
1091 		case VK_FORMAT_BC7_SRGB_BLOCK:
1092 		case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
1093 		case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
1094 		case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
1095 		case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
1096 		case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
1097 		case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
1098 		case VK_FORMAT_EAC_R11_UNORM_BLOCK:
1099 		case VK_FORMAT_EAC_R11_SNORM_BLOCK:
1100 		case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
1101 		case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
1102 #ifdef SWIFTSHADER_ENABLE_ASTC
1103 		case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
1104 		case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
1105 		case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
1106 		case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
1107 		case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
1108 		case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
1109 		case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
1110 		case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
1111 		case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
1112 		case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
1113 		case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
1114 		case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
1115 		case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
1116 		case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
1117 		case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
1118 		case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
1119 		case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
1120 		case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
1121 		case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
1122 		case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
1123 		case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
1124 		case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
1125 		case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
1126 		case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
1127 		case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
1128 		case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
1129 		case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
1130 		case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
1131 #endif
1132 		case VK_FORMAT_D16_UNORM:
1133 		case VK_FORMAT_D32_SFLOAT:
1134 		case VK_FORMAT_D32_SFLOAT_S8_UINT:
1135 			pFormatProperties->optimalTilingFeatures |=
1136 			    VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
1137 			// [[fallthrough]]
1138 
1139 		// Formats which can be sampled, but don't support filtering
1140 		case VK_FORMAT_R8_UINT:
1141 		case VK_FORMAT_R8_SINT:
1142 		case VK_FORMAT_R8G8_UINT:
1143 		case VK_FORMAT_R8G8_SINT:
1144 		case VK_FORMAT_R8G8B8A8_UINT:
1145 		case VK_FORMAT_R8G8B8A8_SINT:
1146 		case VK_FORMAT_A8B8G8R8_UINT_PACK32:
1147 		case VK_FORMAT_A8B8G8R8_SINT_PACK32:
1148 		case VK_FORMAT_A2B10G10R10_UINT_PACK32:
1149 		case VK_FORMAT_A2R10G10B10_UINT_PACK32:
1150 		case VK_FORMAT_R16_UINT:
1151 		case VK_FORMAT_R16_SINT:
1152 		case VK_FORMAT_R16G16_UINT:
1153 		case VK_FORMAT_R16G16_SINT:
1154 		case VK_FORMAT_R16G16B16A16_UINT:
1155 		case VK_FORMAT_R16G16B16A16_SINT:
1156 		case VK_FORMAT_R32_UINT:
1157 		case VK_FORMAT_R32_SINT:
1158 		case VK_FORMAT_R32G32_UINT:
1159 		case VK_FORMAT_R32G32_SINT:
1160 		case VK_FORMAT_R32G32B32A32_UINT:
1161 		case VK_FORMAT_R32G32B32A32_SINT:
1162 		case VK_FORMAT_S8_UINT:
1163 			pFormatProperties->optimalTilingFeatures |=
1164 			    VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
1165 			    VK_FORMAT_FEATURE_BLIT_SRC_BIT |
1166 			    VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
1167 			    VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1168 			break;
1169 
1170 		// YCbCr formats:
1171 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
1172 		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
1173 			pFormatProperties->optimalTilingFeatures |=
1174 			    VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
1175 			    VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
1176 			    VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
1177 			    VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
1178 			    VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT;
1179 			break;
1180 		default:
1181 			break;
1182 	}
1183 
1184 	switch(format)
1185 	{
1186 		case VK_FORMAT_R32_UINT:
1187 		case VK_FORMAT_R32_SINT:
1188 			pFormatProperties->optimalTilingFeatures |=
1189 			    VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
1190 			pFormatProperties->bufferFeatures |=
1191 			    VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
1192 			// [[fallthrough]]
1193 		case VK_FORMAT_R8G8B8A8_UNORM:
1194 		case VK_FORMAT_R8G8B8A8_SNORM:
1195 		case VK_FORMAT_R8G8B8A8_UINT:
1196 		case VK_FORMAT_R8G8B8A8_SINT:
1197 		case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
1198 		case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
1199 		case VK_FORMAT_A8B8G8R8_UINT_PACK32:
1200 		case VK_FORMAT_A8B8G8R8_SINT_PACK32:
1201 		case VK_FORMAT_R16G16B16A16_UINT:
1202 		case VK_FORMAT_R16G16B16A16_SINT:
1203 		case VK_FORMAT_R16G16B16A16_SFLOAT:
1204 		case VK_FORMAT_R32_SFLOAT:
1205 		case VK_FORMAT_R32G32_UINT:
1206 		case VK_FORMAT_R32G32_SINT:
1207 		case VK_FORMAT_R32G32_SFLOAT:
1208 		case VK_FORMAT_R32G32B32A32_UINT:
1209 		case VK_FORMAT_R32G32B32A32_SINT:
1210 		case VK_FORMAT_R32G32B32A32_SFLOAT:
1211 		// shaderStorageImageExtendedFormats
1212 		case VK_FORMAT_R16G16_SFLOAT:
1213 		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
1214 		case VK_FORMAT_R16_SFLOAT:
1215 		case VK_FORMAT_R16G16B16A16_UNORM:
1216 		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1217 		case VK_FORMAT_R16G16_UNORM:
1218 		case VK_FORMAT_R8G8_UNORM:
1219 		case VK_FORMAT_R16_UNORM:
1220 		case VK_FORMAT_R8_UNORM:
1221 		case VK_FORMAT_R16G16B16A16_SNORM:
1222 		case VK_FORMAT_R16G16_SNORM:
1223 		case VK_FORMAT_R8G8_SNORM:
1224 		case VK_FORMAT_R16_SNORM:
1225 		case VK_FORMAT_R8_SNORM:
1226 		case VK_FORMAT_R16G16_SINT:
1227 		case VK_FORMAT_R8G8_SINT:
1228 		case VK_FORMAT_R16_SINT:
1229 		case VK_FORMAT_R8_SINT:
1230 		case VK_FORMAT_A2B10G10R10_UINT_PACK32:
1231 		case VK_FORMAT_R16G16_UINT:
1232 		case VK_FORMAT_R8G8_UINT:
1233 		case VK_FORMAT_R16_UINT:
1234 		case VK_FORMAT_R8_UINT:
1235 			pFormatProperties->optimalTilingFeatures |=
1236 			    VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1237 			// [[fallthrough]]
1238 			pFormatProperties->bufferFeatures |=
1239 			    VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
1240 			break;
1241 		default:
1242 			break;
1243 	}
1244 
1245 	switch(format)
1246 	{
1247 		case VK_FORMAT_R5G6B5_UNORM_PACK16:
1248 		case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
1249 		case VK_FORMAT_R8_UNORM:
1250 		case VK_FORMAT_R8G8_UNORM:
1251 		case VK_FORMAT_R8G8B8A8_UNORM:
1252 		case VK_FORMAT_R8G8B8A8_SRGB:
1253 		case VK_FORMAT_B8G8R8A8_UNORM:
1254 		case VK_FORMAT_B8G8R8A8_SRGB:
1255 		case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
1256 		case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
1257 		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1258 		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
1259 		case VK_FORMAT_R16_SFLOAT:
1260 		case VK_FORMAT_R16G16_SFLOAT:
1261 		case VK_FORMAT_R16G16B16A16_SFLOAT:
1262 		case VK_FORMAT_R32_SFLOAT:
1263 		case VK_FORMAT_R32G32_SFLOAT:
1264 		case VK_FORMAT_R32G32B32A32_SFLOAT:
1265 		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
1266 		case VK_FORMAT_R8_UINT:
1267 		case VK_FORMAT_R8_SINT:
1268 		case VK_FORMAT_R8G8_UINT:
1269 		case VK_FORMAT_R8G8_SINT:
1270 		case VK_FORMAT_R8G8B8A8_UINT:
1271 		case VK_FORMAT_R8G8B8A8_SINT:
1272 		case VK_FORMAT_A8B8G8R8_UINT_PACK32:
1273 		case VK_FORMAT_A8B8G8R8_SINT_PACK32:
1274 		case VK_FORMAT_A2B10G10R10_UINT_PACK32:
1275 		case VK_FORMAT_A2R10G10B10_UINT_PACK32:
1276 		case VK_FORMAT_R16_UINT:
1277 		case VK_FORMAT_R16_SINT:
1278 		case VK_FORMAT_R16G16_UINT:
1279 		case VK_FORMAT_R16G16_SINT:
1280 		case VK_FORMAT_R16G16B16A16_UINT:
1281 		case VK_FORMAT_R16G16B16A16_SINT:
1282 		case VK_FORMAT_R32_UINT:
1283 		case VK_FORMAT_R32_SINT:
1284 		case VK_FORMAT_R32G32_UINT:
1285 		case VK_FORMAT_R32G32_SINT:
1286 		case VK_FORMAT_R32G32B32A32_UINT:
1287 		case VK_FORMAT_R32G32B32A32_SINT:
1288 			pFormatProperties->optimalTilingFeatures |=
1289 			    VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
1290 			    VK_FORMAT_FEATURE_BLIT_DST_BIT;
1291 			break;
1292 		case VK_FORMAT_S8_UINT:
1293 		case VK_FORMAT_D16_UNORM:
1294 		case VK_FORMAT_D32_SFLOAT:          // Note: either VK_FORMAT_D32_SFLOAT or VK_FORMAT_X8_D24_UNORM_PACK32 must be supported
1295 		case VK_FORMAT_D32_SFLOAT_S8_UINT:  // Note: either VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT must be supported
1296 			pFormatProperties->optimalTilingFeatures |=
1297 			    VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
1298 			break;
1299 		default:
1300 			break;
1301 	}
1302 
1303 	if(format.supportsColorAttachmentBlend())
1304 	{
1305 		pFormatProperties->optimalTilingFeatures |=
1306 		    VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
1307 	}
1308 
1309 	switch(format)
1310 	{
1311 		case VK_FORMAT_R8_UNORM:
1312 		case VK_FORMAT_R8_SNORM:
1313 		case VK_FORMAT_R8_UINT:
1314 		case VK_FORMAT_R8_SINT:
1315 		case VK_FORMAT_R8G8_UNORM:
1316 		case VK_FORMAT_R8G8_SNORM:
1317 		case VK_FORMAT_R8G8_UINT:
1318 		case VK_FORMAT_R8G8_SINT:
1319 		case VK_FORMAT_R8G8B8A8_UNORM:
1320 		case VK_FORMAT_R8G8B8A8_SNORM:
1321 		case VK_FORMAT_R8G8B8A8_UINT:
1322 		case VK_FORMAT_R8G8B8A8_SINT:
1323 		case VK_FORMAT_B8G8R8A8_UNORM:
1324 		case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
1325 		case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
1326 		case VK_FORMAT_A8B8G8R8_UINT_PACK32:
1327 		case VK_FORMAT_A8B8G8R8_SINT_PACK32:
1328 		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
1329 		case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
1330 		case VK_FORMAT_A2R10G10B10_UINT_PACK32:
1331 		case VK_FORMAT_A2R10G10B10_SINT_PACK32:
1332 		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1333 		case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
1334 		case VK_FORMAT_A2B10G10R10_UINT_PACK32:
1335 		case VK_FORMAT_A2B10G10R10_SINT_PACK32:
1336 		case VK_FORMAT_R16_UNORM:
1337 		case VK_FORMAT_R16_SNORM:
1338 		case VK_FORMAT_R16_UINT:
1339 		case VK_FORMAT_R16_SINT:
1340 		case VK_FORMAT_R16_SFLOAT:
1341 		case VK_FORMAT_R16G16_UNORM:
1342 		case VK_FORMAT_R16G16_SNORM:
1343 		case VK_FORMAT_R16G16_UINT:
1344 		case VK_FORMAT_R16G16_SINT:
1345 		case VK_FORMAT_R16G16_SFLOAT:
1346 		case VK_FORMAT_R16G16B16A16_UNORM:
1347 		case VK_FORMAT_R16G16B16A16_SNORM:
1348 		case VK_FORMAT_R16G16B16A16_UINT:
1349 		case VK_FORMAT_R16G16B16A16_SINT:
1350 		case VK_FORMAT_R16G16B16A16_SFLOAT:
1351 		case VK_FORMAT_R32_UINT:
1352 		case VK_FORMAT_R32_SINT:
1353 		case VK_FORMAT_R32_SFLOAT:
1354 		case VK_FORMAT_R32G32_UINT:
1355 		case VK_FORMAT_R32G32_SINT:
1356 		case VK_FORMAT_R32G32_SFLOAT:
1357 		case VK_FORMAT_R32G32B32_UINT:
1358 		case VK_FORMAT_R32G32B32_SINT:
1359 		case VK_FORMAT_R32G32B32_SFLOAT:
1360 		case VK_FORMAT_R32G32B32A32_UINT:
1361 		case VK_FORMAT_R32G32B32A32_SINT:
1362 		case VK_FORMAT_R32G32B32A32_SFLOAT:
1363 			pFormatProperties->bufferFeatures |=
1364 			    VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
1365 			break;
1366 		default:
1367 			break;
1368 	}
1369 
1370 	switch(format)
1371 	{
1372 		// Vulkan 1.1 mandatory
1373 		case VK_FORMAT_R8_UNORM:
1374 		case VK_FORMAT_R8_SNORM:
1375 		case VK_FORMAT_R8_UINT:
1376 		case VK_FORMAT_R8_SINT:
1377 		case VK_FORMAT_R8G8_UNORM:
1378 		case VK_FORMAT_R8G8_SNORM:
1379 		case VK_FORMAT_R8G8_UINT:
1380 		case VK_FORMAT_R8G8_SINT:
1381 		case VK_FORMAT_R8G8B8A8_UNORM:
1382 		case VK_FORMAT_R8G8B8A8_SNORM:
1383 		case VK_FORMAT_R8G8B8A8_UINT:
1384 		case VK_FORMAT_R8G8B8A8_SINT:
1385 		case VK_FORMAT_B8G8R8A8_UNORM:
1386 		case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
1387 		case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
1388 		case VK_FORMAT_A8B8G8R8_UINT_PACK32:
1389 		case VK_FORMAT_A8B8G8R8_SINT_PACK32:
1390 		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1391 		case VK_FORMAT_A2B10G10R10_UINT_PACK32:
1392 		case VK_FORMAT_R16_UINT:
1393 		case VK_FORMAT_R16_SINT:
1394 		case VK_FORMAT_R16_SFLOAT:
1395 		case VK_FORMAT_R16G16_UINT:
1396 		case VK_FORMAT_R16G16_SINT:
1397 		case VK_FORMAT_R16G16_SFLOAT:
1398 		case VK_FORMAT_R16G16B16A16_UINT:
1399 		case VK_FORMAT_R16G16B16A16_SINT:
1400 		case VK_FORMAT_R16G16B16A16_SFLOAT:
1401 		case VK_FORMAT_R32_UINT:
1402 		case VK_FORMAT_R32_SINT:
1403 		case VK_FORMAT_R32_SFLOAT:
1404 		case VK_FORMAT_R32G32_UINT:
1405 		case VK_FORMAT_R32G32_SINT:
1406 		case VK_FORMAT_R32G32_SFLOAT:
1407 		case VK_FORMAT_R32G32B32A32_UINT:
1408 		case VK_FORMAT_R32G32B32A32_SINT:
1409 		case VK_FORMAT_R32G32B32A32_SFLOAT:
1410 		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
1411 		// Optional
1412 		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
1413 		case VK_FORMAT_A2R10G10B10_UINT_PACK32:
1414 			pFormatProperties->bufferFeatures |=
1415 			    VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;
1416 			break;
1417 		default:
1418 			break;
1419 	}
1420 
1421 	if(pFormatProperties->optimalTilingFeatures)
1422 	{
1423 		pFormatProperties->linearTilingFeatures = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
1424 		                                          VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1425 
1426 		if(!format.isCompressed())
1427 		{
1428 			if(pFormatProperties->optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)
1429 			{
1430 				pFormatProperties->linearTilingFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
1431 			}
1432 			if(pFormatProperties->optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)
1433 			{
1434 				pFormatProperties->linearTilingFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
1435 			}
1436 		}
1437 	}
1438 }
1439 
getImageFormatProperties(Format format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags,VkImageFormatProperties * pImageFormatProperties) const1440 void PhysicalDevice::getImageFormatProperties(Format format, VkImageType type, VkImageTiling tiling,
1441                                               VkImageUsageFlags usage, VkImageCreateFlags flags,
1442                                               VkImageFormatProperties *pImageFormatProperties) const
1443 {
1444 	pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
1445 	pImageFormatProperties->maxArrayLayers = vk::MAX_IMAGE_ARRAY_LAYERS;
1446 	pImageFormatProperties->maxExtent.depth = 1;
1447 
1448 	switch(type)
1449 	{
1450 		case VK_IMAGE_TYPE_1D:
1451 			pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_1D;
1452 			pImageFormatProperties->maxExtent.width = 1 << (vk::MAX_IMAGE_LEVELS_1D - 1);
1453 			pImageFormatProperties->maxExtent.height = 1;
1454 			break;
1455 		case VK_IMAGE_TYPE_2D:
1456 			if(flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
1457 			{
1458 				pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_CUBE;
1459 				pImageFormatProperties->maxExtent.width = 1 << (vk::MAX_IMAGE_LEVELS_CUBE - 1);
1460 				pImageFormatProperties->maxExtent.height = 1 << (vk::MAX_IMAGE_LEVELS_CUBE - 1);
1461 			}
1462 			else
1463 			{
1464 				pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_2D;
1465 				pImageFormatProperties->maxExtent.width = 1 << (vk::MAX_IMAGE_LEVELS_2D - 1);
1466 				pImageFormatProperties->maxExtent.height = 1 << (vk::MAX_IMAGE_LEVELS_2D - 1);
1467 
1468 				VkFormatProperties props;
1469 				GetFormatProperties(format, &props);
1470 				auto features = tiling == VK_IMAGE_TILING_LINEAR ? props.linearTilingFeatures : props.optimalTilingFeatures;
1471 				if(features & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
1472 				{
1473 					// Only renderable formats make sense for multisample
1474 					pImageFormatProperties->sampleCounts = getSampleCounts();
1475 				}
1476 			}
1477 			break;
1478 		case VK_IMAGE_TYPE_3D:
1479 			pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_3D;
1480 			pImageFormatProperties->maxExtent.width = 1 << (vk::MAX_IMAGE_LEVELS_3D - 1);
1481 			pImageFormatProperties->maxExtent.height = 1 << (vk::MAX_IMAGE_LEVELS_3D - 1);
1482 			pImageFormatProperties->maxExtent.depth = 1 << (vk::MAX_IMAGE_LEVELS_3D - 1);
1483 			pImageFormatProperties->maxArrayLayers = 1;  // no 3D + layers
1484 			break;
1485 		default:
1486 			UNREACHABLE("VkImageType: %d", int(type));
1487 			break;
1488 	}
1489 
1490 	pImageFormatProperties->maxResourceSize = 1u << 31;  // Minimum value for maxResourceSize
1491 
1492 	// "Images created with tiling equal to VK_IMAGE_TILING_LINEAR have further restrictions on their limits and capabilities
1493 	//  compared to images created with tiling equal to VK_IMAGE_TILING_OPTIMAL."
1494 	if(tiling == VK_IMAGE_TILING_LINEAR)
1495 	{
1496 		pImageFormatProperties->maxMipLevels = 1;
1497 		pImageFormatProperties->maxArrayLayers = 1;
1498 		pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
1499 	}
1500 
1501 	// "Images created with a format from one of those listed in Formats requiring sampler Y'CbCr conversion for VK_IMAGE_ASPECT_COLOR_BIT image views
1502 	//  have further restrictions on their limits and capabilities compared to images created with other formats."
1503 	if(format.isYcbcrFormat())
1504 	{
1505 		pImageFormatProperties->maxMipLevels = 1;  // TODO(b/151263485): This is relied on by the sampler to disable mipmapping for Y'CbCr image sampling.
1506 		pImageFormatProperties->maxArrayLayers = 1;
1507 		pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
1508 	}
1509 }
1510 
getQueueFamilyPropertyCount() const1511 uint32_t PhysicalDevice::getQueueFamilyPropertyCount() const
1512 {
1513 	return 1;
1514 }
1515 
getQueueFamilyProperties() const1516 VkQueueFamilyProperties PhysicalDevice::getQueueFamilyProperties() const
1517 {
1518 	VkQueueFamilyProperties properties = {};
1519 	properties.minImageTransferGranularity.width = 1;
1520 	properties.minImageTransferGranularity.height = 1;
1521 	properties.minImageTransferGranularity.depth = 1;
1522 	properties.queueCount = 1;
1523 	properties.queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
1524 	properties.timestampValidBits = 64;
1525 
1526 	return properties;
1527 }
1528 
getQueueFamilyProperties(uint32_t pQueueFamilyPropertyCount,VkQueueFamilyProperties * pQueueFamilyProperties) const1529 void PhysicalDevice::getQueueFamilyProperties(uint32_t pQueueFamilyPropertyCount,
1530                                               VkQueueFamilyProperties *pQueueFamilyProperties) const
1531 {
1532 	for(uint32_t i = 0; i < pQueueFamilyPropertyCount; i++)
1533 	{
1534 		pQueueFamilyProperties[i] = getQueueFamilyProperties();
1535 	}
1536 }
1537 
getQueueFamilyProperties(uint32_t pQueueFamilyPropertyCount,VkQueueFamilyProperties2 * pQueueFamilyProperties) const1538 void PhysicalDevice::getQueueFamilyProperties(uint32_t pQueueFamilyPropertyCount,
1539                                               VkQueueFamilyProperties2 *pQueueFamilyProperties) const
1540 {
1541 	for(uint32_t i = 0; i < pQueueFamilyPropertyCount; i++)
1542 	{
1543 		pQueueFamilyProperties[i].queueFamilyProperties = getQueueFamilyProperties();
1544 	}
1545 }
1546 
GetMemoryProperties()1547 const VkPhysicalDeviceMemoryProperties &PhysicalDevice::GetMemoryProperties()
1548 {
1549 	static const VkPhysicalDeviceMemoryProperties properties{
1550 		1,  // memoryTypeCount
1551 		{
1552 		    // vk::MEMORY_TYPE_GENERIC_BIT
1553 		    {
1554 		        (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
1555 		         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
1556 		         VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
1557 		         VK_MEMORY_PROPERTY_HOST_CACHED_BIT),  // propertyFlags
1558 		        0                                      // heapIndex
1559 		    },
1560 		},
1561 		1,  // memoryHeapCount
1562 		{
1563 		    {
1564 		        1ull << 31,                      // size, FIXME(sugoi): This should be configurable based on available RAM
1565 		        VK_MEMORY_HEAP_DEVICE_LOCAL_BIT  // flags
1566 		    },
1567 		}
1568 	};
1569 
1570 	return properties;
1571 }
1572 
1573 }  // namespace vk
1574