diff options
-rw-r--r-- | Meta/Lagom/CMakeLists.txt | 9 | ||||
-rw-r--r-- | Userland/Applications/3DFileViewer/main.cpp | 3 | ||||
-rw-r--r-- | Userland/Libraries/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/GLContext.cpp | 14 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/GLContext.h | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibGPU/CMakeLists.txt | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibGPU/Device.h | 6 | ||||
-rw-r--r-- | Userland/Libraries/LibGPU/Driver.cpp | 76 | ||||
-rw-r--r-- | Userland/Libraries/LibGPU/Driver.h | 42 | ||||
-rw-r--r-- | Userland/Libraries/LibSoftGPU/Device.cpp | 9 |
11 files changed, 165 insertions, 9 deletions
diff --git a/Meta/Lagom/CMakeLists.txt b/Meta/Lagom/CMakeLists.txt index 88640f7ed1..e986d7b19a 100644 --- a/Meta/Lagom/CMakeLists.txt +++ b/Meta/Lagom/CMakeLists.txt @@ -346,12 +346,19 @@ if (BUILD_LAGOM) LIBS m LagomCompress LagomTextCodec LagomIPC ) + # GPU + file(GLOB LIBGPU_SOURCES CONFIGURE_DEPENDS "../../Userland/Libraries/LibGPU/*.cpp") + lagom_lib(GPU gpu + SOURCES ${LIBGPU_SOURCES} + LIBS dl + ) + # GL file(GLOB LIBGL_SOURCES CONFIGURE_DEPENDS "../../Userland/Libraries/LibGL/*.cpp") file(GLOB LIBGL_TEX_SOURCES CONFIGURE_DEPENDS "../../Userland/Libraries/LibGL/Tex/*.cpp") lagom_lib(GL gl SOURCES ${LIBGL_SOURCES} ${LIBGL_TEX_SOURCES} - LIBS m LagomGfx LagomSoftGPU) + LIBS m LagomGfx LagomGPU) # GUI-GML file(GLOB LIBGUI_GML_SOURCES CONFIGURE_DEPENDS "../../Userland/Libraries/LibGUI/GML/*.cpp") diff --git a/Userland/Applications/3DFileViewer/main.cpp b/Userland/Applications/3DFileViewer/main.cpp index c1c61fec1a..e27246411b 100644 --- a/Userland/Applications/3DFileViewer/main.cpp +++ b/Userland/Applications/3DFileViewer/main.cpp @@ -358,11 +358,12 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) { auto app = GUI::Application::construct(arguments); - TRY(Core::System::pledge("stdio thread recvfd sendfd rpath unix")); + TRY(Core::System::pledge("stdio thread recvfd sendfd rpath unix prot_exec")); TRY(Core::System::unveil("/tmp/portal/filesystemaccess", "rw")); TRY(Core::System::unveil("/home/anon/Documents/3D Models", "r")); TRY(Core::System::unveil("/res", "r")); + TRY(Core::System::unveil("/usr/lib", "r")); TRY(Core::System::unveil(nullptr, nullptr)); // Construct the main window diff --git a/Userland/Libraries/CMakeLists.txt b/Userland/Libraries/CMakeLists.txt index 034d76a58e..cf19348520 100644 --- a/Userland/Libraries/CMakeLists.txt +++ b/Userland/Libraries/CMakeLists.txt @@ -22,6 +22,7 @@ add_subdirectory(LibFileSystemAccessClient) add_subdirectory(LibGemini) add_subdirectory(LibGfx) add_subdirectory(LibGL) +add_subdirectory(LibGPU) add_subdirectory(LibGUI) add_subdirectory(LibHTTP) add_subdirectory(LibIMAP) diff --git a/Userland/Libraries/LibGL/CMakeLists.txt b/Userland/Libraries/LibGL/CMakeLists.txt index 3ce3ebc535..0aedebc0ca 100644 --- a/Userland/Libraries/LibGL/CMakeLists.txt +++ b/Userland/Libraries/LibGL/CMakeLists.txt @@ -18,4 +18,4 @@ set(SOURCES ) serenity_lib(LibGL gl) -target_link_libraries(LibGL LibM LibCore LibGfx LibSoftGPU) +target_link_libraries(LibGL LibM LibCore LibGfx LibGPU) diff --git a/Userland/Libraries/LibGL/GLContext.cpp b/Userland/Libraries/LibGL/GLContext.cpp index 9ba9d06791..70b6c93b04 100644 --- a/Userland/Libraries/LibGL/GLContext.cpp +++ b/Userland/Libraries/LibGL/GLContext.cpp @@ -15,12 +15,12 @@ #include <AK/Variant.h> #include <AK/Vector.h> #include <LibGL/GLContext.h> +#include <LibGPU/Device.h> #include <LibGPU/Enums.h> #include <LibGPU/ImageFormat.h> #include <LibGfx/Bitmap.h> #include <LibGfx/Painter.h> #include <LibGfx/Vector4.h> -#include <LibSoftGPU/Device.h> __attribute__((visibility("hidden"))) GL::GLContext* g_gl_context; @@ -61,10 +61,11 @@ static constexpr size_t TEXTURE_MATRIX_STACK_LIMIT = 8; return return_value; \ } -GLContext::GLContext(Gfx::Bitmap& frontbuffer) +GLContext::GLContext(RefPtr<GPU::Driver> driver, NonnullOwnPtr<GPU::Device> device, Gfx::Bitmap& frontbuffer) : m_viewport { frontbuffer.rect() } , m_frontbuffer { frontbuffer } - , m_rasterizer { make<SoftGPU::Device>(frontbuffer.size()) } + , m_driver { driver } + , m_rasterizer { move(device) } , m_device_info { m_rasterizer->info() } { m_texture_units.resize(m_device_info.num_texture_units); @@ -3064,7 +3065,7 @@ void GLContext::sync_light_state() } m_rasterizer->set_options(options); - for (auto light_id = 0u; light_id < SoftGPU::NUM_LIGHTS; light_id++) { + for (auto light_id = 0u; light_id < m_device_info.num_lights; light_id++) { auto const& current_light_state = m_light_states.at(light_id); m_rasterizer->set_light_state(light_id, current_light_state); } @@ -3645,7 +3646,10 @@ void GLContext::get_material_param(Face face, GLenum pname, T* params) NonnullOwnPtr<GLContext> create_context(Gfx::Bitmap& bitmap) { - auto context = make<GLContext>(bitmap); + // FIXME: Make driver selectable. This is currently hardcoded to LibSoftGPU + auto driver = MUST(GPU::Driver::try_create("softgpu")); + auto device = MUST(driver->try_create_device(bitmap.size())); + auto context = make<GLContext>(driver, move(device), bitmap); dbgln_if(GL_DEBUG, "GL::create_context({}) -> {:p}", bitmap.size(), context.ptr()); if (!g_gl_context) diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index cd10b70676..20ebfb9de4 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -19,6 +19,7 @@ #include <LibGL/Tex/TextureUnit.h> #include <LibGPU/Device.h> #include <LibGPU/DeviceInfo.h> +#include <LibGPU/Driver.h> #include <LibGPU/Light.h> #include <LibGPU/Vertex.h> #include <LibGfx/Bitmap.h> @@ -48,7 +49,7 @@ enum Face { class GLContext final { public: - GLContext(Gfx::Bitmap&); + GLContext(RefPtr<GPU::Driver> driver, NonnullOwnPtr<GPU::Device>, Gfx::Bitmap&); ~GLContext(); void gl_begin(GLenum mode); @@ -303,6 +304,7 @@ private: return m_texture_coordinate_generation[texture_unit][capability - GL_TEXTURE_GEN_S]; } + RefPtr<GPU::Driver> m_driver; NonnullOwnPtr<GPU::Device> m_rasterizer; GPU::DeviceInfo const m_device_info; bool m_sampler_config_is_dirty { true }; diff --git a/Userland/Libraries/LibGPU/CMakeLists.txt b/Userland/Libraries/LibGPU/CMakeLists.txt new file mode 100644 index 0000000000..05a77dfb95 --- /dev/null +++ b/Userland/Libraries/LibGPU/CMakeLists.txt @@ -0,0 +1,8 @@ +set(SOURCES + Driver.cpp +) + +serenity_lib(LibGPU gpu) +target_link_libraries(LibGPU LibCore LibDl) + +add_dependencies(LibGPU LibSoftGPU) diff --git a/Userland/Libraries/LibGPU/Device.h b/Userland/Libraries/LibGPU/Device.h index a87a7cc641..39ae7262c4 100644 --- a/Userland/Libraries/LibGPU/Device.h +++ b/Userland/Libraries/LibGPU/Device.h @@ -7,6 +7,7 @@ #pragma once #include <AK/Array.h> +#include <AK/Error.h> #include <AK/NonnullRefPtr.h> #include <AK/RefCounted.h> #include <AK/RefPtr.h> @@ -28,6 +29,7 @@ #include <LibGfx/Matrix3x3.h> #include <LibGfx/Matrix4x4.h> #include <LibGfx/Rect.h> +#include <LibGfx/Size.h> #include <LibGfx/Vector4.h> namespace GPU { @@ -66,3 +68,7 @@ public: }; } + +typedef GPU::Device* (*serenity_gpu_create_device_t)(Gfx::IntSize const& size); + +extern "C" GPU::Device* serenity_gpu_create_device(Gfx::IntSize const& size); diff --git a/Userland/Libraries/LibGPU/Driver.cpp b/Userland/Libraries/LibGPU/Driver.cpp new file mode 100644 index 0000000000..0b529e7661 --- /dev/null +++ b/Userland/Libraries/LibGPU/Driver.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022, Stephan Unverwerth <s.unverwerth@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <AK/HashMap.h> +#include <AK/String.h> +#include <AK/WeakPtr.h> +#ifdef __serenity__ +# include <LibDl/dlfcn.h> +#else +# include <dlfcn.h> +#endif +#include <LibGPU/Driver.h> + +namespace GPU { + +// FIXME: Think of a better way to configure these paths. Maybe use ConfigServer? +static HashMap<String, String> const s_driver_path_map +{ +#if defined(__serenity__) + { "softgpu", "/usr/lib/libsoftgpu.so" }, +#elif defined(__APPLE__) + { "softgpu", "./liblagom-softgpu.dylib" }, +#else + { "softgpu", "./liblagom-softgpu.so" }, +#endif +}; + +static HashMap<String, WeakPtr<Driver>> s_loaded_drivers; + +ErrorOr<NonnullRefPtr<Driver>> Driver::try_create(StringView driver_name) +{ + // Check if the library for this driver is already loaded + auto already_loaded_driver = s_loaded_drivers.find(driver_name); + if (already_loaded_driver != s_loaded_drivers.end() && !already_loaded_driver->value.is_null()) + return *already_loaded_driver->value; + + // Nope, we need to load the library + auto it = s_driver_path_map.find(driver_name); + if (it == s_driver_path_map.end()) + return Error::from_string_literal("The requested GPU driver was not found in the list of allowed driver libraries"); + + auto lib = dlopen(it->value.characters(), RTLD_NOW); + if (!lib) + return Error::from_string_literal("The library for the requested GPU driver could not be opened"); + + auto serenity_gpu_create_device = reinterpret_cast<serenity_gpu_create_device_t>(dlsym(lib, "serenity_gpu_create_device")); + if (!serenity_gpu_create_device) { + dlclose(lib); + return Error::from_string_literal("The library for the requested GPU driver does not contain serenity_gpu_create_device()"); + } + + auto driver = adopt_ref(*new Driver(lib, serenity_gpu_create_device)); + + s_loaded_drivers.set(driver_name, driver->make_weak_ptr()); + + return driver; +} + +Driver::~Driver() +{ + dlclose(m_dlopen_result); +} + +ErrorOr<NonnullOwnPtr<Device>> Driver::try_create_device(Gfx::IntSize size) +{ + auto device_or_null = m_serenity_gpu_create_device(size); + if (!device_or_null) + return Error::from_string_literal("Could not create GPU device"); + + return adopt_own(*device_or_null); +} + +} diff --git a/Userland/Libraries/LibGPU/Driver.h b/Userland/Libraries/LibGPU/Driver.h new file mode 100644 index 0000000000..c2197e167a --- /dev/null +++ b/Userland/Libraries/LibGPU/Driver.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022, Stephan Unverwerth <s.unverwerth@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/Error.h> +#include <AK/NonnullOwnPtr.h> +#include <AK/NonnullRefPtr.h> +#include <AK/RefCounted.h> +#include <AK/StringView.h> +#include <AK/Weakable.h> +#include <LibGPU/Device.h> +#include <LibGfx/Size.h> + +namespace GPU { + +class Driver final + : public RefCounted<Driver> + , public Weakable<Driver> { +public: + static ErrorOr<NonnullRefPtr<Driver>> try_create(StringView driver_name); + ~Driver(); + + ErrorOr<NonnullOwnPtr<Device>> try_create_device(Gfx::IntSize size); + +private: + Driver(void* dlopen_result, serenity_gpu_create_device_t device_creation_function) + : m_dlopen_result { dlopen_result } + , m_serenity_gpu_create_device { device_creation_function } + { + VERIFY(dlopen_result); + VERIFY(device_creation_function); + } + + void* const m_dlopen_result { nullptr }; + serenity_gpu_create_device_t m_serenity_gpu_create_device { nullptr }; +}; + +} diff --git a/Userland/Libraries/LibSoftGPU/Device.cpp b/Userland/Libraries/LibSoftGPU/Device.cpp index ad721f2ee4..2ee86bac64 100644 --- a/Userland/Libraries/LibSoftGPU/Device.cpp +++ b/Userland/Libraries/LibSoftGPU/Device.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/Error.h> #include <AK/Math.h> #include <AK/NumericLimits.h> #include <AK/SIMDExtras.h> @@ -1303,3 +1304,11 @@ Gfx::IntRect Device::get_rasterization_rect_of_size(Gfx::IntSize size) } } + +extern "C" { + +GPU::Device* serenity_gpu_create_device(Gfx::IntSize const& size) +{ + return make<SoftGPU::Device>(size).leak_ptr(); +} +} |