Flutter Engine
The Flutter Engine
VulkanUtilsPriv.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2023 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
12
13#include <vector>
14
15namespace skgpu {
16
17/**
18 * Define a macro that both ganesh and graphite can use to make simple calls into Vulkan so we can
19 * share more code between them.
20*/
21#define SHARED_GR_VULKAN_CALL(IFACE, X) (IFACE)->fFunctions.f##X
22
23/**
24 * Returns a populated VkSamplerYcbcrConversionCreateInfo object based on VulkanYcbcrConversionInfo
25*/
27 const VulkanYcbcrConversionInfo& conversionInfo) {
28#ifdef SK_DEBUG
29 const VkFormatFeatureFlags& featureFlags = conversionInfo.fFormatFeatures;
30 if (conversionInfo.fXChromaOffset == VK_CHROMA_LOCATION_MIDPOINT ||
33 }
34 if (conversionInfo.fXChromaOffset == VK_CHROMA_LOCATION_COSITED_EVEN ||
37 }
38 if (conversionInfo.fChromaFilter == VK_FILTER_LINEAR) {
40 }
41 if (conversionInfo.fForceExplicitReconstruction) {
42 SkASSERT(featureFlags &
44 }
45#endif
46
47 VkFilter chromaFilter = conversionInfo.fChromaFilter;
49 if (!(conversionInfo.fFormatFeatures &
51 // Because we don't have have separate reconstruction filter, the min, mag and
52 // chroma filter must all match. However, we also don't support linear sampling so
53 // the min/mag filter have to be nearest. Therefore, we force the chrome filter to
54 // be nearest regardless of support for the feature
55 // VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT.
56 chromaFilter = VK_FILTER_NEAREST;
57 }
58 }
59
61 outInfo->pNext = nullptr;
62 outInfo->format = conversionInfo.fFormat;
63 outInfo->ycbcrModel = conversionInfo.fYcbcrModel;
64 outInfo->ycbcrRange = conversionInfo.fYcbcrRange;
65 outInfo->components = conversionInfo.fComponents;
66 outInfo->xChromaOffset = conversionInfo.fXChromaOffset;
67 outInfo->yChromaOffset = conversionInfo.fYChromaOffset;
68 outInfo->chromaFilter = chromaFilter;
70}
71
72#ifdef SK_BUILD_FOR_ANDROID
73
74/**
75 * Shared Vulkan AHardwareBuffer utility functions between graphite and ganesh
76*/
77void GetYcbcrConversionInfoFromFormatProps(
78 VulkanYcbcrConversionInfo* outConversionInfo,
80 outConversionInfo->fYcbcrModel = formatProps.suggestedYcbcrModel;
81 outConversionInfo->fYcbcrRange = formatProps.suggestedYcbcrRange;
82 outConversionInfo->fComponents = formatProps.samplerYcbcrConversionComponents;
83 outConversionInfo->fXChromaOffset = formatProps.suggestedXChromaOffset;
84 outConversionInfo->fYChromaOffset = formatProps.suggestedYChromaOffset;
85 outConversionInfo->fForceExplicitReconstruction = VK_FALSE;
86 outConversionInfo->fExternalFormat = formatProps.externalFormat;
87 outConversionInfo->fFormatFeatures = formatProps.formatFeatures;
89 formatProps.formatFeatures) {
90 outConversionInfo->fChromaFilter = VK_FILTER_LINEAR;
91 } else {
92 outConversionInfo->fChromaFilter = VK_FILTER_NEAREST;
93 }
94}
95
96bool GetAHardwareBufferProperties(
99 const skgpu::VulkanInterface* interface,
100 const AHardwareBuffer* hwBuffer,
101 VkDevice device) {
102 outHwbFormatProps->sType =
104 outHwbFormatProps->pNext = nullptr;
105
107 outHwbProps->pNext = outHwbFormatProps;
108
110 SHARED_GR_VULKAN_CALL(interface,
111 GetAndroidHardwareBufferProperties(device,
112 hwBuffer,
113 outHwbProps));
114 if (result != VK_SUCCESS) {
115 SkDebugf("Failed to get AndroidHardwareBufferProperties\n");
116 return false;
117 }
118 return true;
119}
120
121bool AllocateAndBindImageMemory(skgpu::VulkanAlloc* outVulkanAlloc,
122 VkImage image,
123 const VkPhysicalDeviceMemoryProperties2& phyDevMemProps,
125 AHardwareBuffer* hardwareBuffer,
126 const skgpu::VulkanInterface* interface,
127 VkDevice device) {
129 uint32_t typeIndex = 0;
130 bool foundHeap = false;
131 uint32_t memTypeCnt = phyDevMemProps.memoryProperties.memoryTypeCount;
132 for (uint32_t i = 0; i < memTypeCnt && !foundHeap; ++i) {
133 if (hwbProps.memoryTypeBits & (1 << i)) {
134 const VkPhysicalDeviceMemoryProperties& pdmp = phyDevMemProps.memoryProperties;
135 uint32_t supportedFlags = pdmp.memoryTypes[i].propertyFlags &
137 if (supportedFlags == VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
138 typeIndex = i;
139 foundHeap = true;
140 }
141 }
142 }
143
144 /**
145 * Fallback to use any available memory type for AHB.
146 *
147 * For external memory import, compatible memory types are decided by the Vulkan driver since
148 * the memory has been allocated externally. There are usually special requirements against
149 * external memory. e.g. AHB allocated with CPU R/W often usage bits is only importable for
150 * non-device-local heap on some AMD systems.
151 */
152 if (!foundHeap && hwbProps.memoryTypeBits) {
153 typeIndex = ffs(hwbProps.memoryTypeBits) - 1;
154 foundHeap = true;
155 }
156 if (!foundHeap) {
157 return false;
158 }
159
162 hwbImportInfo.pNext = nullptr;
163 hwbImportInfo.buffer = hardwareBuffer;
164
165 VkMemoryDedicatedAllocateInfo dedicatedAllocInfo;
167 dedicatedAllocInfo.pNext = &hwbImportInfo;
168 dedicatedAllocInfo.image = image;
169 dedicatedAllocInfo.buffer = VK_NULL_HANDLE;
170
171 VkMemoryAllocateInfo allocInfo = {
173 &dedicatedAllocInfo, // pNext
174 hwbProps.allocationSize, // allocationSize
175 typeIndex, // memoryTypeIndex
176 };
177
178 VkDeviceMemory memory;
179 result = SHARED_GR_VULKAN_CALL(interface,
180 AllocateMemory(device, &allocInfo, nullptr, &memory));
181 if (result != VK_SUCCESS) {
182 return false;
183 }
184
185 VkBindImageMemoryInfo bindImageInfo;
187 bindImageInfo.pNext = nullptr;
188 bindImageInfo.image = image;
189 bindImageInfo.memory = memory;
190 bindImageInfo.memoryOffset = 0;
191
192 result = SHARED_GR_VULKAN_CALL(interface, BindImageMemory2(device, 1, &bindImageInfo));
193 if (result != VK_SUCCESS) {
194 SHARED_GR_VULKAN_CALL(interface, FreeMemory(device, memory, nullptr));
195 return false;
196 }
197
198 outVulkanAlloc->fMemory = memory;
199 outVulkanAlloc->fOffset = 0;
200 outVulkanAlloc->fSize = hwbProps.allocationSize;
201 outVulkanAlloc->fFlags = 0;
202 outVulkanAlloc->fBackendMemory = 0;
203 return true;
204}
205
206#endif // SK_BUILD_FOR_ANDROID
207
208// Note: since this is called from Vulkan result-checking functions, any Vk calls this function
209// makes must NOT be checked with those same functions to avoid infinite recursion.
211 VkDevice vkDevice,
212 skgpu::VulkanDeviceLostContext deviceLostContext,
213 skgpu::VulkanDeviceLostProc deviceLostProc,
214 bool supportsDeviceFaultInfoExtension) {
215 if (!deviceLostProc) {
216 return;
217 }
218
219 std::vector<VkDeviceFaultAddressInfoEXT> addressInfos = {};
220 std::vector<VkDeviceFaultVendorInfoEXT> vendorInfos = {};
221 std::vector<std::byte> vendorBinaryData = {};
222
223 if (!supportsDeviceFaultInfoExtension) {
224 deviceLostProc(deviceLostContext,
225 "No details: VK_EXT_device_fault not available/enabled.",
226 addressInfos,
227 vendorInfos,
228 vendorBinaryData);
229 return;
230 }
231
232 // Query counts
233 VkDeviceFaultCountsEXT faultCounts = {};
235 VkResult result = SHARED_GR_VULKAN_CALL(vulkanInterface,
236 GetDeviceFaultInfo(vkDevice, &faultCounts, NULL));
237 if (result != VK_SUCCESS) {
238 deviceLostProc(
239 deviceLostContext,
240 "No details: VK_EXT_device_fault error counting failed: " + std::to_string(result),
241 addressInfos,
242 vendorInfos,
243 vendorBinaryData);
244 return;
245 }
246
247 // Prepare storage
248 addressInfos.resize(faultCounts.addressInfoCount);
249 vendorInfos.resize(faultCounts.vendorInfoCount);
250 vendorBinaryData.resize(faultCounts.vendorBinarySize);
251
252 // Query fault info
253 VkDeviceFaultInfoEXT faultInfo = {};
255 faultInfo.pAddressInfos = addressInfos.data();
256 faultInfo.pVendorInfos = vendorInfos.data();
257 faultInfo.pVendorBinaryData =
258 faultCounts.vendorBinarySize > 0 ? vendorBinaryData.data() : nullptr;
259 result = SHARED_GR_VULKAN_CALL(vulkanInterface,
260 GetDeviceFaultInfo(vkDevice, &faultCounts, &faultInfo));
261 if (result != VK_SUCCESS) {
262 deviceLostProc(
263 deviceLostContext,
264 "No details: VK_EXT_device_fault info dumping failed: " + std::to_string(result),
265 addressInfos,
266 vendorInfos,
267 vendorBinaryData);
268 return;
269 }
270
271 deviceLostProc(deviceLostContext,
272 std::string(faultInfo.description),
273 addressInfos,
274 vendorInfos,
275 vendorBinaryData);
276}
277
278} // namespace skgpu
struct AHardwareBuffer AHardwareBuffer
#define SkASSERT(cond)
Definition: SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define SHARED_GR_VULKAN_CALL(IFACE, X)
VkDevice device
Definition: main.cc:53
GAsyncResult * result
sk_sp< const SkImage > image
Definition: SkRecords.h:269
Definition: GpuTools.h:21
void * VulkanDeviceLostContext
Definition: VulkanTypes.h:121
void(* VulkanDeviceLostProc)(VulkanDeviceLostContext faultContext, const std::string &description, const std::vector< VkDeviceFaultAddressInfoEXT > &addressInfos, const std::vector< VkDeviceFaultVendorInfoEXT > &vendorInfos, const std::vector< std::byte > &vendorBinaryData)
Definition: VulkanTypes.h:122
void SetupSamplerYcbcrConversionInfo(VkSamplerYcbcrConversionCreateInfo *outInfo, const VulkanYcbcrConversionInfo &conversionInfo)
void InvokeDeviceLostCallback(const skgpu::VulkanInterface *vulkanInterface, VkDevice vkDevice, skgpu::VulkanDeviceLostContext deviceLostContext, skgpu::VulkanDeviceLostProc deviceLostProc, bool supportsDeviceFaultInfoExtension)
static SkString to_string(int n)
Definition: nanobench.cpp:119
VkSamplerYcbcrModelConversion suggestedYcbcrModel
VkStructureType sType
Definition: vulkan_core.h:5138
VkDeviceSize memoryOffset
Definition: vulkan_core.h:5142
VkDeviceMemory memory
Definition: vulkan_core.h:5141
VkStructureType sType
VkDeviceSize vendorBinarySize
VkStructureType sType
char description[VK_MAX_DESCRIPTION_SIZE]
VkDeviceFaultAddressInfoEXT * pAddressInfos
VkDeviceFaultVendorInfoEXT * pVendorInfos
VkMemoryPropertyFlags propertyFlags
Definition: vulkan_core.h:3043
VkPhysicalDeviceMemoryProperties memoryProperties
Definition: vulkan_core.h:5311
VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES]
Definition: vulkan_core.h:3216
VkSamplerYcbcrModelConversion ycbcrModel
Definition: vulkan_core.h:5426
VkDeviceSize fSize
Definition: VulkanTypes.h:41
VulkanBackendMemory fBackendMemory
Definition: VulkanTypes.h:44
VkDeviceMemory fMemory
Definition: VulkanTypes.h:39
VkDeviceSize fOffset
Definition: VulkanTypes.h:40
VkSamplerYcbcrRange fYcbcrRange
Definition: VulkanTypes.h:104
VkSamplerYcbcrModelConversion fYcbcrModel
Definition: VulkanTypes.h:103
VkComponentMapping fComponents
Definition: VulkanTypes.h:115
VkFormatFeatureFlags fFormatFeatures
Definition: VulkanTypes.h:112
@ VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT
Definition: vulkan_core.h:2271
@ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT
Definition: vulkan_core.h:2278
@ VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT
Definition: vulkan_core.h:2280
@ VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT
Definition: vulkan_core.h:2274
@ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT
Definition: vulkan_core.h:2275
@ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT
Definition: vulkan_core.h:2276
@ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
Definition: vulkan_core.h:2399
@ VK_CHROMA_LOCATION_COSITED_EVEN
Definition: vulkan_core.h:4968
@ VK_CHROMA_LOCATION_MIDPOINT
Definition: vulkan_core.h:4969
VkFlags VkFormatFeatureFlags
Definition: vulkan_core.h:2307
#define VK_FALSE
Definition: vulkan_core.h:125
VkFilter
Definition: vulkan_core.h:2100
@ VK_FILTER_NEAREST
Definition: vulkan_core.h:2101
@ VK_FILTER_LINEAR
Definition: vulkan_core.h:2102
VkResult
Definition: vulkan_core.h:140
@ VK_SUCCESS
Definition: vulkan_core.h:141
#define VK_NULL_HANDLE
Definition: vulkan_core.h:46
@ VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID
Definition: vulkan_core.h:645
@ VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT
Definition: vulkan_core.h:960
@ VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID
Definition: vulkan_core.h:644
@ VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT
Definition: vulkan_core.h:959
@ VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO
Definition: vulkan_core.h:292
@ VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO
Definition: vulkan_core.h:253
@ VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID
Definition: vulkan_core.h:643
@ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO
Definition: vulkan_core.h:256
@ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO
Definition: vulkan_core.h:207