kathenas / rpms / mutter

Forked from rpms/mutter 5 years ago
Clone

Blame SOURCES/0001-cogl-add-new-UNSTABLE_TEXTURES-feature.patch

776610
From bac385833fddb5dadb3be1eaf7b6071991c4b048 Mon Sep 17 00:00:00 2001
776610
From: Ray Strode <rstrode@redhat.com>
776610
Date: Tue, 15 Jan 2019 11:01:38 -0500
776610
Subject: [PATCH 1/9] cogl: add new UNSTABLE_TEXTURES feature
776610
776610
The proprietary nvidia driver garbles texture memory on suspend.
776610
776610
Before we can address that, we need to be able to detect it.
776610
776610
This commit adds a new UNSTABLE_TEXTURES feature that gets set if
776610
the proprietary nvidia driver is in use.
776610
---
776610
 cogl/cogl/cogl-context.h           |  1 +
776610
 cogl/cogl/cogl-types.h             |  5 ++++-
776610
 cogl/cogl/winsys/cogl-winsys-egl.c | 11 +++++++++++
776610
 cogl/cogl/winsys/cogl-winsys-glx.c | 13 +++++++++++--
776610
 4 files changed, 27 insertions(+), 3 deletions(-)
776610
776610
diff --git a/cogl/cogl/cogl-context.h b/cogl/cogl/cogl-context.h
776610
index add575b49..985ce336d 100644
776610
--- a/cogl/cogl/cogl-context.h
776610
+++ b/cogl/cogl/cogl-context.h
776610
@@ -236,60 +236,61 @@ cogl_is_context (void *object);
776610
  * Since: 1.10
776610
  */
776610
 typedef enum _CoglFeatureID
776610
 {
776610
   COGL_FEATURE_ID_TEXTURE_NPOT_BASIC = 1,
776610
   COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP,
776610
   COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT,
776610
   COGL_FEATURE_ID_TEXTURE_NPOT,
776610
   COGL_FEATURE_ID_TEXTURE_RECTANGLE,
776610
   COGL_FEATURE_ID_TEXTURE_3D,
776610
   COGL_FEATURE_ID_GLSL,
776610
   COGL_FEATURE_ID_ARBFP,
776610
   COGL_FEATURE_ID_OFFSCREEN,
776610
   COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE,
776610
   COGL_FEATURE_ID_ONSCREEN_MULTIPLE,
776610
   COGL_FEATURE_ID_UNSIGNED_INT_INDICES,
776610
   COGL_FEATURE_ID_DEPTH_RANGE,
776610
   COGL_FEATURE_ID_POINT_SPRITE,
776610
   COGL_FEATURE_ID_MAP_BUFFER_FOR_READ,
776610
   COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE,
776610
   COGL_FEATURE_ID_MIRRORED_REPEAT,
776610
   COGL_FEATURE_ID_SWAP_BUFFERS_EVENT,
776610
   COGL_FEATURE_ID_GLES2_CONTEXT,
776610
   COGL_FEATURE_ID_DEPTH_TEXTURE,
776610
   COGL_FEATURE_ID_PRESENTATION_TIME,
776610
   COGL_FEATURE_ID_FENCE,
776610
   COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE,
776610
   COGL_FEATURE_ID_TEXTURE_RG,
776610
   COGL_FEATURE_ID_BUFFER_AGE,
776610
   COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL,
776610
+  COGL_FEATURE_ID_UNSTABLE_TEXTURES,
776610
 
776610
   /*< private >*/
776610
   _COGL_N_FEATURE_IDS   /*< skip >*/
776610
 } CoglFeatureID;
776610
 
776610
 
776610
 /**
776610
  * cogl_has_feature:
776610
  * @context: A #CoglContext pointer
776610
  * @feature: A #CoglFeatureID
776610
  *
776610
  * Checks if a given @feature is currently available
776610
  *
776610
  * Cogl does not aim to be a lowest common denominator API, it aims to
776610
  * expose all the interesting features of GPUs to application which
776610
  * means applications have some responsibility to explicitly check
776610
  * that certain features are available before depending on them.
776610
  *
776610
  * Returns: %TRUE if the @feature is currently supported or %FALSE if
776610
  * not.
776610
  *
776610
  * Since: 1.10
776610
  * Stability: unstable
776610
  */
776610
 CoglBool
776610
 cogl_has_feature (CoglContext *context, CoglFeatureID feature);
776610
 
776610
 /**
776610
  * cogl_has_features:
776610
  * @context: A #CoglContext pointer
776610
diff --git a/cogl/cogl/cogl-types.h b/cogl/cogl/cogl-types.h
776610
index f67895dd9..8338e284d 100644
776610
--- a/cogl/cogl/cogl-types.h
776610
+++ b/cogl/cogl/cogl-types.h
776610
@@ -371,91 +371,94 @@ typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
776610
  * @COGL_FEATURE_OFFSCREEN_MULTISAMPLE: Multisample support on FBOs
776610
  * @COGL_FEATURE_OFFSCREEN_BLIT: Blit support on FBOs
776610
  * @COGL_FEATURE_FOUR_CLIP_PLANES: At least 4 clip planes available
776610
  * @COGL_FEATURE_STENCIL_BUFFER: Stencil buffer support
776610
  * @COGL_FEATURE_VBOS: VBO support
776610
  * @COGL_FEATURE_PBOS: PBO support
776610
  * @COGL_FEATURE_UNSIGNED_INT_INDICES: Set if
776610
  *     %COGL_INDICES_TYPE_UNSIGNED_INT is supported in
776610
  *     cogl_vertex_buffer_indices_new().
776610
  * @COGL_FEATURE_DEPTH_RANGE: cogl_material_set_depth_range() support
776610
  * @COGL_FEATURE_TEXTURE_NPOT_BASIC: The hardware supports non power
776610
  *     of two textures, but you also need to check the
776610
  *     %COGL_FEATURE_TEXTURE_NPOT_MIPMAP and %COGL_FEATURE_TEXTURE_NPOT_REPEAT
776610
  *     features to know if the hardware supports npot texture mipmaps
776610
  *     or repeat modes other than
776610
  *     %COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE respectively.
776610
  * @COGL_FEATURE_TEXTURE_NPOT_MIPMAP: Mipmapping is supported in
776610
  *     conjuntion with non power of two textures.
776610
  * @COGL_FEATURE_TEXTURE_NPOT_REPEAT: Repeat modes other than
776610
  *     %COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE are supported by the
776610
  *     hardware.
776610
  * @COGL_FEATURE_POINT_SPRITE: Whether
776610
  *     cogl_material_set_layer_point_sprite_coords_enabled() is supported.
776610
  * @COGL_FEATURE_TEXTURE_3D: 3D texture support
776610
  * @COGL_FEATURE_MAP_BUFFER_FOR_READ: Whether cogl_buffer_map() is
776610
  *     supported with CoglBufferAccess including read support.
776610
  * @COGL_FEATURE_MAP_BUFFER_FOR_WRITE: Whether cogl_buffer_map() is
776610
  *     supported with CoglBufferAccess including write support.
776610
  * @COGL_FEATURE_DEPTH_TEXTURE: Whether #CoglFramebuffer support rendering the
776610
  *     depth buffer to a texture.
776610
+ * @COGL_FEATURE_UNSTABLE_TEXTURES: Whether textures require redrawing on
776610
+ *     resume or not.
776610
  *
776610
  * Flags for the supported features.
776610
  *
776610
  * Since: 0.8
776610
  */
776610
 typedef enum
776610
 {
776610
   COGL_FEATURE_TEXTURE_RECTANGLE      = (1 << 1),
776610
   COGL_FEATURE_TEXTURE_NPOT           = (1 << 2),
776610
   COGL_FEATURE_TEXTURE_YUV            = (1 << 3),
776610
   COGL_FEATURE_TEXTURE_READ_PIXELS    = (1 << 4),
776610
   COGL_FEATURE_SHADERS_GLSL           = (1 << 5),
776610
   COGL_FEATURE_OFFSCREEN              = (1 << 6),
776610
   COGL_FEATURE_OFFSCREEN_MULTISAMPLE  = (1 << 7),
776610
   COGL_FEATURE_OFFSCREEN_BLIT         = (1 << 8),
776610
   COGL_FEATURE_FOUR_CLIP_PLANES       = (1 << 9),
776610
   COGL_FEATURE_STENCIL_BUFFER         = (1 << 10),
776610
   COGL_FEATURE_VBOS		      = (1 << 11),
776610
   COGL_FEATURE_PBOS		      = (1 << 12),
776610
   COGL_FEATURE_UNSIGNED_INT_INDICES   = (1 << 13),
776610
   COGL_FEATURE_DEPTH_RANGE            = (1 << 14),
776610
   COGL_FEATURE_TEXTURE_NPOT_BASIC     = (1 << 15),
776610
   COGL_FEATURE_TEXTURE_NPOT_MIPMAP    = (1 << 16),
776610
   COGL_FEATURE_TEXTURE_NPOT_REPEAT    = (1 << 17),
776610
   COGL_FEATURE_POINT_SPRITE           = (1 << 18),
776610
   COGL_FEATURE_TEXTURE_3D             = (1 << 19),
776610
   COGL_FEATURE_SHADERS_ARBFP          = (1 << 20),
776610
   COGL_FEATURE_MAP_BUFFER_FOR_READ    = (1 << 21),
776610
   COGL_FEATURE_MAP_BUFFER_FOR_WRITE   = (1 << 22),
776610
   COGL_FEATURE_ONSCREEN_MULTIPLE      = (1 << 23),
776610
-  COGL_FEATURE_DEPTH_TEXTURE          = (1 << 24)
776610
+  COGL_FEATURE_DEPTH_TEXTURE          = (1 << 24),
776610
+  COGL_FEATURE_UNSTABLE_TEXTURES      = (1 << 25)
776610
 } CoglFeatureFlags;
776610
 
776610
 /**
776610
  * CoglBufferTarget:
776610
  * @COGL_WINDOW_BUFFER: FIXME
776610
  * @COGL_OFFSCREEN_BUFFER: FIXME
776610
  *
776610
  * Target flags for FBOs.
776610
  *
776610
  * Since: 0.8
776610
  */
776610
 typedef enum
776610
 {
776610
   COGL_WINDOW_BUFFER      = (1 << 1),
776610
   COGL_OFFSCREEN_BUFFER   = (1 << 2)
776610
 } CoglBufferTarget;
776610
 
776610
 /**
776610
  * CoglColor:
776610
  * @red: amount of red
776610
  * @green: amount of green
776610
  * @blue: amount of green
776610
  * @alpha: alpha
776610
  *
776610
  * A structure for holding a color definition. The contents of
776610
  * the CoglColor structure are private and should never by accessed
776610
  * directly.
776610
  *
776610
  * Since: 1.0
776610
  */
776610
diff --git a/cogl/cogl/winsys/cogl-winsys-egl.c b/cogl/cogl/winsys/cogl-winsys-egl.c
776610
index 73648f663..66c2661b3 100644
776610
--- a/cogl/cogl/winsys/cogl-winsys-egl.c
776610
+++ b/cogl/cogl/winsys/cogl-winsys-egl.c
776610
@@ -475,72 +475,83 @@ _cogl_winsys_display_setup (CoglDisplay *display,
776610
       CoglRendererEGL *egl_renderer = display->renderer->winsys;
776610
 
776610
       if (egl_renderer->pf_eglBindWaylandDisplay)
776610
 	egl_renderer->pf_eglBindWaylandDisplay (egl_renderer->edpy,
776610
 						wayland_display);
776610
     }
776610
 #endif
776610
 
776610
   if (egl_renderer->platform_vtable->display_setup &&
776610
       !egl_renderer->platform_vtable->display_setup (display, error))
776610
     goto error;
776610
 
776610
   if (!try_create_context (display, error))
776610
     goto error;
776610
 
776610
   egl_display->found_egl_config = TRUE;
776610
 
776610
   return TRUE;
776610
 
776610
 error:
776610
   _cogl_winsys_display_destroy (display);
776610
   return FALSE;
776610
 }
776610
 
776610
 static CoglBool
776610
 _cogl_winsys_context_init (CoglContext *context, CoglError **error)
776610
 {
776610
   CoglRenderer *renderer = context->display->renderer;
776610
   CoglDisplayEGL *egl_display = context->display->winsys;
776610
   CoglRendererEGL *egl_renderer = renderer->winsys;
776610
+  CoglGpuInfo *info;
776610
 
776610
   context->winsys = g_new0 (CoglContextEGL, 1);
776610
 
776610
   _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE);
776610
 
776610
   memset (context->winsys_features, 0, sizeof (context->winsys_features));
776610
 
776610
   check_egl_extensions (renderer);
776610
 
776610
   if (!_cogl_context_update_features (context, error))
776610
     return FALSE;
776610
 
776610
+  info = &context->gpu;
776610
+
776610
+  if (info->vendor == COGL_GPU_INFO_VENDOR_NVIDIA)
776610
+    {
776610
+      context->feature_flags |= COGL_FEATURE_UNSTABLE_TEXTURES;
776610
+      COGL_FLAGS_SET (context->features,
776610
+                      COGL_FEATURE_ID_UNSTABLE_TEXTURES,
776610
+                      TRUE);
776610
+    }
776610
+
776610
   if (egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_SWAP_REGION)
776610
     {
776610
       COGL_FLAGS_SET (context->winsys_features,
776610
                       COGL_WINSYS_FEATURE_SWAP_REGION, TRUE);
776610
       COGL_FLAGS_SET (context->winsys_features,
776610
                       COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE);
776610
     }
776610
 
776610
   if ((egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_FENCE_SYNC) &&
776610
       _cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_OES_EGL_SYNC))
776610
     COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_FENCE, TRUE);
776610
 
776610
   if (egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_BUFFER_AGE)
776610
     {
776610
       COGL_FLAGS_SET (context->winsys_features,
776610
                       COGL_WINSYS_FEATURE_BUFFER_AGE,
776610
                       TRUE);
776610
       COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_BUFFER_AGE, TRUE);
776610
     }
776610
 
776610
   /* NB: We currently only support creating standalone GLES2 contexts
776610
    * for offscreen rendering and so we need a dummy (non-visible)
776610
    * surface to be able to bind those contexts */
776610
   if (egl_display->dummy_surface != EGL_NO_SURFACE &&
776610
       context->driver == COGL_DRIVER_GLES2)
776610
     COGL_FLAGS_SET (context->features,
776610
                     COGL_FEATURE_ID_GLES2_CONTEXT, TRUE);
776610
 
776610
   if (egl_renderer->platform_vtable->context_init &&
776610
       !egl_renderer->platform_vtable->context_init (context, error))
776610
diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
776610
index 74b0895d1..4a033c0c6 100644
776610
--- a/cogl/cogl/winsys/cogl-winsys-glx.c
776610
+++ b/cogl/cogl/winsys/cogl-winsys-glx.c
776610
@@ -805,149 +805,158 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
776610
   /* XXX: Note: For a long time Mesa exported a hybrid GLX, exporting
776610
    * extensions specified to require GLX 1.3, but still reporting 1.2
776610
    * via glXQueryVersion. */
776610
   if (!glx_renderer->glXQueryVersion (xlib_renderer->xdpy,
776610
                                       &glx_renderer->glx_major,
776610
                                       &glx_renderer->glx_minor)
776610
       || !(glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 2))
776610
     {
776610
       _cogl_set_error (error, COGL_WINSYS_ERROR,
776610
                    COGL_WINSYS_ERROR_INIT,
776610
                    "XServer appears to lack required GLX 1.2 support");
776610
       goto error;
776610
     }
776610
 
776610
   update_base_winsys_features (renderer);
776610
 
776610
   glx_renderer->dri_fd = -1;
776610
 
776610
   return TRUE;
776610
 
776610
 error:
776610
   _cogl_winsys_renderer_disconnect (renderer);
776610
   return FALSE;
776610
 }
776610
 
776610
 static CoglBool
776610
 update_winsys_features (CoglContext *context, CoglError **error)
776610
 {
776610
   CoglGLXDisplay *glx_display = context->display->winsys;
776610
   CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
776610
+  CoglGpuInfo *info;
776610
 
776610
   _COGL_RETURN_VAL_IF_FAIL (glx_display->glx_context, FALSE);
776610
 
776610
   if (!_cogl_context_update_features (context, error))
776610
     return FALSE;
776610
 
776610
+  info = &context->gpu;
776610
+
776610
   memcpy (context->winsys_features,
776610
           glx_renderer->base_winsys_features,
776610
           sizeof (context->winsys_features));
776610
 
776610
   context->feature_flags |= glx_renderer->legacy_feature_flags;
776610
 
776610
   context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE;
776610
   COGL_FLAGS_SET (context->features,
776610
                   COGL_FEATURE_ID_ONSCREEN_MULTIPLE, TRUE);
776610
 
776610
   if (glx_renderer->glXCopySubBuffer || context->glBlitFramebuffer)
776610
     {
776610
-      CoglGpuInfo *info = &context->gpu;
776610
       CoglGpuInfoArchitecture arch = info->architecture;
776610
 
776610
       COGL_FLAGS_SET (context->winsys_features, COGL_WINSYS_FEATURE_SWAP_REGION, TRUE);
776610
 
776610
       /*
776610
        * "The "drisw" binding in Mesa for loading sofware renderers is
776610
        * broken, and neither glBlitFramebuffer nor glXCopySubBuffer
776610
        * work correctly."
776610
        * - ajax
776610
        * - https://bugzilla.gnome.org/show_bug.cgi?id=674208
776610
        *
776610
        * This is broken in software Mesa at least as of 7.10 and got
776610
        * fixed in Mesa 10.1
776610
        */
776610
 
776610
       if (info->driver_package == COGL_GPU_INFO_DRIVER_PACKAGE_MESA &&
776610
           info->driver_package_version < COGL_VERSION_ENCODE (10, 1, 0) &&
776610
           (arch == COGL_GPU_INFO_ARCHITECTURE_LLVMPIPE ||
776610
            arch == COGL_GPU_INFO_ARCHITECTURE_SOFTPIPE ||
776610
            arch == COGL_GPU_INFO_ARCHITECTURE_SWRAST))
776610
 	{
776610
 	  COGL_FLAGS_SET (context->winsys_features,
776610
 			  COGL_WINSYS_FEATURE_SWAP_REGION, FALSE);
776610
 	}
776610
     }
776610
 
776610
   /* Note: glXCopySubBuffer and glBlitFramebuffer won't be throttled
776610
    * by the SwapInterval so we have to throttle swap_region requests
776610
    * manually... */
776610
   if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION) &&
776610
       (glx_display->have_vblank_counter || glx_display->can_vblank_wait))
776610
     COGL_FLAGS_SET (context->winsys_features,
776610
                     COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE);
776610
 
776610
   if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT))
776610
     {
776610
       COGL_FLAGS_SET (context->winsys_features,
776610
 		      COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT, TRUE);
776610
       /* TODO: remove this deprecated feature */
776610
       COGL_FLAGS_SET (context->features,
776610
                       COGL_FEATURE_ID_SWAP_BUFFERS_EVENT,
776610
                       TRUE);
776610
       COGL_FLAGS_SET (context->features,
776610
                       COGL_FEATURE_ID_PRESENTATION_TIME,
776610
                       TRUE);
776610
     }
776610
   else
776610
     {
776610
-      CoglGpuInfo *info = &context->gpu;
776610
       if (glx_display->have_vblank_counter &&
776610
 	  context->display->renderer->xlib_enable_threaded_swap_wait &&
776610
 	  info->vendor == COGL_GPU_INFO_VENDOR_NVIDIA)
776610
         {
776610
           COGL_FLAGS_SET (context->winsys_features,
776610
                           COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT, TRUE);
776610
           COGL_FLAGS_SET (context->winsys_features,
776610
                           COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT, TRUE);
776610
           /* TODO: remove this deprecated feature */
776610
           COGL_FLAGS_SET (context->features,
776610
                           COGL_FEATURE_ID_SWAP_BUFFERS_EVENT,
776610
                           TRUE);
776610
           COGL_FLAGS_SET (context->features,
776610
                           COGL_FEATURE_ID_PRESENTATION_TIME,
776610
                           TRUE);
776610
           COGL_FLAGS_SET (context->private_features,
776610
                           COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT,
776610
                           TRUE);
776610
         }
776610
     }
776610
 
776610
+  if (info->vendor == COGL_GPU_INFO_VENDOR_NVIDIA)
776610
+    {
776610
+      context->feature_flags |= COGL_FEATURE_UNSTABLE_TEXTURES;
776610
+      COGL_FLAGS_SET (context->features,
776610
+                      COGL_FEATURE_ID_UNSTABLE_TEXTURES,
776610
+                      TRUE);
776610
+    }
776610
+
776610
   /* We'll manually handle queueing dirty events in response to
776610
    * Expose events from X */
776610
   COGL_FLAGS_SET (context->private_features,
776610
                   COGL_PRIVATE_FEATURE_DIRTY_EVENTS,
776610
                   TRUE);
776610
 
776610
   if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE))
776610
     COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_BUFFER_AGE, TRUE);
776610
 
776610
   return TRUE;
776610
 }
776610
 
776610
 static void
776610
 glx_attributes_from_framebuffer_config (CoglDisplay *display,
776610
                                         CoglFramebufferConfig *config,
776610
                                         int *attributes)
776610
 {
776610
   CoglGLXRenderer *glx_renderer = display->renderer->winsys;
776610
   int i = 0;
776610
 
776610
   attributes[i++] = GLX_DRAWABLE_TYPE;
776610
   attributes[i++] = GLX_WINDOW_BIT;
776610
 
776610
   attributes[i++] = GLX_RENDER_TYPE;
776610
   attributes[i++] = GLX_RGBA_BIT;
776610
 
776610
   attributes[i++] = GLX_DOUBLEBUFFER;
776610
   attributes[i++] = GL_TRUE;
776610
 
776610
   attributes[i++] = GLX_RED_SIZE;
776610
-- 
776610
2.18.1
776610