i965: Move the remaining intel code to the i965 directory.
[mesa.git] / src / mesa / drivers / dri / i965 / intel_screen.c
1 /**************************************************************************
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
28 #include <errno.h>
29 #include <time.h>
30 #include "main/glheader.h"
31 #include "main/context.h"
32 #include "main/framebuffer.h"
33 #include "main/renderbuffer.h"
34 #include "main/texobj.h"
35 #include "main/hash.h"
36 #include "main/fbobject.h"
37 #include "main/version.h"
38 #include "swrast/s_renderbuffer.h"
39
40 #include "utils.h"
41 #include "xmlpool.h"
42
43 PUBLIC const char __driConfigOptions[] =
44 DRI_CONF_BEGIN
45 DRI_CONF_SECTION_PERFORMANCE
46 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC)
47 /* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
48 * DRI_CONF_BO_REUSE_ALL
49 */
50 DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1")
51 DRI_CONF_DESC_BEGIN(en, "Buffer object reuse")
52 DRI_CONF_ENUM(0, "Disable buffer object reuse")
53 DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects")
54 DRI_CONF_DESC_END
55 DRI_CONF_OPT_END
56
57 DRI_CONF_OPT_BEGIN_B(hiz, "true")
58 DRI_CONF_DESC(en, "Enable Hierarchical Z on gen6+")
59 DRI_CONF_OPT_END
60
61 DRI_CONF_OPT_BEGIN_B(early_z, "false")
62 DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
63 DRI_CONF_OPT_END
64
65 DRI_CONF_SECTION_END
66 DRI_CONF_SECTION_QUALITY
67 DRI_CONF_FORCE_S3TC_ENABLE("false")
68 DRI_CONF_ALLOW_LARGE_TEXTURES(2)
69 DRI_CONF_SECTION_END
70 DRI_CONF_SECTION_DEBUG
71 DRI_CONF_NO_RAST("false")
72 DRI_CONF_ALWAYS_FLUSH_BATCH("false")
73 DRI_CONF_ALWAYS_FLUSH_CACHE("false")
74 DRI_CONF_DISABLE_THROTTLING("false")
75 DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN("false")
76 DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS("false")
77 DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED("false")
78
79 DRI_CONF_OPT_BEGIN_B(shader_precompile, "true")
80 DRI_CONF_DESC(en, "Perform code generation at shader link time.")
81 DRI_CONF_OPT_END
82 DRI_CONF_SECTION_END
83 DRI_CONF_END;
84
85 const GLuint __driNConfigOptions = 14;
86
87 #include "intel_batchbuffer.h"
88 #include "intel_buffers.h"
89 #include "intel_bufmgr.h"
90 #include "intel_chipset.h"
91 #include "intel_fbo.h"
92 #include "intel_mipmap_tree.h"
93 #include "intel_screen.h"
94 #include "intel_tex.h"
95 #include "intel_regions.h"
96
97 #ifndef I915
98 #include "brw_context.h"
99 #endif
100
101 #include "i915_drm.h"
102
103 #ifdef USE_NEW_INTERFACE
104 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
105 #endif /*USE_NEW_INTERFACE */
106
107 /**
108 * For debugging purposes, this returns a time in seconds.
109 */
110 double
111 get_time(void)
112 {
113 struct timespec tp;
114
115 clock_gettime(CLOCK_MONOTONIC, &tp);
116
117 return tp.tv_sec + tp.tv_nsec / 1000000000.0;
118 }
119
120 void
121 aub_dump_bmp(struct gl_context *ctx)
122 {
123 struct gl_framebuffer *fb = ctx->DrawBuffer;
124
125 for (int i = 0; i < fb->_NumColorDrawBuffers; i++) {
126 struct intel_renderbuffer *irb =
127 intel_renderbuffer(fb->_ColorDrawBuffers[i]);
128
129 if (irb && irb->mt) {
130 enum aub_dump_bmp_format format;
131
132 switch (irb->Base.Base.Format) {
133 case MESA_FORMAT_ARGB8888:
134 case MESA_FORMAT_XRGB8888:
135 format = AUB_DUMP_BMP_FORMAT_ARGB_8888;
136 break;
137 default:
138 continue;
139 }
140
141 assert(irb->mt->region->pitch % irb->mt->region->cpp == 0);
142 drm_intel_gem_bo_aub_dump_bmp(irb->mt->region->bo,
143 irb->draw_x,
144 irb->draw_y,
145 irb->Base.Base.Width,
146 irb->Base.Base.Height,
147 format,
148 irb->mt->region->pitch,
149 0);
150 }
151 }
152 }
153
154 static const __DRItexBufferExtension intelTexBufferExtension = {
155 .base = { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
156
157 .setTexBuffer = intelSetTexBuffer,
158 .setTexBuffer2 = intelSetTexBuffer2,
159 .releaseTexBuffer = NULL,
160 };
161
162 static void
163 intelDRI2Flush(__DRIdrawable *drawable)
164 {
165 GET_CURRENT_CONTEXT(ctx);
166 struct intel_context *intel = intel_context(ctx);
167 if (intel == NULL)
168 return;
169
170 if (intel->gen < 4)
171 INTEL_FIREVERTICES(intel);
172
173 intel_resolve_for_dri2_flush(intel, drawable);
174 intel->need_throttle = true;
175
176 if (intel->batch.used)
177 intel_batchbuffer_flush(intel);
178
179 if (INTEL_DEBUG & DEBUG_AUB) {
180 aub_dump_bmp(ctx);
181 }
182 }
183
184 static const struct __DRI2flushExtensionRec intelFlushExtension = {
185 .base = { __DRI2_FLUSH, 3 },
186
187 .flush = intelDRI2Flush,
188 .invalidate = dri2InvalidateDrawable,
189 };
190
191 static struct intel_image_format intel_image_formats[] = {
192 { __DRI_IMAGE_FOURCC_ARGB8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
193 { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } },
194
195 { __DRI_IMAGE_FOURCC_XRGB8888, __DRI_IMAGE_COMPONENTS_RGB, 1,
196 { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB8888, 4 }, } },
197
198 { __DRI_IMAGE_FOURCC_YUV410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
199 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
200 { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 },
201 { 2, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 } } },
202
203 { __DRI_IMAGE_FOURCC_YUV411, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
204 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
205 { 1, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 },
206 { 2, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
207
208 { __DRI_IMAGE_FOURCC_YUV420, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
209 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
210 { 1, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 },
211 { 2, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 } } },
212
213 { __DRI_IMAGE_FOURCC_YUV422, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
214 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
215 { 1, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 },
216 { 2, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
217
218 { __DRI_IMAGE_FOURCC_YUV444, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
219 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
220 { 1, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
221 { 2, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
222
223 { __DRI_IMAGE_FOURCC_NV12, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
224 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
225 { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88, 2 } } },
226
227 { __DRI_IMAGE_FOURCC_NV16, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
228 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
229 { 1, 1, 0, __DRI_IMAGE_FORMAT_GR88, 2 } } },
230
231 /* For YUYV buffers, we set up two overlapping DRI images and treat
232 * them as planar buffers in the compositors. Plane 0 is GR88 and
233 * samples YU or YV pairs and places Y into the R component, while
234 * plane 1 is ARGB and samples YUYV clusters and places pairs and
235 * places U into the G component and V into A. This lets the
236 * texture sampler interpolate the Y components correctly when
237 * sampling from plane 0, and interpolate U and V correctly when
238 * sampling from plane 1. */
239 { __DRI_IMAGE_FOURCC_YUYV, __DRI_IMAGE_COMPONENTS_Y_XUXV, 2,
240 { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 },
241 { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } }
242 };
243
244 static __DRIimage *
245 intel_allocate_image(int dri_format, void *loaderPrivate)
246 {
247 __DRIimage *image;
248
249 image = calloc(1, sizeof *image);
250 if (image == NULL)
251 return NULL;
252
253 image->dri_format = dri_format;
254 image->offset = 0;
255
256 switch (dri_format) {
257 case __DRI_IMAGE_FORMAT_RGB565:
258 image->format = MESA_FORMAT_RGB565;
259 break;
260 case __DRI_IMAGE_FORMAT_XRGB8888:
261 image->format = MESA_FORMAT_XRGB8888;
262 break;
263 case __DRI_IMAGE_FORMAT_ARGB8888:
264 image->format = MESA_FORMAT_ARGB8888;
265 break;
266 case __DRI_IMAGE_FORMAT_ABGR8888:
267 image->format = MESA_FORMAT_RGBA8888_REV;
268 break;
269 case __DRI_IMAGE_FORMAT_XBGR8888:
270 image->format = MESA_FORMAT_RGBX8888_REV;
271 break;
272 case __DRI_IMAGE_FORMAT_R8:
273 image->format = MESA_FORMAT_R8;
274 break;
275 case __DRI_IMAGE_FORMAT_GR88:
276 image->format = MESA_FORMAT_GR88;
277 break;
278 case __DRI_IMAGE_FORMAT_NONE:
279 image->format = MESA_FORMAT_NONE;
280 break;
281 default:
282 free(image);
283 return NULL;
284 }
285
286 image->internal_format = _mesa_get_format_base_format(image->format);
287 image->data = loaderPrivate;
288
289 return image;
290 }
291
292 /**
293 * Sets up a DRIImage structure to point to our shared image in a region
294 */
295 static void
296 intel_setup_image_from_mipmap_tree(struct intel_context *intel, __DRIimage *image,
297 struct intel_mipmap_tree *mt, GLuint level,
298 GLuint zoffset)
299 {
300 unsigned int draw_x, draw_y;
301 uint32_t mask_x, mask_y;
302
303 intel_miptree_make_shareable(intel, mt);
304
305 intel_miptree_check_level_layer(mt, level, zoffset);
306
307 intel_region_get_tile_masks(mt->region, &mask_x, &mask_y, false);
308 intel_miptree_get_image_offset(mt, level, zoffset, &draw_x, &draw_y);
309
310 image->width = mt->level[level].width;
311 image->height = mt->level[level].height;
312 image->tile_x = draw_x & mask_x;
313 image->tile_y = draw_y & mask_y;
314
315 image->offset = intel_region_get_aligned_offset(mt->region,
316 draw_x & ~mask_x,
317 draw_y & ~mask_y,
318 false);
319
320 intel_region_reference(&image->region, mt->region);
321 }
322
323 static void
324 intel_setup_image_from_dimensions(__DRIimage *image)
325 {
326 image->width = image->region->width;
327 image->height = image->region->height;
328 image->tile_x = 0;
329 image->tile_y = 0;
330 image->has_depthstencil = false;
331 }
332
333 static inline uint32_t
334 intel_dri_format(GLuint format)
335 {
336 switch (format) {
337 case MESA_FORMAT_RGB565:
338 return __DRI_IMAGE_FORMAT_RGB565;
339 case MESA_FORMAT_XRGB8888:
340 return __DRI_IMAGE_FORMAT_XRGB8888;
341 case MESA_FORMAT_ARGB8888:
342 return __DRI_IMAGE_FORMAT_ARGB8888;
343 case MESA_FORMAT_RGBA8888_REV:
344 return __DRI_IMAGE_FORMAT_ABGR8888;
345 case MESA_FORMAT_R8:
346 return __DRI_IMAGE_FORMAT_R8;
347 case MESA_FORMAT_RG88:
348 return __DRI_IMAGE_FORMAT_GR88;
349 }
350
351 return MESA_FORMAT_NONE;
352 }
353
354 static __DRIimage *
355 intel_create_image_from_name(__DRIscreen *screen,
356 int width, int height, int format,
357 int name, int pitch, void *loaderPrivate)
358 {
359 struct intel_screen *intelScreen = screen->driverPrivate;
360 __DRIimage *image;
361 int cpp;
362
363 image = intel_allocate_image(format, loaderPrivate);
364 if (image == NULL)
365 return NULL;
366
367 if (image->format == MESA_FORMAT_NONE)
368 cpp = 1;
369 else
370 cpp = _mesa_get_format_bytes(image->format);
371 image->region = intel_region_alloc_for_handle(intelScreen,
372 cpp, width, height,
373 pitch * cpp, name, "image");
374 if (image->region == NULL) {
375 free(image);
376 return NULL;
377 }
378
379 intel_setup_image_from_dimensions(image);
380
381 return image;
382 }
383
384 static __DRIimage *
385 intel_create_image_from_renderbuffer(__DRIcontext *context,
386 int renderbuffer, void *loaderPrivate)
387 {
388 __DRIimage *image;
389 struct intel_context *intel = context->driverPrivate;
390 struct gl_renderbuffer *rb;
391 struct intel_renderbuffer *irb;
392
393 rb = _mesa_lookup_renderbuffer(&intel->ctx, renderbuffer);
394 if (!rb) {
395 _mesa_error(&intel->ctx,
396 GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
397 return NULL;
398 }
399
400 irb = intel_renderbuffer(rb);
401 intel_miptree_make_shareable(intel, irb->mt);
402 image = calloc(1, sizeof *image);
403 if (image == NULL)
404 return NULL;
405
406 image->internal_format = rb->InternalFormat;
407 image->format = rb->Format;
408 image->offset = 0;
409 image->data = loaderPrivate;
410 intel_region_reference(&image->region, irb->mt->region);
411 intel_setup_image_from_dimensions(image);
412 image->dri_format = intel_dri_format(image->format);
413 image->has_depthstencil = irb->mt->stencil_mt? true : false;
414
415 rb->NeedsFinishRenderTexture = true;
416 return image;
417 }
418
419 static __DRIimage *
420 intel_create_image_from_texture(__DRIcontext *context, int target,
421 unsigned texture, int zoffset,
422 int level,
423 unsigned *error,
424 void *loaderPrivate)
425 {
426 __DRIimage *image;
427 struct intel_context *intel = context->driverPrivate;
428 struct gl_texture_object *obj;
429 struct intel_texture_object *iobj;
430 GLuint face = 0;
431
432 obj = _mesa_lookup_texture(&intel->ctx, texture);
433 if (!obj || obj->Target != target) {
434 *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
435 return NULL;
436 }
437
438 if (target == GL_TEXTURE_CUBE_MAP)
439 face = zoffset;
440
441 _mesa_test_texobj_completeness(&intel->ctx, obj);
442 iobj = intel_texture_object(obj);
443 if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) {
444 *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
445 return NULL;
446 }
447
448 if (level < obj->BaseLevel || level > obj->_MaxLevel) {
449 *error = __DRI_IMAGE_ERROR_BAD_MATCH;
450 return NULL;
451 }
452
453 if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < zoffset) {
454 *error = __DRI_IMAGE_ERROR_BAD_MATCH;
455 return NULL;
456 }
457 image = calloc(1, sizeof *image);
458 if (image == NULL) {
459 *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
460 return NULL;
461 }
462
463 image->internal_format = obj->Image[face][level]->InternalFormat;
464 image->format = obj->Image[face][level]->TexFormat;
465 image->data = loaderPrivate;
466 intel_setup_image_from_mipmap_tree(intel, image, iobj->mt, level, zoffset);
467 image->dri_format = intel_dri_format(image->format);
468 image->has_depthstencil = iobj->mt->stencil_mt? true : false;
469 if (image->dri_format == MESA_FORMAT_NONE) {
470 *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
471 free(image);
472 return NULL;
473 }
474
475 *error = __DRI_IMAGE_ERROR_SUCCESS;
476 return image;
477 }
478
479 static void
480 intel_destroy_image(__DRIimage *image)
481 {
482 intel_region_release(&image->region);
483 free(image);
484 }
485
486 static __DRIimage *
487 intel_create_image(__DRIscreen *screen,
488 int width, int height, int format,
489 unsigned int use,
490 void *loaderPrivate)
491 {
492 __DRIimage *image;
493 struct intel_screen *intelScreen = screen->driverPrivate;
494 uint32_t tiling;
495 int cpp;
496
497 tiling = I915_TILING_X;
498 if (use & __DRI_IMAGE_USE_CURSOR) {
499 if (width != 64 || height != 64)
500 return NULL;
501 tiling = I915_TILING_NONE;
502 }
503
504 image = intel_allocate_image(format, loaderPrivate);
505 if (image == NULL)
506 return NULL;
507
508 cpp = _mesa_get_format_bytes(image->format);
509 image->region =
510 intel_region_alloc(intelScreen, tiling, cpp, width, height, true);
511 if (image->region == NULL) {
512 free(image);
513 return NULL;
514 }
515
516 intel_setup_image_from_dimensions(image);
517
518 return image;
519 }
520
521 static GLboolean
522 intel_query_image(__DRIimage *image, int attrib, int *value)
523 {
524 switch (attrib) {
525 case __DRI_IMAGE_ATTRIB_STRIDE:
526 *value = image->region->pitch;
527 return true;
528 case __DRI_IMAGE_ATTRIB_HANDLE:
529 *value = image->region->bo->handle;
530 return true;
531 case __DRI_IMAGE_ATTRIB_NAME:
532 return intel_region_flink(image->region, (uint32_t *) value);
533 case __DRI_IMAGE_ATTRIB_FORMAT:
534 *value = image->dri_format;
535 return true;
536 case __DRI_IMAGE_ATTRIB_WIDTH:
537 *value = image->region->width;
538 return true;
539 case __DRI_IMAGE_ATTRIB_HEIGHT:
540 *value = image->region->height;
541 return true;
542 case __DRI_IMAGE_ATTRIB_COMPONENTS:
543 if (image->planar_format == NULL)
544 return false;
545 *value = image->planar_format->components;
546 return true;
547 case __DRI_IMAGE_ATTRIB_FD:
548 if (drm_intel_bo_gem_export_to_prime(image->region->bo, value) == 0)
549 return true;
550 return false;
551 default:
552 return false;
553 }
554 }
555
556 static __DRIimage *
557 intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
558 {
559 __DRIimage *image;
560
561 image = calloc(1, sizeof *image);
562 if (image == NULL)
563 return NULL;
564
565 intel_region_reference(&image->region, orig_image->region);
566 if (image->region == NULL) {
567 free(image);
568 return NULL;
569 }
570
571 image->internal_format = orig_image->internal_format;
572 image->planar_format = orig_image->planar_format;
573 image->dri_format = orig_image->dri_format;
574 image->format = orig_image->format;
575 image->offset = orig_image->offset;
576 image->width = orig_image->width;
577 image->height = orig_image->height;
578 image->tile_x = orig_image->tile_x;
579 image->tile_y = orig_image->tile_y;
580 image->has_depthstencil = orig_image->has_depthstencil;
581 image->data = loaderPrivate;
582
583 memcpy(image->strides, orig_image->strides, sizeof(image->strides));
584 memcpy(image->offsets, orig_image->offsets, sizeof(image->offsets));
585
586 return image;
587 }
588
589 static GLboolean
590 intel_validate_usage(__DRIimage *image, unsigned int use)
591 {
592 if (use & __DRI_IMAGE_USE_CURSOR) {
593 if (image->region->width != 64 || image->region->height != 64)
594 return GL_FALSE;
595 }
596
597 return GL_TRUE;
598 }
599
600 static __DRIimage *
601 intel_create_image_from_names(__DRIscreen *screen,
602 int width, int height, int fourcc,
603 int *names, int num_names,
604 int *strides, int *offsets,
605 void *loaderPrivate)
606 {
607 struct intel_image_format *f = NULL;
608 __DRIimage *image;
609 int i, index;
610
611 if (screen == NULL || names == NULL || num_names != 1)
612 return NULL;
613
614 for (i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
615 if (intel_image_formats[i].fourcc == fourcc) {
616 f = &intel_image_formats[i];
617 }
618 }
619
620 if (f == NULL)
621 return NULL;
622
623 image = intel_create_image_from_name(screen, width, height,
624 __DRI_IMAGE_FORMAT_NONE,
625 names[0], strides[0],
626 loaderPrivate);
627
628 if (image == NULL)
629 return NULL;
630
631 image->planar_format = f;
632 for (i = 0; i < f->nplanes; i++) {
633 index = f->planes[i].buffer_index;
634 image->offsets[index] = offsets[index];
635 image->strides[index] = strides[index];
636 }
637
638 return image;
639 }
640
641 static __DRIimage *
642 intel_create_image_from_fds(__DRIscreen *screen,
643 int width, int height, int fourcc,
644 int *fds, int num_fds, int *strides, int *offsets,
645 void *loaderPrivate)
646 {
647 struct intel_screen *intelScreen = screen->driverPrivate;
648 struct intel_image_format *f = NULL;
649 __DRIimage *image;
650 int i, index;
651
652 if (fds == NULL || num_fds != 1)
653 return NULL;
654
655 for (i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
656 if (intel_image_formats[i].fourcc == fourcc) {
657 f = &intel_image_formats[i];
658 }
659 }
660
661 if (f == NULL)
662 return NULL;
663
664 image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPrivate);
665 if (image == NULL)
666 return NULL;
667
668 image->region = intel_region_alloc_for_fd(intelScreen,
669 1, width, height,
670 strides[0], fds[0], "image");
671 if (image->region == NULL) {
672 free(image);
673 return NULL;
674 }
675
676 image->planar_format = f;
677 for (i = 0; i < f->nplanes; i++) {
678 index = f->planes[i].buffer_index;
679 image->offsets[index] = offsets[index];
680 image->strides[index] = strides[index];
681 }
682
683 return image;
684 }
685
686
687 static __DRIimage *
688 intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
689 {
690 int width, height, offset, stride, dri_format, index;
691 struct intel_image_format *f;
692 uint32_t mask_x, mask_y;
693 __DRIimage *image;
694
695 if (parent == NULL || parent->planar_format == NULL)
696 return NULL;
697
698 f = parent->planar_format;
699
700 if (plane >= f->nplanes)
701 return NULL;
702
703 width = parent->region->width >> f->planes[plane].width_shift;
704 height = parent->region->height >> f->planes[plane].height_shift;
705 dri_format = f->planes[plane].dri_format;
706 index = f->planes[plane].buffer_index;
707 offset = parent->offsets[index];
708 stride = parent->strides[index];
709
710 image = intel_allocate_image(dri_format, loaderPrivate);
711 if (image == NULL)
712 return NULL;
713
714 if (offset + height * stride > parent->region->bo->size) {
715 _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds");
716 free(image);
717 return NULL;
718 }
719
720 image->region = calloc(sizeof(*image->region), 1);
721 if (image->region == NULL) {
722 free(image);
723 return NULL;
724 }
725
726 image->region->cpp = _mesa_get_format_bytes(image->format);
727 image->region->width = width;
728 image->region->height = height;
729 image->region->pitch = stride;
730 image->region->refcount = 1;
731 image->region->bo = parent->region->bo;
732 drm_intel_bo_reference(image->region->bo);
733 image->region->tiling = parent->region->tiling;
734 image->offset = offset;
735 intel_setup_image_from_dimensions(image);
736
737 intel_region_get_tile_masks(image->region, &mask_x, &mask_y, false);
738 if (offset & mask_x)
739 _mesa_warning(NULL,
740 "intel_create_sub_image: offset not on tile boundary");
741
742 return image;
743 }
744
745 static struct __DRIimageExtensionRec intelImageExtension = {
746 .base = { __DRI_IMAGE, 7 },
747
748 .createImageFromName = intel_create_image_from_name,
749 .createImageFromRenderbuffer = intel_create_image_from_renderbuffer,
750 .destroyImage = intel_destroy_image,
751 .createImage = intel_create_image,
752 .queryImage = intel_query_image,
753 .dupImage = intel_dup_image,
754 .validateUsage = intel_validate_usage,
755 .createImageFromNames = intel_create_image_from_names,
756 .fromPlanar = intel_from_planar,
757 .createImageFromTexture = intel_create_image_from_texture,
758 .createImageFromFds = intel_create_image_from_fds
759 };
760
761 static const __DRIextension *intelScreenExtensions[] = {
762 &intelTexBufferExtension.base,
763 &intelFlushExtension.base,
764 &intelImageExtension.base,
765 &dri2ConfigQueryExtension.base,
766 NULL
767 };
768
769 static bool
770 intel_get_param(__DRIscreen *psp, int param, int *value)
771 {
772 int ret;
773 struct drm_i915_getparam gp;
774
775 memset(&gp, 0, sizeof(gp));
776 gp.param = param;
777 gp.value = value;
778
779 ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
780 if (ret) {
781 if (ret != -EINVAL)
782 _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
783 return false;
784 }
785
786 return true;
787 }
788
789 static bool
790 intel_get_boolean(__DRIscreen *psp, int param)
791 {
792 int value = 0;
793 return intel_get_param(psp, param, &value) && value;
794 }
795
796 static void
797 intelDestroyScreen(__DRIscreen * sPriv)
798 {
799 struct intel_screen *intelScreen = sPriv->driverPrivate;
800
801 dri_bufmgr_destroy(intelScreen->bufmgr);
802 driDestroyOptionInfo(&intelScreen->optionCache);
803
804 free(intelScreen);
805 sPriv->driverPrivate = NULL;
806 }
807
808
809 /**
810 * This is called when we need to set up GL rendering to a new X window.
811 */
812 static GLboolean
813 intelCreateBuffer(__DRIscreen * driScrnPriv,
814 __DRIdrawable * driDrawPriv,
815 const struct gl_config * mesaVis, GLboolean isPixmap)
816 {
817 struct intel_renderbuffer *rb;
818 struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate;
819 gl_format rgbFormat;
820 unsigned num_samples = intel_quantize_num_samples(screen, mesaVis->samples);
821 struct gl_framebuffer *fb;
822
823 if (isPixmap)
824 return false;
825
826 fb = CALLOC_STRUCT(gl_framebuffer);
827 if (!fb)
828 return false;
829
830 _mesa_initialize_window_framebuffer(fb, mesaVis);
831
832 if (mesaVis->redBits == 5)
833 rgbFormat = MESA_FORMAT_RGB565;
834 else if (mesaVis->sRGBCapable)
835 rgbFormat = MESA_FORMAT_SARGB8;
836 else if (mesaVis->alphaBits == 0)
837 rgbFormat = MESA_FORMAT_XRGB8888;
838 else {
839 if (screen->gen >= 4) {
840 rgbFormat = MESA_FORMAT_SARGB8;
841 fb->Visual.sRGBCapable = true;
842 } else {
843 rgbFormat = MESA_FORMAT_ARGB8888;
844 }
845
846 }
847
848 /* setup the hardware-based renderbuffers */
849 rb = intel_create_renderbuffer(rgbFormat, num_samples);
850 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base.Base);
851
852 if (mesaVis->doubleBufferMode) {
853 rb = intel_create_renderbuffer(rgbFormat, num_samples);
854 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base.Base);
855 }
856
857 /*
858 * Assert here that the gl_config has an expected depth/stencil bit
859 * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
860 * which constructs the advertised configs.)
861 */
862 if (mesaVis->depthBits == 24) {
863 assert(mesaVis->stencilBits == 8);
864
865 if (screen->hw_has_separate_stencil) {
866 rb = intel_create_private_renderbuffer(MESA_FORMAT_X8_Z24,
867 num_samples);
868 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
869 rb = intel_create_private_renderbuffer(MESA_FORMAT_S8,
870 num_samples);
871 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
872 } else {
873 /*
874 * Use combined depth/stencil. Note that the renderbuffer is
875 * attached to two attachment points.
876 */
877 rb = intel_create_private_renderbuffer(MESA_FORMAT_S8_Z24,
878 num_samples);
879 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
880 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
881 }
882 }
883 else if (mesaVis->depthBits == 16) {
884 assert(mesaVis->stencilBits == 0);
885 rb = intel_create_private_renderbuffer(MESA_FORMAT_Z16,
886 num_samples);
887 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
888 }
889 else {
890 assert(mesaVis->depthBits == 0);
891 assert(mesaVis->stencilBits == 0);
892 }
893
894 /* now add any/all software-based renderbuffers we may need */
895 _swrast_add_soft_renderbuffers(fb,
896 false, /* never sw color */
897 false, /* never sw depth */
898 false, /* never sw stencil */
899 mesaVis->accumRedBits > 0,
900 false, /* never sw alpha */
901 false /* never sw aux */ );
902 driDrawPriv->driverPrivate = fb;
903
904 return true;
905 }
906
907 static void
908 intelDestroyBuffer(__DRIdrawable * driDrawPriv)
909 {
910 struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
911
912 _mesa_reference_framebuffer(&fb, NULL);
913 }
914
915 /* There are probably better ways to do this, such as an
916 * init-designated function to register chipids and createcontext
917 * functions.
918 */
919 extern bool
920 i830CreateContext(int api,
921 const struct gl_config *mesaVis,
922 __DRIcontext *driContextPriv,
923 unsigned major_version,
924 unsigned minor_version,
925 unsigned *error,
926 void *sharedContextPrivate);
927
928 extern bool
929 i915CreateContext(int api,
930 const struct gl_config *mesaVis,
931 __DRIcontext *driContextPriv,
932 unsigned major_version,
933 unsigned minor_version,
934 unsigned *error,
935 void *sharedContextPrivate);
936 extern bool
937 brwCreateContext(int api,
938 const struct gl_config *mesaVis,
939 __DRIcontext *driContextPriv,
940 unsigned major_version,
941 unsigned minor_version,
942 uint32_t flags,
943 unsigned *error,
944 void *sharedContextPrivate);
945
946 static GLboolean
947 intelCreateContext(gl_api api,
948 const struct gl_config * mesaVis,
949 __DRIcontext * driContextPriv,
950 unsigned major_version,
951 unsigned minor_version,
952 uint32_t flags,
953 unsigned *error,
954 void *sharedContextPrivate)
955 {
956 bool success = false;
957
958 #ifdef I915
959 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
960 struct intel_screen *intelScreen = sPriv->driverPrivate;
961
962 if (IS_9XX(intelScreen->deviceID)) {
963 success = i915CreateContext(api, mesaVis, driContextPriv,
964 major_version, minor_version, error,
965 sharedContextPrivate);
966 } else {
967 intelScreen->no_vbo = true;
968 success = i830CreateContext(api, mesaVis, driContextPriv,
969 major_version, minor_version, error,
970 sharedContextPrivate);
971 }
972 #else
973 success = brwCreateContext(api, mesaVis,
974 driContextPriv,
975 major_version, minor_version, flags,
976 error, sharedContextPrivate);
977 #endif
978
979 if (success)
980 return true;
981
982 if (driContextPriv->driverPrivate != NULL)
983 intelDestroyContext(driContextPriv);
984
985 return false;
986 }
987
988 static bool
989 intel_init_bufmgr(struct intel_screen *intelScreen)
990 {
991 __DRIscreen *spriv = intelScreen->driScrnPriv;
992
993 intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
994
995 intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
996 if (intelScreen->bufmgr == NULL) {
997 fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
998 __func__, __LINE__);
999 return false;
1000 }
1001
1002 drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
1003
1004 if (!intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA)) {
1005 fprintf(stderr, "[%s: %u] Kernel 2.6.39 required.\n", __func__, __LINE__);
1006 return false;
1007 }
1008
1009 return true;
1010 }
1011
1012 /**
1013 * Override intel_screen.hw_has_separate_stencil with environment variable
1014 * INTEL_SEPARATE_STENCIL.
1015 *
1016 * Valid values for INTEL_SEPARATE_STENCIL are "0" and "1". If an invalid
1017 * valid value is encountered, a warning is emitted and INTEL_SEPARATE_STENCIL
1018 * is ignored.
1019 */
1020 static void
1021 intel_override_separate_stencil(struct intel_screen *screen)
1022 {
1023 const char *s = getenv("INTEL_SEPARATE_STENCIL");
1024 if (!s) {
1025 return;
1026 } else if (!strncmp("0", s, 2)) {
1027 screen->hw_has_separate_stencil = false;
1028 } else if (!strncmp("1", s, 2)) {
1029 screen->hw_has_separate_stencil = true;
1030 } else {
1031 fprintf(stderr,
1032 "warning: env variable INTEL_SEPARATE_STENCIL=\"%s\" has "
1033 "invalid value and is ignored", s);
1034 }
1035 }
1036
1037 static bool
1038 intel_detect_swizzling(struct intel_screen *screen)
1039 {
1040 drm_intel_bo *buffer;
1041 unsigned long flags = 0;
1042 unsigned long aligned_pitch;
1043 uint32_t tiling = I915_TILING_X;
1044 uint32_t swizzle_mode = 0;
1045
1046 buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "swizzle test",
1047 64, 64, 4,
1048 &tiling, &aligned_pitch, flags);
1049 if (buffer == NULL)
1050 return false;
1051
1052 drm_intel_bo_get_tiling(buffer, &tiling, &swizzle_mode);
1053 drm_intel_bo_unreference(buffer);
1054
1055 if (swizzle_mode == I915_BIT_6_SWIZZLE_NONE)
1056 return false;
1057 else
1058 return true;
1059 }
1060
1061 static __DRIconfig**
1062 intel_screen_make_configs(__DRIscreen *dri_screen)
1063 {
1064 static const gl_format formats[] = {
1065 MESA_FORMAT_RGB565,
1066 MESA_FORMAT_ARGB8888
1067 };
1068
1069 /* GLX_SWAP_COPY_OML is not supported due to page flipping. */
1070 static const GLenum back_buffer_modes[] = {
1071 GLX_SWAP_UNDEFINED_OML, GLX_NONE,
1072 };
1073
1074 static const uint8_t singlesample_samples[1] = {0};
1075 static const uint8_t multisample_samples[2] = {4, 8};
1076
1077 struct intel_screen *screen = dri_screen->driverPrivate;
1078 uint8_t depth_bits[4], stencil_bits[4];
1079 __DRIconfig **configs = NULL;
1080
1081 /* Generate singlesample configs without accumulation buffer. */
1082 for (int i = 0; i < ARRAY_SIZE(formats); i++) {
1083 __DRIconfig **new_configs;
1084 int num_depth_stencil_bits = 2;
1085
1086 /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
1087 * buffer that has a different number of bits per pixel than the color
1088 * buffer, gen >= 6 supports this.
1089 */
1090 depth_bits[0] = 0;
1091 stencil_bits[0] = 0;
1092
1093 if (formats[i] == MESA_FORMAT_RGB565) {
1094 depth_bits[1] = 16;
1095 stencil_bits[1] = 0;
1096 if (screen->gen >= 6) {
1097 depth_bits[2] = 24;
1098 stencil_bits[2] = 8;
1099 num_depth_stencil_bits = 3;
1100 }
1101 } else {
1102 depth_bits[1] = 24;
1103 stencil_bits[1] = 8;
1104 }
1105
1106 new_configs = driCreateConfigs(formats[i],
1107 depth_bits,
1108 stencil_bits,
1109 num_depth_stencil_bits,
1110 back_buffer_modes, 2,
1111 singlesample_samples, 1,
1112 false);
1113 configs = driConcatConfigs(configs, new_configs);
1114 }
1115
1116 /* Generate the minimum possible set of configs that include an
1117 * accumulation buffer.
1118 */
1119 for (int i = 0; i < ARRAY_SIZE(formats); i++) {
1120 __DRIconfig **new_configs;
1121
1122 if (formats[i] == MESA_FORMAT_RGB565) {
1123 depth_bits[0] = 16;
1124 stencil_bits[0] = 0;
1125 } else {
1126 depth_bits[0] = 24;
1127 stencil_bits[0] = 8;
1128 }
1129
1130 new_configs = driCreateConfigs(formats[i],
1131 depth_bits, stencil_bits, 1,
1132 back_buffer_modes, 1,
1133 singlesample_samples, 1,
1134 true);
1135 configs = driConcatConfigs(configs, new_configs);
1136 }
1137
1138 /* Generate multisample configs.
1139 *
1140 * This loop breaks early, and hence is a no-op, on gen < 6.
1141 *
1142 * Multisample configs must follow the singlesample configs in order to
1143 * work around an X server bug present in 1.12. The X server chooses to
1144 * associate the first listed RGBA888-Z24S8 config, regardless of its
1145 * sample count, with the 32-bit depth visual used for compositing.
1146 *
1147 * Only doublebuffer configs with GLX_SWAP_UNDEFINED_OML behavior are
1148 * supported. Singlebuffer configs are not supported because no one wants
1149 * them.
1150 */
1151 for (int i = 0; i < ARRAY_SIZE(formats); i++) {
1152 if (screen->gen < 6)
1153 break;
1154
1155 __DRIconfig **new_configs;
1156 const int num_depth_stencil_bits = 2;
1157 int num_msaa_modes = 0;
1158
1159 depth_bits[0] = 0;
1160 stencil_bits[0] = 0;
1161
1162 if (formats[i] == MESA_FORMAT_RGB565) {
1163 depth_bits[1] = 16;
1164 stencil_bits[1] = 0;
1165 } else {
1166 depth_bits[1] = 24;
1167 stencil_bits[1] = 8;
1168 }
1169
1170 if (screen->gen >= 7)
1171 num_msaa_modes = 2;
1172 else if (screen->gen == 6)
1173 num_msaa_modes = 1;
1174
1175 new_configs = driCreateConfigs(formats[i],
1176 depth_bits,
1177 stencil_bits,
1178 num_depth_stencil_bits,
1179 back_buffer_modes, 1,
1180 multisample_samples,
1181 num_msaa_modes,
1182 false);
1183 configs = driConcatConfigs(configs, new_configs);
1184 }
1185
1186 if (configs == NULL) {
1187 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
1188 __LINE__);
1189 return NULL;
1190 }
1191
1192 return configs;
1193 }
1194
1195 static void
1196 set_max_gl_versions(struct intel_screen *screen)
1197 {
1198 int gl_version_override = _mesa_get_gl_version_override();
1199
1200 switch (screen->gen) {
1201 case 7:
1202 screen->max_gl_core_version = 31;
1203 screen->max_gl_compat_version = 30;
1204 screen->max_gl_es1_version = 11;
1205 screen->max_gl_es2_version = 30;
1206 break;
1207 case 6:
1208 screen->max_gl_core_version = 31;
1209 screen->max_gl_compat_version = 30;
1210 screen->max_gl_es1_version = 11;
1211 screen->max_gl_es2_version = 30;
1212 break;
1213 case 5:
1214 case 4:
1215 screen->max_gl_core_version = 0;
1216 screen->max_gl_compat_version = 21;
1217 screen->max_gl_es1_version = 11;
1218 screen->max_gl_es2_version = 20;
1219 break;
1220 case 3: {
1221 screen->max_gl_core_version = 0;
1222 screen->max_gl_es1_version = 11;
1223 screen->max_gl_compat_version = 21;
1224 screen->max_gl_es2_version = 20;
1225
1226 break;
1227 }
1228 case 2:
1229 screen->max_gl_core_version = 0;
1230 screen->max_gl_compat_version = 13;
1231 screen->max_gl_es1_version = 11;
1232 screen->max_gl_es2_version = 0;
1233 break;
1234 default:
1235 assert(!"unrecognized intel_screen::gen");
1236 break;
1237 }
1238
1239 if (gl_version_override >= 31) {
1240 screen->max_gl_core_version = MAX2(screen->max_gl_core_version,
1241 gl_version_override);
1242 } else {
1243 screen->max_gl_compat_version = MAX2(screen->max_gl_compat_version,
1244 gl_version_override);
1245 }
1246
1247 #ifndef FEATURE_ES1
1248 screen->max_gl_es1_version = 0;
1249 #endif
1250
1251 #ifndef FEATURE_ES2
1252 screen->max_gl_es2_version = 0;
1253 #endif
1254 }
1255
1256 /**
1257 * This is the driver specific part of the createNewScreen entry point.
1258 * Called when using DRI2.
1259 *
1260 * \return the struct gl_config supported by this driver
1261 */
1262 static const
1263 __DRIconfig **intelInitScreen2(__DRIscreen *psp)
1264 {
1265 struct intel_screen *intelScreen;
1266
1267 if (psp->dri2.loader->base.version <= 2 ||
1268 psp->dri2.loader->getBuffersWithFormat == NULL) {
1269 fprintf(stderr,
1270 "\nERROR! DRI2 loader with getBuffersWithFormat() "
1271 "support required\n");
1272 return false;
1273 }
1274
1275 /* Allocate the private area */
1276 intelScreen = calloc(1, sizeof *intelScreen);
1277 if (!intelScreen) {
1278 fprintf(stderr, "\nERROR! Allocating private area failed\n");
1279 return false;
1280 }
1281 /* parse information in __driConfigOptions */
1282 driParseOptionInfo(&intelScreen->optionCache,
1283 __driConfigOptions, __driNConfigOptions);
1284
1285 intelScreen->driScrnPriv = psp;
1286 psp->driverPrivate = (void *) intelScreen;
1287
1288 if (!intel_init_bufmgr(intelScreen))
1289 return false;
1290
1291 intelScreen->deviceID = drm_intel_bufmgr_gem_get_devid(intelScreen->bufmgr);
1292
1293 if (IS_GEN7(intelScreen->deviceID)) {
1294 intelScreen->gen = 7;
1295 } else if (IS_GEN6(intelScreen->deviceID)) {
1296 intelScreen->gen = 6;
1297 } else if (IS_GEN5(intelScreen->deviceID)) {
1298 intelScreen->gen = 5;
1299 } else if (IS_965(intelScreen->deviceID)) {
1300 intelScreen->gen = 4;
1301 } else if (IS_9XX(intelScreen->deviceID)) {
1302 intelScreen->gen = 3;
1303 } else {
1304 intelScreen->gen = 2;
1305 }
1306
1307 intelScreen->hw_has_separate_stencil = intelScreen->gen >= 6;
1308 intelScreen->hw_must_use_separate_stencil = intelScreen->gen >= 7;
1309
1310 int has_llc = 0;
1311 bool success = intel_get_param(intelScreen->driScrnPriv, I915_PARAM_HAS_LLC,
1312 &has_llc);
1313 if (success && has_llc)
1314 intelScreen->hw_has_llc = true;
1315 else if (!success && intelScreen->gen >= 6)
1316 intelScreen->hw_has_llc = true;
1317
1318 intel_override_separate_stencil(intelScreen);
1319
1320 intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen);
1321
1322 set_max_gl_versions(intelScreen);
1323
1324 psp->api_mask = (1 << __DRI_API_OPENGL);
1325 if (intelScreen->max_gl_core_version > 0)
1326 psp->api_mask |= (1 << __DRI_API_OPENGL_CORE);
1327 if (intelScreen->max_gl_es1_version > 0)
1328 psp->api_mask |= (1 << __DRI_API_GLES);
1329 if (intelScreen->max_gl_es2_version > 0)
1330 psp->api_mask |= (1 << __DRI_API_GLES2);
1331 if (intelScreen->max_gl_es2_version >= 30)
1332 psp->api_mask |= (1 << __DRI_API_GLES3);
1333
1334 psp->extensions = intelScreenExtensions;
1335
1336 return (const __DRIconfig**) intel_screen_make_configs(psp);
1337 }
1338
1339 struct intel_buffer {
1340 __DRIbuffer base;
1341 struct intel_region *region;
1342 };
1343
1344 static __DRIbuffer *
1345 intelAllocateBuffer(__DRIscreen *screen,
1346 unsigned attachment, unsigned format,
1347 int width, int height)
1348 {
1349 struct intel_buffer *intelBuffer;
1350 struct intel_screen *intelScreen = screen->driverPrivate;
1351
1352 assert(attachment == __DRI_BUFFER_FRONT_LEFT ||
1353 attachment == __DRI_BUFFER_BACK_LEFT);
1354
1355 intelBuffer = calloc(1, sizeof *intelBuffer);
1356 if (intelBuffer == NULL)
1357 return NULL;
1358
1359 /* The front and back buffers are color buffers, which are X tiled. */
1360 intelBuffer->region = intel_region_alloc(intelScreen,
1361 I915_TILING_X,
1362 format / 8,
1363 width,
1364 height,
1365 true);
1366
1367 if (intelBuffer->region == NULL) {
1368 free(intelBuffer);
1369 return NULL;
1370 }
1371
1372 intel_region_flink(intelBuffer->region, &intelBuffer->base.name);
1373
1374 intelBuffer->base.attachment = attachment;
1375 intelBuffer->base.cpp = intelBuffer->region->cpp;
1376 intelBuffer->base.pitch = intelBuffer->region->pitch;
1377
1378 return &intelBuffer->base;
1379 }
1380
1381 static void
1382 intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
1383 {
1384 struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
1385
1386 intel_region_release(&intelBuffer->region);
1387 free(intelBuffer);
1388 }
1389
1390
1391 const struct __DriverAPIRec driDriverAPI = {
1392 .InitScreen = intelInitScreen2,
1393 .DestroyScreen = intelDestroyScreen,
1394 .CreateContext = intelCreateContext,
1395 .DestroyContext = intelDestroyContext,
1396 .CreateBuffer = intelCreateBuffer,
1397 .DestroyBuffer = intelDestroyBuffer,
1398 .MakeCurrent = intelMakeCurrent,
1399 .UnbindContext = intelUnbindContext,
1400 .AllocateBuffer = intelAllocateBuffer,
1401 .ReleaseBuffer = intelReleaseBuffer
1402 };
1403
1404 /* This is the table of extensions that the loader will dlsym() for. */
1405 PUBLIC const __DRIextension *__driDriverExtensions[] = {
1406 &driCoreExtension.base,
1407 &driDRI2Extension.base,
1408 NULL
1409 };