intel: make sure to setup image dimension in image_from_planar setup
[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, 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->region->screen = parent->region->screen;
684 image->offset = offset;
685 intel_setup_image_from_dimensions(image);
686
687 intel_region_get_tile_masks(image->region, &mask_x, &mask_y, false);
688 if (offset & mask_x)
689 _mesa_warning(NULL,
690 "intel_create_sub_image: offset not on tile boundary");
691
692 return image;
693 }
694
695 static struct __DRIimageExtensionRec intelImageExtension = {
696 .base = { __DRI_IMAGE, 6 },
697
698 .createImageFromName = intel_create_image_from_name,
699 .createImageFromRenderbuffer = intel_create_image_from_renderbuffer,
700 .destroyImage = intel_destroy_image,
701 .createImage = intel_create_image,
702 .queryImage = intel_query_image,
703 .dupImage = intel_dup_image,
704 .validateUsage = intel_validate_usage,
705 .createImageFromNames = intel_create_image_from_names,
706 .fromPlanar = intel_from_planar,
707 .createImageFromTexture = intel_create_image_from_texture
708 };
709
710 static const __DRIextension *intelScreenExtensions[] = {
711 &intelTexBufferExtension.base,
712 &intelFlushExtension.base,
713 &intelImageExtension.base,
714 &dri2ConfigQueryExtension.base,
715 NULL
716 };
717
718 static bool
719 intel_get_param(__DRIscreen *psp, int param, int *value)
720 {
721 int ret;
722 struct drm_i915_getparam gp;
723
724 memset(&gp, 0, sizeof(gp));
725 gp.param = param;
726 gp.value = value;
727
728 ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
729 if (ret) {
730 if (ret != -EINVAL)
731 _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
732 return false;
733 }
734
735 return true;
736 }
737
738 static bool
739 intel_get_boolean(__DRIscreen *psp, int param)
740 {
741 int value = 0;
742 return intel_get_param(psp, param, &value) && value;
743 }
744
745 static void
746 nop_callback(GLuint key, void *data, void *userData)
747 {
748 }
749
750 static void
751 intelDestroyScreen(__DRIscreen * sPriv)
752 {
753 struct intel_screen *intelScreen = sPriv->driverPrivate;
754
755 dri_bufmgr_destroy(intelScreen->bufmgr);
756 driDestroyOptionInfo(&intelScreen->optionCache);
757
758 /* Some regions may still have references to them at this point, so
759 * flush the hash table to prevent _mesa_DeleteHashTable() from
760 * complaining about the hash not being empty; */
761 _mesa_HashDeleteAll(intelScreen->named_regions, nop_callback, NULL);
762 _mesa_DeleteHashTable(intelScreen->named_regions);
763
764 free(intelScreen);
765 sPriv->driverPrivate = NULL;
766 }
767
768
769 /**
770 * This is called when we need to set up GL rendering to a new X window.
771 */
772 static GLboolean
773 intelCreateBuffer(__DRIscreen * driScrnPriv,
774 __DRIdrawable * driDrawPriv,
775 const struct gl_config * mesaVis, GLboolean isPixmap)
776 {
777 struct intel_renderbuffer *rb;
778 struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate;
779 gl_format rgbFormat;
780 unsigned num_samples = intel_quantize_num_samples(screen, mesaVis->samples);
781 struct gl_framebuffer *fb;
782
783 if (isPixmap)
784 return false;
785
786 fb = CALLOC_STRUCT(gl_framebuffer);
787 if (!fb)
788 return false;
789
790 _mesa_initialize_window_framebuffer(fb, mesaVis);
791
792 if (mesaVis->redBits == 5)
793 rgbFormat = MESA_FORMAT_RGB565;
794 else if (mesaVis->sRGBCapable)
795 rgbFormat = MESA_FORMAT_SARGB8;
796 else if (mesaVis->alphaBits == 0)
797 rgbFormat = MESA_FORMAT_XRGB8888;
798 else
799 rgbFormat = MESA_FORMAT_ARGB8888;
800
801 /* setup the hardware-based renderbuffers */
802 rb = intel_create_renderbuffer(rgbFormat, num_samples);
803 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base.Base);
804
805 if (mesaVis->doubleBufferMode) {
806 rb = intel_create_renderbuffer(rgbFormat, num_samples);
807 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base.Base);
808 }
809
810 /*
811 * Assert here that the gl_config has an expected depth/stencil bit
812 * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
813 * which constructs the advertised configs.)
814 */
815 if (mesaVis->depthBits == 24) {
816 assert(mesaVis->stencilBits == 8);
817
818 if (screen->hw_has_separate_stencil) {
819 rb = intel_create_private_renderbuffer(MESA_FORMAT_X8_Z24,
820 num_samples);
821 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
822 rb = intel_create_private_renderbuffer(MESA_FORMAT_S8,
823 num_samples);
824 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
825 } else {
826 /*
827 * Use combined depth/stencil. Note that the renderbuffer is
828 * attached to two attachment points.
829 */
830 rb = intel_create_private_renderbuffer(MESA_FORMAT_S8_Z24,
831 num_samples);
832 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
833 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
834 }
835 }
836 else if (mesaVis->depthBits == 16) {
837 assert(mesaVis->stencilBits == 0);
838 rb = intel_create_private_renderbuffer(MESA_FORMAT_Z16,
839 num_samples);
840 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
841 }
842 else {
843 assert(mesaVis->depthBits == 0);
844 assert(mesaVis->stencilBits == 0);
845 }
846
847 /* now add any/all software-based renderbuffers we may need */
848 _swrast_add_soft_renderbuffers(fb,
849 false, /* never sw color */
850 false, /* never sw depth */
851 false, /* never sw stencil */
852 mesaVis->accumRedBits > 0,
853 false, /* never sw alpha */
854 false /* never sw aux */ );
855 driDrawPriv->driverPrivate = fb;
856
857 return true;
858 }
859
860 static void
861 intelDestroyBuffer(__DRIdrawable * driDrawPriv)
862 {
863 struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
864
865 _mesa_reference_framebuffer(&fb, NULL);
866 }
867
868 /* There are probably better ways to do this, such as an
869 * init-designated function to register chipids and createcontext
870 * functions.
871 */
872 extern bool
873 i830CreateContext(int api,
874 const struct gl_config *mesaVis,
875 __DRIcontext *driContextPriv,
876 unsigned major_version,
877 unsigned minor_version,
878 unsigned *error,
879 void *sharedContextPrivate);
880
881 extern bool
882 i915CreateContext(int api,
883 const struct gl_config *mesaVis,
884 __DRIcontext *driContextPriv,
885 unsigned major_version,
886 unsigned minor_version,
887 unsigned *error,
888 void *sharedContextPrivate);
889 extern bool
890 brwCreateContext(int api,
891 const struct gl_config *mesaVis,
892 __DRIcontext *driContextPriv,
893 unsigned major_version,
894 unsigned minor_version,
895 uint32_t flags,
896 unsigned *error,
897 void *sharedContextPrivate);
898
899 static GLboolean
900 intelCreateContext(gl_api api,
901 const struct gl_config * mesaVis,
902 __DRIcontext * driContextPriv,
903 unsigned major_version,
904 unsigned minor_version,
905 uint32_t flags,
906 unsigned *error,
907 void *sharedContextPrivate)
908 {
909 bool success = false;
910
911 #ifdef I915
912 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
913 struct intel_screen *intelScreen = sPriv->driverPrivate;
914
915 if (IS_9XX(intelScreen->deviceID)) {
916 success = i915CreateContext(api, mesaVis, driContextPriv,
917 major_version, minor_version, error,
918 sharedContextPrivate);
919 } else {
920 intelScreen->no_vbo = true;
921 success = i830CreateContext(api, mesaVis, driContextPriv,
922 major_version, minor_version, error,
923 sharedContextPrivate);
924 }
925 #else
926 success = brwCreateContext(api, mesaVis,
927 driContextPriv,
928 major_version, minor_version, flags,
929 error, sharedContextPrivate);
930 #endif
931
932 if (success)
933 return true;
934
935 if (driContextPriv->driverPrivate != NULL)
936 intelDestroyContext(driContextPriv);
937
938 return false;
939 }
940
941 static bool
942 intel_init_bufmgr(struct intel_screen *intelScreen)
943 {
944 __DRIscreen *spriv = intelScreen->driScrnPriv;
945 int num_fences = 0;
946
947 intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
948
949 intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
950 if (intelScreen->bufmgr == NULL) {
951 fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
952 __func__, __LINE__);
953 return false;
954 }
955
956 if (!intel_get_param(spriv, I915_PARAM_NUM_FENCES_AVAIL, &num_fences) ||
957 num_fences == 0) {
958 fprintf(stderr, "[%s: %u] Kernel 2.6.29 required.\n", __func__, __LINE__);
959 return false;
960 }
961
962 drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
963
964 intelScreen->named_regions = _mesa_NewHashTable();
965
966 intelScreen->relaxed_relocations = 0;
967 intelScreen->relaxed_relocations |=
968 intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA) << 0;
969
970 return true;
971 }
972
973 /**
974 * Override intel_screen.hw_has_separate_stencil with environment variable
975 * INTEL_SEPARATE_STENCIL.
976 *
977 * Valid values for INTEL_SEPARATE_STENCIL are "0" and "1". If an invalid
978 * valid value is encountered, a warning is emitted and INTEL_SEPARATE_STENCIL
979 * is ignored.
980 */
981 static void
982 intel_override_separate_stencil(struct intel_screen *screen)
983 {
984 const char *s = getenv("INTEL_SEPARATE_STENCIL");
985 if (!s) {
986 return;
987 } else if (!strncmp("0", s, 2)) {
988 screen->hw_has_separate_stencil = false;
989 } else if (!strncmp("1", s, 2)) {
990 screen->hw_has_separate_stencil = true;
991 } else {
992 fprintf(stderr,
993 "warning: env variable INTEL_SEPARATE_STENCIL=\"%s\" has "
994 "invalid value and is ignored", s);
995 }
996 }
997
998 static bool
999 intel_detect_swizzling(struct intel_screen *screen)
1000 {
1001 drm_intel_bo *buffer;
1002 unsigned long flags = 0;
1003 unsigned long aligned_pitch;
1004 uint32_t tiling = I915_TILING_X;
1005 uint32_t swizzle_mode = 0;
1006
1007 buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "swizzle test",
1008 64, 64, 4,
1009 &tiling, &aligned_pitch, flags);
1010 if (buffer == NULL)
1011 return false;
1012
1013 drm_intel_bo_get_tiling(buffer, &tiling, &swizzle_mode);
1014 drm_intel_bo_unreference(buffer);
1015
1016 if (swizzle_mode == I915_BIT_6_SWIZZLE_NONE)
1017 return false;
1018 else
1019 return true;
1020 }
1021
1022 static __DRIconfig**
1023 intel_screen_make_configs(__DRIscreen *dri_screen)
1024 {
1025 static const gl_format formats[] = {
1026 MESA_FORMAT_RGB565,
1027 MESA_FORMAT_ARGB8888
1028 };
1029
1030 /* GLX_SWAP_COPY_OML is not supported due to page flipping. */
1031 static const GLenum back_buffer_modes[] = {
1032 GLX_SWAP_UNDEFINED_OML, GLX_NONE,
1033 };
1034
1035 static const uint8_t singlesample_samples[1] = {0};
1036 static const uint8_t multisample_samples[2] = {4, 8};
1037
1038 struct intel_screen *screen = dri_screen->driverPrivate;
1039 uint8_t depth_bits[4], stencil_bits[4];
1040 __DRIconfig **configs = NULL;
1041
1042 /* Generate singlesample configs without accumulation buffer. */
1043 for (int i = 0; i < ARRAY_SIZE(formats); i++) {
1044 __DRIconfig **new_configs;
1045 int num_depth_stencil_bits = 2;
1046
1047 /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
1048 * buffer that has a different number of bits per pixel than the color
1049 * buffer, gen >= 6 supports this.
1050 */
1051 depth_bits[0] = 0;
1052 stencil_bits[0] = 0;
1053
1054 if (formats[i] == MESA_FORMAT_RGB565) {
1055 depth_bits[1] = 16;
1056 stencil_bits[1] = 0;
1057 if (screen->gen >= 6) {
1058 depth_bits[2] = 24;
1059 stencil_bits[2] = 8;
1060 num_depth_stencil_bits = 3;
1061 }
1062 } else {
1063 depth_bits[1] = 24;
1064 stencil_bits[1] = 8;
1065 }
1066
1067 new_configs = driCreateConfigs(formats[i],
1068 depth_bits,
1069 stencil_bits,
1070 num_depth_stencil_bits,
1071 back_buffer_modes, 2,
1072 singlesample_samples, 1,
1073 false);
1074 configs = driConcatConfigs(configs, new_configs);
1075 }
1076
1077 /* Generate the minimum possible set of configs that include an
1078 * accumulation buffer.
1079 */
1080 for (int i = 0; i < ARRAY_SIZE(formats); i++) {
1081 __DRIconfig **new_configs;
1082
1083 if (formats[i] == MESA_FORMAT_RGB565) {
1084 depth_bits[0] = 16;
1085 stencil_bits[0] = 0;
1086 } else {
1087 depth_bits[0] = 24;
1088 stencil_bits[0] = 8;
1089 }
1090
1091 new_configs = driCreateConfigs(formats[i],
1092 depth_bits, stencil_bits, 1,
1093 back_buffer_modes, 1,
1094 singlesample_samples, 1,
1095 true);
1096 configs = driConcatConfigs(configs, new_configs);
1097 }
1098
1099 /* Generate multisample configs.
1100 *
1101 * This loop breaks early, and hence is a no-op, on gen < 6.
1102 *
1103 * Multisample configs must follow the singlesample configs in order to
1104 * work around an X server bug present in 1.12. The X server chooses to
1105 * associate the first listed RGBA888-Z24S8 config, regardless of its
1106 * sample count, with the 32-bit depth visual used for compositing.
1107 *
1108 * Only doublebuffer configs with GLX_SWAP_UNDEFINED_OML behavior are
1109 * supported. Singlebuffer configs are not supported because no one wants
1110 * them.
1111 */
1112 for (int i = 0; i < ARRAY_SIZE(formats); i++) {
1113 if (screen->gen < 6)
1114 break;
1115
1116 __DRIconfig **new_configs;
1117 const int num_depth_stencil_bits = 2;
1118 int num_msaa_modes = 0;
1119
1120 depth_bits[0] = 0;
1121 stencil_bits[0] = 0;
1122
1123 if (formats[i] == MESA_FORMAT_RGB565) {
1124 depth_bits[1] = 16;
1125 stencil_bits[1] = 0;
1126 } else {
1127 depth_bits[1] = 24;
1128 stencil_bits[1] = 8;
1129 }
1130
1131 if (screen->gen >= 7)
1132 num_msaa_modes = 2;
1133 else if (screen->gen == 6)
1134 num_msaa_modes = 1;
1135
1136 new_configs = driCreateConfigs(formats[i],
1137 depth_bits,
1138 stencil_bits,
1139 num_depth_stencil_bits,
1140 back_buffer_modes, 1,
1141 multisample_samples,
1142 num_msaa_modes,
1143 false);
1144 configs = driConcatConfigs(configs, new_configs);
1145 }
1146
1147 if (configs == NULL) {
1148 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
1149 __LINE__);
1150 return NULL;
1151 }
1152
1153 return configs;
1154 }
1155
1156 static void
1157 set_max_gl_versions(struct intel_screen *screen)
1158 {
1159 switch (screen->gen) {
1160 case 7:
1161 if (screen->kernel_has_gen7_sol_reset) {
1162 screen->max_gl_core_version = 31;
1163 screen->max_gl_compat_version = 30;
1164 screen->max_gl_es1_version = 11;
1165 screen->max_gl_es2_version = 30;
1166 } else {
1167 screen->max_gl_core_version = 0;
1168 screen->max_gl_compat_version = 21;
1169 screen->max_gl_es1_version = 11;
1170 screen->max_gl_es2_version = 20;
1171 }
1172 break;
1173 case 6:
1174 screen->max_gl_core_version = 31;
1175 screen->max_gl_compat_version = 30;
1176 screen->max_gl_es1_version = 11;
1177 screen->max_gl_es2_version = 20;
1178 break;
1179 case 5:
1180 case 4:
1181 screen->max_gl_core_version = 0;
1182 screen->max_gl_compat_version = 21;
1183 screen->max_gl_es1_version = 11;
1184 screen->max_gl_es2_version = 20;
1185 break;
1186 case 3: {
1187 bool has_fragment_shader = driQueryOptionb(&screen->optionCache, "fragment_shader");
1188 bool has_occlusion_query = driQueryOptionb(&screen->optionCache, "stub_occlusion_query");
1189
1190 screen->max_gl_core_version = 0;
1191 screen->max_gl_es1_version = 11;
1192
1193 if (has_fragment_shader && has_occlusion_query) {
1194 screen->max_gl_compat_version = 21;
1195 } else {
1196 screen->max_gl_compat_version = 14;
1197 }
1198
1199 if (has_fragment_shader) {
1200 screen->max_gl_es2_version = 20;
1201 } else {
1202 screen->max_gl_es2_version = 0;
1203 }
1204
1205 break;
1206 }
1207 case 2:
1208 screen->max_gl_core_version = 0;
1209 screen->max_gl_compat_version = 13;
1210 screen->max_gl_es1_version = 11;
1211 screen->max_gl_es2_version = 0;
1212 break;
1213 default:
1214 assert(!"unrecognized intel_screen::gen");
1215 break;
1216 }
1217
1218 #ifndef FEATURE_ES1
1219 screen->max_gl_es1_version = 0;
1220 #endif
1221
1222 #ifndef FEATURE_ES2
1223 screen->max_gl_es2_version = 0;
1224 #endif
1225 }
1226
1227 /**
1228 * This is the driver specific part of the createNewScreen entry point.
1229 * Called when using DRI2.
1230 *
1231 * \return the struct gl_config supported by this driver
1232 */
1233 static const
1234 __DRIconfig **intelInitScreen2(__DRIscreen *psp)
1235 {
1236 struct intel_screen *intelScreen;
1237
1238 if (psp->dri2.loader->base.version <= 2 ||
1239 psp->dri2.loader->getBuffersWithFormat == NULL) {
1240 fprintf(stderr,
1241 "\nERROR! DRI2 loader with getBuffersWithFormat() "
1242 "support required\n");
1243 return false;
1244 }
1245
1246 /* Allocate the private area */
1247 intelScreen = calloc(1, sizeof *intelScreen);
1248 if (!intelScreen) {
1249 fprintf(stderr, "\nERROR! Allocating private area failed\n");
1250 return false;
1251 }
1252 /* parse information in __driConfigOptions */
1253 driParseOptionInfo(&intelScreen->optionCache,
1254 __driConfigOptions, __driNConfigOptions);
1255
1256 intelScreen->driScrnPriv = psp;
1257 psp->driverPrivate = (void *) intelScreen;
1258
1259 if (!intel_init_bufmgr(intelScreen))
1260 return false;
1261
1262 intelScreen->deviceID = drm_intel_bufmgr_gem_get_devid(intelScreen->bufmgr);
1263
1264 intelScreen->kernel_has_gen7_sol_reset =
1265 intel_get_boolean(intelScreen->driScrnPriv,
1266 I915_PARAM_HAS_GEN7_SOL_RESET);
1267
1268 if (IS_GEN7(intelScreen->deviceID)) {
1269 intelScreen->gen = 7;
1270 } else if (IS_GEN6(intelScreen->deviceID)) {
1271 intelScreen->gen = 6;
1272 } else if (IS_GEN5(intelScreen->deviceID)) {
1273 intelScreen->gen = 5;
1274 } else if (IS_965(intelScreen->deviceID)) {
1275 intelScreen->gen = 4;
1276 } else if (IS_9XX(intelScreen->deviceID)) {
1277 intelScreen->gen = 3;
1278 } else {
1279 intelScreen->gen = 2;
1280 }
1281
1282 intelScreen->hw_has_separate_stencil = intelScreen->gen >= 6;
1283 intelScreen->hw_must_use_separate_stencil = intelScreen->gen >= 7;
1284
1285 int has_llc = 0;
1286 bool success = intel_get_param(intelScreen->driScrnPriv, I915_PARAM_HAS_LLC,
1287 &has_llc);
1288 if (success && has_llc)
1289 intelScreen->hw_has_llc = true;
1290 else if (!success && intelScreen->gen >= 6)
1291 intelScreen->hw_has_llc = true;
1292
1293 intel_override_separate_stencil(intelScreen);
1294
1295 intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen);
1296
1297 set_max_gl_versions(intelScreen);
1298
1299 psp->api_mask = (1 << __DRI_API_OPENGL);
1300 if (intelScreen->max_gl_es1_version > 0)
1301 psp->api_mask |= (1 << __DRI_API_GLES);
1302 if (intelScreen->max_gl_es2_version > 0)
1303 psp->api_mask |= (1 << __DRI_API_GLES2);
1304 if (intelScreen->max_gl_es2_version >= 30)
1305 psp->api_mask |= (1 << __DRI_API_GLES3);
1306
1307 psp->extensions = intelScreenExtensions;
1308
1309 return (const __DRIconfig**) intel_screen_make_configs(psp);
1310 }
1311
1312 struct intel_buffer {
1313 __DRIbuffer base;
1314 struct intel_region *region;
1315 };
1316
1317 static __DRIbuffer *
1318 intelAllocateBuffer(__DRIscreen *screen,
1319 unsigned attachment, unsigned format,
1320 int width, int height)
1321 {
1322 struct intel_buffer *intelBuffer;
1323 struct intel_screen *intelScreen = screen->driverPrivate;
1324
1325 assert(attachment == __DRI_BUFFER_FRONT_LEFT ||
1326 attachment == __DRI_BUFFER_BACK_LEFT);
1327
1328 intelBuffer = calloc(1, sizeof *intelBuffer);
1329 if (intelBuffer == NULL)
1330 return NULL;
1331
1332 /* The front and back buffers are color buffers, which are X tiled. */
1333 intelBuffer->region = intel_region_alloc(intelScreen,
1334 I915_TILING_X,
1335 format / 8,
1336 width,
1337 height,
1338 true);
1339
1340 if (intelBuffer->region == NULL) {
1341 free(intelBuffer);
1342 return NULL;
1343 }
1344
1345 intel_region_flink(intelBuffer->region, &intelBuffer->base.name);
1346
1347 intelBuffer->base.attachment = attachment;
1348 intelBuffer->base.cpp = intelBuffer->region->cpp;
1349 intelBuffer->base.pitch = intelBuffer->region->pitch;
1350
1351 return &intelBuffer->base;
1352 }
1353
1354 static void
1355 intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
1356 {
1357 struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
1358
1359 intel_region_release(&intelBuffer->region);
1360 free(intelBuffer);
1361 }
1362
1363
1364 const struct __DriverAPIRec driDriverAPI = {
1365 .InitScreen = intelInitScreen2,
1366 .DestroyScreen = intelDestroyScreen,
1367 .CreateContext = intelCreateContext,
1368 .DestroyContext = intelDestroyContext,
1369 .CreateBuffer = intelCreateBuffer,
1370 .DestroyBuffer = intelDestroyBuffer,
1371 .MakeCurrent = intelMakeCurrent,
1372 .UnbindContext = intelUnbindContext,
1373 .AllocateBuffer = intelAllocateBuffer,
1374 .ReleaseBuffer = intelReleaseBuffer
1375 };
1376
1377 /* This is the table of extensions that the loader will dlsym() for. */
1378 PUBLIC const __DRIextension *__driDriverExtensions[] = {
1379 &driCoreExtension.base,
1380 &driDRI2Extension.base,
1381 NULL
1382 };