#include "src/gpu/vk/VulkanUtilsPriv.h"
#include "include/gpu/vk/VulkanBackendContext.h"
#include "include/private/base/SkDebug.h"
#include "src/gpu/vk/VulkanInterface.h"
#include <algorithm>
#include <vector>
namespace skgpu {
#define SHARED_GR_VULKAN_CALL(IFACE, X) …
void SetupSamplerYcbcrConversionInfo(VkSamplerYcbcrConversionCreateInfo* outInfo,
const VulkanYcbcrConversionInfo& conversionInfo) { … }
#ifdef SK_BUILD_FOR_ANDROID
void GetYcbcrConversionInfoFromFormatProps(
VulkanYcbcrConversionInfo* outConversionInfo,
const VkAndroidHardwareBufferFormatPropertiesANDROID& formatProps) {
outConversionInfo->fYcbcrModel = formatProps.suggestedYcbcrModel;
outConversionInfo->fYcbcrRange = formatProps.suggestedYcbcrRange;
outConversionInfo->fComponents = formatProps.samplerYcbcrConversionComponents;
outConversionInfo->fXChromaOffset = formatProps.suggestedXChromaOffset;
outConversionInfo->fYChromaOffset = formatProps.suggestedYChromaOffset;
outConversionInfo->fForceExplicitReconstruction = VK_FALSE;
outConversionInfo->fExternalFormat = formatProps.externalFormat;
outConversionInfo->fFormatFeatures = formatProps.formatFeatures;
if (VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT &
formatProps.formatFeatures) {
outConversionInfo->fChromaFilter = VK_FILTER_LINEAR;
} else {
outConversionInfo->fChromaFilter = VK_FILTER_NEAREST;
}
}
bool GetAHardwareBufferProperties(
VkAndroidHardwareBufferFormatPropertiesANDROID* outHwbFormatProps,
VkAndroidHardwareBufferPropertiesANDROID* outHwbProps,
const skgpu::VulkanInterface* interface,
const AHardwareBuffer* hwBuffer,
VkDevice device) {
outHwbFormatProps->sType =
VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
outHwbFormatProps->pNext = nullptr;
outHwbProps->sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
outHwbProps->pNext = outHwbFormatProps;
VkResult result =
SHARED_GR_VULKAN_CALL(interface,
GetAndroidHardwareBufferProperties(device,
hwBuffer,
outHwbProps));
if (result != VK_SUCCESS) {
SkDebugf("Failed to get AndroidHardwareBufferProperties (result:%d)", result);
#if __ANDROID_API__ >= 26
AHardwareBuffer_Desc hwbDesc;
AHardwareBuffer_describe(hwBuffer, &hwbDesc);
SkDebugf("^ %" PRIu32 "x%" PRIu32 " AHB -- format:%" PRIu32 ", usage:%" PRIu64
", layers:%" PRIu32,
hwbDesc.width,
hwbDesc.height,
hwbDesc.format,
hwbDesc.usage,
hwbDesc.layers);
#endif
return false;
}
return true;
}
bool AllocateAndBindImageMemory(skgpu::VulkanAlloc* outVulkanAlloc,
VkImage image,
const VkPhysicalDeviceMemoryProperties2& phyDevMemProps,
const VkAndroidHardwareBufferPropertiesANDROID& hwbProps,
AHardwareBuffer* hardwareBuffer,
const skgpu::VulkanInterface* interface,
VkDevice device) {
VkResult result;
uint32_t typeIndex = 0;
bool foundHeap = false;
uint32_t memTypeCnt = phyDevMemProps.memoryProperties.memoryTypeCount;
for (uint32_t i = 0; i < memTypeCnt && !foundHeap; ++i) {
if (hwbProps.memoryTypeBits & (1 << i)) {
const VkPhysicalDeviceMemoryProperties& pdmp = phyDevMemProps.memoryProperties;
uint32_t supportedFlags = pdmp.memoryTypes[i].propertyFlags &
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
if (supportedFlags == VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
typeIndex = i;
foundHeap = true;
}
}
}
if (!foundHeap && hwbProps.memoryTypeBits) {
typeIndex = ffs(hwbProps.memoryTypeBits) - 1;
foundHeap = true;
}
if (!foundHeap) {
return false;
}
VkImportAndroidHardwareBufferInfoANDROID hwbImportInfo;
hwbImportInfo.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
hwbImportInfo.pNext = nullptr;
hwbImportInfo.buffer = hardwareBuffer;
VkMemoryDedicatedAllocateInfo dedicatedAllocInfo;
dedicatedAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
dedicatedAllocInfo.pNext = &hwbImportInfo;
dedicatedAllocInfo.image = image;
dedicatedAllocInfo.buffer = VK_NULL_HANDLE;
VkMemoryAllocateInfo allocInfo = {
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
&dedicatedAllocInfo,
hwbProps.allocationSize,
typeIndex,
};
VkDeviceMemory memory;
result = SHARED_GR_VULKAN_CALL(interface,
AllocateMemory(device, &allocInfo, nullptr, &memory));
if (result != VK_SUCCESS) {
return false;
}
VkBindImageMemoryInfo bindImageInfo;
bindImageInfo.sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
bindImageInfo.pNext = nullptr;
bindImageInfo.image = image;
bindImageInfo.memory = memory;
bindImageInfo.memoryOffset = 0;
result = SHARED_GR_VULKAN_CALL(interface, BindImageMemory2(device, 1, &bindImageInfo));
if (result != VK_SUCCESS) {
SHARED_GR_VULKAN_CALL(interface, FreeMemory(device, memory, nullptr));
return false;
}
outVulkanAlloc->fMemory = memory;
outVulkanAlloc->fOffset = 0;
outVulkanAlloc->fSize = hwbProps.allocationSize;
outVulkanAlloc->fFlags = 0;
outVulkanAlloc->fBackendMemory = 0;
return true;
}
#endif
void InvokeDeviceLostCallback(const skgpu::VulkanInterface* vulkanInterface,
VkDevice vkDevice,
skgpu::VulkanDeviceLostContext deviceLostContext,
skgpu::VulkanDeviceLostProc deviceLostProc,
bool supportsDeviceFaultInfoExtension) { … }
sk_sp<skgpu::VulkanInterface> MakeInterface(const skgpu::VulkanBackendContext& context,
const skgpu::VulkanExtensions* extOverride,
uint32_t* instanceVersionOut,
uint32_t* physDevVersionOut) { … }
}