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