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