diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index 5ea9fbc..d8f9843 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -135,9 +135,11 @@ Known local toolchain state: used by `RTT` diagnostics. It also owns and validates framebuffer blit color mask and linear/nearest filters used by `RTT::resize` and `RTT::copy`, plus the default linear clamp-to-edge - render-target texture parameters 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 + 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. 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`. It also owns and validates sampler wrap S/T/R, min/mag filter, and desktop border-color parameter mapping used by legacy `Sampler`. The PanoPainter diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 64a24b1..14d56b2 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -394,15 +394,17 @@ format mapping for `Texture2D` image uploads and framebuffer status naming for pixel-buffer target/usage/access tokens used by `RTT` and `PBO` readbacks now live in `pp_renderer_gl`. The framebuffer blit color mask and linear/nearest filter tokens used by `RTT::resize` and `RTT::copy`, plus the default -render-target texture parameters used by `RTT::create`, also live in +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`. Mesh index-type and primitive-mode 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, framebuffer blit, render-target texture parameter, -mesh draw-mode, and cube-face texture-target interpretation to that backend -library. Sampler wrap, min/mag filter, and desktop border-color parameter +framebuffer diagnostic, framebuffer blit, render-target setup, mesh draw-mode, +and cube-face texture-target interpretation to that backend library. Sampler +wrap, min/mag filter, and desktop border-color 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 diff --git a/src/renderer_gl/opengl_capabilities.cpp b/src/renderer_gl/opengl_capabilities.cpp index 7b82678..75d253b 100644 --- a/src/renderer_gl/opengl_capabilities.cpp +++ b/src/renderer_gl/opengl_capabilities.cpp @@ -24,6 +24,16 @@ 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_texture_2d = 0x0DE1U; +constexpr std::uint32_t gl_renderbuffer = 0x8D41U; +constexpr std::uint32_t gl_depth_component24 = 0x81A6U; +constexpr std::uint32_t gl_framebuffer = 0x8D40U; +constexpr std::uint32_t gl_read_framebuffer = 0x8CA8U; +constexpr std::uint32_t gl_draw_framebuffer = 0x8CA9U; +constexpr std::uint32_t gl_draw_framebuffer_binding = 0x8CA6U; +constexpr std::uint32_t gl_read_framebuffer_binding = 0x8CAAU; +constexpr std::uint32_t gl_color_attachment0 = 0x8CE0U; +constexpr std::uint32_t gl_depth_attachment = 0x8D00U; constexpr std::uint32_t gl_framebuffer_complete = 0x8CD5U; constexpr std::uint32_t gl_framebuffer_incomplete_attachment = 0x8CD6U; constexpr std::uint32_t gl_framebuffer_incomplete_missing_attachment = 0x8CD7U; @@ -173,6 +183,61 @@ std::uint32_t pixel_buffer_map_read_access() noexcept return gl_map_read_bit; } +std::uint32_t texture_2d_target() noexcept +{ + return gl_texture_2d; +} + +std::uint32_t renderbuffer_target() noexcept +{ + return gl_renderbuffer; +} + +std::uint32_t depth_component24_format() noexcept +{ + return gl_depth_component24; +} + +std::uint32_t framebuffer_target() noexcept +{ + return gl_framebuffer; +} + +std::uint32_t draw_framebuffer_target() noexcept +{ + return gl_draw_framebuffer; +} + +std::uint32_t read_framebuffer_target() noexcept +{ + return gl_read_framebuffer; +} + +std::uint32_t draw_framebuffer_binding_query() noexcept +{ + return gl_draw_framebuffer_binding; +} + +std::uint32_t read_framebuffer_binding_query() noexcept +{ + return gl_read_framebuffer_binding; +} + +std::uint32_t framebuffer_color_attachment() noexcept +{ + return gl_color_attachment0; +} + +std::uint32_t framebuffer_depth_attachment() noexcept +{ + return gl_depth_attachment; +} + +std::uint32_t framebuffer_complete_status() noexcept +{ + return gl_framebuffer_complete; +} + const char* framebuffer_status_name(std::uint32_t status) noexcept { switch (status) { diff --git a/src/renderer_gl/opengl_capabilities.h b/src/renderer_gl/opengl_capabilities.h index 084c60e..141eda5 100644 --- a/src/renderer_gl/opengl_capabilities.h +++ b/src/renderer_gl/opengl_capabilities.h @@ -54,6 +54,17 @@ struct OpenGlReadbackFormat { [[nodiscard]] std::uint32_t pixel_unpack_buffer_target() noexcept; [[nodiscard]] std::uint32_t pixel_buffer_stream_read_usage() noexcept; [[nodiscard]] std::uint32_t pixel_buffer_map_read_access() noexcept; +[[nodiscard]] std::uint32_t texture_2d_target() noexcept; +[[nodiscard]] std::uint32_t renderbuffer_target() noexcept; +[[nodiscard]] std::uint32_t depth_component24_format() noexcept; +[[nodiscard]] std::uint32_t framebuffer_target() noexcept; +[[nodiscard]] std::uint32_t draw_framebuffer_target() noexcept; +[[nodiscard]] std::uint32_t read_framebuffer_target() noexcept; +[[nodiscard]] std::uint32_t draw_framebuffer_binding_query() noexcept; +[[nodiscard]] std::uint32_t read_framebuffer_binding_query() noexcept; +[[nodiscard]] std::uint32_t framebuffer_color_attachment() noexcept; +[[nodiscard]] std::uint32_t framebuffer_depth_attachment() noexcept; +[[nodiscard]] std::uint32_t framebuffer_complete_status() noexcept; [[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_blit_filter(bool linear) noexcept; diff --git a/src/rtt.cpp b/src/rtt.cpp index ae69e3f..27d3c24 100644 --- a/src/rtt.cpp +++ b/src/rtt.cpp @@ -7,6 +7,45 @@ #include +namespace { + +[[nodiscard]] GLenum texture_2d_target() noexcept +{ + return static_cast(pp::renderer::gl::texture_2d_target()); +} + +[[nodiscard]] GLenum renderbuffer_target() noexcept +{ + return static_cast(pp::renderer::gl::renderbuffer_target()); +} + +[[nodiscard]] GLenum framebuffer_target() noexcept +{ + return static_cast(pp::renderer::gl::framebuffer_target()); +} + +[[nodiscard]] GLenum draw_framebuffer_target() noexcept +{ + return static_cast(pp::renderer::gl::draw_framebuffer_target()); +} + +[[nodiscard]] GLenum read_framebuffer_target() noexcept +{ + return static_cast(pp::renderer::gl::read_framebuffer_target()); +} + +[[nodiscard]] GLenum draw_framebuffer_binding_query() noexcept +{ + return static_cast(pp::renderer::gl::draw_framebuffer_binding_query()); +} + +[[nodiscard]] GLenum read_framebuffer_binding_query() noexcept +{ + return static_cast(pp::renderer::gl::read_framebuffer_binding_query()); +} + +} + RTT& RTT::operator=(RTT&& other) { int_fmt = other.int_fmt; @@ -73,8 +112,8 @@ bool RTT::resize(int width, int height) App::I->render_task([&] { - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldDFboID); - glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &oldRFboID); + glGetIntegerv(draw_framebuffer_binding_query(), &oldDFboID); + glGetIntegerv(read_framebuffer_binding_query(), &oldRFboID); ret = new_rtt.create(width, height, -1, int_fmt, rboID != 0); if (!ret) @@ -83,8 +122,8 @@ bool RTT::resize(int width, int height) return; } - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, new_rtt.fboID); - glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID); + glBindFramebuffer(draw_framebuffer_target(), new_rtt.fboID); + glBindFramebuffer(read_framebuffer_target(), fboID); glBlitFramebuffer( 0, 0, @@ -97,8 +136,8 @@ bool RTT::resize(int width, int height) static_cast(pp::renderer::gl::framebuffer_color_buffer_mask()), static_cast(pp::renderer::gl::framebuffer_blit_filter(true))); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oldDFboID); - glBindFramebuffer(GL_READ_FRAMEBUFFER, oldRFboID); + glBindFramebuffer(draw_framebuffer_target(), oldDFboID); + glBindFramebuffer(read_framebuffer_target(), oldRFboID); destroy(); }); @@ -151,17 +190,17 @@ void RTT::copy(const RTT & source) { GLint old_draw = 0; GLint old_read = 0; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_draw); - glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &old_read); + glGetIntegerv(draw_framebuffer_binding_query(), &old_draw); + glGetIntegerv(read_framebuffer_binding_query(), &old_read); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboID); - glBindFramebuffer(GL_READ_FRAMEBUFFER, source.fboID); + glBindFramebuffer(draw_framebuffer_target(), fboID); + glBindFramebuffer(read_framebuffer_target(), source.fboID); glBlitFramebuffer(0, 0, source.w, source.h, 0, 0, w, h, static_cast(pp::renderer::gl::framebuffer_color_buffer_mask()), static_cast(pp::renderer::gl::framebuffer_blit_filter(true))); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old_draw); - glBindFramebuffer(GL_READ_FRAMEBUFFER, old_read); + glBindFramebuffer(draw_framebuffer_target(), old_draw); + glBindFramebuffer(read_framebuffer_target(), old_read); }); } @@ -175,17 +214,17 @@ void RTT::copy(const RTT& source, const glm::vec4& rect) GLint old_draw = 0; GLint old_read = 0; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_draw); - glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &old_read); + glGetIntegerv(draw_framebuffer_binding_query(), &old_draw); + glGetIntegerv(read_framebuffer_binding_query(), &old_read); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboID); - glBindFramebuffer(GL_READ_FRAMEBUFFER, source.fboID); + glBindFramebuffer(draw_framebuffer_target(), fboID); + glBindFramebuffer(read_framebuffer_target(), source.fboID); glBlitFramebuffer(r.x, r.y, r.z, r.w, r.x, r.y, r.z, r.w, static_cast(pp::renderer::gl::framebuffer_color_buffer_mask()), static_cast(pp::renderer::gl::framebuffer_blit_filter(false))); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old_draw); - glBindFramebuffer(GL_READ_FRAMEBUFFER, old_read); + glBindFramebuffer(draw_framebuffer_target(), old_draw); + glBindFramebuffer(read_framebuffer_target(), old_read); }); } @@ -222,56 +261,69 @@ bool RTT::create(int width, int height, int tex/* = -1*/, GLint internal_format, const auto ifmt = static_cast( pp::renderer::gl::texture_upload_type_for_internal_format(static_cast(internal_format))); - glBindTexture(GL_TEXTURE_2D, texID); + glBindTexture(texture_2d_target(), texID); if (tex == -1) - glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, GL_RGBA, ifmt, 0); + glTexImage2D(texture_2d_target(), 0, internal_format, width, height, 0, GL_RGBA, ifmt, 0); for (const auto parameter : pp::renderer::gl::default_render_target_texture_parameters()) { glTexParameterf( - GL_TEXTURE_2D, + texture_2d_target(), static_cast(parameter.name), static_cast(parameter.value)); } - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(texture_2d_target(), 0); // Create a renderbuffer object to store depth info if (depth_buffer) { glGenRenderbuffers(1, &rboID); - glBindRenderbuffer(GL_RENDERBUFFER, rboID); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height); - glBindRenderbuffer(GL_RENDERBUFFER, 0); + glBindRenderbuffer(renderbuffer_target(), rboID); + glRenderbufferStorage( + renderbuffer_target(), + static_cast(pp::renderer::gl::depth_component24_format()), + width, + height); + glBindRenderbuffer(renderbuffer_target(), 0); } GLint oldFboID; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldFboID); + glGetIntegerv(draw_framebuffer_binding_query(), &oldFboID); // Create a framebuffer object glGenFramebuffers(1, &fboID); - glBindFramebuffer(GL_FRAMEBUFFER, fboID); + glBindFramebuffer(framebuffer_target(), fboID); //LOG("RTT CREATE %d - tex %d", fboID, texID); // Attach the texture to FBO color attachment point - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texID, 0); + glFramebufferTexture2D( + framebuffer_target(), + static_cast(pp::renderer::gl::framebuffer_color_attachment()), + texture_2d_target(), + texID, + 0); if (depth_buffer) { // Attach the renderbuffer to depth attachment point - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboID); + glFramebufferRenderbuffer( + framebuffer_target(), + static_cast(pp::renderer::gl::framebuffer_depth_attachment()), + renderbuffer_target(), + rboID); } // Check FBO status - status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) + status = glCheckFramebufferStatus(framebuffer_target()); + if (status != static_cast(pp::renderer::gl::framebuffer_complete_status())) LOG("RTT::create failed because: %s", pp::renderer::gl::framebuffer_status_name(static_cast(status))); // Switch back to window-system-provided framebuffer - glBindFramebuffer(GL_FRAMEBUFFER, oldFboID); + glBindFramebuffer(framebuffer_target(), oldFboID); oldRFboID = 0; oldDFboID = 0; }); - return status == GL_FRAMEBUFFER_COMPLETE; + return status == static_cast(pp::renderer::gl::framebuffer_complete_status()); } void RTT::bindFramebuffer() @@ -286,10 +338,10 @@ void RTT::bindFramebuffer() #endif } #endif // _DEBUG - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldDFboID); - glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &oldRFboID); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboID); - glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID); + glGetIntegerv(draw_framebuffer_binding_query(), &oldDFboID); + glGetIntegerv(read_framebuffer_binding_query(), &oldRFboID); + glBindFramebuffer(draw_framebuffer_target(), fboID); + glBindFramebuffer(read_framebuffer_target(), fboID); bound = true; } @@ -298,8 +350,8 @@ void RTT::unbindFramebuffer() assert(App::I->is_render_thread()); if (!bound) return; - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oldDFboID); - glBindFramebuffer(GL_READ_FRAMEBUFFER, oldRFboID); + glBindFramebuffer(draw_framebuffer_target(), oldDFboID); + glBindFramebuffer(read_framebuffer_target(), oldRFboID); oldRFboID = 0; oldDFboID = 0; bound = false; @@ -360,8 +412,8 @@ uint8_t* RTT::readTextureData(uint8_t* buffer) const noexcept { const auto readback = pp::renderer::gl::rgba8_readback_format(); GLint old; - glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &old); - glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID); + glGetIntegerv(read_framebuffer_binding_query(), &old); + glBindFramebuffer(read_framebuffer_target(), fboID); glReadPixels( 0, 0, @@ -370,7 +422,7 @@ uint8_t* RTT::readTextureData(uint8_t* buffer) const noexcept static_cast(readback.pixel_format), static_cast(readback.component_type), buffer); - glBindFramebuffer(GL_READ_FRAMEBUFFER, old); + glBindFramebuffer(read_framebuffer_target(), old); }); return buffer; } @@ -385,8 +437,8 @@ float* RTT::readTextureDataFloat(float* buffer) const noexcept { const auto readback = pp::renderer::gl::rgba32f_readback_format(); GLint old; - glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &old); - glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID); + glGetIntegerv(read_framebuffer_binding_query(), &old); + glBindFramebuffer(read_framebuffer_target(), fboID); glReadPixels( 0, 0, @@ -395,7 +447,7 @@ float* RTT::readTextureDataFloat(float* buffer) const noexcept static_cast(readback.pixel_format), static_cast(readback.component_type), buffer); - glBindFramebuffer(GL_READ_FRAMEBUFFER, old); + glBindFramebuffer(read_framebuffer_target(), old); }); return buffer; } @@ -422,13 +474,13 @@ float * RTT::createBufferFloat() const noexcept void RTT::bindTexture() { assert(App::I->is_render_thread()); - glBindTexture(GL_TEXTURE_2D, texID); + glBindTexture(texture_2d_target(), texID); } void RTT::unbindTexture() { assert(App::I->is_render_thread()); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(texture_2d_target(), 0); } Image RTT::get_image() const noexcept diff --git a/tests/renderer_gl/capabilities_tests.cpp b/tests/renderer_gl/capabilities_tests.cpp index c550300..a05e880 100644 --- a/tests/renderer_gl/capabilities_tests.cpp +++ b/tests/renderer_gl/capabilities_tests.cpp @@ -142,6 +142,7 @@ void maps_pixel_buffer_parameters(pp::tests::Harness& h) void names_framebuffer_status_codes(pp::tests::Harness& h) { + PP_EXPECT(h, pp::renderer::gl::framebuffer_complete_status() == 0x8CD5U); PP_EXPECT(h, pp::renderer::gl::framebuffer_status_name(0x8CD5U) == std::string_view("GL_FRAMEBUFFER_COMPLETE")); PP_EXPECT(h, pp::renderer::gl::framebuffer_status_name(0x8219U) == std::string_view("GL_FRAMEBUFFER_UNDEFINED")); PP_EXPECT(h, pp::renderer::gl::framebuffer_status_name(0x8CD6U) @@ -159,6 +160,20 @@ void names_framebuffer_status_codes(pp::tests::Harness& h) PP_EXPECT(h, pp::renderer::gl::framebuffer_status_name(0U) == std::string_view("UNKNOWN")); } +void maps_framebuffer_render_target_parameters(pp::tests::Harness& h) +{ + PP_EXPECT(h, pp::renderer::gl::texture_2d_target() == 0x0DE1U); + PP_EXPECT(h, pp::renderer::gl::renderbuffer_target() == 0x8D41U); + PP_EXPECT(h, pp::renderer::gl::depth_component24_format() == 0x81A6U); + PP_EXPECT(h, pp::renderer::gl::framebuffer_target() == 0x8D40U); + PP_EXPECT(h, pp::renderer::gl::draw_framebuffer_target() == 0x8CA9U); + PP_EXPECT(h, pp::renderer::gl::read_framebuffer_target() == 0x8CA8U); + PP_EXPECT(h, pp::renderer::gl::draw_framebuffer_binding_query() == 0x8CA6U); + PP_EXPECT(h, pp::renderer::gl::read_framebuffer_binding_query() == 0x8CAAU); + PP_EXPECT(h, pp::renderer::gl::framebuffer_color_attachment() == 0x8CE0U); + PP_EXPECT(h, pp::renderer::gl::framebuffer_depth_attachment() == 0x8D00U); +} + void maps_framebuffer_blit_parameters(pp::tests::Harness& h) { PP_EXPECT(h, pp::renderer::gl::framebuffer_color_buffer_mask() == 0x00004000U); @@ -349,6 +364,7 @@ int main() 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); + 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_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);