Move OpenGL image format mapping
This commit is contained in:
@@ -127,7 +127,9 @@ Known local toolchain state:
|
||||
by the legacy app initialization path; `pp_renderer_gl_capabilities_tests`
|
||||
validates framebuffer fetch, map-buffer alignment, desktop GL float support,
|
||||
GLES float/half-float extensions, WebGL exclusion behavior, and the
|
||||
upload-type mapping used by legacy `Texture2D` and `RTT` creation.
|
||||
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)`.
|
||||
- `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.
|
||||
|
||||
@@ -388,9 +388,10 @@ catalog now consumed by the legacy OpenGL app initialization path.
|
||||
`pp_renderer_gl` now exists as the first OpenGL backend library and owns pure
|
||||
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. 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.
|
||||
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.
|
||||
|
||||
Implementation tasks:
|
||||
|
||||
@@ -629,8 +630,8 @@ Results:
|
||||
- `pp_renderer_gl_capabilities_tests` passed on default MSVC, vcpkg-headless,
|
||||
and Android arm64 configure/build, covering framebuffer fetch, map-buffer
|
||||
alignment, desktop GL core float support, GLES float/half-float extensions,
|
||||
WebGL exclusion behavior, and upload types for RGBA8/RGBA16F/RGBA32F
|
||||
internal formats.
|
||||
WebGL exclusion behavior, upload types for RGBA8/RGBA16F/RGBA32F internal
|
||||
formats, and image channel-count format mapping including invalid counts.
|
||||
- PowerShell analyze automation returns JSON summaries and includes the shader
|
||||
validation target.
|
||||
- `windows-msvc-vcpkg-headless` configured through the Visual Studio bundled
|
||||
|
||||
@@ -7,6 +7,14 @@ namespace {
|
||||
constexpr std::uint32_t gl_unsigned_byte = 0x1401U;
|
||||
constexpr std::uint32_t gl_float = 0x1406U;
|
||||
constexpr std::uint32_t gl_half_float = 0x140BU;
|
||||
constexpr std::uint32_t gl_red = 0x1903U;
|
||||
constexpr std::uint32_t gl_rgb = 0x1907U;
|
||||
constexpr std::uint32_t gl_rgba = 0x1908U;
|
||||
constexpr std::uint32_t gl_rg = 0x8227U;
|
||||
constexpr std::uint32_t gl_r8 = 0x8229U;
|
||||
constexpr std::uint32_t gl_rg8 = 0x822BU;
|
||||
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;
|
||||
|
||||
@@ -68,4 +76,20 @@ std::uint32_t texture_upload_type_for_internal_format(std::uint32_t internal_for
|
||||
}
|
||||
}
|
||||
|
||||
OpenGlPixelFormat texture_format_for_channel_count(std::uint32_t channel_count) noexcept
|
||||
{
|
||||
switch (channel_count) {
|
||||
case 1:
|
||||
return OpenGlPixelFormat { .internal_format = gl_r8, .pixel_format = gl_red, .channel_count = 1 };
|
||||
case 2:
|
||||
return OpenGlPixelFormat { .internal_format = gl_rg8, .pixel_format = gl_rg, .channel_count = 2 };
|
||||
case 3:
|
||||
return OpenGlPixelFormat { .internal_format = gl_rgb8, .pixel_format = gl_rgb, .channel_count = 3 };
|
||||
case 4:
|
||||
return OpenGlPixelFormat { .internal_format = gl_rgba8, .pixel_format = gl_rgba, .channel_count = 4 };
|
||||
default:
|
||||
return OpenGlPixelFormat {};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,10 +20,17 @@ struct OpenGlCapabilities {
|
||||
bool float16_textures = false;
|
||||
};
|
||||
|
||||
struct OpenGlPixelFormat {
|
||||
std::uint32_t internal_format = 0;
|
||||
std::uint32_t pixel_format = 0;
|
||||
std::uint32_t channel_count = 0;
|
||||
};
|
||||
|
||||
[[nodiscard]] OpenGlCapabilities detect_opengl_capabilities(
|
||||
std::span<const std::string_view> extensions,
|
||||
OpenGlRuntime runtime) 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;
|
||||
|
||||
}
|
||||
|
||||
@@ -188,9 +188,16 @@ bool Texture2D::create(int width, int height, GLint internal_format, GLint forma
|
||||
}
|
||||
bool Texture2D::create(const Image& img)
|
||||
{
|
||||
static GLint formats[] = { GL_RED, GL_RG, GL_RGB, GL_RGBA };
|
||||
static GLint iformats[] = { GL_R8, GL_RG8, GL_RGB8, GL_RGBA8 };
|
||||
return create(img.width, img.height, iformats[img.comp - 1], formats[img.comp - 1], img.data());
|
||||
const auto format = pp::renderer::gl::texture_format_for_channel_count(static_cast<std::uint32_t>(img.comp));
|
||||
if (format.channel_count == 0U)
|
||||
return false;
|
||||
|
||||
return create(
|
||||
img.width,
|
||||
img.height,
|
||||
static_cast<GLint>(format.internal_format),
|
||||
static_cast<GLint>(format.pixel_format),
|
||||
img.data());
|
||||
}
|
||||
|
||||
void Texture2D::create_mipmaps()
|
||||
|
||||
@@ -84,6 +84,36 @@ void selects_texture_upload_type_from_internal_format(pp::tests::Harness& h)
|
||||
PP_EXPECT(h, pp::renderer::gl::texture_upload_type_for_internal_format(0U) == gl_unsigned_byte);
|
||||
}
|
||||
|
||||
void maps_image_channel_count_to_texture_format(pp::tests::Harness& h)
|
||||
{
|
||||
constexpr std::uint32_t gl_red = 0x1903U;
|
||||
constexpr std::uint32_t gl_rgb = 0x1907U;
|
||||
constexpr std::uint32_t gl_rgba = 0x1908U;
|
||||
constexpr std::uint32_t gl_rg = 0x8227U;
|
||||
constexpr std::uint32_t gl_r8 = 0x8229U;
|
||||
constexpr std::uint32_t gl_rg8 = 0x822BU;
|
||||
constexpr std::uint32_t gl_rgb8 = 0x8051U;
|
||||
constexpr std::uint32_t gl_rgba8 = 0x8058U;
|
||||
|
||||
const auto r = pp::renderer::gl::texture_format_for_channel_count(1U);
|
||||
const auto rg = pp::renderer::gl::texture_format_for_channel_count(2U);
|
||||
const auto rgb = pp::renderer::gl::texture_format_for_channel_count(3U);
|
||||
const auto rgba = pp::renderer::gl::texture_format_for_channel_count(4U);
|
||||
const auto invalid = pp::renderer::gl::texture_format_for_channel_count(5U);
|
||||
|
||||
PP_EXPECT(h, r.internal_format == gl_r8);
|
||||
PP_EXPECT(h, r.pixel_format == gl_red);
|
||||
PP_EXPECT(h, rg.internal_format == gl_rg8);
|
||||
PP_EXPECT(h, rg.pixel_format == gl_rg);
|
||||
PP_EXPECT(h, rgb.internal_format == gl_rgb8);
|
||||
PP_EXPECT(h, rgb.pixel_format == gl_rgb);
|
||||
PP_EXPECT(h, rgba.internal_format == gl_rgba8);
|
||||
PP_EXPECT(h, rgba.pixel_format == gl_rgba);
|
||||
PP_EXPECT(h, invalid.channel_count == 0U);
|
||||
PP_EXPECT(h, invalid.internal_format == 0U);
|
||||
PP_EXPECT(h, invalid.pixel_format == 0U);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
@@ -94,5 +124,6 @@ int main()
|
||||
harness.run("detects_gles_texture_float_extensions", detects_gles_texture_float_extensions);
|
||||
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);
|
||||
return harness.finish();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user