i965/gs: Add GS_OPCODE_SET_DWORD_2_IMMED.
[mesa.git] / src / mesa / drivers / dri / i915 / intel_screen.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include <errno.h>
29 #include <time.h>
30 #include "main/glheader.h"
31 #include "main/context.h"
32 #include "main/framebuffer.h"
33 #include "main/renderbuffer.h"
34 #include "main/texobj.h"
35 #include "main/hash.h"
36 #include "main/fbobject.h"
37 #include "main/version.h"
38 #include "swrast/s_renderbuffer.h"
39
40 #include "utils.h"
41 #include "xmlpool.h"
42
43 PUBLIC const char __driConfigOptions[] =
44 DRI_CONF_BEGIN
45 DRI_CONF_SECTION_PERFORMANCE
46 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC)
47 /* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
48 * DRI_CONF_BO_REUSE_ALL
49 */
50 DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1")
51 DRI_CONF_DESC_BEGIN(en, "Buffer object reuse")
52 DRI_CONF_ENUM(0, "Disable buffer object reuse")
53 DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects")
54 DRI_CONF_DESC_END
55 DRI_CONF_OPT_END
56
57 DRI_CONF_OPT_BEGIN_B(early_z, "false")
58 DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
59 DRI_CONF_OPT_END
60
61 DRI_CONF_SECTION_END
62 DRI_CONF_SECTION_QUALITY
63 DRI_CONF_FORCE_S3TC_ENABLE("false")
64 DRI_CONF_SECTION_END
65 DRI_CONF_SECTION_DEBUG
66 DRI_CONF_NO_RAST("false")
67 DRI_CONF_ALWAYS_FLUSH_BATCH("false")
68 DRI_CONF_ALWAYS_FLUSH_CACHE("false")
69 DRI_CONF_DISABLE_THROTTLING("false")
70 DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN("false")
71 DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS("false")
72 DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED("false")
73
74 DRI_CONF_OPT_BEGIN_B(shader_precompile, "true")
75 DRI_CONF_DESC(en, "Perform code generation at shader link time.")
76 DRI_CONF_OPT_END
77 DRI_CONF_SECTION_END
78 DRI_CONF_END;
79
80 #include "intel_batchbuffer.h"
81 #include "intel_buffers.h"
82 #include "intel_bufmgr.h"
83 #include "intel_chipset.h"
84 #include "intel_fbo.h"
85 #include "intel_mipmap_tree.h"
86 #include "intel_screen.h"
87 #include "intel_tex.h"
88 #include "intel_regions.h"
89
90 #include "i915_drm.h"
91
92 #ifdef USE_NEW_INTERFACE
93 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
94 #endif /*USE_NEW_INTERFACE */
95
96 /**
97 * For debugging purposes, this returns a time in seconds.
98 */
99 double
100 get_time(void)
101 {
102 struct timespec tp;
103
104 clock_gettime(CLOCK_MONOTONIC, &tp);
105
106 return tp.tv_sec + tp.tv_nsec / 1000000000.0;
107 }
108
109 void
110 aub_dump_bmp(struct gl_context *ctx)
111 {
112 struct gl_framebuffer *fb = ctx->DrawBuffer;
113
114 for (int i = 0; i < fb->_NumColorDrawBuffers; i++) {
115 struct intel_renderbuffer *irb =
116 intel_renderbuffer(fb->_ColorDrawBuffers[i]);
117
118 if (irb && irb->mt) {
119 enum aub_dump_bmp_format format;
120
121 switch (irb->Base.Base.Format) {
122 case MESA_FORMAT_ARGB8888:
123 case MESA_FORMAT_XRGB8888:
124 format = AUB_DUMP_BMP_FORMAT_ARGB_8888;
125 break;
126 default:
127 continue;
128 }
129
130 assert(irb->mt->region->pitch % irb->mt->region->cpp == 0);
131 drm_intel_gem_bo_aub_dump_bmp(irb->mt->region->bo,
132 irb->draw_x,
133 irb->draw_y,
134 irb->Base.Base.Width,
135 irb->Base.Base.Height,
136 format,
137 irb->mt->region->pitch,
138 0);
139 }
140 }
141 }
142
143 static const __DRItexBufferExtension intelTexBufferExtension = {
144 .base = { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
145
146 .setTexBuffer = intelSetTexBuffer,
147 .setTexBuffer2 = intelSetTexBuffer2,
148 .releaseTexBuffer = NULL,
149 };
150
151 static void
152 intelDRI2Flush(__DRIdrawable *drawable)
153 {
154 GET_CURRENT_CONTEXT(ctx);
155 struct intel_context *intel = intel_context(ctx);
156 if (intel == NULL)
157 return;
158
159 INTEL_FIREVERTICES(intel);
160
161 intel->need_throttle = true;
162
163 if (intel->batch.used)
164 intel_batchbuffer_flush(intel);
165
166 if (INTEL_DEBUG & DEBUG_AUB) {
167 aub_dump_bmp(ctx);
168 }
169 }
170
171 static const struct __DRI2flushExtensionRec intelFlushExtension = {
172 .base = { __DRI2_FLUSH, 3 },
173
174 .flush = intelDRI2Flush,
175 .invalidate = dri2InvalidateDrawable,
176 };
177
178 static struct intel_image_format intel_image_formats[] = {
179 { __DRI_IMAGE_FOURCC_ARGB8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
180 { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } },
181
182 { __DRI_IMAGE_FOURCC_XRGB8888, __DRI_IMAGE_COMPONENTS_RGB, 1,
183 { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB8888, 4 }, } },
184
185 { __DRI_IMAGE_FOURCC_YUV410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
186 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
187 { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 },
188 { 2, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 } } },
189
190 { __DRI_IMAGE_FOURCC_YUV411, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
191 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
192 { 1, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 },
193 { 2, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
194
195 { __DRI_IMAGE_FOURCC_YUV420, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
196 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
197 { 1, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 },
198 { 2, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 } } },
199
200 { __DRI_IMAGE_FOURCC_YUV422, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
201 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
202 { 1, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 },
203 { 2, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
204
205 { __DRI_IMAGE_FOURCC_YUV444, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
206 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
207 { 1, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
208 { 2, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
209
210 { __DRI_IMAGE_FOURCC_NV12, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
211 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
212 { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88, 2 } } },
213
214 { __DRI_IMAGE_FOURCC_NV16, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
215 { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
216 { 1, 1, 0, __DRI_IMAGE_FORMAT_GR88, 2 } } },
217
218 /* For YUYV buffers, we set up two overlapping DRI images and treat
219 * them as planar buffers in the compositors. Plane 0 is GR88 and
220 * samples YU or YV pairs and places Y into the R component, while
221 * plane 1 is ARGB and samples YUYV clusters and places pairs and
222 * places U into the G component and V into A. This lets the
223 * texture sampler interpolate the Y components correctly when
224 * sampling from plane 0, and interpolate U and V correctly when
225 * sampling from plane 1. */
226 { __DRI_IMAGE_FOURCC_YUYV, __DRI_IMAGE_COMPONENTS_Y_XUXV, 2,
227 { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 },
228 { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } }
229 };
230
231 static __DRIimage *
232 intel_allocate_image(int dri_format, void *loaderPrivate)
233 {
234 __DRIimage *image;
235
236 image = calloc(1, sizeof *image);
237 if (image == NULL)
238 return NULL;
239
240 image->dri_format = dri_format;
241 image->offset = 0;
242
243 switch (dri_format) {
244 case __DRI_IMAGE_FORMAT_RGB565:
245 image->format = MESA_FORMAT_RGB565;
246 break;
247 case __DRI_IMAGE_FORMAT_XRGB8888:
248 image->format = MESA_FORMAT_XRGB8888;
249 break;
250 case __DRI_IMAGE_FORMAT_ARGB8888:
251 image->format = MESA_FORMAT_ARGB8888;
252 break;
253 case __DRI_IMAGE_FORMAT_ABGR8888:
254 image->format = MESA_FORMAT_RGBA8888_REV;
255 break;
256 case __DRI_IMAGE_FORMAT_XBGR8888:
257 image->format = MESA_FORMAT_RGBX8888_REV;
258 break;
259 case __DRI_IMAGE_FORMAT_R8:
260 image->format = MESA_FORMAT_R8;
261 break;
262 case __DRI_IMAGE_FORMAT_GR88:
263 image->format = MESA_FORMAT_GR88;
264 break;
265 case __DRI_IMAGE_FORMAT_NONE:
266 image->format = MESA_FORMAT_NONE;
267 break;
268 default:
269 free(image);
270 return NULL;
271 }
272
273 image->internal_format = _mesa_get_format_base_format(image->format);
274 image->data = loaderPrivate;
275
276 return image;
277 }
278
279 /**
280 * Sets up a DRIImage structure to point to our shared image in a region
281 */
282 static void
283 intel_setup_image_from_mipmap_tree(struct intel_context *intel, __DRIimage *image,
284 struct intel_mipmap_tree *mt, GLuint level,
285 GLuint zoffset)
286 {
287 unsigned int draw_x, draw_y;
288 uint32_t mask_x, mask_y;
289
290 intel_miptree_check_level_layer(mt, level, zoffset);
291
292 intel_region_get_tile_masks(mt->region, &mask_x, &mask_y, false);
293 intel_miptree_get_image_offset(mt, level, zoffset, &draw_x, &draw_y);
294
295 image->width = mt->level[level].width;
296 image->height = mt->level[level].height;
297 image->tile_x = draw_x & mask_x;
298 image->tile_y = draw_y & mask_y;
299
300 image->offset = intel_region_get_aligned_offset(mt->region,
301 draw_x & ~mask_x,
302 draw_y & ~mask_y,
303 false);
304
305 intel_region_reference(&image->region, mt->region);
306 }
307
308 static void
309 intel_setup_image_from_dimensions(__DRIimage *image)
310 {
311 image->width = image->region->width;
312 image->height = image->region->height;
313 image->tile_x = 0;
314 image->tile_y = 0;
315 }
316
317 static inline uint32_t
318 intel_dri_format(GLuint format)
319 {
320 switch (format) {
321 case MESA_FORMAT_RGB565:
322 return __DRI_IMAGE_FORMAT_RGB565;
323 case MESA_FORMAT_XRGB8888:
324 return __DRI_IMAGE_FORMAT_XRGB8888;
325 case MESA_FORMAT_ARGB8888:
326 return __DRI_IMAGE_FORMAT_ARGB8888;
327 case MESA_FORMAT_RGBA8888_REV:
328 return __DRI_IMAGE_FORMAT_ABGR8888;
329 case MESA_FORMAT_R8:
330 return __DRI_IMAGE_FORMAT_R8;
331 case MESA_FORMAT_RG88:
332 return __DRI_IMAGE_FORMAT_GR88;
333 }
334
335 return MESA_FORMAT_NONE;
336 }
337
338 static __DRIimage *
339 intel_create_image_from_name(__DRIscreen *screen,
340 int width, int height, int format,
341 int name, int pitch, void *loaderPrivate)
342 {
343 struct intel_screen *intelScreen = screen->driverPrivate;
344 __DRIimage *image;
345 int cpp;
346
347 image = intel_allocate_image(format, loaderPrivate);
348 if (image == NULL)
349 return NULL;
350
351 if (image->format == MESA_FORMAT_NONE)
352 cpp = 1;
353 else
354 cpp = _mesa_get_format_bytes(image->format);
355 image->region = intel_region_alloc_for_handle(intelScreen,
356 cpp, width, height,
357 pitch * cpp, name, "image");
358 if (image->region == NULL) {
359 free(image);
360 return NULL;
361 }
362
363 intel_setup_image_from_dimensions(image);
364
365 return image;
366 }
367
368 static __DRIimage *
369 intel_create_image_from_renderbuffer(__DRIcontext *context,
370 int renderbuffer, void *loaderPrivate)
371 {
372 __DRIimage *image;
373 struct intel_context *intel = context->driverPrivate;
374 struct gl_renderbuffer *rb;
375 struct intel_renderbuffer *irb;
376
377 rb = _mesa_lookup_renderbuffer(&intel->ctx, renderbuffer);
378 if (!rb) {
379 _mesa_error(&intel->ctx,
380 GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
381 return NULL;
382 }
383
384 irb = intel_renderbuffer(rb);
385 image = calloc(1, sizeof *image);
386 if (image == NULL)
387 return NULL;
388
389 image->internal_format = rb->InternalFormat;
390 image->format = rb->Format;
391 image->offset = 0;
392 image->data = loaderPrivate;
393 intel_region_reference(&image->region, irb->mt->region);
394 intel_setup_image_from_dimensions(image);
395 image->dri_format = intel_dri_format(image->format);
396
397 rb->NeedsFinishRenderTexture = true;
398 return image;
399 }
400
401 static __DRIimage *
402 intel_create_image_from_texture(__DRIcontext *context, int target,
403 unsigned texture, int zoffset,
404 int level,
405 unsigned *error,
406 void *loaderPrivate)
407 {
408 __DRIimage *image;
409 struct intel_context *intel = context->driverPrivate;
410 struct gl_texture_object *obj;
411 struct intel_texture_object *iobj;
412 GLuint face = 0;
413
414 obj = _mesa_lookup_texture(&intel->ctx, texture);
415 if (!obj || obj->Target != target) {
416 *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
417 return NULL;
418 }
419
420 if (target == GL_TEXTURE_CUBE_MAP)
421 face = zoffset;
422
423 _mesa_test_texobj_completeness(&intel->ctx, obj);
424 iobj = intel_texture_object(obj);
425 if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) {
426 *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
427 return NULL;
428 }
429
430 if (level < obj->BaseLevel || level > obj->_MaxLevel) {
431 *error = __DRI_IMAGE_ERROR_BAD_MATCH;
432 return NULL;
433 }
434
435 if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < zoffset) {
436 *error = __DRI_IMAGE_ERROR_BAD_MATCH;
437 return NULL;
438 }
439 image = calloc(1, sizeof *image);
440 if (image == NULL) {
441 *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
442 return NULL;
443 }
444
445 image->internal_format = obj->Image[face][level]->InternalFormat;
446 image->format = obj->Image[face][level]->TexFormat;
447 image->data = loaderPrivate;
448 intel_setup_image_from_mipmap_tree(intel, image, iobj->mt, level, zoffset);
449 image->dri_format = intel_dri_format(image->format);
450 if (image->dri_format == MESA_FORMAT_NONE) {
451 *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
452 free(image);
453 return NULL;
454 }
455
456 *error = __DRI_IMAGE_ERROR_SUCCESS;
457 return image;
458 }
459
460 static void
461 intel_destroy_image(__DRIimage *image)
462 {
463 intel_region_release(&image->region);
464 free(image);
465 }
466
467 static __DRIimage *
468 intel_create_image(__DRIscreen *screen,
469 int width, int height, int format,
470 unsigned int use,
471 void *loaderPrivate)
472 {
473 __DRIimage *image;
474 struct intel_screen *intelScreen = screen->driverPrivate;
475 uint32_t tiling;
476 int cpp;
477
478 tiling = I915_TILING_X;
479 if (use & __DRI_IMAGE_USE_CURSOR) {
480 if (width != 64 || height != 64)
481 return NULL;
482 tiling = I915_TILING_NONE;
483 }
484
485 image = intel_allocate_image(format, loaderPrivate);
486 if (image == NULL)
487 return NULL;
488
489 cpp = _mesa_get_format_bytes(image->format);
490 image->region =
491 intel_region_alloc(intelScreen, tiling, cpp, width, height, true);
492 if (image->region == NULL) {
493 free(image);
494 return NULL;
495 }
496
497 intel_setup_image_from_dimensions(image);
498
499 return image;
500 }
501
502 static GLboolean
503 intel_query_image(__DRIimage *image, int attrib, int *value)
504 {
505 switch (attrib) {
506 case __DRI_IMAGE_ATTRIB_STRIDE:
507 *value = image->region->pitch;
508 return true;
509 case __DRI_IMAGE_ATTRIB_HANDLE:
510 *value = image->region->bo->handle;
511 return true;
512 case __DRI_IMAGE_ATTRIB_NAME:
513 return intel_region_flink(image->region, (uint32_t *) value);
514 case __DRI_IMAGE_ATTRIB_FORMAT:
515 *value = image->dri_format;
516 return true;
517 case __DRI_IMAGE_ATTRIB_WIDTH:
518 *value = image->region->width;
519 return true;
520 case __DRI_IMAGE_ATTRIB_HEIGHT:
521 *value = image->region->height;
522 return true;
523 case __DRI_IMAGE_ATTRIB_COMPONENTS:
524 if (image->planar_format == NULL)
525 return false;
526 *value = image->planar_format->components;
527 return true;
528 case __DRI_IMAGE_ATTRIB_FD:
529 if (drm_intel_bo_gem_export_to_prime(image->region->bo, value) == 0)
530 return true;
531 return false;
532 default:
533 return false;
534 }
535 }
536
537 static __DRIimage *
538 intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
539 {
540 __DRIimage *image;
541
542 image = calloc(1, sizeof *image);
543 if (image == NULL)
544 return NULL;
545
546 intel_region_reference(&image->region, orig_image->region);
547 if (image->region == NULL) {
548 free(image);
549 return NULL;
550 }
551
552 image->internal_format = orig_image->internal_format;
553 image->planar_format = orig_image->planar_format;
554 image->dri_format = orig_image->dri_format;
555 image->format = orig_image->format;
556 image->offset = orig_image->offset;
557 image->width = orig_image->width;
558 image->height = orig_image->height;
559 image->tile_x = orig_image->tile_x;
560 image->tile_y = orig_image->tile_y;
561 image->data = loaderPrivate;
562
563 memcpy(image->strides, orig_image->strides, sizeof(image->strides));
564 memcpy(image->offsets, orig_image->offsets, sizeof(image->offsets));
565
566 return image;
567 }
568
569 static GLboolean
570 intel_validate_usage(__DRIimage *image, unsigned int use)
571 {
572 if (use & __DRI_IMAGE_USE_CURSOR) {
573 if (image->region->width != 64 || image->region->height != 64)
574 return GL_FALSE;
575 }
576
577 return GL_TRUE;
578 }
579
580 static __DRIimage *
581 intel_create_image_from_names(__DRIscreen *screen,
582 int width, int height, int fourcc,
583 int *names, int num_names,
584 int *strides, int *offsets,
585 void *loaderPrivate)
586 {
587 struct intel_image_format *f = NULL;
588 __DRIimage *image;
589 int i, index;
590
591 if (screen == NULL || names == NULL || num_names != 1)
592 return NULL;
593
594 for (i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
595 if (intel_image_formats[i].fourcc == fourcc) {
596 f = &intel_image_formats[i];
597 }
598 }
599
600 if (f == NULL)
601 return NULL;
602
603 image = intel_create_image_from_name(screen, width, height,
604 __DRI_IMAGE_FORMAT_NONE,
605 names[0], strides[0],
606 loaderPrivate);
607
608 if (image == NULL)
609 return NULL;
610
611 image->planar_format = f;
612 for (i = 0; i < f->nplanes; i++) {
613 index = f->planes[i].buffer_index;
614 image->offsets[index] = offsets[index];
615 image->strides[index] = strides[index];
616 }
617
618 return image;
619 }
620
621 static __DRIimage *
622 intel_create_image_from_fds(__DRIscreen *screen,
623 int width, int height, int fourcc,
624 int *fds, int num_fds, int *strides, int *offsets,
625 void *loaderPrivate)
626 {
627 struct intel_screen *intelScreen = screen->driverPrivate;
628 struct intel_image_format *f = NULL;
629 __DRIimage *image;
630 int i, index;
631
632 if (fds == NULL || num_fds != 1)
633 return NULL;
634
635 for (i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
636 if (intel_image_formats[i].fourcc == fourcc) {
637 f = &intel_image_formats[i];
638 }
639 }
640
641 if (f == NULL)
642 return NULL;
643
644 image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPrivate);
645 if (image == NULL)
646 return NULL;
647
648 image->region = intel_region_alloc_for_fd(intelScreen,
649 1, width, height,
650 strides[0], fds[0], "image");
651 if (image->region == NULL) {
652 free(image);
653 return NULL;
654 }
655
656 image->planar_format = f;
657 for (i = 0; i < f->nplanes; i++) {
658 index = f->planes[i].buffer_index;
659 image->offsets[index] = offsets[index];
660 image->strides[index] = strides[index];
661 }
662
663 return image;
664 }
665
666
667 static __DRIimage *
668 intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
669 {
670 int width, height, offset, stride, dri_format, index;
671 struct intel_image_format *f;
672 uint32_t mask_x, mask_y;
673 __DRIimage *image;
674
675 if (parent == NULL || parent->planar_format == NULL)
676 return NULL;
677
678 f = parent->planar_format;
679
680 if (plane >= f->nplanes)
681 return NULL;
682
683 width = parent->region->width >> f->planes[plane].width_shift;
684 height = parent->region->height >> f->planes[plane].height_shift;
685 dri_format = f->planes[plane].dri_format;
686 index = f->planes[plane].buffer_index;
687 offset = parent->offsets[index];
688 stride = parent->strides[index];
689
690 image = intel_allocate_image(dri_format, loaderPrivate);
691 if (image == NULL)
692 return NULL;
693
694 if (offset + height * stride > parent->region->bo->size) {
695 _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds");
696 free(image);
697 return NULL;
698 }
699
700 image->region = calloc(sizeof(*image->region), 1);
701 if (image->region == NULL) {
702 free(image);
703 return NULL;
704 }
705
706 image->region->cpp = _mesa_get_format_bytes(image->format);
707 image->region->width = width;
708 image->region->height = height;
709 image->region->pitch = stride;
710 image->region->refcount = 1;
711 image->region->bo = parent->region->bo;
712 drm_intel_bo_reference(image->region->bo);
713 image->region->tiling = parent->region->tiling;
714 image->offset = offset;
715 intel_setup_image_from_dimensions(image);
716
717 intel_region_get_tile_masks(image->region, &mask_x, &mask_y, false);
718 if (offset & mask_x)
719 _mesa_warning(NULL,
720 "intel_create_sub_image: offset not on tile boundary");
721
722 return image;
723 }
724
725 static struct __DRIimageExtensionRec intelImageExtension = {
726 .base = { __DRI_IMAGE, 7 },
727
728 .createImageFromName = intel_create_image_from_name,
729 .createImageFromRenderbuffer = intel_create_image_from_renderbuffer,
730 .destroyImage = intel_destroy_image,
731 .createImage = intel_create_image,
732 .queryImage = intel_query_image,
733 .dupImage = intel_dup_image,
734 .validateUsage = intel_validate_usage,
735 .createImageFromNames = intel_create_image_from_names,
736 .fromPlanar = intel_from_planar,
737 .createImageFromTexture = intel_create_image_from_texture,
738 .createImageFromFds = intel_create_image_from_fds
739 };
740
741 static const __DRIextension *intelScreenExtensions[] = {
742 &intelTexBufferExtension.base,
743 &intelFlushExtension.base,
744 &intelImageExtension.base,
745 &dri2ConfigQueryExtension.base,
746 NULL
747 };
748
749 static bool
750 intel_get_param(__DRIscreen *psp, int param, int *value)
751 {
752 int ret;
753 struct drm_i915_getparam gp;
754
755 memset(&gp, 0, sizeof(gp));
756 gp.param = param;
757 gp.value = value;
758
759 ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
760 if (ret) {
761 if (ret != -EINVAL)
762 _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
763 return false;
764 }
765
766 return true;
767 }
768
769 static bool
770 intel_get_boolean(__DRIscreen *psp, int param)
771 {
772 int value = 0;
773 return intel_get_param(psp, param, &value) && value;
774 }
775
776 static void
777 intelDestroyScreen(__DRIscreen * sPriv)
778 {
779 struct intel_screen *intelScreen = sPriv->driverPrivate;
780
781 dri_bufmgr_destroy(intelScreen->bufmgr);
782 driDestroyOptionInfo(&intelScreen->optionCache);
783
784 free(intelScreen);
785 sPriv->driverPrivate = NULL;
786 }
787
788
789 /**
790 * This is called when we need to set up GL rendering to a new X window.
791 */
792 static GLboolean
793 intelCreateBuffer(__DRIscreen * driScrnPriv,
794 __DRIdrawable * driDrawPriv,
795 const struct gl_config * mesaVis, GLboolean isPixmap)
796 {
797 struct intel_renderbuffer *rb;
798 gl_format rgbFormat;
799 struct gl_framebuffer *fb;
800
801 if (isPixmap)
802 return false;
803
804 fb = CALLOC_STRUCT(gl_framebuffer);
805 if (!fb)
806 return false;
807
808 _mesa_initialize_window_framebuffer(fb, mesaVis);
809
810 if (mesaVis->redBits == 5)
811 rgbFormat = MESA_FORMAT_RGB565;
812 else if (mesaVis->sRGBCapable)
813 rgbFormat = MESA_FORMAT_SARGB8;
814 else if (mesaVis->alphaBits == 0)
815 rgbFormat = MESA_FORMAT_XRGB8888;
816 else
817 rgbFormat = MESA_FORMAT_ARGB8888;
818
819 /* setup the hardware-based renderbuffers */
820 rb = intel_create_renderbuffer(rgbFormat);
821 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base.Base);
822
823 if (mesaVis->doubleBufferMode) {
824 rb = intel_create_renderbuffer(rgbFormat);
825 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base.Base);
826 }
827
828 /*
829 * Assert here that the gl_config has an expected depth/stencil bit
830 * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
831 * which constructs the advertised configs.)
832 */
833 if (mesaVis->depthBits == 24) {
834 assert(mesaVis->stencilBits == 8);
835
836 /*
837 * Use combined depth/stencil. Note that the renderbuffer is
838 * attached to two attachment points.
839 */
840 rb = intel_create_private_renderbuffer(MESA_FORMAT_S8_Z24);
841 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
842 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
843 }
844 else if (mesaVis->depthBits == 16) {
845 assert(mesaVis->stencilBits == 0);
846 rb = intel_create_private_renderbuffer(MESA_FORMAT_Z16);
847 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
848 }
849 else {
850 assert(mesaVis->depthBits == 0);
851 assert(mesaVis->stencilBits == 0);
852 }
853
854 /* now add any/all software-based renderbuffers we may need */
855 _swrast_add_soft_renderbuffers(fb,
856 false, /* never sw color */
857 false, /* never sw depth */
858 false, /* never sw stencil */
859 mesaVis->accumRedBits > 0,
860 false, /* never sw alpha */
861 false /* never sw aux */ );
862 driDrawPriv->driverPrivate = fb;
863
864 return true;
865 }
866
867 static void
868 intelDestroyBuffer(__DRIdrawable * driDrawPriv)
869 {
870 struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
871
872 _mesa_reference_framebuffer(&fb, NULL);
873 }
874
875 /* There are probably better ways to do this, such as an
876 * init-designated function to register chipids and createcontext
877 * functions.
878 */
879 extern bool
880 i830CreateContext(int api,
881 const struct gl_config *mesaVis,
882 __DRIcontext *driContextPriv,
883 unsigned major_version,
884 unsigned minor_version,
885 unsigned *error,
886 void *sharedContextPrivate);
887
888 extern bool
889 i915CreateContext(int api,
890 const struct gl_config *mesaVis,
891 __DRIcontext *driContextPriv,
892 unsigned major_version,
893 unsigned minor_version,
894 unsigned *error,
895 void *sharedContextPrivate);
896
897 static GLboolean
898 intelCreateContext(gl_api api,
899 const struct gl_config * mesaVis,
900 __DRIcontext * driContextPriv,
901 unsigned major_version,
902 unsigned minor_version,
903 uint32_t flags,
904 unsigned *error,
905 void *sharedContextPrivate)
906 {
907 bool success = false;
908
909 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
910 struct intel_screen *intelScreen = sPriv->driverPrivate;
911
912 if (IS_9XX(intelScreen->deviceID)) {
913 success = i915CreateContext(api, mesaVis, driContextPriv,
914 major_version, minor_version, error,
915 sharedContextPrivate);
916 } else {
917 intelScreen->no_vbo = true;
918 success = i830CreateContext(api, mesaVis, driContextPriv,
919 major_version, minor_version, error,
920 sharedContextPrivate);
921 }
922
923 if (success)
924 return true;
925
926 if (driContextPriv->driverPrivate != NULL)
927 intelDestroyContext(driContextPriv);
928
929 return false;
930 }
931
932 static bool
933 intel_init_bufmgr(struct intel_screen *intelScreen)
934 {
935 __DRIscreen *spriv = intelScreen->driScrnPriv;
936
937 intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
938
939 intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
940 if (intelScreen->bufmgr == NULL) {
941 fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
942 __func__, __LINE__);
943 return false;
944 }
945
946 drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
947
948 if (!intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA)) {
949 fprintf(stderr, "[%s: %u] Kernel 2.6.39 required.\n", __func__, __LINE__);
950 return false;
951 }
952
953 return true;
954 }
955
956 static bool
957 intel_detect_swizzling(struct intel_screen *screen)
958 {
959 drm_intel_bo *buffer;
960 unsigned long flags = 0;
961 unsigned long aligned_pitch;
962 uint32_t tiling = I915_TILING_X;
963 uint32_t swizzle_mode = 0;
964
965 buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "swizzle test",
966 64, 64, 4,
967 &tiling, &aligned_pitch, flags);
968 if (buffer == NULL)
969 return false;
970
971 drm_intel_bo_get_tiling(buffer, &tiling, &swizzle_mode);
972 drm_intel_bo_unreference(buffer);
973
974 if (swizzle_mode == I915_BIT_6_SWIZZLE_NONE)
975 return false;
976 else
977 return true;
978 }
979
980 static __DRIconfig**
981 intel_screen_make_configs(__DRIscreen *dri_screen)
982 {
983 static const gl_format formats[] = {
984 MESA_FORMAT_RGB565,
985 MESA_FORMAT_ARGB8888
986 };
987
988 /* GLX_SWAP_COPY_OML is not supported due to page flipping. */
989 static const GLenum back_buffer_modes[] = {
990 GLX_SWAP_UNDEFINED_OML, GLX_NONE,
991 };
992
993 static const uint8_t singlesample_samples[1] = {0};
994
995 uint8_t depth_bits[4], stencil_bits[4];
996 __DRIconfig **configs = NULL;
997
998 /* Generate singlesample configs without accumulation buffer. */
999 for (int i = 0; i < ARRAY_SIZE(formats); i++) {
1000 __DRIconfig **new_configs;
1001 int num_depth_stencil_bits = 2;
1002
1003 /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
1004 * buffer that has a different number of bits per pixel than the color
1005 * buffer.
1006 */
1007 depth_bits[0] = 0;
1008 stencil_bits[0] = 0;
1009
1010 if (formats[i] == MESA_FORMAT_RGB565) {
1011 depth_bits[1] = 16;
1012 stencil_bits[1] = 0;
1013 } else {
1014 depth_bits[1] = 24;
1015 stencil_bits[1] = 8;
1016 }
1017
1018 new_configs = driCreateConfigs(formats[i],
1019 depth_bits,
1020 stencil_bits,
1021 num_depth_stencil_bits,
1022 back_buffer_modes, 2,
1023 singlesample_samples, 1,
1024 false);
1025 configs = driConcatConfigs(configs, new_configs);
1026 }
1027
1028 /* Generate the minimum possible set of configs that include an
1029 * accumulation buffer.
1030 */
1031 for (int i = 0; i < ARRAY_SIZE(formats); i++) {
1032 __DRIconfig **new_configs;
1033
1034 if (formats[i] == MESA_FORMAT_RGB565) {
1035 depth_bits[0] = 16;
1036 stencil_bits[0] = 0;
1037 } else {
1038 depth_bits[0] = 24;
1039 stencil_bits[0] = 8;
1040 }
1041
1042 new_configs = driCreateConfigs(formats[i],
1043 depth_bits, stencil_bits, 1,
1044 back_buffer_modes, 1,
1045 singlesample_samples, 1,
1046 true);
1047 configs = driConcatConfigs(configs, new_configs);
1048 }
1049
1050 if (configs == NULL) {
1051 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
1052 __LINE__);
1053 return NULL;
1054 }
1055
1056 return configs;
1057 }
1058
1059 static void
1060 set_max_gl_versions(struct intel_screen *screen)
1061 {
1062 int gl_version_override = _mesa_get_gl_version_override();
1063
1064 switch (screen->gen) {
1065 case 3:
1066 screen->max_gl_core_version = 0;
1067 screen->max_gl_es1_version = 11;
1068 screen->max_gl_compat_version = 21;
1069 screen->max_gl_es2_version = 20;
1070 break;
1071 case 2:
1072 screen->max_gl_core_version = 0;
1073 screen->max_gl_compat_version = 13;
1074 screen->max_gl_es1_version = 11;
1075 screen->max_gl_es2_version = 0;
1076 break;
1077 default:
1078 assert(!"unrecognized intel_screen::gen");
1079 break;
1080 }
1081
1082 if (gl_version_override >= 31) {
1083 screen->max_gl_core_version = MAX2(screen->max_gl_core_version,
1084 gl_version_override);
1085 } else {
1086 screen->max_gl_compat_version = MAX2(screen->max_gl_compat_version,
1087 gl_version_override);
1088 }
1089
1090 #ifndef FEATURE_ES1
1091 screen->max_gl_es1_version = 0;
1092 #endif
1093
1094 #ifndef FEATURE_ES2
1095 screen->max_gl_es2_version = 0;
1096 #endif
1097 }
1098
1099 /**
1100 * This is the driver specific part of the createNewScreen entry point.
1101 * Called when using DRI2.
1102 *
1103 * \return the struct gl_config supported by this driver
1104 */
1105 static const
1106 __DRIconfig **intelInitScreen2(__DRIscreen *psp)
1107 {
1108 struct intel_screen *intelScreen;
1109
1110 if (psp->dri2.loader->base.version <= 2 ||
1111 psp->dri2.loader->getBuffersWithFormat == NULL) {
1112 fprintf(stderr,
1113 "\nERROR! DRI2 loader with getBuffersWithFormat() "
1114 "support required\n");
1115 return false;
1116 }
1117
1118 /* Allocate the private area */
1119 intelScreen = calloc(1, sizeof *intelScreen);
1120 if (!intelScreen) {
1121 fprintf(stderr, "\nERROR! Allocating private area failed\n");
1122 return false;
1123 }
1124 /* parse information in __driConfigOptions */
1125 driParseOptionInfo(&intelScreen->optionCache, __driConfigOptions);
1126
1127 intelScreen->driScrnPriv = psp;
1128 psp->driverPrivate = (void *) intelScreen;
1129
1130 if (!intel_init_bufmgr(intelScreen))
1131 return false;
1132
1133 intelScreen->deviceID = drm_intel_bufmgr_gem_get_devid(intelScreen->bufmgr);
1134
1135 if (IS_9XX(intelScreen->deviceID)) {
1136 intelScreen->gen = 3;
1137 } else {
1138 intelScreen->gen = 2;
1139 }
1140
1141 intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen);
1142
1143 set_max_gl_versions(intelScreen);
1144
1145 psp->api_mask = (1 << __DRI_API_OPENGL);
1146 if (intelScreen->max_gl_core_version > 0)
1147 psp->api_mask |= (1 << __DRI_API_OPENGL_CORE);
1148 if (intelScreen->max_gl_es1_version > 0)
1149 psp->api_mask |= (1 << __DRI_API_GLES);
1150 if (intelScreen->max_gl_es2_version > 0)
1151 psp->api_mask |= (1 << __DRI_API_GLES2);
1152 if (intelScreen->max_gl_es2_version >= 30)
1153 psp->api_mask |= (1 << __DRI_API_GLES3);
1154
1155 psp->extensions = intelScreenExtensions;
1156
1157 return (const __DRIconfig**) intel_screen_make_configs(psp);
1158 }
1159
1160 struct intel_buffer {
1161 __DRIbuffer base;
1162 struct intel_region *region;
1163 };
1164
1165 static __DRIbuffer *
1166 intelAllocateBuffer(__DRIscreen *screen,
1167 unsigned attachment, unsigned format,
1168 int width, int height)
1169 {
1170 struct intel_buffer *intelBuffer;
1171 struct intel_screen *intelScreen = screen->driverPrivate;
1172
1173 assert(attachment == __DRI_BUFFER_FRONT_LEFT ||
1174 attachment == __DRI_BUFFER_BACK_LEFT);
1175
1176 intelBuffer = calloc(1, sizeof *intelBuffer);
1177 if (intelBuffer == NULL)
1178 return NULL;
1179
1180 /* The front and back buffers are color buffers, which are X tiled. */
1181 intelBuffer->region = intel_region_alloc(intelScreen,
1182 I915_TILING_X,
1183 format / 8,
1184 width,
1185 height,
1186 true);
1187
1188 if (intelBuffer->region == NULL) {
1189 free(intelBuffer);
1190 return NULL;
1191 }
1192
1193 intel_region_flink(intelBuffer->region, &intelBuffer->base.name);
1194
1195 intelBuffer->base.attachment = attachment;
1196 intelBuffer->base.cpp = intelBuffer->region->cpp;
1197 intelBuffer->base.pitch = intelBuffer->region->pitch;
1198
1199 return &intelBuffer->base;
1200 }
1201
1202 static void
1203 intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
1204 {
1205 struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
1206
1207 intel_region_release(&intelBuffer->region);
1208 free(intelBuffer);
1209 }
1210
1211
1212 const struct __DriverAPIRec driDriverAPI = {
1213 .InitScreen = intelInitScreen2,
1214 .DestroyScreen = intelDestroyScreen,
1215 .CreateContext = intelCreateContext,
1216 .DestroyContext = intelDestroyContext,
1217 .CreateBuffer = intelCreateBuffer,
1218 .DestroyBuffer = intelDestroyBuffer,
1219 .MakeCurrent = intelMakeCurrent,
1220 .UnbindContext = intelUnbindContext,
1221 .AllocateBuffer = intelAllocateBuffer,
1222 .ReleaseBuffer = intelReleaseBuffer
1223 };
1224
1225 /* This is the table of extensions that the loader will dlsym() for. */
1226 PUBLIC const __DRIextension *__driDriverExtensions[] = {
1227 &driCoreExtension.base,
1228 &driDRI2Extension.base,
1229 NULL
1230 };