/* ** Copyright (c) 2015-2018, 2023 The Khronos Group Inc. ** ** 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. */ #pragma once #include #include #include #include #include #include #include #include #include #include "vk_video/vulkan_video_codecs_common.h" #include "vk_video/vulkan_video_codec_h264std.h" #include "vk_video/vulkan_video_codec_h264std_decode.h" #include "vk_video/vulkan_video_codec_h264std_encode.h" #include "vk_video/vulkan_video_codec_h265std.h" #include "vk_video/vulkan_video_codec_h265std_decode.h" #include "vk_video/vulkan_video_codec_h265std_encode.h" #include "vulkan/vulkan.h" #include "vulkan/vk_icd.h" #include "vk_typemap_helper.h" namespace vkmock { using mutex_t = std::mutex; using lock_guard_t = std::lock_guard; using unique_lock_t = std::unique_lock; static mutex_t global_lock; static uint64_t global_unique_handle = 1; static const uint32_t SUPPORTED_LOADER_ICD_INTERFACE_VERSION = 5; static uint32_t loader_interface_version = 0; static bool negotiate_loader_icd_interface_called = false; static void* CreateDispObjHandle() { auto handle = new VK_LOADER_DATA; set_loader_magic_value(handle); return handle; } static void DestroyDispObjHandle(void* handle) { delete reinterpret_cast(handle); } static constexpr uint32_t icd_physical_device_count = 1; static std::unordered_map> physical_device_map; static std::unordered_map> display_map; // Map device memory handle to any mapped allocations that we'll need to free on unmap static std::unordered_map> mapped_memory_map; // Map device memory allocation handle to the size static std::unordered_map allocated_memory_size_map; static std::unordered_map>> queue_map; static VkDeviceAddress current_available_address = 0x10000000; struct BufferState { VkDeviceSize size; VkDeviceAddress address; }; static std::unordered_map> buffer_map; static std::unordered_map> image_memory_size_map; static std::unordered_map> command_pool_map; static std::unordered_map> command_pool_buffer_map; static constexpr uint32_t icd_swapchain_image_count = 1; static std::unordered_map swapchain_image_map; // TODO: Would like to codegen this but limits aren't in XML static VkPhysicalDeviceLimits SetLimits(VkPhysicalDeviceLimits* limits) { limits->maxImageDimension1D = 4096; limits->maxImageDimension2D = 4096; limits->maxImageDimension3D = 256; limits->maxImageDimensionCube = 4096; limits->maxImageArrayLayers = 256; limits->maxTexelBufferElements = 65536; limits->maxUniformBufferRange = 16384; limits->maxStorageBufferRange = 134217728; limits->maxPushConstantsSize = 128; limits->maxMemoryAllocationCount = 4096; limits->maxSamplerAllocationCount = 4000; limits->bufferImageGranularity = 1; limits->sparseAddressSpaceSize = 2147483648; limits->maxBoundDescriptorSets = 4; limits->maxPerStageDescriptorSamplers = 16; limits->maxPerStageDescriptorUniformBuffers = 12; limits->maxPerStageDescriptorStorageBuffers = 4; limits->maxPerStageDescriptorSampledImages = 16; limits->maxPerStageDescriptorStorageImages = 4; limits->maxPerStageDescriptorInputAttachments = 4; limits->maxPerStageResources = 128; limits->maxDescriptorSetSamplers = 96; limits->maxDescriptorSetUniformBuffers = 72; limits->maxDescriptorSetUniformBuffersDynamic = 8; limits->maxDescriptorSetStorageBuffers = 24; limits->maxDescriptorSetStorageBuffersDynamic = 4; limits->maxDescriptorSetSampledImages = 96; limits->maxDescriptorSetStorageImages = 24; limits->maxDescriptorSetInputAttachments = 4; limits->maxVertexInputAttributes = 16; limits->maxVertexInputBindings = 16; limits->maxVertexInputAttributeOffset = 2047; limits->maxVertexInputBindingStride = 2048; limits->maxVertexOutputComponents = 64; limits->maxTessellationGenerationLevel = 64; limits->maxTessellationPatchSize = 32; limits->maxTessellationControlPerVertexInputComponents = 64; limits->maxTessellationControlPerVertexOutputComponents = 64; limits->maxTessellationControlPerPatchOutputComponents = 120; limits->maxTessellationControlTotalOutputComponents = 2048; limits->maxTessellationEvaluationInputComponents = 64; limits->maxTessellationEvaluationOutputComponents = 64; limits->maxGeometryShaderInvocations = 32; limits->maxGeometryInputComponents = 64; limits->maxGeometryOutputComponents = 64; limits->maxGeometryOutputVertices = 256; limits->maxGeometryTotalOutputComponents = 1024; limits->maxFragmentInputComponents = 64; limits->maxFragmentOutputAttachments = 4; limits->maxFragmentDualSrcAttachments = 1; limits->maxFragmentCombinedOutputResources = 4; limits->maxComputeSharedMemorySize = 16384; limits->maxComputeWorkGroupCount[0] = 65535; limits->maxComputeWorkGroupCount[1] = 65535; limits->maxComputeWorkGroupCount[2] = 65535; limits->maxComputeWorkGroupInvocations = 128; limits->maxComputeWorkGroupSize[0] = 128; limits->maxComputeWorkGroupSize[1] = 128; limits->maxComputeWorkGroupSize[2] = 64; limits->subPixelPrecisionBits = 4; limits->subTexelPrecisionBits = 4; limits->mipmapPrecisionBits = 4; limits->maxDrawIndexedIndexValue = UINT32_MAX; limits->maxDrawIndirectCount = UINT16_MAX; limits->maxSamplerLodBias = 2.0f; limits->maxSamplerAnisotropy = 16; limits->maxViewports = 16; limits->maxViewportDimensions[0] = 4096; limits->maxViewportDimensions[1] = 4096; limits->viewportBoundsRange[0] = -8192; limits->viewportBoundsRange[1] = 8191; limits->viewportSubPixelBits = 0; limits->minMemoryMapAlignment = 64; limits->minTexelBufferOffsetAlignment = 16; limits->minUniformBufferOffsetAlignment = 16; limits->minStorageBufferOffsetAlignment = 16; limits->minTexelOffset = -8; limits->maxTexelOffset = 7; limits->minTexelGatherOffset = -8; limits->maxTexelGatherOffset = 7; limits->minInterpolationOffset = 0.0f; limits->maxInterpolationOffset = 0.5f; limits->subPixelInterpolationOffsetBits = 4; limits->maxFramebufferWidth = 4096; limits->maxFramebufferHeight = 4096; limits->maxFramebufferLayers = 256; limits->framebufferColorSampleCounts = 0x7F; limits->framebufferDepthSampleCounts = 0x7F; limits->framebufferStencilSampleCounts = 0x7F; limits->framebufferNoAttachmentsSampleCounts = 0x7F; limits->maxColorAttachments = 4; limits->sampledImageColorSampleCounts = 0x7F; limits->sampledImageIntegerSampleCounts = 0x7F; limits->sampledImageDepthSampleCounts = 0x7F; limits->sampledImageStencilSampleCounts = 0x7F; limits->storageImageSampleCounts = 0x7F; limits->maxSampleMaskWords = 1; limits->timestampComputeAndGraphics = VK_TRUE; limits->timestampPeriod = 1; limits->maxClipDistances = 8; limits->maxCullDistances = 8; limits->maxCombinedClipAndCullDistances = 8; limits->discreteQueuePriorities = 2; limits->pointSizeRange[0] = 1.0f; limits->pointSizeRange[1] = 64.0f; limits->lineWidthRange[0] = 1.0f; limits->lineWidthRange[1] = 8.0f; limits->pointSizeGranularity = 1.0f; limits->lineWidthGranularity = 1.0f; limits->strictLines = VK_TRUE; limits->standardSampleLocations = VK_TRUE; limits->optimalBufferCopyOffsetAlignment = 1; limits->optimalBufferCopyRowPitchAlignment = 1; limits->nonCoherentAtomSize = 256; return *limits; } void SetBoolArrayTrue(VkBool32* bool_array, uint32_t num_bools) { for (uint32_t i = 0; i < num_bools; ++i) { bool_array[i] = VK_TRUE; } } VkDeviceSize GetImageSizeFromCreateInfo(const VkImageCreateInfo* pCreateInfo) { VkDeviceSize size = pCreateInfo->extent.width; size *= pCreateInfo->extent.height; size *= pCreateInfo->extent.depth; // TODO: A pixel size is 32 bytes. This accounts for the largest possible pixel size of any format. It could be changed to more // accurate size if need be. size *= 32; size *= pCreateInfo->arrayLayers; size *= (pCreateInfo->mipLevels > 1 ? 2 : 1); switch (pCreateInfo->format) { case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: size *= 3; break; case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: size *= 2; break; default: break; } return size; } } // namespace vkmock