blob: e1ec2eb0130fe2060d7d01068bfedaacdcdefa24 [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 Paul14aff232012-01-02 15:20:04 -070036#include "main/version.h"
Brian Pauld0dc75c2011-12-05 20:40:48 -070037#include "swrast/s_renderbuffer.h"
Brian Paul6c244b02009-01-26 12:38:46 -070038
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000039#include "utils.h"
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000040#include "xmlpool.h"
41
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000042PUBLIC const char __driConfigOptions[] =
Eric Anholta0e453a2008-01-17 14:23:04 -080043 DRI_CONF_BEGIN
44 DRI_CONF_SECTION_PERFORMANCE
Jesse Barnese9bf3e42008-07-31 11:50:37 -070045 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC)
Eric Anholtfe91c052008-03-05 14:14:54 -080046 /* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
47 * DRI_CONF_BO_REUSE_ALL
48 */
Dave Airlief75843a2008-08-24 17:59:10 +100049 DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1")
Eric Anholtfe91c052008-03-05 14:14:54 -080050 DRI_CONF_DESC_BEGIN(en, "Buffer object reuse")
51 DRI_CONF_ENUM(0, "Disable buffer object reuse")
52 DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects")
53 DRI_CONF_DESC_END
54 DRI_CONF_OPT_END
Eric Anholt1ba96652009-06-03 16:40:20 +000055
Eric Anholt8e7a8d62010-03-03 11:51:51 -080056 DRI_CONF_OPT_BEGIN(texture_tiling, bool, true)
57 DRI_CONF_DESC(en, "Enable texture tiling")
58 DRI_CONF_OPT_END
Eric Anholt1ba96652009-06-03 16:40:20 +000059
Eric Anholtd09fce52012-03-06 11:05:20 -080060 DRI_CONF_OPT_BEGIN(hiz, bool, true)
61 DRI_CONF_DESC(en, "Enable Hierarchical Z on gen6+")
62 DRI_CONF_OPT_END
63
Eric Anholtb30dc2c2009-06-09 16:12:43 -070064 DRI_CONF_OPT_BEGIN(early_z, bool, false)
65 DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
66 DRI_CONF_OPT_END
67
Eric Anholta58514c2010-08-17 15:07:22 -070068 DRI_CONF_OPT_BEGIN(fragment_shader, bool, true)
Eric Anholt862a2a52009-07-29 13:00:09 -070069 DRI_CONF_DESC(en, "Enable limited ARB_fragment_shader support on 915/945.")
70 DRI_CONF_OPT_END
71
Eric Anholta0e453a2008-01-17 14:23:04 -080072 DRI_CONF_SECTION_END
73 DRI_CONF_SECTION_QUALITY
74 DRI_CONF_FORCE_S3TC_ENABLE(false)
Michel Dänzeracba9c12008-04-29 18:43:28 +020075 DRI_CONF_ALLOW_LARGE_TEXTURES(2)
Eric Anholta0e453a2008-01-17 14:23:04 -080076 DRI_CONF_SECTION_END
77 DRI_CONF_SECTION_DEBUG
78 DRI_CONF_NO_RAST(false)
Eric Anholt40bc2742009-03-05 17:18:49 -080079 DRI_CONF_ALWAYS_FLUSH_BATCH(false)
Eric Anholtf3687282009-03-05 17:08:36 -080080 DRI_CONF_ALWAYS_FLUSH_CACHE(false)
Eric Anholt64224782012-01-25 14:13:13 -080081 DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN(false)
Kenneth Graunke04089432012-07-18 00:07:17 -070082 DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED(false)
Eric Anholt81aa5d72009-07-29 13:07:49 -070083
84 DRI_CONF_OPT_BEGIN(stub_occlusion_query, bool, false)
85 DRI_CONF_DESC(en, "Enable stub ARB_occlusion_query support on 915/945.")
86 DRI_CONF_OPT_END
Eric Anholtc6abde22011-11-23 10:01:39 -080087
88 DRI_CONF_OPT_BEGIN(shader_precompile, bool, false)
89 DRI_CONF_DESC(en, "Perform code generation at shader link time.")
90 DRI_CONF_OPT_END
Eric Anholta0e453a2008-01-17 14:23:04 -080091 DRI_CONF_SECTION_END
92DRI_CONF_END;
93
Kenneth Graunke04089432012-07-18 00:07:17 -070094const GLuint __driNConfigOptions = 15;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +000095
Eric Anholtdf9f8912010-12-13 11:02:15 -080096#include "intel_batchbuffer.h"
97#include "intel_buffers.h"
98#include "intel_bufmgr.h"
99#include "intel_chipset.h"
100#include "intel_fbo.h"
Chad Versaceda2816a2011-11-16 14:04:25 -0800101#include "intel_mipmap_tree.h"
Eric Anholtdf9f8912010-12-13 11:02:15 -0800102#include "intel_screen.h"
103#include "intel_tex.h"
104#include "intel_regions.h"
105
106#include "i915_drm.h"
107
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000108#ifdef USE_NEW_INTERFACE
Eric Anholt85063f12008-02-13 16:08:19 -0800109static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000110#endif /*USE_NEW_INTERFACE */
111
Eric Anholt006c1a32012-08-07 10:05:38 -0700112/**
113 * For debugging purposes, this returns a time in seconds.
114 */
115double
116get_time(void)
117{
118 struct timespec tp;
119
120 clock_gettime(CLOCK_MONOTONIC, &tp);
121
122 return tp.tv_sec + tp.tv_nsec / 1000000000.0;
123}
124
Kenneth Graunke252d3112012-03-29 23:37:09 -0700125void
126aub_dump_bmp(struct gl_context *ctx)
127{
128 struct gl_framebuffer *fb = ctx->DrawBuffer;
129
130 for (int i = 0; i < fb->_NumColorDrawBuffers; i++) {
131 struct intel_renderbuffer *irb =
132 intel_renderbuffer(fb->_ColorDrawBuffers[i]);
133
134 if (irb && irb->mt) {
135 enum aub_dump_bmp_format format;
136
137 switch (irb->Base.Base.Format) {
138 case MESA_FORMAT_ARGB8888:
139 case MESA_FORMAT_XRGB8888:
140 format = AUB_DUMP_BMP_FORMAT_ARGB_8888;
141 break;
142 default:
143 continue;
144 }
145
146 drm_intel_gem_bo_aub_dump_bmp(irb->mt->region->bo,
147 irb->draw_x,
148 irb->draw_y,
149 irb->Base.Base.Width,
150 irb->Base.Base.Height,
151 format,
152 irb->mt->region->pitch *
153 irb->mt->region->cpp,
154 0);
155 }
156 }
157}
158
Kristian Høgsberg6d487792008-02-14 22:12:51 -0500159static const __DRItexBufferExtension intelTexBufferExtension = {
160 { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
161 intelSetTexBuffer,
Eric Anholt66175aa2009-03-18 12:07:09 -0700162 intelSetTexBuffer2,
Kristian Høgsberg6d487792008-02-14 22:12:51 -0500163};
164
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500165static void
Chad Versace61fd6842012-07-12 13:01:26 -0700166intel_downsample_for_dri2_flush(struct intel_context *intel,
167 __DRIdrawable *drawable)
168{
169 if (intel->gen < 6) {
170 /* MSAA is not supported, so don't waste time checking for
171 * a multisample buffer.
172 */
173 return;
174 }
175
176 struct gl_framebuffer *fb = drawable->driverPrivate;
177 struct intel_renderbuffer *rb;
178
179 /* Usually, only the back buffer will need to be downsampled. However,
180 * the front buffer will also need it if the user has rendered into it.
181 */
182 static const gl_buffer_index buffers[2] = {
183 BUFFER_BACK_LEFT,
184 BUFFER_FRONT_LEFT,
185 };
186
187 for (int i = 0; i < 2; ++i) {
188 rb = intel_get_renderbuffer(fb, buffers[i]);
189 if (rb == NULL || rb->mt == NULL)
190 continue;
191 intel_miptree_downsample(intel, rb->mt);
192 }
193}
194
195static void
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500196intelDRI2Flush(__DRIdrawable *drawable)
197{
Eric Anholtdea5e572011-02-14 18:57:49 -0800198 GET_CURRENT_CONTEXT(ctx);
199 struct intel_context *intel = intel_context(ctx);
Anuj Phogatce1c9492012-01-17 13:21:52 -0800200 if (intel == NULL)
201 return;
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500202
Anuj Phogatce1c9492012-01-17 13:21:52 -0800203 if (intel->gen < 4)
204 INTEL_FIREVERTICES(intel);
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500205
Chad Versace61fd6842012-07-12 13:01:26 -0700206 intel_downsample_for_dri2_flush(intel, drawable);
Anuj Phogatce1c9492012-01-17 13:21:52 -0800207 intel->need_throttle = true;
Kristian Høgsberge67c3382010-05-18 21:50:44 -0400208
Anuj Phogatce1c9492012-01-17 13:21:52 -0800209 if (intel->batch.used)
210 intel_batchbuffer_flush(intel);
Eric Anholt0247d892012-03-06 15:31:42 -0800211
212 if (INTEL_DEBUG & DEBUG_AUB) {
Kenneth Graunke252d3112012-03-29 23:37:09 -0700213 aub_dump_bmp(ctx);
Eric Anholt0247d892012-03-06 15:31:42 -0800214 }
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500215}
216
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500217static const struct __DRI2flushExtensionRec intelFlushExtension = {
218 { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
219 intelDRI2Flush,
Kristian Høgsberge67c3382010-05-18 21:50:44 -0400220 dri2InvalidateDrawable,
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500221};
222
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500223static __DRIimage *
Kristian Høgsberg1bb15c02012-07-05 00:17:47 -0400224intel_allocate_image(int dri_format, void *loaderPrivate)
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500225{
226 __DRIimage *image;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500227
228 image = CALLOC(sizeof *image);
229 if (image == NULL)
230 return NULL;
231
Kristian Høgsberg1bb15c02012-07-05 00:17:47 -0400232 image->dri_format = dri_format;
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400233 image->offset = 0;
Ander Conselvan de Oliveira249817e2012-04-30 12:32:45 +0300234
Kristian Høgsberg1bb15c02012-07-05 00:17:47 -0400235 switch (dri_format) {
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500236 case __DRI_IMAGE_FORMAT_RGB565:
237 image->format = MESA_FORMAT_RGB565;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500238 break;
239 case __DRI_IMAGE_FORMAT_XRGB8888:
240 image->format = MESA_FORMAT_XRGB8888;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500241 break;
242 case __DRI_IMAGE_FORMAT_ARGB8888:
243 image->format = MESA_FORMAT_ARGB8888;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500244 break;
Chia-I Wu9fe197c2011-08-21 21:36:40 +0800245 case __DRI_IMAGE_FORMAT_ABGR8888:
246 image->format = MESA_FORMAT_RGBA8888_REV;
Chia-I Wu9fe197c2011-08-21 21:36:40 +0800247 break;
Sean V Kelleyfd0082c2012-04-24 07:49:10 -0700248 case __DRI_IMAGE_FORMAT_XBGR8888:
249 image->format = MESA_FORMAT_RGBX8888_REV;
Sean V Kelleyfd0082c2012-04-24 07:49:10 -0700250 break;
Kristian Høgsberg44a2b572012-07-05 12:13:06 -0400251 case __DRI_IMAGE_FORMAT_R8:
252 image->format = MESA_FORMAT_R8;
253 break;
254 case __DRI_IMAGE_FORMAT_GR88:
255 image->format = MESA_FORMAT_GR88;
256 break;
257 case __DRI_IMAGE_FORMAT_NONE:
258 image->format = MESA_FORMAT_NONE;
259 break;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500260 default:
261 free(image);
262 return NULL;
263 }
264
Kristian Høgsberg454fc072012-07-05 00:07:15 -0400265 image->internal_format = _mesa_get_format_base_format(image->format);
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500266 image->data = loaderPrivate;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500267
Kristian Høgsberg1bb15c02012-07-05 00:17:47 -0400268 return image;
269}
270
271static __DRIimage *
272intel_create_image_from_name(__DRIscreen *screen,
273 int width, int height, int format,
274 int name, int pitch, void *loaderPrivate)
275{
276 struct intel_screen *intelScreen = screen->driverPrivate;
277 __DRIimage *image;
278 int cpp;
279
280 image = intel_allocate_image(format, loaderPrivate);
Kristian Høgsberg636646a2012-07-16 10:54:30 -0400281 if (image->format == MESA_FORMAT_NONE)
282 cpp = 0;
283 else
284 cpp = _mesa_get_format_bytes(image->format);
Kristian Høgsberg9ec0b2a2010-09-22 15:07:15 -0400285 image->region = intel_region_alloc_for_handle(intelScreen,
Kristian Høgsberg9087ba12010-06-03 21:56:21 -0400286 cpp, width, height,
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500287 pitch, name, "image");
288 if (image->region == NULL) {
289 FREE(image);
290 return NULL;
291 }
292
293 return image;
294}
295
296static __DRIimage *
297intel_create_image_from_renderbuffer(__DRIcontext *context,
298 int renderbuffer, void *loaderPrivate)
299{
300 __DRIimage *image;
301 struct intel_context *intel = context->driverPrivate;
302 struct gl_renderbuffer *rb;
303 struct intel_renderbuffer *irb;
304
Kristian Høgsbergd7322c92010-02-26 14:49:31 -0500305 rb = _mesa_lookup_renderbuffer(&intel->ctx, renderbuffer);
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500306 if (!rb) {
307 _mesa_error(&intel->ctx,
308 GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
309 return NULL;
310 }
311
312 irb = intel_renderbuffer(rb);
313 image = CALLOC(sizeof *image);
314 if (image == NULL)
315 return NULL;
316
317 image->internal_format = rb->InternalFormat;
318 image->format = rb->Format;
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400319 image->offset = 0;
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500320 image->data = loaderPrivate;
Chad Versaceda2816a2011-11-16 14:04:25 -0800321 intel_region_reference(&image->region, irb->mt->region);
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500322
Ander Conselvan de Oliveira249817e2012-04-30 12:32:45 +0300323 switch (image->format) {
324 case MESA_FORMAT_RGB565:
325 image->dri_format = __DRI_IMAGE_FORMAT_RGB565;
326 break;
327 case MESA_FORMAT_XRGB8888:
328 image->dri_format = __DRI_IMAGE_FORMAT_XRGB8888;
329 break;
330 case MESA_FORMAT_ARGB8888:
331 image->dri_format = __DRI_IMAGE_FORMAT_ARGB8888;
332 break;
333 case MESA_FORMAT_RGBA8888_REV:
334 image->dri_format = __DRI_IMAGE_FORMAT_ABGR8888;
335 break;
Kristian Høgsberg44a2b572012-07-05 12:13:06 -0400336 case MESA_FORMAT_R8:
337 image->dri_format = __DRI_IMAGE_FORMAT_R8;
338 break;
339 case MESA_FORMAT_RG88:
340 image->dri_format = __DRI_IMAGE_FORMAT_GR88;
341 break;
Ander Conselvan de Oliveira249817e2012-04-30 12:32:45 +0300342 }
343
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500344 return image;
345}
346
347static void
348intel_destroy_image(__DRIimage *image)
349{
350 intel_region_release(&image->region);
351 FREE(image);
352}
353
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400354static __DRIimage *
355intel_create_image(__DRIscreen *screen,
356 int width, int height, int format,
357 unsigned int use,
358 void *loaderPrivate)
359{
360 __DRIimage *image;
George Sapountzis875a7572011-11-03 13:04:57 +0200361 struct intel_screen *intelScreen = screen->driverPrivate;
Kristian Høgsberge5169e92011-05-06 10:31:18 -0400362 uint32_t tiling;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400363 int cpp;
364
Kristian Høgsberge5169e92011-05-06 10:31:18 -0400365 tiling = I915_TILING_X;
366 if (use & __DRI_IMAGE_USE_CURSOR) {
367 if (width != 64 || height != 64)
368 return NULL;
369 tiling = I915_TILING_NONE;
370 }
371
Kristian Høgsberg4fddb2b2012-05-02 15:30:13 -0400372 /* We only support write for cursor drm images */
373 if ((use & __DRI_IMAGE_USE_WRITE) &&
374 use != (__DRI_IMAGE_USE_WRITE | __DRI_IMAGE_USE_CURSOR))
375 return NULL;
376
Kristian Høgsberg1bb15c02012-07-05 00:17:47 -0400377 image = intel_allocate_image(format, loaderPrivate);
Kristian Høgsberg4fddb2b2012-05-02 15:30:13 -0400378 image->usage = use;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400379 cpp = _mesa_get_format_bytes(image->format);
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400380 image->region =
Kristian Høgsberg1bb15c02012-07-05 00:17:47 -0400381 intel_region_alloc(intelScreen, tiling, cpp, width, height, true);
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400382 if (image->region == NULL) {
383 FREE(image);
384 return NULL;
385 }
386
387 return image;
388}
389
390static GLboolean
391intel_query_image(__DRIimage *image, int attrib, int *value)
392{
393 switch (attrib) {
394 case __DRI_IMAGE_ATTRIB_STRIDE:
395 *value = image->region->pitch * image->region->cpp;
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700396 return true;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400397 case __DRI_IMAGE_ATTRIB_HANDLE:
Eric Anholt8004a1c2011-09-22 11:58:37 -0700398 *value = image->region->bo->handle;
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700399 return true;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400400 case __DRI_IMAGE_ATTRIB_NAME:
401 return intel_region_flink(image->region, (uint32_t *) value);
Jesse Barnes8de5c352012-02-21 12:53:09 -0800402 case __DRI_IMAGE_ATTRIB_FORMAT:
Ander Conselvan de Oliveirafc7d2242012-04-26 16:21:19 +0300403 *value = image->dri_format;
404 return true;
Kristian Høgsberg44f066b2012-07-13 11:19:24 -0400405 case __DRI_IMAGE_ATTRIB_WIDTH:
406 *value = image->region->width;
407 return true;
408 case __DRI_IMAGE_ATTRIB_HEIGHT:
409 *value = image->region->height;
410 return true;
411 default:
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700412 return false;
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400413 }
414}
415
Benjamin Franzke3af3c582011-03-09 20:56:02 +0100416static __DRIimage *
417intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
418{
419 __DRIimage *image;
420
421 image = CALLOC(sizeof *image);
422 if (image == NULL)
423 return NULL;
424
Benjamin Franzke3af3c582011-03-09 20:56:02 +0100425 intel_region_reference(&image->region, orig_image->region);
426 if (image->region == NULL) {
427 FREE(image);
428 return NULL;
429 }
430
431 image->internal_format = orig_image->internal_format;
Kristian Høgsberg4fddb2b2012-05-02 15:30:13 -0400432 image->usage = orig_image->usage;
Ander Conselvan de Oliveira249817e2012-04-30 12:32:45 +0300433 image->dri_format = orig_image->dri_format;
Benjamin Franzke3af3c582011-03-09 20:56:02 +0100434 image->format = orig_image->format;
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400435 image->offset = orig_image->offset;
Benjamin Franzke3af3c582011-03-09 20:56:02 +0100436 image->data = loaderPrivate;
437
438 return image;
439}
440
Kristian Høgsberg221c6782012-01-18 15:32:35 -0500441static GLboolean
442intel_validate_usage(__DRIimage *image, unsigned int use)
443{
444 if (use & __DRI_IMAGE_USE_CURSOR) {
445 if (image->region->width != 64 || image->region->height != 64)
446 return GL_FALSE;
447 }
448
Kristian Høgsberg4fddb2b2012-05-02 15:30:13 -0400449 /* We only support write for cursor drm images */
450 if ((use & __DRI_IMAGE_USE_WRITE) &&
451 use != (__DRI_IMAGE_USE_WRITE | __DRI_IMAGE_USE_CURSOR))
452 return GL_FALSE;
453
Kristian Høgsberg221c6782012-01-18 15:32:35 -0500454 return GL_TRUE;
455}
456
Kristian Høgsberg4fddb2b2012-05-02 15:30:13 -0400457static int
458intel_image_write(__DRIimage *image, const void *buf, size_t count)
459{
460 if (image->region->map_refcount)
461 return -1;
462 if (!(image->usage & __DRI_IMAGE_USE_WRITE))
463 return -1;
464
465 drm_intel_bo_map(image->region->bo, true);
466 memcpy(image->region->bo->virtual, buf, count);
467 drm_intel_bo_unmap(image->region->bo);
468
469 return 0;
470}
471
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400472static __DRIimage *
473intel_create_sub_image(__DRIimage *parent,
474 int width, int height, int dri_format,
475 int offset, int pitch, void *loaderPrivate)
476{
477 __DRIimage *image;
478 int cpp;
479 uint32_t mask_x, mask_y;
480
481 image = intel_allocate_image(dri_format, loaderPrivate);
482 cpp = _mesa_get_format_bytes(image->format);
483 if (offset + height * cpp * pitch > parent->region->bo->size) {
484 _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds");
485 FREE(image);
486 return NULL;
487 }
488
489 image->region = calloc(sizeof(*image->region), 1);
490 if (image->region == NULL) {
491 FREE(image);
492 return NULL;
493 }
494
495 image->region->cpp = _mesa_get_format_bytes(image->format);
496 image->region->width = width;
497 image->region->height = height;
498 image->region->pitch = pitch;
499 image->region->refcount = 1;
500 image->region->bo = parent->region->bo;
501 drm_intel_bo_reference(image->region->bo);
502 image->region->tiling = parent->region->tiling;
503 image->region->screen = parent->region->screen;
504 image->offset = offset;
505
506 intel_region_get_tile_masks(image->region, &mask_x, &mask_y);
507 if (offset & mask_x)
508 _mesa_warning(NULL,
509 "intel_create_sub_image: offset not on tile boundary");
510
511 return image;
512}
513
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500514static struct __DRIimageExtensionRec intelImageExtension = {
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400515 { __DRI_IMAGE, 5 },
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500516 intel_create_image_from_name,
517 intel_create_image_from_renderbuffer,
518 intel_destroy_image,
Kristian Høgsbergf3019322010-06-06 20:39:19 -0400519 intel_create_image,
Benjamin Franzke3af3c582011-03-09 20:56:02 +0100520 intel_query_image,
Kristian Høgsberg221c6782012-01-18 15:32:35 -0500521 intel_dup_image,
Kristian Høgsberg4fddb2b2012-05-02 15:30:13 -0400522 intel_validate_usage,
Kristian Høgsberg95bc0522012-07-05 13:02:02 -0400523 intel_image_write,
524 intel_create_sub_image
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500525};
526
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400527static const __DRIextension *intelScreenExtensions[] = {
Kristian Høgsberg6d487792008-02-14 22:12:51 -0500528 &intelTexBufferExtension.base,
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500529 &intelFlushExtension.base,
Kristian Høgsbergc2624712010-02-11 18:59:40 -0500530 &intelImageExtension.base,
Jesse Barnes234286c2010-04-22 12:47:41 -0700531 &dri2ConfigQueryExtension.base,
Kristian Høgsbergac3e8382007-05-15 15:17:30 -0400532 NULL
533};
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000534
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700535static bool
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500536intel_get_param(__DRIscreen *psp, int param, int *value)
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500537{
538 int ret;
Alan Hourihane1c718c02008-02-22 00:18:54 +0000539 struct drm_i915_getparam gp;
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500540
Eric Anholtf33d1002012-02-16 11:30:49 -0800541 memset(&gp, 0, sizeof(gp));
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500542 gp.param = param;
543 gp.value = value;
544
Alan Hourihane1c718c02008-02-22 00:18:54 +0000545 ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500546 if (ret) {
Eric Anholtf6ca4a32011-03-09 12:54:14 -0800547 if (ret != -EINVAL)
548 _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700549 return false;
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500550 }
551
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700552 return true;
Kristian Høgsberg24e7e452008-01-09 18:04:19 -0500553}
Kristian Høgsbergac3e8382007-05-15 15:17:30 -0400554
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700555static bool
Chris Wilson900a5c92011-03-01 14:46:50 +0000556intel_get_boolean(__DRIscreen *psp, int param)
557{
558 int value = 0;
559 return intel_get_param(psp, param, &value) && value;
560}
561
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000562static void
Kristian Høgsberg2d995882010-02-11 17:18:01 -0500563nop_callback(GLuint key, void *data, void *userData)
564{
565}
566
567static void
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500568intelDestroyScreen(__DRIscreen * sPriv)
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000569{
George Sapountzis875a7572011-11-03 13:04:57 +0200570 struct intel_screen *intelScreen = sPriv->driverPrivate;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000571
Eric Anholt904f31a2008-09-16 17:01:06 -0700572 dri_bufmgr_destroy(intelScreen->bufmgr);
Eric Anholt6d66f232009-07-02 13:30:20 -0700573 driDestroyOptionInfo(&intelScreen->optionCache);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000574
Kristian Høgsberg2d995882010-02-11 17:18:01 -0500575 /* Some regions may still have references to them at this point, so
576 * flush the hash table to prevent _mesa_DeleteHashTable() from
577 * complaining about the hash not being empty; */
578 _mesa_HashDeleteAll(intelScreen->named_regions, nop_callback, NULL);
579 _mesa_DeleteHashTable(intelScreen->named_regions);
580
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000581 FREE(intelScreen);
George Sapountzis875a7572011-11-03 13:04:57 +0200582 sPriv->driverPrivate = NULL;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000583}
584
585
586/**
587 * This is called when we need to set up GL rendering to a new X window.
588 */
589static GLboolean
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500590intelCreateBuffer(__DRIscreen * driScrnPriv,
591 __DRIdrawable * driDrawPriv,
Kristian Høgsbergd3491e72010-10-12 11:58:47 -0400592 const struct gl_config * mesaVis, GLboolean isPixmap)
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000593{
Kristian Høgsbergd2821282010-01-01 23:21:16 -0500594 struct intel_renderbuffer *rb;
George Sapountzis875a7572011-11-03 13:04:57 +0200595 struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate;
Chad Versace2b4fbc42012-07-09 16:51:23 -0700596 gl_format rgbFormat;
Chad Versacee2f23762012-07-11 15:10:49 -0700597 unsigned num_samples = intel_quantize_num_samples(screen, mesaVis->samples);
Chad Versace2b4fbc42012-07-09 16:51:23 -0700598 struct gl_framebuffer *fb;
Kristian Høgsbergd2821282010-01-01 23:21:16 -0500599
Chad Versace2b4fbc42012-07-09 16:51:23 -0700600 if (isPixmap)
601 return false;
602
603 fb = CALLOC_STRUCT(gl_framebuffer);
604 if (!fb)
605 return false;
606
607 _mesa_initialize_window_framebuffer(fb, mesaVis);
608
609 if (mesaVis->redBits == 5)
610 rgbFormat = MESA_FORMAT_RGB565;
611 else if (mesaVis->alphaBits == 0)
612 rgbFormat = MESA_FORMAT_XRGB8888;
613 else
614 rgbFormat = MESA_FORMAT_ARGB8888;
615
616 /* setup the hardware-based renderbuffers */
Chad Versacee2f23762012-07-11 15:10:49 -0700617 rb = intel_create_renderbuffer(rgbFormat, num_samples);
Chad Versace2b4fbc42012-07-09 16:51:23 -0700618 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base.Base);
619
620 if (mesaVis->doubleBufferMode) {
Chad Versacee2f23762012-07-11 15:10:49 -0700621 rb = intel_create_renderbuffer(rgbFormat, num_samples);
Chad Versace2b4fbc42012-07-09 16:51:23 -0700622 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base.Base);
623 }
624
625 /*
626 * Assert here that the gl_config has an expected depth/stencil bit
627 * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
628 * which constructs the advertised configs.)
629 */
630 if (mesaVis->depthBits == 24) {
631 assert(mesaVis->stencilBits == 8);
632
633 if (screen->hw_has_separate_stencil) {
Chad Versacee2f23762012-07-11 15:10:49 -0700634 rb = intel_create_private_renderbuffer(MESA_FORMAT_X8_Z24,
635 num_samples);
Chad Versace2b4fbc42012-07-09 16:51:23 -0700636 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
Chad Versacee2f23762012-07-11 15:10:49 -0700637 rb = intel_create_private_renderbuffer(MESA_FORMAT_S8,
638 num_samples);
Chad Versace2b4fbc42012-07-09 16:51:23 -0700639 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
640 } else {
641 /*
642 * Use combined depth/stencil. Note that the renderbuffer is
643 * attached to two attachment points.
644 */
Chad Versacee2f23762012-07-11 15:10:49 -0700645 rb = intel_create_private_renderbuffer(MESA_FORMAT_S8_Z24,
646 num_samples);
Chad Versace2b4fbc42012-07-09 16:51:23 -0700647 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
648 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
649 }
650 }
651 else if (mesaVis->depthBits == 16) {
652 assert(mesaVis->stencilBits == 0);
Chad Versacee2f23762012-07-11 15:10:49 -0700653 rb = intel_create_private_renderbuffer(MESA_FORMAT_Z16,
654 num_samples);
Chad Versace8c94f6b2012-07-09 17:01:29 -0700655 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000656 }
657 else {
Chad Versace2b4fbc42012-07-09 16:51:23 -0700658 assert(mesaVis->depthBits == 0);
659 assert(mesaVis->stencilBits == 0);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000660 }
Chad Versace2b4fbc42012-07-09 16:51:23 -0700661
662 /* now add any/all software-based renderbuffers we may need */
663 _swrast_add_soft_renderbuffers(fb,
664 false, /* never sw color */
665 false, /* never sw depth */
666 false, /* never sw stencil */
667 mesaVis->accumRedBits > 0,
668 false, /* never sw alpha */
669 false /* never sw aux */ );
670 driDrawPriv->driverPrivate = fb;
671
672 return true;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000673}
674
675static void
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500676intelDestroyBuffer(__DRIdrawable * driDrawPriv)
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000677{
Kristian Høgsbergd2821282010-01-01 23:21:16 -0500678 struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
679
680 _mesa_reference_framebuffer(&fb, NULL);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000681}
682
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000683/* There are probably better ways to do this, such as an
684 * init-designated function to register chipids and createcontext
685 * functions.
686 */
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700687extern bool
688i830CreateContext(const struct gl_config *mesaVis,
689 __DRIcontext *driContextPriv,
690 void *sharedContextPrivate);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000691
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700692extern bool
693i915CreateContext(int api,
694 const struct gl_config *mesaVis,
695 __DRIcontext *driContextPriv,
696 void *sharedContextPrivate);
697extern bool
698brwCreateContext(int api,
699 const struct gl_config *mesaVis,
700 __DRIcontext *driContextPriv,
701 void *sharedContextPrivate);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000702
703static GLboolean
Kristian Høgsberga7a9a912010-04-27 11:04:51 -0400704intelCreateContext(gl_api api,
Kristian Høgsbergd3491e72010-10-12 11:58:47 -0400705 const struct gl_config * mesaVis,
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500706 __DRIcontext * driContextPriv,
Ian Romanicke532b622011-12-01 14:06:58 -0800707 unsigned major_version,
708 unsigned minor_version,
709 uint32_t flags,
710 unsigned *error,
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000711 void *sharedContextPrivate)
712{
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500713 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
George Sapountzis875a7572011-11-03 13:04:57 +0200714 struct intel_screen *intelScreen = sPriv->driverPrivate;
Eric Anholt35cdd7b2012-01-11 12:07:15 -0800715 bool success = false;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000716
Eric Anholtbea6b5f2007-12-20 11:29:39 -0800717#ifdef I915
Eric Anholt19420e62008-02-15 13:16:01 -0800718 if (IS_9XX(intelScreen->deviceID)) {
719 if (!IS_965(intelScreen->deviceID)) {
Ian Romanicke532b622011-12-01 14:06:58 -0800720 success = i915CreateContext(api, mesaVis, driContextPriv,
721 sharedContextPrivate);
Eric Anholt19420e62008-02-15 13:16:01 -0800722 }
Eric Anholtbea6b5f2007-12-20 11:29:39 -0800723 } else {
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700724 intelScreen->no_vbo = true;
Ian Romanicke532b622011-12-01 14:06:58 -0800725 success = i830CreateContext(mesaVis, driContextPriv,
726 sharedContextPrivate);
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000727 }
Eric Anholtbea6b5f2007-12-20 11:29:39 -0800728#else
729 if (IS_965(intelScreen->deviceID))
Ian Romanicke532b622011-12-01 14:06:58 -0800730 success = brwCreateContext(api, mesaVis,
731 driContextPriv,
732 sharedContextPrivate);
Eric Anholtbea6b5f2007-12-20 11:29:39 -0800733#endif
Ian Romanicke532b622011-12-01 14:06:58 -0800734
735 if (success) {
736 struct gl_context *ctx =
737 (struct gl_context *) driContextPriv->driverPrivate;
738
739 _mesa_compute_version(ctx);
Eric Anholt9c1b4182012-07-26 14:43:56 -0700740 if (ctx->Version >= major_version * 10 + minor_version) {
Ian Romanicke532b622011-12-01 14:06:58 -0800741 return true;
742 }
743
Jordan Justen881bb4a2012-07-17 11:22:32 -0700744 *error = __DRI_CTX_ERROR_BAD_VERSION;
Ian Romanicke532b622011-12-01 14:06:58 -0800745 intelDestroyContext(driContextPriv);
746 } else {
747 *error = __DRI_CTX_ERROR_NO_MEMORY;
748 fprintf(stderr, "Unrecognized deviceID 0x%x\n", intelScreen->deviceID);
749 }
750
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700751 return false;
Keith Whitwell6b9e31f2006-11-01 12:03:11 +0000752}
753
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700754static bool
Kristian Høgsberg5777dee2010-02-11 16:44:21 -0500755intel_init_bufmgr(struct intel_screen *intelScreen)
Eric Anholt7e0bbdc2008-09-04 22:16:31 +0100756{
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500757 __DRIscreen *spriv = intelScreen->driScrnPriv;
Eric Anholtcb4ef342009-07-01 17:08:16 -0700758 int num_fences = 0;
Eric Anholt7e0bbdc2008-09-04 22:16:31 +0100759
Eric Anholt2222aa02012-03-09 16:27:35 -0800760 intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
Eric Anholt7e0bbdc2008-09-04 22:16:31 +0100761
Eric Anholt827ba442009-11-18 18:15:25 +0100762 intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
Eric Anholt7e0bbdc2008-09-04 22:16:31 +0100763 if (intelScreen->bufmgr == NULL) {
Eric Anholt827ba442009-11-18 18:15:25 +0100764 fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
765 __func__, __LINE__);
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700766 return false;
Eric Anholt7e0bbdc2008-09-04 22:16:31 +0100767 }
768
Eric Anholtbb350002010-03-04 15:47:19 -0800769 if (!intel_get_param(spriv, I915_PARAM_NUM_FENCES_AVAIL, &num_fences) ||
770 num_fences == 0) {
771 fprintf(stderr, "[%s: %u] Kernel 2.6.29 required.\n", __func__, __LINE__);
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700772 return false;
Eric Anholtbb350002010-03-04 15:47:19 -0800773 }
Eric Anholte7aef002009-04-06 09:38:16 -0700774
Eric Anholt06d14722010-03-02 18:04:40 -0800775 drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
776
Kristian Høgsberg2d995882010-02-11 17:18:01 -0500777 intelScreen->named_regions = _mesa_NewHashTable();
778
Chris Wilson900a5c92011-03-01 14:46:50 +0000779 intelScreen->relaxed_relocations = 0;
780 intelScreen->relaxed_relocations |=
781 intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA) << 0;
782
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700783 return true;
Eric Anholt7e0bbdc2008-09-04 22:16:31 +0100784}
785
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500786/**
Chad Versace6b2bf272011-05-26 15:24:48 -0700787 * Override intel_screen.hw_has_separate_stencil with environment variable
788 * INTEL_SEPARATE_STENCIL.
789 *
790 * Valid values for INTEL_SEPARATE_STENCIL are "0" and "1". If an invalid
791 * valid value is encountered, a warning is emitted and INTEL_SEPARATE_STENCIL
792 * is ignored.
793 */
794static void
795intel_override_separate_stencil(struct intel_screen *screen)
796{
797 const char *s = getenv("INTEL_SEPARATE_STENCIL");
798 if (!s) {
799 return;
800 } else if (!strncmp("0", s, 2)) {
801 screen->hw_has_separate_stencil = false;
802 } else if (!strncmp("1", s, 2)) {
803 screen->hw_has_separate_stencil = true;
804 } else {
805 fprintf(stderr,
806 "warning: env variable INTEL_SEPARATE_STENCIL=\"%s\" has "
807 "invalid value and is ignored", s);
808 }
809}
810
Daniel Vetterf172eae2012-03-02 21:38:44 +0100811static bool
812intel_detect_swizzling(struct intel_screen *screen)
813{
814 drm_intel_bo *buffer;
815 unsigned long flags = 0;
816 unsigned long aligned_pitch;
817 uint32_t tiling = I915_TILING_X;
818 uint32_t swizzle_mode = 0;
819
820 buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "swizzle test",
821 64, 64, 4,
822 &tiling, &aligned_pitch, flags);
823 if (buffer == NULL)
824 return false;
825
826 drm_intel_bo_get_tiling(buffer, &tiling, &swizzle_mode);
827 drm_intel_bo_unreference(buffer);
828
829 if (swizzle_mode == I915_BIT_6_SWIZZLE_NONE)
830 return false;
831 else
832 return true;
833}
834
Chad Versaceb2d428c2012-07-12 14:17:22 -0700835static __DRIconfig**
836intel_screen_make_configs(__DRIscreen *dri_screen)
837{
838 static const GLenum back_buffer_modes[] = {
839 GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
840 };
841
Chad Versace8b5d68d2012-08-02 14:51:47 -0700842 static const uint8_t singlesample_samples[1] = {0};
Chad Versacee943e5c2012-08-02 17:13:17 -0700843 static const uint8_t multisample_samples[2] = {4, 8};
Chad Versace8b5d68d2012-08-02 14:51:47 -0700844
Chad Versacee943e5c2012-08-02 17:13:17 -0700845 struct intel_screen *screen = dri_screen->driverPrivate;
Chad Versaceb2d428c2012-07-12 14:17:22 -0700846 GLenum fb_format[3];
847 GLenum fb_type[3];
Chad Versace8b5d68d2012-08-02 14:51:47 -0700848 uint8_t depth_bits[4], stencil_bits[4];
Chad Versaceb2d428c2012-07-12 14:17:22 -0700849 __DRIconfig **configs = NULL;
850
Chad Versaceb2d428c2012-07-12 14:17:22 -0700851 fb_format[0] = GL_RGB;
852 fb_type[0] = GL_UNSIGNED_SHORT_5_6_5;
853
854 fb_format[1] = GL_BGR;
855 fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV;
856
857 fb_format[2] = GL_BGRA;
858 fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV;
859
Chad Versacee943e5c2012-08-02 17:13:17 -0700860 /* Generate singlesample configs without accumulation buffer. */
Chad Versace8b5d68d2012-08-02 14:51:47 -0700861 for (int i = 0; i < ARRAY_SIZE(fb_format); i++) {
Chad Versaceb2d428c2012-07-12 14:17:22 -0700862 __DRIconfig **new_configs;
Chad Versace8b5d68d2012-08-02 14:51:47 -0700863 const int num_depth_stencil_bits = 2;
Chad Versaceb2d428c2012-07-12 14:17:22 -0700864
865 /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
866 * buffer that has a different number of bits per pixel than the color
867 * buffer. This isn't yet supported here.
868 */
Chad Versace8b5d68d2012-08-02 14:51:47 -0700869 depth_bits[0] = 0;
870 stencil_bits[0] = 0;
871
872 if (fb_type[i] == GL_UNSIGNED_SHORT_5_6_5) {
Chad Versaceb2d428c2012-07-12 14:17:22 -0700873 depth_bits[1] = 16;
874 stencil_bits[1] = 0;
875 } else {
876 depth_bits[1] = 24;
877 stencil_bits[1] = 8;
878 }
879
Chad Versace8b5d68d2012-08-02 14:51:47 -0700880 new_configs = driCreateConfigs(fb_format[i], fb_type[i],
Chad Versaceb2d428c2012-07-12 14:17:22 -0700881 depth_bits,
882 stencil_bits,
Chad Versace8b5d68d2012-08-02 14:51:47 -0700883 num_depth_stencil_bits,
Chad Versaceb2d428c2012-07-12 14:17:22 -0700884 back_buffer_modes,
885 ARRAY_SIZE(back_buffer_modes),
Chad Versace8b5d68d2012-08-02 14:51:47 -0700886 singlesample_samples, 1,
Chad Versaceb2d428c2012-07-12 14:17:22 -0700887 false);
Chad Versacea4bf68c2012-08-01 21:23:47 -0700888 configs = driConcatConfigs(configs, new_configs);
Chad Versaceb2d428c2012-07-12 14:17:22 -0700889 }
890
891 /* Generate the minimum possible set of configs that include an
892 * accumulation buffer.
893 */
Chad Versace8b5d68d2012-08-02 14:51:47 -0700894 for (int i = 0; i < ARRAY_SIZE(fb_format); i++) {
Chad Versaceb2d428c2012-07-12 14:17:22 -0700895 __DRIconfig **new_configs;
896
Chad Versace8b5d68d2012-08-02 14:51:47 -0700897 if (fb_type[i] == GL_UNSIGNED_SHORT_5_6_5) {
Chad Versaceb2d428c2012-07-12 14:17:22 -0700898 depth_bits[0] = 16;
899 stencil_bits[0] = 0;
900 } else {
901 depth_bits[0] = 24;
902 stencil_bits[0] = 8;
903 }
904
Chad Versace8b5d68d2012-08-02 14:51:47 -0700905 new_configs = driCreateConfigs(fb_format[i], fb_type[i],
Chad Versaceb2d428c2012-07-12 14:17:22 -0700906 depth_bits, stencil_bits, 1,
907 back_buffer_modes + 1, 1,
Chad Versace8b5d68d2012-08-02 14:51:47 -0700908 singlesample_samples, 1,
Chad Versaceb2d428c2012-07-12 14:17:22 -0700909 true);
Chad Versacea4bf68c2012-08-01 21:23:47 -0700910 configs = driConcatConfigs(configs, new_configs);
Chad Versaceb2d428c2012-07-12 14:17:22 -0700911 }
912
Chad Versacee943e5c2012-08-02 17:13:17 -0700913 /* Generate multisample configs.
914 *
915 * This loop breaks early, and hence is a no-op, on gen < 6.
916 *
917 * Multisample configs must follow the singlesample configs in order to
918 * work around an X server bug present in 1.12. The X server chooses to
919 * associate the first listed RGBA888-Z24S8 config, regardless of its
920 * sample count, with the 32-bit depth visual used for compositing.
921 *
922 * Only doublebuffer configs with GLX_SWAP_UNDEFINED_OML behavior are
923 * supported. Singlebuffer configs are not supported because no one wants
924 * them. GLX_SWAP_COPY_OML is not supported due to page flipping.
925 */
926 for (int i = 0; i < ARRAY_SIZE(fb_format); i++) {
927 if (screen->gen < 6)
928 break;
929
930 __DRIconfig **new_configs;
931 const int num_depth_stencil_bits = 2;
Eric Anholt3aaeb3e2012-08-07 11:33:10 -0700932 int num_msaa_modes = 0;
Chad Versacee943e5c2012-08-02 17:13:17 -0700933
934 depth_bits[0] = 0;
935 stencil_bits[0] = 0;
936
937 if (fb_type[i] == GL_UNSIGNED_SHORT_5_6_5) {
938 depth_bits[1] = 16;
939 stencil_bits[1] = 0;
940 } else {
941 depth_bits[1] = 24;
942 stencil_bits[1] = 8;
943 }
944
945 if (screen->gen >= 7)
946 num_msaa_modes = 2;
947 else if (screen->gen == 6)
948 num_msaa_modes = 1;
949
950 new_configs = driCreateConfigs(fb_format[i], fb_type[i],
951 depth_bits,
952 stencil_bits,
953 num_depth_stencil_bits,
954 back_buffer_modes + 1, 1,
955 multisample_samples,
956 num_msaa_modes,
957 false);
958 configs = driConcatConfigs(configs, new_configs);
959 }
960
Chad Versaceb2d428c2012-07-12 14:17:22 -0700961 if (configs == NULL) {
962 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
963 __LINE__);
964 return NULL;
965 }
966
967 return configs;
968}
969
Chad Versace6b2bf272011-05-26 15:24:48 -0700970/**
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500971 * This is the driver specific part of the createNewScreen entry point.
Brian Paul8d976ae2008-06-11 19:33:14 -0600972 * Called when using DRI2.
973 *
Kristian Høgsbergd3491e72010-10-12 11:58:47 -0400974 * \return the struct gl_config supported by this driver
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500975 */
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -0400976static const
Kristian Høgsbergd61f0732010-01-01 17:09:12 -0500977__DRIconfig **intelInitScreen2(__DRIscreen *psp)
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500978{
Kristian Høgsberg5777dee2010-02-11 16:44:21 -0500979 struct intel_screen *intelScreen;
Kristian Høgsberg5efee4d2010-04-27 21:43:40 -0400980 unsigned int api_mask;
Kristian Høgsberg7c50d292010-01-08 12:35:47 -0500981
Eric Anholt1b4374d2012-07-04 10:52:34 -0700982 if (psp->dri2.loader->base.version <= 2 ||
983 psp->dri2.loader->getBuffersWithFormat == NULL) {
984 fprintf(stderr,
985 "\nERROR! DRI2 loader with getBuffersWithFormat() "
986 "support required\n");
987 return false;
988 }
989
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500990 /* Allocate the private area */
Kristian Høgsberg5777dee2010-02-11 16:44:21 -0500991 intelScreen = CALLOC(sizeof *intelScreen);
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500992 if (!intelScreen) {
993 fprintf(stderr, "\nERROR! Allocating private area failed\n");
Kenneth Graunke2e5a1a22011-10-07 12:26:50 -0700994 return false;
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -0500995 }
996 /* parse information in __driConfigOptions */
997 driParseOptionInfo(&intelScreen->optionCache,
998 __driConfigOptions, __driNConfigOptions);
999
1000 intelScreen->driScrnPriv = psp;
George Sapountzis875a7572011-11-03 13:04:57 +02001001 psp->driverPrivate = (void *) intelScreen;
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001002
Eric Anholt2222aa02012-03-09 16:27:35 -08001003 if (!intel_init_bufmgr(intelScreen))
1004 return false;
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001005
Eric Anholt2222aa02012-03-09 16:27:35 -08001006 intelScreen->deviceID = drm_intel_bufmgr_gem_get_devid(intelScreen->bufmgr);
Eric Anholt4ac2f092010-12-02 18:25:45 -08001007
Eric Anholtcd2a24a2011-12-29 23:37:17 -08001008 intelScreen->kernel_has_gen7_sol_reset =
1009 intel_get_boolean(intelScreen->driScrnPriv,
1010 I915_PARAM_HAS_GEN7_SOL_RESET);
1011
Kenneth Graunke89a82d72011-05-16 15:19:22 -07001012 if (IS_GEN7(intelScreen->deviceID)) {
1013 intelScreen->gen = 7;
1014 } else if (IS_GEN6(intelScreen->deviceID)) {
Kristian Høgsberg73630882011-04-25 09:49:09 -04001015 intelScreen->gen = 6;
1016 } else if (IS_GEN5(intelScreen->deviceID)) {
1017 intelScreen->gen = 5;
1018 } else if (IS_965(intelScreen->deviceID)) {
1019 intelScreen->gen = 4;
1020 } else if (IS_9XX(intelScreen->deviceID)) {
1021 intelScreen->gen = 3;
1022 } else {
1023 intelScreen->gen = 2;
1024 }
1025
Chad Versacee5411d82011-11-17 08:53:39 -08001026 intelScreen->hw_has_separate_stencil = intelScreen->gen >= 6;
Chad Versace6b2bf272011-05-26 15:24:48 -07001027 intelScreen->hw_must_use_separate_stencil = intelScreen->gen >= 7;
Chad Versace6b2bf272011-05-26 15:24:48 -07001028
Eric Anholt249fc702012-03-21 14:35:14 -07001029 int has_llc = 0;
1030 bool success = intel_get_param(intelScreen->driScrnPriv, I915_PARAM_HAS_LLC,
1031 &has_llc);
1032 if (success && has_llc)
1033 intelScreen->hw_has_llc = true;
1034 else if (!success && intelScreen->gen >= 6)
1035 intelScreen->hw_has_llc = true;
Eugeni Dodonov7def2932012-02-01 18:06:53 -02001036
Chad Versace6b2bf272011-05-26 15:24:48 -07001037 intel_override_separate_stencil(intelScreen);
1038
Kristian Høgsberg5efee4d2010-04-27 21:43:40 -04001039 api_mask = (1 << __DRI_API_OPENGL);
1040#if FEATURE_ES1
1041 api_mask |= (1 << __DRI_API_GLES);
1042#endif
1043#if FEATURE_ES2
1044 api_mask |= (1 << __DRI_API_GLES2);
1045#endif
1046
1047 if (IS_9XX(intelScreen->deviceID) || IS_965(intelScreen->deviceID))
1048 psp->api_mask = api_mask;
1049
Daniel Vetterf172eae2012-03-02 21:38:44 +01001050 intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen);
1051
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -04001052 psp->extensions = intelScreenExtensions;
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001053
Chad Versaceb2d428c2012-07-12 14:17:22 -07001054 return (const __DRIconfig**) intel_screen_make_configs(psp);
Kristian Høgsbergc5c73c12008-01-21 17:07:33 -05001055}
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -04001056
Benjamin Franzke2adfde32011-02-04 12:01:31 +01001057struct intel_buffer {
1058 __DRIbuffer base;
1059 struct intel_region *region;
1060};
1061
1062static __DRIbuffer *
1063intelAllocateBuffer(__DRIscreen *screen,
1064 unsigned attachment, unsigned format,
1065 int width, int height)
1066{
1067 struct intel_buffer *intelBuffer;
George Sapountzis875a7572011-11-03 13:04:57 +02001068 struct intel_screen *intelScreen = screen->driverPrivate;
Chad Versace79653c12011-11-15 07:08:49 -08001069
Chad Versace83fa0842012-07-09 15:51:06 -07001070 assert(attachment == __DRI_BUFFER_FRONT_LEFT ||
1071 attachment == __DRI_BUFFER_BACK_LEFT);
Benjamin Franzke2adfde32011-02-04 12:01:31 +01001072
1073 intelBuffer = CALLOC(sizeof *intelBuffer);
1074 if (intelBuffer == NULL)
1075 return NULL;
1076
Chad Versace83fa0842012-07-09 15:51:06 -07001077 /* The front and back buffers are color buffers, which are X tiled. */
Chad Versace79653c12011-11-15 07:08:49 -08001078 intelBuffer->region = intel_region_alloc(intelScreen,
Chad Versace83fa0842012-07-09 15:51:06 -07001079 I915_TILING_X,
1080 format / 8,
1081 width,
1082 height,
Chad Versace79653c12011-11-15 07:08:49 -08001083 true);
Benjamin Franzke2adfde32011-02-04 12:01:31 +01001084
1085 if (intelBuffer->region == NULL) {
1086 FREE(intelBuffer);
1087 return NULL;
1088 }
1089
1090 intel_region_flink(intelBuffer->region, &intelBuffer->base.name);
1091
1092 intelBuffer->base.attachment = attachment;
1093 intelBuffer->base.cpp = intelBuffer->region->cpp;
1094 intelBuffer->base.pitch =
1095 intelBuffer->region->pitch * intelBuffer->region->cpp;
1096
1097 return &intelBuffer->base;
1098}
1099
1100static void
1101intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
1102{
1103 struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
1104
1105 intel_region_release(&intelBuffer->region);
1106 free(intelBuffer);
1107}
1108
1109
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -04001110const struct __DriverAPIRec driDriverAPI = {
George Sapountzis7192c372011-11-03 12:46:08 +02001111 .InitScreen = intelInitScreen2,
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -04001112 .DestroyScreen = intelDestroyScreen,
1113 .CreateContext = intelCreateContext,
1114 .DestroyContext = intelDestroyContext,
1115 .CreateBuffer = intelCreateBuffer,
1116 .DestroyBuffer = intelDestroyBuffer,
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -04001117 .MakeCurrent = intelMakeCurrent,
1118 .UnbindContext = intelUnbindContext,
Benjamin Franzke2adfde32011-02-04 12:01:31 +01001119 .AllocateBuffer = intelAllocateBuffer,
1120 .ReleaseBuffer = intelReleaseBuffer
Kristian Høgsberge82dd8c2008-03-26 19:26:59 -04001121};
Kristian Høgsberg39a0e4e2010-01-01 17:56:29 -05001122
1123/* This is the table of extensions that the loader will dlsym() for. */
1124PUBLIC const __DRIextension *__driDriverExtensions[] = {
1125 &driCoreExtension.base,
Kristian Høgsberg39a0e4e2010-01-01 17:56:29 -05001126 &driDRI2Extension.base,
1127 NULL
1128};