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 GLES float/half-float extensions, WebGL exclusion behavior, and the
upload-type mapping used by legacy `Texture2D` and `RTT` creation. It also upload-type mapping used by legacy `Texture2D` and `RTT` creation. It also
validates image channel-count to OpenGL texture format mapping, including 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 - `windows-msvc-vcpkg-headless` validates manifest install/configure/build/test
for the current headless component matrix; see DEBT-0007 for remaining app for the current headless component matrix; see DEBT-0007 for remaining app
and platform triplet migration. 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 OpenGL capability detection for framebuffer fetch, map-buffer alignment, and
float texture support. It also owns the OpenGL texture upload-type mapping used 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 by legacy `Texture2D` and `RTT` creation, plus image channel-count to texture
format mapping for `Texture2D` image uploads. The legacy app delegates format mapping for `Texture2D` image uploads and framebuffer status naming for
extension and upload-format interpretation to that backend library, but the `RTT` diagnostics. The legacy app delegates extension, upload-format, and
existing renderer classes are not yet fully behind the renderer interfaces. framebuffer diagnostic interpretation to that backend library, but the existing
renderer classes are not yet fully behind the renderer interfaces.
Implementation tasks: Implementation tasks:
@@ -631,7 +632,8 @@ Results:
and Android arm64 configure/build, covering framebuffer fetch, map-buffer and Android arm64 configure/build, covering framebuffer fetch, map-buffer
alignment, desktop GL core float support, GLES float/half-float extensions, alignment, desktop GL core float support, GLES float/half-float extensions,
WebGL exclusion behavior, upload types for RGBA8/RGBA16F/RGBA32F internal 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 - PowerShell analyze automation returns JSON summaries and includes the shader
validation target. validation target.
- `windows-msvc-vcpkg-headless` configured through the Visual Studio bundled - `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_rgba8 = 0x8058U;
constexpr std::uint32_t gl_rgba32f = 0x8814U; constexpr std::uint32_t gl_rgba32f = 0x8814U;
constexpr std::uint32_t gl_rgba16f = 0x881AU; 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 [[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]] 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]] 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); 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 // Check FBO status
status = glCheckFramebufferStatus(GL_FRAMEBUFFER); status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) 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 // Switch back to window-system-provided framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, oldFboID); 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); 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() 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("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("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_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(); return harness.finish();
} }