Migrate software rendering stack from OSMesa to EGL Surfaceless.
- Removed OSMesa support and associated files (PlatformOSMesa, BlueGLOSMesa). - Implemented universal EGL Surfaceless support for macOS and Linux. - Added BlueEGL dynamic loading layer to resolve EGL symbols at runtime, removing link-time dependency on libEGL. - Patched Mesa build system for macOS to support EGL without X11 or DRI3. - Added workaround for Mesa/macOS multi-threaded shader specialization issues by forcing synchronous compilation. - Correctly filter Vulkan instance extensions to avoid crashes on non-Metal drivers. - Verified rendering correctness via renderdiff on macOS using llvmpipe (OpenGL and WebGPU).
This commit is contained in:
@@ -33,7 +33,7 @@ option(FILAMENT_SUPPORTS_XCB "Include XCB support in Linux builds" ON)
|
||||
|
||||
option(FILAMENT_SUPPORTS_XLIB "Include XLIB support in Linux builds" ON)
|
||||
|
||||
option(FILAMENT_SUPPORTS_EGL_ON_LINUX "Use EGL for OpenGL in Linux builds" OFF)
|
||||
option(FILAMENT_SUPPORTS_EGL_ON_DESKTOP "Use EGL for OpenGL in Linux builds" OFF)
|
||||
|
||||
option(FILAMENT_SUPPORTS_WAYLAND "Include Wayland support in Linux builds" OFF)
|
||||
|
||||
@@ -51,8 +51,6 @@ option(FILAMENT_ENABLE_FEATURE_LEVEL_0 "Enable Feature Level 0" ON)
|
||||
|
||||
option(FILAMENT_ENABLE_MULTIVIEW "Enable multiview for Filament" OFF)
|
||||
|
||||
option(FILAMENT_SUPPORTS_OSMESA "Enable OSMesa (headless GL context) for Filament" OFF)
|
||||
|
||||
option(FILAMENT_ENABLE_FGVIEWER "Enable the frame graph viewer" OFF)
|
||||
|
||||
option(FILAMENT_USE_ABSEIL_LOGGING "Use Abseil to log, may increase binary size" OFF)
|
||||
@@ -157,23 +155,13 @@ else()
|
||||
set(LINUX FALSE)
|
||||
endif()
|
||||
|
||||
if (NOT FILAMENT_OSMESA_PATH STREQUAL "")
|
||||
if (NOT EXISTS ${FILAMENT_OSMESA_PATH}/)
|
||||
message(FATAL_ERROR "Cannot find specified OSMesa build directory: ${FILAMENT_OSMESA_PATH}")
|
||||
endif()
|
||||
set(FILAMENT_SUPPORTS_OSMESA TRUE)
|
||||
endif()
|
||||
|
||||
if (LINUX)
|
||||
if (FILAMENT_SUPPORTS_WAYLAND)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_WAYLAND)
|
||||
set(FILAMENT_SUPPORTS_X11 FALSE)
|
||||
elseif (FILAMENT_SUPPORTS_EGL_ON_LINUX)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_EGL_ON_LINUX)
|
||||
elseif (FILAMENT_SUPPORTS_EGL_ON_DESKTOP)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_EGL_ON_DESKTOP)
|
||||
set(FILAMENT_SUPPORTS_X11 FALSE)
|
||||
elseif (FILAMENT_SUPPORTS_OSMESA)
|
||||
set(FILAMENT_SUPPORTS_X11 FALSE)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_OSMESA)
|
||||
else ()
|
||||
if (FILAMENT_SUPPORTS_XCB)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_XCB)
|
||||
@@ -203,8 +191,8 @@ if (NOT ANDROID AND NOT WEBGL AND NOT IOS AND NOT FILAMENT_LINUX_IS_MOBILE)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
if (FILAMENT_SUPPORTS_OSMESA)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_OSMESA)
|
||||
if (FILAMENT_SUPPORTS_EGL_ON_DESKTOP)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_EGL_ON_DESKTOP)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -362,7 +350,7 @@ if (FILAMENT_USE_EXTERNAL_GLES3)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFILAMENT_USE_EXTERNAL_GLES3")
|
||||
endif()
|
||||
|
||||
if (FILAMENT_SUPPORTS_EGL_ON_LINUX)
|
||||
if (FILAMENT_SUPPORTS_EGL_ON_DESKTOP)
|
||||
set(EGL TRUE)
|
||||
endif()
|
||||
|
||||
@@ -1005,3 +993,4 @@ endif()
|
||||
if ((NOT CMAKE_CROSSCOMPILING AND NOT FILAMENT_IMPORT_PREBUILT_EXECUTABLES) OR FILAMENT_EXPORT_PREBUILT_EXECUTABLES)
|
||||
export(TARGETS matc cmgen filamesh mipgen resgen uberz glslminifier FILE ${IMPORT_EXECUTABLES})
|
||||
endif()
|
||||
|
||||
|
||||
15
build.sh
15
build.sh
@@ -198,7 +198,7 @@ VULKAN_ANDROID_GRADLE_OPTION=""
|
||||
WEBGPU_OPTION="-DFILAMENT_SUPPORTS_WEBGPU=OFF"
|
||||
WEBGPU_ANDROID_GRADLE_OPTION=""
|
||||
|
||||
EGL_ON_LINUX_OPTION="-DFILAMENT_SUPPORTS_EGL_ON_LINUX=OFF"
|
||||
EGL_ON_LINUX_OPTION="-DFILAMENT_SUPPORTS_EGL_ON_DESKTOP=OFF"
|
||||
|
||||
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=OFF"
|
||||
MATDBG_GRADLE_OPTION=""
|
||||
@@ -216,8 +216,6 @@ BACKEND_DEBUG_FLAG_OPTION=""
|
||||
|
||||
STEREOSCOPIC_OPTION=""
|
||||
|
||||
OSMESA_OPTION=""
|
||||
|
||||
IOS_BUILD_SIMULATOR=false
|
||||
BUILD_UNIVERSAL_LIBRARIES=false
|
||||
|
||||
@@ -308,7 +306,7 @@ function build_desktop_target {
|
||||
${IMPORT_EXECUTABLES_DIR_OPTION} \
|
||||
-DCMAKE_BUILD_TYPE="$1" \
|
||||
-DCMAKE_INSTALL_PREFIX="../${lc_target}/filament" \
|
||||
${EGL_ON_LINUX_OPTION} \
|
||||
${EGL_ON_DESKTOP_OPTION} \
|
||||
${FGVIEWER_OPTION} \
|
||||
${WEBGPU_OPTION} \
|
||||
${MATDBG_OPTION} \
|
||||
@@ -317,7 +315,6 @@ function build_desktop_target {
|
||||
${COVERAGE_OPTION} \
|
||||
${BACKEND_DEBUG_FLAG_OPTION} \
|
||||
${STEREOSCOPIC_OPTION} \
|
||||
${OSMESA_OPTION} \
|
||||
${architectures} \
|
||||
../..
|
||||
ln -sf "out/cmake-${lc_target}/compile_commands.json" \
|
||||
@@ -858,7 +855,7 @@ function check_debug_release_build {
|
||||
|
||||
pushd "$(dirname "$0")" > /dev/null
|
||||
|
||||
while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:Py:" opt; do
|
||||
while getopts ":hacCfgimp:q:uvWslwE:dtk:bVx:S:X:Py:" opt; do
|
||||
case ${opt} in
|
||||
h)
|
||||
print_help
|
||||
@@ -987,10 +984,6 @@ while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:Py:" opt; do
|
||||
IOS_BUILD_SIMULATOR=true
|
||||
echo "iOS simulator support enabled."
|
||||
;;
|
||||
e)
|
||||
EGL_ON_LINUX_OPTION="-DFILAMENT_SUPPORTS_EGL_ON_LINUX=ON -DFILAMENT_SKIP_SDL2=ON -DFILAMENT_SKIP_SAMPLES=ON"
|
||||
echo "EGL on Linux support enabled; skipping SDL2."
|
||||
;;
|
||||
l)
|
||||
IOS_BUILD_SIMULATOR=true
|
||||
BUILD_UNIVERSAL_LIBRARIES=true
|
||||
@@ -1025,7 +1018,7 @@ while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:Py:" opt; do
|
||||
exit 1
|
||||
esac
|
||||
;;
|
||||
X) OSMESA_OPTION="-DFILAMENT_OSMESA_PATH=${OPTARG}"
|
||||
E) EGL_ON_DESKTOP_OPTION="-DFILAMENT_SUPPORTS_EGL_ON_DESKTOP=ON -DFILAMENT_EGL_PATH=${OPTARG}"
|
||||
;;
|
||||
y)
|
||||
ISSUE_SPLIT_BUILD=true
|
||||
|
||||
@@ -137,9 +137,12 @@ mkdir -p out
|
||||
source ${ORIG_DIR}/venv/bin/activate
|
||||
|
||||
if [[ "$OS_NAME" == "Darwin" ]]; then
|
||||
LOCAL_LDFLAGS="-L/opt/homebrew/opt/llvm@${LLVM_VERSION}/lib"
|
||||
LOCAL_CPPFLAGS="-I/opt/homebrew/opt/llvm@${LLVM_VERSION}/include -I/opt/homebrew/include"
|
||||
LOCAL_PATH=${PATH}:/opt/homebrew/opt/llvm@${LLVM_VERSION}/bin
|
||||
# Ensure Homebrew and LLVM paths are correctly set for the linker and compiler
|
||||
HOMEBREW_PREFIX=$(brew --prefix)
|
||||
LOCAL_LDFLAGS="-L${HOMEBREW_PREFIX}/lib -L${HOMEBREW_PREFIX}/opt/llvm@${LLVM_VERSION}/lib"
|
||||
LOCAL_CPPFLAGS="-I${HOMEBREW_PREFIX}/include -I${HOMEBREW_PREFIX}/opt/llvm@${LLVM_VERSION}/include"
|
||||
LOCAL_PATH=${PATH}:${HOMEBREW_PREFIX}/opt/llvm@${LLVM_VERSION}/bin
|
||||
LOCAL_PKG_CONFIG_PATH="${HOMEBREW_PREFIX}/lib/pkgconfig:${HOMEBREW_PREFIX}/opt/llvm@${LLVM_VERSION}/lib/pkgconfig"
|
||||
|
||||
# This is necessary to be able to build vk (lavapipe) on macOS. Doesn't seem like a real dependency.
|
||||
sed -I '' "s/error('Vulkan drivers require dri3 for X11 support')//g" meson.build
|
||||
@@ -148,13 +151,39 @@ if [[ "$OS_NAME" == "Darwin" ]]; then
|
||||
sed -I '' "s/dep_xcb_present = null_dep/dep_xcb_present = dependency('xcb-present')/g" meson.build
|
||||
fi
|
||||
|
||||
# Modify mesa to allow building EGL surfaceless without X11 or DRI
|
||||
python3 - <<EOF
|
||||
import os
|
||||
path = 'meson.build'
|
||||
with open(path, 'r') as f:
|
||||
content = f.read()
|
||||
content = content.replace(
|
||||
"""with_egl = get_option('egl') \\
|
||||
.require(with_platform_windows or with_platform_haiku or with_dri or with_platform_android, error_message : 'EGL requires DRI, Haiku, Windows or Android') \\
|
||||
.require(with_shared_glapi, error_message : 'EGL requires shared-glapi') \\
|
||||
.require(with_glx != 'xlib', error_message :'EGL requires DRI, but GLX is being built with xlib support') \\
|
||||
.disable_auto_if(with_platform_haiku) \\
|
||||
.allowed()""",
|
||||
"""with_egl = get_option('egl') \\
|
||||
.require(with_shared_glapi, error_message : 'EGL requires shared-glapi') \\
|
||||
.disable_auto_if(with_platform_haiku) \\
|
||||
.allowed()"""
|
||||
)
|
||||
content = content.replace(
|
||||
"with_dri = false",
|
||||
"with_dri = true"
|
||||
)
|
||||
with open(path, 'w') as f:
|
||||
f.write(content)
|
||||
EOF
|
||||
|
||||
# -Dosmesa=true => builds OSMesa, which is an offscreen GL context
|
||||
# -Dgallium-drivers=swrast => builds GL software rasterizer
|
||||
# -Dvulkan-drivers=swrast => builds VK software rasterizer
|
||||
# -Dgallium-drivers=llvmpipe is needed for GL >= 4.1 pipe-screen (see src/gallium/auxiliary/target-helpers/inline_sw_helper.h)
|
||||
PKG_CONFIG_PATH=${LOCAL_PKG_CONFIG_PATH} PATH=${LOCAL_PATH} \
|
||||
CXX=${LOCAL_CXX} CC=${LOCAL_CC} LDFLAGS=${LOCAL_LDFLAGS} CPPFLAGS=${LOCAL_CPPFLAGS} \
|
||||
meson setup --wipe builddir/ -Dprefix="${MESA_DIR}/out" -Dglx=xlib -Dosmesa=true -Dgallium-drivers=llvmpipe,swrast -Dvulkan-drivers=swrast
|
||||
meson setup --wipe builddir/ -Dprefix="${MESA_DIR}/out" -Dglx=disabled -Degl=enabled -Dosmesa=false -Dplatforms= -Dgallium-drivers=llvmpipe,swrast -Dvulkan-drivers=swrast -Dshared-glapi=enabled
|
||||
PKG_CONFIG_PATH=${LOCAL_PKG_CONFIG_PATH} PATH=${LOCAL_PATH} \
|
||||
CXX=${LOCAL_CXX} CC=${LOCAL_CC} LDFLAGS=${LOCAL_LDFLAGS} CPPFLAGS=${LOCAL_CPPFLAGS} \
|
||||
meson install -C builddir/
|
||||
|
||||
@@ -116,8 +116,8 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformCocoaTouchGL.mm)
|
||||
list(APPEND SRCS src/opengl/platforms/CocoaTouchExternalImage.mm)
|
||||
elseif (APPLE)
|
||||
if (FILAMENT_SUPPORTS_OSMESA)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformOSMesa.cpp)
|
||||
if (FILAMENT_SUPPORTS_EGL_ON_DESKTOP)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformEGLHeadless.cpp)
|
||||
else()
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformCocoaGL.mm)
|
||||
list(APPEND SRCS src/opengl/platforms/CocoaExternalImage.mm)
|
||||
@@ -127,10 +127,8 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3)
|
||||
elseif (LINUX)
|
||||
if (FILAMENT_SUPPORTS_X11)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformGLX.cpp)
|
||||
elseif (FILAMENT_SUPPORTS_EGL_ON_LINUX)
|
||||
elseif (FILAMENT_SUPPORTS_EGL_ON_DESKTOP)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformEGLHeadless.cpp)
|
||||
elseif (FILAMENT_SUPPORTS_OSMESA)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformOSMesa.cpp)
|
||||
endif()
|
||||
elseif (WIN32)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformWGL.cpp)
|
||||
@@ -449,9 +447,6 @@ endif()
|
||||
|
||||
if (LINUX)
|
||||
target_link_libraries(${TARGET} PRIVATE dl)
|
||||
if(FILAMENT_SUPPORTS_EGL_ON_LINUX)
|
||||
target_link_libraries(${TARGET} PUBLIC EGL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
@@ -487,12 +482,9 @@ set(LINUX_LINKER_OPTIMIZATION_FLAGS
|
||||
-Wl,--exclude-libs,bluegl
|
||||
)
|
||||
|
||||
if (FILAMENT_SUPPORTS_OSMESA)
|
||||
if (LINUX)
|
||||
set(OSMESA_COMPILE_FLAGS -I${FILAMENT_OSMESA_PATH}/include/GL)
|
||||
elseif (APPLE)
|
||||
set(OSMESA_COMPILE_FLAGS -I${FILAMENT_OSMESA_PATH}/include)
|
||||
endif()
|
||||
if (FILAMENT_SUPPORTS_EGL_ON_DESKTOP AND NOT FILAMENT_EGL_PATH STREQUAL "")
|
||||
target_include_directories(${TARGET} PRIVATE ${FILAMENT_EGL_PATH}/include)
|
||||
target_include_directories(${TARGET} PRIVATE ${FILAMENT_EGL_PATH}/../include)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_OSMESA_H
|
||||
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_OSMESA_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "bluegl/BlueGL.h"
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <osmesa.h>
|
||||
#elif defined(__APPLE__)
|
||||
#undef GLAPI
|
||||
#include <GL/osmesa.h>
|
||||
#endif
|
||||
|
||||
#include <backend/platforms/OpenGLPlatform.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
/**
|
||||
* A concrete implementation of OpenGLPlatform that uses OSMesa, which is an offscreen
|
||||
* context that can be used in conjunction with Mesa for software rasterization.
|
||||
* See https://docs.mesa3d.org/osmesa.html for more information.
|
||||
*/
|
||||
class PlatformOSMesa : public OpenGLPlatform {
|
||||
protected:
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Platform Interface
|
||||
|
||||
Driver* createDriver(void* sharedGLContext, const DriverConfig& driverConfig) override;
|
||||
|
||||
int getOSVersion() const noexcept final override { return 0; }
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// OpenGLPlatform Interface
|
||||
|
||||
void terminate() noexcept override;
|
||||
|
||||
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
|
||||
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
|
||||
void destroySwapChain(SwapChain* swapChain) noexcept override;
|
||||
bool makeCurrent(ContextType type, SwapChain* drawSwapChain,
|
||||
SwapChain* readSwapChain) override;
|
||||
void commit(SwapChain* swapChain) noexcept override;
|
||||
|
||||
private:
|
||||
OSMesaContext mContext;
|
||||
void* mOsMesaApi = nullptr;
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_OSMESA_H
|
||||
@@ -44,8 +44,8 @@
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
|
||||
#if defined(FILAMENT_SUPPORTS_OSMESA)
|
||||
#include <backend/platforms/PlatformOSMesa.h>
|
||||
#if defined(FILAMENT_SUPPORTS_EGL_ON_DESKTOP)
|
||||
#include <backend/platforms/PlatformEGLHeadless.h>
|
||||
#else
|
||||
#include <backend/platforms/PlatformCocoaGL.h>
|
||||
#endif
|
||||
@@ -55,14 +55,10 @@
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
|
||||
#include "backend/platforms/PlatformGLX.h"
|
||||
#endif
|
||||
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
|
||||
#elif defined(FILAMENT_SUPPORTS_EGL_ON_DESKTOP)
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
|
||||
#include "backend/platforms/PlatformEGLHeadless.h"
|
||||
#endif
|
||||
#elif defined(FILAMENT_SUPPORTS_OSMESA)
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
|
||||
#include "backend/platforms/PlatformOSMesa.h"
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(WIN32)
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
|
||||
@@ -175,18 +171,16 @@ Platform* PlatformFactory::create(Backend* backend) noexcept {
|
||||
#elif defined(FILAMENT_IOS)
|
||||
return new PlatformCocoaTouchGL();
|
||||
#elif defined(__APPLE__)
|
||||
#if defined(FILAMENT_SUPPORTS_OSMESA)
|
||||
return new PlatformOSMesa();
|
||||
#if defined(FILAMENT_SUPPORTS_EGL_ON_DESKTOP)
|
||||
return new PlatformEGLHeadless();
|
||||
#else
|
||||
return new PlatformCocoaGL();
|
||||
#endif
|
||||
#elif defined(__linux__)
|
||||
#if defined(FILAMENT_SUPPORTS_X11)
|
||||
return new PlatformGLX();
|
||||
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
|
||||
#elif defined(FILAMENT_SUPPORTS_EGL_ON_DESKTOP)
|
||||
return new PlatformEGLHeadless();
|
||||
#elif defined(FILAMENT_SUPPORTS_OSMESA)
|
||||
return new PlatformOSMesa();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
|
||||
@@ -222,6 +222,17 @@ void ShaderCompilerService::init() noexcept {
|
||||
}
|
||||
|
||||
if (mMode == Mode::THREAD_POOL) {
|
||||
char const* const renderer = mDriver.getContext().state.renderer;
|
||||
|
||||
#ifdef __APPLE__
|
||||
if (UTILS_UNLIKELY(strstr(renderer, "Mesa") || strstr(renderer, "llvmpipe"))) {
|
||||
// Mesa on macOS has issues with shared contexts and shader specialization/linking
|
||||
// across threads, leading to "linking with uncompiled/unspecialized shader" errors.
|
||||
mMode = Mode::SYNCHRONOUS;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// - on Adreno there is a single compiler object. We can't use a pool > 1
|
||||
// also glProgramBinary blocks if other threads are compiling.
|
||||
// - on Mali shader compilation can be multithreaded, but program linking happens on
|
||||
@@ -237,7 +248,6 @@ void ShaderCompilerService::init() noexcept {
|
||||
uint32_t poolSize = 1;
|
||||
JobSystem::Priority priority = JobSystem::Priority::DISPLAY;
|
||||
|
||||
auto const& renderer = mDriver.getContext().state.renderer;
|
||||
// Some drivers support parallel shader compilation well, so we use N
|
||||
// threads, we can use lower priority threads here because urgent compilations
|
||||
// will most likely happen on the main gl thread. Using too many thread can
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#if defined(__ANDROID__) || defined(FILAMENT_USE_EXTERNAL_GLES3) || defined(__EMSCRIPTEN__) || defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
|
||||
#if defined(__ANDROID__) || defined(FILAMENT_USE_EXTERNAL_GLES3) || defined(__EMSCRIPTEN__) || (defined(FILAMENT_SUPPORTS_EGL_ON_DESKTOP) && defined(__linux__))
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
# include <GLES3/gl3.h>
|
||||
@@ -62,7 +62,6 @@
|
||||
|
||||
#include <OpenGLES/ES3/gl.h>
|
||||
#include <OpenGLES/ES3/glext.h>
|
||||
|
||||
#else
|
||||
|
||||
// bluegl exposes symbols prefixed with bluegl_ to avoid clashing with clients that also link
|
||||
@@ -74,6 +73,11 @@
|
||||
#include <bluegl/BlueGLDefines.h>
|
||||
#include <bluegl/BlueGL.h>
|
||||
|
||||
extern "C" {
|
||||
void glFramebufferTextureMultiviewOVR(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);
|
||||
void glFramebufferTextureMultisampleMultiviewOVR(GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Validate the header configurations we aim to support */
|
||||
|
||||
@@ -23,9 +23,7 @@
|
||||
#include <backend/Platform.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <EGL/eglplatform.h>
|
||||
#include <bluegl/BlueEGL.h>
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include <sys/system_properties.h>
|
||||
@@ -130,7 +128,20 @@ void PlatformEGL::setEglDisplay(EGLDisplay display) noexcept {
|
||||
|
||||
Driver* PlatformEGL::createDriver(void* sharedContext, const DriverConfig& driverConfig) {
|
||||
if (mEGLDisplay == EGL_NO_DISPLAY) {
|
||||
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
|
||||
PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplayEXT =
|
||||
(PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
|
||||
|
||||
if (getPlatformDisplayEXT) {
|
||||
// 0x31DD is EGL_PLATFORM_SURFACELESS_MESA
|
||||
mEGLDisplay = getPlatformDisplayEXT(0x31DD, (void*)EGL_DEFAULT_DISPLAY, nullptr);
|
||||
}
|
||||
|
||||
if (mEGLDisplay == EGL_NO_DISPLAY) {
|
||||
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
}
|
||||
|
||||
assert_invariant(mEGLDisplay != EGL_NO_DISPLAY);
|
||||
|
||||
EGLint major, minor;
|
||||
@@ -196,9 +207,11 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const DriverConfig& drive
|
||||
Config contextAttribs;
|
||||
|
||||
if (isOpenGL()) {
|
||||
// Request a OpenGL 4.1 context
|
||||
// Request a OpenGL 4.1 Core Profile context
|
||||
contextAttribs[EGL_CONTEXT_MAJOR_VERSION] = 4;
|
||||
contextAttribs[EGL_CONTEXT_MINOR_VERSION] = 1;
|
||||
contextAttribs[EGL_CONTEXT_OPENGL_PROFILE_MASK] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT;
|
||||
contextAttribs[EGL_CONTEXT_FLAGS_KHR] = EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
||||
} else {
|
||||
// Request a ES2 context, devices that support ES3 will return an ES3 context
|
||||
contextAttribs[EGL_CONTEXT_CLIENT_VERSION] = 2;
|
||||
@@ -717,11 +730,20 @@ bool PlatformEGL::setExternalImage(ExternalImageHandleRef externalImage,
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
|
||||
void PlatformEGL::initializeGlExtensions() noexcept {
|
||||
const char* const extensions = (const char*)glGetString(GL_EXTENSIONS);
|
||||
if (extensions) {
|
||||
GLUtils::unordered_string_set const glExtensions = GLUtils::split(extensions);
|
||||
ext.gl.OES_EGL_image_external_essl3 = glExtensions.has("GL_OES_EGL_image_external_essl3");
|
||||
GLUtils::unordered_string_set glExtensions;
|
||||
if (isOpenGL()) {
|
||||
GLint n = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &n);
|
||||
for (GLint i = 0; i < n; i++) {
|
||||
glExtensions.emplace((const char*)glGetStringi(GL_EXTENSIONS, (GLuint)i));
|
||||
}
|
||||
} else {
|
||||
const char* const extensions = (const char*)glGetString(GL_EXTENSIONS);
|
||||
if (extensions) {
|
||||
glExtensions = GLUtils::split(extensions);
|
||||
}
|
||||
}
|
||||
ext.gl.OES_EGL_image_external_essl3 = glExtensions.has("GL_OES_EGL_image_external_essl3");
|
||||
}
|
||||
|
||||
EGLContext PlatformEGL::getContextForType(ContextType const type) const noexcept {
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
#include <backend/platforms/PlatformEGLHeadless.h>
|
||||
|
||||
#include <bluegl/BlueGL.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <bluegl/BlueEGL.h>
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
@@ -44,6 +42,12 @@ bool PlatformEGLHeadless::isOpenGL() const noexcept {
|
||||
|
||||
backend::Driver* PlatformEGLHeadless::createDriver(void* sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) {
|
||||
int bindBlueGL = bluegl::bind();
|
||||
if (UTILS_UNLIKELY(bindBlueGL != 0)) {
|
||||
LOG(ERROR) << "bluegl bind failed";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto bindApiHelper = [](EGLenum api, const char* errorString) -> bool {
|
||||
EGLBoolean bindAPI = eglBindAPI(api);
|
||||
if (UTILS_UNLIKELY(bindAPI == EGL_FALSE || bindAPI == EGL_BAD_PARAMETER)) {
|
||||
@@ -60,12 +64,6 @@ backend::Driver* PlatformEGLHeadless::createDriver(void* sharedContext,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int bindBlueGL = bluegl::bind();
|
||||
if (UTILS_UNLIKELY(bindBlueGL != 0)) {
|
||||
LOG(ERROR) << "bluegl bind failed";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return PlatformEGL::createDriver(sharedContext, driverConfig);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <backend/platforms/PlatformOSMesa.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Panic.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <memory>
|
||||
|
||||
#if defined(__linux__)
|
||||
// This is to ensure that linking during compilation will not fail even if
|
||||
// OSMesaGetProcAddress is not linked.
|
||||
__attribute__((weak)) OSMESAproc OSMesaGetProcAddress(char const*);
|
||||
#endif
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
using namespace backend;
|
||||
|
||||
namespace {
|
||||
|
||||
using BackingType = GLfloat;
|
||||
#define BACKING_GL_TYPE GL_FLOAT
|
||||
|
||||
struct OSMesaSwapchain {
|
||||
OSMesaSwapchain(uint32_t width, uint32_t height)
|
||||
: width(width),
|
||||
height(height),
|
||||
buffer(new uint8_t[width * height * 4 * sizeof(BackingType)]) {}
|
||||
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
std::unique_ptr<uint8_t[]> buffer;
|
||||
};
|
||||
|
||||
struct OSMesaAPI {
|
||||
private:
|
||||
using CreateContextAttribsFunc = OSMesaContext (*)(const int *, OSMesaContext);
|
||||
using DestroyContextFunc = GLboolean (*)(OSMesaContext);
|
||||
using MakeCurrentFunc = GLboolean (*)(OSMesaContext ctx, void* buffer, GLenum type,
|
||||
GLsizei width, GLsizei height);
|
||||
using GetProcAddressFunc = OSMESAproc (*)(const char* funcName);
|
||||
|
||||
public:
|
||||
CreateContextAttribsFunc fOSMesaCreateContextAttribs;
|
||||
DestroyContextFunc fOSMesaDestroyContext;
|
||||
MakeCurrentFunc fOSMesaMakeCurrent;
|
||||
GetProcAddressFunc fOSMesaGetProcAddress;
|
||||
|
||||
OSMesaAPI() {
|
||||
static constexpr char const* libraryNames[] = {
|
||||
#if defined(__linux__)
|
||||
"libOSMesa.so",
|
||||
"libosmesa.so",
|
||||
#elif defined(__APPLE__)
|
||||
"libOSMesa.dylib",
|
||||
#endif
|
||||
};
|
||||
for (char const* libName: libraryNames) {
|
||||
mLib = dlopen(libName, RTLD_GLOBAL | RTLD_NOW);
|
||||
if (mLib) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mLib) {
|
||||
// Loading from a libosmesa.os
|
||||
fOSMesaGetProcAddress = (GetProcAddressFunc) dlsym(mLib, "OSMesaGetProcAddress");
|
||||
}
|
||||
#if defined(__linux__)
|
||||
else {
|
||||
// Filament is built into a .so
|
||||
fOSMesaGetProcAddress = (GetProcAddressFunc) dlsym(RTLD_LOCAL, "OSMesaGetProcAddress");
|
||||
}
|
||||
if (!fOSMesaGetProcAddress) {
|
||||
// Statically linking osmesa
|
||||
fOSMesaGetProcAddress = OSMesaGetProcAddress;
|
||||
}
|
||||
#endif // __linux__
|
||||
|
||||
FILAMENT_CHECK_PRECONDITION(fOSMesaGetProcAddress)
|
||||
<< "Unable to link against libOSMesa to create a software GL context";
|
||||
|
||||
fOSMesaCreateContextAttribs =
|
||||
(CreateContextAttribsFunc) fOSMesaGetProcAddress("OSMesaCreateContextAttribs");
|
||||
fOSMesaDestroyContext = (DestroyContextFunc) fOSMesaGetProcAddress("OSMesaDestroyContext");
|
||||
fOSMesaMakeCurrent = (MakeCurrentFunc) fOSMesaGetProcAddress("OSMesaMakeCurrent");
|
||||
}
|
||||
|
||||
~OSMesaAPI() {
|
||||
if (mLib) {
|
||||
dlclose(mLib);
|
||||
}
|
||||
}
|
||||
private:
|
||||
void* mLib = nullptr;
|
||||
};
|
||||
|
||||
}// anonymous namespace
|
||||
|
||||
Driver* PlatformOSMesa::createDriver(void* sharedGLContext,
|
||||
const DriverConfig& driverConfig) {
|
||||
|
||||
OSMesaAPI* api = new OSMesaAPI();
|
||||
mOsMesaApi = api;
|
||||
|
||||
static constexpr int attribs[] = {
|
||||
OSMESA_FORMAT, GL_RGBA,
|
||||
OSMESA_DEPTH_BITS, 24,
|
||||
OSMESA_STENCIL_BITS, 8,
|
||||
OSMESA_ACCUM_BITS, 0,
|
||||
OSMESA_PROFILE, OSMESA_CORE_PROFILE,
|
||||
0,
|
||||
};
|
||||
|
||||
FILAMENT_CHECK_PRECONDITION(sharedGLContext == nullptr)
|
||||
<< "shared GL context is not supported with PlatformOSMesa";
|
||||
mContext = api->fOSMesaCreateContextAttribs(attribs, NULL);
|
||||
|
||||
// We need to do a no-op makecurrent here so that the context will be in a correct state before
|
||||
// any GL calls.
|
||||
auto chain = createSwapChain(1, 1, 0);
|
||||
makeCurrent(ContextType::UNPROTECTED, chain, nullptr);
|
||||
destroySwapChain(chain);
|
||||
|
||||
int result = bluegl::bind();
|
||||
FILAMENT_CHECK_POSTCONDITION(!result) << "Unable to load OpenGL entry points.";
|
||||
|
||||
return OpenGLPlatform::createDefaultDriver(this, sharedGLContext, driverConfig);
|
||||
}
|
||||
|
||||
void PlatformOSMesa::terminate() noexcept {
|
||||
OSMesaAPI* api = (OSMesaAPI*) mOsMesaApi;
|
||||
api->fOSMesaDestroyContext(mContext);
|
||||
delete api;
|
||||
mOsMesaApi = nullptr;
|
||||
|
||||
bluegl::unbind();
|
||||
}
|
||||
|
||||
Platform::SwapChain* PlatformOSMesa::createSwapChain(void* nativeWindow, uint64_t flags) noexcept {
|
||||
FILAMENT_CHECK_POSTCONDITION(false) << "Cannot create non-headless swapchain";
|
||||
return (SwapChain*) nativeWindow;
|
||||
}
|
||||
|
||||
Platform::SwapChain* PlatformOSMesa::createSwapChain(uint32_t width, uint32_t height,
|
||||
uint64_t flags) noexcept {
|
||||
OSMesaSwapchain* swapchain = new OSMesaSwapchain(width, height);
|
||||
return (SwapChain*) swapchain;
|
||||
}
|
||||
|
||||
void PlatformOSMesa::destroySwapChain(Platform::SwapChain* swapChain) noexcept {
|
||||
OSMesaSwapchain* impl = (OSMesaSwapchain*) swapChain;
|
||||
delete impl;
|
||||
}
|
||||
|
||||
bool PlatformOSMesa::makeCurrent(ContextType type, SwapChain* drawSwapChain,
|
||||
SwapChain* readSwapChain) {
|
||||
OSMesaAPI* api = (OSMesaAPI*) mOsMesaApi;
|
||||
OSMesaSwapchain* impl = (OSMesaSwapchain*) drawSwapChain;
|
||||
|
||||
auto result = api->fOSMesaMakeCurrent(mContext, (BackingType*) impl->buffer.get(),
|
||||
BACKING_GL_TYPE, impl->width, impl->height);
|
||||
FILAMENT_CHECK_POSTCONDITION(result == GL_TRUE) << "OSMesaMakeCurrent failed!";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PlatformOSMesa::commit(Platform::SwapChain* swapChain) noexcept {
|
||||
// No-op since we are not scanning out to a display.
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
@@ -580,7 +580,11 @@ Driver* VulkanPlatform::createDriver(void* sharedContext,
|
||||
}
|
||||
#endif
|
||||
|
||||
instExts.merge(getRequiredInstanceExtensions());
|
||||
ExtensionSet const requiredExts = getRequiredInstanceExtensions();
|
||||
ExtensionSet const filteredRequiredExts = getInstanceExtensions(requiredExts);
|
||||
for (auto const& extension : filteredRequiredExts) {
|
||||
instExts.insert(extension);
|
||||
}
|
||||
}
|
||||
if (mImpl->mInstance == VK_NULL_HANDLE) {
|
||||
createInstance(instExts);
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace filament::backend {
|
||||
|
||||
VulkanPlatform::ExtensionSet VulkanPlatformApple::getSwapchainInstanceExtensions() const {
|
||||
ExtensionSet const ret = {
|
||||
VK_KHR_SURFACE_EXTENSION_NAME,
|
||||
VK_EXT_METAL_SURFACE_EXTENSION_NAME,
|
||||
};
|
||||
return ret;
|
||||
|
||||
@@ -31,17 +31,15 @@ if (WIN32)
|
||||
set(SRCS ${SRCS} src/BlueGLCoreWindowsImpl.S)
|
||||
endif()
|
||||
elseif (APPLE AND NOT IOS)
|
||||
if (FILAMENT_SUPPORTS_OSMESA)
|
||||
set(SRCS ${SRCS} src/BlueGLOSMesa.cpp)
|
||||
if (FILAMENT_SUPPORTS_EGL_ON_DESKTOP)
|
||||
set(SRCS ${SRCS} src/BlueGLEGL.cpp)
|
||||
else()
|
||||
set(SRCS ${SRCS} src/BlueGLDarwin.cpp)
|
||||
endif()
|
||||
set(SRCS ${SRCS} src/BlueGLCoreDarwinUniversalImpl.S)
|
||||
elseif(LINUX)
|
||||
if (FILAMENT_SUPPORTS_EGL_ON_LINUX)
|
||||
set(SRCS ${SRCS} src/BlueGLLinuxEGL.cpp)
|
||||
elseif (FILAMENT_SUPPORTS_OSMESA)
|
||||
set(SRCS ${SRCS} src/BlueGLOSMesa.cpp)
|
||||
if (FILAMENT_SUPPORTS_EGL_ON_DESKTOP)
|
||||
set(SRCS ${SRCS} src/BlueGLEGL.cpp)
|
||||
else()
|
||||
set(SRCS ${SRCS} src/BlueGLLinux.cpp)
|
||||
endif()
|
||||
@@ -56,18 +54,15 @@ include_directories(${PUBLIC_HDR_DIR})
|
||||
# we're building a library
|
||||
add_library(${TARGET} STATIC ${PUBLIC_HDRS} ${SRCS})
|
||||
|
||||
if(FILAMENT_SUPPORTS_OSMESA)
|
||||
if (APPLE)
|
||||
target_compile_options(${TARGET} PRIVATE -I${FILAMENT_OSMESA_PATH}/include)
|
||||
else()
|
||||
target_compile_options(${TARGET} PRIVATE -I${FILAMENT_OSMESA_PATH}/include/GL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# specify where the public headers of this library are
|
||||
target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
|
||||
set_target_properties(${TARGET} PROPERTIES FOLDER Libs)
|
||||
|
||||
if (FILAMENT_SUPPORTS_EGL_ON_DESKTOP AND NOT FILAMENT_EGL_PATH STREQUAL "")
|
||||
target_include_directories(${TARGET} PRIVATE ${FILAMENT_EGL_PATH}/include)
|
||||
target_include_directories(${TARGET} PRIVATE ${FILAMENT_EGL_PATH}/../include)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(${TARGET} PRIVATE opengl32 gdi32)
|
||||
endif()
|
||||
|
||||
161
libs/bluegl/include/bluegl/BlueEGL.h
Normal file
161
libs/bluegl/include/bluegl/BlueEGL.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (C) 2025 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_BLUEGL_BLUEEGL_H
|
||||
#define TNT_BLUEGL_BLUEEGL_H
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define EGL_PLATFORM_SURFACELESS_MESA 0x31DD
|
||||
|
||||
extern void* bluegl_eglGetProcAddress;
|
||||
extern void* bluegl_eglGetDisplay;
|
||||
extern void* bluegl_eglInitialize;
|
||||
extern void* bluegl_eglTerminate;
|
||||
extern void* bluegl_eglBindAPI;
|
||||
extern void* bluegl_eglCreateContext;
|
||||
extern void* bluegl_eglDestroyContext;
|
||||
extern void* bluegl_eglMakeCurrent;
|
||||
extern void* bluegl_eglCreatePbufferSurface;
|
||||
extern void* bluegl_eglCreateWindowSurface;
|
||||
extern void* bluegl_eglDestroySurface;
|
||||
extern void* bluegl_eglSurfaceAttrib;
|
||||
extern void* bluegl_eglSwapBuffers;
|
||||
extern void* bluegl_eglQueryString;
|
||||
extern void* bluegl_eglChooseConfig;
|
||||
extern void* bluegl_eglGetConfigAttrib;
|
||||
extern void* bluegl_eglGetConfigs;
|
||||
extern void* bluegl_eglGetCurrentContext;
|
||||
extern void* bluegl_eglReleaseThread;
|
||||
extern void* bluegl_eglGetError;
|
||||
extern void* bluegl_eglGetPlatformDisplayEXT;
|
||||
|
||||
#if !defined(__ANDROID__)
|
||||
|
||||
#ifdef eglGetProcAddress
|
||||
#undef eglGetProcAddress
|
||||
#endif
|
||||
#define eglGetProcAddress ((PFNEGLGETPROCADDRESSPROC)bluegl_eglGetProcAddress)
|
||||
|
||||
#ifdef eglGetDisplay
|
||||
#undef eglGetDisplay
|
||||
#endif
|
||||
#define eglGetDisplay ((PFNEGLGETDISPLAYPROC)bluegl_eglGetDisplay)
|
||||
|
||||
#ifdef eglInitialize
|
||||
#undef eglInitialize
|
||||
#endif
|
||||
#define eglInitialize ((PFNEGLINITIALIZEPROC)bluegl_eglInitialize)
|
||||
|
||||
#ifdef eglTerminate
|
||||
#undef eglTerminate
|
||||
#endif
|
||||
#define eglTerminate ((PFNEGLTERMINATEPROC)bluegl_eglTerminate)
|
||||
|
||||
#ifdef eglBindAPI
|
||||
#undef eglBindAPI
|
||||
#endif
|
||||
#define eglBindAPI ((PFNEGLBINDAPIPROC)bluegl_eglBindAPI)
|
||||
|
||||
#ifdef eglCreateContext
|
||||
#undef eglCreateContext
|
||||
#endif
|
||||
#define eglCreateContext ((PFNEGLCREATECONTEXTPROC)bluegl_eglCreateContext)
|
||||
|
||||
#ifdef eglDestroyContext
|
||||
#undef eglDestroyContext
|
||||
#endif
|
||||
#define eglDestroyContext ((PFNEGLDESTROYCONTEXTPROC)bluegl_eglDestroyContext)
|
||||
|
||||
#ifdef eglMakeCurrent
|
||||
#undef eglMakeCurrent
|
||||
#endif
|
||||
#define eglMakeCurrent ((PFNEGLMAKECURRENTPROC)bluegl_eglMakeCurrent)
|
||||
|
||||
#ifdef eglCreatePbufferSurface
|
||||
#undef eglCreatePbufferSurface
|
||||
#endif
|
||||
#define eglCreatePbufferSurface ((PFNEGLCREATEPBUFFERSURFACEPROC)bluegl_eglCreatePbufferSurface)
|
||||
|
||||
#ifdef eglCreateWindowSurface
|
||||
#undef eglCreateWindowSurface
|
||||
#endif
|
||||
#define eglCreateWindowSurface ((PFNEGLCREATEWINDOWSURFACEPROC)bluegl_eglCreateWindowSurface)
|
||||
|
||||
#ifdef eglDestroySurface
|
||||
#undef eglDestroySurface
|
||||
#endif
|
||||
#define eglDestroySurface ((PFNEGLDESTROYSURFACEPROC)bluegl_eglDestroySurface)
|
||||
|
||||
#ifdef eglSurfaceAttrib
|
||||
#undef eglSurfaceAttrib
|
||||
#endif
|
||||
#define eglSurfaceAttrib ((PFNEGLSURFACEATTRIBPROC)bluegl_eglSurfaceAttrib)
|
||||
|
||||
#ifdef eglSwapBuffers
|
||||
#undef eglSwapBuffers
|
||||
#endif
|
||||
#define eglSwapBuffers ((PFNEGLSWAPBUFFERSPROC)bluegl_eglSwapBuffers)
|
||||
|
||||
#ifdef eglQueryString
|
||||
#undef eglQueryString
|
||||
#endif
|
||||
#define eglQueryString ((PFNEGLQUERYSTRINGPROC)bluegl_eglQueryString)
|
||||
|
||||
#ifdef eglChooseConfig
|
||||
#undef eglChooseConfig
|
||||
#endif
|
||||
#define eglChooseConfig ((PFNEGLCHOOSECONFIGPROC)bluegl_eglChooseConfig)
|
||||
|
||||
#ifdef eglGetConfigAttrib
|
||||
#undef eglGetConfigAttrib
|
||||
#endif
|
||||
#define eglGetConfigAttrib ((PFNEGLGETCONFIGATTRIBPROC)bluegl_eglGetConfigAttrib)
|
||||
|
||||
#ifdef eglGetConfigs
|
||||
#undef eglGetConfigs
|
||||
#endif
|
||||
#define eglGetConfigs ((PFNEGLGETCONFIGSPROC)bluegl_eglGetConfigs)
|
||||
|
||||
#ifdef eglGetCurrentContext
|
||||
#undef eglGetCurrentContext
|
||||
#endif
|
||||
#define eglGetCurrentContext ((PFNEGLGETCURRENTCONTEXTPROC)bluegl_eglGetCurrentContext)
|
||||
|
||||
#ifdef eglReleaseThread
|
||||
#undef eglReleaseThread
|
||||
#endif
|
||||
#define eglReleaseThread ((PFNEGLRELEASETHREADPROC)bluegl_eglReleaseThread)
|
||||
|
||||
#ifdef eglGetError
|
||||
#undef eglGetError
|
||||
#endif
|
||||
#define eglGetError ((PFNEGLGETERRORPROC)bluegl_eglGetError)
|
||||
|
||||
#define eglGetPlatformDisplayEXT ((PFNEGLGETPLATFORMDISPLAYEXTPROC)bluegl_eglGetPlatformDisplayEXT)
|
||||
|
||||
#endif // !defined(__ANDROID__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TNT_BLUEGL_BLUEEGL_H
|
||||
130
libs/bluegl/src/BlueGLEGL.cpp
Normal file
130
libs/bluegl/src/BlueGLEGL.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace bluegl {
|
||||
|
||||
struct Driver {
|
||||
void* (*eglGetProcAddress)(const char*);
|
||||
void* library;
|
||||
void* glapi;
|
||||
void* glesv2;
|
||||
} g_driver = {nullptr, nullptr, nullptr, nullptr};
|
||||
|
||||
extern "C" {
|
||||
#define BLUEGL_EGL_STUB(name) \
|
||||
void* bluegl_##name; \
|
||||
void* name() { return bluegl_##name; }
|
||||
|
||||
void* bluegl_eglGetProcAddress;
|
||||
void* bluegl_eglGetDisplay;
|
||||
void* bluegl_eglInitialize;
|
||||
void* bluegl_eglTerminate;
|
||||
void* bluegl_eglBindAPI;
|
||||
void* bluegl_eglCreateContext;
|
||||
void* bluegl_eglDestroyContext;
|
||||
void* bluegl_eglMakeCurrent;
|
||||
void* bluegl_eglCreatePbufferSurface;
|
||||
void* bluegl_eglCreateWindowSurface;
|
||||
void* bluegl_eglDestroySurface;
|
||||
void* bluegl_eglSurfaceAttrib;
|
||||
void* bluegl_eglSwapBuffers;
|
||||
void* bluegl_eglQueryString;
|
||||
void* bluegl_eglChooseConfig;
|
||||
void* bluegl_eglGetConfigAttrib;
|
||||
void* bluegl_eglGetConfigs;
|
||||
void* bluegl_eglGetCurrentContext;
|
||||
void* bluegl_eglReleaseThread;
|
||||
void* bluegl_eglGetError;
|
||||
void* bluegl_eglGetPlatformDisplayEXT;
|
||||
}
|
||||
|
||||
bool initBinder() {
|
||||
#ifdef __APPLE__
|
||||
const char* library_name = "libEGL.1.dylib";
|
||||
const char* glapi_name = "libglapi.0.dylib";
|
||||
const char* glesv2_name = "libGLESv2.2.dylib";
|
||||
#else
|
||||
const char* library_name = "libEGL.so.1";
|
||||
const char* glapi_name = "libglapi.so.0";
|
||||
const char* glesv2_name = "libGLESv2.so.2";
|
||||
#endif
|
||||
g_driver.library = dlopen(library_name, RTLD_GLOBAL | RTLD_NOW);
|
||||
|
||||
if (!g_driver.library) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_driver.glapi = dlopen(glapi_name, RTLD_GLOBAL | RTLD_NOW);
|
||||
g_driver.glesv2 = dlopen(glesv2_name, RTLD_GLOBAL | RTLD_NOW);
|
||||
|
||||
g_driver.eglGetProcAddress = (void *(*)(const char *))
|
||||
dlsym(g_driver.library, "eglGetProcAddress");
|
||||
|
||||
#define LOAD_EGL_SYMBOL(name) bluegl_##name = dlsym(g_driver.library, #name)
|
||||
LOAD_EGL_SYMBOL(eglGetProcAddress);
|
||||
LOAD_EGL_SYMBOL(eglGetDisplay);
|
||||
LOAD_EGL_SYMBOL(eglInitialize);
|
||||
LOAD_EGL_SYMBOL(eglTerminate);
|
||||
LOAD_EGL_SYMBOL(eglBindAPI);
|
||||
LOAD_EGL_SYMBOL(eglCreateContext);
|
||||
LOAD_EGL_SYMBOL(eglDestroyContext);
|
||||
LOAD_EGL_SYMBOL(eglMakeCurrent);
|
||||
LOAD_EGL_SYMBOL(eglCreatePbufferSurface);
|
||||
LOAD_EGL_SYMBOL(eglCreateWindowSurface);
|
||||
LOAD_EGL_SYMBOL(eglDestroySurface);
|
||||
LOAD_EGL_SYMBOL(eglSurfaceAttrib);
|
||||
LOAD_EGL_SYMBOL(eglSwapBuffers);
|
||||
LOAD_EGL_SYMBOL(eglQueryString);
|
||||
LOAD_EGL_SYMBOL(eglChooseConfig);
|
||||
LOAD_EGL_SYMBOL(eglGetConfigAttrib);
|
||||
LOAD_EGL_SYMBOL(eglGetConfigs);
|
||||
LOAD_EGL_SYMBOL(eglGetCurrentContext);
|
||||
LOAD_EGL_SYMBOL(eglReleaseThread);
|
||||
LOAD_EGL_SYMBOL(eglGetError);
|
||||
bluegl_eglGetPlatformDisplayEXT = (void*)g_driver.eglGetProcAddress("eglGetPlatformDisplayEXT");
|
||||
|
||||
return g_driver.eglGetProcAddress;
|
||||
}
|
||||
|
||||
void* loadFunction(const char* name) {
|
||||
void* ptr = (void*) g_driver.eglGetProcAddress((const char*) name);
|
||||
if (!ptr) {
|
||||
if (g_driver.glesv2) {
|
||||
ptr = dlsym(g_driver.glesv2, name);
|
||||
}
|
||||
if (!ptr && g_driver.glapi) {
|
||||
ptr = dlsym(g_driver.glapi, name);
|
||||
}
|
||||
if (!ptr) {
|
||||
ptr = dlsym(g_driver.library, name);
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void shutdownBinder() {
|
||||
if (g_driver.library) dlclose(g_driver.library);
|
||||
if (g_driver.glapi) dlclose(g_driver.glapi);
|
||||
if (g_driver.glesv2) dlclose(g_driver.glesv2);
|
||||
memset(&g_driver, 0, sizeof(g_driver));
|
||||
}
|
||||
|
||||
} // namespace bluegl
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace bluegl {
|
||||
|
||||
struct Driver {
|
||||
void* (*eglGetProcAddress)(const char*);
|
||||
void* library;
|
||||
} g_driver = {nullptr, nullptr};
|
||||
|
||||
bool initBinder() {
|
||||
const char* library_name = "libEGL.so.1";
|
||||
g_driver.library = dlopen(library_name, RTLD_GLOBAL | RTLD_NOW);
|
||||
|
||||
if (!g_driver.library) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_driver.eglGetProcAddress = (void *(*)(const char *))
|
||||
dlsym(g_driver.library, "eglGetProcAddress");
|
||||
|
||||
return g_driver.eglGetProcAddress;
|
||||
}
|
||||
|
||||
void* loadFunction(const char* name) {
|
||||
return (void*) g_driver.eglGetProcAddress((const char*) name);
|
||||
}
|
||||
|
||||
void shutdownBinder() {
|
||||
dlclose(g_driver.library);
|
||||
memset(&g_driver, 0, sizeof(g_driver));
|
||||
}
|
||||
|
||||
} // namespace bluegl
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
#include <osmesa.h>
|
||||
|
||||
// This is to ensure that linking during compilation will not fail even if
|
||||
// OSMesaGetProcAddress is not linked.
|
||||
__attribute__((weak)) OSMESAproc OSMesaGetProcAddress(char const*);
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
#include <GL/osmesa.h>
|
||||
|
||||
#endif // __linux__
|
||||
|
||||
#if defined(__linux__)
|
||||
#endif
|
||||
|
||||
namespace bluegl {
|
||||
|
||||
namespace {
|
||||
using ProcAddressFunc = void*(*)(char const* funcName);
|
||||
}
|
||||
|
||||
struct Driver {
|
||||
ProcAddressFunc OSMesaGetProcAddress;
|
||||
void* library;
|
||||
} g_driver = {nullptr, nullptr};
|
||||
|
||||
bool initBinder() {
|
||||
static constexpr char const* libraryNames[] = {
|
||||
#if defined(__linux__)
|
||||
"libOSMesa.so",
|
||||
"libosmesa.so",
|
||||
#elif defined(__APPLE__)
|
||||
"libOSMesa.dylib",
|
||||
#endif
|
||||
};
|
||||
for (char const* name: libraryNames) {
|
||||
g_driver.library = dlopen(name, RTLD_GLOBAL | RTLD_NOW);
|
||||
if (g_driver.library) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (g_driver.library) {
|
||||
// Linking against a libosmesa.so.
|
||||
g_driver.OSMesaGetProcAddress =
|
||||
(ProcAddressFunc) dlsym(g_driver.library, "OSMesaGetProcAddress");
|
||||
}
|
||||
#if defined(__linux__)
|
||||
else {
|
||||
// If Filament was built as a dynamic library.
|
||||
g_driver.OSMesaGetProcAddress = (ProcAddressFunc) dlsym(RTLD_LOCAL, "OSMesaGetProcAddress");
|
||||
}
|
||||
if (!g_driver.OSMesaGetProcAddress) {
|
||||
// If statically linking OSMesa.
|
||||
g_driver.OSMesaGetProcAddress = (ProcAddressFunc) OSMesaGetProcAddress;
|
||||
}
|
||||
#endif
|
||||
|
||||
return g_driver.OSMesaGetProcAddress;
|
||||
}
|
||||
|
||||
void* loadFunction(const char* name) {
|
||||
return (void*) g_driver.OSMesaGetProcAddress(name);
|
||||
}
|
||||
|
||||
void shutdownBinder() {
|
||||
if (g_driver.library) {
|
||||
dlclose(g_driver.library);
|
||||
}
|
||||
memset(&g_driver, 0, sizeof(g_driver));
|
||||
}
|
||||
|
||||
} // namespace bluegl
|
||||
3
lldb_cmds.txt
Normal file
3
lldb_cmds.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
run
|
||||
bt
|
||||
quit
|
||||
@@ -35,7 +35,7 @@ fi
|
||||
|
||||
# Build backend_test_mac
|
||||
echo "Building backend_test_mac..."
|
||||
"${PROJECT_ROOT_DIR}/build.sh" -W -p desktop -X "${PROJECT_ROOT_DIR}/mesa" debug ${BACKEND_TEST_TARGET}
|
||||
"${PROJECT_ROOT_DIR}/build.sh" -W -p desktop -E "${PROJECT_ROOT_DIR}/mesa" debug ${BACKEND_TEST_TARGET}
|
||||
|
||||
set +e
|
||||
|
||||
|
||||
@@ -40,12 +40,12 @@ function start_render_() {
|
||||
fi
|
||||
# -W enables the webgpu build
|
||||
# -f forces regeneration of cmake build files
|
||||
# -X points to the mesa directory, which contains the compiled gl and vk drivers.
|
||||
# -E points to the mesa directory, which contains the compiled gl and vk drivers.
|
||||
GLTF_VIEWER_PATH="$(pwd)/out/cmake-debug/samples/gltf_viewer"
|
||||
if [[ "$NOREBUILD" == "true" ]] && [[ -f ${GLTF_VIEWER_PATH} ]]; then
|
||||
echo "Skipping build of gltf_viewer"
|
||||
else
|
||||
CXX=`which clang++` CC=`which clang` ./build.sh -f -W -X ${MESA_DIR} -p desktop debug gltf_viewer
|
||||
./build.sh -f -W -E ${MESA_DIR} -p desktop debug gltf_viewer
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
BIN
test/renderdiff/src/__pycache__/results.cpython-314.pyc
Normal file
BIN
test/renderdiff/src/__pycache__/results.cpython-314.pyc
Normal file
Binary file not shown.
BIN
test/renderdiff/src/__pycache__/test_config.cpython-314.pyc
Normal file
BIN
test/renderdiff/src/__pycache__/test_config.cpython-314.pyc
Normal file
Binary file not shown.
BIN
test/renderdiff/src/__pycache__/utils.cpython-314.pyc
Normal file
BIN
test/renderdiff/src/__pycache__/utils.cpython-314.pyc
Normal file
Binary file not shown.
Reference in New Issue
Block a user