From d133f94f8f711cef436e6f4cf5bd4d0bbbe81f22 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 17 Jun 2020 18:42:53 -0400 Subject: [PATCH 01/13] cogl: Introduce and use cogl_context_is_hardware_accelerated We delegate the answer through CoglDriverVtable::is_hardware_accelerated since this is properly a property of the renderer, and not something the cogl core should know about. The answer given for the nop driver is admittedly arbitrary, yes it's infinitely fast but no there's not any "hardware" making it so. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194 --- cogl/cogl/cogl-context.c | 6 +++++ cogl/cogl/cogl-context.h | 10 +++++++++ cogl/cogl/cogl-driver.h | 3 +++ cogl/cogl/driver/gl/cogl-util-gl-private.h | 3 +++ cogl/cogl/driver/gl/cogl-util-gl.c | 25 +++++++++++++++++++++ cogl/cogl/driver/gl/gl/cogl-driver-gl.c | 1 + cogl/cogl/driver/gl/gles/cogl-driver-gles.c | 1 + cogl/cogl/driver/nop/cogl-driver-nop.c | 7 ++++++ src/backends/meta-renderer.c | 17 +------------- 9 files changed, 57 insertions(+), 16 deletions(-) diff --git a/cogl/cogl/cogl-context.c b/cogl/cogl/cogl-context.c index 50b4b68aed6..bc92ec38e88 100644 --- a/cogl/cogl/cogl-context.c +++ b/cogl/cogl/cogl-context.c @@ -593,3 +593,9 @@ cogl_get_graphics_reset_status (CoglContext *context) return COGL_GRAPHICS_RESET_STATUS_NO_ERROR; } } + +gboolean +cogl_context_is_hardware_accelerated (CoglContext *context) +{ + return context->driver_vtable->is_hardware_accelerated (context); +} diff --git a/cogl/cogl/cogl-context.h b/cogl/cogl/cogl-context.h index 2807f2a5ac3..e0d79d92780 100644 --- a/cogl/cogl/cogl-context.h +++ b/cogl/cogl/cogl-context.h @@ -357,6 +357,16 @@ typedef enum _CoglGraphicsResetStatus COGL_EXPORT CoglGraphicsResetStatus cogl_get_graphics_reset_status (CoglContext *context); +/** + * cogl_context_is_hardware_accelerated: + * @context: a #CoglContext pointer + * + * Returns: %TRUE if the @context is hardware accelerated, or %FALSE if + * not. + */ +COGL_EXPORT gboolean +cogl_context_is_hardware_accelerated (CoglContext *context); + G_END_DECLS #endif /* __COGL_CONTEXT_H__ */ diff --git a/cogl/cogl/cogl-driver.h b/cogl/cogl/cogl-driver.h index 5dcecf86298..e52a99cfb89 100644 --- a/cogl/cogl/cogl-driver.h +++ b/cogl/cogl/cogl-driver.h @@ -46,6 +46,9 @@ struct _CoglDriverVtable void (* context_deinit) (CoglContext *context); + gboolean + (* is_hardware_accelerated) (CoglContext *context); + /* TODO: factor this out since this is OpenGL specific and * so can be ignored by non-OpenGL drivers. */ gboolean diff --git a/cogl/cogl/driver/gl/cogl-util-gl-private.h b/cogl/cogl/driver/gl/cogl-util-gl-private.h index 52279be678e..c434ebde014 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-util-gl-private.h @@ -91,6 +91,9 @@ _cogl_gl_util_clear_gl_errors (CoglContext *ctx); gboolean _cogl_gl_util_catch_out_of_memory (CoglContext *ctx, GError **error); +gboolean +_cogl_driver_gl_is_hardware_accelerated (CoglContext *context); + /* Parses a GL version number stored in a string. @version_string must * point to the beginning of the version number (ie, it can't point to * the "OpenGL ES" part on GLES). The version number can be followed diff --git a/cogl/cogl/driver/gl/cogl-util-gl.c b/cogl/cogl/driver/gl/cogl-util-gl.c index 34488c7d8fd..d21ee01248c 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl.c +++ b/cogl/cogl/driver/gl/cogl-util-gl.c @@ -179,3 +179,28 @@ _cogl_gl_util_parse_gl_version (const char *version_string, return TRUE; } + +/* + * This should arguably use something like GLX_MESA_query_renderer, but + * a) that's GLX-only, and you could add it to EGL too but + * b) that'd make this a winsys query when really it's not a property of + * the winsys but the renderer, and + * c) only Mesa really supports it anyway, and + * d) Mesa is the only software renderer of interest. + * + * So instead just check a list of known software renderer strings. + */ +gboolean +_cogl_driver_gl_is_hardware_accelerated (CoglContext *ctx) +{ + const char *renderer = (const char *) ctx->glGetString (GL_RENDERER); + gboolean software; + + software = strstr (renderer, "llvmpipe") != NULL || + strstr (renderer, "softpipe") != NULL || + strstr (renderer, "software rasterizer") != NULL || + strstr (renderer, "Software Rasterizer") != NULL || + strstr (renderer, "SWR"); + + return !software; +} diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c index 220c581e991..29492b04c79 100644 --- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c @@ -532,6 +532,7 @@ _cogl_driver_gl = { _cogl_driver_gl_real_context_init, _cogl_driver_gl_context_deinit, + _cogl_driver_gl_is_hardware_accelerated, _cogl_driver_pixel_format_from_gl_internal, _cogl_driver_pixel_format_to_gl, _cogl_driver_update_features, diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c index daaaec44f06..04e35c56add 100644 --- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c @@ -396,6 +396,7 @@ _cogl_driver_gles = { _cogl_driver_gl_context_init, _cogl_driver_gl_context_deinit, + _cogl_driver_gl_is_hardware_accelerated, _cogl_driver_pixel_format_from_gl_internal, _cogl_driver_pixel_format_to_gl, _cogl_driver_update_features, diff --git a/cogl/cogl/driver/nop/cogl-driver-nop.c b/cogl/cogl/driver/nop/cogl-driver-nop.c index 3594a966b21..664c653dbcf 100644 --- a/cogl/cogl/driver/nop/cogl-driver-nop.c +++ b/cogl/cogl/driver/nop/cogl-driver-nop.c @@ -63,11 +63,18 @@ _cogl_driver_nop_context_deinit (CoglContext *context) { } +static gboolean +_cogl_driver_nop_is_hardware_accelerated (CoglContext *context) +{ + return FALSE; +} + const CoglDriverVtable _cogl_driver_nop = { _cogl_driver_nop_context_init, _cogl_driver_nop_context_deinit, + _cogl_driver_nop_is_hardware_accelerated, NULL, /* pixel_format_from_gl_internal */ NULL, /* pixel_format_to_gl */ _cogl_driver_update_features, diff --git a/src/backends/meta-renderer.c b/src/backends/meta-renderer.c index 983a570e1c8..b5cc37efbfc 100644 --- a/src/backends/meta-renderer.c +++ b/src/backends/meta-renderer.c @@ -194,23 +194,8 @@ meta_renderer_is_hardware_accelerated (MetaRenderer *renderer) ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); - CoglGpuInfo *info = &cogl_context->gpu; - switch (info->architecture) - { - case COGL_GPU_INFO_ARCHITECTURE_UNKNOWN: - case COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE: - case COGL_GPU_INFO_ARCHITECTURE_SGX: - case COGL_GPU_INFO_ARCHITECTURE_MALI: - return TRUE; - case COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE: - case COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE: - case COGL_GPU_INFO_ARCHITECTURE_SWRAST: - return FALSE; - } - - g_assert_not_reached (); - return FALSE; + return cogl_context_is_hardware_accelerated (cogl_context); } static void -- GitLab From d6f5ac56038d86c13e90df1571f52e0da8e16d4b Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 17 Jun 2020 18:53:19 -0400 Subject: [PATCH 02/13] cogl: Remove now-unused CoglGpuInfo This had been an entirely-too-GL-aware collection of renderer queries, mostly to work around driver bugs and handle software drivers intelligently. The driver workarounds have been removed (fix your driver, and if you can't because it's closed-source, fix that first), and we now delegate the am-i-software-or-not logic to the backend, so this can all go https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194 --- cogl/cogl/cogl-context-private.h | 5 - cogl/cogl/cogl-context.c | 1 - cogl/cogl/cogl-gpu-info-private.h | 112 ---- cogl/cogl/cogl-gpu-info.c | 572 -------------------- cogl/cogl/driver/gl/gl/cogl-driver-gl.c | 2 - cogl/cogl/driver/gl/gles/cogl-driver-gles.c | 2 - cogl/cogl/driver/nop/cogl-driver-nop.c | 2 - cogl/cogl/meson.build | 2 - 8 files changed, 698 deletions(-) delete mode 100644 cogl/cogl/cogl-gpu-info-private.h delete mode 100644 cogl/cogl/cogl-gpu-info.c diff --git a/cogl/cogl/cogl-context-private.h b/cogl/cogl/cogl-context-private.h index 8dc5c2c23b5..4151f3bf7f8 100644 --- a/cogl/cogl/cogl-context-private.h +++ b/cogl/cogl/cogl-context-private.h @@ -46,7 +46,6 @@ #include "cogl-pipeline-cache.h" #include "cogl-texture-2d.h" #include "cogl-sampler-cache-private.h" -#include "cogl-gpu-info-private.h" #include "cogl-gl-header.h" #include "cogl-framebuffer-private.h" #include "cogl-onscreen-private.h" @@ -70,10 +69,6 @@ struct _CoglContext CoglDriver driver; - /* Information about the GPU and driver which we can use to - determine certain workarounds */ - CoglGpuInfo gpu; - /* vtables for the driver functions */ const CoglDriverVtable *driver_vtable; const CoglTextureDriver *texture_driver; diff --git a/cogl/cogl/cogl-context.c b/cogl/cogl/cogl-context.c index bc92ec38e88..1d84cf544f6 100644 --- a/cogl/cogl/cogl-context.c +++ b/cogl/cogl/cogl-context.c @@ -45,7 +45,6 @@ #include "cogl-onscreen-private.h" #include "cogl-attribute-private.h" #include "cogl1-context.h" -#include "cogl-gpu-info-private.h" #include "cogl-gtype-private.h" #include "winsys/cogl-winsys-private.h" diff --git a/cogl/cogl/cogl-gpu-info-private.h b/cogl/cogl/cogl-gpu-info-private.h deleted file mode 100644 index 7ab4950f8ac..00000000000 --- a/cogl/cogl/cogl-gpu-info-private.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_GPU_INFO_PRIVATE_H -#define __COGL_GPU_INFO_PRIVATE_H - -#include "cogl-context.h" - -typedef enum _CoglGpuInfoArchitectureFlag -{ - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE, - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED, - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_SOFTWARE, - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE, - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_DEFERRED, - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_SOFTWARE -} CoglGpuInfoArchitectureFlag; - -typedef enum _CoglGpuInfoArchitecture -{ - COGL_GPU_INFO_ARCHITECTURE_UNKNOWN, - COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE, - COGL_GPU_INFO_ARCHITECTURE_SGX, - COGL_GPU_INFO_ARCHITECTURE_MALI, - COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE, - COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE, - COGL_GPU_INFO_ARCHITECTURE_SWRAST -} CoglGpuInfoArchitecture; - -typedef enum -{ - COGL_GPU_INFO_VENDOR_UNKNOWN, - COGL_GPU_INFO_VENDOR_INTEL, - COGL_GPU_INFO_VENDOR_IMAGINATION_TECHNOLOGIES, - COGL_GPU_INFO_VENDOR_ARM, - COGL_GPU_INFO_VENDOR_QUALCOMM, - COGL_GPU_INFO_VENDOR_NVIDIA, - COGL_GPU_INFO_VENDOR_ATI, - COGL_GPU_INFO_VENDOR_MESA -} CoglGpuInfoVendor; - -typedef enum -{ - COGL_GPU_INFO_DRIVER_PACKAGE_UNKNOWN, - COGL_GPU_INFO_DRIVER_PACKAGE_MESA -} CoglGpuInfoDriverPackage; - -typedef enum -{ - COGL_GPU_INFO_DRIVER_STUB -} CoglGpuInfoDriverBug; - -typedef struct _CoglGpuInfoVersion CoglGpuInfoVersion; - -typedef struct _CoglGpuInfo CoglGpuInfo; - -struct _CoglGpuInfo -{ - CoglGpuInfoVendor vendor; - const char *vendor_name; - - CoglGpuInfoDriverPackage driver_package; - const char *driver_package_name; - int driver_package_version; - - CoglGpuInfoArchitecture architecture; - const char *architecture_name; - CoglGpuInfoArchitectureFlag architecture_flags; - - CoglGpuInfoDriverBug driver_bugs; -}; - -/* - * _cogl_gpu_info_init: - * @ctx: A #CoglContext - * @gpu: A return location for the GPU information - * - * Determines information about the GPU and driver from the given - * context. - */ -void -_cogl_gpu_info_init (CoglContext *ctx, - CoglGpuInfo *gpu); - -#endif /* __COGL_GPU_INFO_PRIVATE_H */ diff --git a/cogl/cogl/cogl-gpu-info.c b/cogl/cogl/cogl-gpu-info.c deleted file mode 100644 index f44319e96e8..00000000000 --- a/cogl/cogl/cogl-gpu-info.c +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include -#include - -#include - -#include "cogl-gpu-info-private.h" -#include "cogl-context-private.h" -#include "cogl-version.h" - -typedef struct -{ - const char *renderer_string; - const char *version_string; - const char *vendor_string; -} CoglGpuInfoStrings; - -typedef struct CoglGpuInfoArchitectureDescription -{ - CoglGpuInfoArchitecture architecture; - const char *name; - CoglGpuInfoArchitectureFlag flags; - gboolean (* check_function) (const CoglGpuInfoStrings *strings); - -} CoglGpuInfoArchitectureDescription; - -typedef struct -{ - CoglGpuInfoVendor vendor; - const char *name; - gboolean (* check_function) (const CoglGpuInfoStrings *strings); - const CoglGpuInfoArchitectureDescription *architectures; - -} CoglGpuInfoVendorDescription; - -typedef struct -{ - CoglGpuInfoDriverPackage driver_package; - const char *name; - gboolean (* check_function) (const CoglGpuInfoStrings *strings, - int *version_out); -} CoglGpuInfoDriverPackageDescription; - -static gboolean -_cogl_gpu_info_parse_version_string (const char *version_string, - int n_components, - const char **tail, - int *version_ret) -{ - int version = 0; - uint64_t part; - int i; - - for (i = 0; ; i++) - { - errno = 0; - part = g_ascii_strtoull (version_string, - (char **) &version_string, - 10); - - if (errno || part > COGL_VERSION_MAX_COMPONENT_VALUE) - return FALSE; - - version |= part << ((2 - i) * COGL_VERSION_COMPONENT_BITS); - - if (i + 1 >= n_components) - break; - - if (*version_string != '.') - return FALSE; - - version_string++; - } - - if (version_ret) - *version_ret = version; - if (tail) - *tail = version_string; - - return TRUE; -} - -static gboolean -match_phrase (const char *string, const char *phrase) -{ - const char *part = strstr (string, phrase); - int len; - - if (part == NULL) - return FALSE; - - /* The match must either be at the beginning of the string or - preceded by a space. */ - if (part > string && part[-1] != ' ') - return FALSE; - - /* Also match must either be at end of string or followed by a - * space. */ - len = strlen (phrase); - if (part[len] != '\0' && part[len] != ' ') - return FALSE; - - return TRUE; -} - -static gboolean -check_intel_vendor (const CoglGpuInfoStrings *strings) -{ - return match_phrase (strings->renderer_string, "Intel(R)"); -} - -static gboolean -check_imagination_technologies_vendor (const CoglGpuInfoStrings *strings) -{ - if (strcmp (strings->vendor_string, "Imagination Technologies") != 0) - return FALSE; - return TRUE; -} - -static gboolean -check_arm_vendor (const CoglGpuInfoStrings *strings) -{ - if (strcmp (strings->vendor_string, "ARM") != 0) - return FALSE; - return TRUE; -} - -static gboolean -check_qualcomm_vendor (const CoglGpuInfoStrings *strings) -{ - if (strcmp (strings->vendor_string, "Qualcomm") != 0) - return FALSE; - return TRUE; -} - -static gboolean -check_nvidia_vendor (const CoglGpuInfoStrings *strings) -{ - if (strcmp (strings->vendor_string, "NVIDIA") != 0 && - strcmp (strings->vendor_string, "NVIDIA Corporation") != 0) - return FALSE; - - return TRUE; -} - -static gboolean -check_ati_vendor (const CoglGpuInfoStrings *strings) -{ - if (strcmp (strings->vendor_string, "ATI") != 0) - return FALSE; - - return TRUE; -} - -static gboolean -check_mesa_vendor (const CoglGpuInfoStrings *strings) -{ - if (strcmp (strings->vendor_string, "Tungsten Graphics, Inc") == 0) - return TRUE; - else if (strcmp (strings->vendor_string, "VMware, Inc.") == 0) - return TRUE; - else if (strcmp (strings->vendor_string, "Mesa Project") == 0) - return TRUE; - - return FALSE; -} - -static gboolean -check_true (const CoglGpuInfoStrings *strings) -{ - /* This is a last resort so it always matches */ - return TRUE; -} - -static gboolean -check_sandybridge_architecture (const CoglGpuInfoStrings *strings) -{ - return match_phrase (strings->renderer_string, "Sandybridge"); -} - -static gboolean -check_llvmpipe_architecture (const CoglGpuInfoStrings *strings) -{ - return match_phrase (strings->renderer_string, "llvmpipe"); -} - -static gboolean -check_softpipe_architecture (const CoglGpuInfoStrings *strings) -{ - return match_phrase (strings->renderer_string, "softpipe"); -} - -static gboolean -check_swrast_architecture (const CoglGpuInfoStrings *strings) -{ - return match_phrase (strings->renderer_string, "software rasterizer") || - match_phrase (strings->renderer_string, "Software Rasterizer"); -} - -static gboolean -check_sgx_architecture (const CoglGpuInfoStrings *strings) -{ - if (strncmp (strings->renderer_string, "PowerVR SGX", 12) != 0) - return FALSE; - - return TRUE; -} - -static gboolean -check_mali_architecture (const CoglGpuInfoStrings *strings) -{ - if (strncmp (strings->renderer_string, "Mali-", 5) != 0) - return FALSE; - - return TRUE; -} - -static const CoglGpuInfoArchitectureDescription -intel_architectures[] = - { - { - COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE, - "Sandybridge", - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE | - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE, - check_sandybridge_architecture - }, - { - COGL_GPU_INFO_ARCHITECTURE_UNKNOWN, - "Unknown", - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE | - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE, - check_true - } - }; - -static const CoglGpuInfoArchitectureDescription -powervr_architectures[] = - { - { - COGL_GPU_INFO_ARCHITECTURE_SGX, - "SGX", - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED | - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_DEFERRED, - check_sgx_architecture - }, - { - COGL_GPU_INFO_ARCHITECTURE_UNKNOWN, - "Unknown", - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED | - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED, - check_true - } - }; - -static const CoglGpuInfoArchitectureDescription -arm_architectures[] = - { - { - COGL_GPU_INFO_ARCHITECTURE_MALI, - "Mali", - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED | - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE, - check_mali_architecture - }, - { - COGL_GPU_INFO_ARCHITECTURE_UNKNOWN, - "Unknown", - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_TILED | - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE, - check_true - } - }; - -static const CoglGpuInfoArchitectureDescription -mesa_architectures[] = - { - { - COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE, - "LLVM Pipe", - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE | - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_SOFTWARE | - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE | - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_SOFTWARE, - check_llvmpipe_architecture - }, - { - COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE, - "Softpipe", - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE | - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_SOFTWARE | - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE | - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_SOFTWARE, - check_softpipe_architecture - }, - { - COGL_GPU_INFO_ARCHITECTURE_SWRAST, - "SWRast", - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE | - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_SOFTWARE | - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE | - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_SOFTWARE, - check_swrast_architecture - }, - { - COGL_GPU_INFO_ARCHITECTURE_UNKNOWN, - "Unknown", - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE | - COGL_GPU_INFO_ARCHITECTURE_FLAG_FRAGMENT_IMMEDIATE_MODE, - check_true - } - }; - -static const CoglGpuInfoArchitectureDescription -unknown_architectures[] = - { - { - COGL_GPU_INFO_ARCHITECTURE_UNKNOWN, - "Unknown", - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE | - COGL_GPU_INFO_ARCHITECTURE_FLAG_VERTEX_IMMEDIATE_MODE, - check_true - } - }; - -static const CoglGpuInfoVendorDescription -_cogl_gpu_info_vendors[] = - { - { - COGL_GPU_INFO_VENDOR_INTEL, - "Intel", - check_intel_vendor, - intel_architectures - }, - { - COGL_GPU_INFO_VENDOR_IMAGINATION_TECHNOLOGIES, - "Imagination Technologies", - check_imagination_technologies_vendor, - powervr_architectures - }, - { - COGL_GPU_INFO_VENDOR_ARM, - "ARM", - check_arm_vendor, - arm_architectures - }, - { - COGL_GPU_INFO_VENDOR_QUALCOMM, - "Qualcomm", - check_qualcomm_vendor, - unknown_architectures - }, - { - COGL_GPU_INFO_VENDOR_NVIDIA, - "Nvidia", - check_nvidia_vendor, - unknown_architectures - }, - { - COGL_GPU_INFO_VENDOR_ATI, - "ATI", - check_ati_vendor, - unknown_architectures - }, - /* Must be last */ - { - COGL_GPU_INFO_VENDOR_MESA, - "Mesa", - check_mesa_vendor, - mesa_architectures - }, - { - COGL_GPU_INFO_VENDOR_UNKNOWN, - "Unknown", - check_true, - unknown_architectures - } - }; - -static gboolean -check_mesa_driver_package (const CoglGpuInfoStrings *strings, - int *version_ret) -{ - uint64_t micro_part; - const char *v; - - /* The version string should always begin a two-part GL version - number */ - if (!_cogl_gpu_info_parse_version_string (strings->version_string, - 2, /* n_components */ - &v, /* tail */ - NULL /* version_ret */)) - return FALSE; - - /* In mesa this will be followed optionally by "(Core Profile)" and - * then "Mesa" */ - v = strstr (v, " Mesa "); - if (!v) - return FALSE; - - v += 6; - - /* Next there will be a version string that is at least two - components. On a git devel build the version will be something - like "-devel" instead */ - if (!_cogl_gpu_info_parse_version_string (v, - 2, /* n_components */ - &v, /* tail */ - version_ret)) - return FALSE; - - /* If it is a development build then we'll just leave the micro - number as 0 */ - if (g_str_has_prefix (v, "-devel")) - return TRUE; - - /* Otherwise there should be a micro version number */ - if (*v != '.') - return FALSE; - - errno = 0; - micro_part = g_ascii_strtoull (v + 1, NULL /* endptr */, 10 /* base */); - if (errno || micro_part > COGL_VERSION_MAX_COMPONENT_VALUE) - return FALSE; - - *version_ret = COGL_VERSION_ENCODE (COGL_VERSION_GET_MAJOR (*version_ret), - COGL_VERSION_GET_MINOR (*version_ret), - micro_part); - - return TRUE; -} - -UNIT_TEST (check_mesa_driver_package_parser, - 0, /* no requirements */ - 0 /* no failure cases */) -{ - /* renderer_string, version_string, vendor_string;*/ - const CoglGpuInfoStrings test_strings[2] = { - { NULL, "3.1 Mesa 9.2-devel15436ad", NULL }, - { NULL, "3.1 (Core Profile) Mesa 9.2.0-devel (git-15436ad)", NULL } - }; - int i; - int version; - - for (i = 0; i < G_N_ELEMENTS (test_strings); i++) - { - g_assert (check_mesa_driver_package (&test_strings[i], &version)); - g_assert_cmpint (version, ==, COGL_VERSION_ENCODE (9, 2, 0)); - } -} - -static gboolean -check_unknown_driver_package (const CoglGpuInfoStrings *strings, - int *version_out) -{ - *version_out = 0; - - /* This is a last resort so it always matches */ - return TRUE; -} - -static const CoglGpuInfoDriverPackageDescription -_cogl_gpu_info_driver_packages[] = - { - { - COGL_GPU_INFO_DRIVER_PACKAGE_MESA, - "Mesa", - check_mesa_driver_package - }, - /* Must be last */ - { - COGL_GPU_INFO_DRIVER_PACKAGE_UNKNOWN, - "Unknown", - check_unknown_driver_package - } - }; - -void -_cogl_gpu_info_init (CoglContext *ctx, - CoglGpuInfo *gpu) -{ - CoglGpuInfoStrings strings; - int i; - - strings.renderer_string = (const char *) ctx->glGetString (GL_RENDERER); - strings.version_string = _cogl_context_get_gl_version (ctx); - strings.vendor_string = (const char *) ctx->glGetString (GL_VENDOR); - - /* Determine the driver package */ - for (i = 0; ; i++) - { - const CoglGpuInfoDriverPackageDescription *description = - _cogl_gpu_info_driver_packages + i; - - if (description->check_function (&strings, &gpu->driver_package_version)) - { - gpu->driver_package = description->driver_package; - gpu->driver_package_name = description->name; - break; - } - } - - /* Determine the GPU vendor */ - for (i = 0; ; i++) - { - const CoglGpuInfoVendorDescription *description = - _cogl_gpu_info_vendors + i; - - if (description->check_function (&strings)) - { - int j; - - gpu->vendor = description->vendor; - gpu->vendor_name = description->name; - - for (j = 0; ; j++) - { - const CoglGpuInfoArchitectureDescription *architecture = - description->architectures + j; - - if (architecture->check_function (&strings)) - { - gpu->architecture = architecture->architecture; - gpu->architecture_name = architecture->name; - gpu->architecture_flags = architecture->flags; - goto probed; - } - } - } - } - -probed: - - COGL_NOTE (WINSYS, "Driver package = %s, vendor = %s, architecture = %s\n", - gpu->driver_package_name, - gpu->vendor_name, - gpu->architecture_name); - - /* Determine the driver bugs */ - gpu->driver_bugs = 0; -} diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c index 29492b04c79..42351c4d808 100644 --- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c @@ -419,8 +419,6 @@ _cogl_driver_update_features (CoglContext *ctx, _cogl_get_gl_version (ctx, &gl_major, &gl_minor); - _cogl_gpu_info_init (ctx, &ctx->gpu); - ctx->glsl_major = 1; ctx->glsl_minor = 2; ctx->glsl_version_to_use = 120; diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c index 04e35c56add..d85d2f9f209 100644 --- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c @@ -282,8 +282,6 @@ _cogl_driver_update_features (CoglContext *context, context->glsl_minor = 0; context->glsl_version_to_use = 100; - _cogl_gpu_info_init (context, &context->gpu); - if (!_cogl_get_gl_version (context, &gl_major, &gl_minor)) { gl_major = 1; diff --git a/cogl/cogl/driver/nop/cogl-driver-nop.c b/cogl/cogl/driver/nop/cogl-driver-nop.c index 664c653dbcf..5edd93a22a1 100644 --- a/cogl/cogl/driver/nop/cogl-driver-nop.c +++ b/cogl/cogl/driver/nop/cogl-driver-nop.c @@ -45,8 +45,6 @@ static gboolean _cogl_driver_update_features (CoglContext *ctx, GError **error) { - /* _cogl_gpu_info_init (ctx, &ctx->gpu); */ - memset (ctx->private_features, 0, sizeof (ctx->private_features)); return TRUE; diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build index 21f6d8c0cf9..a4383dc3d08 100644 --- a/cogl/cogl/meson.build +++ b/cogl/cogl/meson.build @@ -208,8 +208,6 @@ cogl_sources = [ 'cogl-debug.h', 'cogl-debug-options.h', 'cogl-dma-buf-handle.c', - 'cogl-gpu-info.c', - 'cogl-gpu-info-private.h', 'cogl-context-private.h', 'cogl-context.c', 'cogl-renderer-private.h', -- GitLab From 1285619bcf18f3ad4502108e43abb842961146ab Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 28 Jan 2020 15:15:44 -0500 Subject: [PATCH 03/13] cogl: Move GL context/version details into the driver https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194 --- cogl/cogl/cogl-context-private.h | 14 ---- cogl/cogl/cogl-context.c | 92 ---------------------- cogl/cogl/driver/gl/cogl-util-gl-private.h | 14 ++++ cogl/cogl/driver/gl/cogl-util-gl.c | 88 +++++++++++++++++++++ 4 files changed, 102 insertions(+), 106 deletions(-) diff --git a/cogl/cogl/cogl-context-private.h b/cogl/cogl/cogl-context-private.h index 4151f3bf7f8..a2ed950d0cc 100644 --- a/cogl/cogl/cogl-context-private.h +++ b/cogl/cogl/cogl-context-private.h @@ -310,18 +310,4 @@ void _cogl_context_set_current_modelview_entry (CoglContext *context, CoglMatrixEntry *entry); -/* - * _cogl_context_get_gl_extensions: - * @context: A CoglContext - * - * Return value: a NULL-terminated array of strings representing the - * supported extensions by the current driver. This array is owned - * by the caller and should be freed with g_strfreev(). - */ -char ** -_cogl_context_get_gl_extensions (CoglContext *context); - -const char * -_cogl_context_get_gl_version (CoglContext *context); - #endif /* __COGL_CONTEXT_PRIVATE_H */ diff --git a/cogl/cogl/cogl-context.c b/cogl/cogl/cogl-context.c index 1d84cf544f6..908738f2955 100644 --- a/cogl/cogl/cogl-context.c +++ b/cogl/cogl/cogl-context.c @@ -56,10 +56,6 @@ #define GL_POINT_SPRITE 0x8861 #endif -#ifndef GL_NUM_EXTENSIONS -#define GL_NUM_EXTENSIONS 0x821D -#endif - /* This is a relatively new extension */ #ifndef GL_PURGED_CONTEXT_RESET_NV #define GL_PURGED_CONTEXT_RESET_NV 0x92BB @@ -469,94 +465,6 @@ _cogl_context_set_current_modelview_entry (CoglContext *context, context->current_modelview_entry = entry; } -char ** -_cogl_context_get_gl_extensions (CoglContext *context) -{ - const char *env_disabled_extensions; - char **ret; - - /* In GL 3, querying GL_EXTENSIONS is deprecated so we have to build - * the array using glGetStringi instead */ -#ifdef HAVE_COGL_GL - if (context->driver == COGL_DRIVER_GL3) - { - int num_extensions, i; - - context->glGetIntegerv (GL_NUM_EXTENSIONS, &num_extensions); - - ret = g_malloc (sizeof (char *) * (num_extensions + 1)); - - for (i = 0; i < num_extensions; i++) - { - const char *ext = - (const char *) context->glGetStringi (GL_EXTENSIONS, i); - ret[i] = g_strdup (ext); - } - - ret[num_extensions] = NULL; - } - else -#endif - { - const char *all_extensions = - (const char *) context->glGetString (GL_EXTENSIONS); - - ret = g_strsplit (all_extensions, " ", 0 /* max tokens */); - } - - if ((env_disabled_extensions = g_getenv ("COGL_DISABLE_GL_EXTENSIONS"))) - { - char **split_env_disabled_extensions; - char **src, **dst; - - if (env_disabled_extensions) - split_env_disabled_extensions = - g_strsplit (env_disabled_extensions, - ",", - 0 /* no max tokens */); - else - split_env_disabled_extensions = NULL; - - for (dst = ret, src = ret; - *src; - src++) - { - char **d; - - if (split_env_disabled_extensions) - for (d = split_env_disabled_extensions; *d; d++) - if (!strcmp (*src, *d)) - goto disabled; - - *(dst++) = *src; - continue; - - disabled: - g_free (*src); - continue; - } - - *dst = NULL; - - if (split_env_disabled_extensions) - g_strfreev (split_env_disabled_extensions); - } - - return ret; -} - -const char * -_cogl_context_get_gl_version (CoglContext *context) -{ - const char *version_override; - - if ((version_override = g_getenv ("COGL_OVERRIDE_GL_VERSION"))) - return version_override; - else - return (const char *) context->glGetString (GL_VERSION); - -} - int64_t cogl_get_clock_time (CoglContext *context) { diff --git a/cogl/cogl/driver/gl/cogl-util-gl-private.h b/cogl/cogl/driver/gl/cogl-util-gl-private.h index c434ebde014..369baab874c 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-util-gl-private.h @@ -94,6 +94,20 @@ _cogl_gl_util_catch_out_of_memory (CoglContext *ctx, GError **error); gboolean _cogl_driver_gl_is_hardware_accelerated (CoglContext *context); +/* + * _cogl_context_get_gl_extensions: + * @context: A CoglContext + * + * Return value: a NULL-terminated array of strings representing the + * supported extensions by the current driver. This array is owned + * by the caller and should be freed with g_strfreev(). + */ +char ** +_cogl_context_get_gl_extensions (CoglContext *context); + +const char * +_cogl_context_get_gl_version (CoglContext *context); + /* Parses a GL version number stored in a string. @version_string must * point to the beginning of the version number (ie, it can't point to * the "OpenGL ES" part on GLES). The version number can be followed diff --git a/cogl/cogl/driver/gl/cogl-util-gl.c b/cogl/cogl/driver/gl/cogl-util-gl.c index d21ee01248c..52ad54076f5 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl.c +++ b/cogl/cogl/driver/gl/cogl-util-gl.c @@ -147,6 +147,94 @@ _cogl_gl_util_catch_out_of_memory (CoglContext *ctx, GError **error) return FALSE; } +char ** +_cogl_context_get_gl_extensions (CoglContext *context) +{ + const char *env_disabled_extensions; + char **ret; + + /* In GL 3, querying GL_EXTENSIONS is deprecated so we have to build + * the array using glGetStringi instead */ +#ifdef HAVE_COGL_GL + if (context->driver == COGL_DRIVER_GL3) + { + int num_extensions, i; + + context->glGetIntegerv (GL_NUM_EXTENSIONS, &num_extensions); + + ret = g_malloc (sizeof (char *) * (num_extensions + 1)); + + for (i = 0; i < num_extensions; i++) + { + const char *ext = + (const char *) context->glGetStringi (GL_EXTENSIONS, i); + ret[i] = g_strdup (ext); + } + + ret[num_extensions] = NULL; + } + else +#endif + { + const char *all_extensions = + (const char *) context->glGetString (GL_EXTENSIONS); + + ret = g_strsplit (all_extensions, " ", 0 /* max tokens */); + } + + if ((env_disabled_extensions = g_getenv ("COGL_DISABLE_GL_EXTENSIONS"))) + { + char **split_env_disabled_extensions; + char **src, **dst; + + if (env_disabled_extensions) + split_env_disabled_extensions = + g_strsplit (env_disabled_extensions, + ",", + 0 /* no max tokens */); + else + split_env_disabled_extensions = NULL; + + for (dst = ret, src = ret; + *src; + src++) + { + char **d; + + if (split_env_disabled_extensions) + for (d = split_env_disabled_extensions; *d; d++) + if (!strcmp (*src, *d)) + goto disabled; + + *(dst++) = *src; + continue; + + disabled: + g_free (*src); + continue; + } + + *dst = NULL; + + if (split_env_disabled_extensions) + g_strfreev (split_env_disabled_extensions); + } + + return ret; +} + +const char * +_cogl_context_get_gl_version (CoglContext *context) +{ + const char *version_override; + + if ((version_override = g_getenv ("COGL_OVERRIDE_GL_VERSION"))) + return version_override; + else + return (const char *) context->glGetString (GL_VERSION); + +} + gboolean _cogl_gl_util_parse_gl_version (const char *version_string, int *major_out, -- GitLab From 462df7e61a026b5c3b14d146c46e43bad0493b55 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 16 Jan 2020 15:37:38 -0500 Subject: [PATCH 04/13] cogl: Move some GL-specific GLSL details into the driver _cogl_shader_set_source_with_boilerplate and _cogl_shader_compile_real have enough GL assumptions that it makes sense to push them into the backend. Taken together their only callers are under driver/gl, so. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194 --- cogl/cogl/cogl-glsl-shader-private.h | 41 ---- cogl/cogl/cogl-glsl-shader.c | 189 ------------------ cogl/cogl/deprecated/cogl-shader-private.h | 12 -- cogl/cogl/deprecated/cogl-shader.c | 96 --------- .../driver/gl/cogl-pipeline-fragend-glsl.c | 2 +- .../driver/gl/cogl-pipeline-opengl-private.h | 9 + .../driver/gl/cogl-pipeline-progend-glsl.c | 76 +++++++ .../driver/gl/cogl-pipeline-vertend-glsl.c | 146 +++++++++++++- cogl/cogl/meson.build | 2 - 9 files changed, 231 insertions(+), 342 deletions(-) delete mode 100644 cogl/cogl/cogl-glsl-shader-private.h delete mode 100644 cogl/cogl/cogl-glsl-shader.c diff --git a/cogl/cogl/cogl-glsl-shader-private.h b/cogl/cogl/cogl-glsl-shader-private.h deleted file mode 100644 index 9899c12c15d..00000000000 --- a/cogl/cogl/cogl-glsl-shader-private.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _COGL_GLSL_SHADER_PRIVATE_H_ -#define _COGL_GLSL_SHADER_PRIVATE_H_ - -void -_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx, - GLuint shader_gl_handle, - GLenum shader_gl_type, - CoglPipeline *pipeline, - GLsizei count_in, - const char **strings_in, - const GLint *lengths_in); - -#endif /* _COGL_GLSL_SHADER_PRIVATE_H_ */ diff --git a/cogl/cogl/cogl-glsl-shader.c b/cogl/cogl/cogl-glsl-shader.c deleted file mode 100644 index fda923c3433..00000000000 --- a/cogl/cogl/cogl-glsl-shader.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg - * Neil Roberts - */ - -#include "cogl-config.h" - -#include "cogl-context-private.h" -#include "cogl-glsl-shader-private.h" -#include "cogl-glsl-shader-boilerplate.h" -#include "driver/gl/cogl-util-gl-private.h" - -#include - -#include - -static gboolean -add_layer_vertex_boilerplate_cb (CoglPipelineLayer *layer, - void *user_data) -{ - GString *layer_declarations = user_data; - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - g_string_append_printf (layer_declarations, - "attribute vec4 cogl_tex_coord%d_in;\n" - "#define cogl_texture_matrix%i cogl_texture_matrix[%i]\n" - "#define cogl_tex_coord%i_out _cogl_tex_coord[%i]\n", - layer->index, - layer->index, - unit_index, - layer->index, - unit_index); - return TRUE; -} - -static gboolean -add_layer_fragment_boilerplate_cb (CoglPipelineLayer *layer, - void *user_data) -{ - GString *layer_declarations = user_data; - g_string_append_printf (layer_declarations, - "#define cogl_tex_coord%i_in _cogl_tex_coord[%i]\n", - layer->index, - _cogl_pipeline_layer_get_unit_index (layer)); - return TRUE; -} - -void -_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx, - GLuint shader_gl_handle, - GLenum shader_gl_type, - CoglPipeline *pipeline, - GLsizei count_in, - const char **strings_in, - const GLint *lengths_in) -{ - const char *vertex_boilerplate; - const char *fragment_boilerplate; - - const char **strings = g_alloca (sizeof (char *) * (count_in + 4)); - GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 4)); - char *version_string; - int count = 0; - - int n_layers; - - vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE; - fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE; - - version_string = g_strdup_printf ("#version %i\n\n", - ctx->glsl_version_to_use); - strings[count] = version_string; - lengths[count++] = -1; - - if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL)) - { - static const char image_external_extension[] = - "#extension GL_OES_EGL_image_external : require\n"; - strings[count] = image_external_extension; - lengths[count++] = sizeof (image_external_extension) - 1; - } - - if (shader_gl_type == GL_VERTEX_SHADER) - { - strings[count] = vertex_boilerplate; - lengths[count++] = strlen (vertex_boilerplate); - } - else if (shader_gl_type == GL_FRAGMENT_SHADER) - { - strings[count] = fragment_boilerplate; - lengths[count++] = strlen (fragment_boilerplate); - } - - n_layers = cogl_pipeline_get_n_layers (pipeline); - if (n_layers) - { - GString *layer_declarations = ctx->codegen_boilerplate_buffer; - g_string_set_size (layer_declarations, 0); - - g_string_append_printf (layer_declarations, - "varying vec4 _cogl_tex_coord[%d];\n", - n_layers); - - if (shader_gl_type == GL_VERTEX_SHADER) - { - g_string_append_printf (layer_declarations, - "uniform mat4 cogl_texture_matrix[%d];\n", - n_layers); - - _cogl_pipeline_foreach_layer_internal (pipeline, - add_layer_vertex_boilerplate_cb, - layer_declarations); - } - else if (shader_gl_type == GL_FRAGMENT_SHADER) - { - _cogl_pipeline_foreach_layer_internal (pipeline, - add_layer_fragment_boilerplate_cb, - layer_declarations); - } - - strings[count] = layer_declarations->str; - lengths[count++] = -1; /* null terminated */ - } - - memcpy (strings + count, strings_in, sizeof (char *) * count_in); - if (lengths_in) - memcpy (lengths + count, lengths_in, sizeof (GLint) * count_in); - else - { - int i; - - for (i = 0; i < count_in; i++) - lengths[count + i] = -1; /* null terminated */ - } - count += count_in; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE))) - { - GString *buf = g_string_new (NULL); - int i; - - g_string_append_printf (buf, - "%s shader:\n", - shader_gl_type == GL_VERTEX_SHADER ? - "vertex" : "fragment"); - for (i = 0; i < count; i++) - if (lengths[i] != -1) - g_string_append_len (buf, strings[i], lengths[i]); - else - g_string_append (buf, strings[i]); - - g_message ("%s", buf->str); - - g_string_free (buf, TRUE); - } - - GE( ctx, glShaderSource (shader_gl_handle, count, - (const char **) strings, lengths) ); - - g_free (version_string); -} diff --git a/cogl/cogl/deprecated/cogl-shader-private.h b/cogl/cogl/deprecated/cogl-shader-private.h index f19aaa22c85..ae47f18795f 100644 --- a/cogl/cogl/deprecated/cogl-shader-private.h +++ b/cogl/cogl/deprecated/cogl-shader-private.h @@ -47,16 +47,4 @@ struct _CoglShader char *source; }; -void -_cogl_shader_compile_real (CoglHandle handle, - CoglPipeline *pipeline); - -void -_cogl_shader_set_source_with_boilerplate (GLuint shader_gl_handle, - GLenum shader_gl_type, - int n_tex_coord_attribs, - GLsizei count_in, - const char **strings_in, - const GLint *lengths_in); - #endif /* __COGL_SHADER_H */ diff --git a/cogl/cogl/deprecated/cogl-shader.c b/cogl/cogl/deprecated/cogl-shader.c index 7015454775c..ec899ce34ff 100644 --- a/cogl/cogl/deprecated/cogl-shader.c +++ b/cogl/cogl/deprecated/cogl-shader.c @@ -32,7 +32,6 @@ #include "cogl-context-private.h" #include "cogl-object-private.h" -#include "cogl-glsl-shader-private.h" #include "cogl-glsl-shader-boilerplate.h" #include "driver/gl/cogl-util-gl-private.h" #include "deprecated/cogl-shader-private.h" @@ -45,13 +44,6 @@ static void _cogl_shader_free (CoglShader *shader); COGL_HANDLE_DEFINE (Shader, shader); -#ifndef GL_FRAGMENT_SHADER -#define GL_FRAGMENT_SHADER 0x8B30 -#endif -#ifndef GL_VERTEX_SHADER -#define GL_VERTEX_SHADER 0x8B31 -#endif - static void _cogl_shader_free (CoglShader *shader) { @@ -91,23 +83,6 @@ cogl_create_shader (CoglShaderType type) return _cogl_shader_handle_new (shader); } -static void -delete_shader (CoglShader *shader) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (shader->gl_handle) - GE (ctx, glDeleteShader (shader->gl_handle)); - - shader->gl_handle = 0; - - if (shader->compilation_pipeline) - { - cogl_object_unref (shader->compilation_pipeline); - shader->compilation_pipeline = NULL; - } -} - void cogl_shader_source (CoglHandle handle, const char *source) @@ -124,77 +99,6 @@ cogl_shader_source (CoglHandle handle, shader->source = g_strdup (source); } -void -_cogl_shader_compile_real (CoglHandle handle, - CoglPipeline *pipeline) -{ - CoglShader *shader = handle; - GLenum gl_type; - GLint status; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (shader->gl_handle) - { - CoglPipeline *prev = shader->compilation_pipeline; - - /* XXX: currently the only things that will affect the - * boilerplate for user shaders, apart from driver features, - * are the pipeline layer-indices and texture-unit-indices - */ - if (pipeline == prev || - _cogl_pipeline_layer_and_unit_numbers_equal (prev, pipeline)) - return; - } - - if (shader->gl_handle) - delete_shader (shader); - - switch (shader->type) - { - case COGL_SHADER_TYPE_VERTEX: - gl_type = GL_VERTEX_SHADER; - break; - case COGL_SHADER_TYPE_FRAGMENT: - gl_type = GL_FRAGMENT_SHADER; - break; - default: - g_assert_not_reached (); - break; - } - - shader->gl_handle = ctx->glCreateShader (gl_type); - - _cogl_glsl_shader_set_source_with_boilerplate (ctx, - shader->gl_handle, - gl_type, - pipeline, - 1, - (const char **) - &shader->source, - NULL); - - GE (ctx, glCompileShader (shader->gl_handle)); - - shader->compilation_pipeline = cogl_object_ref (pipeline); - - GE (ctx, glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status)); - if (!status) - { - char buffer[512]; - int len = 0; - - ctx->glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer); - buffer[len] = '\0'; - - g_warning ("Failed to compile GLSL program:\n" - "src:\n%s\n" - "error:\n%s\n", - shader->source, - buffer); - } -} - CoglShaderType cogl_shader_get_type (CoglHandle handle) { diff --git a/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c b/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c index 0e95fb3909f..4d754d9b33f 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c +++ b/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c @@ -43,11 +43,11 @@ #include "cogl-snippet-private.h" #include "cogl-list.h" #include "driver/gl/cogl-util-gl-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" #include "cogl-context-private.h" #include "cogl-object-private.h" #include "cogl-pipeline-cache.h" -#include "cogl-glsl-shader-private.h" #include "driver/gl/cogl-pipeline-fragend-glsl-private.h" #include "deprecated/cogl-shader-private.h" #include "deprecated/cogl-program-private.h" diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h b/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h index afcb4460ee5..8cae99cc085 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h +++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h @@ -146,5 +146,14 @@ _cogl_pipeline_flush_gl_state (CoglContext *context, gboolean skip_gl_state, gboolean unknown_color_alpha); +void +_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx, + GLuint shader_gl_handle, + GLenum shader_gl_type, + CoglPipeline *pipeline, + GLsizei count_in, + const char **strings_in, + const GLint *lengths_in); + #endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */ diff --git a/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c b/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c index 3a049a70b0b..8b318deb592 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c +++ b/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c @@ -633,6 +633,82 @@ _cogl_pipeline_progend_glsl_start (CoglPipeline *pipeline) return TRUE; } +static void +_cogl_shader_compile_real (CoglHandle handle, + CoglPipeline *pipeline) +{ + CoglShader *shader = handle; + GLenum gl_type; + GLint status; + + _COGL_GET_CONTEXT (ctx, NO_RETVAL); + + if (shader->gl_handle) + { + CoglPipeline *prev = shader->compilation_pipeline; + + /* XXX: currently the only things that will affect the + * boilerplate for user shaders, apart from driver features, + * are the pipeline layer-indices and texture-unit-indices + */ + if (pipeline == prev || + _cogl_pipeline_layer_and_unit_numbers_equal (prev, pipeline)) + return; + + GE (ctx, glDeleteShader (shader->gl_handle)); + shader->gl_handle = 0; + + if (shader->compilation_pipeline) + { + cogl_object_unref (shader->compilation_pipeline); + shader->compilation_pipeline = NULL; + } + } + + switch (shader->type) + { + case COGL_SHADER_TYPE_VERTEX: + gl_type = GL_VERTEX_SHADER; + break; + case COGL_SHADER_TYPE_FRAGMENT: + gl_type = GL_FRAGMENT_SHADER; + break; + default: + g_assert_not_reached (); + break; + } + + shader->gl_handle = ctx->glCreateShader (gl_type); + + _cogl_glsl_shader_set_source_with_boilerplate (ctx, + shader->gl_handle, + gl_type, + pipeline, + 1, + (const char **) + &shader->source, + NULL); + GE (ctx, glCompileShader (shader->gl_handle)); + + shader->compilation_pipeline = cogl_object_ref (pipeline); + + GE (ctx, glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status)); + if (!status) + { + char buffer[512]; + int len = 0; + + ctx->glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer); + buffer[len] = '\0'; + + g_warning ("Failed to compile GLSL program:\n" + "src:\n%s\n" + "error:\n%s\n", + shader->source, + buffer); + } +} + static void _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline, unsigned long pipelines_difference) diff --git a/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c b/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c index c69f50ae890..7ef7a49937c 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c +++ b/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c @@ -45,7 +45,7 @@ #include "cogl-context-private.h" #include "cogl-object-private.h" #include "cogl-pipeline-state-private.h" -#include "cogl-glsl-shader-private.h" +#include "cogl-glsl-shader-boilerplate.h" #include "driver/gl/cogl-pipeline-vertend-glsl-private.h" #include "deprecated/cogl-program-private.h" @@ -132,6 +132,150 @@ dirty_shader_state (CoglPipeline *pipeline) NULL); } +static gboolean +add_layer_vertex_boilerplate_cb (CoglPipelineLayer *layer, + void *user_data) +{ + GString *layer_declarations = user_data; + int unit_index = _cogl_pipeline_layer_get_unit_index (layer); + g_string_append_printf (layer_declarations, + "attribute vec4 cogl_tex_coord%d_in;\n" + "#define cogl_texture_matrix%i cogl_texture_matrix[%i]\n" + "#define cogl_tex_coord%i_out _cogl_tex_coord[%i]\n", + layer->index, + layer->index, + unit_index, + layer->index, + unit_index); + return TRUE; +} + +static gboolean +add_layer_fragment_boilerplate_cb (CoglPipelineLayer *layer, + void *user_data) +{ + GString *layer_declarations = user_data; + g_string_append_printf (layer_declarations, + "#define cogl_tex_coord%i_in _cogl_tex_coord[%i]\n", + layer->index, + _cogl_pipeline_layer_get_unit_index (layer)); + return TRUE; +} + +void +_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx, + GLuint shader_gl_handle, + GLenum shader_gl_type, + CoglPipeline *pipeline, + GLsizei count_in, + const char **strings_in, + const GLint *lengths_in) +{ + const char *vertex_boilerplate; + const char *fragment_boilerplate; + + const char **strings = g_alloca (sizeof (char *) * (count_in + 4)); + GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 4)); + char *version_string; + int count = 0; + + int n_layers; + + vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE; + fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE; + + version_string = g_strdup_printf ("#version %i\n\n", + ctx->glsl_version_to_use); + strings[count] = version_string; + lengths[count++] = -1; + + if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL)) + { + static const char image_external_extension[] = + "#extension GL_OES_EGL_image_external : require\n"; + strings[count] = image_external_extension; + lengths[count++] = sizeof (image_external_extension) - 1; + } + + if (shader_gl_type == GL_VERTEX_SHADER) + { + strings[count] = vertex_boilerplate; + lengths[count++] = strlen (vertex_boilerplate); + } + else if (shader_gl_type == GL_FRAGMENT_SHADER) + { + strings[count] = fragment_boilerplate; + lengths[count++] = strlen (fragment_boilerplate); + } + + n_layers = cogl_pipeline_get_n_layers (pipeline); + if (n_layers) + { + GString *layer_declarations = ctx->codegen_boilerplate_buffer; + g_string_set_size (layer_declarations, 0); + + g_string_append_printf (layer_declarations, + "varying vec4 _cogl_tex_coord[%d];\n", + n_layers); + + if (shader_gl_type == GL_VERTEX_SHADER) + { + g_string_append_printf (layer_declarations, + "uniform mat4 cogl_texture_matrix[%d];\n", + n_layers); + + _cogl_pipeline_foreach_layer_internal (pipeline, + add_layer_vertex_boilerplate_cb, + layer_declarations); + } + else if (shader_gl_type == GL_FRAGMENT_SHADER) + { + _cogl_pipeline_foreach_layer_internal (pipeline, + add_layer_fragment_boilerplate_cb, + layer_declarations); + } + + strings[count] = layer_declarations->str; + lengths[count++] = -1; /* null terminated */ + } + + memcpy (strings + count, strings_in, sizeof (char *) * count_in); + if (lengths_in) + memcpy (lengths + count, lengths_in, sizeof (GLint) * count_in); + else + { + int i; + + for (i = 0; i < count_in; i++) + lengths[count + i] = -1; /* null terminated */ + } + count += count_in; + + if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE))) + { + GString *buf = g_string_new (NULL); + int i; + + g_string_append_printf (buf, + "%s shader:\n", + shader_gl_type == GL_VERTEX_SHADER ? + "vertex" : "fragment"); + for (i = 0; i < count; i++) + if (lengths[i] != -1) + g_string_append_len (buf, strings[i], lengths[i]); + else + g_string_append (buf, strings[i]); + + g_message ("%s", buf->str); + + g_string_free (buf, TRUE); + } + + GE( ctx, glShaderSource (shader_gl_handle, count, + (const char **) strings, lengths) ); + + g_free (version_string); +} GLuint _cogl_pipeline_vertend_glsl_get_shader (CoglPipeline *pipeline) { diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build index a4383dc3d08..edcac793e36 100644 --- a/cogl/cogl/meson.build +++ b/cogl/cogl/meson.build @@ -274,8 +274,6 @@ cogl_sources = [ 'cogl-pipeline-layer-state.c', 'cogl-pipeline-state-private.h', 'cogl-pipeline-debug.c', - 'cogl-glsl-shader.c', - 'cogl-glsl-shader-private.h', 'cogl-glsl-shader-boilerplate.h', 'cogl-pipeline-snippet-private.h', 'cogl-pipeline-snippet.c', -- GitLab From 4ff58cc63f5383d1bf037376c0fcf64426fdb79a Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 16 Jan 2020 16:42:16 -0500 Subject: [PATCH 05/13] cogl: Move some pre-layer-change-notify code into the driver A CoglTextureUnit is a GL-specific type, this should happen in the driver not the core. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194 --- cogl/cogl/cogl-pipeline-layer.c | 12 ------------ cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c | 10 ++++++++++ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/cogl/cogl/cogl-pipeline-layer.c b/cogl/cogl/cogl-pipeline-layer.c index c6f13696a8e..3362c62204b 100644 --- a/cogl/cogl/cogl-pipeline-layer.c +++ b/cogl/cogl/cogl-pipeline-layer.c @@ -44,7 +44,6 @@ #include "cogl-node-private.h" #include "cogl-context-private.h" #include "cogl-texture-private.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" #include @@ -342,8 +341,6 @@ _cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner, CoglPipelineLayer *layer, CoglPipelineLayerState change) { - CoglTextureUnit *unit; - /* Identify the case where the layer is new with no owner or * dependants and so we don't need to do anything. */ if (_cogl_list_empty (&COGL_NODE (layer)->children) && @@ -403,15 +400,6 @@ _cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner, progend->layer_pre_change_notify (required_owner, layer, change); } - /* If the layer being changed is the same as the last layer we - * flushed to the corresponding texture unit then we keep a track of - * the changes so we can try to minimize redundant OpenGL calls if - * the same layer is flushed again. - */ - unit = _cogl_get_texture_unit (_cogl_pipeline_layer_get_unit_index (layer)); - if (unit->layer == layer) - unit->layer_changes_since_flush |= change; - init_layer_state: if (required_owner) diff --git a/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c b/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c index 8b318deb592..083308cedcd 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c +++ b/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c @@ -953,6 +953,7 @@ _cogl_pipeline_progend_glsl_layer_pre_change_notify ( CoglPipelineLayerState change) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); + CoglTextureUnit *unit; if ((change & (_cogl_pipeline_get_layer_state_for_fragment_codegen (ctx) | COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN))) @@ -977,6 +978,15 @@ _cogl_pipeline_progend_glsl_layer_pre_change_notify ( program_state->unit_state[unit_index].dirty_texture_matrix = TRUE; } } + + /* If the layer being changed is the same as the last layer we + * flushed to the corresponding texture unit then we keep a track of + * the changes so we can try to minimize redundant OpenGL calls if + * the same layer is flushed again. + */ + unit = _cogl_get_texture_unit (_cogl_pipeline_layer_get_unit_index (layer)); + if (unit->layer == layer) + unit->layer_changes_since_flush |= change; } static void -- GitLab From e03c75bac760ebd24036f8c7d009b3080c64743d Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 9 Apr 2020 13:06:28 -0400 Subject: [PATCH 06/13] cogl: Add a slot for driver-private state to CoglContext https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194 --- cogl/cogl/cogl-context-private.h | 2 ++ cogl/cogl/driver/gl/cogl-util-gl-private.h | 5 +++++ cogl/cogl/driver/gl/cogl-util-gl.c | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/cogl/cogl/cogl-context-private.h b/cogl/cogl/cogl-context-private.h index a2ed950d0cc..594b80c3018 100644 --- a/cogl/cogl/cogl-context-private.h +++ b/cogl/cogl/cogl-context-private.h @@ -73,6 +73,8 @@ struct _CoglContext const CoglDriverVtable *driver_vtable; const CoglTextureDriver *texture_driver; + void *driver_context; + int glsl_major; int glsl_minor; diff --git a/cogl/cogl/driver/gl/cogl-util-gl-private.h b/cogl/cogl/driver/gl/cogl-util-gl-private.h index 369baab874c..fb3f8534ccf 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-util-gl-private.h @@ -76,6 +76,11 @@ _cogl_gl_error_to_string (GLenum error_code); #endif /* COGL_GL_DEBUG */ +typedef struct _CoglGLContext CoglGLContext; /* opaque for the moment */ + +CoglGLContext * +_cogl_driver_gl_context (CoglContext *context); + gboolean _cogl_driver_gl_context_init (CoglContext *context); diff --git a/cogl/cogl/driver/gl/cogl-util-gl.c b/cogl/cogl/driver/gl/cogl-util-gl.c index 52ad54076f5..afd6d3a8ad0 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl.c +++ b/cogl/cogl/driver/gl/cogl-util-gl.c @@ -75,6 +75,12 @@ _cogl_gl_error_to_string (GLenum error_code) } #endif /* COGL_GL_DEBUG */ +CoglGLContext * +_cogl_driver_gl_context (CoglContext *context) +{ + return context->driver_context; +} + gboolean _cogl_driver_gl_context_init (CoglContext *context) { -- GitLab From 245977e525f34d8cd162132cf3f743857649a1a3 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 9 Apr 2020 14:12:31 -0400 Subject: [PATCH 07/13] cogl: Move texture unit state to CoglGLContext https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194 --- cogl/cogl/cogl-context-private.h | 3 -- cogl/cogl/driver/gl/cogl-pipeline-opengl.c | 39 +++++++++++++--------- cogl/cogl/driver/gl/cogl-util-gl-private.h | 5 ++- cogl/cogl/driver/gl/cogl-util-gl.c | 14 ++++++-- 4 files changed, 39 insertions(+), 22 deletions(-) diff --git a/cogl/cogl/cogl-context-private.h b/cogl/cogl/cogl-context-private.h index 594b80c3018..79d4f7b5ed7 100644 --- a/cogl/cogl/cogl-context-private.h +++ b/cogl/cogl/cogl-context-private.h @@ -121,9 +121,6 @@ struct _CoglContext CoglMatrixEntry identity_entry; - GArray *texture_units; - int active_texture_unit; - /* Only used for comparing other pipelines when reading pixels. */ CoglPipeline *opaque_color_pipeline; diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c index 44a968a2cf6..df1ce13e2dc 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c +++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c @@ -94,47 +94,51 @@ CoglTextureUnit * _cogl_get_texture_unit (int index_) { _COGL_GET_CONTEXT (ctx, NULL); + CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - if (ctx->texture_units->len < (index_ + 1)) + if (glctx->texture_units->len < (index_ + 1)) { int i; - int prev_len = ctx->texture_units->len; - ctx->texture_units = g_array_set_size (ctx->texture_units, index_ + 1); + int prev_len = glctx->texture_units->len; + glctx->texture_units = g_array_set_size (glctx->texture_units, + index_ + 1); for (i = prev_len; i <= index_; i++) { CoglTextureUnit *unit = - &g_array_index (ctx->texture_units, CoglTextureUnit, i); + &g_array_index (glctx->texture_units, CoglTextureUnit, i); texture_unit_init (ctx, unit, i); } } - return &g_array_index (ctx->texture_units, CoglTextureUnit, index_); + return &g_array_index (glctx->texture_units, CoglTextureUnit, index_); } void _cogl_destroy_texture_units (CoglContext *ctx) { int i; + CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - for (i = 0; i < ctx->texture_units->len; i++) + for (i = 0; i < glctx->texture_units->len; i++) { CoglTextureUnit *unit = - &g_array_index (ctx->texture_units, CoglTextureUnit, i); + &g_array_index (glctx->texture_units, CoglTextureUnit, i); texture_unit_free (unit); } - g_array_free (ctx->texture_units, TRUE); + g_array_free (glctx->texture_units, TRUE); } void _cogl_set_active_texture_unit (int unit_index) { _COGL_GET_CONTEXT (ctx, NO_RETVAL); + CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - if (ctx->active_texture_unit != unit_index) + if (glctx->active_texture_unit != unit_index) { GE (ctx, glActiveTexture (GL_TEXTURE0 + unit_index)); - ctx->active_texture_unit = unit_index; + glctx->active_texture_unit = unit_index; } } @@ -190,11 +194,12 @@ _cogl_delete_gl_texture (GLuint gl_texture) int i; _COGL_GET_CONTEXT (ctx, NO_RETVAL); + CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - for (i = 0; i < ctx->texture_units->len; i++) + for (i = 0; i < glctx->texture_units->len; i++) { CoglTextureUnit *unit = - &g_array_index (ctx->texture_units, CoglTextureUnit, i); + &g_array_index (glctx->texture_units, CoglTextureUnit, i); if (unit->gl_texture == gl_texture) { @@ -218,11 +223,12 @@ _cogl_pipeline_texture_storage_change_notify (CoglTexture *texture) int i; _COGL_GET_CONTEXT (ctx, NO_RETVAL); + CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - for (i = 0; i < ctx->texture_units->len; i++) + for (i = 0; i < glctx->texture_units->len; i++) { CoglTextureUnit *unit = - &g_array_index (ctx->texture_units, CoglTextureUnit, i); + &g_array_index (glctx->texture_units, CoglTextureUnit, i); if (unit->layer && _cogl_pipeline_layer_get_texture (unit->layer) == texture) @@ -704,11 +710,12 @@ foreach_texture_unit_update_filter_and_wrap_modes (void) int i; _COGL_GET_CONTEXT (ctx, NO_RETVAL); + CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - for (i = 0; i < ctx->texture_units->len; i++) + for (i = 0; i < glctx->texture_units->len; i++) { CoglTextureUnit *unit = - &g_array_index (ctx->texture_units, CoglTextureUnit, i); + &g_array_index (glctx->texture_units, CoglTextureUnit, i); if (unit->layer) { diff --git a/cogl/cogl/driver/gl/cogl-util-gl-private.h b/cogl/cogl/driver/gl/cogl-util-gl-private.h index fb3f8534ccf..0d23da1a868 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-util-gl-private.h @@ -76,7 +76,10 @@ _cogl_gl_error_to_string (GLenum error_code); #endif /* COGL_GL_DEBUG */ -typedef struct _CoglGLContext CoglGLContext; /* opaque for the moment */ +typedef struct _CoglGLContext { + GArray *texture_units; + int active_texture_unit; +} CoglGLContext; CoglGLContext * _cogl_driver_gl_context (CoglContext *context); diff --git a/cogl/cogl/driver/gl/cogl-util-gl.c b/cogl/cogl/driver/gl/cogl-util-gl.c index afd6d3a8ad0..c49c5289f78 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl.c +++ b/cogl/cogl/driver/gl/cogl-util-gl.c @@ -84,12 +84,21 @@ _cogl_driver_gl_context (CoglContext *context) gboolean _cogl_driver_gl_context_init (CoglContext *context) { - context->texture_units = + CoglGLContext *gl_context; + + if (!context->driver_context) + context->driver_context = g_new0 (CoglContext, 1); + + gl_context = _cogl_driver_gl_context (context); + if (!gl_context) + return FALSE; + + gl_context->texture_units = g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit)); /* See cogl-pipeline.c for more details about why we leave texture unit 1 * active by default... */ - context->active_texture_unit = 1; + gl_context->active_texture_unit = 1; GE (context, glActiveTexture (GL_TEXTURE1)); return TRUE; @@ -99,6 +108,7 @@ void _cogl_driver_gl_context_deinit (CoglContext *context) { _cogl_destroy_texture_units (context); + g_free (context->driver_context); } GLenum -- GitLab From e2c2a332e6bd957db10dda9ae5639c76d2bd12e0 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 15 Jan 2020 15:45:17 -0500 Subject: [PATCH 08/13] cogl: Add and use sampler init/free hooks in the CoglDriverVtable next_fake_sampler_object_number moves to CoglGLContext. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194 --- cogl/cogl/cogl-driver.h | 9 +++ cogl/cogl/cogl-sampler-cache.c | 57 +------------------ .../driver/gl/cogl-pipeline-opengl-private.h | 8 +++ cogl/cogl/driver/gl/cogl-pipeline-opengl.c | 42 ++++++++++++++ cogl/cogl/driver/gl/cogl-util-gl-private.h | 4 ++ cogl/cogl/driver/gl/cogl-util-gl.c | 1 + cogl/cogl/driver/gl/gl/cogl-driver-gl.c | 3 + cogl/cogl/driver/gl/gles/cogl-driver-gles.c | 3 + 8 files changed, 72 insertions(+), 55 deletions(-) diff --git a/cogl/cogl/cogl-driver.h b/cogl/cogl/cogl-driver.h index e52a99cfb89..6ad24d65c8e 100644 --- a/cogl/cogl/cogl-driver.h +++ b/cogl/cogl/cogl-driver.h @@ -35,6 +35,7 @@ #include "cogl-offscreen.h" #include "cogl-framebuffer-private.h" #include "cogl-attribute-private.h" +#include "cogl-sampler-cache-private.h" typedef struct _CoglDriverVtable CoglDriverVtable; @@ -265,6 +266,14 @@ struct _CoglDriverVtable const void *data, unsigned int size, GError **error); + + void + (*sampler_init) (CoglContext *context, + CoglSamplerCacheEntry *entry); + + void + (*sampler_free) (CoglContext *context, + CoglSamplerCacheEntry *entry); }; #define COGL_DRIVER_ERROR (_cogl_driver_error_quark ()) diff --git a/cogl/cogl/cogl-sampler-cache.c b/cogl/cogl/cogl-sampler-cache.c index f2dbaeb6312..2e0e761f008 100644 --- a/cogl/cogl/cogl-sampler-cache.c +++ b/cogl/cogl/cogl-sampler-cache.c @@ -34,11 +34,6 @@ #include "cogl-sampler-cache-private.h" #include "cogl-context-private.h" -#include "driver/gl/cogl-util-gl-private.h" - -#ifndef GL_TEXTURE_WRAP_R -#define GL_TEXTURE_WRAP_R 0x8072 -#endif struct _CoglSamplerCache { @@ -54,10 +49,6 @@ struct _CoglSamplerCache GL state. */ GHashTable *hash_table_cogl; GHashTable *hash_table_gl; - - /* This is used for generated fake unique sampler object numbers - when the sampler object extension is not supported */ - GLuint next_fake_sampler_object_number; }; static CoglSamplerCacheWrapMode @@ -176,22 +167,10 @@ _cogl_sampler_cache_new (CoglContext *context) sampler_state_equal_gl); cache->hash_table_cogl = g_hash_table_new (hash_sampler_state_cogl, sampler_state_equal_cogl); - cache->next_fake_sampler_object_number = 1; return cache; } -static void -set_wrap_mode (CoglContext *context, - GLuint sampler_object, - GLenum param, - CoglSamplerCacheWrapMode wrap_mode) -{ - GE( context, glSamplerParameteri (sampler_object, - param, - wrap_mode) ); -} - static CoglSamplerCacheEntry * _cogl_sampler_cache_get_entry_gl (CoglSamplerCache *cache, const CoglSamplerCacheEntry *key) @@ -202,39 +181,9 @@ _cogl_sampler_cache_get_entry_gl (CoglSamplerCache *cache, if (entry == NULL) { - CoglContext *context = cache->context; - entry = g_slice_dup (CoglSamplerCacheEntry, key); - if (_cogl_has_private_feature (context, - COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS)) - { - GE( context, glGenSamplers (1, &entry->sampler_object) ); - - GE( context, glSamplerParameteri (entry->sampler_object, - GL_TEXTURE_MIN_FILTER, - entry->min_filter) ); - GE( context, glSamplerParameteri (entry->sampler_object, - GL_TEXTURE_MAG_FILTER, - entry->mag_filter) ); - - set_wrap_mode (context, - entry->sampler_object, - GL_TEXTURE_WRAP_S, - entry->wrap_mode_s); - set_wrap_mode (context, - entry->sampler_object, - GL_TEXTURE_WRAP_T, - entry->wrap_mode_t); - } - else - { - /* If sampler objects aren't supported then we'll invent a - unique number so that pipelines can still compare the - unique state just by comparing the sampler object - numbers */ - entry->sampler_object = cache->next_fake_sampler_object_number++; - } + cache->context->driver_vtable->sampler_init (cache->context, entry); g_hash_table_insert (cache->hash_table_gl, entry, entry); } @@ -320,9 +269,7 @@ hash_table_free_gl_cb (void *key, CoglContext *context = user_data; CoglSamplerCacheEntry *entry = value; - if (_cogl_has_private_feature (context, - COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS)) - GE( context, glDeleteSamplers (1, &entry->sampler_object) ); + context->driver_vtable->sampler_free (context, entry); g_slice_free (CoglSamplerCacheEntry, entry); } diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h b/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h index 8cae99cc085..e10ca69dcbb 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h +++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h @@ -155,5 +155,13 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx, const char **strings_in, const GLint *lengths_in); +void +_cogl_sampler_gl_init (CoglContext *context, + CoglSamplerCacheEntry *entry); + +void +_cogl_sampler_gl_free (CoglContext *context, + CoglSamplerCacheEntry *entry); + #endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */ diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c index df1ce13e2dc..3264a002971 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c +++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c @@ -694,6 +694,48 @@ _cogl_pipeline_layer_forward_wrap_modes (CoglPipelineLayer *layer, gl_wrap_mode_t); } +void +_cogl_sampler_gl_init (CoglContext *context, CoglSamplerCacheEntry *entry) +{ + if (_cogl_has_private_feature (context, + COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS)) + { + GE( context, glGenSamplers (1, &entry->sampler_object) ); + + GE( context, glSamplerParameteri (entry->sampler_object, + GL_TEXTURE_MIN_FILTER, + entry->min_filter) ); + GE( context, glSamplerParameteri (entry->sampler_object, + GL_TEXTURE_MAG_FILTER, + entry->mag_filter) ); + + GE (context, glSamplerParameteri (entry->sampler_object, + GL_TEXTURE_WRAP_S, + entry->wrap_mode_s) ); + GE (context, glSamplerParameteri (entry->sampler_object, + GL_TEXTURE_WRAP_T, + entry->wrap_mode_t) ); + } + else + { + CoglGLContext *gl_context = context->driver_context; + + /* If sampler objects aren't supported then we'll invent a + unique number so that pipelines can still compare the + unique state just by comparing the sampler object + numbers */ + entry->sampler_object = gl_context->next_fake_sampler_object_number++; + } +} + +void +_cogl_sampler_gl_free (CoglContext *context, CoglSamplerCacheEntry *entry) +{ + if (_cogl_has_private_feature (context, + COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS)) + GE( context, glDeleteSamplers (1, &entry->sampler_object) ); +} + /* OpenGL associates the min/mag filters and repeat modes with the * texture object not the texture unit so we always have to re-assert * the filter and repeat modes whenever we use a texture since it may diff --git a/cogl/cogl/driver/gl/cogl-util-gl-private.h b/cogl/cogl/driver/gl/cogl-util-gl-private.h index 0d23da1a868..b3367973f5a 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-util-gl-private.h @@ -79,6 +79,10 @@ _cogl_gl_error_to_string (GLenum error_code); typedef struct _CoglGLContext { GArray *texture_units; int active_texture_unit; + + /* This is used for generated fake unique sampler object numbers + when the sampler object extension is not supported */ + GLuint next_fake_sampler_object_number; } CoglGLContext; CoglGLContext * diff --git a/cogl/cogl/driver/gl/cogl-util-gl.c b/cogl/cogl/driver/gl/cogl-util-gl.c index c49c5289f78..1e2381934a9 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl.c +++ b/cogl/cogl/driver/gl/cogl-util-gl.c @@ -93,6 +93,7 @@ _cogl_driver_gl_context_init (CoglContext *context) if (!gl_context) return FALSE; + gl_context->next_fake_sampler_object_number = 1; gl_context->texture_units = g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit)); diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c index 42351c4d808..d066ff0722c 100644 --- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c @@ -42,6 +42,7 @@ #include "driver/gl/cogl-attribute-gl-private.h" #include "driver/gl/cogl-clip-stack-gl-private.h" #include "driver/gl/cogl-buffer-gl-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" static gboolean _cogl_driver_gl_real_context_init (CoglContext *context) @@ -562,4 +563,6 @@ _cogl_driver_gl = _cogl_buffer_gl_map_range, _cogl_buffer_gl_unmap, _cogl_buffer_gl_set_data, + _cogl_sampler_gl_init, + _cogl_sampler_gl_free, }; diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c index d85d2f9f209..34f850fd534 100644 --- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c @@ -42,6 +42,7 @@ #include "driver/gl/cogl-attribute-gl-private.h" #include "driver/gl/cogl-clip-stack-gl-private.h" #include "driver/gl/cogl-buffer-gl-private.h" +#include "driver/gl/cogl-pipeline-opengl-private.h" #ifndef GL_UNSIGNED_INT_24_8 #define GL_UNSIGNED_INT_24_8 0x84FA @@ -426,4 +427,6 @@ _cogl_driver_gles = _cogl_buffer_gl_map_range, _cogl_buffer_gl_unmap, _cogl_buffer_gl_set_data, + _cogl_sampler_gl_init, + _cogl_sampler_gl_free, }; -- GitLab From 0b6f5c6f55bf5f0964b4e452d378cedf5d0cf36e Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 15 Jan 2020 16:02:29 -0500 Subject: [PATCH 09/13] cogl: Move GL-specific uniform code to the driver vtable https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194 --- cogl/cogl/cogl-boxed-value.c | 88 +----------------- cogl/cogl/cogl-driver.h | 5 + .../driver/gl/cogl-pipeline-opengl-private.h | 5 + cogl/cogl/driver/gl/cogl-pipeline-opengl.c | 92 +++++++++++++++++++ cogl/cogl/driver/gl/gl/cogl-driver-gl.c | 1 + cogl/cogl/driver/gl/gles/cogl-driver-gles.c | 1 + 6 files changed, 105 insertions(+), 87 deletions(-) diff --git a/cogl/cogl/cogl-boxed-value.c b/cogl/cogl/cogl-boxed-value.c index 7d55231c0f9..9a9ba41c218 100644 --- a/cogl/cogl/cogl-boxed-value.c +++ b/cogl/cogl/cogl-boxed-value.c @@ -34,7 +34,6 @@ #include "cogl-boxed-value.h" #include "cogl-context-private.h" -#include "driver/gl/cogl-util-gl-private.h" gboolean _cogl_boxed_value_equal (const CoglBoxedValue *bva, @@ -286,90 +285,5 @@ _cogl_boxed_value_set_uniform (CoglContext *ctx, GLint location, const CoglBoxedValue *value) { - switch (value->type) - { - case COGL_BOXED_NONE: - break; - - case COGL_BOXED_INT: - { - const int *ptr; - - if (value->count == 1) - ptr = value->v.int_value; - else - ptr = value->v.int_array; - - switch (value->size) - { - case 1: - GE( ctx, glUniform1iv (location, value->count, ptr) ); - break; - case 2: - GE( ctx, glUniform2iv (location, value->count, ptr) ); - break; - case 3: - GE( ctx, glUniform3iv (location, value->count, ptr) ); - break; - case 4: - GE( ctx, glUniform4iv (location, value->count, ptr) ); - break; - } - } - break; - - case COGL_BOXED_FLOAT: - { - const float *ptr; - - if (value->count == 1) - ptr = value->v.float_value; - else - ptr = value->v.float_array; - - switch (value->size) - { - case 1: - GE( ctx, glUniform1fv (location, value->count, ptr) ); - break; - case 2: - GE( ctx, glUniform2fv (location, value->count, ptr) ); - break; - case 3: - GE( ctx, glUniform3fv (location, value->count, ptr) ); - break; - case 4: - GE( ctx, glUniform4fv (location, value->count, ptr) ); - break; - } - } - break; - - case COGL_BOXED_MATRIX: - { - const float *ptr; - - if (value->count == 1) - ptr = value->v.matrix; - else - ptr = value->v.float_array; - - switch (value->size) - { - case 2: - GE( ctx, glUniformMatrix2fv (location, value->count, - FALSE, ptr) ); - break; - case 3: - GE( ctx, glUniformMatrix3fv (location, value->count, - FALSE, ptr) ); - break; - case 4: - GE( ctx, glUniformMatrix4fv (location, value->count, - FALSE, ptr) ); - break; - } - } - break; - } + ctx->driver_vtable->set_uniform (ctx, location, value); } diff --git a/cogl/cogl/cogl-driver.h b/cogl/cogl/cogl-driver.h index 6ad24d65c8e..04c5d2e58bb 100644 --- a/cogl/cogl/cogl-driver.h +++ b/cogl/cogl/cogl-driver.h @@ -274,6 +274,11 @@ struct _CoglDriverVtable void (*sampler_free) (CoglContext *context, CoglSamplerCacheEntry *entry); + + void + (* set_uniform) (CoglContext *ctx, + GLint location, + const CoglBoxedValue *value); }; #define COGL_DRIVER_ERROR (_cogl_driver_error_quark ()) diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h b/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h index e10ca69dcbb..62846237c7a 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h +++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h @@ -163,5 +163,10 @@ void _cogl_sampler_gl_free (CoglContext *context, CoglSamplerCacheEntry *entry); +void +_cogl_gl_set_uniform (CoglContext *ctx, + GLint location, + const CoglBoxedValue *value); + #endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */ diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c index 3264a002971..da13e293b11 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c +++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c @@ -1190,3 +1190,95 @@ done: COGL_TIMER_STOP (_cogl_uprof_context, pipeline_flush_timer); } +void +_cogl_gl_set_uniform (CoglContext *ctx, + GLint location, + const CoglBoxedValue *value) +{ + switch (value->type) + { + case COGL_BOXED_NONE: + break; + + case COGL_BOXED_INT: + { + const int *ptr; + + if (value->count == 1) + ptr = value->v.int_value; + else + ptr = value->v.int_array; + + switch (value->size) + { + case 1: + GE( ctx, glUniform1iv (location, value->count, ptr) ); + break; + case 2: + GE( ctx, glUniform2iv (location, value->count, ptr) ); + break; + case 3: + GE( ctx, glUniform3iv (location, value->count, ptr) ); + break; + case 4: + GE( ctx, glUniform4iv (location, value->count, ptr) ); + break; + } + } + break; + + case COGL_BOXED_FLOAT: + { + const float *ptr; + + if (value->count == 1) + ptr = value->v.float_value; + else + ptr = value->v.float_array; + + switch (value->size) + { + case 1: + GE( ctx, glUniform1fv (location, value->count, ptr) ); + break; + case 2: + GE( ctx, glUniform2fv (location, value->count, ptr) ); + break; + case 3: + GE( ctx, glUniform3fv (location, value->count, ptr) ); + break; + case 4: + GE( ctx, glUniform4fv (location, value->count, ptr) ); + break; + } + } + break; + + case COGL_BOXED_MATRIX: + { + const float *ptr; + + if (value->count == 1) + ptr = value->v.matrix; + else + ptr = value->v.float_array; + + switch (value->size) + { + case 2: + GE( ctx, glUniformMatrix2fv (location, value->count, + FALSE, ptr) ); + break; + case 3: + GE( ctx, glUniformMatrix3fv (location, value->count, + FALSE, ptr) ); + break; + case 4: + GE( ctx, glUniformMatrix4fv (location, value->count, + FALSE, ptr) ); + break; + } + } + break; + } +} diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c index d066ff0722c..950cbe662b1 100644 --- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c @@ -565,4 +565,5 @@ _cogl_driver_gl = _cogl_buffer_gl_set_data, _cogl_sampler_gl_init, _cogl_sampler_gl_free, + _cogl_gl_set_uniform, /* XXX name is weird... */ }; diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c index 34f850fd534..32f8c526ac7 100644 --- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c @@ -429,4 +429,5 @@ _cogl_driver_gles = _cogl_buffer_gl_set_data, _cogl_sampler_gl_init, _cogl_sampler_gl_free, + _cogl_gl_set_uniform, }; -- GitLab From ca79073014d1639d334188e4a591f1984cbbd2b8 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 28 Jan 2020 15:16:25 -0500 Subject: [PATCH 10/13] cogl: Move graphics reset status into the driver vtable https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194 --- cogl/cogl/cogl-context.c | 39 +------------------ cogl/cogl/cogl-driver.h | 3 ++ cogl/cogl/driver/gl/cogl-util-gl-private.h | 3 ++ cogl/cogl/driver/gl/cogl-util-gl.c | 43 +++++++++++++++++++++ cogl/cogl/driver/gl/gl/cogl-driver-gl.c | 1 + cogl/cogl/driver/gl/gles/cogl-driver-gles.c | 1 + cogl/cogl/driver/nop/cogl-driver-nop.c | 1 + 7 files changed, 53 insertions(+), 38 deletions(-) diff --git a/cogl/cogl/cogl-context.c b/cogl/cogl/cogl-context.c index 908738f2955..e6effb00800 100644 --- a/cogl/cogl/cogl-context.c +++ b/cogl/cogl/cogl-context.c @@ -56,24 +56,6 @@ #define GL_POINT_SPRITE 0x8861 #endif -/* This is a relatively new extension */ -#ifndef GL_PURGED_CONTEXT_RESET_NV -#define GL_PURGED_CONTEXT_RESET_NV 0x92BB -#endif - -/* These aren't defined in the GLES2 headers */ -#ifndef GL_GUILTY_CONTEXT_RESET_ARB -#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 -#endif - -#ifndef GL_INNOCENT_CONTEXT_RESET_ARB -#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 -#endif - -#ifndef GL_UNKNOWN_CONTEXT_RESET_ARB -#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 -#endif - static void _cogl_context_free (CoglContext *context); COGL_OBJECT_DEFINE (Context, context); @@ -479,26 +461,7 @@ cogl_get_clock_time (CoglContext *context) CoglGraphicsResetStatus cogl_get_graphics_reset_status (CoglContext *context) { - if (!context->glGetGraphicsResetStatus) - return COGL_GRAPHICS_RESET_STATUS_NO_ERROR; - - switch (context->glGetGraphicsResetStatus ()) - { - case GL_GUILTY_CONTEXT_RESET_ARB: - return COGL_GRAPHICS_RESET_STATUS_GUILTY_CONTEXT_RESET; - - case GL_INNOCENT_CONTEXT_RESET_ARB: - return COGL_GRAPHICS_RESET_STATUS_INNOCENT_CONTEXT_RESET; - - case GL_UNKNOWN_CONTEXT_RESET_ARB: - return COGL_GRAPHICS_RESET_STATUS_UNKNOWN_CONTEXT_RESET; - - case GL_PURGED_CONTEXT_RESET_NV: - return COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET; - - default: - return COGL_GRAPHICS_RESET_STATUS_NO_ERROR; - } + return context->driver_vtable->get_graphics_reset_status (context); } gboolean diff --git a/cogl/cogl/cogl-driver.h b/cogl/cogl/cogl-driver.h index 04c5d2e58bb..d8f3cc18fe6 100644 --- a/cogl/cogl/cogl-driver.h +++ b/cogl/cogl/cogl-driver.h @@ -50,6 +50,9 @@ struct _CoglDriverVtable gboolean (* is_hardware_accelerated) (CoglContext *context); + CoglGraphicsResetStatus + (* get_graphics_reset_status) (CoglContext *context); + /* TODO: factor this out since this is OpenGL specific and * so can be ignored by non-OpenGL drivers. */ gboolean diff --git a/cogl/cogl/driver/gl/cogl-util-gl-private.h b/cogl/cogl/driver/gl/cogl-util-gl-private.h index b3367973f5a..c3f55086370 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl-private.h +++ b/cogl/cogl/driver/gl/cogl-util-gl-private.h @@ -131,4 +131,7 @@ _cogl_gl_util_parse_gl_version (const char *version_string, int *major_out, int *minor_out); +CoglGraphicsResetStatus +_cogl_gl_get_graphics_reset_status (CoglContext *context); + #endif /* _COGL_UTIL_GL_PRIVATE_H_ */ diff --git a/cogl/cogl/driver/gl/cogl-util-gl.c b/cogl/cogl/driver/gl/cogl-util-gl.c index 1e2381934a9..e41c17c93d2 100644 --- a/cogl/cogl/driver/gl/cogl-util-gl.c +++ b/cogl/cogl/driver/gl/cogl-util-gl.c @@ -37,6 +37,24 @@ #include "driver/gl/cogl-pipeline-opengl-private.h" #include "driver/gl/cogl-util-gl-private.h" +/* This is a relatively new extension */ +#ifndef GL_PURGED_CONTEXT_RESET_NV +#define GL_PURGED_CONTEXT_RESET_NV 0x92BB +#endif + +/* These aren't defined in the GLES2 headers */ +#ifndef GL_GUILTY_CONTEXT_RESET_ARB +#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 +#endif + +#ifndef GL_INNOCENT_CONTEXT_RESET_ARB +#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 +#endif + +#ifndef GL_UNKNOWN_CONTEXT_RESET_ARB +#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 +#endif + #ifdef COGL_GL_DEBUG /* GL error to string conversion */ static const struct { @@ -309,3 +327,28 @@ _cogl_driver_gl_is_hardware_accelerated (CoglContext *ctx) return !software; } + +CoglGraphicsResetStatus +_cogl_gl_get_graphics_reset_status (CoglContext *context) +{ + if (!context->glGetGraphicsResetStatus) + return COGL_GRAPHICS_RESET_STATUS_NO_ERROR; + + switch (context->glGetGraphicsResetStatus ()) + { + case GL_GUILTY_CONTEXT_RESET_ARB: + return COGL_GRAPHICS_RESET_STATUS_GUILTY_CONTEXT_RESET; + + case GL_INNOCENT_CONTEXT_RESET_ARB: + return COGL_GRAPHICS_RESET_STATUS_INNOCENT_CONTEXT_RESET; + + case GL_UNKNOWN_CONTEXT_RESET_ARB: + return COGL_GRAPHICS_RESET_STATUS_UNKNOWN_CONTEXT_RESET; + + case GL_PURGED_CONTEXT_RESET_NV: + return COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET; + + default: + return COGL_GRAPHICS_RESET_STATUS_NO_ERROR; + } +} diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c index 950cbe662b1..3c2231ebc36 100644 --- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c @@ -532,6 +532,7 @@ _cogl_driver_gl = _cogl_driver_gl_real_context_init, _cogl_driver_gl_context_deinit, _cogl_driver_gl_is_hardware_accelerated, + _cogl_gl_get_graphics_reset_status, _cogl_driver_pixel_format_from_gl_internal, _cogl_driver_pixel_format_to_gl, _cogl_driver_update_features, diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c index 32f8c526ac7..3cb11af6996 100644 --- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c @@ -396,6 +396,7 @@ _cogl_driver_gles = _cogl_driver_gl_context_init, _cogl_driver_gl_context_deinit, _cogl_driver_gl_is_hardware_accelerated, + _cogl_gl_get_graphics_reset_status, _cogl_driver_pixel_format_from_gl_internal, _cogl_driver_pixel_format_to_gl, _cogl_driver_update_features, diff --git a/cogl/cogl/driver/nop/cogl-driver-nop.c b/cogl/cogl/driver/nop/cogl-driver-nop.c index 5edd93a22a1..f7e6d948f60 100644 --- a/cogl/cogl/driver/nop/cogl-driver-nop.c +++ b/cogl/cogl/driver/nop/cogl-driver-nop.c @@ -73,6 +73,7 @@ _cogl_driver_nop = _cogl_driver_nop_context_init, _cogl_driver_nop_context_deinit, _cogl_driver_nop_is_hardware_accelerated, + NULL, /* get_graphics_reset_status */ NULL, /* pixel_format_from_gl_internal */ NULL, /* pixel_format_to_gl */ _cogl_driver_update_features, -- GitLab From 1f5d6a01f5e102004027b6a7866daf22b17d3960 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 16 Jan 2020 15:00:55 -0500 Subject: [PATCH 11/13] cogl: Remove unused driver includes https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194 --- cogl/cogl/cogl-atlas-texture.c | 1 - cogl/cogl/cogl-matrix-stack.c | 1 - cogl/cogl/deprecated/cogl-program.c | 1 - 3 files changed, 3 deletions(-) diff --git a/cogl/cogl/cogl-atlas-texture.c b/cogl/cogl/cogl-atlas-texture.c index 04d8880854d..5374629fc0a 100644 --- a/cogl/cogl/cogl-atlas-texture.c +++ b/cogl/cogl/cogl-atlas-texture.c @@ -48,7 +48,6 @@ #include "cogl1-context.h" #include "cogl-sub-texture.h" #include "cogl-gtype-private.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" #include "driver/gl/cogl-texture-gl-private.h" #include diff --git a/cogl/cogl/cogl-matrix-stack.c b/cogl/cogl/cogl-matrix-stack.c index 2e5150afa7c..138d3ac545f 100644 --- a/cogl/cogl/cogl-matrix-stack.c +++ b/cogl/cogl/cogl-matrix-stack.c @@ -41,7 +41,6 @@ #include "cogl-matrix-private.h" #include "cogl-magazine-private.h" #include "cogl-gtype-private.h" -#include "driver/gl/cogl-util-gl-private.h" static void _cogl_matrix_stack_free (CoglMatrixStack *stack); diff --git a/cogl/cogl/deprecated/cogl-program.c b/cogl/cogl/deprecated/cogl-program.c index adf5543d2b0..65904c6b5db 100644 --- a/cogl/cogl/deprecated/cogl-program.c +++ b/cogl/cogl/deprecated/cogl-program.c @@ -31,7 +31,6 @@ #include "cogl-config.h" #include "cogl-util.h" -#include "driver/gl/cogl-util-gl-private.h" #include "cogl-context-private.h" #include "cogl-object-private.h" -- GitLab From ab9f241cc5294bcabf456fccd728cb1b77401d0b Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 9 Apr 2020 15:11:52 -0400 Subject: [PATCH 12/13] cogl: Remove some dead stores not flagged by the compiler https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194 --- cogl/cogl/cogl-texture.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cogl/cogl/cogl-texture.c b/cogl/cogl/cogl-texture.c index c82481156ce..2481943c8b7 100644 --- a/cogl/cogl/cogl-texture.c +++ b/cogl/cogl/cogl-texture.c @@ -62,11 +62,6 @@ #include #include -/* This isn't defined in the GLES headers */ -#ifndef GL_RED -#define GL_RED 0x1903 -#endif - COGL_GTYPE_DEFINE_INTERFACE (Texture, texture); uint32_t @@ -786,8 +781,6 @@ cogl_texture_get_data (CoglTexture *texture, if (texture_format == COGL_PIXEL_FORMAT_A_8) { closest_format = COGL_PIXEL_FORMAT_A_8; - closest_gl_format = GL_RED; - closest_gl_type = GL_UNSIGNED_BYTE; } else if (format == COGL_PIXEL_FORMAT_A_8) { @@ -798,8 +791,6 @@ cogl_texture_get_data (CoglTexture *texture, * pre-multiplied here because we're only going to look at * the alpha component */ closest_format = COGL_PIXEL_FORMAT_RGBA_8888; - closest_gl_format = GL_RGBA; - closest_gl_type = GL_UNSIGNED_BYTE; } } -- GitLab From 1398c6dfa4aae6b2b91eb05370e7c4c5bdfb693f Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 9 Apr 2020 15:13:25 -0400 Subject: [PATCH 13/13] cogl: Remove some unused #define GL_BLAH safeties None of these constants are referenced in the files defining them. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194 --- cogl/cogl/cogl-attribute.c | 5 ----- cogl/cogl/cogl-context.c | 5 ----- cogl/cogl/cogl-pixel-buffer.c | 16 ---------------- 3 files changed, 26 deletions(-) diff --git a/cogl/cogl/cogl-attribute.c b/cogl/cogl/cogl-attribute.c index 6c1842e1729..1c0c88d0b98 100644 --- a/cogl/cogl/cogl-attribute.c +++ b/cogl/cogl/cogl-attribute.c @@ -51,11 +51,6 @@ #include #include -/* This isn't defined in the GLES headers */ -#ifndef GL_UNSIGNED_INT -#define GL_UNSIGNED_INT 0x1405 -#endif - static void _cogl_attribute_free (CoglAttribute *attribute); COGL_OBJECT_DEFINE (Attribute, attribute); diff --git a/cogl/cogl/cogl-context.c b/cogl/cogl/cogl-context.c index e6effb00800..dc99f350862 100644 --- a/cogl/cogl/cogl-context.c +++ b/cogl/cogl/cogl-context.c @@ -51,11 +51,6 @@ #include #include -/* These aren't defined in the GLES headers */ -#ifndef GL_POINT_SPRITE -#define GL_POINT_SPRITE 0x8861 -#endif - static void _cogl_context_free (CoglContext *context); COGL_OBJECT_DEFINE (Context, context); diff --git a/cogl/cogl/cogl-pixel-buffer.c b/cogl/cogl/cogl-pixel-buffer.c index 7abebacccef..d7d38397159 100644 --- a/cogl/cogl/cogl-pixel-buffer.c +++ b/cogl/cogl/cogl-pixel-buffer.c @@ -51,22 +51,6 @@ #include "cogl-pixel-buffer.h" #include "cogl-gtype-private.h" -/* - * GL/GLES compatibility defines for the buffer API: - */ - -#if defined (HAVE_COGL_GL) - -#ifndef GL_PIXEL_UNPACK_BUFFER -#define GL_PIXEL_UNPACK_BUFFER GL_PIXEL_UNPACK_BUFFER_ARB -#endif - -#ifndef GL_PIXEL_PACK_BUFFER -#define GL_PIXEL_PACK_BUFFER GL_PIXEL_PACK_BUFFER_ARB -#endif - -#endif - static void _cogl_pixel_buffer_free (CoglPixelBuffer *buffer); -- GitLab