diff --git a/c_api/include/taichi/taichi_opengl.h b/c_api/include/taichi/taichi_opengl.h index 0522de61ce047..925e1f8a75c9f 100644 --- a/c_api/include/taichi/taichi_opengl.h +++ b/c_api/include/taichi/taichi_opengl.h @@ -6,6 +6,21 @@ extern "C" { #endif // __cplusplus +// Structure `TiOpenglRuntimeInteropInfo` +typedef struct TiOpenglRuntimeInteropInfo { + void *get_proc_addr; +} TiOpenglRuntimeInteropInfo; + +// Function `ti_import_opengl_runtime` +TI_DLL_EXPORT void TI_API_CALL +ti_import_opengl_runtime(TiRuntime runtime, + TiOpenglRuntimeInteropInfo *interop_info); + +// Function `ti_export_opengl_runtime` +TI_DLL_EXPORT void TI_API_CALL +ti_export_opengl_runtime(TiRuntime runtime, + TiOpenglRuntimeInteropInfo *interop_info); + // Structure `TiOpenglMemoryInteropInfo` typedef struct TiOpenglMemoryInteropInfo { GLuint buffer; diff --git a/c_api/src/taichi_opengl_impl.cpp b/c_api/src/taichi_opengl_impl.cpp index dc52e5ab2ac27..ff9d7f290c350 100644 --- a/c_api/src/taichi_opengl_impl.cpp +++ b/c_api/src/taichi_opengl_impl.cpp @@ -3,6 +3,7 @@ OpenglRuntime::OpenglRuntime() : GfxRuntime(taichi::Arch::opengl), + device_(), gfx_runtime_(taichi::lang::gfx::GfxRuntime::Params{ host_result_buffer_.data(), &device_}) { taichi::lang::DeviceCapabilityConfig caps{}; @@ -18,6 +19,14 @@ taichi::lang::gfx::GfxRuntime &OpenglRuntime::get_gfx_runtime() { return gfx_runtime_; } +void ti_export_opengl_runtime(TiRuntime runtime, + TiOpenglRuntimeInteropInfo *interop_info) { + TI_CAPI_TRY_CATCH_BEGIN(); + // FIXME: (penguinliogn) + interop_info->get_proc_addr = taichi::lang::opengl::kGetOpenglProcAddr; + TI_CAPI_TRY_CATCH_END(); +} + void ti_export_opengl_memory(TiRuntime runtime, TiMemory memory, TiOpenglMemoryInteropInfo *interop_info) { diff --git a/c_api/src/taichi_vulkan_impl.cpp b/c_api/src/taichi_vulkan_impl.cpp index 426d0ab35145a..51c583b579380 100644 --- a/c_api/src/taichi_vulkan_impl.cpp +++ b/c_api/src/taichi_vulkan_impl.cpp @@ -26,6 +26,8 @@ VulkanRuntimeImported::Workaround::Workaround( taichi::lang::vulkan::VulkanLoader::instance().load_instance(params.instance); taichi::lang::vulkan::VulkanLoader::instance().load_device(params.device); vk_device.vk_caps().vk_api_version = api_version; + // FIXME: (penguinliong) Workaround missing vulkan caps from import. + vk_device.vk_caps().external_memory = true; taichi::lang::DeviceCapabilityConfig caps{}; diff --git a/c_api/taichi.json b/c_api/taichi.json index 94d7ea041afa2..4a7edf819820d 100644 --- a/c_api/taichi.json +++ b/c_api/taichi.json @@ -1248,6 +1248,44 @@ "taichi/taichi_core.h" ], "declarations": [ + { + "name": "opengl_runtime_interop_info", + "type": "structure", + "fields": [ + { + "name": "get_proc_addr", + "type": "void*" + } + ] + }, + { + "name": "import_opengl_runtime", + "type": "function", + "parameters": [ + { + "type": "handle.runtime" + }, + { + "name": "interop_info", + "type": "structure.opengl_runtime_interop_info", + "by_mut": true + } + ] + }, + { + "name": "export_opengl_runtime", + "type": "function", + "parameters": [ + { + "type": "handle.runtime" + }, + { + "name": "interop_info", + "type": "structure.opengl_runtime_interop_info", + "by_mut": true + } + ] + }, { "name": "opengl_memory_interop_info", "type": "structure", diff --git a/taichi/rhi/opengl/opengl_api.cpp b/taichi/rhi/opengl/opengl_api.cpp index a374e9c9e415a..b784351024f7e 100644 --- a/taichi/rhi/opengl/opengl_api.cpp +++ b/taichi/rhi/opengl/opengl_api.cpp @@ -24,6 +24,7 @@ int opengl_max_grid_dim = 1024; // without this global static boolean. static bool kUseGles = false; static std::optional supported; // std::nullopt +void *kGetOpenglProcAddr; static void glfw_error_callback(int code, const char *description) { TI_WARN("GLFW Error {}: {}", code, description); @@ -44,6 +45,7 @@ bool initialize_opengl(bool use_gles, bool error_tolerance) { // Code below is guaranteed to be called at most once. int opengl_version = 0; + void *get_proc_addr = nullptr; if (glfwInit()) { glfwSetErrorCallback(glfw_error_callback); @@ -53,7 +55,6 @@ bool initialize_opengl(bool use_gles, bool error_tolerance) { glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); } else { - glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); @@ -73,6 +74,7 @@ bool initialize_opengl(bool use_gles, bool error_tolerance) { TI_DEBUG("[glsl] cannot create GLFW window: error {}: {}", status, desc); } else { glfwMakeContextCurrent(window); + get_proc_addr = (void *)&glfwGetProcAddress; if (use_gles) { opengl_version = gladLoadGLES2(glfwGetProcAddress); } else { @@ -148,6 +150,7 @@ bool initialize_opengl(bool use_gles, bool error_tolerance) { eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_context); + get_proc_addr = (void *)&glad_eglGetProcAddress; if (use_gles) { opengl_version = gladLoadGLES2(glad_eglGetProcAddress); } else { @@ -194,6 +197,7 @@ bool initialize_opengl(bool use_gles, bool error_tolerance) { supported = std::make_optional(true); kUseGles = use_gles; + kGetOpenglProcAddr = get_proc_addr; return true; } diff --git a/taichi/rhi/opengl/opengl_device.cpp b/taichi/rhi/opengl/opengl_device.cpp index 759edb1637f43..be6e587f30a13 100644 --- a/taichi/rhi/opengl/opengl_device.cpp +++ b/taichi/rhi/opengl/opengl_device.cpp @@ -489,6 +489,7 @@ void GLStream::command_sync() { } GLDevice::GLDevice() : stream_(this) { + initialize_opengl(false, true); DeviceCapabilityConfig caps{}; if (!is_gles()) { // 64bit isn't supported in ES profile @@ -555,9 +556,9 @@ GLint GLDevice::get_devalloc_size(DeviceAllocation handle) { GLint size = 0; glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); check_opengl_error("glGetBufferParameteriv"); - return size; glBindBuffer(GL_ARRAY_BUFFER, 0); check_opengl_error("glBindBuffer"); + return size; } std::unique_ptr GLDevice::create_pipeline( @@ -871,7 +872,9 @@ void GLCommandList::CmdImageToBuffer::execute() { (void *)offset); check_opengl_error("glGetTexImage"); glBindTexture(image_dims, /*target=*/0); + check_opengl_error("glBindTexture"); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, /*target=*/0); + check_opengl_error("glBindBuffer"); } } // namespace opengl diff --git a/taichi/rhi/opengl/opengl_device.h b/taichi/rhi/opengl/opengl_device.h index 7645aaf1c002f..1ea7a427123c6 100644 --- a/taichi/rhi/opengl/opengl_device.h +++ b/taichi/rhi/opengl/opengl_device.h @@ -11,6 +11,7 @@ namespace opengl { class GLDevice; void check_opengl_error(const std::string &msg = "OpenGL"); +extern void *kGetOpenglProcAddr; class GLResourceSet : public ShaderResourceSet { public: