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 <[email protected]> --- 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 _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
