dri: add loader_dri_create_image helper

The DRI image extension already has two different ways to allocate an
image (with and without a modifier) and will soon grow a third one.
Add a helper, which handles calling the appropriate implementation to
get rid of code duplication in the winsys.

This convert the two obvious call sites (GBM dri and EGL wayland)
that profit from the code dedup.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8106>
This commit is contained in:
Lucas Stach 2020-12-15 14:39:32 +01:00 committed by Marge Bot
parent 7327b2b7b4
commit cb9ae4273d
6 changed files with 133 additions and 83 deletions

View File

@ -40,6 +40,7 @@
#include <sys/mman.h>
#include "egl_dri2.h"
#include "loader_dri_helper.h"
#include "loader.h"
#include "util/u_vector.h"
#include "util/anon_file.h"
@ -578,28 +579,16 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
dri2_surf->back->linear_copy == NULL) {
/* The LINEAR modifier should be a perfect alias of the LINEAR use
* flag; try the new interface first before the old, then fall back. */
if (dri2_dpy->image->base.version >= 15 &&
dri2_dpy->image->createImageWithModifiers) {
uint64_t linear_mod = DRM_FORMAT_MOD_LINEAR;
uint64_t linear_mod = DRM_FORMAT_MOD_LINEAR;
dri2_surf->back->linear_copy =
loader_dri_create_image(dri2_dpy->dri_screen, dri2_dpy->image,
dri2_surf->base.Width,
dri2_surf->base.Height,
linear_dri_image_format,
use_flags | __DRI_IMAGE_USE_LINEAR,
&linear_mod, 1, NULL);
dri2_surf->back->linear_copy =
dri2_dpy->image->createImageWithModifiers(dri2_dpy->dri_screen,
dri2_surf->base.Width,
dri2_surf->base.Height,
linear_dri_image_format,
&linear_mod,
1,
NULL);
} else {
dri2_surf->back->linear_copy =
dri2_dpy->image->createImage(dri2_dpy->dri_screen,
dri2_surf->base.Width,
dri2_surf->base.Height,
linear_dri_image_format,
use_flags |
__DRI_IMAGE_USE_LINEAR,
NULL);
}
if (dri2_surf->back->linear_copy == NULL)
return -1;
}
@ -609,26 +598,13 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
* createImageWithModifiers, then fall back to the old createImage,
* and hope it allocates an image which is acceptable to the winsys.
*/
if (num_modifiers && dri2_dpy->image->base.version >= 15 &&
dri2_dpy->image->createImageWithModifiers) {
dri2_surf->back->dri_image =
dri2_dpy->image->createImageWithModifiers(dri2_dpy->dri_screen,
dri2_surf->base.Width,
dri2_surf->base.Height,
dri_image_format,
modifiers,
num_modifiers,
NULL);
} else {
dri2_surf->back->dri_image =
dri2_dpy->image->createImage(dri2_dpy->dri_screen,
dri2_surf->base.Width,
dri2_surf->base.Height,
dri_image_format,
dri2_dpy->is_different_gpu ?
0 : use_flags,
NULL);
}
dri2_surf->back->dri_image =
loader_dri_create_image(dri2_dpy->dri_screen, dri2_dpy->image,
dri2_surf->base.Width,
dri2_surf->base.Height,
dri_image_format,
dri2_dpy->is_different_gpu ? 0 : use_flags,
modifiers, num_modifiers, NULL);
dri2_surf->back->age = 0;
}

View File

@ -47,6 +47,7 @@
#include "gbm_driint.h"
#include "gbmint.h"
#include "loader_dri_helper.h"
#include "loader.h"
#include "util/debug.h"
#include "util/macros.h"
@ -1151,8 +1152,7 @@ gbm_dri_bo_create(struct gbm_device *gbm,
struct gbm_dri_device *dri = gbm_dri_device(gbm);
struct gbm_dri_bo *bo;
int dri_format;
unsigned dri_use = 0, i;
bool has_valid_modifier;
unsigned dri_use = 0;
/* Callers of this may specify a modifier, or a dri usage, but not both. The
* newer modifier interface deprecates the older usage flags.
@ -1191,50 +1191,21 @@ gbm_dri_bo_create(struct gbm_device *gbm,
/* Gallium drivers requires shared in order to get the handle/stride */
dri_use |= __DRI_IMAGE_USE_SHARE;
if (modifiers) {
if (!dri->image || dri->image->base.version < 14 ||
!dri->image->createImageWithModifiers) {
errno = ENOSYS;
goto failed;
}
/* It's acceptable to create an image with INVALID modifier in the list,
* but it cannot be on the only modifier (since it will certainly fail
* later). While we could easily catch this after modifier creation, doing
* the check here is a convenient debug check likely pointing at whatever
* interface the client is using to build its modifier list.
*/
has_valid_modifier = false;
for (i = 0; i < count; i++) {
if (modifiers[i] != DRM_FORMAT_MOD_INVALID) {
has_valid_modifier = true;
break;
}
}
if (!has_valid_modifier) {
errno = EINVAL;
goto failed;
}
bo->image =
dri->image->createImageWithModifiers(dri->screen,
width, height,
dri_format,
modifiers, count,
bo);
if (bo->image) {
/* The client passed in a list of invalid modifiers */
assert(gbm_dri_bo_get_modifier(&bo->base) != DRM_FORMAT_MOD_INVALID);
}
} else {
bo->image = dri->image->createImage(dri->screen, width, height,
dri_format, dri_use, bo);
if (modifiers && (dri->image->base.version < 14 ||
!dri->image->createImageWithModifiers)) {
errno = ENOSYS;
return NULL;
}
bo->image = loader_dri_create_image(dri->screen, dri->image, width, height,
dri_format, dri_use, modifiers, count,
bo);
if (bo->image == NULL)
goto failed;
if (modifiers)
assert(gbm_dri_bo_get_modifier(&bo->base) != DRM_FORMAT_MOD_INVALID);
dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE,
&bo->base.handle.s32);
dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE,

View File

@ -1,4 +1,6 @@
LOADER_C_FILES := \
loader_dri_helper.c \
loader_dri_helper.h \
loader.c \
loader.h \
pci_id_driver_map.c \

View File

@ -0,0 +1,68 @@
/*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <sys/types.h>
#include <GL/gl.h> /* dri_interface needs GL types */
#include <GL/internal/dri_interface.h>
#include "drm-uapi/drm_fourcc.h"
#include "loader_dri_helper.h"
__DRIimage *loader_dri_create_image(__DRIscreen *screen,
const __DRIimageExtension *image,
uint32_t width, uint32_t height,
uint32_t dri_format, uint32_t dri_usage,
const uint64_t *modifiers,
unsigned int modifiers_count,
void *loaderPrivate)
{
if (modifiers &&
image->base.version > 14 && image->createImageWithModifiers) {
bool has_valid_modifier = false;
int i;
/* It's acceptable to create an image with INVALID modifier in the list,
* but it cannot be on the only modifier (since it will certainly fail
* later). While we could easily catch this after modifier creation, doing
* the check here is a convenient debug check likely pointing at whatever
* interface the client is using to build its modifier list.
*/
for (i = 0; i < modifiers_count; i++) {
if (modifiers[i] != DRM_FORMAT_MOD_INVALID) {
has_valid_modifier = true;
break;
}
}
if (!has_valid_modifier)
return NULL;
return image->createImageWithModifiers(screen, width, height,
dri_format, modifiers,
modifiers_count, loaderPrivate);
}
/* No modifier given or fallback to the legacy createImage allowed */
return image->createImage(screen, width, height, dri_format, dri_usage,
loaderPrivate);
}

View File

@ -0,0 +1,33 @@
/*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include <stdbool.h>
#include <sys/types.h>
#include <GL/gl.h> /* dri_interface needs GL types */
#include <GL/internal/dri_interface.h>
__DRIimage *loader_dri_create_image(__DRIscreen *screen,
const __DRIimageExtension *image,
uint32_t width, uint32_t height,
uint32_t dri_format, uint32_t dri_usage,
const uint64_t *modifiers,
unsigned int modifiers_count,
void *loaderPrivate);

View File

@ -47,7 +47,7 @@ endif
libloader = static_library(
'loader',
['loader.c', 'pci_id_driver_map.c'],
['loader_dri_helper.c', 'loader.c', 'pci_id_driver_map.c'],
c_args : loader_c_args,
gnu_symbol_visibility : 'hidden',
include_directories : [inc_include, inc_src, inc_util],