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