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