浏览代码

vulkan support

/siyaoH-1.17-android
siyao 3 年前
当前提交
82b622e7
共有 5 个文件被更改,包括 232 次插入27 次删除
  1. 5
      engine/Build.bee.cs
  2. 10
      engine/src/shell/platform/unity/android/uiwidgets_panel.cc
  3. 4
      engine/src/shell/platform/unity/android/uiwidgets_panel.h
  4. 222
      engine/src/shell/platform/unity/android/unity_surface_manager.cc
  5. 18
      engine/src/shell/platform/unity/android/unity_surface_manager.h

5
engine/Build.bee.cs


class AndroidAppToolchain : AndroidNdkToolchain
{
public AndroidAppToolchain(NPath path) : base(new AndroidNdkLocator(Architecture.Armv7).UseSpecific(path).WithForcedApiLevel(26))
public AndroidAppToolchain(NPath path) : base(new AndroidNdkLocator(Architecture.Armv7).UseSpecific(path).WithForcedApiLevel(28))
{
}

"-nostdlib++",
"-Wl,--warn-shared-textrel",
"-nostdlib",
"--sysroot="+ flutterRoot+"/third_party/android_tools/ndk/platforms/android-26/arch-arm",
"--sysroot="+ flutterRoot+"/third_party/android_tools/ndk/platforms/android-28/arch-arm",
"-L"+ flutterRoot + "/third_party/android_tools/ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a",
"-Wl,--build-id=sha1",
"-g",

new SystemLibrary("EGL"),
new SystemLibrary("GLESv2"),
new SystemLibrary("log"),
new SystemLibrary("vulkan"),
};
});
}

10
engine/src/shell/platform/unity/android/uiwidgets_panel.cc


return window_type_ == EditorWindowPanel;
}
GLuint UIWidgetsPanel::OnEnable(size_t width,
void* UIWidgetsPanel::OnEnable(size_t width,
size_t height, float device_pixel_ratio,
const char *streaming_assets_path,
const char *settings)

surface_manager_ = nullptr;
}
GLuint UIWidgetsPanel::OnRenderTexture(size_t width,
void* UIWidgetsPanel::OnRenderTexture(size_t width,
size_t height, float device_pixel_ratio)
{

panel->Release();
}
UIWIDGETS_API(GLuint)
UIWIDGETS_API(void*)
return panel->OnEnable(width, height, device_pixel_ratio,
return (void*)panel->OnEnable(width, height, device_pixel_ratio,
streaming_assets_path, settings);
}

panel->OnDisable();
}
UIWIDGETS_API(GLuint)
UIWIDGETS_API(void*)
UIWidgetsPanel_onRenderTexture(UIWidgetsPanel *panel,
int width, int height, float dpi)
{

4
engine/src/shell/platform/unity/android/uiwidgets_panel.h


~UIWidgetsPanel();
GLuint OnEnable(size_t width, size_t height,
void* OnEnable(size_t width, size_t height,
float device_pixel_ratio, const char* streaming_assets_path,
const char* settings);

GLuint OnRenderTexture(size_t width, size_t height,
void* OnRenderTexture(size_t width, size_t height,
float dpi);
bool ReleaseNativeRenderTexture();

222
engine/src/shell/platform/unity/android/unity_surface_manager.cc


#include "src/shell/common/shell_io_manager.h"
#include "src/shell/gpu/gpu_surface_delegate.h"
#include "src/shell/gpu/gpu_surface_gl_delegate.h"
#define UNITY_USED_VULKAN_API_FUNCTIONS(apply) \
apply(vkGetDeviceProcAddr); \
apply(vkCreateInstance); \
apply(vkCmdBeginRenderPass); \
apply(vkCreateBuffer); \
apply(vkGetPhysicalDeviceMemoryProperties); \
apply(vkGetBufferMemoryRequirements); \
apply(vkMapMemory); \
apply(vkBindBufferMemory); \
apply(vkAllocateMemory); \
apply(vkDestroyBuffer); \
apply(vkFreeMemory); \
apply(vkUnmapMemory); \
apply(vkQueueWaitIdle); \
apply(vkDeviceWaitIdle); \
apply(vkCmdCopyBufferToImage); \
apply(vkFlushMappedMemoryRanges); \
apply(vkCreatePipelineLayout); \
apply(vkCreateShaderModule); \
apply(vkDestroyShaderModule); \
apply(vkCreateGraphicsPipelines); \
apply(vkCmdBindPipeline); \
apply(vkCmdDraw); \
apply(vkCmdPushConstants); \
apply(vkCmdBindVertexBuffers); \
apply(vkDestroyPipeline); \
apply(vkGetAndroidHardwareBufferPropertiesANDROID); \
apply(vkDestroyPipelineLayout);
#define VULKAN_DEFINE_API_FUNCPTR(func) static PFN_##func my_##func
VULKAN_DEFINE_API_FUNCPTR(vkGetInstanceProcAddr);
UNITY_USED_VULKAN_API_FUNCTIONS(VULKAN_DEFINE_API_FUNCPTR);
#undef VULKAN_DEFINE_API_FUNCPTR
static void LoadVulkanAPI(PFN_vkGetInstanceProcAddr getInstanceProcAddr,
VkInstance instance)
{
if (!my_vkGetInstanceProcAddr && getInstanceProcAddr)
my_vkGetInstanceProcAddr = getInstanceProcAddr;
if (!my_vkCreateInstance)
my_vkCreateInstance = (PFN_vkCreateInstance)my_vkGetInstanceProcAddr(
VK_NULL_HANDLE, "vkCreateInstance");
#define LOAD_VULKAN_FUNC(fn) \
if (!my_##fn) \
my_##fn = (PFN_##fn)my_vkGetInstanceProcAddr(instance, #fn)
UNITY_USED_VULKAN_API_FUNCTIONS(LOAD_VULKAN_FUNC);
#undef LOAD_VULKAN_FUNC
}
static bool getMemoryTypeIndex(uint32_t typeBits, VkPhysicalDevice device, VkFlags quirementsMaks,
uint32_t &index)
{
// const auto& memoryPropertys =
// VulkanManager::Get().physical->mempryProperties;
VkPhysicalDeviceMemoryProperties memoryPropertys;
vkGetPhysicalDeviceMemoryProperties(device, &memoryPropertys);
for (uint32_t i = 0; i < memoryPropertys.memoryTypeCount; i++)
{
if ((typeBits & 1) == 1)
{
// Type is available, does it match user properties?
if ((memoryPropertys.memoryTypes[i].propertyFlags &
quirementsMaks) == quirementsMaks)
{
index = i;
return true;
}
}
typeBits >>= 1;
}
return false;
}
namespace uiwidgets
{

{
buffer = nullptr;
usage.width = width; //format.width;
usage.width = width; //format.width;
AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER |
AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER |
AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
if (m_UnityVulkan != nullptr)
{
auto vkDevice = m_Instance.device;
// auto memoryPropertys = m_Instance.memoryTypeIndex;
// VkImage vkImage;
bool useExternalFormat = true;
VkResult err;
AHardwareBuffer_Desc bufferDesc;
AHardwareBuffer_describe(buffer, &bufferDesc);
VkAndroidHardwareBufferFormatPropertiesANDROID formatInfo = {
.sType =
VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID,
.pNext = nullptr,
};
VkAndroidHardwareBufferPropertiesANDROID properties = {
.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID,
.pNext = &formatInfo,
};
err = vkGetAndroidHardwareBufferPropertiesANDROID(vkDevice, buffer, &properties);
VkExternalFormatANDROID externalFormat{
.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID,
.pNext = nullptr,
.externalFormat = formatInfo.externalFormat,
};
VkExternalMemoryImageCreateInfo externalCreateInfo{
.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
.pNext = &externalFormat,
.handleTypes =
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID,
};
VkImageCreateInfo imageInfo = {};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageInfo.pNext = &externalCreateInfo;
imageInfo.flags = 0;
imageInfo.imageType = VK_IMAGE_TYPE_2D;
imageInfo.format =
VK_FORMAT_UNDEFINED;
imageInfo.extent = {
bufferDesc.width,
bufferDesc.height,
1,
};
imageInfo.mipLevels = 1, imageInfo.arrayLayers = 1;
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageInfo.queueFamilyIndexCount = 0;
imageInfo.pQueueFamilyIndices = nullptr;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
auto result = vkCreateImage(vkDevice, &imageInfo, nullptr, &vk_Image_);
VkImportAndroidHardwareBufferInfoANDROID androidHardwareBufferInfo{
.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
.pNext = nullptr,
.buffer = buffer,
};
VkMemoryDedicatedAllocateInfo memoryAllocateInfo{
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
.pNext = &androidHardwareBufferInfo,
.image = vk_Image_,
.buffer = VK_NULL_HANDLE,
};
// android的hardbuffer位置(properties)
VkMemoryRequirements requires;
vkGetImageMemoryRequirements(vkDevice, vk_Image_, &requires);
uint32_t memoryTypeIndex = 0;
bool getIndex =
getMemoryTypeIndex(properties.memoryTypeBits, m_Instance.physicalDevice, 0, memoryTypeIndex);
assert(getIndex);
VkMemoryAllocateInfo memoryInfo = {};
memoryInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memoryInfo.pNext = &memoryAllocateInfo;
memoryInfo.memoryTypeIndex = memoryTypeIndex;
memoryInfo.allocationSize = properties.allocationSize;
auto al = vkAllocateMemory(vkDevice, &memoryInfo, nullptr, &memory);
VkBindImageMemoryInfo bindImageInfo;
bindImageInfo.sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
bindImageInfo.pNext = nullptr;
bindImageInfo.image = vk_Image_;
bindImageInfo.memory = memory;
bindImageInfo.memoryOffset = 0;
// vkBindImageMemory2KHR(vkDevice, 1, &bindImageInfo);
vkBindImageMemory2(vkDevice, 1, &bindImageInfo);
}
EGLClientBuffer native_buffer = eglGetNativeClientBufferANDROID(buffer);
assert(native_buffer);
auto success = false;

EGL_NATIVE_BUFFER_ANDROID, native_buffer, attrs);
EGL_NATIVE_BUFFER_ANDROID, native_buffer, attrs);
egl_texture_ = 0;
glGenTextures(1, &egl_texture_);

glGenFramebuffers(1, &fbo_);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, egl_texture_, 0);

FML_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
if(buffer != nullptr){
if (buffer != nullptr)
{
if(image){
if (image)
{
eglDestroyImageKHR(egl_display_, image);
glDeleteTextures(1, &egl_texture_);

void UnitySurfaceManager::GetUnityContext()
{
if(egl_unity_context_ != nullptr){
if (egl_unity_context_ != nullptr)
{
FML_CHECK(egl_display_ != EGL_NO_DISPLAY)
<< "Renderer type is invalid";
FML_CHECK(egl_display_ != EGL_NO_DISPLAY)
<< "Renderer type is invalid";
auto *graphics = unity_interfaces->Get<IUnityGraphics>();
UnityGfxRenderer renderer = graphics->GetRenderer();
FML_DCHECK(renderer == kUnityGfxRendererOpenGLES30 ||
renderer == kUnityGfxRendererOpenGLES20 ||
renderer == kUnityGfxRendererVulkan);
if (renderer == kUnityGfxRendererVulkan)
{
m_UnityVulkan = unity_interfaces->Get<IUnityGraphicsVulkan>();
m_Instance = m_UnityVulkan->Instance();
LoadVulkanAPI(m_Instance.getInstanceProcAddr, m_Instance.instance);
egl_display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); // eglGetCurrentDisplay(); //
FML_CHECK(egl_display_ != EGL_NO_DISPLAY);
eglBindAPI(EGL_OPENGL_ES_API);
}
// Initialize the display connection.
FML_CHECK(eglInitialize(egl_display_, nullptr, nullptr) == EGL_TRUE)

18
engine/src/shell/platform/unity/android/unity_surface_manager.h


#include "Unity/IUnityGraphics.h"
#include "Unity/IUnityGraphicsVulkan.h"
#include "include/gpu/vk/GrVkBackendContext.h"
namespace uiwidgets
{

GLuint CreateRenderSurface(size_t width, size_t height);
void DestroyRenderSurface();
GLuint GetTexture() {return egl_texture_;}
void* GetTexture() {
if( m_UnityVulkan != nullptr){
return (void*)&vk_Image_;
}
return (void*)egl_texture_;
}
bool ClearCurrent();

EGLImageKHR image;
bool initialize_succeeded_;
IUnityGraphicsVulkan* m_UnityVulkan = nullptr;
UnityVulkanInstance m_Instance;
sk_sp<GrContext> gr_context_;
sk_sp<SkSurface> m_SkSurface;
VkImage vk_Image_ = 0;
VkDeviceMemory memory;
GLuint fbo_ = 0;
};
正在加载...
取消
保存