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.h"
18#include "Pipeline/SpirvShader.hpp" // sw::SIMD::Width
19
20#include <limits>
21#include <cstring>
22
23namespace vk
24{
25
26static void setExternalMemoryProperties(VkExternalMemoryHandleTypeFlagBits handleType, VkExternalMemoryProperties* properties)
27{
28#if SWIFTSHADER_EXTERNAL_MEMORY_LINUX_MEMFD
29 if (handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
30 {
31 properties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
32 properties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
33 properties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
34 return;
35 }
36#endif
37 properties->compatibleHandleTypes = 0;
38 properties->exportFromImportedHandleTypes = 0;
39 properties->externalMemoryFeatures = 0;
40}
41
42PhysicalDevice::PhysicalDevice(const void*, void* mem)
43{
44}
45
46const VkPhysicalDeviceFeatures& PhysicalDevice::getFeatures() const
47{
48 static const VkPhysicalDeviceFeatures features
49 {
50 VK_TRUE, // robustBufferAccess
51 VK_FALSE, // fullDrawIndexUint32
52 VK_FALSE, // imageCubeArray
53 VK_TRUE, // independentBlend
54 VK_FALSE, // geometryShader
55 VK_FALSE, // tessellationShader
56 VK_FALSE, // sampleRateShading
57 VK_FALSE, // dualSrcBlend
58 VK_FALSE, // logicOp
59 VK_TRUE, // multiDrawIndirect
60 VK_TRUE, // drawIndirectFirstInstance
61 VK_FALSE, // depthClamp
62 VK_FALSE, // depthBiasClamp
63 VK_TRUE, // fillModeNonSolid
64 VK_FALSE, // depthBounds
65 VK_FALSE, // wideLines
66 VK_FALSE, // largePoints
67 VK_FALSE, // alphaToOne
68 VK_FALSE, // multiViewport
69 VK_FALSE, // samplerAnisotropy
70 VK_TRUE, // textureCompressionETC2
71 VK_FALSE, // textureCompressionASTC_LDR
72 VK_FALSE, // textureCompressionBC
73 VK_FALSE, // occlusionQueryPrecise
74 VK_FALSE, // pipelineStatisticsQuery
75 VK_TRUE, // vertexPipelineStoresAndAtomics
76 VK_TRUE, // fragmentStoresAndAtomics
77 VK_FALSE, // shaderTessellationAndGeometryPointSize
78 VK_FALSE, // shaderImageGatherExtended
79 VK_FALSE, // shaderStorageImageExtendedFormats
80 VK_FALSE, // shaderStorageImageMultisample
81 VK_FALSE, // shaderStorageImageReadWithoutFormat
82 VK_FALSE, // shaderStorageImageWriteWithoutFormat
83 VK_FALSE, // shaderUniformBufferArrayDynamicIndexing
84 VK_FALSE, // shaderSampledImageArrayDynamicIndexing
85 VK_FALSE, // shaderStorageBufferArrayDynamicIndexing
86 VK_FALSE, // shaderStorageImageArrayDynamicIndexing
87 VK_FALSE, // shaderClipDistance
88 VK_FALSE, // shaderCullDistance
89 VK_FALSE, // shaderFloat64
90 VK_FALSE, // shaderInt64
91 VK_FALSE, // shaderInt16
92 VK_FALSE, // shaderResourceResidency
93 VK_FALSE, // shaderResourceMinLod
94 VK_FALSE, // sparseBinding
95 VK_FALSE, // sparseResidencyBuffer
96 VK_FALSE, // sparseResidencyImage2D
97 VK_FALSE, // sparseResidencyImage3D
98 VK_FALSE, // sparseResidency2Samples
99 VK_FALSE, // sparseResidency4Samples
100 VK_FALSE, // sparseResidency8Samples
101 VK_FALSE, // sparseResidency16Samples
102 VK_FALSE, // sparseResidencyAliased
103 VK_FALSE, // variableMultisampleRate
104 VK_FALSE, // inheritedQueries
105 };
106
107 return features;
108}
109
110void PhysicalDevice::getFeatures(VkPhysicalDeviceSamplerYcbcrConversionFeatures* features) const
111{
112 features->samplerYcbcrConversion = VK_TRUE;
113}
114
115void PhysicalDevice::getFeatures(VkPhysicalDevice16BitStorageFeatures* features) const
116{
117 features->storageBuffer16BitAccess = VK_FALSE;
118 features->storageInputOutput16 = VK_FALSE;
119 features->storagePushConstant16 = VK_FALSE;
120 features->uniformAndStorageBuffer16BitAccess = VK_FALSE;
121}
122
123void PhysicalDevice::getFeatures(VkPhysicalDeviceVariablePointerFeatures* features) const
124{
125 features->variablePointersStorageBuffer = VK_FALSE;
126 features->variablePointers = VK_FALSE;
127}
128
129void PhysicalDevice::getFeatures(VkPhysicalDevice8BitStorageFeaturesKHR* features) const
130{
131 features->storageBuffer8BitAccess = VK_FALSE;
132 features->uniformAndStorageBuffer8BitAccess = VK_FALSE;
133 features->storagePushConstant8 = VK_FALSE;
134}
135
136void PhysicalDevice::getFeatures(VkPhysicalDeviceMultiviewFeatures* features) const
137{
138 features->multiview = VK_TRUE;
139 features->multiviewGeometryShader = VK_FALSE;
140 features->multiviewTessellationShader = VK_FALSE;
141}
142
143void PhysicalDevice::getFeatures(VkPhysicalDeviceProtectedMemoryFeatures* features) const
144{
145 features->protectedMemory = VK_FALSE;
146}
147
148void PhysicalDevice::getFeatures(VkPhysicalDeviceShaderDrawParameterFeatures* features) const
149{
150 features->shaderDrawParameters = VK_FALSE;
151}
152
153void PhysicalDevice::getFeatures(VkPhysicalDeviceLineRasterizationFeaturesEXT* features) const
154{
155 features->rectangularLines = VK_TRUE;
156 features->bresenhamLines = VK_TRUE;
157 features->smoothLines = VK_FALSE;
158 features->stippledRectangularLines = VK_FALSE;
159 features->stippledBresenhamLines = VK_FALSE;
160 features->stippledSmoothLines = VK_FALSE;
161}
162
163void PhysicalDevice::getFeatures(VkPhysicalDeviceProvokingVertexFeaturesEXT* features) const
164{
165 features->provokingVertexLast = VK_TRUE;
166}
167
168VkSampleCountFlags PhysicalDevice::getSampleCounts() const
169{
170 return VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT;
171}
172
173const VkPhysicalDeviceLimits& PhysicalDevice::getLimits() const
174{
175 VkSampleCountFlags sampleCounts = getSampleCounts();
176
177 static const VkPhysicalDeviceLimits limits =
178 {
179 1 << (vk::MAX_IMAGE_LEVELS_1D - 1), // maxImageDimension1D
180 1 << (vk::MAX_IMAGE_LEVELS_2D - 1), // maxImageDimension2D
181 1 << (vk::MAX_IMAGE_LEVELS_3D - 1), // maxImageDimension3D
182 1 << (vk::MAX_IMAGE_LEVELS_CUBE - 1), // maxImageDimensionCube
183 vk::MAX_IMAGE_ARRAY_LAYERS, // maxImageArrayLayers
184 65536, // maxTexelBufferElements
185 16384, // maxUniformBufferRange
186 (1ul << 27), // maxStorageBufferRange
187 vk::MAX_PUSH_CONSTANT_SIZE, // maxPushConstantsSize
188 4096, // maxMemoryAllocationCount
189 4000, // maxSamplerAllocationCount
190 131072, // bufferImageGranularity
191 0, // sparseAddressSpaceSize (unsupported)
192 MAX_BOUND_DESCRIPTOR_SETS, // maxBoundDescriptorSets
193 16, // maxPerStageDescriptorSamplers
194 14, // maxPerStageDescriptorUniformBuffers
195 16, // maxPerStageDescriptorStorageBuffers
196 16, // maxPerStageDescriptorSampledImages
197 4, // maxPerStageDescriptorStorageImages
198 4, // maxPerStageDescriptorInputAttachments
199 128, // maxPerStageResources
200 96, // maxDescriptorSetSamplers
201 72, // maxDescriptorSetUniformBuffers
202 MAX_DESCRIPTOR_SET_UNIFORM_BUFFERS_DYNAMIC, // maxDescriptorSetUniformBuffersDynamic
203 24, // maxDescriptorSetStorageBuffers
204 MAX_DESCRIPTOR_SET_STORAGE_BUFFERS_DYNAMIC, // maxDescriptorSetStorageBuffersDynamic
205 96, // maxDescriptorSetSampledImages
206 24, // maxDescriptorSetStorageImages
207 4, // maxDescriptorSetInputAttachments
208 16, // maxVertexInputAttributes
209 vk::MAX_VERTEX_INPUT_BINDINGS, // maxVertexInputBindings
210 2047, // maxVertexInputAttributeOffset
211 2048, // maxVertexInputBindingStride
212 sw::MAX_INTERFACE_COMPONENTS, // maxVertexOutputComponents
213 0, // maxTessellationGenerationLevel (unsupported)
214 0, // maxTessellationPatchSize (unsupported)
215 0, // maxTessellationControlPerVertexInputComponents (unsupported)
216 0, // maxTessellationControlPerVertexOutputComponents (unsupported)
217 0, // maxTessellationControlPerPatchOutputComponents (unsupported)
218 0, // maxTessellationControlTotalOutputComponents (unsupported)
219 0, // maxTessellationEvaluationInputComponents (unsupported)
220 0, // maxTessellationEvaluationOutputComponents (unsupported)
221 0, // maxGeometryShaderInvocations (unsupported)
222 0, // maxGeometryInputComponents (unsupported)
223 0, // maxGeometryOutputComponents (unsupported)
224 0, // maxGeometryOutputVertices (unsupported)
225 0, // maxGeometryTotalOutputComponents (unsupported)
226 sw::MAX_INTERFACE_COMPONENTS, // maxFragmentInputComponents
227 4, // maxFragmentOutputAttachments
228 1, // maxFragmentDualSrcAttachments
229 4, // maxFragmentCombinedOutputResources
230 16384, // maxComputeSharedMemorySize
231 { 65535, 65535, 65535 }, // maxComputeWorkGroupCount[3]
232 128, // maxComputeWorkGroupInvocations
233 { 128, 128, 64, }, // maxComputeWorkGroupSize[3]
234 vk::SUBPIXEL_PRECISION_BITS, // subPixelPrecisionBits
235 4, // subTexelPrecisionBits
236 4, // mipmapPrecisionBits
237 UINT32_MAX, // maxDrawIndexedIndexValue
238 UINT32_MAX, // maxDrawIndirectCount
239 vk::MAX_SAMPLER_LOD_BIAS, // maxSamplerLodBias
240 16, // maxSamplerAnisotropy
241 16, // maxViewports
242 { 4096, 4096 }, // maxViewportDimensions[2]
243 { -8192, 8191 }, // viewportBoundsRange[2]
244 0, // viewportSubPixelBits
245 64, // minMemoryMapAlignment
246 vk::MIN_TEXEL_BUFFER_OFFSET_ALIGNMENT, // minTexelBufferOffsetAlignment
247 vk::MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT, // minUniformBufferOffsetAlignment
248 vk::MIN_STORAGE_BUFFER_OFFSET_ALIGNMENT, // minStorageBufferOffsetAlignment
249 sw::MIN_TEXEL_OFFSET, // minTexelOffset
250 sw::MAX_TEXEL_OFFSET, // maxTexelOffset
251 sw::MIN_TEXEL_OFFSET, // minTexelGatherOffset
252 sw::MAX_TEXEL_OFFSET, // maxTexelGatherOffset
253 -0.5, // minInterpolationOffset
254 0.5, // maxInterpolationOffset
255 4, // subPixelInterpolationOffsetBits
256 4096, // maxFramebufferWidth
257 4096, // maxFramebufferHeight
258 256, // maxFramebufferLayers
259 sampleCounts, // framebufferColorSampleCounts
260 sampleCounts, // framebufferDepthSampleCounts
261 sampleCounts, // framebufferStencilSampleCounts
262 sampleCounts, // framebufferNoAttachmentsSampleCounts
263 4, // maxColorAttachments
264 sampleCounts, // sampledImageColorSampleCounts
265 VK_SAMPLE_COUNT_1_BIT, // sampledImageIntegerSampleCounts
266 sampleCounts, // sampledImageDepthSampleCounts
267 sampleCounts, // sampledImageStencilSampleCounts
268 VK_SAMPLE_COUNT_1_BIT, // storageImageSampleCounts (unsupported)
269 1, // maxSampleMaskWords
270 VK_FALSE, // timestampComputeAndGraphics
271 60, // timestampPeriod
272 8, // maxClipDistances
273 8, // maxCullDistances
274 8, // maxCombinedClipAndCullDistances
275 2, // discreteQueuePriorities
276 { 1.0, vk::MAX_POINT_SIZE }, // pointSizeRange[2]
277 { 1.0, 1.0 }, // lineWidthRange[2] (unsupported)
278 0.0, // pointSizeGranularity (unsupported)
279 0.0, // lineWidthGranularity (unsupported)
280 VK_TRUE, // strictLines
281 VK_TRUE, // standardSampleLocations
282 64, // optimalBufferCopyOffsetAlignment
283 64, // optimalBufferCopyRowPitchAlignment
284 256, // nonCoherentAtomSize
285 };
286
287 return limits;
288}
289
290const VkPhysicalDeviceProperties& PhysicalDevice::getProperties() const
291{
292 static const VkPhysicalDeviceProperties properties
293 {
294 API_VERSION,
295 DRIVER_VERSION,
296 VENDOR_ID,
297 DEVICE_ID,
298 VK_PHYSICAL_DEVICE_TYPE_CPU, // deviceType
299 SWIFTSHADER_DEVICE_NAME, // deviceName
300 SWIFTSHADER_UUID, // pipelineCacheUUID
301 getLimits(), // limits
302 {} // sparseProperties
303 };
304
305 return properties;
306}
307
308void PhysicalDevice::getProperties(VkPhysicalDeviceIDProperties* properties) const
309{
310 memset(properties->deviceUUID, 0, VK_UUID_SIZE);
311 memset(properties->driverUUID, 0, VK_UUID_SIZE);
312 memset(properties->deviceLUID, 0, VK_LUID_SIZE);
313
314 memcpy(properties->deviceUUID, SWIFTSHADER_UUID, VK_UUID_SIZE);
315 *((uint64_t*)properties->driverUUID) = DRIVER_VERSION;
316
317 properties->deviceNodeMask = 0;
318 properties->deviceLUIDValid = VK_FALSE;
319}
320
321void PhysicalDevice::getProperties(VkPhysicalDeviceMaintenance3Properties* properties) const
322{
323 properties->maxMemoryAllocationSize = 1u << 31;
324 properties->maxPerSetDescriptors = 1024;
325}
326
327void PhysicalDevice::getProperties(VkPhysicalDeviceMultiviewProperties* properties) const
328{
329 properties->maxMultiviewViewCount = 6;
330 properties->maxMultiviewInstanceIndex = 1u<<27;
331}
332
333void PhysicalDevice::getProperties(VkPhysicalDevicePointClippingProperties* properties) const
334{
335 properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
336}
337
338void PhysicalDevice::getProperties(VkPhysicalDeviceProtectedMemoryProperties* properties) const
339{
340 properties->protectedNoFault = VK_FALSE;
341}
342
343void PhysicalDevice::getProperties(VkPhysicalDeviceSubgroupProperties* properties) const
344{
345 properties->subgroupSize = sw::SIMD::Width;
346 properties->supportedStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
347 properties->supportedOperations =
348 VK_SUBGROUP_FEATURE_BASIC_BIT |
349 VK_SUBGROUP_FEATURE_VOTE_BIT |
350 VK_SUBGROUP_FEATURE_BALLOT_BIT |
351 VK_SUBGROUP_FEATURE_SHUFFLE_BIT |
352 VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT;
353 properties->quadOperationsInAllStages = VK_FALSE;
354}
355
356void PhysicalDevice::getProperties(const VkExternalMemoryHandleTypeFlagBits* handleType, VkExternalImageFormatProperties* properties) const
357{
358 setExternalMemoryProperties(*handleType, &properties->externalMemoryProperties);
359}
360
361void PhysicalDevice::getProperties(VkSamplerYcbcrConversionImageFormatProperties* properties) const
362{
363 properties->combinedImageSamplerDescriptorCount = 1; // Need only one descriptor for YCbCr sampling.
364}
365
366#ifdef __ANDROID__
367void PhysicalDevice::getProperties(VkPhysicalDevicePresentationPropertiesANDROID* properties) const
368{
369 properties->sharedImage = VK_FALSE;
370}
371#endif
372
373void PhysicalDevice::getProperties(const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties) const
374{
375 setExternalMemoryProperties(pExternalBufferInfo->handleType, &pExternalBufferProperties->externalMemoryProperties);
376}
377
378void PhysicalDevice::getProperties(const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties) const
379{
380 pExternalFenceProperties->compatibleHandleTypes = 0;
381 pExternalFenceProperties->exportFromImportedHandleTypes = 0;
382 pExternalFenceProperties->externalFenceFeatures = 0;
383}
384
385void PhysicalDevice::getProperties(const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties) const
386{
387#if SWIFTSHADER_EXTERNAL_SEMAPHORE_LINUX_MEMFD
388 if (pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
389 {
390 pExternalSemaphoreProperties->compatibleHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
391 pExternalSemaphoreProperties->exportFromImportedHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
392 pExternalSemaphoreProperties->externalSemaphoreFeatures = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
393 return;
394 }
395#endif
396#if SWIFTSHADER_EXTERNAL_SEMAPHORE_ZIRCON_EVENT
397 if (pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA)
398 {
399 pExternalSemaphoreProperties->compatibleHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA;
400 pExternalSemaphoreProperties->exportFromImportedHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_TEMP_ZIRCON_EVENT_BIT_FUCHSIA;
401 pExternalSemaphoreProperties->externalSemaphoreFeatures = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
402 return;
403 }
404#endif
405 pExternalSemaphoreProperties->compatibleHandleTypes = 0;
406 pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
407 pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
408}
409
410void PhysicalDevice::getProperties(VkPhysicalDeviceDriverPropertiesKHR* properties) const
411{
412 properties->driverID = VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR;
413 strcpy(properties->driverName, "SwiftShader driver");
414 strcpy(properties->driverInfo, "");
415 properties->conformanceVersion = {1, 1, 3, 3};
416}
417
418void PhysicalDevice::getProperties(VkPhysicalDeviceLineRasterizationPropertiesEXT* properties) const
419{
420 properties->lineSubPixelPrecisionBits = vk::SUBPIXEL_PRECISION_BITS;
421}
422
423void PhysicalDevice::getProperties(VkPhysicalDeviceProvokingVertexPropertiesEXT* properties) const
424{
425 properties->provokingVertexModePerPipeline = VK_TRUE;
426}
427
428bool PhysicalDevice::hasFeatures(const VkPhysicalDeviceFeatures& requestedFeatures) const
429{
430 const VkPhysicalDeviceFeatures& supportedFeatures = getFeatures();
431 const VkBool32* supportedFeature = reinterpret_cast<const VkBool32*>(&supportedFeatures);
432 const VkBool32* requestedFeature = reinterpret_cast<const VkBool32*>(&requestedFeatures);
433 constexpr auto featureCount = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
434
435 for(unsigned int i = 0; i < featureCount; i++)
436 {
437 if((requestedFeature[i] == VK_TRUE) && (supportedFeature[i] != VK_TRUE))
438 {
439 return false;
440 }
441 }
442
443 return true;
444}
445
446void PhysicalDevice::getFormatProperties(Format format, VkFormatProperties* pFormatProperties) const
447{
448 pFormatProperties->linearTilingFeatures = 0; // Unsupported format
449 pFormatProperties->optimalTilingFeatures = 0; // Unsupported format
450 pFormatProperties->bufferFeatures = 0; // Unsupported format
451
452 switch(format)
453 {
454 // Formats which can be sampled *and* filtered
455 case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
456 case VK_FORMAT_R5G6B5_UNORM_PACK16:
457 case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
458 case VK_FORMAT_R8_UNORM:
459 case VK_FORMAT_R8_SRGB:
460 case VK_FORMAT_R8_SNORM:
461 case VK_FORMAT_R8G8_UNORM:
462 case VK_FORMAT_R8G8_SRGB:
463 case VK_FORMAT_R8G8_SNORM:
464 case VK_FORMAT_R8G8B8A8_UNORM:
465 case VK_FORMAT_R8G8B8A8_SNORM:
466 case VK_FORMAT_R8G8B8A8_SRGB:
467 case VK_FORMAT_B8G8R8A8_UNORM:
468 case VK_FORMAT_B8G8R8A8_SRGB:
469 case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
470 case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
471 case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
472 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
473 case VK_FORMAT_R16_SFLOAT:
474 case VK_FORMAT_R16G16_SFLOAT:
475 case VK_FORMAT_R16G16B16A16_SFLOAT:
476 case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
477 case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
478 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
479 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
480 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
481 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
482 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
483 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
484 case VK_FORMAT_EAC_R11_UNORM_BLOCK:
485 case VK_FORMAT_EAC_R11_SNORM_BLOCK:
486 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
487 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
488 pFormatProperties->optimalTilingFeatures |=
489 VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
490 // Fall through
491
492 // Formats which can be sampled, but don't support filtering
493 case VK_FORMAT_R8_UINT:
494 case VK_FORMAT_R8_SINT:
495 case VK_FORMAT_R8G8_UINT:
496 case VK_FORMAT_R8G8_SINT:
497 case VK_FORMAT_R8G8B8A8_UINT:
498 case VK_FORMAT_R8G8B8A8_SINT:
499 case VK_FORMAT_A8B8G8R8_UINT_PACK32:
500 case VK_FORMAT_A8B8G8R8_SINT_PACK32:
501 case VK_FORMAT_A2B10G10R10_UINT_PACK32:
502 case VK_FORMAT_R16_UINT:
503 case VK_FORMAT_R16_SINT:
504 case VK_FORMAT_R16G16_UINT:
505 case VK_FORMAT_R16G16_SINT:
506 case VK_FORMAT_R16G16B16A16_UINT:
507 case VK_FORMAT_R16G16B16A16_SINT:
508 case VK_FORMAT_R32_UINT:
509 case VK_FORMAT_R32_SINT:
510 case VK_FORMAT_R32_SFLOAT:
511 case VK_FORMAT_R32G32_UINT:
512 case VK_FORMAT_R32G32_SINT:
513 case VK_FORMAT_R32G32_SFLOAT:
514 case VK_FORMAT_R32G32B32A32_UINT:
515 case VK_FORMAT_R32G32B32A32_SINT:
516 case VK_FORMAT_R32G32B32A32_SFLOAT:
517 case VK_FORMAT_S8_UINT:
518 case VK_FORMAT_D16_UNORM:
519 case VK_FORMAT_D32_SFLOAT:
520 case VK_FORMAT_D32_SFLOAT_S8_UINT:
521 pFormatProperties->optimalTilingFeatures |=
522 VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
523 VK_FORMAT_FEATURE_BLIT_SRC_BIT |
524 VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
525 VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
526 break;
527
528 // YCbCr formats:
529 case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
530 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
531 pFormatProperties->optimalTilingFeatures |=
532 VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
533 VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
534 VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
535 VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT;
536 break;
537 default:
538 break;
539 }
540
541 switch(format)
542 {
543 case VK_FORMAT_R32_UINT:
544 case VK_FORMAT_R32_SINT:
545 pFormatProperties->optimalTilingFeatures |=
546 VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
547 pFormatProperties->bufferFeatures |=
548 VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
549 // Fall through
550 case VK_FORMAT_R8G8B8A8_UNORM:
551 case VK_FORMAT_R8G8B8A8_SNORM:
552 case VK_FORMAT_R8G8B8A8_UINT:
553 case VK_FORMAT_R8G8B8A8_SINT:
554 case VK_FORMAT_R16G16B16A16_UINT:
555 case VK_FORMAT_R16G16B16A16_SINT:
556 case VK_FORMAT_R16G16B16A16_SFLOAT:
557 case VK_FORMAT_R32_SFLOAT:
558 case VK_FORMAT_R32G32_UINT:
559 case VK_FORMAT_R32G32_SINT:
560 case VK_FORMAT_R32G32_SFLOAT:
561 case VK_FORMAT_R32G32B32A32_UINT:
562 case VK_FORMAT_R32G32B32A32_SINT:
563 case VK_FORMAT_R32G32B32A32_SFLOAT:
564 pFormatProperties->optimalTilingFeatures |=
565 VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
566 // Fall through
567 case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
568 case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
569 case VK_FORMAT_A8B8G8R8_UINT_PACK32:
570 case VK_FORMAT_A8B8G8R8_SINT_PACK32:
571 pFormatProperties->bufferFeatures |=
572 VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
573 break;
574 default:
575 break;
576 }
577
578 switch(format)
579 {
580 case VK_FORMAT_R5G6B5_UNORM_PACK16:
581 case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
582 case VK_FORMAT_R8_UNORM:
583 case VK_FORMAT_R8G8_UNORM:
584 case VK_FORMAT_R8G8B8A8_UNORM:
585 case VK_FORMAT_R8G8B8A8_SRGB:
586 case VK_FORMAT_B8G8R8A8_UNORM:
587 case VK_FORMAT_B8G8R8A8_SRGB:
588 case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
589 case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
590 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
591 case VK_FORMAT_R16_SFLOAT:
592 case VK_FORMAT_R16G16_SFLOAT:
593 case VK_FORMAT_R16G16B16A16_SFLOAT:
594 pFormatProperties->optimalTilingFeatures |=
595 VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
596 // Fall through
597 case VK_FORMAT_R8_UINT:
598 case VK_FORMAT_R8_SINT:
599 case VK_FORMAT_R8G8_UINT:
600 case VK_FORMAT_R8G8_SINT:
601 case VK_FORMAT_R8G8B8A8_UINT:
602 case VK_FORMAT_R8G8B8A8_SINT:
603 case VK_FORMAT_A8B8G8R8_UINT_PACK32:
604 case VK_FORMAT_A8B8G8R8_SINT_PACK32:
605 case VK_FORMAT_A2B10G10R10_UINT_PACK32:
606 case VK_FORMAT_R16_UINT:
607 case VK_FORMAT_R16_SINT:
608 case VK_FORMAT_R16G16_UINT:
609 case VK_FORMAT_R16G16_SINT:
610 case VK_FORMAT_R16G16B16A16_UINT:
611 case VK_FORMAT_R16G16B16A16_SINT:
612 case VK_FORMAT_R32_UINT:
613 case VK_FORMAT_R32_SINT:
614 case VK_FORMAT_R32_SFLOAT:
615 case VK_FORMAT_R32G32_UINT:
616 case VK_FORMAT_R32G32_SINT:
617 case VK_FORMAT_R32G32_SFLOAT:
618 case VK_FORMAT_R32G32B32A32_UINT:
619 case VK_FORMAT_R32G32B32A32_SINT:
620 case VK_FORMAT_R32G32B32A32_SFLOAT:
621 pFormatProperties->optimalTilingFeatures |=
622 VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
623 VK_FORMAT_FEATURE_BLIT_DST_BIT;
624 break;
625 case VK_FORMAT_S8_UINT:
626 case VK_FORMAT_D16_UNORM:
627 case VK_FORMAT_D32_SFLOAT: // Note: either VK_FORMAT_D32_SFLOAT or VK_FORMAT_X8_D24_UNORM_PACK32 must be supported
628 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
629 pFormatProperties->optimalTilingFeatures |=
630 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
631 break;
632 default:
633 break;
634 }
635
636 switch(format)
637 {
638 case VK_FORMAT_R8_UNORM:
639 case VK_FORMAT_R8_SNORM:
640 case VK_FORMAT_R8_UINT:
641 case VK_FORMAT_R8_SINT:
642 case VK_FORMAT_R8G8_UNORM:
643 case VK_FORMAT_R8G8_SNORM:
644 case VK_FORMAT_R8G8_UINT:
645 case VK_FORMAT_R8G8_SINT:
646 case VK_FORMAT_R8G8B8A8_UNORM:
647 case VK_FORMAT_R8G8B8A8_SNORM:
648 case VK_FORMAT_R8G8B8A8_UINT:
649 case VK_FORMAT_R8G8B8A8_SINT:
650 case VK_FORMAT_B8G8R8A8_UNORM:
651 case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
652 case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
653 case VK_FORMAT_A8B8G8R8_UINT_PACK32:
654 case VK_FORMAT_A8B8G8R8_SINT_PACK32:
655 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
656 case VK_FORMAT_R16_UNORM:
657 case VK_FORMAT_R16_SNORM:
658 case VK_FORMAT_R16_UINT:
659 case VK_FORMAT_R16_SINT:
660 case VK_FORMAT_R16_SFLOAT:
661 case VK_FORMAT_R16G16_UNORM:
662 case VK_FORMAT_R16G16_SNORM:
663 case VK_FORMAT_R16G16_UINT:
664 case VK_FORMAT_R16G16_SINT:
665 case VK_FORMAT_R16G16_SFLOAT:
666 case VK_FORMAT_R16G16B16A16_UNORM:
667 case VK_FORMAT_R16G16B16A16_SNORM:
668 case VK_FORMAT_R16G16B16A16_UINT:
669 case VK_FORMAT_R16G16B16A16_SINT:
670 case VK_FORMAT_R16G16B16A16_SFLOAT:
671 case VK_FORMAT_R32_UINT:
672 case VK_FORMAT_R32_SINT:
673 case VK_FORMAT_R32_SFLOAT:
674 case VK_FORMAT_R32G32_UINT:
675 case VK_FORMAT_R32G32_SINT:
676 case VK_FORMAT_R32G32_SFLOAT:
677 case VK_FORMAT_R32G32B32_UINT:
678 case VK_FORMAT_R32G32B32_SINT:
679 case VK_FORMAT_R32G32B32_SFLOAT:
680 case VK_FORMAT_R32G32B32A32_UINT:
681 case VK_FORMAT_R32G32B32A32_SINT:
682 case VK_FORMAT_R32G32B32A32_SFLOAT:
683 pFormatProperties->bufferFeatures |=
684 VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
685 break;
686 default:
687 break;
688 }
689
690 switch(format)
691 {
692 case VK_FORMAT_R8_UNORM:
693 case VK_FORMAT_R8_SNORM:
694 case VK_FORMAT_R8_UINT:
695 case VK_FORMAT_R8_SINT:
696 case VK_FORMAT_R8G8_UNORM:
697 case VK_FORMAT_R8G8_SNORM:
698 case VK_FORMAT_R8G8_UINT:
699 case VK_FORMAT_R8G8_SINT:
700 case VK_FORMAT_R8G8B8A8_UNORM:
701 case VK_FORMAT_R8G8B8A8_SNORM:
702 case VK_FORMAT_R8G8B8A8_UINT:
703 case VK_FORMAT_R8G8B8A8_SINT:
704 case VK_FORMAT_B8G8R8A8_UNORM:
705 case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
706 case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
707 case VK_FORMAT_A8B8G8R8_UINT_PACK32:
708 case VK_FORMAT_A8B8G8R8_SINT_PACK32:
709 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
710 case VK_FORMAT_A2B10G10R10_UINT_PACK32:
711 case VK_FORMAT_R16_UINT:
712 case VK_FORMAT_R16_SINT:
713 case VK_FORMAT_R16_SFLOAT:
714 case VK_FORMAT_R16G16_UINT:
715 case VK_FORMAT_R16G16_SINT:
716 case VK_FORMAT_R16G16_SFLOAT:
717 case VK_FORMAT_R16G16B16A16_UINT:
718 case VK_FORMAT_R16G16B16A16_SINT:
719 case VK_FORMAT_R16G16B16A16_SFLOAT:
720 case VK_FORMAT_R32_UINT:
721 case VK_FORMAT_R32_SINT:
722 case VK_FORMAT_R32_SFLOAT:
723 case VK_FORMAT_R32G32_UINT:
724 case VK_FORMAT_R32G32_SINT:
725 case VK_FORMAT_R32G32_SFLOAT:
726 case VK_FORMAT_R32G32B32A32_UINT:
727 case VK_FORMAT_R32G32B32A32_SINT:
728 case VK_FORMAT_R32G32B32A32_SFLOAT:
729 case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
730 pFormatProperties->bufferFeatures |=
731 VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;
732 break;
733 default:
734 break;
735 }
736
737 if(pFormatProperties->optimalTilingFeatures)
738 {
739 pFormatProperties->linearTilingFeatures = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
740 VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
741 }
742}
743
744void PhysicalDevice::getImageFormatProperties(Format format, VkImageType type, VkImageTiling tiling,
745 VkImageUsageFlags usage, VkImageCreateFlags flags,
746 VkImageFormatProperties* pImageFormatProperties) const
747{
748 pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
749 pImageFormatProperties->maxArrayLayers = vk::MAX_IMAGE_ARRAY_LAYERS;
750 pImageFormatProperties->maxExtent.depth = 1;
751
752 switch(type)
753 {
754 case VK_IMAGE_TYPE_1D:
755 pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_1D;
756 pImageFormatProperties->maxExtent.width = 1 << (vk::MAX_IMAGE_LEVELS_1D - 1);
757 pImageFormatProperties->maxExtent.height = 1;
758 break;
759 case VK_IMAGE_TYPE_2D:
760 if(flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
761 {
762 pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_CUBE;
763 pImageFormatProperties->maxExtent.width = 1 << (vk::MAX_IMAGE_LEVELS_CUBE - 1);
764 pImageFormatProperties->maxExtent.height = 1 << (vk::MAX_IMAGE_LEVELS_CUBE - 1);
765 }
766 else
767 {
768 pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_2D;
769 pImageFormatProperties->maxExtent.width = 1 << (vk::MAX_IMAGE_LEVELS_2D - 1);
770 pImageFormatProperties->maxExtent.height = 1 << (vk::MAX_IMAGE_LEVELS_2D - 1);
771
772 VkFormatProperties props;
773 getFormatProperties(format, &props);
774 auto features = tiling == VK_IMAGE_TILING_LINEAR ? props.linearTilingFeatures : props.optimalTilingFeatures;
775 if (features & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
776 {
777 // Only renderable formats make sense for multisample
778 pImageFormatProperties->sampleCounts = getSampleCounts();
779 }
780 }
781 break;
782 case VK_IMAGE_TYPE_3D:
783 pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_3D;
784 pImageFormatProperties->maxExtent.width = 1 << (vk::MAX_IMAGE_LEVELS_3D - 1);
785 pImageFormatProperties->maxExtent.height = 1 << (vk::MAX_IMAGE_LEVELS_3D - 1);
786 pImageFormatProperties->maxExtent.depth = 1 << (vk::MAX_IMAGE_LEVELS_3D - 1);
787 pImageFormatProperties->maxArrayLayers = 1; // no 3D + layers
788 break;
789 default:
790 UNREACHABLE("VkImageType: %d", int(type));
791 break;
792 }
793
794 pImageFormatProperties->maxResourceSize = 1u << 31; // Minimum value for maxResourceSize
795
796 // "Images created with tiling equal to VK_IMAGE_TILING_LINEAR have further restrictions on their limits and capabilities
797 // compared to images created with tiling equal to VK_IMAGE_TILING_OPTIMAL."
798 if(tiling == VK_IMAGE_TILING_LINEAR)
799 {
800 pImageFormatProperties->maxMipLevels = 1;
801 pImageFormatProperties->maxArrayLayers = 1;
802 pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
803 }
804
805 // "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
806 // have further restrictions on their limits and capabilities compared to images created with other formats."
807 if(format.isYcbcrFormat())
808 {
809 pImageFormatProperties->maxMipLevels = 1;
810 pImageFormatProperties->maxArrayLayers = 1;
811 pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
812 }
813}
814
815uint32_t PhysicalDevice::getQueueFamilyPropertyCount() const
816{
817 return 1;
818}
819
820void PhysicalDevice::getQueueFamilyProperties(uint32_t pQueueFamilyPropertyCount,
821 VkQueueFamilyProperties* pQueueFamilyProperties) const
822{
823 for(uint32_t i = 0; i < pQueueFamilyPropertyCount; i++)
824 {
825 pQueueFamilyProperties[i].minImageTransferGranularity.width = 1;
826 pQueueFamilyProperties[i].minImageTransferGranularity.height = 1;
827 pQueueFamilyProperties[i].minImageTransferGranularity.depth = 1;
828 pQueueFamilyProperties[i].queueCount = 1;
829 pQueueFamilyProperties[i].queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
830 pQueueFamilyProperties[i].timestampValidBits = 0; // No support for time stamps
831 }
832}
833
834void PhysicalDevice::getQueueFamilyProperties(uint32_t pQueueFamilyPropertyCount,
835 VkQueueFamilyProperties2* pQueueFamilyProperties) const
836{
837 for(uint32_t i = 0; i < pQueueFamilyPropertyCount; i++)
838 {
839 pQueueFamilyProperties[i].queueFamilyProperties.minImageTransferGranularity.width = 1;
840 pQueueFamilyProperties[i].queueFamilyProperties.minImageTransferGranularity.height = 1;
841 pQueueFamilyProperties[i].queueFamilyProperties.minImageTransferGranularity.depth = 1;
842 pQueueFamilyProperties[i].queueFamilyProperties.queueCount = 1;
843 pQueueFamilyProperties[i].queueFamilyProperties.queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
844 pQueueFamilyProperties[i].queueFamilyProperties.timestampValidBits = 0; // No support for time stamps
845 }
846}
847
848const VkPhysicalDeviceMemoryProperties& PhysicalDevice::getMemoryProperties() const
849{
850 static const VkPhysicalDeviceMemoryProperties properties
851 {
852 1, // memoryTypeCount
853 {
854 // vk::MEMORY_TYPE_GENERIC_BIT
855 {
856 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
857 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
858 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
859 VK_MEMORY_PROPERTY_HOST_CACHED_BIT, // propertyFlags
860 0 // heapIndex
861 },
862 },
863 1, // memoryHeapCount
864 {
865 {
866 1ull << 31, // size, FIXME(sugoi): This should be configurable based on available RAM
867 VK_MEMORY_HEAP_DEVICE_LOCAL_BIT // flags
868 },
869 }
870 };
871
872 return properties;
873}
874
875} // namespace vk
876