diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index 26b6711952c..180380b4c4c 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -40,6 +40,7 @@ #include #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; } diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c index 751b2e56497..dff0b3c7ecf 100644 --- a/src/gbm/backends/dri/gbm_dri.c +++ b/src/gbm/backends/dri/gbm_dri.c @@ -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, diff --git a/src/loader/Makefile.sources b/src/loader/Makefile.sources index b61ef1cd943..6627222ac30 100644 --- a/src/loader/Makefile.sources +++ b/src/loader/Makefile.sources @@ -1,4 +1,6 @@ LOADER_C_FILES := \ + loader_dri_helper.c \ + loader_dri_helper.h \ loader.c \ loader.h \ pci_id_driver_map.c \ diff --git a/src/loader/loader_dri_helper.c b/src/loader/loader_dri_helper.c new file mode 100644 index 00000000000..21419f087d6 --- /dev/null +++ b/src/loader/loader_dri_helper.c @@ -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 +#include +#include +#include + +#include /* dri_interface needs GL types */ +#include + +#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); +} diff --git a/src/loader/loader_dri_helper.h b/src/loader/loader_dri_helper.h new file mode 100644 index 00000000000..e0aae69477b --- /dev/null +++ b/src/loader/loader_dri_helper.h @@ -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 +#include + +#include /* dri_interface needs GL types */ +#include + +__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); diff --git a/src/loader/meson.build b/src/loader/meson.build index 34a43e33f09..57a93c3aa17 100644 --- a/src/loader/meson.build +++ b/src/loader/meson.build @@ -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],