Support 16-bit floating point textures
Add R16G16B16_FLOAT and R16B16B16A16_FLOAT_PREMULTIPLIED formats, which are using half floats. The intention is to use these for HDR content. Not done here: Update memory texture tests to include floating point textures.
This commit is contained in:
@@ -292,6 +292,20 @@ gdk_gl_context_upload_texture (GdkGLContext *context,
|
||||
gl_type = GL_UNSIGNED_SHORT;
|
||||
bpp = 8;
|
||||
}
|
||||
else if (data_format == GDK_MEMORY_R16G16B16_FLOAT)
|
||||
{
|
||||
gl_internalformat = GL_RGB16F;
|
||||
gl_format = GL_RGB;
|
||||
gl_type = GL_HALF_FLOAT;
|
||||
bpp = 6;
|
||||
}
|
||||
else if (data_format == GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED)
|
||||
{
|
||||
gl_internalformat = GL_RGBA16F;
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_HALF_FLOAT;
|
||||
bpp = 8;
|
||||
}
|
||||
else /* Fall-back, convert to cairo-surface-format */
|
||||
{
|
||||
copy = g_malloc (width * height * 4);
|
||||
|
||||
@@ -120,6 +120,9 @@ type_from_internal_format (int internal_format)
|
||||
case GL_RGB16:
|
||||
case GL_RGBA16:
|
||||
return GL_UNSIGNED_SHORT;
|
||||
case GL_RGB16F:
|
||||
case GL_RGBA16F:
|
||||
return GL_HALF_FLOAT;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
@@ -134,6 +137,10 @@ internal_format_for_format (GdkMemoryFormat format)
|
||||
return GL_RGB16;
|
||||
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
|
||||
return GL_RGBA16;
|
||||
case GDK_MEMORY_R16G16B16_FLOAT:
|
||||
return GL_RGB16F;
|
||||
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
|
||||
return GL_RGB16F;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gsk/ngl/fp16private.h"
|
||||
|
||||
/**
|
||||
* GdkMemoryTexture:
|
||||
@@ -66,8 +67,12 @@ gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
|
||||
return 6;
|
||||
|
||||
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
|
||||
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
|
||||
return 8;
|
||||
|
||||
case GDK_MEMORY_R16G16B16_FLOAT:
|
||||
return 6;
|
||||
|
||||
case GDK_MEMORY_N_FORMATS:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
@@ -364,6 +369,74 @@ SWIZZLE_16TO8(0,1,2,3)
|
||||
SWIZZLE_16TO8(2,1,0,3)
|
||||
SWIZZLE_16TO8(1,2,3,0)
|
||||
|
||||
#define SWIZZLE_FP16_OPAQUE(A,R,G,B) \
|
||||
static void \
|
||||
convert_fp16_swizzle_opaque_ ## A ## R ## G ## B (guchar *dest_data, \
|
||||
gsize dest_stride, \
|
||||
const guchar *src_data, \
|
||||
gsize src_stride, \
|
||||
gsize width, \
|
||||
gsize height) \
|
||||
{ \
|
||||
gsize x, y; \
|
||||
float *c; \
|
||||
\
|
||||
c = g_malloc (width * sizeof (float)); \
|
||||
for (y = 0; y < height; y++) \
|
||||
{ \
|
||||
guint16 *src = (guint16 *)src_data; \
|
||||
half_to_float (src, c, width); \
|
||||
for (x = 0; x < width; x++) \
|
||||
{ \
|
||||
dest_data[4 * x + A] = 255; \
|
||||
dest_data[4 * x + R] = (guchar)(255 * c[3 * x + 0]); \
|
||||
dest_data[4 * x + G] = (guchar)(255 * c[3 * x + 1]); \
|
||||
dest_data[4 * x + B] = (guchar)(255 * c[3 * x + 2]); \
|
||||
} \
|
||||
dest_data += dest_stride; \
|
||||
src_data += src_stride; \
|
||||
} \
|
||||
g_free (c); \
|
||||
}
|
||||
|
||||
SWIZZLE_FP16_OPAQUE(3,2,1,0)
|
||||
SWIZZLE_FP16_OPAQUE(0,1,2,3)
|
||||
SWIZZLE_FP16_OPAQUE(3,0,1,2)
|
||||
|
||||
#define SWIZZLE_FP16(A,R,G,B) \
|
||||
static void \
|
||||
convert_fp16_swizzle_ ## A ## R ## G ## B (guchar *dest_data, \
|
||||
gsize dest_stride, \
|
||||
const guchar *src_data, \
|
||||
gsize src_stride, \
|
||||
gsize width, \
|
||||
gsize height) \
|
||||
{ \
|
||||
gsize x, y; \
|
||||
float *c; \
|
||||
\
|
||||
c = g_malloc (width * sizeof (float)); \
|
||||
for (y = 0; y < height; y++) \
|
||||
{ \
|
||||
guint16 *src = (guint16 *)src_data; \
|
||||
half_to_float (src, c, width); \
|
||||
for (x = 0; x < width; x++) \
|
||||
{ \
|
||||
dest_data[4 * x + A] = (guchar)(255 * c[4 * x + 0]); \
|
||||
dest_data[4 * x + R] = (guchar)(255 * c[4 * x + 1]); \
|
||||
dest_data[4 * x + G] = (guchar)(255 * c[4 * x + 2]); \
|
||||
dest_data[4 * x + B] = (guchar)(255 * c[4 * x + 3]); \
|
||||
} \
|
||||
dest_data += dest_stride; \
|
||||
src_data += src_stride; \
|
||||
} \
|
||||
g_free (c); \
|
||||
}
|
||||
|
||||
SWIZZLE_FP16(3,2,1,0)
|
||||
SWIZZLE_FP16(0,1,2,3)
|
||||
SWIZZLE_FP16(3,0,1,2)
|
||||
|
||||
typedef void (* ConversionFunc) (guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
const guchar *src_data,
|
||||
@@ -383,7 +456,9 @@ static ConversionFunc converters[GDK_MEMORY_N_FORMATS][3] =
|
||||
{ convert_swizzle_opaque_3210, convert_swizzle_opaque_0123, convert_swizzle_opaque_3012 },
|
||||
{ convert_swizzle_opaque_3012, convert_swizzle_opaque_0321, convert_swizzle_opaque_3210 },
|
||||
{ convert_16to8_swizzle_opaque_2103, convert_16to8_swizzle_opaque_1230, convert_16to8_swizzle_opaque_0123 },
|
||||
{ convert_16to8_swizzle_2103, convert_16to8_swizzle_1230, convert_16to8_swizzle_0123 }
|
||||
{ convert_16to8_swizzle_2103, convert_16to8_swizzle_1230, convert_16to8_swizzle_0123 },
|
||||
{ convert_fp16_swizzle_opaque_3210, convert_fp16_swizzle_opaque_0123, convert_fp16_swizzle_opaque_3012 },
|
||||
{ convert_fp16_swizzle_3210, convert_fp16_swizzle_0123, convert_fp16_swizzle_3012 }
|
||||
};
|
||||
|
||||
void
|
||||
|
||||
@@ -46,6 +46,11 @@ G_BEGIN_DECLS
|
||||
* @GDK_MEMORY_R16G16B16A16_PREMULTIPLIED: 4 guint16 values; for red, green,
|
||||
* blue, alpha. The color values are premultiplied with the alpha value.
|
||||
* Since 4.6
|
||||
* @GDK_MEMORY_R16G16B16_FLOAT: 3 half-float values; for red, green, blue.
|
||||
* The data is opaque. Since 4.6
|
||||
* @GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED: 4 half-float values; for
|
||||
* red, green, blue and alpha. The color values are premultiplied with
|
||||
* the alpha value. Since 4.6
|
||||
* @GDK_MEMORY_N_FORMATS: The number of formats. This value will change as
|
||||
* more formats get added, so do not rely on its concrete integer.
|
||||
*
|
||||
@@ -75,6 +80,8 @@ typedef enum {
|
||||
GDK_MEMORY_B8G8R8,
|
||||
GDK_MEMORY_R16G16B16,
|
||||
GDK_MEMORY_R16G16B16A16_PREMULTIPLIED,
|
||||
GDK_MEMORY_R16G16B16_FLOAT,
|
||||
GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED,
|
||||
|
||||
GDK_MEMORY_N_FORMATS
|
||||
} GdkMemoryFormat;
|
||||
|
||||
@@ -189,6 +189,10 @@ main (int argc, char *argv[])
|
||||
|
||||
for (format = 0; format < GDK_MEMORY_N_FORMATS; format++)
|
||||
{
|
||||
if (format == GDK_MEMORY_R16G16B16_FLOAT ||
|
||||
format == GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED)
|
||||
continue;
|
||||
|
||||
for (color = 0; color < N_COLORS; color++)
|
||||
{
|
||||
TestData *test_data = g_new (TestData, 1);
|
||||
|
||||
Reference in New Issue
Block a user