Skip to content

Commit

Permalink
igl | vulkan - external hw buffer support #2
Browse files Browse the repository at this point in the history
Summary:
- refactoring making attachment interface
- moving common logic for buffer desc validation check to interface class

Reviewed By: EricGriffith, corporateshark

Differential Revision: D58441164

fbshipit-source-id: bea00bf33725c9685dd9fc6bb25f5e528c33cee2
  • Loading branch information
Oleksii Maliarov authored and facebook-github-bot committed Jun 26, 2024
1 parent e770947 commit e83aee9
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 28 deletions.
24 changes: 14 additions & 10 deletions src/igl/android/NativeHWBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,19 +147,19 @@ Result allocateNativeHWBuffer(const TextureDesc& desc,
}

INativeHWTextureBuffer::~INativeHWTextureBuffer() {
if (!isHwBufferExternal_) {
if (hwBuffer_ != nullptr) {
AHardwareBuffer_release(hwBuffer_);
hwBuffer_ = nullptr;
}
}

Result INativeHWTextureBuffer::attachHWBuffer(struct AHardwareBuffer* buffer) {
Result INativeHWTextureBuffer::attachHWBuffer(AHardwareBuffer* buffer) {
if (hwBuffer_) {
return Result{Result::Code::InvalidOperation,
isHwBufferExternal_ ? "Hardware buffer already attached"
: "Hardware buffer already created"};
return Result{Result::Code::InvalidOperation, "Hardware buffer already provided"};
}

AHardwareBuffer_acquire(buffer);

AHardwareBuffer_Desc hwbDesc;
AHardwareBuffer_describe(buffer, &hwbDesc);

Expand All @@ -169,19 +169,20 @@ Result INativeHWTextureBuffer::attachHWBuffer(struct AHardwareBuffer* buffer) {
hwbDesc.height);
const bool isValid = desc.format != TextureFormat::Invalid && desc.usage != 0;
if (!isValid) {
AHardwareBuffer_release(buffer);
return Result(Result::Code::Unsupported, "Can not create texture for hardware buffer");
}

return createTextureInternal(desc, buffer, true);
hwBuffer_ = buffer;

return createTextureInternal(desc, buffer);
}

Result INativeHWTextureBuffer::createHWBuffer(const TextureDesc& desc,
bool hasStorageAlready,
bool surfaceComposite) {
if (hwBuffer_) {
return Result{Result::Code::InvalidOperation,
isHwBufferExternal_ ? "Hardware buffer already attached"
: "Hardware buffer already created"};
return Result{Result::Code::InvalidOperation, "Hardware buffer already provided"};
}

const bool isValid = desc.numLayers == 1 && desc.numSamples == 1 && desc.numMipLevels == 1 &&
Expand All @@ -199,10 +200,13 @@ Result INativeHWTextureBuffer::createHWBuffer(const TextureDesc& desc,
return allocationResult;
}

Result result = createTextureInternal(desc, buffer, false);
Result result = createTextureInternal(desc, buffer);
if (!result.isOk()) {
AHardwareBuffer_release(buffer);
} else {
hwBuffer_ = buffer;
}

return result;
}

Expand Down
7 changes: 2 additions & 5 deletions src/igl/android/NativeHWBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class INativeHWTextureBuffer {

virtual ~INativeHWTextureBuffer();

Result attachHWBuffer(struct AHardwareBuffer* buffer);
Result attachHWBuffer(AHardwareBuffer* buffer);
Result createHWBuffer(const TextureDesc& desc, bool hasStorageAlready, bool surfaceComposite);

Result lockHWBuffer(std::byte* IGL_NULLABLE* IGL_NONNULL dst, RangeDesc& outRange) const;
Expand All @@ -35,12 +35,9 @@ class INativeHWTextureBuffer {
AHardwareBuffer* getHardwareBuffer();

protected:
virtual Result createTextureInternal(const TextureDesc& desc,
struct AHardwareBuffer* buffer,
bool isHwBufferExternal) = 0;
virtual Result createTextureInternal(const TextureDesc& desc, AHardwareBuffer* buffer) = 0;

AHardwareBuffer* hwBuffer_ = nullptr;
bool isHwBufferExternal_ = false;
};

// utils
Expand Down
22 changes: 20 additions & 2 deletions src/igl/vulkan/PlatformDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <igl/vulkan/VulkanSwapchain.h>

#if IGL_PLATFORM_ANDROID && __ANDROID_MIN_SDK_VERSION__ >= 26
#include <android/hardware_buffer.h>
#include <igl/vulkan/android/NativeHWBuffer.h>
#endif

Expand Down Expand Up @@ -124,7 +125,6 @@ std::shared_ptr<ITexture> PlatformDevice::createTextureFromNativeDrawable(Result
}

#if IGL_PLATFORM_ANDROID && __ANDROID_MIN_SDK_VERSION__ >= 26

/// returns a android::NativeHWTextureBuffer on platforms supporting it
/// this texture allows CPU and GPU to both read/write memory
std::shared_ptr<ITexture> PlatformDevice::createTextureWithSharedMemory(const TextureDesc& desc,
Expand All @@ -133,7 +133,7 @@ std::shared_ptr<ITexture> PlatformDevice::createTextureWithSharedMemory(const Te

auto texture =
std::make_shared<igl::vulkan::android::NativeHWTextureBuffer>(device_, desc.format);
subResult = texture->create(desc);
subResult = texture->createHWBuffer(desc, false, false);
Result::setResult(outResult, subResult.code, subResult.message);
if (!subResult.isOk()) {
return nullptr;
Expand All @@ -142,6 +142,24 @@ std::shared_ptr<ITexture> PlatformDevice::createTextureWithSharedMemory(const Te
return std::move(texture);
}

std::shared_ptr<ITexture> PlatformDevice::createTextureWithSharedMemory(
struct AHardwareBuffer* buffer,
Result* outResult) const {
Result subResult;

AHardwareBuffer_Desc hwbDesc;
AHardwareBuffer_describe(buffer, &hwbDesc);

auto texture = std::make_shared<igl::vulkan::android::NativeHWTextureBuffer>(
device_, igl::android::getIglFormat(hwbDesc.format));
subResult = texture->attachHWBuffer(buffer);
Result::setResult(outResult, subResult.code, subResult.message);
if (!subResult.isOk()) {
return nullptr;
}

return std::move(texture);
}
#endif

VkFence PlatformDevice::getVkFenceFromSubmitHandle(SubmitHandle handle) const {
Expand Down
6 changes: 6 additions & 0 deletions src/igl/vulkan/PlatformDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#include <igl/Texture.h>
#include <igl/vulkan/Common.h>

#if IGL_PLATFORM_ANDROID && __ANDROID_MIN_SDK_VERSION__ >= 26
struct AHardwareBuffer;
#endif

namespace igl {
class ITexture;

Expand Down Expand Up @@ -44,6 +48,8 @@ class PlatformDevice : public IPlatformDevice {
#if IGL_PLATFORM_ANDROID && __ANDROID_MIN_SDK_VERSION__ >= 26
std::shared_ptr<ITexture> createTextureWithSharedMemory(const TextureDesc& desc,
Result* outResult) const;
std::shared_ptr<ITexture> createTextureWithSharedMemory(AHardwareBuffer* buffer,
Result* outResult) const;
#endif

/// @param handle The handle to the GPU Fence
Expand Down
7 changes: 1 addition & 6 deletions src/igl/vulkan/android/NativeHWBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#if IGL_PLATFORM_ANDROID && __ANDROID_MIN_SDK_VERSION__ >= 26

#include <android/hardware_buffer.h>
#include <android/native_window.h>
#include <vulkan/vulkan_android.h>

#include <igl/vulkan/Device.h>
Expand All @@ -27,8 +26,7 @@ NativeHWTextureBuffer::NativeHWTextureBuffer(const igl::vulkan::Device& device,
NativeHWTextureBuffer::~NativeHWTextureBuffer() {}

Result NativeHWTextureBuffer::createTextureInternal(const TextureDesc& desc,
struct AHardwareBuffer* buffer,
bool isHwBufferExternal) {
AHardwareBuffer* buffer) {
const VkImageUsageFlags usageFlags =
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
Expand Down Expand Up @@ -71,9 +69,6 @@ Result NativeHWTextureBuffer::createTextureInternal(const TextureDesc& desc,
return Result(Result::Code::RuntimeError, "Failed to create vulkan texture");
}

hwBuffer_ = buffer;
isHwBufferExternal_ = isHwBufferExternal;

desc_ = std::move(desc);
texture_ = std::move(vkTexture);

Expand Down
6 changes: 1 addition & 5 deletions src/igl/vulkan/android/NativeHWBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

#include <igl/vulkan/Texture.h>

#include <jni.h>

struct AHardwareBuffer;

namespace igl::vulkan::android {
Expand All @@ -35,9 +33,7 @@ class NativeHWTextureBuffer : public igl::android::INativeHWTextureBuffer, publi
Result create(const TextureDesc& desc) override;

// INativeHWTextureBuffer overrides
Result createTextureInternal(const TextureDesc& desc,
struct AHardwareBuffer* buffer,
bool isHwBufferExternal) override;
Result createTextureInternal(const TextureDesc& desc, AHardwareBuffer* buffer) override;
};

} // namespace igl::vulkan::android
Expand Down

0 comments on commit e83aee9

Please sign in to comment.