From 9b6c5b0849e0e4a93443d9f7fe7ed7d6b16e18fd Mon Sep 17 00:00:00 2001 From: omigamedev Date: Tue, 2 Jun 2026 20:19:54 +0200 Subject: [PATCH] Map render pass clear masks to OpenGL --- docs/modernization/build-inventory.md | 3 +- docs/modernization/roadmap.md | 5 ++-- src/renderer_gl/opengl_capabilities.cpp | 24 +++++++++++++++ src/renderer_gl/opengl_capabilities.h | 3 ++ tests/renderer_gl/capabilities_tests.cpp | 37 ++++++++++++++++++++++++ 5 files changed, 69 insertions(+), 3 deletions(-) diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index 48aa1d6..674d854 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -200,7 +200,8 @@ Known local toolchain state: render-target texture parameters, texture/renderbuffer targets, depth format, framebuffer targets, binding queries, attachment points, and completion status used by `RTT::create` and framebuffer bind/restore paths, plus RTT - clear color/depth masks and color-write-mask query tokens. `RTT` no longer + clear color/depth masks, renderer API render-pass color/depth/stencil + clear-mask mapping, and color-write-mask query tokens. `RTT` no longer spells GL enum names directly. It also validates renderer API primitive-topology to OpenGL draw-mode mapping, Shape index-type, fill/stroke primitive-mode, buffer target, static upload usage, diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 4fbc1d8..d62b319 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -454,8 +454,9 @@ to OpenGL token mapping, plus the default render-target texture parameters, texture/renderbuffer targets, depth format, framebuffer targets, binding queries, attachment points, and completion status used by `RTT::create` and framebuffer bind/restore paths, also live in -`pp_renderer_gl`. RTT clear color/depth masks and color-write-mask query tokens -also live in `pp_renderer_gl`. `RTT` no longer spells GL enum names directly. +`pp_renderer_gl`. RTT clear color/depth masks, renderer API render-pass +color/depth/stencil clear-mask mapping, and color-write-mask query tokens also +live in `pp_renderer_gl`. `RTT` no longer spells GL enum names directly. Renderer API primitive-topology to OpenGL draw-mode mapping, mesh index-type and primitive-mode decisions used by legacy `Shape` drawing, plus Shape buffer targets, static upload usage, and vertex attribute component/normalization diff --git a/src/renderer_gl/opengl_capabilities.cpp b/src/renderer_gl/opengl_capabilities.cpp index 607d2d1..04f6812 100644 --- a/src/renderer_gl/opengl_capabilities.cpp +++ b/src/renderer_gl/opengl_capabilities.cpp @@ -106,6 +106,7 @@ constexpr std::uint32_t gl_framebuffer_undefined = 0x8219U; constexpr std::uint32_t gl_framebuffer_incomplete_multisample = 0x8D56U; constexpr std::uint32_t gl_color_buffer_bit = 0x00004000U; constexpr std::uint32_t gl_depth_buffer_bit = 0x00000100U; +constexpr std::uint32_t gl_stencil_buffer_bit = 0x00000400U; constexpr std::uint32_t gl_color_writemask = 0x0C23U; constexpr std::uint32_t gl_texture_cube_map = 0x8513U; constexpr std::uint32_t gl_texture_cube_map_positive_x = 0x8515U; @@ -465,6 +466,29 @@ std::uint32_t framebuffer_depth_buffer_mask() noexcept return gl_depth_buffer_bit; } +std::uint32_t framebuffer_stencil_buffer_mask() noexcept +{ + return gl_stencil_buffer_bit; +} + +std::uint32_t clear_mask_for_render_pass(pp::renderer::RenderPassDesc desc) noexcept +{ + std::uint32_t mask = 0U; + if (desc.clear_color_enabled) { + mask |= gl_color_buffer_bit; + } + + if (desc.clear_depth_enabled) { + mask |= gl_depth_buffer_bit; + } + + if (desc.clear_stencil_enabled) { + mask |= gl_stencil_buffer_bit; + } + + return mask; +} + std::uint32_t color_write_mask_query() noexcept { return gl_color_writemask; diff --git a/src/renderer_gl/opengl_capabilities.h b/src/renderer_gl/opengl_capabilities.h index 13fb2c6..fc062b3 100644 --- a/src/renderer_gl/opengl_capabilities.h +++ b/src/renderer_gl/opengl_capabilities.h @@ -105,6 +105,9 @@ struct OpenGlWindowsWglContextConfig { [[nodiscard]] const char* framebuffer_status_name(std::uint32_t status) noexcept; [[nodiscard]] std::uint32_t framebuffer_color_buffer_mask() noexcept; [[nodiscard]] std::uint32_t framebuffer_depth_buffer_mask() noexcept; +[[nodiscard]] std::uint32_t framebuffer_stencil_buffer_mask() noexcept; +[[nodiscard]] std::uint32_t clear_mask_for_render_pass( + pp::renderer::RenderPassDesc desc) noexcept; [[nodiscard]] std::uint32_t color_write_mask_query() noexcept; [[nodiscard]] std::uint32_t framebuffer_blit_filter(bool linear) noexcept; [[nodiscard]] OpenGlEnumMapping blit_filter_for_renderer_filter( diff --git a/tests/renderer_gl/capabilities_tests.cpp b/tests/renderer_gl/capabilities_tests.cpp index 7aecbcb..464bc95 100644 --- a/tests/renderer_gl/capabilities_tests.cpp +++ b/tests/renderer_gl/capabilities_tests.cpp @@ -258,6 +258,7 @@ void maps_framebuffer_blit_parameters(pp::tests::Harness& h) PP_EXPECT(h, pp::renderer::gl::framebuffer_color_buffer_mask() == 0x00004000U); PP_EXPECT(h, pp::renderer::gl::framebuffer_depth_buffer_mask() == 0x00000100U); + PP_EXPECT(h, pp::renderer::gl::framebuffer_stencil_buffer_mask() == 0x00000400U); PP_EXPECT(h, pp::renderer::gl::color_write_mask_query() == 0x0C23U); PP_EXPECT(h, pp::renderer::gl::framebuffer_blit_filter(true) == 0x2601U); PP_EXPECT(h, pp::renderer::gl::framebuffer_blit_filter(false) == 0x2600U); @@ -269,6 +270,41 @@ void maps_framebuffer_blit_parameters(pp::tests::Harness& h) PP_EXPECT(h, invalid.value == 0U); } +void maps_render_pass_clear_masks(pp::tests::Harness& h) +{ + const auto no_clear = pp::renderer::gl::clear_mask_for_render_pass(pp::renderer::RenderPassDesc { + .clear_color_enabled = false, + .clear_depth_enabled = false, + .clear_stencil_enabled = false, + }); + const auto color_only = pp::renderer::gl::clear_mask_for_render_pass(pp::renderer::RenderPassDesc { + .clear_color_enabled = true, + .clear_depth_enabled = false, + .clear_stencil_enabled = false, + }); + const auto depth_only = pp::renderer::gl::clear_mask_for_render_pass(pp::renderer::RenderPassDesc { + .clear_color_enabled = false, + .clear_depth_enabled = true, + .clear_stencil_enabled = false, + }); + const auto stencil_only = pp::renderer::gl::clear_mask_for_render_pass(pp::renderer::RenderPassDesc { + .clear_color_enabled = false, + .clear_depth_enabled = false, + .clear_stencil_enabled = true, + }); + const auto all_buffers = pp::renderer::gl::clear_mask_for_render_pass(pp::renderer::RenderPassDesc { + .clear_color_enabled = true, + .clear_depth_enabled = true, + .clear_stencil_enabled = true, + }); + + PP_EXPECT(h, no_clear == 0U); + PP_EXPECT(h, color_only == 0x00004000U); + PP_EXPECT(h, depth_only == 0x00000100U); + PP_EXPECT(h, stencil_only == 0x00000400U); + PP_EXPECT(h, all_buffers == 0x00004500U); +} + void maps_renderer_primitive_topologies_to_draw_modes(pp::tests::Harness& h) { PP_EXPECT(h, pp::renderer::gl::primitive_mode_for_renderer_topology( @@ -720,6 +756,7 @@ int main() harness.run("names_framebuffer_status_codes", names_framebuffer_status_codes); harness.run("maps_framebuffer_render_target_parameters", maps_framebuffer_render_target_parameters); harness.run("maps_framebuffer_blit_parameters", maps_framebuffer_blit_parameters); + harness.run("maps_render_pass_clear_masks", maps_render_pass_clear_masks); harness.run("maps_renderer_primitive_topologies_to_draw_modes", maps_renderer_primitive_topologies_to_draw_modes); harness.run("maps_shape_index_and_primitive_modes", maps_shape_index_and_primitive_modes); harness.run("maps_panopainter_cube_faces_to_texture_targets", maps_panopainter_cube_faces_to_texture_targets);