---
include/GL/internal/dri_interface.h | 28 ++++++++++++++++++++++++++--
src/egl/drivers/dri2/platform_android.c | 18 ++++++++++++++++--
src/gallium/state_trackers/dri/dri_screen.c | 24 +++++++++++++++++++++++-
3 files changed, 65 insertions(+), 5 deletions(-)
diff --git a/include/GL/internal/dri_interface.h
b/include/GL/internal/dri_interface.h
index a8f5af1..c314a43 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -960,21 +960,29 @@ typedef unsigned int
struct __DRIbufferRec {
unsigned int attachment;
unsigned int name;
unsigned int pitch;
unsigned int cpp;
unsigned int flags;
};
#define __DRI_DRI2_LOADER "DRI_DRI2Loader"
-#define __DRI_DRI2_LOADER_VERSION 3
+#define __DRI_DRI2_LOADER_VERSION 4
+
+enum dri_loader_cap {
+ /* Whether the loader handles RGBA channel ordering correctly. If not,
+ * only BGRA ordering can be exposed.
+ */
+ DRI_LOADER_CAP_RGBA_ORDERING,
+};
+
struct __DRIdri2LoaderExtensionRec {
__DRIextension base;
__DRIbuffer *(*getBuffers)(__DRIdrawable *driDrawable,
int *width, int *height,
unsigned int *attachments, int count,
int *out_count, void *loaderPrivate);
/**
* Flush pending front-buffer rendering
@@ -1010,20 +1018,28 @@ struct __DRIdri2LoaderExtensionRec {
* \c attachments.
* \param loaderPrivate Loader's private data that was previously passed
* into __DRIdri2ExtensionRec::createNewDrawable.
*
* \since 3
*/
__DRIbuffer *(*getBuffersWithFormat)(__DRIdrawable *driDrawable,
int *width, int *height,
unsigned int *attachments, int count,
int *out_count, void *loaderPrivate);
+
+ /**
+ * Return a loader capability value. If the loader doesn't know the enum,
+ * it will return 0.
+ *
+ * \since 4
+ */
+ unsigned (*getCapability)(void *loaderPrivate, enum dri_loader_cap cap);
};
/**
* This extension provides alternative screen, drawable and context
* constructors for DRI2.
*/
#define __DRI_DRI2 "DRI_DRI2"
#define __DRI_DRI2_VERSION 4
#define __DRI_API_OPENGL 0 /**< OpenGL compatibility profile */
@@ -1704,21 +1720,21 @@ enum __DRIimageBufferMask {
__DRI_IMAGE_BUFFER_FRONT = (1 << 1)
};
struct __DRIimageList {
uint32_t image_mask;
__DRIimage *back;
__DRIimage *front;
};
#define __DRI_IMAGE_LOADER "DRI_IMAGE_LOADER"
-#define __DRI_IMAGE_LOADER_VERSION 1
+#define __DRI_IMAGE_LOADER_VERSION 2
struct __DRIimageLoaderExtensionRec {
__DRIextension base;
/**
* Allocate color buffers.
*
* \param driDrawable
* \param width Width of allocated buffers
* \param height Height of allocated buffers
@@ -1740,20 +1756,28 @@ struct __DRIimageLoaderExtensionRec {
* Flush pending front-buffer rendering
*
* Any rendering that has been performed to the
* fake front will be flushed to the front
*
* \param driDrawable Drawable whose front-buffer is to be flushed
* \param loaderPrivate Loader's private data that was previously passed
* into __DRIdri2ExtensionRec::createNewDrawable
*/
void (*flushFrontBuffer)(__DRIdrawable *driDrawable, void *loaderPrivate);
+
+ /**
+ * Return a loader capability value. If the loader doesn't know the enum,
+ * it will return 0.
+ *
+ * \since 2
+ */
+ unsigned (*getCapability)(void *loaderPrivate, enum dri_loader_cap cap);
};
/**
* DRI extension.
*/
#define __DRI_IMAGE_DRIVER "DRI_IMAGE_DRIVER"
#define __DRI_IMAGE_DRIVER_VERSION 1
struct __DRIimageDriverExtensionRec {
diff --git a/src/egl/drivers/dri2/platform_android.c
b/src/egl/drivers/dri2/platform_android.c
index 300e2d9..bae4241 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -1006,20 +1006,32 @@ droid_get_buffers_with_format(__DRIdrawable *
driDrawable,
*out_count = droid_get_buffers_parse_attachments(dri2_surf, attachments,
count);
if (width)
*width = dri2_surf->base.Width;
if (height)
*height = dri2_surf->base.Height;
return dri2_surf->buffers;
}
+static unsigned
+droid_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
+{
+ /* Note: loaderPrivate is _EGLDisplay* */
+ switch (cap) {
+ case DRI_LOADER_CAP_RGBA_ORDERING:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
static EGLBoolean
droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
static const struct {
int format;
unsigned int rgba_masks[4];
} visuals[] = {
{ HAL_PIXEL_FORMAT_RGBA_8888, { 0x000000ff, 0x0000ff00, 0x00ff0000,
0xff000000 } },
{ HAL_PIXEL_FORMAT_RGBX_8888, { 0x000000ff, 0x0000ff00, 0x00ff0000,
0x00000000 } },
@@ -1118,32 +1130,34 @@ static const struct dri2_egl_display_vtbl
droid_display_vtbl = {
.post_sub_buffer = dri2_fallback_post_sub_buffer,
.copy_buffers = dri2_fallback_copy_buffers,
.query_buffer_age = droid_query_buffer_age,
.query_surface = droid_query_surface,
.create_wayland_buffer_from_image =
dri2_fallback_create_wayland_buffer_from_image,
.get_sync_values = dri2_fallback_get_sync_values,
.get_dri_drawable = dri2_surface_get_dri_drawable,
};
static const __DRIdri2LoaderExtension droid_dri2_loader_extension = {
- .base = { __DRI_DRI2_LOADER, 3 },
+ .base = { __DRI_DRI2_LOADER, 4 },
.getBuffers = NULL,
.flushFrontBuffer = droid_flush_front_buffer,
.getBuffersWithFormat = droid_get_buffers_with_format,
+ .getCapability = droid_get_capability;
};
static const __DRIimageLoaderExtension droid_image_loader_extension = {
- .base = { __DRI_IMAGE_LOADER, 1 },
+ .base = { __DRI_IMAGE_LOADER, 2 },
.getBuffers = droid_image_get_buffers,
.flushFrontBuffer = droid_flush_front_buffer,
+ .getCapability = droid_get_capability,
};
static const __DRIextension *droid_dri2_loader_extensions[] = {
&droid_dri2_loader_extension.base,
&image_lookup_extension.base,
&use_invalidate.base,
NULL,
};
static const __DRIextension *droid_image_loader_extensions[] = {
diff --git a/src/gallium/state_trackers/dri/dri_screen.c
b/src/gallium/state_trackers/dri/dri_screen.c
index 59a850b..890a8bf 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -117,20 +117,35 @@ dri_fill_st_options(struct dri_screen *screen)
driQueryOptionb(optionCache,
"allow_glsl_builtin_variable_redeclaration");
options->allow_higher_compat_version =
driQueryOptionb(optionCache, "allow_higher_compat_version");
options->glsl_zero_init = driQueryOptionb(optionCache, "glsl_zero_init");
options->force_glsl_abs_sqrt =
driQueryOptionb(optionCache, "force_glsl_abs_sqrt");
driComputeOptionsSha1(optionCache, options->config_options_sha1);
}
+static unsigned
+dri_loader_get_cap(struct dri_screen *screen, enum dri_loader_cap cap)
+{
+ const __DRIdri2LoaderExtension *dri2_loader = screen->sPriv->dri2.loader;
+ const __DRIimageLoaderExtension *image_loader = screen->sPriv->image.loader;
+
+ if (dri2_loader && dri2_loader->base.version >= 4)
+ return dri2_loader->getCapability(screen->sPriv->loaderPrivate, cap);
+
+ if (image_loader && image_loader->base.version >= 2)
+ return image_loader->getCapability(screen->sPriv->loaderPrivate, cap);
+
+ return 0;
+}
+
static const __DRIconfig **
dri_fill_in_modes(struct dri_screen *screen)
{
static const mesa_format mesa_formats[] = {
MESA_FORMAT_B8G8R8A8_UNORM,
MESA_FORMAT_B8G8R8X8_UNORM,
MESA_FORMAT_B8G8R8A8_SRGB,
MESA_FORMAT_B8G8R8X8_SRGB,
MESA_FORMAT_B5G6R5_UNORM,
@@ -228,22 +243,29 @@ dri_fill_in_modes(struct dri_screen *screen)
if (pf_z32) {
depth_bits_array[depth_buffer_factor] = 32;
stencil_bits_array[depth_buffer_factor++] = 0;
}
mixed_color_depth =
p_screen->get_param(p_screen, PIPE_CAP_MIXED_COLOR_DEPTH_BITS);
assert(ARRAY_SIZE(mesa_formats) == ARRAY_SIZE(pipe_formats));
+ /* Expose only BGRA ordering if the loader doesn't support RGBA ordering. */
+ unsigned num_formats;
+ if (dri_loader_get_cap(screen, DRI_LOADER_CAP_RGBA_ORDERING))
+ num_formats = ARRAY_SIZE(mesa_formats);
+ else
+ num_formats = 5;
+
/* Add configs. */
- for (format = 0; format < ARRAY_SIZE(mesa_formats); format++) {
+ for (format = 0; format < num_formats; format++) {
__DRIconfig **new_configs = NULL;
unsigned num_msaa_modes = 0; /* includes a single-sample mode */
uint8_t msaa_modes[MSAA_VISUAL_MAX_SAMPLES];
if (!p_screen->is_format_supported(p_screen, pipe_formats[format],
PIPE_TEXTURE_2D, 0,
PIPE_BIND_RENDER_TARGET))
continue;
for (i = 1; i <= msaa_samples_max; i++) {