Merge remote-tracking branch 'fdo-personal/wip/nir-vtn' into vulkan
[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 &intelFenceExtension.base,
913 &intelFlushExtension.base,
914 &intelImageExtension.base,
915 &intelRendererQueryExtension.base,
916 &dri2ConfigQueryExtension.base,
917 NULL
918 };
919
920 static const __DRIextension *intelRobustScreenExtensions[] = {
921 &intelTexBufferExtension.base,
922 &intelFenceExtension.base,
923 &intelFlushExtension.base,
924 &intelImageExtension.base,
925 &intelRendererQueryExtension.base,
926 &dri2ConfigQueryExtension.base,
927 &dri2Robustness.base,
928 NULL
929 };
930
931 static bool
932 intel_get_param(__DRIscreen *psp, int param, int *value)
933 {
934 int ret;
935 struct drm_i915_getparam gp;
936
937 memset(&gp, 0, sizeof(gp));
938 gp.param = param;
939 gp.value = value;
940
941 ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
942 if (ret) {
943 if (ret != -EINVAL)
944 _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
945 return false;
946 }
947
948 return true;
949 }
950
951 static bool
952 intel_get_boolean(__DRIscreen *psp, int param)
953 {
954 int value = 0;
955 return intel_get_param(psp, param, &value) && value;
956 }
957
958 static void
959 intelDestroyScreen(__DRIscreen * sPriv)
960 {
961 struct intel_screen *intelScreen = sPriv->driverPrivate;
962
963 dri_bufmgr_destroy(intelScreen->bufmgr);
964 driDestroyOptionInfo(&intelScreen->optionCache);
965
966 ralloc_free(intelScreen);
967 sPriv->driverPrivate = NULL;
968 }
969
970
971 /**
972 * This is called when we need to set up GL rendering to a new X window.
973 */
974 static GLboolean
975 intelCreateBuffer(__DRIscreen * driScrnPriv,
976 __DRIdrawable * driDrawPriv,
977 const struct gl_config * mesaVis, GLboolean isPixmap)
978 {
979 struct intel_renderbuffer *rb;
980 struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate;
981 mesa_format rgbFormat;
982 unsigned num_samples = intel_quantize_num_samples(screen, mesaVis->samples);
983 struct gl_framebuffer *fb;
984
985 if (isPixmap)
986 return false;
987
988 fb = CALLOC_STRUCT(gl_framebuffer);
989 if (!fb)
990 return false;
991
992 _mesa_initialize_window_framebuffer(fb, mesaVis);
993
994 if (screen->winsys_msaa_samples_override != -1) {
995 num_samples = screen->winsys_msaa_samples_override;
996 fb->Visual.samples = num_samples;
997 }
998
999 if (mesaVis->redBits == 5)
1000 rgbFormat = MESA_FORMAT_B5G6R5_UNORM;
1001 else if (mesaVis->sRGBCapable)
1002 rgbFormat = MESA_FORMAT_B8G8R8A8_SRGB;
1003 else if (mesaVis->alphaBits == 0)
1004 rgbFormat = MESA_FORMAT_B8G8R8X8_UNORM;
1005 else {
1006 rgbFormat = MESA_FORMAT_B8G8R8A8_SRGB;
1007 fb->Visual.sRGBCapable = true;
1008 }
1009
1010 /* setup the hardware-based renderbuffers */
1011 rb = intel_create_renderbuffer(rgbFormat, num_samples);
1012 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base.Base);
1013
1014 if (mesaVis->doubleBufferMode) {
1015 rb = intel_create_renderbuffer(rgbFormat, num_samples);
1016 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base.Base);
1017 }
1018
1019 /*
1020 * Assert here that the gl_config has an expected depth/stencil bit
1021 * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
1022 * which constructs the advertised configs.)
1023 */
1024 if (mesaVis->depthBits == 24) {
1025 assert(mesaVis->stencilBits == 8);
1026
1027 if (screen->devinfo->has_hiz_and_separate_stencil) {
1028 rb = intel_create_private_renderbuffer(MESA_FORMAT_Z24_UNORM_X8_UINT,
1029 num_samples);
1030 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
1031 rb = intel_create_private_renderbuffer(MESA_FORMAT_S_UINT8,
1032 num_samples);
1033 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
1034 } else {
1035 /*
1036 * Use combined depth/stencil. Note that the renderbuffer is
1037 * attached to two attachment points.
1038 */
1039 rb = intel_create_private_renderbuffer(MESA_FORMAT_Z24_UNORM_S8_UINT,
1040 num_samples);
1041 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
1042 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
1043 }
1044 }
1045 else if (mesaVis->depthBits == 16) {
1046 assert(mesaVis->stencilBits == 0);
1047 rb = intel_create_private_renderbuffer(MESA_FORMAT_Z_UNORM16,
1048 num_samples);
1049 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
1050 }
1051 else {
1052 assert(mesaVis->depthBits == 0);
1053 assert(mesaVis->stencilBits == 0);
1054 }
1055
1056 /* now add any/all software-based renderbuffers we may need */
1057 _swrast_add_soft_renderbuffers(fb,
1058 false, /* never sw color */
1059 false, /* never sw depth */
1060 false, /* never sw stencil */
1061 mesaVis->accumRedBits > 0,
1062 false, /* never sw alpha */
1063 false /* never sw aux */ );
1064 driDrawPriv->driverPrivate = fb;
1065
1066 return true;
1067 }
1068
1069 static void
1070 intelDestroyBuffer(__DRIdrawable * driDrawPriv)
1071 {
1072 struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
1073
1074 _mesa_reference_framebuffer(&fb, NULL);
1075 }
1076
1077 static bool
1078 intel_init_bufmgr(struct intel_screen *intelScreen)
1079 {
1080 __DRIscreen *spriv = intelScreen->driScrnPriv;
1081
1082 intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
1083
1084 intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
1085 if (intelScreen->bufmgr == NULL) {
1086 fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
1087 __func__, __LINE__);
1088 return false;
1089 }
1090
1091 drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
1092
1093 if (!intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA)) {
1094 fprintf(stderr, "[%s: %u] Kernel 2.6.39 required.\n", __func__, __LINE__);
1095 return false;
1096 }
1097
1098 return true;
1099 }
1100
1101 static bool
1102 intel_detect_swizzling(struct intel_screen *screen)
1103 {
1104 drm_intel_bo *buffer;
1105 unsigned long flags = 0;
1106 unsigned long aligned_pitch;
1107 uint32_t tiling = I915_TILING_X;
1108 uint32_t swizzle_mode = 0;
1109
1110 buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "swizzle test",
1111 64, 64, 4,
1112 &tiling, &aligned_pitch, flags);
1113 if (buffer == NULL)
1114 return false;
1115
1116 drm_intel_bo_get_tiling(buffer, &tiling, &swizzle_mode);
1117 drm_intel_bo_unreference(buffer);
1118
1119 if (swizzle_mode == I915_BIT_6_SWIZZLE_NONE)
1120 return false;
1121 else
1122 return true;
1123 }
1124
1125 /**
1126 * Return array of MSAA modes supported by the hardware. The array is
1127 * zero-terminated and sorted in decreasing order.
1128 */
1129 const int*
1130 intel_supported_msaa_modes(const struct intel_screen *screen)
1131 {
1132 static const int gen8_modes[] = {8, 4, 2, 0, -1};
1133 static const int gen7_modes[] = {8, 4, 0, -1};
1134 static const int gen6_modes[] = {4, 0, -1};
1135 static const int gen4_modes[] = {0, -1};
1136
1137 if (screen->devinfo->gen >= 8) {
1138 return gen8_modes;
1139 } else if (screen->devinfo->gen >= 7) {
1140 return gen7_modes;
1141 } else if (screen->devinfo->gen == 6) {
1142 return gen6_modes;
1143 } else {
1144 return gen4_modes;
1145 }
1146 }
1147
1148 static __DRIconfig**
1149 intel_screen_make_configs(__DRIscreen *dri_screen)
1150 {
1151 static const mesa_format formats[] = {
1152 MESA_FORMAT_B5G6R5_UNORM,
1153 MESA_FORMAT_B8G8R8A8_UNORM,
1154 MESA_FORMAT_B8G8R8X8_UNORM
1155 };
1156
1157 /* GLX_SWAP_COPY_OML is not supported due to page flipping. */
1158 static const GLenum back_buffer_modes[] = {
1159 GLX_SWAP_UNDEFINED_OML, GLX_NONE,
1160 };
1161
1162 static const uint8_t singlesample_samples[1] = {0};
1163 static const uint8_t multisample_samples[2] = {4, 8};
1164
1165 struct intel_screen *screen = dri_screen->driverPrivate;
1166 const struct brw_device_info *devinfo = screen->devinfo;
1167 uint8_t depth_bits[4], stencil_bits[4];
1168 __DRIconfig **configs = NULL;
1169
1170 /* Generate singlesample configs without accumulation buffer. */
1171 for (int i = 0; i < ARRAY_SIZE(formats); i++) {
1172 __DRIconfig **new_configs;
1173 int num_depth_stencil_bits = 2;
1174
1175 /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
1176 * buffer that has a different number of bits per pixel than the color
1177 * buffer, gen >= 6 supports this.
1178 */
1179 depth_bits[0] = 0;
1180 stencil_bits[0] = 0;
1181
1182 if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) {
1183 depth_bits[1] = 16;
1184 stencil_bits[1] = 0;
1185 if (devinfo->gen >= 6) {
1186 depth_bits[2] = 24;
1187 stencil_bits[2] = 8;
1188 num_depth_stencil_bits = 3;
1189 }
1190 } else {
1191 depth_bits[1] = 24;
1192 stencil_bits[1] = 8;
1193 }
1194
1195 new_configs = driCreateConfigs(formats[i],
1196 depth_bits,
1197 stencil_bits,
1198 num_depth_stencil_bits,
1199 back_buffer_modes, 2,
1200 singlesample_samples, 1,
1201 false);
1202 configs = driConcatConfigs(configs, new_configs);
1203 }
1204
1205 /* Generate the minimum possible set of configs that include an
1206 * accumulation buffer.
1207 */
1208 for (int i = 0; i < ARRAY_SIZE(formats); i++) {
1209 __DRIconfig **new_configs;
1210
1211 if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) {
1212 depth_bits[0] = 16;
1213 stencil_bits[0] = 0;
1214 } else {
1215 depth_bits[0] = 24;
1216 stencil_bits[0] = 8;
1217 }
1218
1219 new_configs = driCreateConfigs(formats[i],
1220 depth_bits, stencil_bits, 1,
1221 back_buffer_modes, 1,
1222 singlesample_samples, 1,
1223 true);
1224 configs = driConcatConfigs(configs, new_configs);
1225 }
1226
1227 /* Generate multisample configs.
1228 *
1229 * This loop breaks early, and hence is a no-op, on gen < 6.
1230 *
1231 * Multisample configs must follow the singlesample configs in order to
1232 * work around an X server bug present in 1.12. The X server chooses to
1233 * associate the first listed RGBA888-Z24S8 config, regardless of its
1234 * sample count, with the 32-bit depth visual used for compositing.
1235 *
1236 * Only doublebuffer configs with GLX_SWAP_UNDEFINED_OML behavior are
1237 * supported. Singlebuffer configs are not supported because no one wants
1238 * them.
1239 */
1240 for (int i = 0; i < ARRAY_SIZE(formats); i++) {
1241 if (devinfo->gen < 6)
1242 break;
1243
1244 __DRIconfig **new_configs;
1245 const int num_depth_stencil_bits = 2;
1246 int num_msaa_modes = 0;
1247
1248 depth_bits[0] = 0;
1249 stencil_bits[0] = 0;
1250
1251 if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) {
1252 depth_bits[1] = 16;
1253 stencil_bits[1] = 0;
1254 } else {
1255 depth_bits[1] = 24;
1256 stencil_bits[1] = 8;
1257 }
1258
1259 if (devinfo->gen >= 7)
1260 num_msaa_modes = 2;
1261 else if (devinfo->gen == 6)
1262 num_msaa_modes = 1;
1263
1264 new_configs = driCreateConfigs(formats[i],
1265 depth_bits,
1266 stencil_bits,
1267 num_depth_stencil_bits,
1268 back_buffer_modes, 1,
1269 multisample_samples,
1270 num_msaa_modes,
1271 false);
1272 configs = driConcatConfigs(configs, new_configs);
1273 }
1274
1275 if (configs == NULL) {
1276 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
1277 __LINE__);
1278 return NULL;
1279 }
1280
1281 return configs;
1282 }
1283
1284 static void
1285 set_max_gl_versions(struct intel_screen *screen)
1286 {
1287 __DRIscreen *psp = screen->driScrnPriv;
1288
1289 switch (screen->devinfo->gen) {
1290 case 9:
1291 case 8:
1292 case 7:
1293 case 6:
1294 psp->max_gl_core_version = 33;
1295 psp->max_gl_compat_version = 30;
1296 psp->max_gl_es1_version = 11;
1297 psp->max_gl_es2_version = 30;
1298 break;
1299 case 5:
1300 case 4:
1301 psp->max_gl_core_version = 0;
1302 psp->max_gl_compat_version = 21;
1303 psp->max_gl_es1_version = 11;
1304 psp->max_gl_es2_version = 20;
1305 break;
1306 default:
1307 unreachable("unrecognized intel_screen::gen");
1308 }
1309 }
1310
1311 /* drop when libdrm 2.4.61 is released */
1312 #ifndef I915_PARAM_REVISION
1313 #define I915_PARAM_REVISION 32
1314 #endif
1315
1316 static int
1317 brw_get_revision(int fd)
1318 {
1319 struct drm_i915_getparam gp;
1320 int revision;
1321 int ret;
1322
1323 memset(&gp, 0, sizeof(gp));
1324 gp.param = I915_PARAM_REVISION;
1325 gp.value = &revision;
1326
1327 ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
1328 if (ret)
1329 revision = -1;
1330
1331 return revision;
1332 }
1333
1334 /**
1335 * This is the driver specific part of the createNewScreen entry point.
1336 * Called when using DRI2.
1337 *
1338 * \return the struct gl_config supported by this driver
1339 */
1340 static const
1341 __DRIconfig **intelInitScreen2(__DRIscreen *psp)
1342 {
1343 struct intel_screen *intelScreen;
1344
1345 if (psp->image.loader) {
1346 } else if (psp->dri2.loader->base.version <= 2 ||
1347 psp->dri2.loader->getBuffersWithFormat == NULL) {
1348 fprintf(stderr,
1349 "\nERROR! DRI2 loader with getBuffersWithFormat() "
1350 "support required\n");
1351 return false;
1352 }
1353
1354 /* Allocate the private area */
1355 intelScreen = rzalloc(NULL, struct intel_screen);
1356 if (!intelScreen) {
1357 fprintf(stderr, "\nERROR! Allocating private area failed\n");
1358 return false;
1359 }
1360 /* parse information in __driConfigOptions */
1361 driParseOptionInfo(&intelScreen->optionCache, brw_config_options.xml);
1362
1363 intelScreen->driScrnPriv = psp;
1364 psp->driverPrivate = (void *) intelScreen;
1365
1366 if (!intel_init_bufmgr(intelScreen))
1367 return false;
1368
1369 intelScreen->deviceID = drm_intel_bufmgr_gem_get_devid(intelScreen->bufmgr);
1370 intelScreen->devinfo = brw_get_device_info(intelScreen->deviceID,
1371 brw_get_revision(psp->fd));
1372 if (!intelScreen->devinfo)
1373 return false;
1374
1375 intelScreen->hw_must_use_separate_stencil = intelScreen->devinfo->gen >= 7;
1376
1377 intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen);
1378
1379 const char *force_msaa = getenv("INTEL_FORCE_MSAA");
1380 if (force_msaa) {
1381 intelScreen->winsys_msaa_samples_override =
1382 intel_quantize_num_samples(intelScreen, atoi(force_msaa));
1383 printf("Forcing winsys sample count to %d\n",
1384 intelScreen->winsys_msaa_samples_override);
1385 } else {
1386 intelScreen->winsys_msaa_samples_override = -1;
1387 }
1388
1389 set_max_gl_versions(intelScreen);
1390
1391 /* Notification of GPU resets requires hardware contexts and a kernel new
1392 * enough to support DRM_IOCTL_I915_GET_RESET_STATS. If the ioctl is
1393 * supported, calling it with a context of 0 will either generate EPERM or
1394 * no error. If the ioctl is not supported, it always generate EINVAL.
1395 * Use this to determine whether to advertise the __DRI2_ROBUSTNESS
1396 * extension to the loader.
1397 *
1398 * Don't even try on pre-Gen6, since we don't attempt to use contexts there.
1399 */
1400 if (intelScreen->devinfo->gen >= 6) {
1401 struct drm_i915_reset_stats stats;
1402 memset(&stats, 0, sizeof(stats));
1403
1404 const int ret = drmIoctl(psp->fd, DRM_IOCTL_I915_GET_RESET_STATS, &stats);
1405
1406 intelScreen->has_context_reset_notification =
1407 (ret != -1 || errno != EINVAL);
1408 }
1409
1410 psp->extensions = !intelScreen->has_context_reset_notification
1411 ? intelScreenExtensions : intelRobustScreenExtensions;
1412
1413 intelScreen->compiler = brw_compiler_create(intelScreen,
1414 intelScreen->devinfo);
1415
1416 return (const __DRIconfig**) intel_screen_make_configs(psp);
1417 }
1418
1419 struct intel_screen *
1420 intel_screen_create(int fd)
1421 {
1422 __DRIscreen *psp;
1423 __DRIconfig **configs;
1424 int i;
1425
1426 psp = malloc(sizeof(*psp));
1427 if (psp == NULL)
1428 return NULL;
1429
1430 psp->image.loader = (void *) 1; /* Don't complain about this being NULL */
1431 psp->fd = fd;
1432 psp->dri2.useInvalidate = (void *) 1;
1433
1434 configs = (__DRIconfig **) intelInitScreen2(psp);
1435 for (i = 0; configs[i]; i++)
1436 free(configs[i]);
1437 free(configs);
1438
1439 return psp->driverPrivate;
1440 }
1441
1442 void
1443 intel_screen_destroy(struct intel_screen *screen)
1444 {
1445 __DRIscreen *psp;
1446
1447 psp = screen->driScrnPriv;
1448 intelDestroyScreen(screen->driScrnPriv);
1449 free(psp);
1450 }
1451
1452
1453 struct brw_context *
1454 intel_context_create(struct intel_screen *screen)
1455 {
1456 __DRIcontext *driContextPriv;
1457 struct brw_context *brw;
1458 unsigned error;
1459
1460 driContextPriv = malloc(sizeof(*driContextPriv));
1461 if (driContextPriv == NULL)
1462 return NULL;
1463
1464 driContextPriv->driScreenPriv = screen->driScrnPriv;
1465
1466 brwCreateContext(API_OPENGL_CORE,
1467 NULL, /* visual */
1468 driContextPriv,
1469 3, 0,
1470 0, /* flags */
1471 false, /* notify_reset */
1472 &error,
1473 NULL);
1474
1475 brw = driContextPriv->driverPrivate;
1476 brw->ctx.FirstTimeCurrent = false;
1477
1478 return driContextPriv->driverPrivate;
1479 }
1480
1481 void
1482 intel_context_destroy(struct brw_context *brw)
1483 {
1484 __DRIcontext *driContextPriv;
1485
1486 driContextPriv = brw->driContext;
1487 intelDestroyContext(driContextPriv);
1488 free(driContextPriv);
1489 }
1490
1491 struct intel_buffer {
1492 __DRIbuffer base;
1493 drm_intel_bo *bo;
1494 };
1495
1496 static __DRIbuffer *
1497 intelAllocateBuffer(__DRIscreen *screen,
1498 unsigned attachment, unsigned format,
1499 int width, int height)
1500 {
1501 struct intel_buffer *intelBuffer;
1502 struct intel_screen *intelScreen = screen->driverPrivate;
1503
1504 assert(attachment == __DRI_BUFFER_FRONT_LEFT ||
1505 attachment == __DRI_BUFFER_BACK_LEFT);
1506
1507 intelBuffer = calloc(1, sizeof *intelBuffer);
1508 if (intelBuffer == NULL)
1509 return NULL;
1510
1511 /* The front and back buffers are color buffers, which are X tiled. */
1512 uint32_t tiling = I915_TILING_X;
1513 unsigned long pitch;
1514 int cpp = format / 8;
1515 intelBuffer->bo = drm_intel_bo_alloc_tiled(intelScreen->bufmgr,
1516 "intelAllocateBuffer",
1517 width,
1518 height,
1519 cpp,
1520 &tiling, &pitch,
1521 BO_ALLOC_FOR_RENDER);
1522
1523 if (intelBuffer->bo == NULL) {
1524 free(intelBuffer);
1525 return NULL;
1526 }
1527
1528 drm_intel_bo_flink(intelBuffer->bo, &intelBuffer->base.name);
1529
1530 intelBuffer->base.attachment = attachment;
1531 intelBuffer->base.cpp = cpp;
1532 intelBuffer->base.pitch = pitch;
1533
1534 return &intelBuffer->base;
1535 }
1536
1537 static void
1538 intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
1539 {
1540 struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
1541
1542 drm_intel_bo_unreference(intelBuffer->bo);
1543 free(intelBuffer);
1544 }
1545
1546 static const struct __DriverAPIRec brw_driver_api = {
1547 .InitScreen = intelInitScreen2,
1548 .DestroyScreen = intelDestroyScreen,
1549 .CreateContext = brwCreateContext,
1550 .DestroyContext = intelDestroyContext,
1551 .CreateBuffer = intelCreateBuffer,
1552 .DestroyBuffer = intelDestroyBuffer,
1553 .MakeCurrent = intelMakeCurrent,
1554 .UnbindContext = intelUnbindContext,
1555 .AllocateBuffer = intelAllocateBuffer,
1556 .ReleaseBuffer = intelReleaseBuffer
1557 };
1558
1559 static const struct __DRIDriverVtableExtensionRec brw_vtable = {
1560 .base = { __DRI_DRIVER_VTABLE, 1 },
1561 .vtable = &brw_driver_api,
1562 };
1563
1564 static const __DRIextension *brw_driver_extensions[] = {
1565 &driCoreExtension.base,
1566 &driImageDriverExtension.base,
1567 &driDRI2Extension.base,
1568 &brw_vtable.base,
1569 &brw_config_options.base,
1570 NULL
1571 };
1572
1573 PUBLIC const __DRIextension **__driDriverGetExtensions_i965(void)
1574 {
1575 globalDriverAPI = &brw_driver_api;
1576
1577 return brw_driver_extensions;
1578 }