Move OpenGL framebuffer diagnostics

This commit is contained in:
2026-06-01 17:50:51 +02:00
parent 2e0ebd0e13
commit aa32c47e18
6 changed files with 63 additions and 18 deletions

View File

@@ -129,7 +129,8 @@ Known local toolchain state:
GLES float/half-float extensions, WebGL exclusion behavior, and the
upload-type mapping used by legacy `Texture2D` and `RTT` creation. It also
validates image channel-count to OpenGL texture format mapping, including
invalid channel counts rejected by `Texture2D::create(Image)`.
invalid channel counts rejected by `Texture2D::create(Image)`, and
framebuffer status naming used by `RTT` diagnostics.
- `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.

View File

@@ -389,9 +389,10 @@ catalog now consumed by the legacy OpenGL app initialization path.
OpenGL capability detection for framebuffer fetch, map-buffer alignment, and
float texture support. It also owns the OpenGL texture upload-type mapping used
by legacy `Texture2D` and `RTT` creation, plus image channel-count to texture
format mapping for `Texture2D` image uploads. The legacy app delegates
extension and upload-format interpretation to that backend library, but the
existing renderer classes are not yet fully behind the renderer interfaces.
format mapping for `Texture2D` image uploads and framebuffer status naming for
`RTT` diagnostics. The legacy app delegates extension, upload-format, and
framebuffer diagnostic interpretation to that backend library, but the existing
renderer classes are not yet fully behind the renderer interfaces.
Implementation tasks:
@@ -631,7 +632,8 @@ Results:
and Android arm64 configure/build, covering framebuffer fetch, map-buffer
alignment, desktop GL core float support, GLES float/half-float extensions,
WebGL exclusion behavior, upload types for RGBA8/RGBA16F/RGBA32F internal
formats, and image channel-count format mapping including invalid counts.
formats, image channel-count format mapping including invalid counts, and
framebuffer status names.
- PowerShell analyze automation returns JSON summaries and includes the shader
validation target.
- `windows-msvc-vcpkg-headless` configured through the Visual Studio bundled

View File

@@ -17,6 +17,14 @@ 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_framebuffer_complete = 0x8CD5U;
constexpr std::uint32_t gl_framebuffer_incomplete_attachment = 0x8CD6U;
constexpr std::uint32_t gl_framebuffer_incomplete_missing_attachment = 0x8CD7U;
constexpr std::uint32_t gl_framebuffer_incomplete_draw_buffer = 0x8CDBU;
constexpr std::uint32_t gl_framebuffer_incomplete_read_buffer = 0x8CDCU;
constexpr std::uint32_t gl_framebuffer_unsupported = 0x8CDDU;
constexpr std::uint32_t gl_framebuffer_undefined = 0x8219U;
constexpr std::uint32_t gl_framebuffer_incomplete_multisample = 0x8D56U;
[[nodiscard]] bool contains(std::string_view text, std::string_view needle) noexcept
{
@@ -92,4 +100,28 @@ OpenGlPixelFormat texture_format_for_channel_count(std::uint32_t channel_count)
}
}
const char* framebuffer_status_name(std::uint32_t status) noexcept
{
switch (status) {
case gl_framebuffer_complete:
return "GL_FRAMEBUFFER_COMPLETE";
case gl_framebuffer_undefined:
return "GL_FRAMEBUFFER_UNDEFINED";
case gl_framebuffer_incomplete_attachment:
return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
case gl_framebuffer_incomplete_missing_attachment:
return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
case gl_framebuffer_incomplete_draw_buffer:
return "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER";
case gl_framebuffer_incomplete_read_buffer:
return "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER";
case gl_framebuffer_unsupported:
return "GL_FRAMEBUFFER_UNSUPPORTED";
case gl_framebuffer_incomplete_multisample:
return "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE";
default:
return "UNKNOWN";
}
}
}

View File

@@ -32,5 +32,6 @@ struct OpenGlPixelFormat {
[[nodiscard]] std::uint32_t texture_upload_type_for_internal_format(std::uint32_t internal_format) noexcept;
[[nodiscard]] OpenGlPixelFormat texture_format_for_channel_count(std::uint32_t channel_count) noexcept;
[[nodiscard]] const char* framebuffer_status_name(std::uint32_t status) noexcept;
}

View File

@@ -244,22 +244,11 @@ bool RTT::create(int width, int height, int tex/* = -1*/, GLint internal_format,
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboID);
}
auto err2str = [](GLenum err) {
switch (err)
{
case GL_FRAMEBUFFER_UNDEFINED: return "GL_FRAMEBUFFER_UNDEFINED";
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: return "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
case GL_FRAMEBUFFER_UNSUPPORTED: return "GL_FRAMEBUFFER_UNSUPPORTED";
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: return "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE";
default: return "UNKNOWN";
}
};
// Check FBO status
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
LOG("RTT::create failed because: %s", err2str(status));
LOG("RTT::create failed because: %s",
pp::renderer::gl::framebuffer_status_name(static_cast<std::uint32_t>(status)));
// Switch back to window-system-provided framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, oldFboID);

View File

@@ -114,6 +114,25 @@ void maps_image_channel_count_to_texture_format(pp::tests::Harness& h)
PP_EXPECT(h, invalid.pixel_format == 0U);
}
void names_framebuffer_status_codes(pp::tests::Harness& h)
{
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)
== std::string_view("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"));
PP_EXPECT(h, pp::renderer::gl::framebuffer_status_name(0x8CD7U)
== std::string_view("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"));
PP_EXPECT(h, pp::renderer::gl::framebuffer_status_name(0x8CDBU)
== std::string_view("GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"));
PP_EXPECT(h, pp::renderer::gl::framebuffer_status_name(0x8CDCU)
== std::string_view("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"));
PP_EXPECT(h, pp::renderer::gl::framebuffer_status_name(0x8CDDU)
== std::string_view("GL_FRAMEBUFFER_UNSUPPORTED"));
PP_EXPECT(h, pp::renderer::gl::framebuffer_status_name(0x8D56U)
== std::string_view("GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"));
PP_EXPECT(h, pp::renderer::gl::framebuffer_status_name(0U) == std::string_view("UNKNOWN"));
}
}
int main()
@@ -125,5 +144,6 @@ 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("names_framebuffer_status_codes", names_framebuffer_status_codes);
return harness.finish();
}