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