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