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 "drm-uapi/drm_fourcc.h"
27#include <errno.h>
28#include <time.h>
29#include <unistd.h>
30#include "main/context.h"
31#include "main/framebuffer.h"
32#include "main/renderbuffer.h"
33#include "main/texobj.h"
34#include "main/hash.h"
35#include "main/fbobject.h"
36#include "main/version.h"
37#include "main/glthread.h"
38#include "swrast/s_renderbuffer.h"
39#include "util/ralloc.h"
40#include "util/disk_cache.h"
41#include "brw_defines.h"
42#include "brw_state.h"
43#include "compiler/nir/nir.h"
44
45#include "utils.h"
46#include "util/disk_cache.h"
47#include "util/driconf.h"
48#include "util/u_cpu_detect.h"
49#include "util/u_memory.h"
50
51#include "common/intel_defines.h"
52
53static const driOptionDescription brw_driconf[] = {
54   DRI_CONF_SECTION_PERFORMANCE
55      /* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
56       * DRI_CONF_BO_REUSE_ALL
57       */
58      DRI_CONF_OPT_E(bo_reuse, 1, 0, 1,
59                     "Buffer object reuse",
60                     DRI_CONF_ENUM(0, "Disable buffer object reuse")
61                     DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects"))
62      DRI_CONF_MESA_NO_ERROR(false)
63      DRI_CONF_MESA_GLTHREAD(false)
64   DRI_CONF_SECTION_END
65
66   DRI_CONF_SECTION_QUALITY
67      DRI_CONF_PRECISE_TRIG(false)
68
69      DRI_CONF_OPT_I(clamp_max_samples, -1, 0, 0,
70                     "Clamp the value of GL_MAX_SAMPLES to the "
71                     "given integer. If negative, then do not clamp.")
72   DRI_CONF_SECTION_END
73
74   DRI_CONF_SECTION_DEBUG
75      DRI_CONF_ALWAYS_FLUSH_BATCH(false)
76      DRI_CONF_ALWAYS_FLUSH_CACHE(false)
77      DRI_CONF_DISABLE_THROTTLING(false)
78      DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN(false)
79      DRI_CONF_FORCE_GLSL_VERSION(0)
80      DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS(false)
81      DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED(false)
82      DRI_CONF_DUAL_COLOR_BLEND_BY_LOCATION(false)
83      DRI_CONF_ALLOW_EXTRA_PP_TOKENS(false)
84      DRI_CONF_ALLOW_GLSL_EXTENSION_DIRECTIVE_MIDSHADER(false)
85      DRI_CONF_ALLOW_GLSL_BUILTIN_VARIABLE_REDECLARATION(false)
86      DRI_CONF_ALLOW_GLSL_CROSS_STAGE_INTERPOLATION_MISMATCH(false)
87      DRI_CONF_ALLOW_HIGHER_COMPAT_VERSION(false)
88      DRI_CONF_FORCE_COMPAT_PROFILE(false)
89      DRI_CONF_FORCE_GLSL_ABS_SQRT(false)
90      DRI_CONF_FORCE_GL_VENDOR()
91
92      DRI_CONF_OPT_B(shader_precompile, true, "Perform code generation at shader link time.")
93   DRI_CONF_SECTION_END
94
95   DRI_CONF_SECTION_MISCELLANEOUS
96      DRI_CONF_GLSL_ZERO_INIT(false)
97      DRI_CONF_VS_POSITION_ALWAYS_INVARIANT(false)
98      DRI_CONF_VS_POSITION_ALWAYS_PRECISE(false)
99      DRI_CONF_ALLOW_RGB10_CONFIGS(false)
100      DRI_CONF_ALLOW_RGB565_CONFIGS(true)
101   DRI_CONF_SECTION_END
102};
103
104static char *
105brw_driconf_get_xml(UNUSED const char *driver_name)
106{
107   return driGetOptionsXml(brw_driconf, ARRAY_SIZE(brw_driconf));
108}
109
110static const __DRIconfigOptionsExtension brw_config_options = {
111   .base = { __DRI_CONFIG_OPTIONS, 2 },
112   .xml = NULL,
113   .getXml = brw_driconf_get_xml,
114};
115
116#include "brw_batch.h"
117#include "brw_buffers.h"
118#include "brw_bufmgr.h"
119#include "brw_fbo.h"
120#include "brw_mipmap_tree.h"
121#include "brw_screen.h"
122#include "brw_tex.h"
123#include "brw_image.h"
124
125#include "brw_context.h"
126
127#include "drm-uapi/i915_drm.h"
128
129/**
130 * For debugging purposes, this returns a time in seconds.
131 */
132double
133get_time(void)
134{
135   struct timespec tp;
136
137   clock_gettime(CLOCK_MONOTONIC, &tp);
138
139   return tp.tv_sec + tp.tv_nsec / 1000000000.0;
140}
141
142static const __DRItexBufferExtension brwTexBufferExtension = {
143   .base = { __DRI_TEX_BUFFER, 3 },
144
145   .setTexBuffer        = brw_set_texbuffer,
146   .setTexBuffer2       = brw_set_texbuffer2,
147   .releaseTexBuffer    = brw_release_texbuffer,
148};
149
150static void
151brw_dri2_flush_with_flags(__DRIcontext *cPriv,
152                            __DRIdrawable *dPriv,
153                            unsigned flags,
154                            enum __DRI2throttleReason reason)
155{
156   struct brw_context *brw = cPriv->driverPrivate;
157
158   if (!brw)
159      return;
160
161   struct gl_context *ctx = &brw->ctx;
162
163   _mesa_glthread_finish(ctx);
164
165   FLUSH_VERTICES(ctx, 0, 0);
166
167   if (flags & __DRI2_FLUSH_DRAWABLE)
168      brw_resolve_for_dri2_flush(brw, dPriv);
169
170   if (reason == __DRI2_THROTTLE_SWAPBUFFER)
171      brw->need_swap_throttle = true;
172   if (reason == __DRI2_THROTTLE_FLUSHFRONT)
173      brw->need_flush_throttle = true;
174
175   brw_batch_flush(brw);
176}
177
178/**
179 * Provides compatibility with loaders that only support the older (version
180 * 1-3) flush interface.
181 *
182 * That includes libGL up to Mesa 9.0, and the X Server at least up to 1.13.
183 */
184static void
185brw_dri2_flush(__DRIdrawable *drawable)
186{
187   brw_dri2_flush_with_flags(drawable->driContextPriv, drawable,
188                               __DRI2_FLUSH_DRAWABLE,
189                               __DRI2_THROTTLE_SWAPBUFFER);
190}
191
192static const struct __DRI2flushExtensionRec brwFlushExtension = {
193    .base = { __DRI2_FLUSH, 4 },
194
195    .flush              = brw_dri2_flush,
196    .invalidate         = dri2InvalidateDrawable,
197    .flush_with_flags   = brw_dri2_flush_with_flags,
198};
199
200static const struct brw_image_format brw_image_formats[] = {
201   { DRM_FORMAT_ABGR16161616F, __DRI_IMAGE_COMPONENTS_RGBA, 1,
202     { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR16161616F, 8 } } },
203
204   { DRM_FORMAT_XBGR16161616F, __DRI_IMAGE_COMPONENTS_RGB, 1,
205     { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR16161616F, 8 } } },
206
207   { DRM_FORMAT_ARGB2101010, __DRI_IMAGE_COMPONENTS_RGBA, 1,
208     { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB2101010, 4 } } },
209
210   { DRM_FORMAT_XRGB2101010, __DRI_IMAGE_COMPONENTS_RGB, 1,
211     { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB2101010, 4 } } },
212
213   { DRM_FORMAT_ABGR2101010, __DRI_IMAGE_COMPONENTS_RGBA, 1,
214     { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR2101010, 4 } } },
215
216   { DRM_FORMAT_XBGR2101010, __DRI_IMAGE_COMPONENTS_RGB, 1,
217     { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR2101010, 4 } } },
218
219   { DRM_FORMAT_ARGB8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
220     { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } },
221
222   { DRM_FORMAT_ABGR8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
223     { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR8888, 4 } } },
224
225   { __DRI_IMAGE_FOURCC_SARGB8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
226     { { 0, 0, 0, __DRI_IMAGE_FORMAT_SARGB8, 4 } } },
227
228   { __DRI_IMAGE_FOURCC_SXRGB8888, __DRI_IMAGE_COMPONENTS_RGB, 1,
229     { { 0, 0, 0, __DRI_IMAGE_FORMAT_SXRGB8, 4 } } },
230
231   { DRM_FORMAT_XRGB8888, __DRI_IMAGE_COMPONENTS_RGB, 1,
232     { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB8888, 4 }, } },
233
234   { DRM_FORMAT_XBGR8888, __DRI_IMAGE_COMPONENTS_RGB, 1,
235     { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR8888, 4 }, } },
236
237   { DRM_FORMAT_ARGB1555, __DRI_IMAGE_COMPONENTS_RGBA, 1,
238     { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB1555, 2 } } },
239
240   { DRM_FORMAT_RGB565, __DRI_IMAGE_COMPONENTS_RGB, 1,
241     { { 0, 0, 0, __DRI_IMAGE_FORMAT_RGB565, 2 } } },
242
243   { DRM_FORMAT_R8, __DRI_IMAGE_COMPONENTS_R, 1,
244     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, } },
245
246   { DRM_FORMAT_R16, __DRI_IMAGE_COMPONENTS_R, 1,
247     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16, 1 }, } },
248
249   { DRM_FORMAT_GR88, __DRI_IMAGE_COMPONENTS_RG, 1,
250     { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 }, } },
251
252   { DRM_FORMAT_GR1616, __DRI_IMAGE_COMPONENTS_RG, 1,
253     { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR1616, 2 }, } },
254
255   { DRM_FORMAT_YUV410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
256     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
257       { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 },
258       { 2, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 } } },
259
260   { DRM_FORMAT_YUV411, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
261     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
262       { 1, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 },
263       { 2, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
264
265   { DRM_FORMAT_YUV420, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
266     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
267       { 1, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 },
268       { 2, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 } } },
269
270   { DRM_FORMAT_YUV422, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
271     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
272       { 1, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 },
273       { 2, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
274
275   { DRM_FORMAT_YUV444, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
276     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
277       { 1, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
278       { 2, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
279
280   { DRM_FORMAT_YVU410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
281     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
282       { 2, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 },
283       { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 } } },
284
285   { DRM_FORMAT_YVU411, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
286     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
287       { 2, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 },
288       { 1, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
289
290   { DRM_FORMAT_YVU420, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
291     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
292       { 2, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 },
293       { 1, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 } } },
294
295   { DRM_FORMAT_YVU422, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
296     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
297       { 2, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 },
298       { 1, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
299
300   { DRM_FORMAT_YVU444, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
301     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
302       { 2, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
303       { 1, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
304
305   { DRM_FORMAT_NV12, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
306     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
307       { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88, 2 } } },
308
309   { DRM_FORMAT_P010, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
310     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16, 2 },
311       { 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616, 4 } } },
312
313   { DRM_FORMAT_P012, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
314     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16, 2 },
315       { 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616, 4 } } },
316
317   { DRM_FORMAT_P016, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
318     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R16, 2 },
319       { 1, 1, 1, __DRI_IMAGE_FORMAT_GR1616, 4 } } },
320
321   { DRM_FORMAT_NV16, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
322     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
323       { 1, 1, 0, __DRI_IMAGE_FORMAT_GR88, 2 } } },
324
325   { DRM_FORMAT_AYUV, __DRI_IMAGE_COMPONENTS_AYUV, 1,
326     { { 0, 0, 0, __DRI_IMAGE_FORMAT_ABGR8888, 4 } } },
327
328   { DRM_FORMAT_XYUV8888, __DRI_IMAGE_COMPONENTS_XYUV, 1,
329     { { 0, 0, 0, __DRI_IMAGE_FORMAT_XBGR8888, 4 } } },
330
331   /* For YUYV and UYVY buffers, we set up two overlapping DRI images
332    * and treat them as planar buffers in the compositors.
333    * Plane 0 is GR88 and samples YU or YV pairs and places Y into
334    * the R component, while plane 1 is ARGB/ABGR and samples YUYV/UYVY
335    * clusters and places pairs and places U into the G component and
336    * V into A.  This lets the texture sampler interpolate the Y
337    * components correctly when sampling from plane 0, and interpolate
338    * U and V correctly when sampling from plane 1. */
339   { DRM_FORMAT_YUYV, __DRI_IMAGE_COMPONENTS_Y_XUXV, 2,
340     { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 },
341       { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } },
342   { DRM_FORMAT_UYVY, __DRI_IMAGE_COMPONENTS_Y_UXVX, 2,
343     { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 },
344       { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888, 4 } } }
345};
346
347static const struct {
348   uint64_t modifier;
349   unsigned since_ver;
350} supported_modifiers[] = {
351   { .modifier = DRM_FORMAT_MOD_LINEAR       , .since_ver = 1 },
352   { .modifier = I915_FORMAT_MOD_X_TILED     , .since_ver = 1 },
353   { .modifier = I915_FORMAT_MOD_Y_TILED     , .since_ver = 6 },
354   { .modifier = I915_FORMAT_MOD_Y_TILED_CCS , .since_ver = 9 },
355};
356
357static bool
358modifier_is_supported(const struct intel_device_info *devinfo,
359                      const struct brw_image_format *fmt, int dri_format,
360                      unsigned use, uint64_t modifier)
361{
362   const struct isl_drm_modifier_info *modinfo =
363      isl_drm_modifier_get_info(modifier);
364   int i;
365
366   /* ISL had better know about the modifier */
367   if (!modinfo)
368      return false;
369
370   if (devinfo->ver < 9 && (use & __DRI_IMAGE_USE_SCANOUT) &&
371       !(modinfo->tiling == ISL_TILING_LINEAR ||
372         modinfo->tiling == ISL_TILING_X))
373      return false;
374
375   if (modinfo->aux_usage == ISL_AUX_USAGE_CCS_E) {
376      /* If INTEL_DEBUG=norbc is set, don't support any CCS_E modifiers */
377      if (INTEL_DEBUG(DEBUG_NO_RBC))
378         return false;
379
380      /* CCS_E is not supported for planar images */
381      if (fmt && fmt->nplanes > 1)
382         return false;
383
384      if (fmt) {
385         assert(dri_format == 0);
386         dri_format = fmt->planes[0].dri_format;
387      }
388
389      mesa_format format = driImageFormatToGLFormat(dri_format);
390      /* Whether or not we support compression is based on the RGBA non-sRGB
391       * version of the format.
392       */
393      format = _mesa_format_fallback_rgbx_to_rgba(format);
394      format = _mesa_get_srgb_format_linear(format);
395      if (!isl_format_supports_ccs_e(devinfo,
396                                     brw_isl_format_for_mesa_format(format)))
397         return false;
398   }
399
400   for (i = 0; i < ARRAY_SIZE(supported_modifiers); i++) {
401      if (supported_modifiers[i].modifier != modifier)
402         continue;
403
404      return supported_modifiers[i].since_ver <= devinfo->ver;
405   }
406
407   return false;
408}
409
410static uint64_t
411tiling_to_modifier(uint32_t tiling)
412{
413   static const uint64_t map[] = {
414      [I915_TILING_NONE]   = DRM_FORMAT_MOD_LINEAR,
415      [I915_TILING_X]      = I915_FORMAT_MOD_X_TILED,
416      [I915_TILING_Y]      = I915_FORMAT_MOD_Y_TILED,
417   };
418
419   assert(tiling < ARRAY_SIZE(map));
420
421   return map[tiling];
422}
423
424static void
425brw_image_warn_if_unaligned(__DRIimage *image, const char *func)
426{
427   uint32_t tiling, swizzle;
428   brw_bo_get_tiling(image->bo, &tiling, &swizzle);
429
430   if (tiling != I915_TILING_NONE && (image->offset & 0xfff)) {
431      _mesa_warning(NULL, "%s: offset 0x%08x not on tile boundary",
432                    func, image->offset);
433   }
434}
435
436static const struct brw_image_format *
437brw_image_format_lookup(int fourcc)
438{
439   for (unsigned i = 0; i < ARRAY_SIZE(brw_image_formats); i++) {
440      if (brw_image_formats[i].fourcc == fourcc)
441         return &brw_image_formats[i];
442   }
443
444   return NULL;
445}
446
447static bool
448brw_image_get_fourcc(__DRIimage *image, int *fourcc)
449{
450   if (image->planar_format) {
451      *fourcc = image->planar_format->fourcc;
452      return true;
453   }
454
455   for (unsigned i = 0; i < ARRAY_SIZE(brw_image_formats); i++) {
456      if (brw_image_formats[i].planes[0].dri_format == image->dri_format) {
457         *fourcc = brw_image_formats[i].fourcc;
458         return true;
459      }
460   }
461   return false;
462}
463
464static __DRIimage *
465brw_allocate_image(struct brw_screen *screen, int dri_format,
466                   void *loaderPrivate)
467{
468    __DRIimage *image;
469
470    image = calloc(1, sizeof *image);
471    if (image == NULL)
472       return NULL;
473
474    image->screen = screen;
475    image->dri_format = dri_format;
476    image->offset = 0;
477
478    image->format = driImageFormatToGLFormat(dri_format);
479    if (dri_format != __DRI_IMAGE_FORMAT_NONE &&
480        image->format == MESA_FORMAT_NONE) {
481       free(image);
482       return NULL;
483    }
484
485    image->internal_format = _mesa_get_format_base_format(image->format);
486    image->driScrnPriv = screen->driScrnPriv;
487    image->loader_private = loaderPrivate;
488
489    return image;
490}
491
492/**
493 * Sets up a DRIImage structure to point to a slice out of a miptree.
494 */
495static void
496brw_setup_image_from_mipmap_tree(struct brw_context *brw, __DRIimage *image,
497                                 struct brw_mipmap_tree *mt, GLuint level,
498                                 GLuint zoffset)
499{
500   brw_miptree_make_shareable(brw, mt);
501
502   brw_miptree_check_level_layer(mt, level, zoffset);
503
504   image->width = minify(mt->surf.phys_level0_sa.width,
505                         level - mt->first_level);
506   image->height = minify(mt->surf.phys_level0_sa.height,
507                          level - mt->first_level);
508   image->pitch = mt->surf.row_pitch_B;
509
510   image->offset = brw_miptree_get_tile_offsets(mt, level, zoffset,
511                                                  &image->tile_x,
512                                                  &image->tile_y);
513
514   brw_bo_unreference(image->bo);
515   image->bo = mt->bo;
516   brw_bo_reference(mt->bo);
517}
518
519static __DRIimage *
520brw_create_image_from_name(__DRIscreen *dri_screen,
521                           int width, int height, int format,
522                           int name, int pitch, void *loaderPrivate)
523{
524    struct brw_screen *screen = dri_screen->driverPrivate;
525    __DRIimage *image;
526    int cpp;
527
528    image = brw_allocate_image(screen, format, loaderPrivate);
529    if (image == NULL)
530       return NULL;
531
532    if (image->format == MESA_FORMAT_NONE)
533       cpp = 1;
534    else
535       cpp = _mesa_get_format_bytes(image->format);
536
537    image->width = width;
538    image->height = height;
539    image->pitch = pitch * cpp;
540    image->bo = brw_bo_gem_create_from_name(screen->bufmgr, "image",
541                                                  name);
542    if (!image->bo) {
543       free(image);
544       return NULL;
545    }
546    image->modifier = tiling_to_modifier(image->bo->tiling_mode);
547
548    return image;
549}
550
551static __DRIimage *
552brw_create_image_from_renderbuffer(__DRIcontext *context,
553                                   int renderbuffer, void *loaderPrivate)
554{
555   __DRIimage *image;
556   struct brw_context *brw = context->driverPrivate;
557   struct gl_context *ctx = &brw->ctx;
558   struct gl_renderbuffer *rb;
559   struct brw_renderbuffer *irb;
560
561   rb = _mesa_lookup_renderbuffer(ctx, renderbuffer);
562   if (!rb) {
563      _mesa_error(ctx, GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
564      return NULL;
565   }
566
567   irb = brw_renderbuffer(rb);
568   brw_miptree_make_shareable(brw, irb->mt);
569   image = calloc(1, sizeof *image);
570   if (image == NULL)
571      return NULL;
572
573   image->internal_format = rb->InternalFormat;
574   image->format = rb->Format;
575   image->modifier = tiling_to_modifier(
576                        isl_tiling_to_i915_tiling(irb->mt->surf.tiling));
577   image->offset = 0;
578   image->driScrnPriv = context->driScreenPriv;
579   image->loader_private = loaderPrivate;
580   brw_bo_unreference(image->bo);
581   image->bo = irb->mt->bo;
582   brw_bo_reference(irb->mt->bo);
583   image->width = rb->Width;
584   image->height = rb->Height;
585   image->pitch = irb->mt->surf.row_pitch_B;
586   image->dri_format = driGLFormatToImageFormat(image->format);
587   image->has_depthstencil = irb->mt->stencil_mt? true : false;
588
589   rb->NeedsFinishRenderTexture = true;
590   return image;
591}
592
593static __DRIimage *
594brw_create_image_from_texture(__DRIcontext *context, int target,
595                              unsigned texture, int zoffset,
596                              int level,
597                              unsigned *error,
598                              void *loaderPrivate)
599{
600   __DRIimage *image;
601   struct brw_context *brw = context->driverPrivate;
602   struct gl_texture_object *obj;
603   struct brw_texture_object *iobj;
604   GLuint face = 0;
605
606   obj = _mesa_lookup_texture(&brw->ctx, texture);
607   if (!obj || obj->Target != target) {
608      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
609      return NULL;
610   }
611
612   if (target == GL_TEXTURE_CUBE_MAP)
613      face = zoffset;
614
615   _mesa_test_texobj_completeness(&brw->ctx, obj);
616   iobj = brw_texture_object(obj);
617   if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) {
618      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
619      return NULL;
620   }
621
622   if (level < obj->Attrib.BaseLevel || level > obj->_MaxLevel) {
623      *error = __DRI_IMAGE_ERROR_BAD_MATCH;
624      return NULL;
625   }
626
627   if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < zoffset) {
628      *error = __DRI_IMAGE_ERROR_BAD_MATCH;
629      return NULL;
630   }
631   image = calloc(1, sizeof *image);
632   if (image == NULL) {
633      *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
634      return NULL;
635   }
636
637   image->internal_format = obj->Image[face][level]->InternalFormat;
638   image->format = obj->Image[face][level]->TexFormat;
639   image->modifier = tiling_to_modifier(
640                        isl_tiling_to_i915_tiling(iobj->mt->surf.tiling));
641   image->driScrnPriv = context->driScreenPriv;
642   image->loader_private = loaderPrivate;
643   brw_setup_image_from_mipmap_tree(brw, image, iobj->mt, level, zoffset);
644   image->dri_format = driGLFormatToImageFormat(image->format);
645   image->has_depthstencil = iobj->mt->stencil_mt? true : false;
646   image->planar_format = iobj->planar_format;
647   if (image->dri_format == __DRI_IMAGE_FORMAT_NONE) {
648      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
649      free(image);
650      return NULL;
651   }
652
653   *error = __DRI_IMAGE_ERROR_SUCCESS;
654   return image;
655}
656
657static void
658brw_destroy_image(__DRIimage *image)
659{
660   const __DRIscreen * driScreen = image->driScrnPriv;
661   const __DRIimageLoaderExtension *imgLoader = driScreen->image.loader;
662   const __DRIdri2LoaderExtension *dri2Loader = driScreen->dri2.loader;
663
664   if (imgLoader && imgLoader->base.version >= 4 &&
665         imgLoader->destroyLoaderImageState) {
666      imgLoader->destroyLoaderImageState(image->loader_private);
667   } else if (dri2Loader && dri2Loader->base.version >= 5 &&
668         dri2Loader->destroyLoaderImageState) {
669      dri2Loader->destroyLoaderImageState(image->loader_private);
670   }
671
672   brw_bo_unreference(image->bo);
673   free(image);
674}
675
676enum modifier_priority {
677   MODIFIER_PRIORITY_INVALID = 0,
678   MODIFIER_PRIORITY_LINEAR,
679   MODIFIER_PRIORITY_X,
680   MODIFIER_PRIORITY_Y,
681   MODIFIER_PRIORITY_Y_CCS,
682};
683
684const uint64_t priority_to_modifier[] = {
685   [MODIFIER_PRIORITY_INVALID] = DRM_FORMAT_MOD_INVALID,
686   [MODIFIER_PRIORITY_LINEAR] = DRM_FORMAT_MOD_LINEAR,
687   [MODIFIER_PRIORITY_X] = I915_FORMAT_MOD_X_TILED,
688   [MODIFIER_PRIORITY_Y] = I915_FORMAT_MOD_Y_TILED,
689   [MODIFIER_PRIORITY_Y_CCS] = I915_FORMAT_MOD_Y_TILED_CCS,
690};
691
692static uint64_t
693select_best_modifier(struct intel_device_info *devinfo,
694                     int dri_format,
695                     unsigned use,
696                     const uint64_t *modifiers,
697                     const unsigned count)
698{
699   enum modifier_priority prio = MODIFIER_PRIORITY_INVALID;
700
701   for (int i = 0; i < count; i++) {
702      if (!modifier_is_supported(devinfo, NULL, dri_format, use, modifiers[i]))
703         continue;
704
705      switch (modifiers[i]) {
706      case I915_FORMAT_MOD_Y_TILED_CCS:
707         prio = MAX2(prio, MODIFIER_PRIORITY_Y_CCS);
708         break;
709      case I915_FORMAT_MOD_Y_TILED:
710         prio = MAX2(prio, MODIFIER_PRIORITY_Y);
711         break;
712      case I915_FORMAT_MOD_X_TILED:
713         prio = MAX2(prio, MODIFIER_PRIORITY_X);
714         break;
715      case DRM_FORMAT_MOD_LINEAR:
716         prio = MAX2(prio, MODIFIER_PRIORITY_LINEAR);
717         break;
718      case DRM_FORMAT_MOD_INVALID:
719      default:
720         break;
721      }
722   }
723
724   return priority_to_modifier[prio];
725}
726
727static __DRIimage *
728brw_create_image_common(__DRIscreen *dri_screen,
729                        int width, int height, int format,
730                        unsigned int use,
731                        const uint64_t *modifiers,
732                        unsigned count,
733                        void *loaderPrivate)
734{
735   __DRIimage *image;
736   struct brw_screen *screen = dri_screen->driverPrivate;
737   uint64_t modifier = DRM_FORMAT_MOD_INVALID;
738   bool ok;
739
740   if (use & __DRI_IMAGE_USE_CURSOR) {
741      if (width != 64 || height != 64)
742         return NULL;
743      modifier = DRM_FORMAT_MOD_LINEAR;
744   }
745
746   if (use & __DRI_IMAGE_USE_LINEAR)
747      modifier = DRM_FORMAT_MOD_LINEAR;
748
749   if (modifier == DRM_FORMAT_MOD_INVALID) {
750      if (modifiers) {
751         /* User requested specific modifiers */
752         modifier = select_best_modifier(&screen->devinfo, format, use,
753                                         modifiers, count);
754         if (modifier == DRM_FORMAT_MOD_INVALID)
755            return NULL;
756      } else {
757         /* Historically, X-tiled was the default, and so lack of modifier means
758          * X-tiled.
759          */
760         modifier = I915_FORMAT_MOD_X_TILED;
761      }
762   }
763
764   image = brw_allocate_image(screen, format, loaderPrivate);
765   if (image == NULL)
766      return NULL;
767
768   const struct isl_drm_modifier_info *mod_info =
769      isl_drm_modifier_get_info(modifier);
770
771   struct isl_surf surf;
772   ok = isl_surf_init(&screen->isl_dev, &surf,
773                      .dim = ISL_SURF_DIM_2D,
774                      .format = brw_isl_format_for_mesa_format(image->format),
775                      .width = width,
776                      .height = height,
777                      .depth = 1,
778                      .levels = 1,
779                      .array_len = 1,
780                      .samples = 1,
781                      .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT |
782                               ISL_SURF_USAGE_TEXTURE_BIT |
783                               ISL_SURF_USAGE_STORAGE_BIT |
784                               ((use & __DRI_IMAGE_USE_SCANOUT) ?
785                                ISL_SURF_USAGE_DISPLAY_BIT : 0),
786                      .tiling_flags = (1 << mod_info->tiling));
787   assert(ok);
788   if (!ok) {
789      free(image);
790      return NULL;
791   }
792
793   struct isl_surf aux_surf = {0,};
794   if (mod_info->aux_usage == ISL_AUX_USAGE_CCS_E) {
795      ok = isl_surf_get_ccs_surf(&screen->isl_dev, &surf, NULL, &aux_surf, 0);
796      if (!ok) {
797         free(image);
798         return NULL;
799      }
800   } else {
801      assert(mod_info->aux_usage == ISL_AUX_USAGE_NONE);
802      aux_surf.size_B = 0;
803   }
804
805   /* We request that the bufmgr zero the buffer for us for two reasons:
806    *
807    *  1) If a buffer gets re-used from the pool, we don't want to leak random
808    *     garbage from our process to some other.
809    *
810    *  2) For images with CCS_E, we want to ensure that the CCS starts off in
811    *     a valid state.  A CCS value of 0 indicates that the given block is
812    *     in the pass-through state which is what we want.
813    */
814   image->bo = brw_bo_alloc_tiled(screen->bufmgr, "image",
815                                  surf.size_B + aux_surf.size_B,
816                                  BRW_MEMZONE_OTHER,
817                                  isl_tiling_to_i915_tiling(mod_info->tiling),
818                                  surf.row_pitch_B, BO_ALLOC_ZEROED);
819   if (image->bo == NULL) {
820      free(image);
821      return NULL;
822   }
823   image->width = width;
824   image->height = height;
825   image->pitch = surf.row_pitch_B;
826   image->modifier = modifier;
827
828   if (aux_surf.size_B) {
829      image->aux_offset = surf.size_B;
830      image->aux_pitch = aux_surf.row_pitch_B;
831      image->aux_size = aux_surf.size_B;
832   }
833
834   return image;
835}
836
837static __DRIimage *
838brw_create_image(__DRIscreen *dri_screen,
839                 int width, int height, int format,
840                 unsigned int use,
841                 void *loaderPrivate)
842{
843   return brw_create_image_common(dri_screen, width, height, format, use,
844                                  NULL, 0, loaderPrivate);
845}
846
847static void *
848brw_map_image(__DRIcontext *context, __DRIimage *image,
849              int x0, int y0, int width, int height,
850              unsigned int flags, int *stride, void **map_info)
851{
852   struct brw_context *brw = NULL;
853   struct brw_bo *bo = NULL;
854   void *raw_data = NULL;
855   GLuint pix_w = 1;
856   GLuint pix_h = 1;
857   GLint pix_bytes = 1;
858
859   if (!context || !image || !stride || !map_info || *map_info)
860      return NULL;
861
862   if (x0 < 0 || x0 >= image->width || width > image->width - x0)
863      return NULL;
864
865   if (y0 < 0 || y0 >= image->height || height > image->height - y0)
866      return NULL;
867
868   if (flags & MAP_INTERNAL_MASK)
869      return NULL;
870
871   brw = context->driverPrivate;
872   bo = image->bo;
873
874   assert(brw);
875   assert(bo);
876
877   /* DRI flags and GL_MAP.*_BIT flags are the same, so just pass them on. */
878   raw_data = brw_bo_map(brw, bo, flags);
879   if (!raw_data)
880      return NULL;
881
882   _mesa_get_format_block_size(image->format, &pix_w, &pix_h);
883   pix_bytes = _mesa_get_format_bytes(image->format);
884
885   assert(pix_w);
886   assert(pix_h);
887   assert(pix_bytes > 0);
888
889   raw_data += (x0 / pix_w) * pix_bytes + (y0 / pix_h) * image->pitch;
890
891   brw_bo_reference(bo);
892
893   *stride = image->pitch;
894   *map_info = bo;
895
896   return raw_data;
897}
898
899static void
900brw_unmap_image(UNUSED __DRIcontext *context, UNUSED __DRIimage *image,
901                void *map_info)
902{
903   struct brw_bo *bo = map_info;
904
905   brw_bo_unmap(bo);
906   brw_bo_unreference(bo);
907}
908
909static __DRIimage *
910brw_create_image_with_modifiers(__DRIscreen *dri_screen,
911                                  int width, int height, int format,
912                                  const uint64_t *modifiers,
913                                  const unsigned count,
914                                  void *loaderPrivate)
915{
916   return brw_create_image_common(dri_screen, width, height, format, 0,
917                                  modifiers, count, loaderPrivate);
918}
919
920static __DRIimage *
921brw_create_image_with_modifiers2(__DRIscreen *dri_screen,
922                                 int width, int height, int format,
923                                 const uint64_t *modifiers,
924                                 const unsigned count, unsigned int use,
925                                 void *loaderPrivate)
926{
927   return brw_create_image_common(dri_screen, width, height, format, use,
928                                  modifiers, count, loaderPrivate);
929}
930
931static GLboolean
932brw_query_image(__DRIimage *image, int attrib, int *value)
933{
934   switch (attrib) {
935   case __DRI_IMAGE_ATTRIB_STRIDE:
936      *value = image->pitch;
937      return true;
938   case __DRI_IMAGE_ATTRIB_HANDLE: {
939      __DRIscreen *dri_screen = image->screen->driScrnPriv;
940      uint32_t handle;
941      if (brw_bo_export_gem_handle_for_device(image->bo,
942                                              dri_screen->fd,
943                                              &handle))
944         return false;
945      *value = handle;
946      return true;
947   }
948   case __DRI_IMAGE_ATTRIB_NAME:
949      return !brw_bo_flink(image->bo, (uint32_t *) value);
950   case __DRI_IMAGE_ATTRIB_FORMAT:
951      *value = image->dri_format;
952      return true;
953   case __DRI_IMAGE_ATTRIB_WIDTH:
954      *value = image->width;
955      return true;
956   case __DRI_IMAGE_ATTRIB_HEIGHT:
957      *value = image->height;
958      return true;
959   case __DRI_IMAGE_ATTRIB_COMPONENTS:
960      if (image->planar_format == NULL)
961         return false;
962      *value = image->planar_format->components;
963      return true;
964   case __DRI_IMAGE_ATTRIB_FD:
965      return !brw_bo_gem_export_to_prime(image->bo, value);
966   case __DRI_IMAGE_ATTRIB_FOURCC:
967      return brw_image_get_fourcc(image, value);
968   case __DRI_IMAGE_ATTRIB_NUM_PLANES:
969      if (isl_drm_modifier_has_aux(image->modifier)) {
970         assert(!image->planar_format || image->planar_format->nplanes == 1);
971         *value = 2;
972      } else if (image->planar_format) {
973         *value = image->planar_format->nplanes;
974      } else {
975         *value = 1;
976      }
977      return true;
978   case __DRI_IMAGE_ATTRIB_OFFSET:
979      *value = image->offset;
980      return true;
981   case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER:
982      *value = (image->modifier & 0xffffffff);
983      return true;
984   case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER:
985      *value = ((image->modifier >> 32) & 0xffffffff);
986      return true;
987
988  default:
989      return false;
990   }
991}
992
993static GLboolean
994brw_query_format_modifier_attribs(__DRIscreen *dri_screen,
995                                    uint32_t fourcc, uint64_t modifier,
996                                    int attrib, uint64_t *value)
997{
998   struct brw_screen *screen = dri_screen->driverPrivate;
999   const struct brw_image_format *f = brw_image_format_lookup(fourcc);
1000
1001   if (!modifier_is_supported(&screen->devinfo, f, 0, 0, modifier))
1002      return false;
1003
1004   switch (attrib) {
1005   case __DRI_IMAGE_FORMAT_MODIFIER_ATTRIB_PLANE_COUNT:
1006      *value = isl_drm_modifier_has_aux(modifier) ? 2 : f->nplanes;
1007      return true;
1008
1009   default:
1010      return false;
1011   }
1012}
1013
1014static __DRIimage *
1015brw_dup_image(__DRIimage *orig_image, void *loaderPrivate)
1016{
1017   __DRIimage *image;
1018
1019   image = calloc(1, sizeof *image);
1020   if (image == NULL)
1021      return NULL;
1022
1023   brw_bo_reference(orig_image->bo);
1024   image->screen          = orig_image->screen;
1025   image->bo              = orig_image->bo;
1026   image->internal_format = orig_image->internal_format;
1027   image->planar_format   = orig_image->planar_format;
1028   image->dri_format      = orig_image->dri_format;
1029   image->format          = orig_image->format;
1030   image->modifier        = orig_image->modifier;
1031   image->offset          = orig_image->offset;
1032   image->width           = orig_image->width;
1033   image->height          = orig_image->height;
1034   image->pitch           = orig_image->pitch;
1035   image->tile_x          = orig_image->tile_x;
1036   image->tile_y          = orig_image->tile_y;
1037   image->has_depthstencil = orig_image->has_depthstencil;
1038   image->driScrnPriv     = orig_image->driScrnPriv;
1039   image->loader_private  = loaderPrivate;
1040   image->aux_offset      = orig_image->aux_offset;
1041   image->aux_pitch       = orig_image->aux_pitch;
1042
1043   memcpy(image->strides, orig_image->strides, sizeof(image->strides));
1044   memcpy(image->offsets, orig_image->offsets, sizeof(image->offsets));
1045
1046   return image;
1047}
1048
1049static GLboolean
1050brw_validate_usage(__DRIimage *image, unsigned int use)
1051{
1052   if (use & __DRI_IMAGE_USE_CURSOR) {
1053      if (image->width != 64 || image->height != 64)
1054         return GL_FALSE;
1055   }
1056
1057   return GL_TRUE;
1058}
1059
1060static __DRIimage *
1061brw_create_image_from_names(__DRIscreen *dri_screen,
1062                            int width, int height, int fourcc,
1063                            int *names, int num_names,
1064                            int *strides, int *offsets,
1065                            void *loaderPrivate)
1066{
1067    const struct brw_image_format *f = NULL;
1068    __DRIimage *image;
1069    int i, index;
1070
1071    if (dri_screen == NULL || names == NULL || num_names != 1)
1072        return NULL;
1073
1074    f = brw_image_format_lookup(fourcc);
1075    if (f == NULL)
1076        return NULL;
1077
1078    image = brw_create_image_from_name(dri_screen, width, height,
1079                                       __DRI_IMAGE_FORMAT_NONE,
1080                                       names[0], strides[0],
1081                                       loaderPrivate);
1082
1083   if (image == NULL)
1084      return NULL;
1085
1086    image->planar_format = f;
1087    for (i = 0; i < f->nplanes; i++) {
1088        index = f->planes[i].buffer_index;
1089        image->offsets[index] = offsets[index];
1090        image->strides[index] = strides[index];
1091    }
1092
1093    return image;
1094}
1095
1096static __DRIimage *
1097brw_create_image_from_fds_common(__DRIscreen *dri_screen,
1098                                 int width, int height, int fourcc,
1099                                 uint64_t modifier, int *fds, int num_fds,
1100                                 int *strides, int *offsets,
1101                                 void *loaderPrivate)
1102{
1103   struct brw_screen *screen = dri_screen->driverPrivate;
1104   const struct brw_image_format *f;
1105   __DRIimage *image;
1106   int i, index;
1107   bool ok;
1108
1109   if (fds == NULL || num_fds < 1)
1110      return NULL;
1111
1112   f = brw_image_format_lookup(fourcc);
1113   if (f == NULL)
1114      return NULL;
1115
1116   if (modifier != DRM_FORMAT_MOD_INVALID &&
1117       !modifier_is_supported(&screen->devinfo, f, 0, 0, modifier))
1118      return NULL;
1119
1120   if (f->nplanes == 1)
1121      image = brw_allocate_image(screen, f->planes[0].dri_format,
1122                                   loaderPrivate);
1123   else
1124      image = brw_allocate_image(screen, __DRI_IMAGE_FORMAT_NONE,
1125                                   loaderPrivate);
1126
1127   if (image == NULL)
1128      return NULL;
1129
1130   image->width = width;
1131   image->height = height;
1132   image->pitch = strides[0];
1133
1134   image->planar_format = f;
1135
1136   if (modifier != DRM_FORMAT_MOD_INVALID) {
1137      const struct isl_drm_modifier_info *mod_info =
1138         isl_drm_modifier_get_info(modifier);
1139      uint32_t tiling = isl_tiling_to_i915_tiling(mod_info->tiling);
1140      image->bo = brw_bo_gem_create_from_prime_tiled(screen->bufmgr, fds[0],
1141                                                     tiling, strides[0]);
1142   } else {
1143      image->bo = brw_bo_gem_create_from_prime(screen->bufmgr, fds[0]);
1144   }
1145
1146   if (image->bo == NULL) {
1147      free(image);
1148      return NULL;
1149   }
1150
1151   /* We only support all planes from the same bo.
1152    * brw_bo_gem_create_from_prime() should return the same pointer for all
1153    * fds received here */
1154   for (i = 1; i < num_fds; i++) {
1155      struct brw_bo *aux = brw_bo_gem_create_from_prime(screen->bufmgr, fds[i]);
1156      brw_bo_unreference(aux);
1157      if (aux != image->bo) {
1158         brw_bo_unreference(image->bo);
1159         free(image);
1160         return NULL;
1161      }
1162   }
1163
1164   if (modifier != DRM_FORMAT_MOD_INVALID)
1165      image->modifier = modifier;
1166   else
1167      image->modifier = tiling_to_modifier(image->bo->tiling_mode);
1168
1169   const struct isl_drm_modifier_info *mod_info =
1170      isl_drm_modifier_get_info(image->modifier);
1171
1172   int size = 0;
1173   struct isl_surf surf;
1174   for (i = 0; i < f->nplanes; i++) {
1175      index = f->planes[i].buffer_index;
1176      image->offsets[index] = offsets[index];
1177      image->strides[index] = strides[index];
1178
1179      mesa_format format = driImageFormatToGLFormat(f->planes[i].dri_format);
1180      /* The images we will create are actually based on the RGBA non-sRGB
1181       * version of the format.
1182       */
1183      format = _mesa_format_fallback_rgbx_to_rgba(format);
1184      format = _mesa_get_srgb_format_linear(format);
1185
1186      ok = isl_surf_init(&screen->isl_dev, &surf,
1187                         .dim = ISL_SURF_DIM_2D,
1188                         .format = brw_isl_format_for_mesa_format(format),
1189                         .width = image->width >> f->planes[i].width_shift,
1190                         .height = image->height >> f->planes[i].height_shift,
1191                         .depth = 1,
1192                         .levels = 1,
1193                         .array_len = 1,
1194                         .samples = 1,
1195                         .row_pitch_B = strides[index],
1196                         .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT |
1197                                  ISL_SURF_USAGE_TEXTURE_BIT |
1198                                  ISL_SURF_USAGE_STORAGE_BIT,
1199                         .tiling_flags = (1 << mod_info->tiling));
1200      if (!ok) {
1201         brw_bo_unreference(image->bo);
1202         free(image);
1203         return NULL;
1204      }
1205
1206      const int end = offsets[index] + surf.size_B;
1207      if (size < end)
1208         size = end;
1209   }
1210
1211   if (mod_info->aux_usage == ISL_AUX_USAGE_CCS_E) {
1212      /* Even though we initialize surf in the loop above, we know that
1213       * anything with CCS_E will have exactly one plane so surf is properly
1214       * initialized when we get here.
1215       */
1216      assert(f->nplanes == 1);
1217
1218      image->aux_offset = offsets[1];
1219      image->aux_pitch = strides[1];
1220
1221      /* Scanout hardware requires that the CCS be placed after the main
1222       * surface in memory.  We consider any CCS that is placed any earlier in
1223       * memory to be invalid and reject it.
1224       *
1225       * At some point in the future, this restriction may be relaxed if the
1226       * hardware becomes less strict but we may need a new modifier for that.
1227       */
1228      assert(size > 0);
1229      if (image->aux_offset < size) {
1230         brw_bo_unreference(image->bo);
1231         free(image);
1232         return NULL;
1233      }
1234
1235      struct isl_surf aux_surf = {0,};
1236      ok = isl_surf_get_ccs_surf(&screen->isl_dev, &surf, NULL, &aux_surf,
1237                                 image->aux_pitch);
1238      if (!ok) {
1239         brw_bo_unreference(image->bo);
1240         free(image);
1241         return NULL;
1242      }
1243
1244      image->aux_size = aux_surf.size_B;
1245
1246      const int end = image->aux_offset + aux_surf.size_B;
1247      if (size < end)
1248         size = end;
1249   } else {
1250      assert(mod_info->aux_usage == ISL_AUX_USAGE_NONE);
1251   }
1252
1253   /* Check that the requested image actually fits within the BO. 'size'
1254    * is already relative to the offsets, so we don't need to add that. */
1255   if (image->bo->size == 0) {
1256      image->bo->size = size;
1257   } else if (size > image->bo->size) {
1258      brw_bo_unreference(image->bo);
1259      free(image);
1260      return NULL;
1261   }
1262
1263   if (f->nplanes == 1) {
1264      image->offset = image->offsets[0];
1265      brw_image_warn_if_unaligned(image, __func__);
1266   }
1267
1268   return image;
1269}
1270
1271static __DRIimage *
1272brw_create_image_from_fds(__DRIscreen *dri_screen,
1273                          int width, int height, int fourcc,
1274                          int *fds, int num_fds, int *strides, int *offsets,
1275                          void *loaderPrivate)
1276{
1277   return brw_create_image_from_fds_common(dri_screen, width, height, fourcc,
1278                                           DRM_FORMAT_MOD_INVALID,
1279                                           fds, num_fds, strides, offsets,
1280                                           loaderPrivate);
1281}
1282
1283static __DRIimage *
1284brw_create_image_from_dma_bufs2(__DRIscreen *dri_screen,
1285                                int width, int height,
1286                                int fourcc, uint64_t modifier,
1287                                int *fds, int num_fds,
1288                                int *strides, int *offsets,
1289                                enum __DRIYUVColorSpace yuv_color_space,
1290                                enum __DRISampleRange sample_range,
1291                                enum __DRIChromaSiting horizontal_siting,
1292                                enum __DRIChromaSiting vertical_siting,
1293                                unsigned *error,
1294                                void *loaderPrivate)
1295{
1296   __DRIimage *image;
1297   const struct brw_image_format *f = brw_image_format_lookup(fourcc);
1298
1299   if (!f) {
1300      *error = __DRI_IMAGE_ERROR_BAD_MATCH;
1301      return NULL;
1302   }
1303
1304   image = brw_create_image_from_fds_common(dri_screen, width, height,
1305                                            fourcc, modifier,
1306                                            fds, num_fds, strides, offsets,
1307                                            loaderPrivate);
1308
1309   /*
1310    * Invalid parameters and any inconsistencies between are assumed to be
1311    * checked by the caller. Therefore besides unsupported formats one can fail
1312    * only in allocation.
1313    */
1314   if (!image) {
1315      *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
1316      return NULL;
1317   }
1318
1319   image->yuv_color_space = yuv_color_space;
1320   image->sample_range = sample_range;
1321   image->horizontal_siting = horizontal_siting;
1322   image->vertical_siting = vertical_siting;
1323   image->imported_dmabuf = true;
1324
1325   *error = __DRI_IMAGE_ERROR_SUCCESS;
1326   return image;
1327}
1328
1329static __DRIimage *
1330brw_create_image_from_dma_bufs(__DRIscreen *dri_screen,
1331                               int width, int height, int fourcc,
1332                               int *fds, int num_fds,
1333                               int *strides, int *offsets,
1334                               enum __DRIYUVColorSpace yuv_color_space,
1335                               enum __DRISampleRange sample_range,
1336                               enum __DRIChromaSiting horizontal_siting,
1337                               enum __DRIChromaSiting vertical_siting,
1338                               unsigned *error,
1339                               void *loaderPrivate)
1340{
1341   return brw_create_image_from_dma_bufs2(dri_screen, width, height,
1342                                          fourcc, DRM_FORMAT_MOD_INVALID,
1343                                          fds, num_fds, strides, offsets,
1344                                          yuv_color_space,
1345                                          sample_range,
1346                                          horizontal_siting,
1347                                          vertical_siting,
1348                                          error,
1349                                          loaderPrivate);
1350}
1351
1352static bool
1353brw_image_format_is_supported(const struct intel_device_info *devinfo,
1354                                const struct brw_image_format *fmt)
1355{
1356   /* Currently, all formats with an brw_image_format are available on all
1357    * platforms so there's really nothing to check there.
1358    */
1359
1360#ifndef NDEBUG
1361   if (fmt->nplanes == 1) {
1362      mesa_format format = driImageFormatToGLFormat(fmt->planes[0].dri_format);
1363      /* The images we will create are actually based on the RGBA non-sRGB
1364       * version of the format.
1365       */
1366      format = _mesa_format_fallback_rgbx_to_rgba(format);
1367      format = _mesa_get_srgb_format_linear(format);
1368      enum isl_format isl_format = brw_isl_format_for_mesa_format(format);
1369      assert(isl_format_supports_rendering(devinfo, isl_format));
1370   }
1371#endif
1372
1373   return true;
1374}
1375
1376static GLboolean
1377brw_query_dma_buf_formats(__DRIscreen *_screen, int max,
1378                            int *formats, int *count)
1379{
1380   struct brw_screen *screen = _screen->driverPrivate;
1381   int num_formats = 0, i;
1382
1383   for (i = 0; i < ARRAY_SIZE(brw_image_formats); i++) {
1384      /* These formats are valid DRI formats but do not exist in drm_fourcc.h
1385       * in the Linux kernel. We don't want to accidentally advertise them
1386       * them through the EGL layer.
1387       */
1388      if (brw_image_formats[i].fourcc == __DRI_IMAGE_FOURCC_SARGB8888 ||
1389          brw_image_formats[i].fourcc == __DRI_IMAGE_FOURCC_SABGR8888 ||
1390          brw_image_formats[i].fourcc == __DRI_IMAGE_FOURCC_SXRGB8888)
1391         continue;
1392
1393      if (!brw_image_format_is_supported(&screen->devinfo,
1394                                           &brw_image_formats[i]))
1395         continue;
1396
1397      num_formats++;
1398      if (max == 0)
1399         continue;
1400
1401      formats[num_formats - 1] = brw_image_formats[i].fourcc;
1402      if (num_formats >= max)
1403         break;
1404   }
1405
1406   *count = num_formats;
1407   return true;
1408}
1409
1410static GLboolean
1411brw_query_dma_buf_modifiers(__DRIscreen *_screen, int fourcc, int max,
1412                              uint64_t *modifiers,
1413                              unsigned int *external_only,
1414                              int *count)
1415{
1416   struct brw_screen *screen = _screen->driverPrivate;
1417   const struct brw_image_format *f;
1418   int num_mods = 0, i;
1419
1420   f = brw_image_format_lookup(fourcc);
1421   if (f == NULL)
1422      return false;
1423
1424   if (!brw_image_format_is_supported(&screen->devinfo, f))
1425      return false;
1426
1427   for (i = 0; i < ARRAY_SIZE(supported_modifiers); i++) {
1428      uint64_t modifier = supported_modifiers[i].modifier;
1429      if (!modifier_is_supported(&screen->devinfo, f, 0, 0, modifier))
1430         continue;
1431
1432      num_mods++;
1433      if (max == 0)
1434         continue;
1435
1436      modifiers[num_mods - 1] = modifier;
1437      if (num_mods >= max)
1438        break;
1439   }
1440
1441   if (external_only != NULL) {
1442      for (i = 0; i < num_mods && i < max; i++) {
1443         if (f->components == __DRI_IMAGE_COMPONENTS_Y_U_V ||
1444             f->components == __DRI_IMAGE_COMPONENTS_Y_UV ||
1445             f->components == __DRI_IMAGE_COMPONENTS_AYUV ||
1446             f->components == __DRI_IMAGE_COMPONENTS_XYUV ||
1447             f->components == __DRI_IMAGE_COMPONENTS_Y_XUXV ||
1448             f->components == __DRI_IMAGE_COMPONENTS_Y_UXVX) {
1449            external_only[i] = GL_TRUE;
1450         }
1451         else {
1452            external_only[i] = GL_FALSE;
1453         }
1454      }
1455   }
1456
1457   *count = num_mods;
1458   return true;
1459}
1460
1461static __DRIimage *
1462brw_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
1463{
1464    int width, height, offset, stride, size, dri_format;
1465    __DRIimage *image;
1466
1467    if (parent == NULL)
1468       return NULL;
1469
1470    width = parent->width;
1471    height = parent->height;
1472
1473    const struct brw_image_format *f = parent->planar_format;
1474
1475    if (f && plane < f->nplanes) {
1476       /* Use the planar format definition. */
1477       width >>= f->planes[plane].width_shift;
1478       height >>= f->planes[plane].height_shift;
1479       dri_format = f->planes[plane].dri_format;
1480       int index = f->planes[plane].buffer_index;
1481       offset = parent->offsets[index];
1482       stride = parent->strides[index];
1483       size = height * stride;
1484    } else if (plane == 0) {
1485       /* The only plane of a non-planar image: copy the parent definition
1486        * directly. */
1487       dri_format = parent->dri_format;
1488       offset = parent->offset;
1489       stride = parent->pitch;
1490       size = height * stride;
1491    } else if (plane == 1 && parent->modifier != DRM_FORMAT_MOD_INVALID &&
1492               isl_drm_modifier_has_aux(parent->modifier)) {
1493       /* Auxiliary plane */
1494       dri_format = parent->dri_format;
1495       offset = parent->aux_offset;
1496       stride = parent->aux_pitch;
1497       size = parent->aux_size;
1498    } else {
1499       return NULL;
1500    }
1501
1502    if (offset + size > parent->bo->size) {
1503       _mesa_warning(NULL, "intel_from_planar: subimage out of bounds");
1504       return NULL;
1505    }
1506
1507    image = brw_allocate_image(parent->screen, dri_format, loaderPrivate);
1508    if (image == NULL)
1509       return NULL;
1510
1511    image->bo = parent->bo;
1512    brw_bo_reference(parent->bo);
1513    image->modifier = parent->modifier;
1514
1515    image->width = width;
1516    image->height = height;
1517    image->pitch = stride;
1518    image->offset = offset;
1519
1520    brw_image_warn_if_unaligned(image, __func__);
1521
1522    return image;
1523}
1524
1525static const __DRIimageExtension brwImageExtension = {
1526    .base = { __DRI_IMAGE, 19 },
1527
1528    .createImageFromName                = brw_create_image_from_name,
1529    .createImageFromRenderbuffer        = brw_create_image_from_renderbuffer,
1530    .destroyImage                       = brw_destroy_image,
1531    .createImage                        = brw_create_image,
1532    .queryImage                         = brw_query_image,
1533    .dupImage                           = brw_dup_image,
1534    .validateUsage                      = brw_validate_usage,
1535    .createImageFromNames               = brw_create_image_from_names,
1536    .fromPlanar                         = brw_from_planar,
1537    .createImageFromTexture             = brw_create_image_from_texture,
1538    .createImageFromFds                 = brw_create_image_from_fds,
1539    .createImageFromDmaBufs             = brw_create_image_from_dma_bufs,
1540    .blitImage                          = NULL,
1541    .getCapabilities                    = NULL,
1542    .mapImage                           = brw_map_image,
1543    .unmapImage                         = brw_unmap_image,
1544    .createImageWithModifiers           = brw_create_image_with_modifiers,
1545    .createImageFromDmaBufs2            = brw_create_image_from_dma_bufs2,
1546    .queryDmaBufFormats                 = brw_query_dma_buf_formats,
1547    .queryDmaBufModifiers               = brw_query_dma_buf_modifiers,
1548    .queryDmaBufFormatModifierAttribs   = brw_query_format_modifier_attribs,
1549    .createImageWithModifiers2          = brw_create_image_with_modifiers2,
1550};
1551
1552static int
1553brw_query_renderer_integer(__DRIscreen *dri_screen,
1554                           int param, unsigned int *value)
1555{
1556   const struct brw_screen *const screen =
1557      (struct brw_screen *) dri_screen->driverPrivate;
1558
1559   switch (param) {
1560   case __DRI2_RENDERER_VENDOR_ID:
1561      value[0] = 0x8086;
1562      return 0;
1563   case __DRI2_RENDERER_DEVICE_ID:
1564      value[0] = screen->deviceID;
1565      return 0;
1566   case __DRI2_RENDERER_ACCELERATED:
1567      value[0] = 1;
1568      return 0;
1569   case __DRI2_RENDERER_VIDEO_MEMORY: {
1570      /* Once a batch uses more than 75% of the maximum mappable size, we
1571       * assume that there's some fragmentation, and we start doing extra
1572       * flushing, etc.  That's the big cliff apps will care about.
1573       */
1574      const unsigned gpu_mappable_megabytes =
1575         screen->aperture_threshold / (1024 * 1024);
1576
1577      const long system_memory_pages = sysconf(_SC_PHYS_PAGES);
1578      const long system_page_size = sysconf(_SC_PAGE_SIZE);
1579
1580      if (system_memory_pages <= 0 || system_page_size <= 0)
1581         return -1;
1582
1583      const uint64_t system_memory_bytes = (uint64_t) system_memory_pages
1584         * (uint64_t) system_page_size;
1585
1586      const unsigned system_memory_megabytes =
1587         (unsigned) (system_memory_bytes / (1024 * 1024));
1588
1589      value[0] = MIN2(system_memory_megabytes, gpu_mappable_megabytes);
1590      return 0;
1591   }
1592   case __DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE:
1593      value[0] = 1;
1594      return 0;
1595   case __DRI2_RENDERER_HAS_TEXTURE_3D:
1596      value[0] = 1;
1597      return 0;
1598   case __DRI2_RENDERER_HAS_CONTEXT_PRIORITY:
1599      value[0] = 0;
1600      if (brw_hw_context_set_priority(screen->bufmgr,
1601                                      0, INTEL_CONTEXT_HIGH_PRIORITY) == 0)
1602         value[0] |= __DRI2_RENDERER_HAS_CONTEXT_PRIORITY_HIGH;
1603      if (brw_hw_context_set_priority(screen->bufmgr,
1604                                      0, INTEL_CONTEXT_LOW_PRIORITY) == 0)
1605         value[0] |= __DRI2_RENDERER_HAS_CONTEXT_PRIORITY_LOW;
1606      /* reset to default last, just in case */
1607      if (brw_hw_context_set_priority(screen->bufmgr,
1608                                      0, INTEL_CONTEXT_MEDIUM_PRIORITY) == 0)
1609         value[0] |= __DRI2_RENDERER_HAS_CONTEXT_PRIORITY_MEDIUM;
1610      return 0;
1611   case __DRI2_RENDERER_HAS_FRAMEBUFFER_SRGB:
1612      value[0] = 1;
1613      return 0;
1614   default:
1615      return driQueryRendererIntegerCommon(dri_screen, param, value);
1616   }
1617
1618   return -1;
1619}
1620
1621static int
1622brw_query_renderer_string(__DRIscreen *dri_screen,
1623                          int param, const char **value)
1624{
1625   const struct brw_screen *screen =
1626      (struct brw_screen *) dri_screen->driverPrivate;
1627
1628   switch (param) {
1629   case __DRI2_RENDERER_VENDOR_ID:
1630      value[0] = brw_vendor_string;
1631      return 0;
1632   case __DRI2_RENDERER_DEVICE_ID:
1633      value[0] = brw_get_renderer_string(screen);
1634      return 0;
1635   default:
1636      break;
1637   }
1638
1639   return -1;
1640}
1641
1642static void
1643brw_set_cache_funcs(__DRIscreen *dri_screen,
1644                    __DRIblobCacheSet set, __DRIblobCacheGet get)
1645{
1646   const struct brw_screen *const screen =
1647      (struct brw_screen *) dri_screen->driverPrivate;
1648
1649   if (!screen->disk_cache)
1650      return;
1651
1652   disk_cache_set_callbacks(screen->disk_cache, set, get);
1653}
1654
1655static const __DRI2rendererQueryExtension brwRendererQueryExtension = {
1656   .base = { __DRI2_RENDERER_QUERY, 1 },
1657
1658   .queryInteger = brw_query_renderer_integer,
1659   .queryString = brw_query_renderer_string
1660};
1661
1662static const __DRIrobustnessExtension dri2Robustness = {
1663   .base = { __DRI2_ROBUSTNESS, 1 }
1664};
1665
1666static const __DRI2blobExtension brwBlobExtension = {
1667   .base = { __DRI2_BLOB, 1 },
1668   .set_cache_funcs = brw_set_cache_funcs
1669};
1670
1671static const __DRImutableRenderBufferDriverExtension brwMutableRenderBufferExtension = {
1672   .base = { __DRI_MUTABLE_RENDER_BUFFER_DRIVER, 1 },
1673};
1674
1675static const __DRIextension *screenExtensions[] = {
1676    &brwTexBufferExtension.base,
1677    &brwFenceExtension.base,
1678    &brwFlushExtension.base,
1679    &brwImageExtension.base,
1680    &brwRendererQueryExtension.base,
1681    &brwMutableRenderBufferExtension.base,
1682    &dri2ConfigQueryExtension.base,
1683    &dri2NoErrorExtension.base,
1684    &brwBlobExtension.base,
1685    NULL
1686};
1687
1688static const __DRIextension *brwRobustScreenExtensions[] = {
1689    &brwTexBufferExtension.base,
1690    &brwFenceExtension.base,
1691    &brwFlushExtension.base,
1692    &brwImageExtension.base,
1693    &brwRendererQueryExtension.base,
1694    &brwMutableRenderBufferExtension.base,
1695    &dri2ConfigQueryExtension.base,
1696    &dri2Robustness.base,
1697    &dri2NoErrorExtension.base,
1698    &brwBlobExtension.base,
1699    NULL
1700};
1701
1702static int
1703brw_get_param(struct brw_screen *screen, int param, int *value)
1704{
1705   int ret = 0;
1706   struct drm_i915_getparam gp;
1707
1708   memset(&gp, 0, sizeof(gp));
1709   gp.param = param;
1710   gp.value = value;
1711
1712   if (drmIoctl(screen->fd, DRM_IOCTL_I915_GETPARAM, &gp) == -1) {
1713      ret = -errno;
1714      if (ret != -EINVAL)
1715         _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
1716   }
1717
1718   return ret;
1719}
1720
1721static bool
1722brw_get_boolean(struct brw_screen *screen, int param)
1723{
1724   int value = 0;
1725   return (brw_get_param(screen, param, &value) == 0) && value;
1726}
1727
1728static int
1729brw_get_integer(struct brw_screen *screen, int param)
1730{
1731   int value = -1;
1732
1733   if (brw_get_param(screen, param, &value) == 0)
1734      return value;
1735
1736   return -1;
1737}
1738
1739static void
1740brw_destroy_screen(__DRIscreen *sPriv)
1741{
1742   struct brw_screen *screen = sPriv->driverPrivate;
1743
1744   brw_bufmgr_unref(screen->bufmgr);
1745   driDestroyOptionInfo(&screen->optionCache);
1746
1747   disk_cache_destroy(screen->disk_cache);
1748
1749   ralloc_free(screen);
1750   sPriv->driverPrivate = NULL;
1751}
1752
1753
1754/**
1755 * Create a gl_framebuffer and attach it to __DRIdrawable::driverPrivate.
1756 *
1757 *_This implements driDriverAPI::createNewDrawable, which the DRI layer calls
1758 * when creating a EGLSurface, GLXDrawable, or GLXPixmap. Despite the name,
1759 * this does not allocate GPU memory.
1760 */
1761static GLboolean
1762brw_create_buffer(__DRIscreen *dri_screen,
1763                  __DRIdrawable *driDrawPriv,
1764                  const struct gl_config *mesaVis, GLboolean isPixmap)
1765{
1766   struct brw_renderbuffer *rb;
1767   struct brw_screen *screen = (struct brw_screen *)
1768      dri_screen->driverPrivate;
1769   mesa_format rgbFormat;
1770   unsigned num_samples =
1771      brw_quantize_num_samples(screen, mesaVis->samples);
1772
1773   if (isPixmap)
1774      return false;
1775
1776   struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer);
1777   if (!fb)
1778      return false;
1779
1780   _mesa_initialize_window_framebuffer(fb, mesaVis);
1781
1782   if (screen->winsys_msaa_samples_override != -1) {
1783      num_samples = screen->winsys_msaa_samples_override;
1784      fb->Visual.samples = num_samples;
1785   }
1786
1787   if (mesaVis->redBits == 16 && mesaVis->alphaBits > 0 && mesaVis->floatMode) {
1788      rgbFormat = MESA_FORMAT_RGBA_FLOAT16;
1789   } else if (mesaVis->redBits == 16 && mesaVis->floatMode) {
1790      rgbFormat = MESA_FORMAT_RGBX_FLOAT16;
1791   } else if (mesaVis->redBits == 10 && mesaVis->alphaBits > 0) {
1792      rgbFormat = mesaVis->redMask == 0x3ff00000 ? MESA_FORMAT_B10G10R10A2_UNORM
1793                                                 : MESA_FORMAT_R10G10B10A2_UNORM;
1794   } else if (mesaVis->redBits == 10) {
1795      rgbFormat = mesaVis->redMask == 0x3ff00000 ? MESA_FORMAT_B10G10R10X2_UNORM
1796                                                 : MESA_FORMAT_R10G10B10X2_UNORM;
1797   } else if (mesaVis->redBits == 5) {
1798      rgbFormat = mesaVis->redMask == 0x1f ? MESA_FORMAT_R5G6B5_UNORM
1799                                           : MESA_FORMAT_B5G6R5_UNORM;
1800   } else if (mesaVis->alphaBits == 0) {
1801      rgbFormat = mesaVis->redMask == 0xff ? MESA_FORMAT_R8G8B8X8_SRGB
1802                                           : MESA_FORMAT_B8G8R8X8_SRGB;
1803      fb->Visual.sRGBCapable = true;
1804   } else if (mesaVis->sRGBCapable) {
1805      rgbFormat = mesaVis->redMask == 0xff ? MESA_FORMAT_R8G8B8A8_SRGB
1806                                           : MESA_FORMAT_B8G8R8A8_SRGB;
1807      fb->Visual.sRGBCapable = true;
1808   } else {
1809      rgbFormat = mesaVis->redMask == 0xff ? MESA_FORMAT_R8G8B8A8_SRGB
1810                                           : MESA_FORMAT_B8G8R8A8_SRGB;
1811      fb->Visual.sRGBCapable = true;
1812   }
1813
1814   /* mesaVis->sRGBCapable was set, user is asking for sRGB */
1815   bool srgb_cap_set = mesaVis->redBits >= 8 && mesaVis->sRGBCapable;
1816
1817   /* setup the hardware-based renderbuffers */
1818   rb = brw_create_winsys_renderbuffer(screen, rgbFormat, num_samples);
1819   _mesa_attach_and_own_rb(fb, BUFFER_FRONT_LEFT, &rb->Base.Base);
1820   rb->need_srgb = srgb_cap_set;
1821
1822   if (mesaVis->doubleBufferMode) {
1823      rb = brw_create_winsys_renderbuffer(screen, rgbFormat, num_samples);
1824      _mesa_attach_and_own_rb(fb, BUFFER_BACK_LEFT, &rb->Base.Base);
1825      rb->need_srgb = srgb_cap_set;
1826   }
1827
1828   /*
1829    * Assert here that the gl_config has an expected depth/stencil bit
1830    * combination: one of d24/s8, d16/s0, d0/s0. (See brw_init_screen(),
1831    * which constructs the advertised configs.)
1832    */
1833   if (mesaVis->depthBits == 24) {
1834      assert(mesaVis->stencilBits == 8);
1835
1836      if (screen->devinfo.has_hiz_and_separate_stencil) {
1837         rb = brw_create_private_renderbuffer(screen,
1838                                                MESA_FORMAT_Z24_UNORM_X8_UINT,
1839                                                num_samples);
1840         _mesa_attach_and_own_rb(fb, BUFFER_DEPTH, &rb->Base.Base);
1841         rb = brw_create_private_renderbuffer(screen, MESA_FORMAT_S_UINT8,
1842                                                num_samples);
1843         _mesa_attach_and_own_rb(fb, BUFFER_STENCIL, &rb->Base.Base);
1844      } else {
1845         /*
1846          * Use combined depth/stencil. Note that the renderbuffer is
1847          * attached to two attachment points.
1848          */
1849         rb = brw_create_private_renderbuffer(screen,
1850                                                MESA_FORMAT_Z24_UNORM_S8_UINT,
1851                                                num_samples);
1852         _mesa_attach_and_own_rb(fb, BUFFER_DEPTH, &rb->Base.Base);
1853         _mesa_attach_and_reference_rb(fb, BUFFER_STENCIL, &rb->Base.Base);
1854      }
1855   }
1856   else if (mesaVis->depthBits == 16) {
1857      assert(mesaVis->stencilBits == 0);
1858      rb = brw_create_private_renderbuffer(screen, MESA_FORMAT_Z_UNORM16,
1859                                             num_samples);
1860      _mesa_attach_and_own_rb(fb, BUFFER_DEPTH, &rb->Base.Base);
1861   }
1862   else {
1863      assert(mesaVis->depthBits == 0);
1864      assert(mesaVis->stencilBits == 0);
1865   }
1866
1867   /* now add any/all software-based renderbuffers we may need */
1868   _swrast_add_soft_renderbuffers(fb,
1869                                  false, /* never sw color */
1870                                  false, /* never sw depth */
1871                                  false, /* never sw stencil */
1872                                  mesaVis->accumRedBits > 0,
1873                                  false /* never sw alpha */);
1874   driDrawPriv->driverPrivate = fb;
1875
1876   return true;
1877}
1878
1879static void
1880brw_destroy_buffer(__DRIdrawable *driDrawPriv)
1881{
1882    struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
1883
1884    _mesa_reference_framebuffer(&fb, NULL);
1885}
1886
1887static bool
1888brw_init_bufmgr(struct brw_screen *screen)
1889{
1890   __DRIscreen *dri_screen = screen->driScrnPriv;
1891
1892   bool bo_reuse = false;
1893   int bo_reuse_mode = driQueryOptioni(&screen->optionCache, "bo_reuse");
1894   switch (bo_reuse_mode) {
1895   case DRI_CONF_BO_REUSE_DISABLED:
1896      break;
1897   case DRI_CONF_BO_REUSE_ALL:
1898      bo_reuse = true;
1899      break;
1900   }
1901
1902   screen->bufmgr = brw_bufmgr_get_for_fd(&screen->devinfo, dri_screen->fd, bo_reuse);
1903   if (screen->bufmgr == NULL) {
1904      fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
1905              __func__, __LINE__);
1906      return false;
1907   }
1908   screen->fd = brw_bufmgr_get_fd(screen->bufmgr);
1909
1910   if (!brw_get_boolean(screen, I915_PARAM_HAS_EXEC_NO_RELOC)) {
1911      fprintf(stderr, "[%s: %u] Kernel 3.9 required.\n", __func__, __LINE__);
1912      return false;
1913   }
1914
1915   return true;
1916}
1917
1918static bool
1919brw_detect_swizzling(struct brw_screen *screen)
1920{
1921   /* Broadwell PRM says:
1922    *
1923    *   "Before Gfx8, there was a historical configuration control field to
1924    *    swizzle address bit[6] for in X/Y tiling modes. This was set in three
1925    *    different places: TILECTL[1:0], ARB_MODE[5:4], and
1926    *    DISP_ARB_CTL[14:13].
1927    *
1928    *    For Gfx8 and subsequent generations, the swizzle fields are all
1929    *    reserved, and the CPU's memory controller performs all address
1930    *    swizzling modifications."
1931    */
1932   if (screen->devinfo.ver >= 8)
1933      return false;
1934
1935   uint32_t tiling = I915_TILING_X;
1936   uint32_t swizzle_mode = 0;
1937   struct brw_bo *buffer =
1938      brw_bo_alloc_tiled(screen->bufmgr, "swizzle test", 32768,
1939                         BRW_MEMZONE_OTHER, tiling, 512, 0);
1940   if (buffer == NULL)
1941      return false;
1942
1943   brw_bo_get_tiling(buffer, &tiling, &swizzle_mode);
1944   brw_bo_unreference(buffer);
1945
1946   return swizzle_mode != I915_BIT_6_SWIZZLE_NONE;
1947}
1948
1949static int
1950brw_detect_timestamp(struct brw_screen *screen)
1951{
1952   uint64_t dummy = 0, last = 0;
1953   int upper, lower, loops;
1954
1955   /* On 64bit systems, some old kernels trigger a hw bug resulting in the
1956    * TIMESTAMP register being shifted and the low 32bits always zero.
1957    *
1958    * More recent kernels offer an interface to read the full 36bits
1959    * everywhere.
1960    */
1961   if (brw_reg_read(screen->bufmgr, TIMESTAMP | 1, &dummy) == 0)
1962      return 3;
1963
1964   /* Determine if we have a 32bit or 64bit kernel by inspecting the
1965    * upper 32bits for a rapidly changing timestamp.
1966    */
1967   if (brw_reg_read(screen->bufmgr, TIMESTAMP, &last))
1968      return 0;
1969
1970   upper = lower = 0;
1971   for (loops = 0; loops < 10; loops++) {
1972      /* The TIMESTAMP should change every 80ns, so several round trips
1973       * through the kernel should be enough to advance it.
1974       */
1975      if (brw_reg_read(screen->bufmgr, TIMESTAMP, &dummy))
1976         return 0;
1977
1978      upper += (dummy >> 32) != (last >> 32);
1979      if (upper > 1) /* beware 32bit counter overflow */
1980         return 2; /* upper dword holds the low 32bits of the timestamp */
1981
1982      lower += (dummy & 0xffffffff) != (last & 0xffffffff);
1983      if (lower > 1)
1984         return 1; /* timestamp is unshifted */
1985
1986      last = dummy;
1987   }
1988
1989   /* No advancement? No timestamp! */
1990   return 0;
1991}
1992
1993 /**
1994 * Test if we can use MI_LOAD_REGISTER_MEM from an untrusted batchbuffer.
1995 *
1996 * Some combinations of hardware and kernel versions allow this feature,
1997 * while others don't.  Instead of trying to enumerate every case, just
1998 * try and write a register and see if works.
1999 */
2000static bool
2001brw_detect_pipelined_register(struct brw_screen *screen,
2002                                int reg, uint32_t expected_value, bool reset)
2003{
2004   if (screen->devinfo.no_hw)
2005      return false;
2006
2007   struct brw_bo *results, *bo;
2008   uint32_t *batch;
2009   uint32_t offset = 0;
2010   void *map;
2011   bool success = false;
2012
2013   /* Create a zero'ed temporary buffer for reading our results */
2014   results = brw_bo_alloc(screen->bufmgr, "registers", 4096, BRW_MEMZONE_OTHER);
2015   if (results == NULL)
2016      goto err;
2017
2018   bo = brw_bo_alloc(screen->bufmgr, "batchbuffer", 4096, BRW_MEMZONE_OTHER);
2019   if (bo == NULL)
2020      goto err_results;
2021
2022   map = brw_bo_map(NULL, bo, MAP_WRITE);
2023   if (!map)
2024      goto err_batch;
2025
2026   batch = map;
2027
2028   /* Write the register. */
2029   *batch++ = MI_LOAD_REGISTER_IMM | (3 - 2);
2030   *batch++ = reg;
2031   *batch++ = expected_value;
2032
2033   /* Save the register's value back to the buffer. */
2034   *batch++ = MI_STORE_REGISTER_MEM | (3 - 2);
2035   *batch++ = reg;
2036   struct drm_i915_gem_relocation_entry reloc = {
2037      .offset = (char *) batch - (char *) map,
2038      .delta = offset * sizeof(uint32_t),
2039      .target_handle = results->gem_handle,
2040      .read_domains = I915_GEM_DOMAIN_INSTRUCTION,
2041      .write_domain = I915_GEM_DOMAIN_INSTRUCTION,
2042   };
2043   *batch++ = reloc.presumed_offset + reloc.delta;
2044
2045   /* And afterwards clear the register */
2046   if (reset) {
2047      *batch++ = MI_LOAD_REGISTER_IMM | (3 - 2);
2048      *batch++ = reg;
2049      *batch++ = 0;
2050   }
2051
2052   *batch++ = MI_BATCH_BUFFER_END;
2053
2054   struct drm_i915_gem_exec_object2 exec_objects[2] = {
2055      {
2056         .handle = results->gem_handle,
2057      },
2058      {
2059         .handle = bo->gem_handle,
2060         .relocation_count = 1,
2061         .relocs_ptr = (uintptr_t) &reloc,
2062      }
2063   };
2064
2065   struct drm_i915_gem_execbuffer2 execbuf = {
2066      .buffers_ptr = (uintptr_t) exec_objects,
2067      .buffer_count = 2,
2068      .batch_len = ALIGN((char *) batch - (char *) map, 8),
2069      .flags = I915_EXEC_RENDER,
2070   };
2071
2072   /* Don't bother with error checking - if the execbuf fails, the
2073    * value won't be written and we'll just report that there's no access.
2074    */
2075   drmIoctl(screen->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
2076
2077   /* Check whether the value got written. */
2078   void *results_map = brw_bo_map(NULL, results, MAP_READ);
2079   if (results_map) {
2080      success = *((uint32_t *)results_map + offset) == expected_value;
2081      brw_bo_unmap(results);
2082   }
2083
2084err_batch:
2085   brw_bo_unreference(bo);
2086err_results:
2087   brw_bo_unreference(results);
2088err:
2089   return success;
2090}
2091
2092static bool
2093brw_detect_pipelined_so(struct brw_screen *screen)
2094{
2095   const struct intel_device_info *devinfo = &screen->devinfo;
2096
2097   /* Supposedly, Broadwell just works. */
2098   if (devinfo->ver >= 8)
2099      return true;
2100
2101   if (devinfo->ver <= 6)
2102      return false;
2103
2104   /* See the big explanation about command parser versions below */
2105   if (screen->cmd_parser_version >= (devinfo->is_haswell ? 7 : 2))
2106      return true;
2107
2108   /* We use SO_WRITE_OFFSET0 since you're supposed to write it (unlike the
2109    * statistics registers), and we already reset it to zero before using it.
2110    */
2111   return brw_detect_pipelined_register(screen,
2112                                          GFX7_SO_WRITE_OFFSET(0),
2113                                          0x1337d0d0,
2114                                          false);
2115}
2116
2117/**
2118 * Return array of MSAA modes supported by the hardware. The array is
2119 * zero-terminated and sorted in decreasing order.
2120 */
2121const int*
2122brw_supported_msaa_modes(const struct brw_screen  *screen)
2123{
2124   static const int gfx9_modes[] = {16, 8, 4, 2, 0, -1};
2125   static const int gfx8_modes[] = {8, 4, 2, 0, -1};
2126   static const int gfx7_modes[] = {8, 4, 0, -1};
2127   static const int gfx6_modes[] = {4, 0, -1};
2128   static const int gfx4_modes[] = {0, -1};
2129
2130   if (screen->devinfo.ver >= 9) {
2131      return gfx9_modes;
2132   } else if (screen->devinfo.ver >= 8) {
2133      return gfx8_modes;
2134   } else if (screen->devinfo.ver >= 7) {
2135      return gfx7_modes;
2136   } else if (screen->devinfo.ver == 6) {
2137      return gfx6_modes;
2138   } else {
2139      return gfx4_modes;
2140   }
2141}
2142
2143static unsigned
2144brw_loader_get_cap(const __DRIscreen *dri_screen, enum dri_loader_cap cap)
2145{
2146   if (dri_screen->dri2.loader && dri_screen->dri2.loader->base.version >= 4 &&
2147       dri_screen->dri2.loader->getCapability)
2148      return dri_screen->dri2.loader->getCapability(dri_screen->loaderPrivate, cap);
2149
2150   if (dri_screen->image.loader && dri_screen->image.loader->base.version >= 2 &&
2151       dri_screen->image.loader->getCapability)
2152      return dri_screen->image.loader->getCapability(dri_screen->loaderPrivate, cap);
2153
2154   return 0;
2155}
2156
2157static bool
2158brw_allowed_format(__DRIscreen *dri_screen, mesa_format format)
2159{
2160   struct brw_screen *screen = dri_screen->driverPrivate;
2161
2162   /* Expose only BGRA ordering if the loader doesn't support RGBA ordering. */
2163   bool allow_rgba_ordering = brw_loader_get_cap(dri_screen, DRI_LOADER_CAP_RGBA_ORDERING);
2164   if (!allow_rgba_ordering &&
2165       (format == MESA_FORMAT_R8G8B8A8_UNORM ||
2166        format == MESA_FORMAT_R8G8B8X8_UNORM ||
2167        format == MESA_FORMAT_R8G8B8A8_SRGB ||
2168        format == MESA_FORMAT_R8G8B8X8_SRGB))
2169      return false;
2170
2171    /* Shall we expose 10 bpc formats? */
2172   bool allow_rgb10_configs = driQueryOptionb(&screen->optionCache,
2173                                              "allow_rgb10_configs");
2174   if (!allow_rgb10_configs &&
2175       (format == MESA_FORMAT_B10G10R10A2_UNORM ||
2176        format == MESA_FORMAT_B10G10R10X2_UNORM))
2177      return false;
2178
2179   /* Shall we expose 565 formats? */
2180   bool allow_rgb565_configs = driQueryOptionb(&screen->optionCache,
2181                                               "allow_rgb565_configs");
2182   if (!allow_rgb565_configs && format == MESA_FORMAT_B5G6R5_UNORM)
2183      return false;
2184
2185   /* Shall we expose fp16 formats? */
2186   bool allow_fp16_configs = brw_loader_get_cap(dri_screen, DRI_LOADER_CAP_FP16);
2187   if (!allow_fp16_configs &&
2188       (format == MESA_FORMAT_RGBA_FLOAT16 ||
2189        format == MESA_FORMAT_RGBX_FLOAT16))
2190      return false;
2191
2192   return true;
2193}
2194
2195static __DRIconfig**
2196brw_screen_make_configs(__DRIscreen *dri_screen)
2197{
2198   static const mesa_format formats[] = {
2199      MESA_FORMAT_B5G6R5_UNORM,
2200      MESA_FORMAT_B8G8R8A8_UNORM,
2201      MESA_FORMAT_B8G8R8X8_UNORM,
2202
2203      MESA_FORMAT_B8G8R8A8_SRGB,
2204      MESA_FORMAT_B8G8R8X8_SRGB,
2205
2206      /* For 10 bpc, 30 bit depth framebuffers. */
2207      MESA_FORMAT_B10G10R10A2_UNORM,
2208      MESA_FORMAT_B10G10R10X2_UNORM,
2209
2210      MESA_FORMAT_RGBA_FLOAT16,
2211      MESA_FORMAT_RGBX_FLOAT16,
2212
2213      /* The 32-bit RGBA format must not precede the 32-bit BGRA format.
2214       * Likewise for RGBX and BGRX.  Otherwise, the GLX client and the GLX
2215       * server may disagree on which format the GLXFBConfig represents,
2216       * resulting in swapped color channels.
2217       *
2218       * The problem, as of 2017-05-30:
2219       * When matching a GLXFBConfig to a __DRIconfig, GLX ignores the channel
2220       * order and chooses the first __DRIconfig with the expected channel
2221       * sizes. Specifically, GLX compares the GLXFBConfig's and __DRIconfig's
2222       * __DRI_ATTRIB_{CHANNEL}_SIZE but ignores __DRI_ATTRIB_{CHANNEL}_MASK.
2223       *
2224       * EGL does not suffer from this problem. It correctly compares the
2225       * channel masks when matching EGLConfig to __DRIconfig.
2226       */
2227
2228      /* Required by Android, for HAL_PIXEL_FORMAT_RGBA_8888. */
2229      MESA_FORMAT_R8G8B8A8_UNORM,
2230      MESA_FORMAT_R8G8B8A8_SRGB,
2231
2232      /* Required by Android, for HAL_PIXEL_FORMAT_RGBX_8888. */
2233      MESA_FORMAT_R8G8B8X8_UNORM,
2234      MESA_FORMAT_R8G8B8X8_SRGB,
2235   };
2236
2237   /* __DRI_ATTRIB_SWAP_COPY is not supported due to page flipping. */
2238   static const GLenum back_buffer_modes[] = {
2239      __DRI_ATTRIB_SWAP_UNDEFINED, __DRI_ATTRIB_SWAP_NONE
2240   };
2241
2242   static const uint8_t singlesample_samples[1] = {0};
2243
2244   struct brw_screen *screen = dri_screen->driverPrivate;
2245   const struct intel_device_info *devinfo = &screen->devinfo;
2246   uint8_t depth_bits[4], stencil_bits[4];
2247   __DRIconfig **configs = NULL;
2248
2249   unsigned num_formats = ARRAY_SIZE(formats);
2250
2251   /* Generate singlesample configs, each without accumulation buffer
2252    * and with EGL_MUTABLE_RENDER_BUFFER_BIT_KHR.
2253    */
2254   for (unsigned i = 0; i < num_formats; i++) {
2255      __DRIconfig **new_configs;
2256      int num_depth_stencil_bits = 1;
2257
2258      if (!brw_allowed_format(dri_screen, formats[i]))
2259         continue;
2260
2261      /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
2262       * buffer that has a different number of bits per pixel than the color
2263       * buffer, gen >= 6 supports this.
2264       */
2265      depth_bits[0] = 0;
2266      stencil_bits[0] = 0;
2267
2268      if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) {
2269         if (devinfo->ver >= 8) {
2270            depth_bits[num_depth_stencil_bits] = 16;
2271            stencil_bits[num_depth_stencil_bits] = 0;
2272            num_depth_stencil_bits++;
2273         }
2274         if (devinfo->ver >= 6) {
2275             depth_bits[num_depth_stencil_bits] = 24;
2276             stencil_bits[num_depth_stencil_bits] = 8;
2277             num_depth_stencil_bits++;
2278         }
2279      } else {
2280         depth_bits[num_depth_stencil_bits] = 24;
2281         stencil_bits[num_depth_stencil_bits] = 8;
2282         num_depth_stencil_bits++;
2283      }
2284
2285      new_configs = driCreateConfigs(formats[i],
2286                                     depth_bits,
2287                                     stencil_bits,
2288                                     num_depth_stencil_bits,
2289                                     back_buffer_modes, 2,
2290                                     singlesample_samples, 1,
2291                                     false, false);
2292      configs = driConcatConfigs(configs, new_configs);
2293   }
2294
2295   /* Generate the minimum possible set of configs that include an
2296    * accumulation buffer.
2297    */
2298   for (unsigned i = 0; i < num_formats; i++) {
2299      __DRIconfig **new_configs;
2300
2301      if (!brw_allowed_format(dri_screen, formats[i]))
2302         continue;
2303
2304      if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) {
2305         if (devinfo->ver >= 8) {
2306            depth_bits[0] = 16;
2307            stencil_bits[0] = 0;
2308         } else if (devinfo->ver >= 6) {
2309            depth_bits[0] = 24;
2310            stencil_bits[0] = 8;
2311         } else {
2312            depth_bits[0] = 0;
2313            stencil_bits[0] = 0;
2314         }
2315      } else {
2316         depth_bits[0] = 24;
2317         stencil_bits[0] = 8;
2318      }
2319
2320      new_configs = driCreateConfigs(formats[i],
2321                                     depth_bits, stencil_bits, 1,
2322                                     back_buffer_modes, 1,
2323                                     singlesample_samples, 1,
2324                                     true, false);
2325      configs = driConcatConfigs(configs, new_configs);
2326   }
2327
2328   /* Generate multisample configs.
2329    *
2330    * This loop breaks early, and hence is a no-op, on gen < 6.
2331    *
2332    * Multisample configs must follow the singlesample configs in order to
2333    * work around an X server bug present in 1.12. The X server chooses to
2334    * associate the first listed RGBA888-Z24S8 config, regardless of its
2335    * sample count, with the 32-bit depth visual used for compositing.
2336    *
2337    * Only doublebuffer configs with GLX_SWAP_UNDEFINED_OML behavior are
2338    * supported.  Singlebuffer configs are not supported because no one wants
2339    * them.
2340    */
2341   for (unsigned i = 0; i < num_formats; i++) {
2342      if (devinfo->ver < 6)
2343         break;
2344
2345      if (!brw_allowed_format(dri_screen, formats[i]))
2346         continue;
2347
2348      __DRIconfig **new_configs;
2349      const int num_depth_stencil_bits = 2;
2350      int num_msaa_modes = 0;
2351      const uint8_t *multisample_samples = NULL;
2352
2353      depth_bits[0] = 0;
2354      stencil_bits[0] = 0;
2355
2356      if (formats[i] == MESA_FORMAT_B5G6R5_UNORM && devinfo->ver >= 8) {
2357         depth_bits[1] = 16;
2358         stencil_bits[1] = 0;
2359      } else {
2360         depth_bits[1] = 24;
2361         stencil_bits[1] = 8;
2362      }
2363
2364      if (devinfo->ver >= 9) {
2365         static const uint8_t multisample_samples_gfx9[] = {2, 4, 8, 16};
2366         multisample_samples = multisample_samples_gfx9;
2367         num_msaa_modes = ARRAY_SIZE(multisample_samples_gfx9);
2368      } else if (devinfo->ver == 8) {
2369         static const uint8_t multisample_samples_gfx8[] = {2, 4, 8};
2370         multisample_samples = multisample_samples_gfx8;
2371         num_msaa_modes = ARRAY_SIZE(multisample_samples_gfx8);
2372      } else if (devinfo->ver == 7) {
2373         static const uint8_t multisample_samples_gfx7[] = {4, 8};
2374         multisample_samples = multisample_samples_gfx7;
2375         num_msaa_modes = ARRAY_SIZE(multisample_samples_gfx7);
2376      } else if (devinfo->ver == 6) {
2377         static const uint8_t multisample_samples_gfx6[] = {4};
2378         multisample_samples = multisample_samples_gfx6;
2379         num_msaa_modes = ARRAY_SIZE(multisample_samples_gfx6);
2380      }
2381
2382      new_configs = driCreateConfigs(formats[i],
2383                                     depth_bits,
2384                                     stencil_bits,
2385                                     num_depth_stencil_bits,
2386                                     back_buffer_modes, 1,
2387                                     multisample_samples,
2388                                     num_msaa_modes,
2389                                     false, false);
2390      configs = driConcatConfigs(configs, new_configs);
2391   }
2392
2393   if (configs == NULL) {
2394      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
2395              __LINE__);
2396      return NULL;
2397   }
2398
2399   return configs;
2400}
2401
2402static void
2403set_max_gl_versions(struct brw_screen *screen)
2404{
2405   __DRIscreen *dri_screen = screen->driScrnPriv;
2406   const bool has_astc = screen->devinfo.ver >= 9;
2407
2408   switch (screen->devinfo.ver) {
2409   case 11:
2410   case 10:
2411   case 9:
2412   case 8:
2413      dri_screen->max_gl_core_version = 46;
2414      dri_screen->max_gl_compat_version = 30;
2415      dri_screen->max_gl_es1_version = 11;
2416      dri_screen->max_gl_es2_version = has_astc ? 32 : 31;
2417      break;
2418   case 7:
2419      dri_screen->max_gl_core_version = 33;
2420      if (can_do_pipelined_register_writes(screen)) {
2421         dri_screen->max_gl_core_version = 42;
2422         if (screen->devinfo.is_haswell && can_do_compute_dispatch(screen))
2423            dri_screen->max_gl_core_version = 43;
2424         if (screen->devinfo.is_haswell && can_do_mi_math_and_lrr(screen))
2425            dri_screen->max_gl_core_version = 45;
2426      }
2427      dri_screen->max_gl_compat_version = 30;
2428      dri_screen->max_gl_es1_version = 11;
2429      dri_screen->max_gl_es2_version = screen->devinfo.is_haswell ? 31 : 30;
2430      break;
2431   case 6:
2432      dri_screen->max_gl_core_version = 33;
2433      dri_screen->max_gl_compat_version = 30;
2434      dri_screen->max_gl_es1_version = 11;
2435      dri_screen->max_gl_es2_version = 30;
2436      break;
2437   case 5:
2438   case 4:
2439      dri_screen->max_gl_core_version = 0;
2440      dri_screen->max_gl_compat_version = 21;
2441      dri_screen->max_gl_es1_version = 11;
2442      dri_screen->max_gl_es2_version = 20;
2443      break;
2444   default:
2445      unreachable("unrecognized brw_screen::gen");
2446   }
2447
2448   /* OpenGL 3.3+ requires GL_ARB_blend_func_extended.  Don't advertise those
2449    * versions if driconf disables the extension.
2450    */
2451   if (driQueryOptionb(&screen->optionCache, "disable_blend_func_extended")) {
2452      dri_screen->max_gl_core_version =
2453         MIN2(32, dri_screen->max_gl_core_version);
2454      dri_screen->max_gl_compat_version =
2455         MIN2(32, dri_screen->max_gl_compat_version);
2456   }
2457
2458   /* Using the `allow_higher_compat_version` option during context creation
2459    * means that an application that doesn't request a specific version can be
2460    * given a version higher than 3.0.  However, an application still cannot
2461    * request a higher version.  For that to work, max_gl_compat_version must
2462    * be set.
2463    */
2464   if (dri_screen->max_gl_compat_version < dri_screen->max_gl_core_version) {
2465      if (driQueryOptionb(&screen->optionCache, "allow_higher_compat_version"))
2466         dri_screen->max_gl_compat_version = dri_screen->max_gl_core_version;
2467   }
2468}
2469
2470static void
2471shader_debug_log_mesa(void *data, unsigned *msg_id, const char *fmt, ...)
2472{
2473   struct brw_context *brw = (struct brw_context *)data;
2474   va_list args;
2475
2476   va_start(args, fmt);
2477   _mesa_gl_vdebugf(&brw->ctx, msg_id,
2478                    MESA_DEBUG_SOURCE_SHADER_COMPILER,
2479                    MESA_DEBUG_TYPE_OTHER,
2480                    MESA_DEBUG_SEVERITY_NOTIFICATION, fmt, args);
2481   va_end(args);
2482}
2483
2484static void
2485shader_perf_log_mesa(void *data, unsigned *msg_id, const char *fmt, ...)
2486{
2487   struct brw_context *brw = (struct brw_context *)data;
2488
2489   va_list args;
2490   va_start(args, fmt);
2491
2492   if (INTEL_DEBUG(DEBUG_PERF)) {
2493      va_list args_copy;
2494      va_copy(args_copy, args);
2495      vfprintf(stderr, fmt, args_copy);
2496      va_end(args_copy);
2497   }
2498
2499   if (brw->perf_debug) {
2500      _mesa_gl_vdebugf(&brw->ctx, msg_id,
2501                       MESA_DEBUG_SOURCE_SHADER_COMPILER,
2502                       MESA_DEBUG_TYPE_PERFORMANCE,
2503                       MESA_DEBUG_SEVERITY_MEDIUM, fmt, args);
2504   }
2505   va_end(args);
2506}
2507
2508/**
2509 * This is the driver specific part of the createNewScreen entry point.
2510 * Called when using DRI2.
2511 *
2512 * \return the struct gl_config supported by this driver
2513 */
2514static const
2515__DRIconfig **brw_init_screen(__DRIscreen *dri_screen)
2516{
2517   struct brw_screen *screen;
2518
2519   util_cpu_detect();
2520
2521   if (dri_screen->image.loader) {
2522   } else if (dri_screen->dri2.loader->base.version <= 2 ||
2523       dri_screen->dri2.loader->getBuffersWithFormat == NULL) {
2524      fprintf(stderr,
2525              "\nERROR!  DRI2 loader with getBuffersWithFormat() "
2526              "support required\n");
2527      return NULL;
2528   }
2529
2530   /* Allocate the private area */
2531   screen = rzalloc(NULL, struct brw_screen);
2532   if (!screen) {
2533      fprintf(stderr, "\nERROR!  Allocating private area failed\n");
2534      return NULL;
2535   }
2536   /* parse information in __driConfigOptions */
2537   driOptionCache options;
2538   memset(&options, 0, sizeof(options));
2539
2540   driParseOptionInfo(&options, brw_driconf, ARRAY_SIZE(brw_driconf));
2541   driParseConfigFiles(&screen->optionCache, &options, dri_screen->myNum,
2542                       "i965", NULL, NULL, NULL, 0, NULL, 0);
2543   driDestroyOptionCache(&options);
2544
2545   screen->driScrnPriv = dri_screen;
2546   dri_screen->driverPrivate = (void *) screen;
2547
2548   if (!intel_get_device_info_from_fd(dri_screen->fd, &screen->devinfo))
2549      return NULL;
2550
2551   const struct intel_device_info *devinfo = &screen->devinfo;
2552   screen->deviceID = devinfo->chipset_id;
2553
2554   if (devinfo->ver >= 12) {
2555      fprintf(stderr, "gfx12 and newer are not supported on i965\n");
2556      return NULL;
2557   }
2558
2559   if (!brw_init_bufmgr(screen))
2560       return NULL;
2561
2562   brw_process_intel_debug_variable();
2563
2564   if (INTEL_DEBUG(DEBUG_SHADER_TIME) && devinfo->ver < 7) {
2565      fprintf(stderr,
2566              "shader_time debugging requires gfx7 (Ivybridge) or better.\n");
2567      intel_debug &= ~DEBUG_SHADER_TIME;
2568   }
2569
2570   if (brw_get_integer(screen, I915_PARAM_MMAP_GTT_VERSION) >= 1) {
2571      /* Theorectically unlimited! At least for individual objects...
2572       *
2573       * Currently the entire (global) address space for all GTT maps is
2574       * limited to 64bits. That is all objects on the system that are
2575       * setup for GTT mmapping must fit within 64bits. An attempt to use
2576       * one that exceeds the limit with fail in brw_bo_map_gtt().
2577       *
2578       * Long before we hit that limit, we will be practically limited by
2579       * that any single object must fit in physical memory (RAM). The upper
2580       * limit on the CPU's address space is currently 48bits (Skylake), of
2581       * which only 39bits can be physical memory. (The GPU itself also has
2582       * a 48bit addressable virtual space.) We can fit over 32 million
2583       * objects of the current maximum allocable size before running out
2584       * of mmap space.
2585       */
2586      screen->max_gtt_map_object_size = UINT64_MAX;
2587   } else {
2588      /* Estimate the size of the mappable aperture into the GTT.  There's an
2589       * ioctl to get the whole GTT size, but not one to get the mappable subset.
2590       * It turns out it's basically always 256MB, though some ancient hardware
2591       * was smaller.
2592       */
2593      uint32_t gtt_size = 256 * 1024 * 1024;
2594
2595      /* We don't want to map two objects such that a memcpy between them would
2596       * just fault one mapping in and then the other over and over forever.  So
2597       * we would need to divide the GTT size by 2.  Additionally, some GTT is
2598       * taken up by things like the framebuffer and the ringbuffer and such, so
2599       * be more conservative.
2600       */
2601      screen->max_gtt_map_object_size = gtt_size / 4;
2602   }
2603
2604   screen->aperture_threshold = devinfo->aperture_bytes * 3 / 4;
2605
2606   screen->hw_has_swizzling = brw_detect_swizzling(screen);
2607   screen->hw_has_timestamp = brw_detect_timestamp(screen);
2608
2609   isl_device_init(&screen->isl_dev, &screen->devinfo,
2610                   screen->hw_has_swizzling);
2611
2612   /* Gfx7-7.5 kernel requirements / command parser saga:
2613    *
2614    * - pre-v3.16:
2615    *   Haswell and Baytrail cannot use any privileged batchbuffer features.
2616    *
2617    *   Ivybridge has aliasing PPGTT on by default, which accidentally marks
2618    *   all batches secure, allowing them to use any feature with no checking.
2619    *   This is effectively equivalent to a command parser version of
2620    *   \infinity - everything is possible.
2621    *
2622    *   The command parser does not exist, and querying the version will
2623    *   return -EINVAL.
2624    *
2625    * - v3.16:
2626    *   The kernel enables the command parser by default, for systems with
2627    *   aliasing PPGTT enabled (Ivybridge and Haswell).  However, the
2628    *   hardware checker is still enabled, so Haswell and Baytrail cannot
2629    *   do anything.
2630    *
2631    *   Ivybridge goes from "everything is possible" to "only what the
2632    *   command parser allows" (if the user boots with i915.cmd_parser=0,
2633    *   then everything is possible again).  We can only safely use features
2634    *   allowed by the supported command parser version.
2635    *
2636    *   Annoyingly, I915_PARAM_CMD_PARSER_VERSION reports the static version
2637    *   implemented by the kernel, even if it's turned off.  So, checking
2638    *   for version > 0 does not mean that you can write registers.  We have
2639    *   to try it and see.  The version does, however, indicate the age of
2640    *   the kernel.
2641    *
2642    *   Instead of matching the hardware checker's behavior of converting
2643    *   privileged commands to MI_NOOP, it makes execbuf2 start returning
2644    *   -EINVAL, making it dangerous to try and use privileged features.
2645    *
2646    *   Effective command parser versions:
2647    *   - Haswell:   0 (reporting 1, writes don't work)
2648    *   - Baytrail:  0 (reporting 1, writes don't work)
2649    *   - Ivybridge: 1 (enabled) or infinite (disabled)
2650    *
2651    * - v3.17:
2652    *   Baytrail aliasing PPGTT is enabled, making it like Ivybridge:
2653    *   effectively version 1 (enabled) or infinite (disabled).
2654    *
2655    * - v3.19: f1f55cc0556031c8ee3fe99dae7251e78b9b653b
2656    *   Command parser v2 supports predicate writes.
2657    *
2658    *   - Haswell:   0 (reporting 1, writes don't work)
2659    *   - Baytrail:  2 (enabled) or infinite (disabled)
2660    *   - Ivybridge: 2 (enabled) or infinite (disabled)
2661    *
2662    *   So version >= 2 is enough to know that Ivybridge and Baytrail
2663    *   will work.  Haswell still can't do anything.
2664    *
2665    * - v4.0: Version 3 happened.  Largely not relevant.
2666    *
2667    * - v4.1: 6702cf16e0ba8b0129f5aa1b6609d4e9c70bc13b
2668    *   L3 config registers are properly saved and restored as part
2669    *   of the hardware context.  We can approximately detect this point
2670    *   in time by checking if I915_PARAM_REVISION is recognized - it
2671    *   landed in a later commit, but in the same release cycle.
2672    *
2673    * - v4.2: 245054a1fe33c06ad233e0d58a27ec7b64db9284
2674    *   Command parser finally gains secure batch promotion.  On Haswell,
2675    *   the hardware checker gets disabled, which finally allows it to do
2676    *   privileged commands.
2677    *
2678    *   I915_PARAM_CMD_PARSER_VERSION reports 3.  Effective versions:
2679    *   - Haswell:   3 (enabled) or 0 (disabled)
2680    *   - Baytrail:  3 (enabled) or infinite (disabled)
2681    *   - Ivybridge: 3 (enabled) or infinite (disabled)
2682    *
2683    *   Unfortunately, detecting this point in time is tricky, because
2684    *   no version bump happened when this important change occurred.
2685    *   On Haswell, if we can write any register, then the kernel is at
2686    *   least this new, and we can start trusting the version number.
2687    *
2688    * - v4.4: 2bbe6bbb0dc94fd4ce287bdac9e1bd184e23057b and
2689    *   Command parser reaches version 4, allowing access to Haswell
2690    *   atomic scratch and chicken3 registers.  If version >= 4, we know
2691    *   the kernel is new enough to support privileged features on all
2692    *   hardware.  However, the user might have disabled it...and the
2693    *   kernel will still report version 4.  So we still have to guess
2694    *   and check.
2695    *
2696    * - v4.4: 7b9748cb513a6bef4af87b79f0da3ff7e8b56cd8
2697    *   Command parser v5 whitelists indirect compute shader dispatch
2698    *   registers, needed for OpenGL 4.3 and later.
2699    *
2700    * - v4.8:
2701    *   Command parser v7 lets us use MI_MATH on Haswell.
2702    *
2703    *   Additionally, the kernel begins reporting version 0 when
2704    *   the command parser is disabled, allowing us to skip the
2705    *   guess-and-check step on Haswell.  Unfortunately, this also
2706    *   means that we can no longer use it as an indicator of the
2707    *   age of the kernel.
2708    */
2709   if (brw_get_param(screen, I915_PARAM_CMD_PARSER_VERSION,
2710                       &screen->cmd_parser_version) < 0) {
2711      /* Command parser does not exist - getparam is unrecognized */
2712      screen->cmd_parser_version = 0;
2713   }
2714
2715   /* Kernel 4.13 retuired for exec object capture */
2716   if (brw_get_boolean(screen, I915_PARAM_HAS_EXEC_CAPTURE)) {
2717      screen->kernel_features |= KERNEL_ALLOWS_EXEC_CAPTURE;
2718   }
2719
2720   if (brw_get_boolean(screen, I915_PARAM_HAS_EXEC_BATCH_FIRST)) {
2721      screen->kernel_features |= KERNEL_ALLOWS_EXEC_BATCH_FIRST;
2722   }
2723
2724   if (!brw_detect_pipelined_so(screen)) {
2725      /* We can't do anything, so the effective version is 0. */
2726      screen->cmd_parser_version = 0;
2727   } else {
2728      screen->kernel_features |= KERNEL_ALLOWS_SOL_OFFSET_WRITES;
2729   }
2730
2731   if (devinfo->ver >= 8 || screen->cmd_parser_version >= 2)
2732      screen->kernel_features |= KERNEL_ALLOWS_PREDICATE_WRITES;
2733
2734   /* Haswell requires command parser version 4 in order to have L3
2735    * atomic scratch1 and chicken3 bits
2736    */
2737   if (devinfo->is_haswell && screen->cmd_parser_version >= 4) {
2738      screen->kernel_features |=
2739         KERNEL_ALLOWS_HSW_SCRATCH1_AND_ROW_CHICKEN3;
2740   }
2741
2742   /* Haswell requires command parser version 6 in order to write to the
2743    * MI_MATH GPR registers, and version 7 in order to use
2744    * MI_LOAD_REGISTER_REG (which all users of MI_MATH use).
2745    */
2746   if (devinfo->ver >= 8 ||
2747       (devinfo->is_haswell && screen->cmd_parser_version >= 7)) {
2748      screen->kernel_features |= KERNEL_ALLOWS_MI_MATH_AND_LRR;
2749   }
2750
2751   /* Gfx7 needs at least command parser version 5 to support compute */
2752   if (devinfo->ver >= 8 || screen->cmd_parser_version >= 5)
2753      screen->kernel_features |= KERNEL_ALLOWS_COMPUTE_DISPATCH;
2754
2755   if (brw_get_boolean(screen, I915_PARAM_HAS_CONTEXT_ISOLATION))
2756      screen->kernel_features |= KERNEL_ALLOWS_CONTEXT_ISOLATION;
2757
2758   const char *force_msaa = getenv("INTEL_FORCE_MSAA");
2759   if (force_msaa) {
2760      screen->winsys_msaa_samples_override =
2761         brw_quantize_num_samples(screen, atoi(force_msaa));
2762      printf("Forcing winsys sample count to %d\n",
2763             screen->winsys_msaa_samples_override);
2764   } else {
2765      screen->winsys_msaa_samples_override = -1;
2766   }
2767
2768   set_max_gl_versions(screen);
2769
2770   /* Notification of GPU resets requires hardware contexts and a kernel new
2771    * enough to support DRM_IOCTL_I915_GET_RESET_STATS.  If the ioctl is
2772    * supported, calling it with a context of 0 will either generate EPERM or
2773    * no error.  If the ioctl is not supported, it always generate EINVAL.
2774    * Use this to determine whether to advertise the __DRI2_ROBUSTNESS
2775    * extension to the loader.
2776    *
2777    * Don't even try on pre-Gfx6, since we don't attempt to use contexts there.
2778    */
2779   if (devinfo->ver >= 6) {
2780      struct drm_i915_reset_stats stats;
2781      memset(&stats, 0, sizeof(stats));
2782
2783      const int ret = drmIoctl(screen->fd, DRM_IOCTL_I915_GET_RESET_STATS, &stats);
2784
2785      screen->has_context_reset_notification =
2786         (ret != -1 || errno != EINVAL);
2787   }
2788
2789   dri_screen->extensions = !screen->has_context_reset_notification
2790      ? screenExtensions : brwRobustScreenExtensions;
2791
2792   screen->compiler = brw_compiler_create(screen, devinfo);
2793   screen->compiler->shader_debug_log = shader_debug_log_mesa;
2794   screen->compiler->shader_perf_log = shader_perf_log_mesa;
2795
2796   /* Changing the meaning of constant buffer pointers from a dynamic state
2797    * offset to an absolute address is only safe if the kernel isolates other
2798    * contexts from our changes.
2799    */
2800   screen->compiler->constant_buffer_0_is_relative = devinfo->ver < 8 ||
2801      !(screen->kernel_features & KERNEL_ALLOWS_CONTEXT_ISOLATION);
2802
2803   screen->compiler->glsl_compiler_options[MESA_SHADER_VERTEX].PositionAlwaysInvariant = driQueryOptionb(&screen->optionCache, "vs_position_always_invariant");
2804   screen->compiler->glsl_compiler_options[MESA_SHADER_TESS_EVAL].PositionAlwaysPrecise = driQueryOptionb(&screen->optionCache, "vs_position_always_precise");
2805
2806   screen->compiler->supports_pull_constants = true;
2807   screen->compiler->compact_params = true;
2808   screen->compiler->lower_variable_group_size = true;
2809
2810   screen->has_exec_fence =
2811     brw_get_boolean(screen, I915_PARAM_HAS_EXEC_FENCE);
2812
2813   brw_screen_init_surface_formats(screen);
2814
2815   if (INTEL_DEBUG(DEBUG_BATCH | DEBUG_SUBMIT)) {
2816      unsigned int caps = brw_get_integer(screen, I915_PARAM_HAS_SCHEDULER);
2817      if (caps) {
2818         fprintf(stderr, "Kernel scheduler detected: %08x\n", caps);
2819         if (caps & I915_SCHEDULER_CAP_PRIORITY)
2820            fprintf(stderr, "  - User priority sorting enabled\n");
2821         if (caps & I915_SCHEDULER_CAP_PREEMPTION)
2822            fprintf(stderr, "  - Preemption enabled\n");
2823      }
2824   }
2825
2826   brw_disk_cache_init(screen);
2827
2828   return (const __DRIconfig**) brw_screen_make_configs(dri_screen);
2829}
2830
2831struct brw_buffer {
2832   __DRIbuffer base;
2833   struct brw_bo *bo;
2834};
2835
2836static __DRIbuffer *
2837brw_allocate_buffer(__DRIscreen *dri_screen,
2838                    unsigned attachment, unsigned format,
2839                    int width, int height)
2840{
2841   struct brw_screen *screen = dri_screen->driverPrivate;
2842
2843   assert(attachment == __DRI_BUFFER_FRONT_LEFT ||
2844          attachment == __DRI_BUFFER_BACK_LEFT);
2845
2846   struct brw_buffer *buffer = calloc(1, sizeof *buffer);
2847   if (buffer == NULL)
2848      return NULL;
2849
2850   /* The front and back buffers are color buffers, which are X tiled. GFX9+
2851    * supports Y tiled and compressed buffers, but there is no way to plumb that
2852    * through to here. */
2853   uint32_t pitch;
2854   int cpp = format / 8;
2855   buffer->bo = brw_bo_alloc_tiled_2d(screen->bufmgr,
2856                                      __func__,
2857                                      width,
2858                                      height,
2859                                      cpp,
2860                                      BRW_MEMZONE_OTHER,
2861                                      I915_TILING_X, &pitch,
2862                                      BO_ALLOC_BUSY);
2863
2864   if (buffer->bo == NULL) {
2865      free(buffer);
2866      return NULL;
2867   }
2868
2869   brw_bo_flink(buffer->bo, &buffer->base.name);
2870
2871   buffer->base.attachment = attachment;
2872   buffer->base.cpp = cpp;
2873   buffer->base.pitch = pitch;
2874
2875   return &buffer->base;
2876}
2877
2878static void
2879brw_release_buffer(UNUSED __DRIscreen *dri_screen, __DRIbuffer *_buffer)
2880{
2881   struct brw_buffer *buffer = (struct brw_buffer *) _buffer;
2882
2883   brw_bo_unreference(buffer->bo);
2884   free(buffer);
2885}
2886
2887static const struct __DriverAPIRec brw_driver_api = {
2888   .InitScreen           = brw_init_screen,
2889   .DestroyScreen        = brw_destroy_screen,
2890   .CreateContext        = brw_create_context,
2891   .DestroyContext       = brw_destroy_context,
2892   .CreateBuffer         = brw_create_buffer,
2893   .DestroyBuffer        = brw_destroy_buffer,
2894   .MakeCurrent          = brw_make_current,
2895   .UnbindContext        = brw_unbind_context,
2896   .AllocateBuffer       = brw_allocate_buffer,
2897   .ReleaseBuffer        = brw_release_buffer
2898};
2899
2900static const struct __DRIDriverVtableExtensionRec brw_vtable = {
2901   .base = { __DRI_DRIVER_VTABLE, 1 },
2902   .vtable = &brw_driver_api,
2903};
2904
2905static const __DRIextension *brw_driver_extensions[] = {
2906    &driCoreExtension.base,
2907    &driImageDriverExtension.base,
2908    &driDRI2Extension.base,
2909    &brw_vtable.base,
2910    &brw_config_options.base,
2911    NULL
2912};
2913
2914PUBLIC const __DRIextension **__driDriverGetExtensions_i965(void)
2915{
2916   globalDriverAPI = &brw_driver_api;
2917
2918   return brw_driver_extensions;
2919}
2920