Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
10#include <vector>
11
12namespace skgpu {
13
14/**
15 * Define a macro that both ganesh and graphite can use to make simple calls into Vulkan so we can
16 * share more code between them.
17*/
18#define SHARED_GR_VULKAN_CALL(IFACE, X) (IFACE)->fFunctions.f##X
19
20/**
21 * Returns a populated VkSamplerYcbcrConversionCreateInfo object based on VulkanYcbcrConversionInfo
22*/
24 const VulkanYcbcrConversionInfo& conversionInfo) {
25#ifdef SK_DEBUG
26 const VkFormatFeatureFlags& featureFlags = conversionInfo.fFormatFeatures;
27 if (conversionInfo.fXChromaOffset == VK_CHROMA_LOCATION_MIDPOINT ||
30 }
31 if (conversionInfo.fXChromaOffset == VK_CHROMA_LOCATION_COSITED_EVEN ||
34 }
35 if (conversionInfo.fChromaFilter == VK_FILTER_LINEAR) {
37 }
38 if (conversionInfo.fForceExplicitReconstruction) {
39 SkASSERT(featureFlags &
41 }
42#endif
43
45 outInfo->pNext = nullptr;
46 outInfo->format = conversionInfo.fFormat;
47 outInfo->ycbcrModel = conversionInfo.fYcbcrModel;
48 outInfo->ycbcrRange = conversionInfo.fYcbcrRange;
49 outInfo->components = conversionInfo.fComponents;
50 outInfo->xChromaOffset = conversionInfo.fXChromaOffset;
51 outInfo->yChromaOffset = conversionInfo.fYChromaOffset;
52 outInfo->chromaFilter = conversionInfo.fChromaFilter;
54}
55
56#ifdef SK_BUILD_FOR_ANDROID
57
58/**
59 * Shared Vulkan AHardwareBuffer utility functions between graphite and ganesh
60*/
61void GetYcbcrConversionInfoFromFormatProps(
62 VulkanYcbcrConversionInfo* outConversionInfo,
64 outConversionInfo->fYcbcrModel = formatProps.suggestedYcbcrModel;
65 outConversionInfo->fYcbcrRange = formatProps.suggestedYcbcrRange;
66 outConversionInfo->fComponents = formatProps.samplerYcbcrConversionComponents;
67 outConversionInfo->fXChromaOffset = formatProps.suggestedXChromaOffset;
68 outConversionInfo->fYChromaOffset = formatProps.suggestedYChromaOffset;
69 outConversionInfo->fForceExplicitReconstruction = VK_FALSE;
70 outConversionInfo->fExternalFormat = formatProps.externalFormat;
71 outConversionInfo->fFormatFeatures = formatProps.formatFeatures;
73 formatProps.formatFeatures) {
74 outConversionInfo->fChromaFilter = VK_FILTER_LINEAR;
75 } else {
76 outConversionInfo->fChromaFilter = VK_FILTER_NEAREST;
77 }
78}
79
80bool GetAHardwareBufferProperties(
83 const skgpu::VulkanInterface* interface,
84 const AHardwareBuffer* hwBuffer,
85 VkDevice device) {
86 outHwbFormatProps->sType =
88 outHwbFormatProps->pNext = nullptr;
89
91 outHwbProps->pNext = outHwbFormatProps;
92
94 SHARED_GR_VULKAN_CALL(interface,
95 GetAndroidHardwareBufferProperties(device,
96 hwBuffer,
97 outHwbProps));
98 if (result != VK_SUCCESS) {
99 SkDebugf("Failed to get AndroidHardwareBufferProperties\n");
100 return false;
101 }
102 return true;
103}
104
105bool AllocateAndBindImageMemory(skgpu::VulkanAlloc* outVulkanAlloc,
106 VkImage image,
107 const VkPhysicalDeviceMemoryProperties2& phyDevMemProps,
109 AHardwareBuffer* hardwareBuffer,
110 const skgpu::VulkanInterface* interface,
111 VkDevice device) {
113 uint32_t typeIndex = 0;
114 bool foundHeap = false;
115 uint32_t memTypeCnt = phyDevMemProps.memoryProperties.memoryTypeCount;
116 for (uint32_t i = 0; i < memTypeCnt && !foundHeap; ++i) {
117 if (hwbProps.memoryTypeBits & (1 << i)) {
118 const VkPhysicalDeviceMemoryProperties& pdmp = phyDevMemProps.memoryProperties;
119 uint32_t supportedFlags = pdmp.memoryTypes[i].propertyFlags &
121 if (supportedFlags == VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
122 typeIndex = i;
123 foundHeap = true;
124 }
125 }
126 }
127
128 /**
129 * Fallback to use any available memory type for AHB.
130 *
131 * For external memory import, compatible memory types are decided by the Vulkan driver since
132 * the memory has been allocated externally. There are usually special requirements against
133 * external memory. e.g. AHB allocated with CPU R/W often usage bits is only importable for
134 * non-device-local heap on some AMD systems.
135 */
136 if (!foundHeap && hwbProps.memoryTypeBits) {
137 typeIndex = ffs(hwbProps.memoryTypeBits) - 1;
138 foundHeap = true;
139 }
140 if (!foundHeap) {
141 return false;
142 }
143
146 hwbImportInfo.pNext = nullptr;
147 hwbImportInfo.buffer = hardwareBuffer;
148
149 VkMemoryDedicatedAllocateInfo dedicatedAllocInfo;
151 dedicatedAllocInfo.pNext = &hwbImportInfo;
152 dedicatedAllocInfo.image = image;
153 dedicatedAllocInfo.buffer = VK_NULL_HANDLE;
154
155 VkMemoryAllocateInfo allocInfo = {
157 &dedicatedAllocInfo, // pNext
158 hwbProps.allocationSize, // allocationSize
159 typeIndex, // memoryTypeIndex
160 };
161
162 VkDeviceMemory memory;
163 result = SHARED_GR_VULKAN_CALL(interface,
164 AllocateMemory(device, &allocInfo, nullptr, &memory));
165 if (result != VK_SUCCESS) {
166 return false;
167 }
168
169 VkBindImageMemoryInfo bindImageInfo;
171 bindImageInfo.pNext = nullptr;
172 bindImageInfo.image = image;
173 bindImageInfo.memory = memory;
174 bindImageInfo.memoryOffset = 0;
175
176 result = SHARED_GR_VULKAN_CALL(interface, BindImageMemory2(device, 1, &bindImageInfo));
177 if (result != VK_SUCCESS) {
178 SHARED_GR_VULKAN_CALL(interface, FreeMemory(device, memory, nullptr));
179 return false;
180 }
181
182 outVulkanAlloc->fMemory = memory;
183 outVulkanAlloc->fOffset = 0;
184 outVulkanAlloc->fSize = hwbProps.allocationSize;
185 outVulkanAlloc->fFlags = 0;
186 outVulkanAlloc->fBackendMemory = 0;
187 return true;
188}
189
190#endif // SK_BUILD_FOR_ANDROID
191
192// Note: since this is called from Vulkan result-checking functions, any Vk calls this function
193// makes must NOT be checked with those same functions to avoid infinite recursion.
195 VkDevice vkDevice,
196 skgpu::VulkanDeviceLostContext deviceLostContext,
197 skgpu::VulkanDeviceLostProc deviceLostProc,
198 bool supportsDeviceFaultInfoExtension) {
199 if (!deviceLostProc) {
200 return;
201 }
202
203 std::vector<VkDeviceFaultAddressInfoEXT> addressInfos = {};
204 std::vector<VkDeviceFaultVendorInfoEXT> vendorInfos = {};
205 std::vector<std::byte> vendorBinaryData = {};
206
207 if (!supportsDeviceFaultInfoExtension) {
208 deviceLostProc(deviceLostContext,
209 "No details: VK_EXT_device_fault not available/enabled.",
210 addressInfos,
211 vendorInfos,
212 vendorBinaryData);
213 return;
214 }
215
216 // Query counts
217 VkDeviceFaultCountsEXT faultCounts = {};
219 VkResult result = SHARED_GR_VULKAN_CALL(vulkanInterface,
220 GetDeviceFaultInfo(vkDevice, &faultCounts, NULL));
221 if (result != VK_SUCCESS) {
222 deviceLostProc(
223 deviceLostContext,
224 "No details: VK_EXT_device_fault error counting failed: " + std::to_string(result),
225 addressInfos,
226 vendorInfos,
227 vendorBinaryData);
228 return;
229 }
230
231 // Prepare storage
232 addressInfos.resize(faultCounts.addressInfoCount);
233 vendorInfos.resize(faultCounts.vendorInfoCount);
234 vendorBinaryData.resize(faultCounts.vendorBinarySize);
235
236 // Query fault info
237 VkDeviceFaultInfoEXT faultInfo = {};
239 faultInfo.pAddressInfos = addressInfos.data();
240 faultInfo.pVendorInfos = vendorInfos.data();
241 faultInfo.pVendorBinaryData =
242 faultCounts.vendorBinarySize > 0 ? vendorBinaryData.data() : nullptr;
243 result = SHARED_GR_VULKAN_CALL(vulkanInterface,
244 GetDeviceFaultInfo(vkDevice, &faultCounts, &faultInfo));
245 if (result != VK_SUCCESS) {
246 deviceLostProc(
247 deviceLostContext,
248 "No details: VK_EXT_device_fault info dumping failed: " + std::to_string(result),
249 addressInfos,
250 vendorInfos,
251 vendorBinaryData);
252 return;
253 }
254
255 deviceLostProc(deviceLostContext,
256 std::string(faultInfo.description),
257 addressInfos,
258 vendorInfos,
259 vendorBinaryData);
260}
261
262} // 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
sk_sp< SkImage > image
Definition examples.cpp:29
GAsyncResult * result
void * VulkanDeviceLostContext
void(* VulkanDeviceLostProc)(VulkanDeviceLostContext faultContext, const std::string &description, const std::vector< VkDeviceFaultAddressInfoEXT > &addressInfos, const std::vector< VkDeviceFaultVendorInfoEXT > &vendorInfos, const std::vector< std::byte > &vendorBinaryData)
void SetupSamplerYcbcrConversionInfo(VkSamplerYcbcrConversionCreateInfo *outInfo, const VulkanYcbcrConversionInfo &conversionInfo)
void InvokeDeviceLostCallback(const skgpu::VulkanInterface *vulkanInterface, VkDevice vkDevice, skgpu::VulkanDeviceLostContext deviceLostContext, skgpu::VulkanDeviceLostProc deviceLostProc, bool supportsDeviceFaultInfoExtension)
VkSamplerYcbcrModelConversion suggestedYcbcrModel
VkStructureType sType
VkDeviceSize memoryOffset
VkDeviceMemory memory
VkStructureType sType
VkDeviceSize vendorBinarySize
VkStructureType sType
char description[VK_MAX_DESCRIPTION_SIZE]
VkDeviceFaultAddressInfoEXT * pAddressInfos
VkDeviceFaultVendorInfoEXT * pVendorInfos
VkMemoryPropertyFlags propertyFlags
VkPhysicalDeviceMemoryProperties memoryProperties
VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES]
VkSamplerYcbcrModelConversion ycbcrModel
VkDeviceSize fSize
Definition VulkanTypes.h:40
VulkanBackendMemory fBackendMemory
Definition VulkanTypes.h:43
VkDeviceMemory fMemory
Definition VulkanTypes.h:38
VkDeviceSize fOffset
Definition VulkanTypes.h:39
VkSamplerYcbcrRange fYcbcrRange
VkSamplerYcbcrModelConversion fYcbcrModel
VkFormatFeatureFlags fFormatFeatures
@ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT
@ VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT
@ VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT
@ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT
@ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
@ VK_CHROMA_LOCATION_COSITED_EVEN
@ VK_CHROMA_LOCATION_MIDPOINT
VkFlags VkFormatFeatureFlags
#define VK_FALSE
@ VK_FILTER_NEAREST
@ VK_FILTER_LINEAR
VkResult
@ VK_SUCCESS
#define VK_NULL_HANDLE
Definition vulkan_core.h:46
@ VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID
@ VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT
@ VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID
@ VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT
@ VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO
@ VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO
@ VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID
@ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO
@ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO