{"record":{"id":"44ddc471c51c8c08","repo":"stride3d/stride","slug":"ahardwarebuffer-import-requires-vk-android-external-memory","errorCode":null,"errorMessage":"AHardwareBuffer import requires VK_ANDROID_external_memory_android_hardware_buffer.","messagePattern":"AHardwareBuffer import requires VK_ANDROID_external_memory_android_hardware_buffer\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Graphics/Vulkan/Texture.Android.Vulkan.cs","lineNumber":60,"sourceCode":"            {\n                GraphicsDevice.Collect(NativeSamplerYcbcrConversion);\n                NativeSamplerYcbcrConversion = VkSamplerYcbcrConversion.Null;\n            }\n            if (androidHardwareBuffer != IntPtr.Zero)\n            {\n                AHardwareBuffer_release(androidHardwareBuffer);\n                androidHardwareBuffer = IntPtr.Zero;\n            }\n        }\n\n        /// <summary>Imports an <c>AHardwareBuffer</c> as a Vulkan-backed sampleable Texture.\n        /// Acquires a reference released when the Texture is destroyed.</summary>\n        public static unsafe Texture NewFromAndroidHardwareBuffer(GraphicsDevice device, IntPtr hardwareBuffer)\n        {\n            if (device == null) throw new ArgumentNullException(nameof(device));\n            if (hardwareBuffer == IntPtr.Zero) throw new ArgumentNullException(nameof(hardwareBuffer));\n            if (!device.HasAndroidHardwareBufferSupport)\n                throw new InvalidOperationException(\"AHardwareBuffer import requires VK_ANDROID_external_memory_android_hardware_buffer.\");\n\n            AHardwareBuffer_acquire(hardwareBuffer);\n\n            AHardwareBufferDesc desc;\n            AHardwareBuffer_describe(hardwareBuffer, out desc);\n\n            var formatInfo = new VkAndroidHardwareBufferFormatPropertiesANDROID\n            {\n                sType = VkStructureType.AndroidHardwareBufferFormatPropertiesAndroid,\n            };\n            var props = new VkAndroidHardwareBufferPropertiesANDROID\n            {\n                sType = VkStructureType.AndroidHardwareBufferPropertiesAndroid,\n                pNext = &formatInfo,\n            };\n            device.CheckResult(device.NativeDeviceApi.vkGetAndroidHardwareBufferPropertiesANDROID(device.NativeDevice, hardwareBuffer, &props));\n\n            // Non-zero externalFormat = buffer needs sampler-YCbCr conversion to read as RGB.","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/Vulkan/Texture.Android.Vulkan.cs#L42-L78","documentation":"Texture.NewFromAndroidHardwareBuffer imports an Android AHardwareBuffer as a Vulkan texture. This requires the Vulkan driver to expose the VK_ANDROID_external_memory_android_hardware_buffer extension (device.HasAndroidHardwareBufferSupport). If the physical device lacks that extension, Stride throws InvalidOperationException rather than attempting an import the driver cannot perform.","triggerScenarios":"Calling Texture.NewFromAndroidHardwareBuffer(device, buffer) on a GraphicsDevice whose Vulkan physical device does not report VK_ANDROID_external_memory_android_hardware_buffer; also when the extension is available but not enabled at device creation because the required instance/device extension chain was not requested.","commonSituations":"Running on an Android emulator or older/low-end GPU whose Vulkan ICD omits the extension; on devices below Android API 26 where AHardwareBuffer APIs are missing; enabling Vulkan on Android without enabling the extension chain (VK_KHR_external_memory, AndroidSamplerYcbcrConversion dependencies) during device creation.","solutions":["Check device.HasAndroidHardwareBufferSupport before calling NewFromAndroidHardwareBuffer and use a fallback (copy the buffer via CPU or a different sharing path) when it is false.","Recreate the GraphicsDevice enabling the extension chain: VK_ANDROID_external_memory_android_hardware_buffer plus its dependencies (VK_KHR_external_memory, VK_KHR_sampler_ycbcr_conversion) in device creation.","Run on physical hardware/Android 8.0+ (API 26) with a driver that supports AHardwareBuffer import instead of an emulator or outdated ICD.","Update the GPU driver/OEM Vulkan ICD, which may add the extension."],"exampleFix":"// before\ndisplayTexture = Texture.NewFromAndroidHardwareBuffer(device, surfaceView.HardwareBuffer);\n\n// after\nif (device.HasAndroidHardwareBufferSupport)\n    displayTexture = Texture.NewFromAndroidHardwareBuffer(device, surfaceView.HardwareBuffer);\nelse\n    displayTexture = CopyHardwareBufferToTexture(device, surfaceView.HardwareBuffer);","handlingStrategy":"validation","validationCode":"if (device == null || hardwareBuffer == IntPtr.Zero) throw new ArgumentException(\"Invalid device or hardware buffer.\");\nif (!device.HasAndroidHardwareBufferSupport)\n    throw new NotSupportedException(\"VK_ANDROID_external_memory_android_hardware_buffer unavailable; use fallback upload.\");","typeGuard":"bool CanImportAHardwareBuffer(GraphicsDevice device) => device != null && device.HasAndroidHardwareBufferSupport;","tryCatchPattern":"try\n{\n    texture = Texture.NewFromAndroidHardwareBuffer(device, hardwareBuffer);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"VK_ANDROID_external_memory_android_hardware_buffer\"))\n{\n    texture = UploadFallbackTexture(device, hardwareBuffer);\n}","preventionTips":["Gate all AHardwareBuffer imports behind device.HasAndroidHardwareBufferSupport.","Request the full extension chain (VK_ANDROID_external_memory_android_hardware_buffer + dependencies) at device creation.","Test on both physical devices and emulators early; emulator Vulkan often lacks this extension.","Keep a CPU upload fallback path implemented and tested for unsupported devices."],"tags":["vulkan","android","hardware-buffer","extension-missing"],"backgroundTag":"feature-not-enabled","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}