| // Copyright 2018 The SwiftShader Authors. All Rights Reserved. | 
 | // | 
 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | // you may not use this file except in compliance with the License. | 
 | // You may obtain a copy of the License at | 
 | // | 
 | //    http://www.apache.org/licenses/LICENSE-2.0 | 
 | // | 
 | // Unless required by applicable law or agreed to in writing, software | 
 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | // See the License for the specific language governing permissions and | 
 | // limitations under the License. | 
 |  | 
 | #include "VkPhysicalDevice.hpp" | 
 | #include "VkConfig.h" | 
 |  | 
 | #include <cstring> | 
 |  | 
 | namespace vk | 
 | { | 
 |  | 
 | PhysicalDevice::PhysicalDevice(const void*, void* mem) | 
 | { | 
 | } | 
 |  | 
 | const VkPhysicalDeviceFeatures& PhysicalDevice::getFeatures() const | 
 | { | 
 | 	static const VkPhysicalDeviceFeatures features | 
 | 	{ | 
 | 		true,  // robustBufferAccess | 
 | 		false, // fullDrawIndexUint32 | 
 | 		false, // imageCubeArray | 
 | 		false, // independentBlend | 
 | 		false, // geometryShader | 
 | 		false, // tessellationShader | 
 | 		false, // sampleRateShading | 
 | 		false, // dualSrcBlend | 
 | 		false, // logicOp | 
 | 		false, // multiDrawIndirect | 
 | 		false, // drawIndirectFirstInstance | 
 | 		false, // depthClamp | 
 | 		false, // depthBiasClamp | 
 | 		false, // fillModeNonSolid | 
 | 		false, // depthBounds | 
 | 		false, // wideLines | 
 | 		false, // largePoints | 
 | 		false, // alphaToOne | 
 | 		false, // multiViewport | 
 | 		false, // samplerAnisotropy | 
 | 		true,  // textureCompressionETC2 | 
 | 		false, // textureCompressionASTC_LDR | 
 | 		false, // textureCompressionBC | 
 | 		false, // occlusionQueryPrecise | 
 | 		false, // pipelineStatisticsQuery | 
 | 		false, // vertexPipelineStoresAndAtomics | 
 | 		false, // fragmentStoresAndAtomics | 
 | 		false, // shaderTessellationAndGeometryPointSize | 
 | 		false, // shaderImageGatherExtended | 
 | 		false, // shaderStorageImageExtendedFormats | 
 | 		false, // shaderStorageImageMultisample | 
 | 		false, // shaderStorageImageReadWithoutFormat | 
 | 		false, // shaderStorageImageWriteWithoutFormat | 
 | 		false, // shaderUniformBufferArrayDynamicIndexing | 
 | 		false, // shaderSampledImageArrayDynamicIndexing | 
 | 		false, // shaderStorageBufferArrayDynamicIndexing | 
 | 		false, // shaderStorageImageArrayDynamicIndexing | 
 | 		false, // shaderClipDistance | 
 | 		false, // shaderCullDistance | 
 | 		false, // shaderFloat64 | 
 | 		false, // shaderInt64 | 
 | 		false, // shaderInt16 | 
 | 		false, // shaderResourceResidency | 
 | 		false, // shaderResourceMinLod | 
 | 		false, // sparseBinding | 
 | 		false, // sparseResidencyBuffer | 
 | 		false, // sparseResidencyImage2D | 
 | 		false, // sparseResidencyImage3D | 
 | 		false, // sparseResidency2Samples | 
 | 		false, // sparseResidency4Samples | 
 | 		false, // sparseResidency8Samples | 
 | 		false, // sparseResidency16Samples | 
 | 		false, // sparseResidencyAliased | 
 | 		false, // variableMultisampleRate | 
 | 		false, // inheritedQueries | 
 | 	}; | 
 |  | 
 | 	return features; | 
 | } | 
 |  | 
 | void PhysicalDevice::getFeatures(VkPhysicalDeviceSamplerYcbcrConversionFeatures* features) const | 
 | { | 
 | 	features->samplerYcbcrConversion = VK_FALSE; | 
 | } | 
 |  | 
 | void PhysicalDevice::getFeatures(VkPhysicalDevice16BitStorageFeatures* features) const | 
 | { | 
 | 	features->storageBuffer16BitAccess = VK_FALSE; | 
 | 	features->storageInputOutput16 = VK_FALSE; | 
 | 	features->storagePushConstant16 = VK_FALSE; | 
 | 	features->uniformAndStorageBuffer16BitAccess = VK_FALSE; | 
 | } | 
 |  | 
 | void PhysicalDevice::getFeatures(VkPhysicalDeviceVariablePointerFeatures* features) const | 
 | { | 
 | 	features->variablePointersStorageBuffer = VK_FALSE; | 
 | 	features->variablePointers = VK_FALSE; | 
 | } | 
 |  | 
 | void PhysicalDevice::getFeatures(VkPhysicalDevice8BitStorageFeaturesKHR* features) const | 
 | { | 
 | 	features->storageBuffer8BitAccess = VK_FALSE; | 
 | 	features->uniformAndStorageBuffer8BitAccess = VK_FALSE; | 
 | 	features->storagePushConstant8 = VK_FALSE; | 
 | } | 
 |  | 
 | void PhysicalDevice::getFeatures(VkPhysicalDeviceMultiviewFeatures* features) const | 
 | { | 
 | 	features->multiview = VK_FALSE; | 
 | 	features->multiviewGeometryShader = VK_FALSE; | 
 | 	features->multiviewTessellationShader = VK_FALSE; | 
 | } | 
 |  | 
 | void PhysicalDevice::getFeatures(VkPhysicalDeviceProtectedMemoryFeatures* features) const | 
 | { | 
 | 	features->protectedMemory = VK_FALSE; | 
 | } | 
 |  | 
 | VkSampleCountFlags PhysicalDevice::getSampleCounts() const | 
 | { | 
 | 	return VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT; | 
 | } | 
 |  | 
 | const VkPhysicalDeviceLimits& PhysicalDevice::getLimits() const | 
 | { | 
 | 	VkSampleCountFlags sampleCounts = getSampleCounts(); | 
 |  | 
 | 	static const VkPhysicalDeviceLimits limits = | 
 | 	{ | 
 | 		(1 << vk::MAX_IMAGE_LEVELS_1D), // maxImageDimension1D | 
 | 		(1 << vk::MAX_IMAGE_LEVELS_2D), // maxImageDimension2D | 
 | 		(1 << vk::MAX_IMAGE_LEVELS_3D), // maxImageDimension3D | 
 | 		(1 << vk::MAX_IMAGE_LEVELS_CUBE), // maxImageDimensionCube | 
 | 		(1 << vk::MAX_IMAGE_ARRAY_LAYERS), // maxImageArrayLayers | 
 | 		65536, // maxTexelBufferElements | 
 | 		16384, // maxUniformBufferRange | 
 | 		(1ul << 27), // maxStorageBufferRange | 
 | 		128, // maxPushConstantsSize | 
 | 		4096, // maxMemoryAllocationCount | 
 | 		4000, // maxSamplerAllocationCount | 
 | 		131072, // bufferImageGranularity | 
 | 		0, // sparseAddressSpaceSize (unsupported) | 
 | 		4, // maxBoundDescriptorSets | 
 | 		16, // maxPerStageDescriptorSamplers | 
 | 		12, // maxPerStageDescriptorUniformBuffers | 
 | 		4, // maxPerStageDescriptorStorageBuffers | 
 | 		16, // maxPerStageDescriptorSampledImages | 
 | 		4, // maxPerStageDescriptorStorageImages | 
 | 		4, // maxPerStageDescriptorInputAttachments | 
 | 		128, // maxPerStageResources | 
 | 		96, // maxDescriptorSetSamplers | 
 | 		72, // maxDescriptorSetUniformBuffers | 
 | 		8, // maxDescriptorSetUniformBuffersDynamic | 
 | 		24, // maxDescriptorSetStorageBuffers | 
 | 		4, // maxDescriptorSetStorageBuffersDynamic | 
 | 		96, // maxDescriptorSetSampledImages | 
 | 		24, // maxDescriptorSetStorageImages | 
 | 		4, // maxDescriptorSetInputAttachments | 
 | 		16, // maxVertexInputAttributes | 
 | 		vk::MAX_VERTEX_INPUT_BINDINGS, // maxVertexInputBindings | 
 | 		2047, // maxVertexInputAttributeOffset | 
 | 		2048, // maxVertexInputBindingStride | 
 | 		64, // maxVertexOutputComponents | 
 | 		0, // maxTessellationGenerationLevel (unsupported) | 
 | 		0, // maxTessellationPatchSize (unsupported) | 
 | 		0, // maxTessellationControlPerVertexInputComponents (unsupported) | 
 | 		0, // maxTessellationControlPerVertexOutputComponents (unsupported) | 
 | 		0, // maxTessellationControlPerPatchOutputComponents (unsupported) | 
 | 		0, // maxTessellationControlTotalOutputComponents (unsupported) | 
 | 		0, // maxTessellationEvaluationInputComponents (unsupported) | 
 | 		0, // maxTessellationEvaluationOutputComponents (unsupported) | 
 | 		0, // maxGeometryShaderInvocations (unsupported) | 
 | 		0, // maxGeometryInputComponents (unsupported) | 
 | 		0, // maxGeometryOutputComponents (unsupported) | 
 | 		0, // maxGeometryOutputVertices (unsupported) | 
 | 		0, // maxGeometryTotalOutputComponents (unsupported) | 
 | 		64, // maxFragmentInputComponents | 
 | 		4, // maxFragmentOutputAttachments | 
 | 		1, // maxFragmentDualSrcAttachments | 
 | 		4, // maxFragmentCombinedOutputResources | 
 | 		16384, // maxComputeSharedMemorySize | 
 | 		{ 65535, 65535, 65535 }, // maxComputeWorkGroupCount[3] | 
 | 		128, // maxComputeWorkGroupInvocations | 
 | 		{ 128, 128, 64, }, // maxComputeWorkGroupSize[3] | 
 | 		4, // subPixelPrecisionBits | 
 | 		4, // subTexelPrecisionBits | 
 | 		4, // mipmapPrecisionBits | 
 | 		UINT32_MAX, // maxDrawIndexedIndexValue | 
 | 		UINT32_MAX, // maxDrawIndirectCount | 
 | 		2, // maxSamplerLodBias | 
 | 		16, // maxSamplerAnisotropy | 
 | 		16, // maxViewports | 
 | 		{ 4096, 4096 }, // maxViewportDimensions[2] | 
 | 		{ -8192, 8191 }, // viewportBoundsRange[2] | 
 | 		0, // viewportSubPixelBits | 
 | 		64, // minMemoryMapAlignment | 
 | 		256, // minTexelBufferOffsetAlignment | 
 | 		256, // minUniformBufferOffsetAlignment | 
 | 		256, // minStorageBufferOffsetAlignment | 
 | 		-8, // minTexelOffset | 
 | 		7, // maxTexelOffset | 
 | 		-8, // minTexelGatherOffset | 
 | 		7, // maxTexelGatherOffset | 
 | 		-0.5, // minInterpolationOffset | 
 | 		0.5, // maxInterpolationOffset | 
 | 		4, // subPixelInterpolationOffsetBits | 
 | 		4096, // maxFramebufferWidth | 
 | 		4096, // maxFramebufferHeight | 
 | 		256, // maxFramebufferLayers | 
 | 		sampleCounts, // framebufferColorSampleCounts | 
 | 		sampleCounts, // framebufferDepthSampleCounts | 
 | 		sampleCounts, // framebufferStencilSampleCounts | 
 | 		sampleCounts, // framebufferNoAttachmentsSampleCounts | 
 | 		4,  // maxColorAttachments | 
 | 		sampleCounts, // sampledImageColorSampleCounts | 
 | 		VK_SAMPLE_COUNT_1_BIT, // sampledImageIntegerSampleCounts | 
 | 		sampleCounts, // sampledImageDepthSampleCounts | 
 | 		sampleCounts, // sampledImageStencilSampleCounts | 
 | 		VK_SAMPLE_COUNT_1_BIT, // storageImageSampleCounts (unsupported) | 
 | 		1, // maxSampleMaskWords | 
 | 		false, // timestampComputeAndGraphics | 
 | 		60, // timestampPeriod | 
 | 		8, // maxClipDistances | 
 | 		8, // maxCullDistances | 
 | 		8, // maxCombinedClipAndCullDistances | 
 | 		2, // discreteQueuePriorities | 
 | 		{ 1.0, 64.0 }, // pointSizeRange[2] | 
 | 		{ 1.0, 1.0 }, // lineWidthRange[2] (unsupported) | 
 | 		0.0, // pointSizeGranularity (unsupported) | 
 | 		0.0, // lineWidthGranularity (unsupported) | 
 | 		false, // strictLines | 
 | 		true, // standardSampleLocations | 
 | 		64, // optimalBufferCopyOffsetAlignment | 
 | 		64, // optimalBufferCopyRowPitchAlignment | 
 | 		256, // nonCoherentAtomSize | 
 | 	}; | 
 |  | 
 | 	return limits; | 
 | } | 
 |  | 
 | const VkPhysicalDeviceProperties& PhysicalDevice::getProperties() const | 
 | { | 
 | 	static const VkPhysicalDeviceProperties properties | 
 | 	{ | 
 | 		API_VERSION, | 
 | 		DRIVER_VERSION, | 
 | 		VENDOR_ID, | 
 | 		DEVICE_ID, | 
 | 		VK_PHYSICAL_DEVICE_TYPE_CPU, // deviceType | 
 | 		SWIFTSHADER_DEVICE_NAME, // deviceName | 
 | 		SWIFTSHADER_UUID, // pipelineCacheUUID | 
 | 		getLimits(), // limits | 
 | 		{ 0 } // sparseProperties | 
 | 	}; | 
 |  | 
 | 	return properties; | 
 | } | 
 |  | 
 | void PhysicalDevice::getProperties(VkPhysicalDeviceIDProperties* properties) const | 
 | { | 
 | 	memset(properties->deviceUUID, 0, VK_UUID_SIZE); | 
 | 	memset(properties->driverUUID, 0, VK_UUID_SIZE); | 
 | 	memset(properties->deviceLUID, 0, VK_LUID_SIZE); | 
 |  | 
 | 	memcpy(properties->deviceUUID, SWIFTSHADER_UUID, VK_UUID_SIZE); | 
 | 	*((uint64_t*)properties->driverUUID) = DRIVER_VERSION; | 
 |  | 
 | 	properties->deviceNodeMask = 0; | 
 | 	properties->deviceLUIDValid = VK_FALSE; | 
 | } | 
 |  | 
 | void PhysicalDevice::getProperties(VkPhysicalDeviceMaintenance3Properties* properties) const | 
 | { | 
 | 	properties->maxMemoryAllocationSize = 1 << 31; | 
 | 	properties->maxPerSetDescriptors = 1024; | 
 | } | 
 |  | 
 | void PhysicalDevice::getProperties(VkPhysicalDeviceMultiviewProperties* properties) const | 
 | { | 
 | 	properties->maxMultiviewViewCount = 0; | 
 | 	properties->maxMultiviewInstanceIndex = 0; | 
 | } | 
 |  | 
 | void PhysicalDevice::getProperties(VkPhysicalDevicePointClippingProperties* properties) const | 
 | { | 
 | 	properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES; | 
 | } | 
 |  | 
 | void PhysicalDevice::getProperties(VkPhysicalDeviceProtectedMemoryProperties* properties) const | 
 | { | 
 | 	properties->protectedNoFault = VK_FALSE; | 
 | } | 
 |  | 
 | void PhysicalDevice::getProperties(VkPhysicalDeviceSubgroupProperties* properties) const | 
 | { | 
 | 	properties->subgroupSize = 1; | 
 | 	properties->supportedStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT; | 
 | 	properties->supportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT; | 
 | 	properties->quadOperationsInAllStages = VK_FALSE; | 
 | } | 
 |  | 
 | bool PhysicalDevice::hasFeatures(const VkPhysicalDeviceFeatures& requestedFeatures) const | 
 | { | 
 | 	const VkPhysicalDeviceFeatures& supportedFeatures = getFeatures(); | 
 | 	const VkBool32* supportedFeature = reinterpret_cast<const VkBool32*>(&supportedFeatures); | 
 | 	const VkBool32* requestedFeature = reinterpret_cast<const VkBool32*>(&requestedFeatures); | 
 | 	constexpr auto featureCount = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32); | 
 |  | 
 | 	for(unsigned int i = 0; i < featureCount; i++) | 
 | 	{ | 
 | 		if((requestedFeature[i] == VK_TRUE) && (supportedFeature[i] != VK_TRUE)) | 
 | 		{ | 
 | 			return false; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return true; | 
 | } | 
 |  | 
 | void PhysicalDevice::getFormatProperties(VkFormat format, VkFormatProperties* pFormatProperties) const | 
 | { | 
 | 	pFormatProperties->linearTilingFeatures = 0; // Unsupported format | 
 | 	pFormatProperties->optimalTilingFeatures = 0; // Unsupported format | 
 | 	pFormatProperties->bufferFeatures = 0; // Unsupported format | 
 |  | 
 | 	switch(format)
 | 
 | 	{
 | 
 | 	case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
 | 
 | 	case VK_FORMAT_R5G6B5_UNORM_PACK16:
 | 
 | 	case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
 | 
 | 	case VK_FORMAT_R8_UNORM:
 | 
 | 	case VK_FORMAT_R8_SNORM:
 | 
 | 	case VK_FORMAT_R8G8_UNORM:
 | 
 | 	case VK_FORMAT_R8G8_SNORM:
 | 
 | 	case VK_FORMAT_R8G8B8A8_UNORM:
 | 
 | 	case VK_FORMAT_R8G8B8A8_SNORM:
 | 
 | 	case VK_FORMAT_R8G8B8A8_SRGB:
 | 
 | 	case VK_FORMAT_B8G8R8A8_UNORM:
 | 
 | 	case VK_FORMAT_B8G8R8A8_SRGB:
 | 
 | 	case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
 | 
 | 	case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
 | 
 | 	case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
 | 
 | 	case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
 | 
 | 	case VK_FORMAT_R16_SFLOAT:
 | 
 | 	case VK_FORMAT_R16G16_SFLOAT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_SFLOAT:
 | 
 | 	case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
 | 
 | 	case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
 | 
 | 		pFormatProperties->optimalTilingFeatures |=
 | 
 | 			VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
 | 
 | 		// Fall through
 | 
 | 	case VK_FORMAT_R8_UINT:
 | 
 | 	case VK_FORMAT_R8_SINT:
 | 
 | 	case VK_FORMAT_R8G8_UINT:
 | 
 | 	case VK_FORMAT_R8G8_SINT:
 | 
 | 	case VK_FORMAT_R8G8B8A8_UINT:
 | 
 | 	case VK_FORMAT_R8G8B8A8_SINT:
 | 
 | 	case VK_FORMAT_A8B8G8R8_UINT_PACK32:
 | 
 | 	case VK_FORMAT_A8B8G8R8_SINT_PACK32:
 | 
 | 	case VK_FORMAT_A2B10G10R10_UINT_PACK32:
 | 
 | 	case VK_FORMAT_R16_UINT:
 | 
 | 	case VK_FORMAT_R16_SINT:
 | 
 | 	case VK_FORMAT_R16G16_UINT:
 | 
 | 	case VK_FORMAT_R16G16_SINT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_UINT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_SINT:
 | 
 | 	case VK_FORMAT_R32_UINT:
 | 
 | 	case VK_FORMAT_R32_SINT:
 | 
 | 	case VK_FORMAT_R32_SFLOAT:
 | 
 | 	case VK_FORMAT_R32G32_UINT:
 | 
 | 	case VK_FORMAT_R32G32_SINT:
 | 
 | 	case VK_FORMAT_R32G32_SFLOAT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_UINT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_SINT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_SFLOAT:
 | 
 | 	case VK_FORMAT_D16_UNORM:
 | 
 | 	case VK_FORMAT_D32_SFLOAT:
 | 
 | 		pFormatProperties->optimalTilingFeatures |=
 | 
 | 			VK_FORMAT_FEATURE_BLIT_SRC_BIT |
 | 
 | 			VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
 | 
 | 			VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
 | 
 | 		// Fall through
 | 
 | 	case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
 | 
 | 	case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
 | 
 | 	case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
 | 
 | 	case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
 | 
 | 	case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
 | 
 | 	case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
 | 
 | 	case VK_FORMAT_EAC_R11_UNORM_BLOCK:
 | 
 | 	case VK_FORMAT_EAC_R11_SNORM_BLOCK:
 | 
 | 	case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
 | 
 | 	case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
 | 
 | 		pFormatProperties->optimalTilingFeatures |=
 | 
 | 			VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
 | 
 | 		break;
 | 
 | 	}
 | 
 | 
 | 
 | 	switch(format)
 | 
 | 	{
 | 
 | 	case VK_FORMAT_R32_UINT:
 | 
 | 	case VK_FORMAT_R32_SINT:
 | 
 | 		pFormatProperties->optimalTilingFeatures |=
 | 
 | 			VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
 | 
 | 		pFormatProperties->bufferFeatures |=
 | 
 | 			VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
 | 
 | 		// Fall through
 | 
 | 	case VK_FORMAT_R8G8B8A8_UNORM:
 | 
 | 	case VK_FORMAT_R8G8B8A8_SNORM:
 | 
 | 	case VK_FORMAT_R8G8B8A8_UINT:
 | 
 | 	case VK_FORMAT_R8G8B8A8_SINT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_UINT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_SINT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_SFLOAT:
 | 
 | 	case VK_FORMAT_R32_SFLOAT:
 | 
 | 	case VK_FORMAT_R32G32_UINT:
 | 
 | 	case VK_FORMAT_R32G32_SINT:
 | 
 | 	case VK_FORMAT_R32G32_SFLOAT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_UINT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_SINT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_SFLOAT:
 | 
 | 		pFormatProperties->optimalTilingFeatures |=
 | 
 | 			VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
 | 
 | 		// Fall through
 | 
 | 	case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
 | 
 | 	case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
 | 
 | 	case VK_FORMAT_A8B8G8R8_UINT_PACK32:
 | 
 | 	case VK_FORMAT_A8B8G8R8_SINT_PACK32:
 | 
 | 		pFormatProperties->bufferFeatures |=
 | 
 | 			VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
 | 
 | 		break;
 | 
 | 	}
 | 
 | 
 | 
 | 	switch(format)
 | 
 | 	{
 | 
 | 	case VK_FORMAT_R5G6B5_UNORM_PACK16:
 | 
 | 	case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
 | 
 | 	case VK_FORMAT_R8_UNORM:
 | 
 | 	case VK_FORMAT_R8G8_UNORM:
 | 
 | 	case VK_FORMAT_R8G8B8A8_UNORM:
 | 
 | 	case VK_FORMAT_R8G8B8A8_SRGB:
 | 
 | 	case VK_FORMAT_B8G8R8A8_UNORM:
 | 
 | 	case VK_FORMAT_B8G8R8A8_SRGB:
 | 
 | 	case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
 | 
 | 	case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
 | 
 | 	case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
 | 
 | 	case VK_FORMAT_R16_SFLOAT:
 | 
 | 	case VK_FORMAT_R16G16_SFLOAT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_SFLOAT:
 | 
 | 		pFormatProperties->optimalTilingFeatures |=
 | 
 | 			VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
 | 
 | 		// Fall through
 | 
 | 	case VK_FORMAT_R8_UINT:
 | 
 | 	case VK_FORMAT_R8_SINT:
 | 
 | 	case VK_FORMAT_R8G8_UINT:
 | 
 | 	case VK_FORMAT_R8G8_SINT:
 | 
 | 	case VK_FORMAT_R8G8B8A8_UINT:
 | 
 | 	case VK_FORMAT_R8G8B8A8_SINT:
 | 
 | 	case VK_FORMAT_A8B8G8R8_UINT_PACK32:
 | 
 | 	case VK_FORMAT_A8B8G8R8_SINT_PACK32:
 | 
 | 	case VK_FORMAT_A2B10G10R10_UINT_PACK32:
 | 
 | 	case VK_FORMAT_R16_UINT:
 | 
 | 	case VK_FORMAT_R16_SINT:
 | 
 | 	case VK_FORMAT_R16G16_UINT:
 | 
 | 	case VK_FORMAT_R16G16_SINT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_UINT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_SINT:
 | 
 | 	case VK_FORMAT_R32_UINT:
 | 
 | 	case VK_FORMAT_R32_SINT:
 | 
 | 	case VK_FORMAT_R32_SFLOAT:
 | 
 | 	case VK_FORMAT_R32G32_UINT:
 | 
 | 	case VK_FORMAT_R32G32_SINT:
 | 
 | 	case VK_FORMAT_R32G32_SFLOAT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_UINT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_SINT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_SFLOAT:
 | 
 | 		pFormatProperties->optimalTilingFeatures |=
 | 
 | 			VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
 | 
 | 			VK_FORMAT_FEATURE_BLIT_DST_BIT;
 | 
 | 		break;
 | 
 | 	case VK_FORMAT_D16_UNORM:
 | 
 | 	case VK_FORMAT_D32_SFLOAT: // Note: either VK_FORMAT_D32_SFLOAT or VK_FORMAT_X8_D24_UNORM_PACK32 must be supported
 | 
 | 	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
 | 
 | 		pFormatProperties->optimalTilingFeatures |=
 | 
 | 			VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
 | 
 | 		break;
 | 
 | 	}
 | 
 | 
 | 
 | 	switch(format) | 
 | 	{
 | 
 | 	case VK_FORMAT_R8_UNORM:
 | 
 | 	case VK_FORMAT_R8_SNORM:
 | 
 | 	case VK_FORMAT_R8_UINT:
 | 
 | 	case VK_FORMAT_R8_SINT:
 | 
 | 	case VK_FORMAT_R8G8_UNORM:
 | 
 | 	case VK_FORMAT_R8G8_SNORM:
 | 
 | 	case VK_FORMAT_R8G8_UINT:
 | 
 | 	case VK_FORMAT_R8G8_SINT:
 | 
 | 	case VK_FORMAT_R8G8B8A8_UNORM:
 | 
 | 	case VK_FORMAT_R8G8B8A8_SNORM:
 | 
 | 	case VK_FORMAT_R8G8B8A8_UINT:
 | 
 | 	case VK_FORMAT_R8G8B8A8_SINT:
 | 
 | 	case VK_FORMAT_B8G8R8A8_UNORM:
 | 
 | 	case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
 | 
 | 	case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
 | 
 | 	case VK_FORMAT_A8B8G8R8_UINT_PACK32:
 | 
 | 	case VK_FORMAT_A8B8G8R8_SINT_PACK32:
 | 
 | 	case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
 | 
 | 	case VK_FORMAT_R16_UNORM:
 | 
 | 	case VK_FORMAT_R16_SNORM:
 | 
 | 	case VK_FORMAT_R16_UINT:
 | 
 | 	case VK_FORMAT_R16_SINT:
 | 
 | 	case VK_FORMAT_R16_SFLOAT:
 | 
 | 	case VK_FORMAT_R16G16_UNORM:
 | 
 | 	case VK_FORMAT_R16G16_SNORM:
 | 
 | 	case VK_FORMAT_R16G16_UINT:
 | 
 | 	case VK_FORMAT_R16G16_SINT:
 | 
 | 	case VK_FORMAT_R16G16_SFLOAT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_UNORM:
 | 
 | 	case VK_FORMAT_R16G16B16A16_SNORM:
 | 
 | 	case VK_FORMAT_R16G16B16A16_UINT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_SINT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_SFLOAT:
 | 
 | 	case VK_FORMAT_R32_UINT:
 | 
 | 	case VK_FORMAT_R32_SINT:
 | 
 | 	case VK_FORMAT_R32_SFLOAT:
 | 
 | 	case VK_FORMAT_R32G32_UINT:
 | 
 | 	case VK_FORMAT_R32G32_SINT:
 | 
 | 	case VK_FORMAT_R32G32_SFLOAT:
 | 
 | 	case VK_FORMAT_R32G32B32_UINT:
 | 
 | 	case VK_FORMAT_R32G32B32_SINT:
 | 
 | 	case VK_FORMAT_R32G32B32_SFLOAT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_UINT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_SINT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_SFLOAT:
 | 
 | 		pFormatProperties->bufferFeatures |=
 | 
 | 			VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
 | 
 | 		break;
 | 
 | 	} | 
 | 
 | 
 | 	switch(format) | 
 | 	{
 | 
 | 	case VK_FORMAT_R8_UNORM:
 | 
 | 	case VK_FORMAT_R8_SNORM:
 | 
 | 	case VK_FORMAT_R8_UINT:
 | 
 | 	case VK_FORMAT_R8_SINT:
 | 
 | 	case VK_FORMAT_R8G8_UNORM:
 | 
 | 	case VK_FORMAT_R8G8_SNORM:
 | 
 | 	case VK_FORMAT_R8G8_UINT:
 | 
 | 	case VK_FORMAT_R8G8_SINT:
 | 
 | 	case VK_FORMAT_R8G8B8A8_UNORM:
 | 
 | 	case VK_FORMAT_R8G8B8A8_SNORM:
 | 
 | 	case VK_FORMAT_R8G8B8A8_UINT:
 | 
 | 	case VK_FORMAT_R8G8B8A8_SINT:
 | 
 | 	case VK_FORMAT_B8G8R8A8_UNORM:
 | 
 | 	case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
 | 
 | 	case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
 | 
 | 	case VK_FORMAT_A8B8G8R8_UINT_PACK32:
 | 
 | 	case VK_FORMAT_A8B8G8R8_SINT_PACK32:
 | 
 | 	case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
 | 
 | 	case VK_FORMAT_A2B10G10R10_UINT_PACK32:
 | 
 | 	case VK_FORMAT_R16_UINT:
 | 
 | 	case VK_FORMAT_R16_SINT:
 | 
 | 	case VK_FORMAT_R16_SFLOAT:
 | 
 | 	case VK_FORMAT_R16G16_UINT:
 | 
 | 	case VK_FORMAT_R16G16_SINT:
 | 
 | 	case VK_FORMAT_R16G16_SFLOAT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_UINT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_SINT:
 | 
 | 	case VK_FORMAT_R16G16B16A16_SFLOAT:
 | 
 | 	case VK_FORMAT_R32_UINT:
 | 
 | 	case VK_FORMAT_R32_SINT:
 | 
 | 	case VK_FORMAT_R32_SFLOAT:
 | 
 | 	case VK_FORMAT_R32G32_UINT:
 | 
 | 	case VK_FORMAT_R32G32_SINT:
 | 
 | 	case VK_FORMAT_R32G32_SFLOAT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_UINT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_SINT:
 | 
 | 	case VK_FORMAT_R32G32B32A32_SFLOAT:
 | 
 | 	case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
 | 
 | 		pFormatProperties->bufferFeatures |=
 | 
 | 			VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;
 | 
 | 		break;
 | 
 | 	} | 
 | } | 
 |  | 
 | void PhysicalDevice::getImageFormatProperties(VkFormat format, VkImageType type, VkImageTiling tiling, | 
 |                                               VkImageUsageFlags usage, VkImageCreateFlags flags, | 
 | 	                                          VkImageFormatProperties* pImageFormatProperties) const | 
 | { | 
 | 	pImageFormatProperties->maxArrayLayers = 1 << vk::MAX_IMAGE_ARRAY_LAYERS; | 
 |  | 
 | 	switch(type) | 
 | 	{ | 
 | 	case VK_IMAGE_TYPE_1D: | 
 | 		pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_1D; | 
 | 		pImageFormatProperties->maxExtent.width = 1 << vk::MAX_IMAGE_LEVELS_1D; | 
 | 		pImageFormatProperties->maxExtent.height = 1; | 
 | 		pImageFormatProperties->maxExtent.depth = 1; | 
 | 		break; | 
 | 	case VK_IMAGE_TYPE_2D: | 
 | 		if(flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) | 
 | 		{ | 
 | 			pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_CUBE; | 
 | 			pImageFormatProperties->maxExtent.width = 1 << vk::MAX_IMAGE_LEVELS_CUBE; | 
 | 			pImageFormatProperties->maxExtent.height = 1 << vk::MAX_IMAGE_LEVELS_CUBE; | 
 | 			pImageFormatProperties->maxExtent.depth = 1; | 
 | 		} | 
 | 		else | 
 | 		{ | 
 | 			pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_2D; | 
 | 			pImageFormatProperties->maxExtent.width = 1 << vk::MAX_IMAGE_LEVELS_2D; | 
 | 			pImageFormatProperties->maxExtent.height = 1 << vk::MAX_IMAGE_LEVELS_2D; | 
 | 			pImageFormatProperties->maxExtent.depth = 1; | 
 | 		} | 
 | 		break; | 
 | 	case VK_IMAGE_TYPE_3D: | 
 | 		pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_3D; | 
 | 		pImageFormatProperties->maxExtent.width = 1 << vk::MAX_IMAGE_LEVELS_3D; | 
 | 		pImageFormatProperties->maxExtent.height = 1 << vk::MAX_IMAGE_LEVELS_3D; | 
 | 		pImageFormatProperties->maxExtent.depth = 1 << vk::MAX_IMAGE_LEVELS_3D; | 
 | 		break; | 
 | 	default: | 
 | 		UNREACHABLE(type); | 
 | 		break; | 
 | 	} | 
 |  | 
 | 	pImageFormatProperties->maxResourceSize = 1 << 31; // Minimum value for maxResourceSize | 
 | 	pImageFormatProperties->sampleCounts = getSampleCounts(); | 
 |  | 
 | } | 
 |  | 
 | uint32_t PhysicalDevice::getQueueFamilyPropertyCount() const | 
 | { | 
 | 	return 1; | 
 | } | 
 |  | 
 | void PhysicalDevice::getQueueFamilyProperties(uint32_t pQueueFamilyPropertyCount, | 
 |                                               VkQueueFamilyProperties* pQueueFamilyProperties) const | 
 | { | 
 | 	for(uint32_t i = 0; i < pQueueFamilyPropertyCount; i++) | 
 | 	{ | 
 | 		pQueueFamilyProperties[i].minImageTransferGranularity.width = 1; | 
 | 		pQueueFamilyProperties[i].minImageTransferGranularity.height = 1; | 
 | 		pQueueFamilyProperties[i].minImageTransferGranularity.depth = 1; | 
 | 		pQueueFamilyProperties[i].queueCount = 1; | 
 | 		pQueueFamilyProperties[i].queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT; | 
 | 		pQueueFamilyProperties[i].timestampValidBits = 0; // No support for time stamps | 
 | 	} | 
 | } | 
 |  | 
 | const VkPhysicalDeviceMemoryProperties& PhysicalDevice::getMemoryProperties() const | 
 | { | 
 | 	static const VkPhysicalDeviceMemoryProperties properties | 
 | 	{ | 
 | 		1, // memoryTypeCount | 
 | 		{ | 
 | 			// vk::MEMORY_TYPE_GENERIC_BIT | 
 | 			{ | 
 | 				VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | | 
 | 				VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | | 
 | 				VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | | 
 | 				VK_MEMORY_PROPERTY_HOST_CACHED_BIT, // propertyFlags | 
 | 				0 // heapIndex | 
 | 			}, | 
 | 		}, | 
 | 		1, // memoryHeapCount | 
 | 		{ | 
 | 			{ | 
 | 				1ull << 31, // size, FIXME(sugoi): This should be configurable based on available RAM | 
 | 				VK_MEMORY_HEAP_DEVICE_LOCAL_BIT // flags | 
 | 			}, | 
 | 		} | 
 | 	}; | 
 |  | 
 | 	return properties; | 
 | } | 
 |  | 
 | } // namespace vk |