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