blob: 67dccdf60061def4549e946c61e6874e05311f66 [file] [log] [blame]
Keith Whitwell6b9e31f2006-11-01 12:03:11 +00001/**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
Eric Anholtf6ca4a32011-03-09 12:54:14 -080028#include <errno.h>
Brian Paulecadb512008-09-18 15:17:05 -060029#include "main/glheader.h"
30#include "main/context.h"
31#include "main/framebuffer.h"
Brian Paulecadb512008-09-18 15:17:05 -060032#include "main/renderbuffer.h"
Kristian Høgsberg2d995882010-02-11 17:18:01 -050033#include "main/hash.h"
Kristian Høgsbergd7322c92010-02-26 14:49:31 -050034#include "main/fbobject.h"
Vinson Lee45a56e42011-01-09 01:25:54 -080035#include "main/mfeatures.h"
Brian Paul6c244b02009-01-26 12:38:46 -070036
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000037#include "utils.h"
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000038#include "xmlpool.h"
39
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000040PUBLIC const char __driConfigOptions[] =
Eric Anholta0e453a2008-01-17 14:23:04 -080041 DRI_CONF_BEGIN
42 DRI_CONF_SECTION_PERFORMANCE
Jesse Barnese9bf3e42008-07-31 11:50:37 -070043 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC)
Eric Anholtfe91c052008-03-05 14:14:54 -080044 /* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
45 * DRI_CONF_BO_REUSE_ALL
46 */
Dave Airlief75843a2008-08-24 17:59:10 +100047 DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1")
Eric Anholtfe91c052008-03-05 14:14:54 -080048 DRI_CONF_DESC_BEGIN(en, "Buffer object reuse")
49 DRI_CONF_ENUM(0, "Disable buffer object reuse")
50 DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects")
51 DRI_CONF_DESC_END
52 DRI_CONF_OPT_END
Eric Anholt1ba96652009-06-03 16:40:20 +000053
Eric Anholt8e7a8d62010-03-03 11:51:51 -080054 DRI_CONF_OPT_BEGIN(texture_tiling, bool, true)
55 DRI_CONF_DESC(en, "Enable texture tiling")
56 DRI_CONF_OPT_END
Eric Anholt1ba96652009-06-03 16:40:20 +000057
Eric Anholtb30dc2c2009-06-09 16:12:43 -070058 DRI_CONF_OPT_BEGIN(early_z, bool, false)
59 DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
60 DRI_CONF_OPT_END
61
Eric Anholta58514c2010-08-17 15:07:22 -070062 DRI_CONF_OPT_BEGIN(fragment_shader, bool, true)
Eric Anholt862a2a52009-07-29 13:00:09 -070063 DRI_CONF_DESC(en, "Enable limited ARB_fragment_shader support on 915/945.")
64 DRI_CONF_OPT_END
65
Eric Anholta0e453a2008-01-17 14:23:04 -080066 DRI_CONF_SECTION_END
67 DRI_CONF_SECTION_QUALITY
68 DRI_CONF_FORCE_S3TC_ENABLE(false)
Michel Dänzeracba9c12008-04-29 18:43:28 +020069 DRI_CONF_ALLOW_LARGE_TEXTURES(2)
Eric Anholta0e453a2008-01-17 14:23:04 -080070 DRI_CONF_SECTION_END
71 DRI_CONF_SECTION_DEBUG
72 DRI_CONF_NO_RAST(false)
Eric Anholt40bc2742009-03-05 17:18:49 -080073 DRI_CONF_ALWAYS_FLUSH_BATCH(false)
Eric Anholtf3687282009-03-05 17:08:36 -080074 DRI_CONF_ALWAYS_FLUSH_CACHE(false)
Eric Anholt81aa5d72009-07-29 13:07:49 -070075
76 DRI_CONF_OPT_BEGIN(stub_occlusion_query, bool, false)
77 DRI_CONF_DESC(en, "Enable stub ARB_occlusion_query support on 915/945.")
78 DRI_CONF_OPT_END
Eric Anholta0e453a2008-01-17 14:23:04 -080079 DRI_CONF_SECTION_END
80DRI_CONF_END;
81
Eric Anholt1e4677a2009-12-26 18:43:20 -080082const GLuint __driNConfigOptions = 11;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000083
Eric Anholtdf9f8912010-12-13 11:02:15 -080084#include "intel_batchbuffer.h"
85#include "intel_buffers.h"
86#include "intel_bufmgr.h"
87#include "intel_chipset.h"
88#include "intel_fbo.h"
Chad Versaceda2816a2011-11-16 14:04:25 -080089#include "intel_mipmap_tree.h"
Eric Anholtdf9f8912010-12-13 11:02:15 -080090#include "intel_screen.h"
91#include "intel_tex.h"
92#include "intel_regions.h"
93
94#include "i915_drm.h"
95
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000096#ifdef USE_NEW_INTERFACE
Eric Anholt85063f12008-02-13 16:08:19 -080097static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000098#endif /*USE_NEW_INTERFACE */
99
Kristian Høgsberg6d487792008-02-14 22:12:51 -0500100static const __DRItexBufferExtension intelTexBufferExtension = {
101 { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
102 intelSetTexBuffer,
Eric Anholt66175aa2009-03-18 12:07:09 -0700103 intelSetTexBuffer2,
Kristian Høgsberg6d487792008-02-14 22:12:51 -0500104};
105
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500106static void
107intelDRI2Flush(__DRIdrawable *drawable)
108{
Eric Anholtdea5e572011-02-14 18:57:49 -0800109 GET_CURRENT_CONTEXT(ctx);
110 struct intel_context *intel = intel_context(ctx);
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500111
112 if (intel->gen < 4)
113 INTEL_FIREVERTICES(intel);
114
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700115 intel->need_throttle = true;
Kristian Høgsberge67c3382010-05-18 21:50:44 -0400116
Chris Wilson8d68a902011-02-10 20:25:51 +0000117 if (intel->batch.used)
118 intel_batchbuffer_flush(intel);
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500119}
120
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500121static const struct __DRI2flushExtensionRec intelFlushExtension = {
122 { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
123 intelDRI2Flush,
Kristian Høgsberge67c3382010-05-18 21:50:44 -0400124 dri2InvalidateDrawable,
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500125};
126
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500127static __DRIimage *
Kristian Høgsberg9ec0b2a2010-09-22 15:07:15 -0400128intel_create_image_from_name(__DRIscreen *screen,
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500129 int width, int height, int format,
130 int name, int pitch, void *loaderPrivate)
131{
George Sapountzis875a7572011-11-03 13:04:57 +0200132 struct intel_screen *intelScreen = screen->driverPrivate;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500133 __DRIimage *image;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500134 int cpp;
135
136 image = CALLOC(sizeof *image);
137 if (image == NULL)
138 return NULL;
139
140 switch (format) {
141 case __DRI_IMAGE_FORMAT_RGB565:
142 image->format = MESA_FORMAT_RGB565;
143 image->internal_format = GL_RGB;
144 image->data_type = GL_UNSIGNED_BYTE;
145 break;
146 case __DRI_IMAGE_FORMAT_XRGB8888:
147 image->format = MESA_FORMAT_XRGB8888;
148 image->internal_format = GL_RGB;
149 image->data_type = GL_UNSIGNED_BYTE;
150 break;
151 case __DRI_IMAGE_FORMAT_ARGB8888:
152 image->format = MESA_FORMAT_ARGB8888;
153 image->internal_format = GL_RGBA;
154 image->data_type = GL_UNSIGNED_BYTE;
155 break;
Chia-I Wu9fe197c2011-08-21 21:36:40 +0800156 case __DRI_IMAGE_FORMAT_ABGR8888:
157 image->format = MESA_FORMAT_RGBA8888_REV;
158 image->internal_format = GL_RGBA;
159 image->data_type = GL_UNSIGNED_BYTE;
160 break;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500161 default:
162 free(image);
163 return NULL;
164 }
165
166 image->data = loaderPrivate;
167 cpp = _mesa_get_format_bytes(image->format);
168
Kristian Høgsberg9ec0b2a2010-09-22 15:07:15 -0400169 image->region = intel_region_alloc_for_handle(intelScreen,
Kristian Høgsberg9087ba12010-06-03 21:56:21 -0400170 cpp, width, height,
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500171 pitch, name, "image");
172 if (image->region == NULL) {
173 FREE(image);
174 return NULL;
175 }
176
177 return image;
178}
179
180static __DRIimage *
181intel_create_image_from_renderbuffer(__DRIcontext *context,
182 int renderbuffer, void *loaderPrivate)
183{
184 __DRIimage *image;
185 struct intel_context *intel = context->driverPrivate;
186 struct gl_renderbuffer *rb;
187 struct intel_renderbuffer *irb;
188
Kristian Høgsbergd7322c92010-02-26 14:49:31 -0500189 rb = _mesa_lookup_renderbuffer(&intel->ctx, renderbuffer);
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500190 if (!rb) {
191 _mesa_error(&intel->ctx,
192 GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
193 return NULL;
194 }
195
196 irb = intel_renderbuffer(rb);
197 image = CALLOC(sizeof *image);
198 if (image == NULL)
199 return NULL;
200
201 image->internal_format = rb->InternalFormat;
202 image->format = rb->Format;
203 image->data_type = rb->DataType;
204 image->data = loaderPrivate;
Chad Versaceda2816a2011-11-16 14:04:25 -0800205 intel_region_reference(&image->region, irb->mt->region);
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500206
207 return image;
208}
209
210static void
211intel_destroy_image(__DRIimage *image)
212{
213 intel_region_release(&image->region);
214 FREE(image);
215}
216
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400217static __DRIimage *
218intel_create_image(__DRIscreen *screen,
219 int width, int height, int format,
220 unsigned int use,
221 void *loaderPrivate)
222{
223 __DRIimage *image;
George Sapountzis875a7572011-11-03 13:04:57 +0200224 struct intel_screen *intelScreen = screen->driverPrivate;
Kristian Høgsberge5169e92011-05-06 10:31:18 -0400225 uint32_t tiling;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400226 int cpp;
227
Kristian Høgsberge5169e92011-05-06 10:31:18 -0400228 tiling = I915_TILING_X;
229 if (use & __DRI_IMAGE_USE_CURSOR) {
230 if (width != 64 || height != 64)
231 return NULL;
232 tiling = I915_TILING_NONE;
233 }
234
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400235 image = CALLOC(sizeof *image);
236 if (image == NULL)
237 return NULL;
238
239 switch (format) {
240 case __DRI_IMAGE_FORMAT_RGB565:
241 image->format = MESA_FORMAT_RGB565;
242 image->internal_format = GL_RGB;
243 image->data_type = GL_UNSIGNED_BYTE;
244 break;
245 case __DRI_IMAGE_FORMAT_XRGB8888:
246 image->format = MESA_FORMAT_XRGB8888;
247 image->internal_format = GL_RGB;
248 image->data_type = GL_UNSIGNED_BYTE;
249 break;
250 case __DRI_IMAGE_FORMAT_ARGB8888:
251 image->format = MESA_FORMAT_ARGB8888;
252 image->internal_format = GL_RGBA;
253 image->data_type = GL_UNSIGNED_BYTE;
254 break;
Chia-I Wu9fe197c2011-08-21 21:36:40 +0800255 case __DRI_IMAGE_FORMAT_ABGR8888:
256 image->format = MESA_FORMAT_RGBA8888_REV;
257 image->internal_format = GL_RGBA;
258 image->data_type = GL_UNSIGNED_BYTE;
259 break;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400260 default:
261 free(image);
262 return NULL;
263 }
264
265 image->data = loaderPrivate;
266 cpp = _mesa_get_format_bytes(image->format);
267
268 image->region =
Kristian Høgsberge5169e92011-05-06 10:31:18 -0400269 intel_region_alloc(intelScreen, tiling,
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700270 cpp, width, height, true);
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400271 if (image->region == NULL) {
272 FREE(image);
273 return NULL;
274 }
275
276 return image;
277}
278
279static GLboolean
280intel_query_image(__DRIimage *image, int attrib, int *value)
281{
282 switch (attrib) {
283 case __DRI_IMAGE_ATTRIB_STRIDE:
284 *value = image->region->pitch * image->region->cpp;
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700285 return true;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400286 case __DRI_IMAGE_ATTRIB_HANDLE:
Eric Anholt8004a1c2011-09-22 11:58:37 -0700287 *value = image->region->bo->handle;
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700288 return true;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400289 case __DRI_IMAGE_ATTRIB_NAME:
290 return intel_region_flink(image->region, (uint32_t *) value);
291 default:
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700292 return false;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400293 }
294}
295
Benjamin Franzke3af3c582011-03-09 20:56:02 +0100296static __DRIimage *
297intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
298{
299 __DRIimage *image;
300
301 image = CALLOC(sizeof *image);
302 if (image == NULL)
303 return NULL;
304
Benjamin Franzke3af3c582011-03-09 20:56:02 +0100305 intel_region_reference(&image->region, orig_image->region);
306 if (image->region == NULL) {
307 FREE(image);
308 return NULL;
309 }
310
311 image->internal_format = orig_image->internal_format;
312 image->format = orig_image->format;
313 image->data_type = orig_image->data_type;
314 image->data = loaderPrivate;
315
316 return image;
317}
318
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500319static struct __DRIimageExtensionRec intelImageExtension = {
320 { __DRI_IMAGE, __DRI_IMAGE_VERSION },
321 intel_create_image_from_name,
322 intel_create_image_from_renderbuffer,
323 intel_destroy_image,
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400324 intel_create_image,
Benjamin Franzke3af3c582011-03-09 20:56:02 +0100325 intel_query_image,
326 intel_dup_image
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500327};
328
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400329static const __DRIextension *intelScreenExtensions[] = {
Kristian Høgsberg6d487792008-02-14 22:12:51 -0500330 &intelTexBufferExtension.base,
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500331 &intelFlushExtension.base,
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500332 &intelImageExtension.base,
Jesse Barnes234286c2010-04-22 12:47:41 -0700333 &dri2ConfigQueryExtension.base,
Kristian Høgsbergac3e8382007-05-15 15:17:30 -0400334 NULL
335};
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000336
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700337static bool
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500338intel_get_param(__DRIscreen *psp, int param, int *value)
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500339{
340 int ret;
Alan Hourihane1c718c02008-02-22 00:18:54 +0000341 struct drm_i915_getparam gp;
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500342
343 gp.param = param;
344 gp.value = value;
345
Alan Hourihane1c718c02008-02-22 00:18:54 +0000346 ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500347 if (ret) {
Eric Anholtf6ca4a32011-03-09 12:54:14 -0800348 if (ret != -EINVAL)
349 _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700350 return false;
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500351 }
352
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700353 return true;
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500354}
Kristian Høgsbergac3e8382007-05-15 15:17:30 -0400355
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700356static bool
Chris Wilson900a5c92011-03-01 14:46:50 +0000357intel_get_boolean(__DRIscreen *psp, int param)
358{
359 int value = 0;
360 return intel_get_param(psp, param, &value) && value;
361}
362
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000363static void
Kristian Høgsberg2d995882010-02-11 17:18:01 -0500364nop_callback(GLuint key, void *data, void *userData)
365{
366}
367
368static void
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500369intelDestroyScreen(__DRIscreen * sPriv)
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000370{
George Sapountzis875a7572011-11-03 13:04:57 +0200371 struct intel_screen *intelScreen = sPriv->driverPrivate;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000372
Eric Anholt904f31a2008-09-16 17:01:06 -0700373 dri_bufmgr_destroy(intelScreen->bufmgr);
Eric Anholt6d66f232009-07-02 13:30:20 -0700374 driDestroyOptionInfo(&intelScreen->optionCache);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000375
Kristian Høgsberg2d995882010-02-11 17:18:01 -0500376 /* Some regions may still have references to them at this point, so
377 * flush the hash table to prevent _mesa_DeleteHashTable() from
378 * complaining about the hash not being empty; */
379 _mesa_HashDeleteAll(intelScreen->named_regions, nop_callback, NULL);
380 _mesa_DeleteHashTable(intelScreen->named_regions);
381
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000382 FREE(intelScreen);
George Sapountzis875a7572011-11-03 13:04:57 +0200383 sPriv->driverPrivate = NULL;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000384}
385
386
387/**
388 * This is called when we need to set up GL rendering to a new X window.
389 */
390static GLboolean
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500391intelCreateBuffer(__DRIscreen * driScrnPriv,
392 __DRIdrawable * driDrawPriv,
Kristian Høgsbergd3491e72010-10-12 11:58:47 -0400393 const struct gl_config * mesaVis, GLboolean isPixmap)
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000394{
Kristian Høgsbergd2821282010-01-01 23:21:16 -0500395 struct intel_renderbuffer *rb;
George Sapountzis875a7572011-11-03 13:04:57 +0200396 struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate;
Kristian Høgsbergd2821282010-01-01 23:21:16 -0500397
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000398 if (isPixmap) {
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700399 return false; /* not implemented */
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000400 }
401 else {
Brian Paul4a253432009-10-29 19:12:50 -0600402 gl_format rgbFormat;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000403
Kristian Høgsbergd2821282010-01-01 23:21:16 -0500404 struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer);
Michel Dänzer6b99caf2007-02-15 16:30:40 +0100405
Kristian Høgsbergd2821282010-01-01 23:21:16 -0500406 if (!fb)
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700407 return false;
Michel Dänzer6b99caf2007-02-15 16:30:40 +0100408
Francisco Jerez2ec50d22010-02-03 03:21:04 -0800409 _mesa_initialize_window_framebuffer(fb, mesaVis);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000410
Eric Anholt119f34e2009-02-25 22:54:51 -0800411 if (mesaVis->redBits == 5)
Brian Paul4a253432009-10-29 19:12:50 -0600412 rgbFormat = MESA_FORMAT_RGB565;
Eric Anholt119f34e2009-02-25 22:54:51 -0800413 else if (mesaVis->alphaBits == 0)
Brian Paul409469f2009-10-30 09:12:11 -0600414 rgbFormat = MESA_FORMAT_XRGB8888;
Eric Anholt119f34e2009-02-25 22:54:51 -0800415 else
Brian Paul4a253432009-10-29 19:12:50 -0600416 rgbFormat = MESA_FORMAT_ARGB8888;
Eric Anholt119f34e2009-02-25 22:54:51 -0800417
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000418 /* setup the hardware-based renderbuffers */
Kristian Høgsbergd2821282010-01-01 23:21:16 -0500419 rb = intel_create_renderbuffer(rgbFormat);
420 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000421
422 if (mesaVis->doubleBufferMode) {
Kristian Høgsbergd2821282010-01-01 23:21:16 -0500423 rb = intel_create_renderbuffer(rgbFormat);
424 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000425 }
426
Chad Versacef4efb7f2011-05-26 14:55:54 -0700427 /*
428 * Assert here that the gl_config has an expected depth/stencil bit
429 * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
430 * which constructs the advertised configs.)
431 */
Eric Anholt38c61622007-11-08 14:49:37 -0800432 if (mesaVis->depthBits == 24) {
Eric Anholt800a4b22010-03-16 12:59:59 -0700433 assert(mesaVis->stencilBits == 8);
Chad Versaceaea22362011-06-03 16:33:32 -0700434
435 if (screen->hw_has_separate_stencil
436 && screen->dri2_has_hiz != INTEL_DRI2_HAS_HIZ_FALSE) {
437 /*
438 * Request a separate stencil buffer even if we do not yet know if
439 * the screen supports it. (See comments for
440 * enum intel_dri2_has_hiz).
441 */
442 rb = intel_create_renderbuffer(MESA_FORMAT_X8_Z24);
443 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base);
444 rb = intel_create_renderbuffer(MESA_FORMAT_S8);
445 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base);
446 } else {
447 /*
448 * Use combined depth/stencil. Note that the renderbuffer is
449 * attached to two attachment points.
450 */
451 rb = intel_create_renderbuffer(MESA_FORMAT_S8_Z24);
452 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base);
453 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base);
454 }
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000455 }
456 else if (mesaVis->depthBits == 16) {
Chad Versacef4efb7f2011-05-26 14:55:54 -0700457 assert(mesaVis->stencilBits == 0);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000458 /* just 16-bit depth buffer, no hw stencil */
459 struct intel_renderbuffer *depthRb
Brian Paul4a253432009-10-29 19:12:50 -0600460 = intel_create_renderbuffer(MESA_FORMAT_Z16);
Kristian Høgsbergd2821282010-01-01 23:21:16 -0500461 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000462 }
Chad Versacef4efb7f2011-05-26 14:55:54 -0700463 else {
464 assert(mesaVis->depthBits == 0);
465 assert(mesaVis->stencilBits == 0);
466 }
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000467
468 /* now add any/all software-based renderbuffers we may need */
Kristian Høgsbergd2821282010-01-01 23:21:16 -0500469 _mesa_add_soft_renderbuffers(fb,
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700470 false, /* never sw color */
471 false, /* never sw depth */
472 false, /* never sw stencil */
Chad Versacef4efb7f2011-05-26 14:55:54 -0700473 mesaVis->accumRedBits > 0,
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700474 false, /* never sw alpha */
475 false /* never sw aux */ );
Kristian Høgsbergd2821282010-01-01 23:21:16 -0500476 driDrawPriv->driverPrivate = fb;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000477
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700478 return true;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000479 }
480}
481
482static void
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500483intelDestroyBuffer(__DRIdrawable * driDrawPriv)
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000484{
Kristian Høgsbergd2821282010-01-01 23:21:16 -0500485 struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
486
487 _mesa_reference_framebuffer(&fb, NULL);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000488}
489
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000490/* There are probably better ways to do this, such as an
491 * init-designated function to register chipids and createcontext
492 * functions.
493 */
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700494extern bool
495i830CreateContext(const struct gl_config *mesaVis,
496 __DRIcontext *driContextPriv,
497 void *sharedContextPrivate);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000498
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700499extern bool
500i915CreateContext(int api,
501 const struct gl_config *mesaVis,
502 __DRIcontext *driContextPriv,
503 void *sharedContextPrivate);
504extern bool
505brwCreateContext(int api,
506 const struct gl_config *mesaVis,
507 __DRIcontext *driContextPriv,
508 void *sharedContextPrivate);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000509
510static GLboolean
Kristian Høgsberga7a9a912010-04-27 11:04:51 -0400511intelCreateContext(gl_api api,
Kristian Høgsbergd3491e72010-10-12 11:58:47 -0400512 const struct gl_config * mesaVis,
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500513 __DRIcontext * driContextPriv,
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000514 void *sharedContextPrivate)
515{
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500516 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
George Sapountzis875a7572011-11-03 13:04:57 +0200517 struct intel_screen *intelScreen = sPriv->driverPrivate;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000518
Eric Anholtbea6b5f2007-12-20 11:29:39 -0800519#ifdef I915
Eric Anholt19420e62008-02-15 13:16:01 -0800520 if (IS_9XX(intelScreen->deviceID)) {
521 if (!IS_965(intelScreen->deviceID)) {
Kristian Høgsberg4b691002010-04-27 11:04:51 -0400522 return i915CreateContext(api, mesaVis, driContextPriv,
Eric Anholtbea6b5f2007-12-20 11:29:39 -0800523 sharedContextPrivate);
Eric Anholt19420e62008-02-15 13:16:01 -0800524 }
Eric Anholtbea6b5f2007-12-20 11:29:39 -0800525 } else {
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700526 intelScreen->no_vbo = true;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000527 return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000528 }
Eric Anholtbea6b5f2007-12-20 11:29:39 -0800529#else
530 if (IS_965(intelScreen->deviceID))
Kristian Høgsberg4b691002010-04-27 11:04:51 -0400531 return brwCreateContext(api, mesaVis,
532 driContextPriv, sharedContextPrivate);
Eric Anholtbea6b5f2007-12-20 11:29:39 -0800533#endif
Eric Anholt4ac2f092010-12-02 18:25:45 -0800534 fprintf(stderr, "Unrecognized deviceID 0x%x\n", intelScreen->deviceID);
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700535 return false;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000536}
537
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700538static bool
Kristian Høgsberg5777dee2010-02-11 16:44:21 -0500539intel_init_bufmgr(struct intel_screen *intelScreen)
Eric Anholt7e0bbdc2008-09-04 22:16:31 +0100540{
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500541 __DRIscreen *spriv = intelScreen->driScrnPriv;
Eric Anholtcb4ef342009-07-01 17:08:16 -0700542 int num_fences = 0;
Eric Anholt7e0bbdc2008-09-04 22:16:31 +0100543
Eric Anholt4ac2f092010-12-02 18:25:45 -0800544 intelScreen->no_hw = (getenv("INTEL_NO_HW") != NULL ||
545 getenv("INTEL_DEVID_OVERRIDE") != NULL);
Eric Anholt7e0bbdc2008-09-04 22:16:31 +0100546
Eric Anholt827ba442009-11-18 18:15:25 +0100547 intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
Eric Anholt7e0bbdc2008-09-04 22:16:31 +0100548 if (intelScreen->bufmgr == NULL) {
Eric Anholt827ba442009-11-18 18:15:25 +0100549 fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
550 __func__, __LINE__);
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700551 return false;
Eric Anholt7e0bbdc2008-09-04 22:16:31 +0100552 }
553
Eric Anholtbb350002010-03-04 15:47:19 -0800554 if (!intel_get_param(spriv, I915_PARAM_NUM_FENCES_AVAIL, &num_fences) ||
555 num_fences == 0) {
556 fprintf(stderr, "[%s: %u] Kernel 2.6.29 required.\n", __func__, __LINE__);
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700557 return false;
Eric Anholtbb350002010-03-04 15:47:19 -0800558 }
Eric Anholte7aef002009-04-06 09:38:16 -0700559
Eric Anholt06d14722010-03-02 18:04:40 -0800560 drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
561
Kristian Høgsberg2d995882010-02-11 17:18:01 -0500562 intelScreen->named_regions = _mesa_NewHashTable();
563
Chris Wilson900a5c92011-03-01 14:46:50 +0000564 intelScreen->relaxed_relocations = 0;
565 intelScreen->relaxed_relocations |=
566 intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA) << 0;
567
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700568 return true;
Eric Anholt7e0bbdc2008-09-04 22:16:31 +0100569}
570
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500571/**
Chad Versace6b2bf272011-05-26 15:24:48 -0700572 * Override intel_screen.hw_has_hiz with environment variable INTEL_HIZ.
573 *
574 * Valid values for INTEL_HIZ are "0" and "1". If an invalid valid value is
575 * encountered, a warning is emitted and INTEL_HIZ is ignored.
576 */
577static void
578intel_override_hiz(struct intel_screen *intel)
579{
580 const char *s = getenv("INTEL_HIZ");
581 if (!s) {
582 return;
583 } else if (!strncmp("0", s, 2)) {
584 intel->hw_has_hiz = false;
585 } else if (!strncmp("1", s, 2)) {
586 intel->hw_has_hiz = true;
587 } else {
588 fprintf(stderr,
589 "warning: env variable INTEL_HIZ=\"%s\" has invalid value "
590 "and is ignored", s);
591 }
592}
593
594/**
595 * Override intel_screen.hw_has_separate_stencil with environment variable
596 * INTEL_SEPARATE_STENCIL.
597 *
598 * Valid values for INTEL_SEPARATE_STENCIL are "0" and "1". If an invalid
599 * valid value is encountered, a warning is emitted and INTEL_SEPARATE_STENCIL
600 * is ignored.
601 */
602static void
603intel_override_separate_stencil(struct intel_screen *screen)
604{
605 const char *s = getenv("INTEL_SEPARATE_STENCIL");
606 if (!s) {
607 return;
608 } else if (!strncmp("0", s, 2)) {
609 screen->hw_has_separate_stencil = false;
610 } else if (!strncmp("1", s, 2)) {
611 screen->hw_has_separate_stencil = true;
612 } else {
613 fprintf(stderr,
614 "warning: env variable INTEL_SEPARATE_STENCIL=\"%s\" has "
615 "invalid value and is ignored", s);
616 }
617}
618
619/**
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500620 * This is the driver specific part of the createNewScreen entry point.
Brian Paul8d976ae2008-06-11 19:33:14 -0600621 * Called when using DRI2.
622 *
Kristian Høgsbergd3491e72010-10-12 11:58:47 -0400623 * \return the struct gl_config supported by this driver
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500624 */
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400625static const
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500626__DRIconfig **intelInitScreen2(__DRIscreen *psp)
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500627{
Kristian Høgsberg5777dee2010-02-11 16:44:21 -0500628 struct intel_screen *intelScreen;
Eric Anholt3ee21f32009-01-29 14:57:49 -0800629 GLenum fb_format[3];
630 GLenum fb_type[3];
Kristian Høgsberg5efee4d2010-04-27 21:43:40 -0400631 unsigned int api_mask;
Eric Anholt4ac2f092010-12-02 18:25:45 -0800632 char *devid_override;
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500633
Eric Anholt3ee21f32009-01-29 14:57:49 -0800634 static const GLenum back_buffer_modes[] = {
Ian Romanick6bd9da02010-02-08 13:11:58 -0800635 GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
Eric Anholt3ee21f32009-01-29 14:57:49 -0800636 };
Brian Paule1359362009-02-09 11:16:20 -0700637 uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
Eric Anholt3ee21f32009-01-29 14:57:49 -0800638 int color;
Eric Anholt5d5ae372009-02-10 14:30:38 -0800639 __DRIconfig **configs = NULL;
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500640
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500641 /* Allocate the private area */
Kristian Høgsberg5777dee2010-02-11 16:44:21 -0500642 intelScreen = CALLOC(sizeof *intelScreen);
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500643 if (!intelScreen) {
644 fprintf(stderr, "\nERROR! Allocating private area failed\n");
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700645 return false;
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500646 }
647 /* parse information in __driConfigOptions */
648 driParseOptionInfo(&intelScreen->optionCache,
649 __driConfigOptions, __driNConfigOptions);
650
651 intelScreen->driScrnPriv = psp;
George Sapountzis875a7572011-11-03 13:04:57 +0200652 psp->driverPrivate = (void *) intelScreen;
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500653
Kristian Høgsbergf56b5692008-08-13 11:46:25 -0400654 /* Determine chipset ID */
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500655 if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID,
656 &intelScreen->deviceID))
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700657 return false;
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500658
Eric Anholt4ac2f092010-12-02 18:25:45 -0800659 /* Allow an override of the device ID for the purpose of making the
660 * driver produce dumps for debugging of new chipset enablement.
661 * This implies INTEL_NO_HW, to avoid programming your actual GPU
662 * incorrectly.
663 */
664 devid_override = getenv("INTEL_DEVID_OVERRIDE");
665 if (devid_override) {
666 intelScreen->deviceID = strtod(devid_override, NULL);
667 }
668
Kenneth Graunke89a82d72011-05-16 15:19:22 -0700669 if (IS_GEN7(intelScreen->deviceID)) {
670 intelScreen->gen = 7;
671 } else if (IS_GEN6(intelScreen->deviceID)) {
Kristian Høgsberg73630882011-04-25 09:49:09 -0400672 intelScreen->gen = 6;
673 } else if (IS_GEN5(intelScreen->deviceID)) {
674 intelScreen->gen = 5;
675 } else if (IS_965(intelScreen->deviceID)) {
676 intelScreen->gen = 4;
677 } else if (IS_9XX(intelScreen->deviceID)) {
678 intelScreen->gen = 3;
679 } else {
680 intelScreen->gen = 2;
681 }
682
Chad Versace6b2bf272011-05-26 15:24:48 -0700683 /*
684 * FIXME: The hiz and separate stencil fields need updating once the
685 * FIXME: features are completely implemented for a given chipset.
686 */
687 intelScreen->hw_has_separate_stencil = intelScreen->gen >= 7;
688 intelScreen->hw_must_use_separate_stencil = intelScreen->gen >= 7;
689 intelScreen->hw_has_hiz = false;
690 intelScreen->dri2_has_hiz = INTEL_DRI2_HAS_HIZ_UNKNOWN;
691
692 intel_override_hiz(intelScreen);
693 intel_override_separate_stencil(intelScreen);
694
Kristian Høgsberg5efee4d2010-04-27 21:43:40 -0400695 api_mask = (1 << __DRI_API_OPENGL);
696#if FEATURE_ES1
697 api_mask |= (1 << __DRI_API_GLES);
698#endif
699#if FEATURE_ES2
700 api_mask |= (1 << __DRI_API_GLES2);
701#endif
702
703 if (IS_9XX(intelScreen->deviceID) || IS_965(intelScreen->deviceID))
704 psp->api_mask = api_mask;
705
Eric Anholt7e0bbdc2008-09-04 22:16:31 +0100706 if (!intel_init_bufmgr(intelScreen))
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700707 return false;
Eric Anholt7e0bbdc2008-09-04 22:16:31 +0100708
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400709 psp->extensions = intelScreenExtensions;
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500710
Michel Dänzereaf15db2009-02-10 13:47:49 +0100711 msaa_samples_array[0] = 0;
712
Eric Anholt3ee21f32009-01-29 14:57:49 -0800713 fb_format[0] = GL_RGB;
714 fb_type[0] = GL_UNSIGNED_SHORT_5_6_5;
715
Eric Anholt24ff1692009-01-31 10:32:34 -0800716 fb_format[1] = GL_BGR;
Eric Anholt3ee21f32009-01-29 14:57:49 -0800717 fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV;
718
Eric Anholt24ff1692009-01-31 10:32:34 -0800719 fb_format[2] = GL_BGRA;
Eric Anholt3ee21f32009-01-29 14:57:49 -0800720 fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV;
721
Eric Anholt160c3612009-02-26 00:18:46 -0800722 depth_bits[0] = 0;
723 stencil_bits[0] = 0;
724
Ian Romanickbb65a1d2010-02-08 11:21:29 -0800725 /* Generate a rich set of useful configs that do not include an
726 * accumulation buffer.
727 */
Eric Anholt3ee21f32009-01-29 14:57:49 -0800728 for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
Eric Anholt5d5ae372009-02-10 14:30:38 -0800729 __DRIconfig **new_configs;
Eric Anholt160c3612009-02-26 00:18:46 -0800730 int depth_factor;
Eric Anholt3ee21f32009-01-29 14:57:49 -0800731
Ian Romanick066f45c2010-02-08 10:32:29 -0800732 /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
733 * buffer that has a diffferent number of bits per pixel than the color
734 * buffer. This isn't yet supported here.
Eric Anholt160c3612009-02-26 00:18:46 -0800735 */
736 if (fb_type[color] == GL_UNSIGNED_SHORT_5_6_5) {
737 depth_bits[1] = 16;
738 stencil_bits[1] = 0;
Eric Anholt160c3612009-02-26 00:18:46 -0800739 } else {
740 depth_bits[1] = 24;
Ian Romanick73e24cd2010-02-08 10:34:52 -0800741 stencil_bits[1] = 8;
Eric Anholt160c3612009-02-26 00:18:46 -0800742 }
Ian Romanick73e24cd2010-02-08 10:34:52 -0800743
744 depth_factor = 2;
745
Eric Anholt5d5ae372009-02-10 14:30:38 -0800746 new_configs = driCreateConfigs(fb_format[color], fb_type[color],
747 depth_bits,
748 stencil_bits,
Eric Anholt160c3612009-02-26 00:18:46 -0800749 depth_factor,
Eric Anholt5d5ae372009-02-10 14:30:38 -0800750 back_buffer_modes,
751 ARRAY_SIZE(back_buffer_modes),
752 msaa_samples_array,
Ian Romanick3cce4a12010-02-08 11:09:15 -0800753 ARRAY_SIZE(msaa_samples_array),
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700754 false);
Ian Romanickbb65a1d2010-02-08 11:21:29 -0800755 if (configs == NULL)
756 configs = new_configs;
757 else
758 configs = driConcatConfigs(configs, new_configs);
759 }
760
761 /* Generate the minimum possible set of configs that include an
762 * accumulation buffer.
763 */
764 for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
765 __DRIconfig **new_configs;
766
767 if (fb_type[color] == GL_UNSIGNED_SHORT_5_6_5) {
768 depth_bits[0] = 16;
769 stencil_bits[0] = 0;
770 } else {
771 depth_bits[0] = 24;
772 stencil_bits[0] = 8;
773 }
774
775 new_configs = driCreateConfigs(fb_format[color], fb_type[color],
776 depth_bits, stencil_bits, 1,
777 back_buffer_modes + 1, 1,
778 msaa_samples_array, 1,
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700779 true);
Eric Anholt3ee21f32009-01-29 14:57:49 -0800780 if (configs == NULL)
781 configs = new_configs;
782 else
783 configs = driConcatConfigs(configs, new_configs);
784 }
785
786 if (configs == NULL) {
787 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
788 __LINE__);
789 return NULL;
790 }
791
Eric Anholt5d5ae372009-02-10 14:30:38 -0800792 return (const __DRIconfig **)configs;
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500793}
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400794
Benjamin Franzke2adfde32011-02-04 12:01:31 +0100795struct intel_buffer {
796 __DRIbuffer base;
797 struct intel_region *region;
798};
799
Chad Versace79653c12011-11-15 07:08:49 -0800800/**
801 * \brief Get tiling format for a DRI buffer.
802 *
803 * \param attachment is the buffer's attachmet point, such as
804 * __DRI_BUFFER_DEPTH.
805 * \param out_tiling is the returned tiling format for buffer.
806 * \return false if attachment is unrecognized or is incompatible with screen.
807 */
808static bool
809intel_get_dri_buffer_tiling(struct intel_screen *screen,
810 uint32_t attachment,
811 uint32_t *out_tiling)
812{
813 if (screen->gen < 4) {
814 *out_tiling = I915_TILING_X;
815 return true;
816 }
817
818 switch (attachment) {
819 case __DRI_BUFFER_DEPTH:
820 case __DRI_BUFFER_DEPTH_STENCIL:
821 case __DRI_BUFFER_HIZ:
822 *out_tiling = I915_TILING_Y;
823 return true;
824 case __DRI_BUFFER_ACCUM:
825 case __DRI_BUFFER_FRONT_LEFT:
826 case __DRI_BUFFER_FRONT_RIGHT:
827 case __DRI_BUFFER_BACK_LEFT:
828 case __DRI_BUFFER_BACK_RIGHT:
829 case __DRI_BUFFER_FAKE_FRONT_LEFT:
830 case __DRI_BUFFER_FAKE_FRONT_RIGHT:
831 *out_tiling = I915_TILING_X;
832 return true;
833 case __DRI_BUFFER_STENCIL:
834 /* The stencil buffer is W tiled. However, we request from the kernel
835 * a non-tiled buffer because the GTT is incapable of W fencing.
836 */
837 *out_tiling = I915_TILING_NONE;
838 return true;
839 default:
840 if(unlikely(INTEL_DEBUG & DEBUG_DRI)) {
841 fprintf(stderr, "error: %s: unrecognized DRI buffer attachment 0x%x\n",
842 __FUNCTION__, attachment);
843 }
844 return false;
845 }
846}
847
Benjamin Franzke2adfde32011-02-04 12:01:31 +0100848static __DRIbuffer *
849intelAllocateBuffer(__DRIscreen *screen,
850 unsigned attachment, unsigned format,
851 int width, int height)
852{
853 struct intel_buffer *intelBuffer;
George Sapountzis875a7572011-11-03 13:04:57 +0200854 struct intel_screen *intelScreen = screen->driverPrivate;
Chad Versace79653c12011-11-15 07:08:49 -0800855
Kristian Høgsberg5dfba092011-04-25 09:53:22 -0400856 uint32_t tiling;
Chad Versace79653c12011-11-15 07:08:49 -0800857 uint32_t region_width;
858 uint32_t region_height;
859 uint32_t region_cpp;
860
861 bool ok = true;
862
863 ok = intel_get_dri_buffer_tiling(intelScreen, attachment, &tiling);
864 if (!ok)
865 return NULL;
Benjamin Franzke2adfde32011-02-04 12:01:31 +0100866
867 intelBuffer = CALLOC(sizeof *intelBuffer);
868 if (intelBuffer == NULL)
869 return NULL;
870
Chad Versace79653c12011-11-15 07:08:49 -0800871 if (attachment == __DRI_BUFFER_STENCIL) {
872 /* The stencil buffer has quirky pitch requirements. From Vol 2a,
873 * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
874 * The pitch must be set to 2x the value computed based on width, as
875 * the stencil buffer is stored with two rows interleaved.
876 * To accomplish this, we resort to the nasty hack of doubling the
877 * region's cpp and halving its height.
878 */
879 region_width = ALIGN(width, 64);
880 region_height = ALIGN(ALIGN(height, 2) / 2, 64);
881 region_cpp = format / 4;
882 } else {
883 region_width = width;
884 region_height = height;
885 region_cpp = format / 8;
886 }
Kristian Høgsberg5dfba092011-04-25 09:53:22 -0400887
Chad Versace79653c12011-11-15 07:08:49 -0800888 intelBuffer->region = intel_region_alloc(intelScreen,
889 tiling,
890 region_cpp,
891 region_width,
892 region_height,
893 true);
Benjamin Franzke2adfde32011-02-04 12:01:31 +0100894
895 if (intelBuffer->region == NULL) {
896 FREE(intelBuffer);
897 return NULL;
898 }
899
900 intel_region_flink(intelBuffer->region, &intelBuffer->base.name);
901
902 intelBuffer->base.attachment = attachment;
903 intelBuffer->base.cpp = intelBuffer->region->cpp;
904 intelBuffer->base.pitch =
905 intelBuffer->region->pitch * intelBuffer->region->cpp;
906
907 return &intelBuffer->base;
908}
909
910static void
911intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
912{
913 struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
914
915 intel_region_release(&intelBuffer->region);
916 free(intelBuffer);
917}
918
919
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400920const struct __DriverAPIRec driDriverAPI = {
George Sapountzis7192c372011-11-03 12:46:08 +0200921 .InitScreen = intelInitScreen2,
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400922 .DestroyScreen = intelDestroyScreen,
923 .CreateContext = intelCreateContext,
924 .DestroyContext = intelDestroyContext,
925 .CreateBuffer = intelCreateBuffer,
926 .DestroyBuffer = intelDestroyBuffer,
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400927 .MakeCurrent = intelMakeCurrent,
928 .UnbindContext = intelUnbindContext,
Benjamin Franzke2adfde32011-02-04 12:01:31 +0100929 .AllocateBuffer = intelAllocateBuffer,
930 .ReleaseBuffer = intelReleaseBuffer
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400931};
Kristian Høgsberg39a0e4e2010-01-01 17:56:29 -0500932
933/* This is the table of extensions that the loader will dlsym() for. */
934PUBLIC const __DRIextension *__driDriverExtensions[] = {
935 &driCoreExtension.base,
Kristian Høgsberg39a0e4e2010-01-01 17:56:29 -0500936 &driDRI2Extension.base,
937 NULL
938};