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
39static GLenum
40brw_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
50static GLenum
51brw_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
68static GLenum
69brw_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
85static GLenum
86brw_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
102static int
103brw_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
114static GLenum
115brw_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
135static GLenum
136brw_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
156static GLenum
157brw_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
177void
178brw_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