i965: Do not use purged bo after calling glObjectUnpurgeable
[mesa.git] / src / mesa / drivers / dri / i965 / brw_object_purgeable.c
index 20f66f229c3986c4fa499f776ab55a83af68ce0f..d3dba8c0af06233ddf7058dab35910c2aaf72972 100644 (file)
@@ -100,8 +100,8 @@ intel_render_object_purgeable(struct gl_context * ctx,
    return intel_buffer_purgeable(intel->mt->bo);
 }
 
-static GLenum
-intel_buffer_unpurgeable(drm_intel_bo *buffer)
+static int
+intel_bo_unpurgeable(drm_intel_bo *buffer)
 {
    int retained;
 
@@ -109,7 +109,7 @@ intel_buffer_unpurgeable(drm_intel_bo *buffer)
    if (buffer != NULL)
       retained = drm_intel_bo_madvise(buffer, I915_MADV_WILLNEED);
 
-   return retained ? GL_RETAINED_APPLE : GL_UNDEFINED_APPLE;
+   return retained;
 }
 
 static GLenum
@@ -117,10 +117,20 @@ intel_buffer_object_unpurgeable(struct gl_context * ctx,
                                 struct gl_buffer_object *obj,
                                 GLenum option)
 {
+   struct intel_buffer_object *intel = intel_buffer_object(obj);
+
    (void) ctx;
-   (void) option;
 
-   return intel_buffer_unpurgeable(intel_buffer_object(obj)->buffer);
+   if (!intel->buffer)
+      return GL_UNDEFINED_APPLE;
+
+   if (option == GL_UNDEFINED_APPLE || !intel_bo_unpurgeable(intel->buffer)) {
+      drm_intel_bo_unreference(intel->buffer);
+      intel->buffer = NULL;
+      return GL_UNDEFINED_APPLE;
+   }
+
+   return GL_RETAINED_APPLE;
 }
 
 static GLenum
@@ -131,13 +141,17 @@ intel_texture_object_unpurgeable(struct gl_context * ctx,
    struct intel_texture_object *intel;
 
    (void) ctx;
-   (void) option;
 
    intel = intel_texture_object(obj);
    if (intel->mt == NULL || intel->mt->bo == NULL)
       return GL_UNDEFINED_APPLE;
 
-   return intel_buffer_unpurgeable(intel->mt->bo);
+   if (option == GL_UNDEFINED_APPLE || !intel_bo_unpurgeable(intel->mt->bo)) {
+      intel_miptree_release(&intel->mt);
+      return GL_UNDEFINED_APPLE;
+   }
+
+   return GL_RETAINED_APPLE;
 }
 
 static GLenum
@@ -148,13 +162,17 @@ intel_render_object_unpurgeable(struct gl_context * ctx,
    struct intel_renderbuffer *intel;
 
    (void) ctx;
-   (void) option;
 
    intel = intel_renderbuffer(obj);
    if (intel->mt == NULL)
       return GL_UNDEFINED_APPLE;
 
-   return intel_buffer_unpurgeable(intel->mt->bo);
+   if (option == GL_UNDEFINED_APPLE || !intel_bo_unpurgeable(intel->mt->bo)) {
+      intel_miptree_release(&intel->mt);
+      return GL_UNDEFINED_APPLE;
+   }
+
+   return GL_RETAINED_APPLE;
 }
 
 void