blob: b3f4d5a04363cfb79f884c26679dca0764eb8f22 [file] [log] [blame]
/*
* 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/base/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