Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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