[Mesa-dev] [RFC 4/6] dri: Enable fp16 configs and visuals
Kevin Strasser
kevin.strasser at intel.com
Fri Jan 4 21:56:30 UTC 2019
Add dri image formats for RGBA ordered 64 bpp IEEE 754 half precision
floating point.
Introduce a new dri configuration option so users can diable exposure of
fp16 formats, following the same design and policy of rgb10a2 (opt-in
for i965 and opt-out for gallium).
Add a loader cap field so loaders can indicate if they know how to
handle fp16 formats.
Add visuals to gallium and i965, leverage existing offscreen render
support for MESA_FORMAT_RGBA_FLOAT16 and MESA_FORMAT_RGBX_FLOAT16.
Signed-off-by: Kevin Strasser <kevin.strasser at intel.com>
---
include/GL/internal/dri_interface.h | 5 +++
src/egl/drivers/dri2/egl_dri2.c | 2 ++
.../auxiliary/pipe-loader/driinfo_gallium.h | 1 +
src/gallium/state_trackers/dri/dri2.c | 22 ++++++++++++
src/gallium/state_trackers/dri/dri_drawable.c | 3 ++
src/gallium/state_trackers/dri/dri_screen.c | 26 ++++++++++++++-
src/loader/loader_dri3_helper.c | 5 +++
src/mesa/drivers/dri/common/dri_util.c | 8 +++++
src/mesa/drivers/dri/common/utils.c | 10 ++++++
src/mesa/drivers/dri/i965/intel_screen.c | 39 ++++++++++++++++++++--
src/mesa/state_tracker/st_cb_fbo.c | 3 ++
src/util/xmlpool/t_options.h | 5 +++
12 files changed, 125 insertions(+), 4 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index c5761c4..76ebfae 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1038,6 +1038,7 @@ enum dri_loader_cap {
* only BGRA ordering can be exposed.
*/
DRI_LOADER_CAP_RGBA_ORDERING,
+ DRI_LOADER_CAP_FP16,
};
struct __DRIdri2LoaderExtensionRec {
@@ -1277,6 +1278,8 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_FORMAT_XBGR2101010 0x1010
#define __DRI_IMAGE_FORMAT_ABGR2101010 0x1011
#define __DRI_IMAGE_FORMAT_SABGR8 0x1012
+#define __DRI_IMAGE_FORMAT_XBGR16161616F 0x1013
+#define __DRI_IMAGE_FORMAT_ABGR16161616F 0x1014
#define __DRI_IMAGE_USE_SHARE 0x0001
#define __DRI_IMAGE_USE_SCANOUT 0x0002
@@ -1322,6 +1325,8 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_FOURCC_RGBX1010102 0x30335852
#define __DRI_IMAGE_FOURCC_BGRA1010102 0x30334142
#define __DRI_IMAGE_FOURCC_BGRX1010102 0x30335842
+#define __DRI_IMAGE_FOURCC_ABGR16161616F 0x48344241
+#define __DRI_IMAGE_FOURCC_XBGR16161616F 0x48344258
#define __DRI_IMAGE_FOURCC_YUV410 0x39565559
#define __DRI_IMAGE_FOURCC_YUV411 0x31315559
#define __DRI_IMAGE_FOURCC_YUV420 0x32315559
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index fb8f1b7..6b44767 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -2233,6 +2233,8 @@ dri2_num_fourcc_format_planes(EGLint format)
case DRM_FORMAT_ABGR2101010:
case DRM_FORMAT_RGBA1010102:
case DRM_FORMAT_BGRA1010102:
+ case DRM_FORMAT_XBGR16161616F:
+ case DRM_FORMAT_ABGR16161616F:
case DRM_FORMAT_YUYV:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_UYVY:
diff --git a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
index 9db0dc0..76637e5 100644
--- a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
+++ b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
@@ -37,4 +37,5 @@ DRI_CONF_SECTION_MISCELLANEOUS
DRI_CONF_ALWAYS_HAVE_DEPTH_BUFFER("false")
DRI_CONF_GLSL_ZERO_INIT("false")
DRI_CONF_ALLOW_RGB10_CONFIGS("true")
+ DRI_CONF_ALLOW_FP16_CONFIGS("true")
DRI_CONF_SECTION_END
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
index 6fc07e4..c7f429a 100644
--- a/src/gallium/state_trackers/dri/dri2.c
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -74,6 +74,10 @@ struct dri2_format_mapping {
};
static const struct dri2_format_mapping dri2_format_table[] = {
+ { __DRI_IMAGE_FOURCC_ABGR16161616F, __DRI_IMAGE_FORMAT_ABGR16161616F,
+ __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_R16G16B16A16_FLOAT },
+ { __DRI_IMAGE_FOURCC_XBGR16161616F, __DRI_IMAGE_FORMAT_XBGR16161616F,
+ __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_R16G16B16X16_FLOAT },
{ __DRI_IMAGE_FOURCC_ARGB2101010, __DRI_IMAGE_FORMAT_ARGB2101010,
__DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_B10G10R10A2_UNORM },
{ __DRI_IMAGE_FOURCC_XRGB2101010, __DRI_IMAGE_FORMAT_XRGB2101010,
@@ -222,6 +226,12 @@ dri2_drawable_get_buffers(struct dri_drawable *drawable,
* may occur as the stvis->color_format.
*/
switch(format) {
+ case PIPE_FORMAT_R16G16B16A16_FLOAT:
+ depth = 64;
+ break;
+ case PIPE_FORMAT_R16G16B16X16_FLOAT:
+ depth = 48;
+ break;
case PIPE_FORMAT_B10G10R10A2_UNORM:
case PIPE_FORMAT_R10G10B10A2_UNORM:
case PIPE_FORMAT_BGRA8888_UNORM:
@@ -300,6 +310,12 @@ dri_image_drawable_get_buffers(struct dri_drawable *drawable,
}
switch (pf) {
+ case PIPE_FORMAT_R16G16B16A16_FLOAT:
+ image_format = __DRI_IMAGE_FORMAT_ABGR16161616F;
+ break;
+ case PIPE_FORMAT_R16G16B16X16_FLOAT:
+ image_format = __DRI_IMAGE_FORMAT_XBGR16161616F;
+ break;
case PIPE_FORMAT_B5G5R5A1_UNORM:
image_format = __DRI_IMAGE_FORMAT_ARGB1555;
break;
@@ -373,6 +389,12 @@ dri2_allocate_buffer(__DRIscreen *sPriv,
bind |= PIPE_BIND_SHARED;
switch (format) {
+ case 64:
+ pf = PIPE_FORMAT_R16G16B16A16_FLOAT;
+ break;
+ case 48:
+ pf = PIPE_FORMAT_R16G16B16X16_FLOAT;
+ break;
case 32:
pf = PIPE_FORMAT_BGRA8888_UNORM;
break;
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index e5a7537..9584367 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -260,6 +260,9 @@ dri_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
if (format == __DRI_TEXTURE_FORMAT_RGB) {
/* only need to cover the formats recognized by dri_fill_st_visual */
switch (internal_format) {
+ case PIPE_FORMAT_R16G16B16A16_FLOAT:
+ internal_format = PIPE_FORMAT_R16G16B16X16_FLOAT;
+ break;
case PIPE_FORMAT_B10G10R10A2_UNORM:
internal_format = PIPE_FORMAT_B10G10R10X2_UNORM;
break;
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index 82a0988..c434098 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -142,6 +142,10 @@ dri_fill_in_modes(struct dri_screen *screen)
/* Required by Android, for HAL_PIXEL_FORMAT_RGBX_8888. */
MESA_FORMAT_R8G8B8X8_UNORM,
+
+ /* Required by Android, for HAL_PIXEL_FORMAT_RGBA_FP16. */
+ MESA_FORMAT_RGBA_FLOAT16,
+ MESA_FORMAT_RGBX_FLOAT16,
};
static const enum pipe_format pipe_formats[] = {
PIPE_FORMAT_B10G10R10A2_UNORM,
@@ -155,6 +159,8 @@ dri_fill_in_modes(struct dri_screen *screen)
PIPE_FORMAT_B5G6R5_UNORM,
PIPE_FORMAT_RGBA8888_UNORM,
PIPE_FORMAT_RGBX8888_UNORM,
+ PIPE_FORMAT_R16G16B16A16_FLOAT,
+ PIPE_FORMAT_R16G16B16X16_FLOAT,
};
mesa_format format;
__DRIconfig **configs = NULL;
@@ -167,6 +173,7 @@ dri_fill_in_modes(struct dri_screen *screen)
boolean pf_z16, pf_x8z24, pf_z24x8, pf_s8z24, pf_z24s8, pf_z32;
boolean mixed_color_depth;
boolean allow_rgb10;
+ boolean allow_fp16;
static const GLenum back_buffer_modes[] = {
__DRI_ATTRIB_SWAP_NONE, __DRI_ATTRIB_SWAP_UNDEFINED,
@@ -184,6 +191,8 @@ dri_fill_in_modes(struct dri_screen *screen)
}
allow_rgb10 = driQueryOptionb(&screen->dev->option_cache, "allow_rgb10_configs");
+ allow_fp16 = driQueryOptionb(&screen->dev->option_cache, "allow_fp16_configs");
+ allow_fp16 &= dri_loader_get_cap(screen, DRI_LOADER_CAP_FP16);
msaa_samples_max = (screen->st_api->feature_mask & ST_API_FEATURE_MS_VISUALS_MASK)
? MSAA_VISUAL_MAX_SAMPLES : 1;
@@ -236,7 +245,7 @@ dri_fill_in_modes(struct dri_screen *screen)
if (dri_loader_get_cap(screen, DRI_LOADER_CAP_RGBA_ORDERING))
num_formats = ARRAY_SIZE(mesa_formats);
else
- num_formats = ARRAY_SIZE(mesa_formats) - 2; /* all - RGBA_ORDERING formats */
+ num_formats = ARRAY_SIZE(mesa_formats) - 4; /* all - RGBA_ORDERING formats */
/* Add configs. */
for (format = 0; format < num_formats; format++) {
@@ -251,6 +260,11 @@ dri_fill_in_modes(struct dri_screen *screen)
mesa_formats[format] == MESA_FORMAT_R10G10B10X2_UNORM))
continue;
+ if (!allow_fp16 &&
+ (mesa_formats[format] == MESA_FORMAT_RGBA_FLOAT16 ||
+ mesa_formats[format] == MESA_FORMAT_RGBX_FLOAT16))
+ continue;
+
if (!p_screen->is_format_supported(p_screen, pipe_formats[format],
PIPE_TEXTURE_2D, 0, 0,
PIPE_BIND_RENDER_TARGET |
@@ -315,6 +329,16 @@ dri_fill_st_visual(struct st_visual *stvis,
/* Deduce the color format. */
switch (mode->redMask) {
+ case 0x000000000000ffff:
+ assert(mode->floatMode);
+ if (mode->alphaMask) {
+ assert(mode->alphaMask == 0xffff000000000000);
+ stvis->color_format = PIPE_FORMAT_R16G16B16A16_FLOAT;
+ } else {
+ stvis->color_format = PIPE_FORMAT_R16G16B16X16_FLOAT;
+ }
+ break;
+
case 0x3FF00000:
if (mode->alphaMask) {
assert(mode->alphaMask == 0xC0000000);
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 5c48da9..78cc4b5 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -1120,6 +1120,9 @@ dri3_cpp_for_format(uint32_t format) {
case __DRI_IMAGE_FORMAT_SARGB8:
case __DRI_IMAGE_FORMAT_SABGR8:
return 4;
+ case __DRI_IMAGE_FORMAT_XBGR16161616F:
+ case __DRI_IMAGE_FORMAT_ABGR16161616F:
+ return 8;
case __DRI_IMAGE_FORMAT_NONE:
default:
return 0;
@@ -1178,6 +1181,8 @@ image_format_to_fourcc(int format)
case __DRI_IMAGE_FORMAT_ARGB2101010: return __DRI_IMAGE_FOURCC_ARGB2101010;
case __DRI_IMAGE_FORMAT_XBGR2101010: return __DRI_IMAGE_FOURCC_XBGR2101010;
case __DRI_IMAGE_FORMAT_ABGR2101010: return __DRI_IMAGE_FOURCC_ABGR2101010;
+ case __DRI_IMAGE_FORMAT_XBGR16161616F: return __DRI_IMAGE_FOURCC_XBGR16161616F;
+ case __DRI_IMAGE_FORMAT_ABGR16161616F: return __DRI_IMAGE_FOURCC_ABGR16161616F;
}
return 0;
}
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index ac3a04b..a384cad 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -887,6 +887,14 @@ static const struct {
.mesa_format = MESA_FORMAT_B8G8R8X8_UNORM,
},
{
+ .image_format = __DRI_IMAGE_FORMAT_ABGR16161616F,
+ .mesa_format = MESA_FORMAT_RGBA_FLOAT16,
+ },
+ {
+ .image_format = __DRI_IMAGE_FORMAT_XBGR16161616F,
+ .mesa_format = MESA_FORMAT_RGBX_FLOAT16,
+ },
+ {
.image_format = __DRI_IMAGE_FORMAT_ARGB2101010,
.mesa_format = MESA_FORMAT_B10G10R10A2_UNORM,
},
diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c
index b52c59f..1cf9362 100644
--- a/src/mesa/drivers/dri/common/utils.c
+++ b/src/mesa/drivers/dri/common/utils.c
@@ -200,6 +200,10 @@ driCreateConfigs(mesa_format format,
{ 0x000003FF, 0x000FFC00, 0x3FF00000, 0x00000000 },
/* MESA_FORMAT_R10G10B10A2_UNORM */
{ 0x000003FF, 0x000FFC00, 0x3FF00000, 0xC0000000 },
+ /* MESA_FORMAT_RGBX_FLOAT16 */
+ { 0x000000000000ffff, 0x00000000ffff0000, 0x0000ffff00000000, 0x0000000000000000},
+ /* MESA_FORMAT_RGBA_FLOAT16 */
+ { 0x000000000000ffff, 0x00000000ffff0000, 0x0000ffff00000000, 0xffff000000000000},
};
const uint64_t * masks;
@@ -240,6 +244,12 @@ driCreateConfigs(mesa_format format,
case MESA_FORMAT_B10G10R10A2_UNORM:
masks = masks_table[4];
break;
+ case MESA_FORMAT_RGBA_FLOAT16:
+ masks = masks_table[9];
+ break;
+ case MESA_FORMAT_RGBX_FLOAT16:
+ masks = masks_table[10];
+ break;
case MESA_FORMAT_R10G10B10X2_UNORM:
masks = masks_table[7];
break;
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index 8838f97..948f118 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -96,6 +96,7 @@ DRI_CONF_BEGIN
DRI_CONF_SECTION_MISCELLANEOUS
DRI_CONF_GLSL_ZERO_INIT("false")
DRI_CONF_ALLOW_RGB10_CONFIGS("false")
+ DRI_CONF_ALLOW_FP16_CONFIGS("false")
DRI_CONF_SECTION_END
DRI_CONF_END
};
@@ -183,6 +184,12 @@ static const struct __DRI2flushExtensionRec intelFlushExtension = {
};
static const struct intel_image_format intel_image_formats[] = {
+ { __DRI_IMAGE_FOURCC_ABGR16161616F, __DRI_IMAGE_COMPONENTS_RGBA, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR16161616F, 8 } } },
+
+ { __DRI_IMAGE_FOURCC_XBGR16161616F, __DRI_IMAGE_COMPONENTS_RGB, 1,
+ { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR16161616F, 8 } } },
+
{ __DRI_IMAGE_FOURCC_ARGB2101010, __DRI_IMAGE_COMPONENTS_RGBA, 1,
{ { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB2101010, 4 } } },
@@ -1712,7 +1719,11 @@ intelCreateBuffer(__DRIscreen *dri_screen,
fb->Visual.samples = num_samples;
}
- if (mesaVis->redBits == 10 && mesaVis->alphaBits > 0) {
+ if (mesaVis->redBits == 16 && mesaVis->alphaBits > 0 && mesaVis->floatMode) {
+ rgbFormat = MESA_FORMAT_RGBA_FLOAT16;
+ } else if (mesaVis->redBits == 16 && mesaVis->floatMode) {
+ rgbFormat = MESA_FORMAT_RGBX_FLOAT16;
+ } else if (mesaVis->redBits == 10 && mesaVis->alphaBits > 0) {
rgbFormat = mesaVis->redMask == 0x3ff00000 ? MESA_FORMAT_B10G10R10A2_UNORM
: MESA_FORMAT_R10G10B10A2_UNORM;
} else if (mesaVis->redBits == 10) {
@@ -2148,6 +2159,10 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
MESA_FORMAT_R8G8B8X8_UNORM,
MESA_FORMAT_R8G8B8A8_SRGB,
+
+ /* Required by Android, for HAL_PIXEL_FORMAT_RGBA_FP16. */
+ MESA_FORMAT_RGBA_FLOAT16,
+ MESA_FORMAT_RGBX_FLOAT16,
};
/* __DRI_ATTRIB_SWAP_COPY is not supported due to page flipping. */
@@ -2167,11 +2182,14 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
if (intel_loader_get_cap(dri_screen, DRI_LOADER_CAP_RGBA_ORDERING))
num_formats = ARRAY_SIZE(formats);
else
- num_formats = ARRAY_SIZE(formats) - 3; /* all - RGBA_ORDERING formats */
+ num_formats = ARRAY_SIZE(formats) - 5; /* all - RGBA_ORDERING formats */
- /* Shall we expose 10 bpc formats? */
+ /* Shall we expose 10/16 bpc formats? */
bool allow_rgb10_configs = driQueryOptionb(&screen->optionCache,
"allow_rgb10_configs");
+ bool allow_fp16_configs = driQueryOptionb(&screen->optionCache,
+ "allow_fp16_configs");
+ allow_fp16_configs &= intel_loader_get_cap(dri_screen, DRI_LOADER_CAP_FP16);
/* Generate singlesample configs, each without accumulation buffer
* and with EGL_MUTABLE_RENDER_BUFFER_BIT_KHR.
@@ -2185,6 +2203,11 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
formats[i] == MESA_FORMAT_B10G10R10X2_UNORM))
continue;
+ if (!allow_fp16_configs &&
+ (formats[i] == MESA_FORMAT_RGBA_FLOAT16 ||
+ formats[i] == MESA_FORMAT_RGBX_FLOAT16))
+ continue;
+
/* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
* buffer that has a different number of bits per pixel than the color
* buffer, gen >= 6 supports this.
@@ -2227,6 +2250,11 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
formats[i] == MESA_FORMAT_B10G10R10X2_UNORM))
continue;
+ if (!allow_fp16_configs &&
+ (formats[i] == MESA_FORMAT_RGBA_FLOAT16 ||
+ formats[i] == MESA_FORMAT_RGBX_FLOAT16))
+ continue;
+
if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) {
depth_bits[0] = 16;
stencil_bits[0] = 0;
@@ -2265,6 +2293,11 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
formats[i] == MESA_FORMAT_B10G10R10X2_UNORM))
continue;
+ if (!allow_fp16_configs &&
+ (formats[i] == MESA_FORMAT_RGBA_FLOAT16 ||
+ formats[i] == MESA_FORMAT_RGBX_FLOAT16))
+ continue;
+
__DRIconfig **new_configs;
const int num_depth_stencil_bits = 2;
int num_msaa_modes = 0;
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 8901a86..2545df0 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -414,6 +414,9 @@ st_new_renderbuffer_fb(enum pipe_format format, unsigned samples, boolean sw)
case PIPE_FORMAT_R16G16B16A16_FLOAT:
strb->Base.InternalFormat = GL_RGBA16F;
break;
+ case PIPE_FORMAT_R16G16B16X16_FLOAT:
+ strb->Base.InternalFormat = GL_RGB16F;
+ break;
default:
_mesa_problem(NULL,
"Unexpected format %s in st_new_renderbuffer_fb",
diff --git a/src/util/xmlpool/t_options.h b/src/util/xmlpool/t_options.h
index 80ddf0e..9d502ff 100644
--- a/src/util/xmlpool/t_options.h
+++ b/src/util/xmlpool/t_options.h
@@ -264,6 +264,11 @@ DRI_CONF_OPT_BEGIN_B(allow_rgb10_configs, def) \
DRI_CONF_DESC(en,gettext("Allow exposure of visuals and fbconfigs with rgb10a2 formats")) \
DRI_CONF_OPT_END
+#define DRI_CONF_ALLOW_FP16_CONFIGS(def) \
+DRI_CONF_OPT_BEGIN_B(allow_fp16_configs, def) \
+DRI_CONF_DESC(en,gettext("Allow exposure of visuals and fbconfigs with fp16 formats")) \
+DRI_CONF_OPT_END
+
/**
* \brief Initialization configuration options
*/
--
2.7.4
More information about the mesa-dev
mailing list