From 8130a922d0428fc96e5c9a6806cc9ea08f709336 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Mon, 1 Jun 2026 18:13:55 +0200 Subject: [PATCH] Move sampler parameter mapping to renderer gl --- docs/modernization/build-inventory.md | 9 +++++---- docs/modernization/roadmap.md | 6 +++++- src/renderer_gl/opengl_capabilities.cpp | 24 +++++++++++++++++++++++ src/renderer_gl/opengl_capabilities.h | 7 +++++++ src/texture.cpp | 19 +++++++++++------- tests/renderer_gl/capabilities_tests.cpp | 25 ++++++++++++++++++++++++ 6 files changed, 78 insertions(+), 12 deletions(-) diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index cb74bed..898fda3 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -135,10 +135,11 @@ Known local toolchain state: used by `RTT::create`. It also validates Shape index-type and fill/stroke primitive-mode mapping used by the legacy mesh draw path, plus the PanoPainter cube-face to OpenGL texture-target mapping used by `TextureCube`. - The PanoPainter shader attribute binding catalog used by legacy `Shader` - creation also lives here. It also owns the PanoPainter shader uniform catalog - and legacy hash mapping used by `Shader` active-uniform discovery and the - uniform uniqueness check. + It also owns and validates sampler wrap S/T/R plus min/mag filter parameter + ordering used by legacy `Sampler`. The PanoPainter shader attribute binding + catalog used by legacy `Shader` creation also lives here. It also owns the + PanoPainter shader uniform catalog and legacy hash mapping used by `Shader` + active-uniform discovery and the uniform uniqueness check. - `windows-msvc-vcpkg-headless` validates manifest install/configure/build/test for the current headless component matrix; see DEBT-0007 for remaining app and platform triplet migration. diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 5a09b8f..b353fdb 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -396,7 +396,9 @@ decisions used by legacy `Shape` drawing and the PanoPainter cube-face to OpenGL texture-target mapping used by `TextureCube` also live in `pp_renderer_gl`. The legacy app delegates extension, upload-format, framebuffer diagnostic, render-target texture parameter, mesh draw-mode, and -cube-face texture-target interpretation to that backend library. The PanoPainter shader attribute +cube-face texture-target interpretation to that backend library. Sampler wrap +and min/mag filter parameter mapping for legacy `Sampler` also lives in +`pp_renderer_gl`. The PanoPainter shader attribute binding catalog also lives in `pp_renderer_gl` and is consumed by legacy `Shader` creation. Shader uniform hashing, catalog validation, active-uniform mapping, and the legacy uniform uniqueness check now delegate to @@ -645,6 +647,8 @@ Results: framebuffer status names, plus Shape index-type and fill/stroke primitive mode mapping, PanoPainter cube-face texture-target order, and the linear clamp-to-edge render-target texture parameter set used by `RTT::create`. + Sampler parameter validation covers wrap S/T/R plus min/mag filter ordering + used by legacy `Sampler::set` and `Sampler::set_filter`. Shader attribute binding catalog validation covers the current `pos`, `uvs`, `uvs2`, `col`, and `nor` bindings and rejects empty, unnamed, null-name, and duplicate-name catalogs while preserving legacy shared locations. Shader diff --git a/src/renderer_gl/opengl_capabilities.cpp b/src/renderer_gl/opengl_capabilities.cpp index 4066b54..54cdf9c 100644 --- a/src/renderer_gl/opengl_capabilities.cpp +++ b/src/renderer_gl/opengl_capabilities.cpp @@ -43,6 +43,7 @@ constexpr std::uint32_t gl_texture_mag_filter = 0x2800U; constexpr std::uint32_t gl_texture_min_filter = 0x2801U; constexpr std::uint32_t gl_texture_wrap_s = 0x2802U; constexpr std::uint32_t gl_texture_wrap_t = 0x2803U; +constexpr std::uint32_t gl_texture_wrap_r = 0x8072U; constexpr std::uint32_t gl_clamp_to_edge = 0x812FU; [[nodiscard]] bool contains(std::string_view text, std::string_view needle) noexcept @@ -213,4 +214,27 @@ std::span default_render_target_texture_parameters return parameters; } +std::array sampler_parameters_for_filter_wrap( + std::uint32_t filter, + std::uint32_t wrap) noexcept +{ + return { + OpenGlTextureParameter { .name = gl_texture_wrap_s, .value = wrap }, + OpenGlTextureParameter { .name = gl_texture_wrap_t, .value = wrap }, + OpenGlTextureParameter { .name = gl_texture_wrap_r, .value = wrap }, + OpenGlTextureParameter { .name = gl_texture_min_filter, .value = filter }, + OpenGlTextureParameter { .name = gl_texture_mag_filter, .value = filter }, + }; +} + +std::array sampler_filter_parameters( + std::uint32_t filter_min, + std::uint32_t filter_mag) noexcept +{ + return { + OpenGlTextureParameter { .name = gl_texture_min_filter, .value = filter_min }, + OpenGlTextureParameter { .name = gl_texture_mag_filter, .value = filter_mag }, + }; +} + } diff --git a/src/renderer_gl/opengl_capabilities.h b/src/renderer_gl/opengl_capabilities.h index 9072c52..88af056 100644 --- a/src/renderer_gl/opengl_capabilities.h +++ b/src/renderer_gl/opengl_capabilities.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -44,5 +45,11 @@ struct OpenGlTextureParameter { [[nodiscard]] std::span panopainter_cube_face_texture_targets() noexcept; [[nodiscard]] std::uint32_t cube_face_texture_target(std::uint32_t face_index) noexcept; [[nodiscard]] std::span default_render_target_texture_parameters() noexcept; +[[nodiscard]] std::array sampler_parameters_for_filter_wrap( + std::uint32_t filter, + std::uint32_t wrap) noexcept; +[[nodiscard]] std::array sampler_filter_parameters( + std::uint32_t filter_min, + std::uint32_t filter_mag) noexcept; } diff --git a/src/texture.cpp b/src/texture.cpp index 22d572e..6dc9e5b 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -304,11 +304,12 @@ void Sampler::set(GLint filter /*= GL_LINEAR*/, GLint wrap /*= GL_CLAMP_TO_EDGE* App::I->render_task([=] { #if USE_SAMPLER - glSamplerParameteri(id, GL_TEXTURE_WRAP_S, wrap); - glSamplerParameteri(id, GL_TEXTURE_WRAP_T, wrap); - glSamplerParameteri(id, GL_TEXTURE_WRAP_R, wrap); - glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, filter); - glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, filter); + for (const auto parameter : pp::renderer::gl::sampler_parameters_for_filter_wrap( + static_cast(filter), + static_cast(wrap))) + { + glSamplerParameteri(id, static_cast(parameter.name), static_cast(parameter.value)); + } #endif // USE_SAMPLER }); } @@ -317,8 +318,12 @@ void Sampler::set_filter(GLint filter_min, GLint filter_mag) App::I->render_task([=] { #if USE_SAMPLER - glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, filter_min); - glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, filter_mag); + for (const auto parameter : pp::renderer::gl::sampler_filter_parameters( + static_cast(filter_min), + static_cast(filter_mag))) + { + glSamplerParameteri(id, static_cast(parameter.name), static_cast(parameter.value)); + } #endif // USE_SAMPLER }); } diff --git a/tests/renderer_gl/capabilities_tests.cpp b/tests/renderer_gl/capabilities_tests.cpp index cc718d5..70acd1e 100644 --- a/tests/renderer_gl/capabilities_tests.cpp +++ b/tests/renderer_gl/capabilities_tests.cpp @@ -189,6 +189,30 @@ void exposes_default_render_target_texture_parameters(pp::tests::Harness& h) PP_EXPECT(h, parameters[3].value == 0x812FU); } +void maps_sampler_parameters(pp::tests::Harness& h) +{ + const auto parameters = pp::renderer::gl::sampler_parameters_for_filter_wrap(0x2601U, 0x812FU); + + PP_EXPECT(h, parameters.size() == 5U); + PP_EXPECT(h, parameters[0].name == 0x2802U); + PP_EXPECT(h, parameters[0].value == 0x812FU); + PP_EXPECT(h, parameters[1].name == 0x2803U); + PP_EXPECT(h, parameters[1].value == 0x812FU); + PP_EXPECT(h, parameters[2].name == 0x8072U); + PP_EXPECT(h, parameters[2].value == 0x812FU); + PP_EXPECT(h, parameters[3].name == 0x2801U); + PP_EXPECT(h, parameters[3].value == 0x2601U); + PP_EXPECT(h, parameters[4].name == 0x2800U); + PP_EXPECT(h, parameters[4].value == 0x2601U); + + const auto filters = pp::renderer::gl::sampler_filter_parameters(0x2600U, 0x2601U); + PP_EXPECT(h, filters.size() == 2U); + PP_EXPECT(h, filters[0].name == 0x2801U); + PP_EXPECT(h, filters[0].value == 0x2600U); + PP_EXPECT(h, filters[1].name == 0x2800U); + PP_EXPECT(h, filters[1].value == 0x2601U); +} + void exposes_shader_attribute_binding_catalog(pp::tests::Harness& h) { const auto bindings = pp::renderer::gl::panopainter_shader_attribute_bindings(); @@ -293,6 +317,7 @@ int main() 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); harness.run("exposes_default_render_target_texture_parameters", exposes_default_render_target_texture_parameters); + harness.run("maps_sampler_parameters", maps_sampler_parameters); harness.run("exposes_shader_attribute_binding_catalog", exposes_shader_attribute_binding_catalog); harness.run("rejects_invalid_shader_attribute_binding_catalogs", rejects_invalid_shader_attribute_binding_catalogs); harness.run("exposes_shader_uniform_catalog", exposes_shader_uniform_catalog);