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