Browse Source

DebugTools: expand textureSubImage() tests for half-float types.

Interesting, the shader reinterpret code was added in 2016 but nothing
mentions *why* it was needed, what driver actually needs that. In 2025
all drivers I tested with are happy just with a passthrough.

Which means, this reinterpret is still only ever done in a single
overload of these APIs, reading to a buffer or reading a cube map
doesn't have this code path.
pull/674/head
Vladimír Vondruš 1 year ago
parent
commit
2964c8d7b5
  1. 47
      src/Magnum/DebugTools/Test/TextureImageGLTest.cpp
  2. 25
      src/Magnum/DebugTools/TextureImage.cpp
  3. 12
      src/Magnum/DebugTools/TextureImage.h

47
src/Magnum/DebugTools/Test/TextureImageGLTest.cpp

@ -38,6 +38,7 @@
#include "Magnum/GL/PixelFormat.h"
#include "Magnum/GL/Texture.h"
#include "Magnum/GL/TextureFormat.h"
#include "Magnum/Math/Half.h"
#include "Magnum/Math/Range.h"
#ifndef MAGNUM_TARGET_GLES2
@ -73,6 +74,8 @@ struct TextureImageGLTest: GL::OpenGLTester {
void subImage2DUInt();
void subImage2DFloat();
void subImage2DFloatGeneric();
void subImage2DHalf();
void subImage2DHalfGeneric();
#endif
};
@ -96,10 +99,14 @@ TextureImageGLTest::TextureImageGLTest() {
&TextureImageGLTest::subImage2DUInt,
&TextureImageGLTest::subImage2DFloat,
&TextureImageGLTest::subImage2DFloatGeneric,
&TextureImageGLTest::subImage2DHalf,
&TextureImageGLTest::subImage2DHalfGeneric,
#endif
});
}
using namespace Math::Literals;
constexpr UnsignedByte Data2D[] = { 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
@ -422,6 +429,46 @@ void TextureImageGLTest::subImage2DFloatGeneric() {
Containers::arrayView(Data2DFloat),
TestSuite::Compare::Container);
}
const Half Data2DHalf[] = { 1.0_h,
3.14159_h,
2.71828_h,
1.41421_h };
void TextureImageGLTest::subImage2DHalf() {
GL::Texture2D texture;
texture
.setStorage(1, GL::TextureFormat::R16F, Vector2i{2})
.setSubImage(0, {}, ImageView2D{GL::PixelFormat::Red, GL::PixelType::Half, Vector2i{2}, Data2DHalf});
Image2D image = textureSubImage(texture, 0, {{}, Vector2i{2}}, {GL::PixelFormat::Red, GL::PixelType::Half});
MAGNUM_VERIFY_NO_GL_ERROR();
CORRADE_COMPARE(image.size(), Vector2i{2});
CORRADE_COMPARE(image.format(), pixelFormatWrap(GL::PixelFormat::Red));
CORRADE_COMPARE(GL::PixelType(image.formatExtra()), GL::PixelType::Half);
CORRADE_COMPARE(image.pixelSize(), 2);
CORRADE_COMPARE_AS(Containers::arrayCast<Half>(image.data()),
Containers::arrayView(Data2DHalf),
TestSuite::Compare::Container);
}
void TextureImageGLTest::subImage2DHalfGeneric() {
GL::Texture2D texture;
texture
.setStorage(1, GL::TextureFormat::R16F, Vector2i{2})
.setSubImage(0, {}, ImageView2D{GL::PixelFormat::Red, GL::PixelType::Half, Vector2i{2}, Data2DHalf});
Image2D image = textureSubImage(texture, 0, {{}, Vector2i{2}}, {PixelFormat::R16F});
MAGNUM_VERIFY_NO_GL_ERROR();
CORRADE_COMPARE(image.size(), Vector2i{2});
CORRADE_COMPARE(image.format(), PixelFormat::R16F);
CORRADE_COMPARE(image.formatExtra(), 0);
CORRADE_COMPARE(image.pixelSize(), 2);
CORRADE_COMPARE_AS(Containers::arrayCast<Half>(image.data()),
Containers::arrayView(Data2DHalf),
TestSuite::Compare::Container);
}
#endif
}}}}

25
src/Magnum/DebugTools/TextureImage.cpp

@ -115,9 +115,27 @@ void textureSubImage(GL::Texture2D& texture, const Int level, const Range2Di& ra
}
#endif
/* While I cannot reproduce this on any drivers I tried, not even on WebGL,
the ES3.0 and 3.1 spec says that Float isn't guaranteed to be supported,
only UnsignedByte and Int or UnsignedInt. I could probably do some
comparison against fb.implementationColorReadFormat() but this is more
straightforward.
ES3.2 says Float is supported. What still isn't guaranteed to be
supported are one-, two- and three-component formats, but so far I
didn't have a problem with these anywhere.
Half floats aren't guaranteed to be supported either, but given that I
cannot reproduce this issue anywhere anymore, I don't think I should
waste time implementing a half-float variant. */
/** @todo or just remove this altogether? */
#if defined(MAGNUM_TARGET_GLES) && !defined(MAGNUM_TARGET_GLES2)
GL::PixelType type = GL::pixelType(image.format(), image.formatExtra());
if(type == GL::PixelType::Float) {
if(type == GL::PixelType::Float
#ifndef MAGNUM_TARGET_WEBGL
&& !GL::Context::current().isVersionSupported(GL::Version::GLES320)
#endif
) {
GL::TextureFormat textureFormat;
GL::PixelFormat reinterpretFormat;
GL::PixelFormat format = GL::pixelFormat(image.format());
@ -224,6 +242,11 @@ void textureSubImage(GL::CubeMapTexture& texture, const GL::CubeMapCoordinate co
GL::Framebuffer fb{range};
fb.attachCubeMapTexture(GL::Framebuffer::ColorAttachment{0}, texture, coordinate, level);
/* Compared to textureSubImage(GL::Texture2D&), here's no specialized code
path for float formats, as it's impossible to sample it in a shader with
2D coordinates. It's also questionable if that's still needed. */
/** @todo or just remove this altogether? */
CORRADE_ASSERT(fb.checkStatus(GL::FramebufferTarget::Read) == GL::Framebuffer::Status::Complete,
"DebugTools::textureSubImage(): texture format not framebuffer-readable:" << fb.checkStatus(GL::FramebufferTarget::Read), );

12
src/Magnum/DebugTools/TextureImage.h

@ -50,11 +50,13 @@ is available, it's just an alias to @ref GL::Texture2D::subImage().
The function expects that @p texture has a @ref GL::TextureFormat that's
framebuffer-readable and that the @ref GL::PixelFormat and @ref GL::PixelType
combination or the generic @relativeref{Magnum,PixelFormat} is compatible with
it. In addition, on OpenGL ES 3.0, images with @ref GL::PixelType::Float
are supported --- they are reinterpreted as @ref GL::PixelType::UnsignedInt
using an additional shader and the @glsl floatBitsToUint() @ce GLSL function
and then reinterpreted back to @ref GL::PixelType::Float when read to client
memory.
it. On OpenGL ES 3.0 and 3.1, @ref GL::PixelType::Float isn't guaranteed to be
supported for reading so such images are reinterpreted as
@ref GL::PixelType::UnsignedInt using an additional shader and the
@glsl floatBitsToUint() @ce GLSL function and then reinterpreted back to
@ref GL::PixelType::Float when read to client memory. On OpenGL ES 3.2 and on
desktop GL, @ref GL::PixelType::Float is guaranteed to be supported. No similar
treatment is done for any other types.
@note This function is available only if Magnum is compiled with
@ref MAGNUM_TARGET_GL "TARGET_GL" enabled (done by default). See

Loading…
Cancel
Save