| /* | |
| * Copyright 2022 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #ifndef skgpu_VulkanTypes_DEFINED | |
| #define skgpu_VulkanTypes_DEFINED | |
| #include "include/core/SkTypes.h" | |
| #include "include/private/SkTo.h" | |
| #include "include/private/gpu/vk/SkiaVulkan.h" | |
| #include <cstddef> | |
| #include <cstdint> | |
| #include <functional> | |
| #include <optional> | |
| #include <string> | |
| #include <vector> | |
| #ifndef VK_VERSION_1_1 | |
| #error Skia requires the use of Vulkan 1.1 headers | |
| #endif | |
| namespace skgpu { | |
| namespace graphite { | |
| class VulkanYcbcrConversion; | |
| } | |
| using VulkanGetProc = std::function<PFN_vkVoidFunction( | |
| const char*, // function name | |
| VkInstance, // instance or VK_NULL_HANDLE | |
| VkDevice // device or VK_NULL_HANDLE | |
| )>; | |
| typedef intptr_t VulkanBackendMemory; | |
| /** | |
| * Types for interacting with Vulkan resources created externally to Skia. | |
| */ | |
| struct VulkanAlloc { | |
| // can be VK_NULL_HANDLE iff is an RT and is borrowed | |
| VkDeviceMemory fMemory = VK_NULL_HANDLE; | |
| VkDeviceSize fOffset = 0; | |
| VkDeviceSize fSize = 0; // this can be indeterminate iff Tex uses borrow semantics | |
| uint32_t fFlags = 0; | |
| // handle to memory allocated via skgpu::VulkanMemoryAllocator. | |
| VulkanBackendMemory fBackendMemory = 0; | |
| enum Flag { | |
| kNoncoherent_Flag = 0x1, // memory must be flushed to device after mapping | |
| kMappable_Flag = 0x2, // memory is able to be mapped. | |
| kLazilyAllocated_Flag = 0x4, // memory was created with lazy allocation | |
| }; | |
| bool operator==(const VulkanAlloc& that) const { | |
| return fMemory == that.fMemory && fOffset == that.fOffset && fSize == that.fSize && | |
| fFlags == that.fFlags && fUsesSystemHeap == that.fUsesSystemHeap; | |
| } | |
| private: | |
| bool fUsesSystemHeap = false; | |
| }; | |
| // Used to pass in the necessary information to create a VkSamplerYcbcrConversion object for an | |
| // VkExternalFormatANDROID. | |
| struct SK_API VulkanYcbcrConversionInfo { | |
| public: | |
| // Makes an invalid VulkanYcbcrConversionInfo | |
| VulkanYcbcrConversionInfo() = default; | |
| // For external images format features here should be those returned by a call to | |
| // vkAndroidHardwareBufferFormatPropertiesANDROID | |
| VulkanYcbcrConversionInfo(uint64_t externalFormat, | |
| VkSamplerYcbcrModelConversion ycbcrModel, | |
| VkSamplerYcbcrRange ycbcrRange, | |
| VkChromaLocation xChromaOffset, | |
| VkChromaLocation yChromaOffset, | |
| VkFilter chromaFilter, | |
| VkBool32 forceExplicitReconstruction, | |
| VkComponentMapping components, | |
| VkFormatFeatureFlags formatFeatures) | |
| : VulkanYcbcrConversionInfo(VK_FORMAT_UNDEFINED, | |
| externalFormat, | |
| ycbcrModel, | |
| ycbcrRange, | |
| xChromaOffset, | |
| yChromaOffset, | |
| chromaFilter, | |
| forceExplicitReconstruction, | |
| components, | |
| formatFeatures) {} | |
| VulkanYcbcrConversionInfo(VkFormat format, | |
| VkSamplerYcbcrModelConversion ycbcrModel, | |
| VkSamplerYcbcrRange ycbcrRange, | |
| VkChromaLocation xChromaOffset, | |
| VkChromaLocation yChromaOffset, | |
| VkFilter chromaFilter, | |
| VkBool32 forceExplicitReconstruction, | |
| VkComponentMapping components, | |
| VkFormatFeatureFlags formatFeatures) | |
| : VulkanYcbcrConversionInfo(format, | |
| 0, | |
| ycbcrModel, | |
| ycbcrRange, | |
| xChromaOffset, | |
| yChromaOffset, | |
| chromaFilter, | |
| forceExplicitReconstruction, | |
| components, | |
| formatFeatures) {} | |
| bool operator==(const VulkanYcbcrConversionInfo& that) const { | |
| // Invalid objects are not required to have all other fields initialized or matching. | |
| if (!this->isValid() && !that.isValid()) { | |
| return true; | |
| } | |
| // Note that we do not need to check for fSamplerFilterMustMatchChromaFilter equality. This | |
| // is because the Vulkan spec dictates that Android hardware buffers with the same external | |
| // format must have the same support for key features. See | |
| // https://docs.vulkan.org/spec/latest/chapters/memory.html#_android_hardware_buffer_external_memory | |
| // for more details. | |
| return this->fFormat == that.fFormat && | |
| this->fExternalFormat == that.fExternalFormat && | |
| this->fYcbcrModel == that.fYcbcrModel && | |
| this->fYcbcrRange == that.fYcbcrRange && | |
| this->fXChromaOffset == that.fXChromaOffset && | |
| this->fYChromaOffset == that.fYChromaOffset && | |
| this->fChromaFilter == that.fChromaFilter && | |
| this->fForceExplicitReconstruction == that.fForceExplicitReconstruction && | |
| this->fComponents.r == that.fComponents.r && | |
| this->fComponents.g == that.fComponents.g && | |
| this->fComponents.b == that.fComponents.b && | |
| this->fComponents.a == that.fComponents.a; | |
| } | |
| bool operator!=(const VulkanYcbcrConversionInfo& that) const { return !(*this == that); } | |
| bool isValid() const { | |
| return fYcbcrModel != VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY || | |
| this->hasExternalFormat(); | |
| } | |
| VkFormat format() const { return fFormat; } | |
| bool hasExternalFormat() const { return fExternalFormat != 0; } | |
| uint64_t externalFormat() const { return fExternalFormat; } | |
| VkSamplerYcbcrModelConversion model() const { return fYcbcrModel; } | |
| VkSamplerYcbcrRange range() const { return fYcbcrRange; } | |
| VkChromaLocation xChromaOffset() const { return fXChromaOffset; } | |
| VkChromaLocation yChromaOffset() const { return fYChromaOffset; } | |
| VkFilter chromaFilter() const { return fChromaFilter; } | |
| VkBool32 forceExplicitReconstruction() const { return fForceExplicitReconstruction; } | |
| VkComponentMapping components() const { return fComponents; } | |
| bool samplerFilterMustMatchChromaFilter() const { return fSamplerFilterMustMatchChromaFilter; } | |
| bool supportsLinearFilter() const { return fSupportsLinearFilter; } | |
| // Returns a populated VkSamplerYcbcrConversionCreateInfo object based on | |
| // VulkanYcbcrConversionInfo | |
| void toVkSamplerYcbcrConversionCreateInfo(VkSamplerYcbcrConversionCreateInfo* outInfo, | |
| std::optional<VkFilter>* requiredSamplerFilter) const; | |
| private: | |
| VulkanYcbcrConversionInfo(VkFormat format, | |
| uint64_t externalFormat, | |
| VkSamplerYcbcrModelConversion ycbcrModel, | |
| VkSamplerYcbcrRange ycbcrRange, | |
| VkChromaLocation xChromaOffset, | |
| VkChromaLocation yChromaOffset, | |
| VkFilter chromaFilter, | |
| VkBool32 forceExplicitReconstruction, | |
| VkComponentMapping components, | |
| VkFormatFeatureFlags formatFeatures); | |
| // For use internally to recreate from an ImmutableSamplerInfo. We don't have feature flags | |
| // and assume we've updated all the fields as required by the feature flags previously. | |
| friend class graphite::VulkanYcbcrConversion; | |
| VulkanYcbcrConversionInfo(VkFormat format, | |
| uint64_t externalFormat, | |
| VkSamplerYcbcrModelConversion ycbcrModel, | |
| VkSamplerYcbcrRange ycbcrRange, | |
| VkChromaLocation xChromaOffset, | |
| VkChromaLocation yChromaOffset, | |
| VkFilter chromaFilter, | |
| VkBool32 forceExplicitReconstruction, | |
| VkComponentMapping components, | |
| bool mustMatchChromaFilter, | |
| bool supportsLinearFilter) | |
| : fFormat(format) | |
| , fExternalFormat(externalFormat) | |
| , fYcbcrModel(ycbcrModel) | |
| , fYcbcrRange(ycbcrRange) | |
| , fXChromaOffset(xChromaOffset) | |
| , fYChromaOffset(yChromaOffset) | |
| , fChromaFilter(chromaFilter) | |
| , fForceExplicitReconstruction(forceExplicitReconstruction) | |
| , fComponents(components) | |
| , fSamplerFilterMustMatchChromaFilter(mustMatchChromaFilter) | |
| , fSupportsLinearFilter(supportsLinearFilter) {} | |
| // Format of the source image. Must be set to VK_FORMAT_UNDEFINED for external images or | |
| // a valid image format otherwise. | |
| VkFormat fFormat = VK_FORMAT_UNDEFINED; | |
| // The external format. Must be non-zero for external images, zero otherwise. | |
| // Should be compatible to be used in a VkExternalFormatANDROID struct. | |
| uint64_t fExternalFormat = 0; | |
| VkSamplerYcbcrModelConversion fYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY; | |
| VkSamplerYcbcrRange fYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL; | |
| VkChromaLocation fXChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN; | |
| VkChromaLocation fYChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN; | |
| VkFilter fChromaFilter = VK_FILTER_NEAREST; | |
| VkBool32 fForceExplicitReconstruction = false; | |
| // This is ignored when fExternalFormat is non-zero. | |
| VkComponentMapping fComponents = {VK_COMPONENT_SWIZZLE_IDENTITY, | |
| VK_COMPONENT_SWIZZLE_IDENTITY, | |
| VK_COMPONENT_SWIZZLE_IDENTITY, | |
| VK_COMPONENT_SWIZZLE_IDENTITY}; | |
| // Default these values to the most restrictive. These defaults only really matter until | |
| // we force all clients to go through our constructors. At that point these will be set to the | |
| // correct values. | |
| bool fSamplerFilterMustMatchChromaFilter = true; | |
| bool fSupportsLinearFilter = false; | |
| }; | |
| typedef void* VulkanDeviceLostContext; | |
| typedef void (*VulkanDeviceLostProc)(VulkanDeviceLostContext faultContext, | |
| const std::string& description, | |
| const std::vector<VkDeviceFaultAddressInfoEXT>& addressInfos, | |
| const std::vector<VkDeviceFaultVendorInfoEXT>& vendorInfos, | |
| const std::vector<std::byte>& vendorBinaryData); | |
| } // namespace skgpu | |
| #endif // skgpu_VulkanTypes_DEFINED |