From dc03491b0d74ec07b645ebf2e15e5e3149ebc3a4 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Tue, 2 Jun 2026 18:14:40 +0200 Subject: [PATCH] Map renderer texture formats to OpenGL --- docs/modernization/build-inventory.md | 4 ++- docs/modernization/roadmap.md | 4 ++- src/renderer_gl/opengl_capabilities.cpp | 32 ++++++++++++++++++++++++ src/renderer_gl/opengl_capabilities.h | 9 +++++++ tests/renderer_gl/capabilities_tests.cpp | 28 +++++++++++++++++++++ 5 files changed, 75 insertions(+), 2 deletions(-) diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index 2556492..48f3302 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -185,7 +185,9 @@ Known local toolchain state: upload-type mapping used by legacy `Texture2D` and `RTT` creation, plus the RGBA pixel-format mapping used by `RTT` texture allocation. It also validates image channel-count to OpenGL texture format mapping, including - invalid channel counts rejected by `Texture2D::create(Image)`, RGBA8/RGBA32F + invalid channel counts rejected by `Texture2D::create(Image)`, renderer API + texture-format to OpenGL internal/pixel/component token mapping including + depth-stencil formats, RGBA8/RGBA32F readback formats, checked byte-count math, and PBO pixel-buffer target/usage/access mapping used by `RTT` and `PBO` readbacks, and framebuffer status naming used by `RTT` and `Texture2D` diagnostics. It also owns the 2D texture target, diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 8aaba15..f0244f9 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -440,7 +440,9 @@ float texture support. It also owns the OpenGL texture upload-type mapping used by legacy `Texture2D` and `RTT` creation, RGBA pixel-format mapping used by `RTT` texture allocation, plus image channel-count to texture format mapping for `Texture2D` image uploads and framebuffer status naming for -`RTT` and `Texture2D` diagnostics. `Texture2D` 2D texture binding, upload, +`RTT` and `Texture2D` diagnostics. It also owns renderer API texture-format to +OpenGL internal/pixel/component token mapping, including depth-stencil formats, +for future backend texture objects. `Texture2D` 2D texture binding, upload, mipmap generation, framebuffer readback setup, and update component-type tokens now delegate to `pp_renderer_gl`. `TextureCube` cube-map binding, allocation face targets, RGBA allocation format, and unsigned-byte component type also diff --git a/src/renderer_gl/opengl_capabilities.cpp b/src/renderer_gl/opengl_capabilities.cpp index ab46429..9a11374 100644 --- a/src/renderer_gl/opengl_capabilities.cpp +++ b/src/renderer_gl/opengl_capabilities.cpp @@ -68,6 +68,9 @@ constexpr std::uint32_t gl_rgb8 = 0x8051U; constexpr std::uint32_t gl_rgba8 = 0x8058U; constexpr std::uint32_t gl_rgba32f = 0x8814U; constexpr std::uint32_t gl_rgba16f = 0x881AU; +constexpr std::uint32_t gl_depth_stencil = 0x84F9U; +constexpr std::uint32_t gl_unsigned_int_24_8 = 0x84FAU; +constexpr std::uint32_t gl_depth24_stencil8 = 0x88F0U; constexpr std::uint32_t gl_texture_2d = 0x0DE1U; constexpr std::uint32_t gl_renderbuffer = 0x8D41U; constexpr std::uint32_t gl_depth_component24 = 0x81A6U; @@ -262,6 +265,35 @@ OpenGlPixelFormat texture_format_for_channel_count(std::uint32_t channel_count) } } +OpenGlRendererTextureFormat texture_format_for_renderer_format(pp::renderer::TextureFormat format) noexcept +{ + switch (format) { + case pp::renderer::TextureFormat::rgba8: + return OpenGlRendererTextureFormat { + .internal_format = gl_rgba8, + .pixel_format = gl_rgba, + .component_type = gl_unsigned_byte, + .bytes_per_pixel = 4U, + }; + case pp::renderer::TextureFormat::r8: + return OpenGlRendererTextureFormat { + .internal_format = gl_r8, + .pixel_format = gl_red, + .component_type = gl_unsigned_byte, + .bytes_per_pixel = 1U, + }; + case pp::renderer::TextureFormat::depth24_stencil8: + return OpenGlRendererTextureFormat { + .internal_format = gl_depth24_stencil8, + .pixel_format = gl_depth_stencil, + .component_type = gl_unsigned_int_24_8, + .bytes_per_pixel = 4U, + }; + default: + return OpenGlRendererTextureFormat {}; + } +} + OpenGlReadbackFormat rgba8_readback_format() noexcept { return OpenGlReadbackFormat { diff --git a/src/renderer_gl/opengl_capabilities.h b/src/renderer_gl/opengl_capabilities.h index 5e79f57..ec463f2 100644 --- a/src/renderer_gl/opengl_capabilities.h +++ b/src/renderer_gl/opengl_capabilities.h @@ -40,6 +40,13 @@ struct OpenGlReadbackFormat { std::uint32_t bytes_per_pixel = 0; }; +struct OpenGlRendererTextureFormat { + std::uint32_t internal_format = 0; + std::uint32_t pixel_format = 0; + std::uint32_t component_type = 0; + std::uint32_t bytes_per_pixel = 0; +}; + struct OpenGlWindowsWglContextConfig { std::array context_attributes {}; std::array pixel_format_attributes {}; @@ -59,6 +66,8 @@ struct OpenGlWindowsWglContextConfig { [[nodiscard]] std::uint32_t unsigned_byte_component_type() noexcept; [[nodiscard]] std::uint32_t rgba_pixel_format() noexcept; [[nodiscard]] OpenGlPixelFormat texture_format_for_channel_count(std::uint32_t channel_count) noexcept; +[[nodiscard]] OpenGlRendererTextureFormat texture_format_for_renderer_format( + pp::renderer::TextureFormat format) noexcept; [[nodiscard]] OpenGlReadbackFormat rgba8_readback_format() noexcept; [[nodiscard]] OpenGlReadbackFormat rgba32f_readback_format() noexcept; [[nodiscard]] std::uint64_t readback_byte_count( diff --git a/tests/renderer_gl/capabilities_tests.cpp b/tests/renderer_gl/capabilities_tests.cpp index 34d0680..5f48263 100644 --- a/tests/renderer_gl/capabilities_tests.cpp +++ b/tests/renderer_gl/capabilities_tests.cpp @@ -144,6 +144,33 @@ void maps_image_channel_count_to_texture_format(pp::tests::Harness& h) PP_EXPECT(h, invalid.pixel_format == 0U); } +void maps_renderer_texture_formats_to_opengl_tokens(pp::tests::Harness& h) +{ + const auto rgba8 = pp::renderer::gl::texture_format_for_renderer_format(pp::renderer::TextureFormat::rgba8); + const auto r8 = pp::renderer::gl::texture_format_for_renderer_format(pp::renderer::TextureFormat::r8); + const auto depth_stencil = pp::renderer::gl::texture_format_for_renderer_format( + pp::renderer::TextureFormat::depth24_stencil8); + const auto invalid = pp::renderer::gl::texture_format_for_renderer_format( + static_cast(255U)); + + PP_EXPECT(h, rgba8.internal_format == 0x8058U); + PP_EXPECT(h, rgba8.pixel_format == 0x1908U); + PP_EXPECT(h, rgba8.component_type == 0x1401U); + PP_EXPECT(h, rgba8.bytes_per_pixel == 4U); + PP_EXPECT(h, r8.internal_format == 0x8229U); + PP_EXPECT(h, r8.pixel_format == 0x1903U); + PP_EXPECT(h, r8.component_type == 0x1401U); + PP_EXPECT(h, r8.bytes_per_pixel == 1U); + PP_EXPECT(h, depth_stencil.internal_format == 0x88F0U); + PP_EXPECT(h, depth_stencil.pixel_format == 0x84F9U); + PP_EXPECT(h, depth_stencil.component_type == 0x84FAU); + PP_EXPECT(h, depth_stencil.bytes_per_pixel == 4U); + PP_EXPECT(h, invalid.internal_format == 0U); + PP_EXPECT(h, invalid.pixel_format == 0U); + PP_EXPECT(h, invalid.component_type == 0U); + PP_EXPECT(h, invalid.bytes_per_pixel == 0U); +} + void maps_readback_formats(pp::tests::Harness& h) { const auto rgba8 = pp::renderer::gl::rgba8_readback_format(); @@ -512,6 +539,7 @@ int main() harness.run("ignores_gles_texture_extensions_for_webgl_runtime", ignores_gles_texture_extensions_for_webgl_runtime); harness.run("selects_texture_upload_type_from_internal_format", selects_texture_upload_type_from_internal_format); harness.run("maps_image_channel_count_to_texture_format", maps_image_channel_count_to_texture_format); + harness.run("maps_renderer_texture_formats_to_opengl_tokens", maps_renderer_texture_formats_to_opengl_tokens); harness.run("maps_readback_formats", maps_readback_formats); harness.run("maps_pixel_buffer_parameters", maps_pixel_buffer_parameters); harness.run("names_framebuffer_status_codes", names_framebuffer_status_codes);