#include "libANGLE/renderer/vulkan/vk_renderer.h"
#include "libANGLE/renderer/vulkan/vk_utils.h"
#include <EGL/eglext.h>
#include <fstream>
#include "common/debug.h"
#include "common/platform.h"
#include "common/system_utils.h"
#include "common/vulkan/libvulkan_loader.h"
#include "common/vulkan/vulkan_icd.h"
#include "gpu_info_util/SystemInfo.h"
#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/driver_utils.h"
#include "libANGLE/renderer/vulkan/CompilerVk.h"
#include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h"
#include "libANGLE/renderer/vulkan/ProgramVk.h"
#include "libANGLE/renderer/vulkan/SyncVk.h"
#include "libANGLE/renderer/vulkan/VertexArrayVk.h"
#include "libANGLE/renderer/vulkan/vk_caps_utils.h"
#include "libANGLE/renderer/vulkan/vk_format_utils.h"
#include "libANGLE/renderer/vulkan/vk_resource.h"
#include "libANGLE/trace.h"
#include "platform/PlatformMethods.h"
namespace
{
#if defined(ANGLE_PLATFORM_ANDROID)
constexpr const char *kDefaultPipelineCacheGraphDumpPath = "/data/local/tmp/angle_dumps/";
#else
constexpr const char *kDefaultPipelineCacheGraphDumpPath = …;
#endif
constexpr VkFormatFeatureFlags kInvalidFormatFeatureFlags = …;
#if defined(ANGLE_EXPOSE_NON_CONFORMANT_EXTENSIONS_AND_VERSIONS)
constexpr bool kExposeNonConformantExtensionsAndVersions = true;
#else
constexpr bool kExposeNonConformantExtensionsAndVersions = …;
#endif
#if defined(ANGLE_ENABLE_CRC_FOR_PIPELINE_CACHE)
constexpr bool kEnableCRCForPipelineCache = …;
#else
constexpr bool kEnableCRCForPipelineCache = false;
#endif
#if defined(ANGLE_ENABLE_VULKAN_API_DUMP_LAYER)
constexpr bool kEnableVulkanAPIDumpLayer = true;
#else
constexpr bool kEnableVulkanAPIDumpLayer = …;
#endif
}
namespace rx
{
namespace vk
{
namespace
{
constexpr uint32_t kMinDefaultUniformBufferSize = …;
constexpr uint32_t kPreferredDefaultUniformBufferSize = …;
constexpr size_t kImageSizeThresholdForDedicatedMemoryAllocation = …;
constexpr uint32_t kPipelineCacheVersion = …;
constexpr uint32_t kPipelineCacheVkUpdatePeriod = …;
constexpr uint32_t kPreferredVulkanAPIVersion = …;
bool IsVulkan11(uint32_t apiVersion)
{ … }
bool IsRADV(uint32_t vendorId, uint32_t driverId, const char *deviceName)
{ … }
bool IsQualcommOpenSource(uint32_t vendorId, uint32_t driverId, const char *deviceName)
{ … }
bool IsXclipse()
{ … }
bool StrLess(const char *a, const char *b)
{ … }
bool ExtensionFound(const char *needle, const vk::ExtensionNameList &haystack)
{ … }
VkResult VerifyExtensionsPresent(const vk::ExtensionNameList &haystack,
const vk::ExtensionNameList &needles)
{ … }
constexpr const char *kSkippedMessages[] = …;
constexpr const char *kNoListRestartSkippedMessages[] = …;
constexpr const char *kSkippedMessagesWithVulkanSecondaryCommandBuffer[] = …;
constexpr const char *kSkippedMessagesWithRenderPassObjectsAndVulkanSCB[] = …;
constexpr const char *kSkippedMessagesWithDynamicRendering[] = …;
constexpr vk::SkippedSyncvalMessage kSkippedSyncvalMessages[] = …;
constexpr vk::SkippedSyncvalMessage kSkippedSyncvalMessagesWithoutStoreOpNone[] = …;
constexpr vk::SkippedSyncvalMessage kSkippedSyncvalMessagesWithoutLoadStoreOpNone[] = …;
constexpr vk::SkippedSyncvalMessage kSkippedSyncvalMessagesWithMSRTTEmulation[] = …;
enum class DebugMessageReport
{ … };
bool IsMessageInSkipList(const char *message,
const char *const skippedList[],
size_t skippedListSize)
{ … }
DebugMessageReport ShouldReportDebugMessage(Renderer *renderer,
const char *messageId,
const char *message)
{ … }
const char *GetVkObjectTypeName(VkObjectType type)
{ … }
VKAPI_ATTR VkBool32 VKAPI_CALL
DebugUtilsMessenger(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT *callbackData,
void *userData)
{ … }
VKAPI_ATTR void VKAPI_CALL
MemoryReportCallback(const VkDeviceMemoryReportCallbackDataEXT *callbackData, void *userData)
{ … }
gl::Version LimitVersionTo(const gl::Version ¤t, const gl::Version &lower)
{ … }
[[maybe_unused]] bool FencePropertiesCompatibleWithAndroid(
const VkExternalFenceProperties &externalFenceProperties)
{ … }
[[maybe_unused]] bool SemaphorePropertiesCompatibleWithAndroid(
const VkExternalSemaphoreProperties &externalSemaphoreProperties)
{ … }
uint32_t GetMemoryTypeBitsExcludingHostVisible(Renderer *renderer,
VkMemoryPropertyFlags propertyFlags,
uint32_t availableMemoryTypeBits)
{ … }
ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
class CacheDataHeader
{ … };
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
void PackHeaderDataForPipelineCache(uint32_t compressedDataCRC,
uint32_t cacheDataSize,
uint16_t numChunks,
uint16_t chunkIndex,
CacheDataHeader *dataOut)
{ … }
void UnpackHeaderDataForPipelineCache(CacheDataHeader *data,
uint32_t *versionOut,
uint32_t *compressedDataCRCOut,
uint32_t *cacheDataSizeOut,
size_t *numChunksOut,
size_t *chunkIndexOut)
{ … }
void ComputePipelineCacheVkChunkKey(VkPhysicalDeviceProperties physicalDeviceProperties,
const uint8_t chunkIndex,
angle::BlobCacheKey *hashOut)
{ … }
void CompressAndStorePipelineCacheVk(VkPhysicalDeviceProperties physicalDeviceProperties,
vk::GlobalOps *globalOps,
const std::vector<uint8_t> &cacheData,
const size_t maxTotalSize)
{ … }
class CompressAndStorePipelineCacheTask : public angle::Closure
{ … };
angle::Result GetAndDecompressPipelineCacheVk(VkPhysicalDeviceProperties physicalDeviceProperties,
vk::Context *context,
vk::GlobalOps *globalOps,
angle::MemoryBuffer *uncompressedData,
bool *success)
{ … }
constexpr char kEnableDebugMarkersVarName[] = …;
constexpr char kEnableDebugMarkersPropertyName[] = …;
ANGLE_INLINE gl::ShadingRate GetShadingRateFromVkExtent(const VkExtent2D &extent)
{ … }
void DumpPipelineCacheGraph(Renderer *renderer, const std::ostringstream &graph)
{ … }
bool CanSupportMSRTSSForRGBA8(Renderer *renderer)
{ … }
}
OneOffCommandPool::OneOffCommandPool() : … { … }
void OneOffCommandPool::init(vk::ProtectionType protectionType)
{ … }
void OneOffCommandPool::destroy(VkDevice device)
{ … }
angle::Result OneOffCommandPool::getCommandBuffer(vk::Context *context,
vk::PrimaryCommandBuffer *commandBufferOut)
{ … }
void OneOffCommandPool::releaseCommandBuffer(const QueueSerial &submitQueueSerial,
vk::PrimaryCommandBuffer &&primary)
{ … }
Renderer::Renderer()
: … { … }
Renderer::~Renderer() { … }
bool Renderer::hasSharedGarbage()
{ … }
void Renderer::onDestroy(vk::Context *context)
{ … }
void Renderer::notifyDeviceLost()
{ … }
bool Renderer::isDeviceLost() const
{ … }
angle::Result Renderer::enableInstanceExtensions(vk::Context *context,
const VulkanLayerVector &enabledInstanceLayerNames,
const char *wsiExtension,
UseVulkanSwapchain useVulkanSwapchain,
bool canLoadDebugUtils)
{ … }
angle::Result Renderer::initialize(vk::Context *context,
vk::GlobalOps *globalOps,
angle::vk::ICD desiredICD,
uint32_t preferredVendorId,
uint32_t preferredDeviceId,
UseDebugLayers useDebugLayers,
const char *wsiExtension,
const char *wsiLayer,
angle::NativeWindowSystem nativeWindowSystem,
const angle::FeatureOverrides &featureOverrides)
{ … }
angle::Result Renderer::initializeMemoryAllocator(vk::Context *context)
{ … }
void Renderer::appendDeviceExtensionFeaturesNotPromoted(
const vk::ExtensionNameList &deviceExtensionNames,
VkPhysicalDeviceFeatures2KHR *deviceFeatures,
VkPhysicalDeviceProperties2 *deviceProperties)
{ … }
void Renderer::appendDeviceExtensionFeaturesPromotedTo11(
const vk::ExtensionNameList &deviceExtensionNames,
VkPhysicalDeviceFeatures2KHR *deviceFeatures,
VkPhysicalDeviceProperties2 *deviceProperties)
{ … }
void Renderer::appendDeviceExtensionFeaturesPromotedTo12(
const vk::ExtensionNameList &deviceExtensionNames,
VkPhysicalDeviceFeatures2KHR *deviceFeatures,
VkPhysicalDeviceProperties2 *deviceProperties)
{ … }
void Renderer::appendDeviceExtensionFeaturesPromotedTo13(
const vk::ExtensionNameList &deviceExtensionNames,
VkPhysicalDeviceFeatures2KHR *deviceFeatures,
VkPhysicalDeviceProperties2 *deviceProperties)
{ … }
void Renderer::queryDeviceExtensionFeatures(const vk::ExtensionNameList &deviceExtensionNames)
{ … }
void Renderer::enableDeviceExtensionsNotPromoted(const vk::ExtensionNameList &deviceExtensionNames)
{ … }
void Renderer::enableDeviceExtensionsPromotedTo11(const vk::ExtensionNameList &deviceExtensionNames)
{ … }
void Renderer::enableDeviceExtensionsPromotedTo12(const vk::ExtensionNameList &deviceExtensionNames)
{ … }
void Renderer::enableDeviceExtensionsPromotedTo13(const vk::ExtensionNameList &deviceExtensionNames)
{ … }
angle::Result Renderer::enableDeviceExtensions(vk::Context *context,
const angle::FeatureOverrides &featureOverrides,
UseVulkanSwapchain useVulkanSwapchain,
angle::NativeWindowSystem nativeWindowSystem)
{ … }
void Renderer::initInstanceExtensionEntryPoints()
{ … }
void Renderer::initDeviceExtensionEntryPoints()
{ … }
angle::Result Renderer::setupDevice(vk::Context *context,
const angle::FeatureOverrides &featureOverrides,
const char *wsiLayer,
UseVulkanSwapchain useVulkanSwapchain,
angle::NativeWindowSystem nativeWindowSystem)
{ … }
angle::Result Renderer::createDeviceAndQueue(vk::Context *context, uint32_t queueFamilyIndex)
{ … }
void Renderer::calculatePendingGarbageSizeLimit()
{ … }
void Renderer::initializeValidationMessageSuppressions()
{ … }
angle::Result Renderer::checkQueueForSurfacePresent(vk::Context *context,
VkSurfaceKHR surface,
bool *supportedOut)
{ … }
std::string Renderer::getVendorString() const
{ … }
std::string Renderer::getRendererDescription() const
{ … }
std::string Renderer::getVersionString(bool includeFullVersion) const
{ … }
gl::Version Renderer::getMaxSupportedESVersion() const
{ … }
gl::Version Renderer::getMaxConformantESVersion() const
{ … }
uint32_t Renderer::getDeviceVersion()
{ … }
void Renderer::queryAndCacheFragmentShadingRates()
{ … }
bool Renderer::canSupportFragmentShadingRate() const
{ … }
bool Renderer::canSupportFoveatedRendering() const
{ … }
bool Renderer::canPreferDeviceLocalMemoryHostVisible(VkPhysicalDeviceType deviceType)
{ … }
void Renderer::initFeatures(const vk::ExtensionNameList &deviceExtensionNames,
const angle::FeatureOverrides &featureOverrides,
UseVulkanSwapchain useVulkanSwapchain,
angle::NativeWindowSystem nativeWindowSystem)
{ … }
void Renderer::appBasedFeatureOverrides(const vk::ExtensionNameList &extensions) { … }
angle::Result Renderer::initPipelineCache(vk::Context *context,
vk::PipelineCache *pipelineCache,
bool *success)
{ … }
angle::Result Renderer::ensurePipelineCacheInitialized(vk::Context *context)
{ … }
angle::Result Renderer::getPipelineCache(vk::Context *context,
vk::PipelineCacheAccess *pipelineCacheOut)
{ … }
angle::Result Renderer::mergeIntoPipelineCache(vk::Context *context,
const vk::PipelineCache &pipelineCache)
{ … }
const gl::Caps &Renderer::getNativeCaps() const
{ … }
const gl::TextureCapsMap &Renderer::getNativeTextureCaps() const
{ … }
const gl::Extensions &Renderer::getNativeExtensions() const
{ … }
const gl::Limitations &Renderer::getNativeLimitations() const
{ … }
const ShPixelLocalStorageOptions &Renderer::getNativePixelLocalStorageOptions() const
{ … }
void Renderer::initializeFrontendFeatures(angle::FrontendFeatures *features) const
{ … }
angle::Result Renderer::getPipelineCacheSize(vk::Context *context, size_t *pipelineCacheSizeOut)
{ … }
angle::Result Renderer::syncPipelineCacheVk(vk::Context *context,
vk::GlobalOps *globalOps,
const gl::Context *contextGL)
{ … }
bool Renderer::hasLinearImageFormatFeatureBits(angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const
{ … }
VkFormatFeatureFlags Renderer::getLinearImageFormatFeatureBits(
angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const
{ … }
VkFormatFeatureFlags Renderer::getImageFormatFeatureBits(
angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const
{ … }
bool Renderer::hasImageFormatFeatureBits(angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const
{ … }
bool Renderer::hasBufferFormatFeatureBits(angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const
{ … }
void Renderer::outputVmaStatString()
{ … }
angle::Result Renderer::queueSubmitOneOff(vk::Context *context,
vk::PrimaryCommandBuffer &&primary,
vk::ProtectionType protectionType,
egl::ContextPriority priority,
VkSemaphore waitSemaphore,
VkPipelineStageFlags waitSemaphoreStageMasks,
vk::SubmitPolicy submitPolicy,
QueueSerial *queueSerialOut)
{ … }
angle::Result Renderer::queueSubmitWaitSemaphore(vk::Context *context,
egl::ContextPriority priority,
const vk::Semaphore &waitSemaphore,
VkPipelineStageFlags waitSemaphoreStageMasks,
QueueSerial submitQueueSerial)
{ … }
template <VkFormatFeatureFlags VkFormatProperties::*features>
VkFormatFeatureFlags Renderer::getFormatFeatureBits(angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const
{ … }
template <VkFormatFeatureFlags VkFormatProperties::*features>
bool Renderer::hasFormatFeatureBits(angle::FormatID formatID,
const VkFormatFeatureFlags featureBits) const
{ … }
bool Renderer::haveSameFormatFeatureBits(angle::FormatID formatID1, angle::FormatID formatID2) const
{ … }
void Renderer::cleanupGarbage()
{ … }
void Renderer::cleanupPendingSubmissionGarbage()
{ … }
void Renderer::onNewValidationMessage(const std::string &message)
{ … }
void Renderer::onFramebufferFetchUsed()
{ … }
std::string Renderer::getAndClearLastValidationMessage(uint32_t *countSinceLastClear)
{ … }
uint64_t Renderer::getMaxFenceWaitTimeNs() const
{ … }
void Renderer::setGlobalDebugAnnotator(bool *installedAnnotatorOut)
{ … }
void Renderer::reloadVolkIfNeeded() const
{ … }
void Renderer::initializeInstanceExtensionEntryPointsFromCore() const
{ … }
void Renderer::initializeDeviceExtensionEntryPointsFromCore() const
{ … }
angle::Result Renderer::submitCommands(vk::Context *context,
vk::ProtectionType protectionType,
egl::ContextPriority contextPriority,
const vk::Semaphore *signalSemaphore,
const vk::SharedExternalFence *externalFence,
const QueueSerial &submitQueueSerial)
{ … }
angle::Result Renderer::submitPriorityDependency(vk::Context *context,
vk::ProtectionTypes protectionTypes,
egl::ContextPriority srcContextPriority,
egl::ContextPriority dstContextPriority,
SerialIndex index)
{ … }
void Renderer::handleDeviceLost()
{ … }
angle::Result Renderer::finishResourceUse(vk::Context *context, const vk::ResourceUse &use)
{ … }
angle::Result Renderer::finishQueueSerial(vk::Context *context, const QueueSerial &queueSerial)
{ … }
angle::Result Renderer::waitForResourceUseToFinishWithUserTimeout(vk::Context *context,
const vk::ResourceUse &use,
uint64_t timeout,
VkResult *result)
{ … }
angle::Result Renderer::flushWaitSemaphores(
vk::ProtectionType protectionType,
egl::ContextPriority priority,
std::vector<VkSemaphore> &&waitSemaphores,
std::vector<VkPipelineStageFlags> &&waitSemaphoreStageMasks)
{ … }
angle::Result Renderer::flushRenderPassCommands(
vk::Context *context,
vk::ProtectionType protectionType,
egl::ContextPriority priority,
const vk::RenderPass &renderPass,
VkFramebuffer framebufferOverride,
vk::RenderPassCommandBufferHelper **renderPassCommands)
{ … }
angle::Result Renderer::flushOutsideRPCommands(
vk::Context *context,
vk::ProtectionType protectionType,
egl::ContextPriority priority,
vk::OutsideRenderPassCommandBufferHelper **outsideRPCommands)
{ … }
void Renderer::queuePresent(vk::Context *context,
egl::ContextPriority priority,
const VkPresentInfoKHR &presentInfo,
vk::SwapchainStatus *swapchainStatus)
{ … }
template <typename CommandBufferHelperT, typename RecyclerT>
angle::Result Renderer::getCommandBufferImpl(vk::Context *context,
vk::SecondaryCommandPool *commandPool,
vk::SecondaryCommandMemoryAllocator *commandsAllocator,
RecyclerT *recycler,
CommandBufferHelperT **commandBufferHelperOut)
{ … }
angle::Result Renderer::getOutsideRenderPassCommandBufferHelper(
vk::Context *context,
vk::SecondaryCommandPool *commandPool,
vk::SecondaryCommandMemoryAllocator *commandsAllocator,
vk::OutsideRenderPassCommandBufferHelper **commandBufferHelperOut)
{ … }
angle::Result Renderer::getRenderPassCommandBufferHelper(
vk::Context *context,
vk::SecondaryCommandPool *commandPool,
vk::SecondaryCommandMemoryAllocator *commandsAllocator,
vk::RenderPassCommandBufferHelper **commandBufferHelperOut)
{ … }
void Renderer::recycleOutsideRenderPassCommandBufferHelper(
vk::OutsideRenderPassCommandBufferHelper **commandBuffer)
{ … }
void Renderer::recycleRenderPassCommandBufferHelper(
vk::RenderPassCommandBufferHelper **commandBuffer)
{ … }
void Renderer::logCacheStats() const
{ … }
angle::Result Renderer::getFormatDescriptorCountForVkFormat(vk::Context *context,
VkFormat format,
uint32_t *descriptorCountOut)
{ … }
angle::Result Renderer::getFormatDescriptorCountForExternalFormat(vk::Context *context,
uint64_t format,
uint32_t *descriptorCountOut)
{ … }
void Renderer::onAllocateHandle(vk::HandleType handleType)
{ … }
void Renderer::onDeallocateHandle(vk::HandleType handleType)
{ … }
VkDeviceSize Renderer::getPreferedBufferBlockSize(uint32_t memoryTypeIndex) const
{ … }
angle::Result Renderer::allocateScopedQueueSerialIndex(vk::ScopedQueueSerialIndex *indexOut)
{ … }
angle::Result Renderer::allocateQueueSerialIndex(SerialIndex *serialIndexOut)
{ … }
void Renderer::releaseQueueSerialIndex(SerialIndex index)
{ … }
angle::Result Renderer::finishOneCommandBatchAndCleanup(vk::Context *context, bool *anyBatchCleaned)
{ … }
const char *Renderer::GetVulkanObjectTypeName(VkObjectType type)
{ … }
ImageMemorySuballocator::ImageMemorySuballocator() { … }
ImageMemorySuballocator::~ImageMemorySuballocator() { … }
void ImageMemorySuballocator::destroy(Renderer *renderer) { … }
VkResult ImageMemorySuballocator::allocateAndBindMemory(
Context *context,
Image *image,
const VkImageCreateInfo *imageCreateInfo,
VkMemoryPropertyFlags requiredFlags,
VkMemoryPropertyFlags preferredFlags,
const VkMemoryRequirements *memoryRequirements,
const bool allocateDedicatedMemory,
MemoryAllocationType memoryAllocationType,
Allocation *allocationOut,
VkMemoryPropertyFlags *memoryFlagsOut,
uint32_t *memoryTypeIndexOut,
VkDeviceSize *sizeOut)
{ … }
VkResult ImageMemorySuballocator::mapMemoryAndInitWithNonZeroValue(Renderer *renderer,
Allocation *allocation,
VkDeviceSize size,
int value,
VkMemoryPropertyFlags flags)
{ … }
bool ImageMemorySuballocator::needsDedicatedMemory(VkDeviceSize size) const
{ … }
}
}