From 93ab2db80fed38b6e621085b5e060ae726d77a88 Mon Sep 17 00:00:00 2001 From: Stephan Unverwerth Date: Wed, 14 Sep 2022 23:48:10 +0200 Subject: [PATCH] LibGL+LibSoftGPU: Add GPU side shader infrastructure This adds a shader class to LibSoftGPU and makes use of it when linking GLSL program in LibGL. Also adds actual rendering code to the shader tests. --- Tests/LibGL/TestShaders.cpp | 12 ++++++++ Userland/Libraries/LibGL/Shader.cpp | 2 +- Userland/Libraries/LibGL/Shaders/Program.cpp | 5 +++- Userland/Libraries/LibGL/Shaders/Program.h | 6 +++- Userland/Libraries/LibGPU/Device.h | 3 ++ Userland/Libraries/LibGPU/Shader.h | 29 ++++++++++++++++++++ Userland/Libraries/LibSoftGPU/CMakeLists.txt | 1 + Userland/Libraries/LibSoftGPU/Device.cpp | 6 ++++ Userland/Libraries/LibSoftGPU/Device.h | 1 + Userland/Libraries/LibSoftGPU/Shader.cpp | 16 +++++++++++ Userland/Libraries/LibSoftGPU/Shader.h | 18 ++++++++++++ 11 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 Userland/Libraries/LibGPU/Shader.h create mode 100644 Userland/Libraries/LibSoftGPU/Shader.cpp create mode 100644 Userland/Libraries/LibSoftGPU/Shader.h diff --git a/Tests/LibGL/TestShaders.cpp b/Tests/LibGL/TestShaders.cpp index 6bbffc033d..6a459c70e2 100644 --- a/Tests/LibGL/TestShaders.cpp +++ b/Tests/LibGL/TestShaders.cpp @@ -59,6 +59,18 @@ TEST_CASE(0001_program_creation) glAttachShader(program, vertex_shader); glAttachShader(program, fragment_shader); glLinkProgram(program); + glUseProgram(program); + + glBegin(GL_TRIANGLES); + glColor3f(1, 0, 0); + glVertex2i(-1, -1); + glColor3f(0, 1, 0); + glVertex2i(1, -1); + glColor3f(0, 0, 1); + glVertex2i(1, 1); + glEnd(); + + context->present(); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); diff --git a/Userland/Libraries/LibGL/Shader.cpp b/Userland/Libraries/LibGL/Shader.cpp index 8742c1e8cb..904bedce43 100644 --- a/Userland/Libraries/LibGL/Shader.cpp +++ b/Userland/Libraries/LibGL/Shader.cpp @@ -157,7 +157,7 @@ void GLContext::gl_link_program(GLuint program) // FIXME: implement check "GL_INVALID_OPERATION is generated if program is the currently active program object and transform feedback mode is active." // NOTE: We are ignoring the link result since this is tracked inside the program object - (void)program_it->value->link(); + (void)program_it->value->link(*m_rasterizer); } void GLContext::gl_use_program(GLuint program) diff --git a/Userland/Libraries/LibGL/Shaders/Program.cpp b/Userland/Libraries/LibGL/Shaders/Program.cpp index 8a76a258fd..27d77d0b5f 100644 --- a/Userland/Libraries/LibGL/Shaders/Program.cpp +++ b/Userland/Libraries/LibGL/Shaders/Program.cpp @@ -48,7 +48,7 @@ ErrorOr Program::attach_shader(Shader& shader) return {}; } -ErrorOr Program::link() +ErrorOr Program::link(GPU::Device& device) { m_info_log = TRY(String::from_utf8(""sv)); @@ -86,6 +86,9 @@ ErrorOr Program::link() m_linked_fragment_shader = linked_fragment_shader_or_error.release_value(); + m_gpu_vertex_shader = TRY(device.create_shader({})); + m_gpu_fragment_shader = TRY(device.create_shader({})); + m_link_status = true; return {}; } diff --git a/Userland/Libraries/LibGL/Shaders/Program.h b/Userland/Libraries/LibGL/Shaders/Program.h index 9c3b217add..5ee44e51a4 100644 --- a/Userland/Libraries/LibGL/Shaders/Program.h +++ b/Userland/Libraries/LibGL/Shaders/Program.h @@ -15,6 +15,8 @@ #include #include #include +#include +#include namespace GL { @@ -24,7 +26,7 @@ public: bool is_shader_attached(Shader const&) const; ErrorOr attach_shader(Shader&); - ErrorOr link(); + ErrorOr link(GPU::Device&); bool link_status() const { return m_link_status; } size_t info_log_length() const; @@ -35,6 +37,8 @@ private: Optional m_info_log; OwnPtr m_linked_vertex_shader; OwnPtr m_linked_fragment_shader; + RefPtr m_gpu_vertex_shader; + RefPtr m_gpu_fragment_shader; }; } diff --git a/Userland/Libraries/LibGPU/Device.h b/Userland/Libraries/LibGPU/Device.h index 7b08f315c5..d2a7a112d9 100644 --- a/Userland/Libraries/LibGPU/Device.h +++ b/Userland/Libraries/LibGPU/Device.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +58,7 @@ public: virtual LightModelParameters light_model() const = 0; virtual NonnullRefPtr create_image(PixelFormat const&, u32 width, u32 height, u32 depth, u32 max_levels) = 0; + virtual ErrorOr> create_shader(IR::Shader const&) = 0; virtual void set_sampler_config(unsigned, SamplerConfig const&) = 0; virtual void set_light_state(unsigned, Light const&) = 0; diff --git a/Userland/Libraries/LibGPU/Shader.h b/Userland/Libraries/LibGPU/Shader.h new file mode 100644 index 0000000000..c96a8d0dea --- /dev/null +++ b/Userland/Libraries/LibGPU/Shader.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022, Stephan Unverwerth + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace GPU { + +class Shader : public RefCounted { +public: + Shader(void const* ownership_token) + : m_ownership_token { ownership_token } + { + } + + virtual ~Shader() = default; + + void const* ownership_token() const { return m_ownership_token; } + bool has_same_ownership_token(Shader const& other) const { return other.ownership_token() == ownership_token(); } + +private: + void const* const m_ownership_token { nullptr }; +}; + +} diff --git a/Userland/Libraries/LibSoftGPU/CMakeLists.txt b/Userland/Libraries/LibSoftGPU/CMakeLists.txt index 3dbe3b6725..c97b476e30 100644 --- a/Userland/Libraries/LibSoftGPU/CMakeLists.txt +++ b/Userland/Libraries/LibSoftGPU/CMakeLists.txt @@ -4,6 +4,7 @@ set(SOURCES Image.cpp PixelConverter.cpp Sampler.cpp + Shader.cpp ) add_compile_options(-Wno-psabi) diff --git a/Userland/Libraries/LibSoftGPU/Device.cpp b/Userland/Libraries/LibSoftGPU/Device.cpp index c3085a9328..318617d7e6 100644 --- a/Userland/Libraries/LibSoftGPU/Device.cpp +++ b/Userland/Libraries/LibSoftGPU/Device.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include namespace SoftGPU { @@ -1626,6 +1627,11 @@ NonnullRefPtr Device::create_image(GPU::PixelFormat const& pixel_for return adopt_ref(*new Image(this, pixel_format, width, height, depth, max_levels)); } +ErrorOr> Device::create_shader(GPU::IR::Shader const&) +{ + return adopt_ref(*new Shader(this)); +} + void Device::set_sampler_config(unsigned sampler, GPU::SamplerConfig const& config) { VERIFY(config.bound_image.is_null() || config.bound_image->ownership_token() == this); diff --git a/Userland/Libraries/LibSoftGPU/Device.h b/Userland/Libraries/LibSoftGPU/Device.h index c772814d03..027a81d081 100644 --- a/Userland/Libraries/LibSoftGPU/Device.h +++ b/Userland/Libraries/LibSoftGPU/Device.h @@ -65,6 +65,7 @@ public: virtual GPU::LightModelParameters light_model() const override { return m_lighting_model; } virtual NonnullRefPtr create_image(GPU::PixelFormat const&, u32 width, u32 height, u32 depth, u32 max_levels) override; + virtual ErrorOr> create_shader(GPU::IR::Shader const&) override; virtual void set_sampler_config(unsigned, GPU::SamplerConfig const&) override; virtual void set_light_state(unsigned, GPU::Light const&) override; diff --git a/Userland/Libraries/LibSoftGPU/Shader.cpp b/Userland/Libraries/LibSoftGPU/Shader.cpp new file mode 100644 index 0000000000..44bb9635ea --- /dev/null +++ b/Userland/Libraries/LibSoftGPU/Shader.cpp @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2022, Stephan Unverwerth + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +namespace SoftGPU { + +Shader::Shader(void const* ownership_token) + : GPU::Shader(ownership_token) +{ +} + +} diff --git a/Userland/Libraries/LibSoftGPU/Shader.h b/Userland/Libraries/LibSoftGPU/Shader.h new file mode 100644 index 0000000000..7c6b899d05 --- /dev/null +++ b/Userland/Libraries/LibSoftGPU/Shader.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2022, Stephan Unverwerth + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace SoftGPU { + +class Shader final : public GPU::Shader { +public: + Shader(void const* ownership_token); +}; + +}