1 /*
2  * Copyright © 2010 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 /**
25  * @file brw_object_purgeable.c
26  *
27  * The driver implementation of the GL_APPLE_object_purgeable extension.
28  */
29 
30 #include "main/mtypes.h"
31 #include "main/macros.h"
32 #include "main/bufferobj.h"
33 
34 #include "brw_context.h"
35 #include "brw_buffer_objects.h"
36 #include "brw_fbo.h"
37 #include "brw_mipmap_tree.h"
38 
39 static GLenum
brw_buffer_purgeable(struct brw_bo * buffer)40 brw_buffer_purgeable(struct brw_bo *buffer)
41 {
42    int retained = 0;
43 
44    if (buffer != NULL)
45       retained = brw_bo_madvise(buffer, I915_MADV_DONTNEED);
46 
47    return retained ? GL_VOLATILE_APPLE : GL_RELEASED_APPLE;
48 }
49 
50 static GLenum
brw_buffer_object_purgeable(struct gl_context * ctx,struct gl_buffer_object * obj,GLenum option)51 brw_buffer_object_purgeable(struct gl_context * ctx,
52                             struct gl_buffer_object *obj,
53                             GLenum option)
54 {
55    struct brw_buffer_object *intel_obj = brw_buffer_object(obj);
56 
57    if (intel_obj->buffer != NULL)
58       return brw_buffer_purgeable(intel_obj->buffer);
59 
60    if (option == GL_RELEASED_APPLE) {
61       return GL_RELEASED_APPLE;
62    } else {
63       /* XXX Create the buffer and madvise(MADV_DONTNEED)? */
64       return brw_buffer_purgeable(intel_obj->buffer);
65    }
66 }
67 
68 static GLenum
brw_texture_object_purgeable(struct gl_context * ctx,struct gl_texture_object * obj,GLenum option)69 brw_texture_object_purgeable(struct gl_context * ctx,
70                              struct gl_texture_object *obj,
71                              GLenum option)
72 {
73    struct brw_texture_object *intel;
74 
75    (void) ctx;
76    (void) option;
77 
78    intel = brw_texture_object(obj);
79    if (intel->mt == NULL || intel->mt->bo == NULL)
80       return GL_RELEASED_APPLE;
81 
82    return brw_buffer_purgeable(intel->mt->bo);
83 }
84 
85 static GLenum
brw_render_object_purgeable(struct gl_context * ctx,struct gl_renderbuffer * obj,GLenum option)86 brw_render_object_purgeable(struct gl_context * ctx,
87                             struct gl_renderbuffer *obj,
88                             GLenum option)
89 {
90    struct brw_renderbuffer *intel;
91 
92    (void) ctx;
93    (void) option;
94 
95    intel = brw_renderbuffer(obj);
96    if (intel->mt == NULL)
97       return GL_RELEASED_APPLE;
98 
99    return brw_buffer_purgeable(intel->mt->bo);
100 }
101 
102 static int
brw_bo_unpurgeable(struct brw_bo * buffer)103 brw_bo_unpurgeable(struct brw_bo *buffer)
104 {
105    int retained;
106 
107    retained = 0;
108    if (buffer != NULL)
109       retained = brw_bo_madvise(buffer, I915_MADV_WILLNEED);
110 
111    return retained;
112 }
113 
114 static GLenum
brw_buffer_object_unpurgeable(struct gl_context * ctx,struct gl_buffer_object * obj,GLenum option)115 brw_buffer_object_unpurgeable(struct gl_context * ctx,
116                               struct gl_buffer_object *obj,
117                               GLenum option)
118 {
119    struct brw_buffer_object *intel = brw_buffer_object(obj);
120 
121    (void) ctx;
122 
123    if (!intel->buffer)
124       return GL_UNDEFINED_APPLE;
125 
126    if (option == GL_UNDEFINED_APPLE || !brw_bo_unpurgeable(intel->buffer)) {
127       brw_bo_unreference(intel->buffer);
128       intel->buffer = NULL;
129       return GL_UNDEFINED_APPLE;
130    }
131 
132    return GL_RETAINED_APPLE;
133 }
134 
135 static GLenum
brw_texture_object_unpurgeable(struct gl_context * ctx,struct gl_texture_object * obj,GLenum option)136 brw_texture_object_unpurgeable(struct gl_context * ctx,
137                                  struct gl_texture_object *obj,
138                                  GLenum option)
139 {
140    struct brw_texture_object *intel;
141 
142    (void) ctx;
143 
144    intel = brw_texture_object(obj);
145    if (intel->mt == NULL || intel->mt->bo == NULL)
146       return GL_UNDEFINED_APPLE;
147 
148    if (option == GL_UNDEFINED_APPLE || !brw_bo_unpurgeable(intel->mt->bo)) {
149       brw_miptree_release(&intel->mt);
150       return GL_UNDEFINED_APPLE;
151    }
152 
153    return GL_RETAINED_APPLE;
154 }
155 
156 static GLenum
brw_render_object_unpurgeable(struct gl_context * ctx,struct gl_renderbuffer * obj,GLenum option)157 brw_render_object_unpurgeable(struct gl_context * ctx,
158                               struct gl_renderbuffer *obj,
159                               GLenum option)
160 {
161    struct brw_renderbuffer *intel;
162 
163    (void) ctx;
164 
165    intel = brw_renderbuffer(obj);
166    if (intel->mt == NULL)
167       return GL_UNDEFINED_APPLE;
168 
169    if (option == GL_UNDEFINED_APPLE || !brw_bo_unpurgeable(intel->mt->bo)) {
170       brw_miptree_release(&intel->mt);
171       return GL_UNDEFINED_APPLE;
172    }
173 
174    return GL_RETAINED_APPLE;
175 }
176 
177 void
brw_init_object_purgeable_functions(struct dd_function_table * functions)178 brw_init_object_purgeable_functions(struct dd_function_table *functions)
179 {
180    functions->BufferObjectPurgeable = brw_buffer_object_purgeable;
181    functions->TextureObjectPurgeable = brw_texture_object_purgeable;
182    functions->RenderObjectPurgeable = brw_render_object_purgeable;
183 
184    functions->BufferObjectUnpurgeable = brw_buffer_object_unpurgeable;
185    functions->TextureObjectUnpurgeable = brw_texture_object_unpurgeable;
186    functions->RenderObjectUnpurgeable = brw_render_object_unpurgeable;
187 }
188