094ff568c44763e875f2cc8067f9968c44a6b928
[mesa.git] / src / mesa / drivers / dri / intel / 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 "main/glheader.h"
30 #include "main/context.h"
31 #include "main/framebuffer.h"
32 #include "main/renderbuffer.h"
33 #include "main/hash.h"
34 #include "main/fbobject.h"
35 #include "main/mfeatures.h"
36 #include "main/version.h"
37 #include "swrast/s_renderbuffer.h"
38
39 #include "utils.h"
40 #include "xmlpool.h"
41
42 PUBLIC const char __driConfigOptions[] =
43 DRI_CONF_BEGIN
44 DRI_CONF_SECTION_PERFORMANCE
45 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC)
46 /* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
47 * DRI_CONF_BO_REUSE_ALL
48 */
49 DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1")
50 DRI_CONF_DESC_BEGIN(en, "Buffer object reuse")
51 DRI_CONF_ENUM(0, "Disable buffer object reuse")
52 DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects")
53 DRI_CONF_DESC_END
54 DRI_CONF_OPT_END
55
56 DRI_CONF_OPT_BEGIN(texture_tiling, bool, true)
57 DRI_CONF_DESC(en, "Enable texture tiling")
58 DRI_CONF_OPT_END
59
60 DRI_CONF_OPT_BEGIN(early_z, bool, false)
61 DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
62 DRI_CONF_OPT_END
63
64 DRI_CONF_OPT_BEGIN(fragment_shader, bool, true)
65 DRI_CONF_DESC(en, "Enable limited ARB_fragment_shader support on 915/945.")
66 DRI_CONF_OPT_END
67
68 DRI_CONF_SECTION_END
69 DRI_CONF_SECTION_QUALITY
70 DRI_CONF_FORCE_S3TC_ENABLE(false)
71 DRI_CONF_ALLOW_LARGE_TEXTURES(2)
72 DRI_CONF_SECTION_END
73 DRI_CONF_SECTION_DEBUG
74 DRI_CONF_NO_RAST(false)
75 DRI_CONF_ALWAYS_FLUSH_BATCH(false)
76 DRI_CONF_ALWAYS_FLUSH_CACHE(false)
77
78 DRI_CONF_OPT_BEGIN(stub_occlusion_query, bool, false)
79 DRI_CONF_DESC(en, "Enable stub ARB_occlusion_query support on 915/945.")
80 DRI_CONF_OPT_END
81
82 DRI_CONF_OPT_BEGIN(shader_precompile, bool, false)
83 DRI_CONF_DESC(en, "Perform code generation at shader link time.")
84 DRI_CONF_OPT_END
85 DRI_CONF_SECTION_END
86 DRI_CONF_END;
87
88 const GLuint __driNConfigOptions = 12;
89
90 #include "intel_batchbuffer.h"
91 #include "intel_buffers.h"
92 #include "intel_bufmgr.h"
93 #include "intel_chipset.h"
94 #include "intel_fbo.h"
95 #include "intel_mipmap_tree.h"
96 #include "intel_screen.h"
97 #include "intel_tex.h"
98 #include "intel_regions.h"
99
100 #include "i915_drm.h"
101
102 #ifdef USE_NEW_INTERFACE
103 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
104 #endif /*USE_NEW_INTERFACE */
105
106 static const __DRItexBufferExtension intelTexBufferExtension = {
107 { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
108 intelSetTexBuffer,
109 intelSetTexBuffer2,
110 };
111
112 static void
113 intelDRI2Flush(__DRIdrawable *drawable)
114 {
115 GET_CURRENT_CONTEXT(ctx);
116 struct intel_context *intel = intel_context(ctx);
117 if (intel == NULL)
118 return;
119
120 if (intel->gen < 4)
121 INTEL_FIREVERTICES(intel);
122
123 intel->need_throttle = true;
124
125 if (intel->batch.used)
126 intel_batchbuffer_flush(intel);
127 }
128
129 static const struct __DRI2flushExtensionRec intelFlushExtension = {
130 { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
131 intelDRI2Flush,
132 dri2InvalidateDrawable,
133 };
134
135 static __DRIimage *
136 intel_create_image_from_name(__DRIscreen *screen,
137 int width, int height, int format,
138 int name, int pitch, void *loaderPrivate)
139 {
140 struct intel_screen *intelScreen = screen->driverPrivate;
141 __DRIimage *image;
142 int cpp;
143
144 image = CALLOC(sizeof *image);
145 if (image == NULL)
146 return NULL;
147
148 switch (format) {
149 case __DRI_IMAGE_FORMAT_RGB565:
150 image->format = MESA_FORMAT_RGB565;
151 image->internal_format = GL_RGB;
152 image->data_type = GL_UNSIGNED_BYTE;
153 break;
154 case __DRI_IMAGE_FORMAT_XRGB8888:
155 image->format = MESA_FORMAT_XRGB8888;
156 image->internal_format = GL_RGB;
157 image->data_type = GL_UNSIGNED_BYTE;
158 break;
159 case __DRI_IMAGE_FORMAT_ARGB8888:
160 image->format = MESA_FORMAT_ARGB8888;
161 image->internal_format = GL_RGBA;
162 image->data_type = GL_UNSIGNED_BYTE;
163 break;
164 case __DRI_IMAGE_FORMAT_ABGR8888:
165 image->format = MESA_FORMAT_RGBA8888_REV;
166 image->internal_format = GL_RGBA;
167 image->data_type = GL_UNSIGNED_BYTE;
168 break;
169 default:
170 free(image);
171 return NULL;
172 }
173
174 image->data = loaderPrivate;
175 cpp = _mesa_get_format_bytes(image->format);
176
177 image->region = intel_region_alloc_for_handle(intelScreen,
178 cpp, width, height,
179 pitch, name, "image");
180 if (image->region == NULL) {
181 FREE(image);
182 return NULL;
183 }
184
185 return image;
186 }
187
188 static __DRIimage *
189 intel_create_image_from_renderbuffer(__DRIcontext *context,
190 int renderbuffer, void *loaderPrivate)
191 {
192 __DRIimage *image;
193 struct intel_context *intel = context->driverPrivate;
194 struct gl_renderbuffer *rb;
195 struct intel_renderbuffer *irb;
196
197 rb = _mesa_lookup_renderbuffer(&intel->ctx, renderbuffer);
198 if (!rb) {
199 _mesa_error(&intel->ctx,
200 GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
201 return NULL;
202 }
203
204 irb = intel_renderbuffer(rb);
205 image = CALLOC(sizeof *image);
206 if (image == NULL)
207 return NULL;
208
209 image->internal_format = rb->InternalFormat;
210 image->format = rb->Format;
211 image->data_type = rb->DataType;
212 image->data = loaderPrivate;
213 intel_region_reference(&image->region, irb->mt->region);
214
215 return image;
216 }
217
218 static void
219 intel_destroy_image(__DRIimage *image)
220 {
221 intel_region_release(&image->region);
222 FREE(image);
223 }
224
225 static __DRIimage *
226 intel_create_image(__DRIscreen *screen,
227 int width, int height, int format,
228 unsigned int use,
229 void *loaderPrivate)
230 {
231 __DRIimage *image;
232 struct intel_screen *intelScreen = screen->driverPrivate;
233 uint32_t tiling;
234 int cpp;
235
236 tiling = I915_TILING_X;
237 if (use & __DRI_IMAGE_USE_CURSOR) {
238 if (width != 64 || height != 64)
239 return NULL;
240 tiling = I915_TILING_NONE;
241 }
242
243 image = CALLOC(sizeof *image);
244 if (image == NULL)
245 return NULL;
246
247 switch (format) {
248 case __DRI_IMAGE_FORMAT_RGB565:
249 image->format = MESA_FORMAT_RGB565;
250 image->internal_format = GL_RGB;
251 image->data_type = GL_UNSIGNED_BYTE;
252 break;
253 case __DRI_IMAGE_FORMAT_XRGB8888:
254 image->format = MESA_FORMAT_XRGB8888;
255 image->internal_format = GL_RGB;
256 image->data_type = GL_UNSIGNED_BYTE;
257 break;
258 case __DRI_IMAGE_FORMAT_ARGB8888:
259 image->format = MESA_FORMAT_ARGB8888;
260 image->internal_format = GL_RGBA;
261 image->data_type = GL_UNSIGNED_BYTE;
262 break;
263 case __DRI_IMAGE_FORMAT_ABGR8888:
264 image->format = MESA_FORMAT_RGBA8888_REV;
265 image->internal_format = GL_RGBA;
266 image->data_type = GL_UNSIGNED_BYTE;
267 break;
268 default:
269 free(image);
270 return NULL;
271 }
272
273 image->data = loaderPrivate;
274 cpp = _mesa_get_format_bytes(image->format);
275
276 image->region =
277 intel_region_alloc(intelScreen, tiling,
278 cpp, width, height, true);
279 if (image->region == NULL) {
280 FREE(image);
281 return NULL;
282 }
283
284 return image;
285 }
286
287 static GLboolean
288 intel_query_image(__DRIimage *image, int attrib, int *value)
289 {
290 switch (attrib) {
291 case __DRI_IMAGE_ATTRIB_STRIDE:
292 *value = image->region->pitch * image->region->cpp;
293 return true;
294 case __DRI_IMAGE_ATTRIB_HANDLE:
295 *value = image->region->bo->handle;
296 return true;
297 case __DRI_IMAGE_ATTRIB_NAME:
298 return intel_region_flink(image->region, (uint32_t *) value);
299 default:
300 return false;
301 }
302 }
303
304 static __DRIimage *
305 intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
306 {
307 __DRIimage *image;
308
309 image = CALLOC(sizeof *image);
310 if (image == NULL)
311 return NULL;
312
313 intel_region_reference(&image->region, orig_image->region);
314 if (image->region == NULL) {
315 FREE(image);
316 return NULL;
317 }
318
319 image->internal_format = orig_image->internal_format;
320 image->format = orig_image->format;
321 image->data_type = orig_image->data_type;
322 image->data = loaderPrivate;
323
324 return image;
325 }
326
327 static GLboolean
328 intel_validate_usage(__DRIimage *image, unsigned int use)
329 {
330 if (use & __DRI_IMAGE_USE_CURSOR) {
331 if (image->region->width != 64 || image->region->height != 64)
332 return GL_FALSE;
333 }
334
335 return GL_TRUE;
336 }
337
338 static struct __DRIimageExtensionRec intelImageExtension = {
339 { __DRI_IMAGE, 2 },
340 intel_create_image_from_name,
341 intel_create_image_from_renderbuffer,
342 intel_destroy_image,
343 intel_create_image,
344 intel_query_image,
345 intel_dup_image,
346 intel_validate_usage
347 };
348
349 static const __DRIextension *intelScreenExtensions[] = {
350 &intelTexBufferExtension.base,
351 &intelFlushExtension.base,
352 &intelImageExtension.base,
353 &dri2ConfigQueryExtension.base,
354 NULL
355 };
356
357 static bool
358 intel_get_param(__DRIscreen *psp, int param, int *value)
359 {
360 int ret;
361 struct drm_i915_getparam gp;
362
363 gp.param = param;
364 gp.value = value;
365
366 ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
367 if (ret) {
368 if (ret != -EINVAL)
369 _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
370 return false;
371 }
372
373 return true;
374 }
375
376 static bool
377 intel_get_boolean(__DRIscreen *psp, int param)
378 {
379 int value = 0;
380 return intel_get_param(psp, param, &value) && value;
381 }
382
383 static void
384 nop_callback(GLuint key, void *data, void *userData)
385 {
386 }
387
388 static void
389 intelDestroyScreen(__DRIscreen * sPriv)
390 {
391 struct intel_screen *intelScreen = sPriv->driverPrivate;
392
393 dri_bufmgr_destroy(intelScreen->bufmgr);
394 driDestroyOptionInfo(&intelScreen->optionCache);
395
396 /* Some regions may still have references to them at this point, so
397 * flush the hash table to prevent _mesa_DeleteHashTable() from
398 * complaining about the hash not being empty; */
399 _mesa_HashDeleteAll(intelScreen->named_regions, nop_callback, NULL);
400 _mesa_DeleteHashTable(intelScreen->named_regions);
401
402 FREE(intelScreen);
403 sPriv->driverPrivate = NULL;
404 }
405
406
407 /**
408 * This is called when we need to set up GL rendering to a new X window.
409 */
410 static GLboolean
411 intelCreateBuffer(__DRIscreen * driScrnPriv,
412 __DRIdrawable * driDrawPriv,
413 const struct gl_config * mesaVis, GLboolean isPixmap)
414 {
415 struct intel_renderbuffer *rb;
416 struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate;
417
418 if (isPixmap) {
419 return false; /* not implemented */
420 }
421 else {
422 gl_format rgbFormat;
423
424 struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer);
425
426 if (!fb)
427 return false;
428
429 _mesa_initialize_window_framebuffer(fb, mesaVis);
430
431 if (mesaVis->redBits == 5)
432 rgbFormat = MESA_FORMAT_RGB565;
433 else if (mesaVis->alphaBits == 0)
434 rgbFormat = MESA_FORMAT_XRGB8888;
435 else
436 rgbFormat = MESA_FORMAT_ARGB8888;
437
438 /* setup the hardware-based renderbuffers */
439 rb = intel_create_renderbuffer(rgbFormat);
440 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base);
441
442 if (mesaVis->doubleBufferMode) {
443 rb = intel_create_renderbuffer(rgbFormat);
444 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base);
445 }
446
447 /*
448 * Assert here that the gl_config has an expected depth/stencil bit
449 * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
450 * which constructs the advertised configs.)
451 */
452 if (mesaVis->depthBits == 24) {
453 assert(mesaVis->stencilBits == 8);
454
455 if (screen->hw_has_separate_stencil
456 && screen->dri2_has_hiz != INTEL_DRI2_HAS_HIZ_FALSE) {
457 /*
458 * Request a separate stencil buffer even if we do not yet know if
459 * the screen supports it. (See comments for
460 * enum intel_dri2_has_hiz).
461 */
462 rb = intel_create_renderbuffer(MESA_FORMAT_X8_Z24);
463 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base);
464 rb = intel_create_renderbuffer(MESA_FORMAT_S8);
465 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base);
466 } else {
467 /*
468 * Use combined depth/stencil. Note that the renderbuffer is
469 * attached to two attachment points.
470 */
471 rb = intel_create_renderbuffer(MESA_FORMAT_S8_Z24);
472 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base);
473 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base);
474 }
475 }
476 else if (mesaVis->depthBits == 16) {
477 assert(mesaVis->stencilBits == 0);
478 /* just 16-bit depth buffer, no hw stencil */
479 struct intel_renderbuffer *depthRb
480 = intel_create_renderbuffer(MESA_FORMAT_Z16);
481 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
482 }
483 else {
484 assert(mesaVis->depthBits == 0);
485 assert(mesaVis->stencilBits == 0);
486 }
487
488 /* now add any/all software-based renderbuffers we may need */
489 _swrast_add_soft_renderbuffers(fb,
490 false, /* never sw color */
491 false, /* never sw depth */
492 false, /* never sw stencil */
493 mesaVis->accumRedBits > 0,
494 false, /* never sw alpha */
495 false /* never sw aux */ );
496 driDrawPriv->driverPrivate = fb;
497
498 return true;
499 }
500 }
501
502 static void
503 intelDestroyBuffer(__DRIdrawable * driDrawPriv)
504 {
505 struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
506
507 _mesa_reference_framebuffer(&fb, NULL);
508 }
509
510 /* There are probably better ways to do this, such as an
511 * init-designated function to register chipids and createcontext
512 * functions.
513 */
514 extern bool
515 i830CreateContext(const struct gl_config *mesaVis,
516 __DRIcontext *driContextPriv,
517 void *sharedContextPrivate);
518
519 extern bool
520 i915CreateContext(int api,
521 const struct gl_config *mesaVis,
522 __DRIcontext *driContextPriv,
523 void *sharedContextPrivate);
524 extern bool
525 brwCreateContext(int api,
526 const struct gl_config *mesaVis,
527 __DRIcontext *driContextPriv,
528 void *sharedContextPrivate);
529
530 static GLboolean
531 intelCreateContext(gl_api api,
532 const struct gl_config * mesaVis,
533 __DRIcontext * driContextPriv,
534 unsigned major_version,
535 unsigned minor_version,
536 uint32_t flags,
537 unsigned *error,
538 void *sharedContextPrivate)
539 {
540 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
541 struct intel_screen *intelScreen = sPriv->driverPrivate;
542 bool success = false;
543
544 #ifdef I915
545 if (IS_9XX(intelScreen->deviceID)) {
546 if (!IS_965(intelScreen->deviceID)) {
547 success = i915CreateContext(api, mesaVis, driContextPriv,
548 sharedContextPrivate);
549 }
550 } else {
551 intelScreen->no_vbo = true;
552 success = i830CreateContext(mesaVis, driContextPriv,
553 sharedContextPrivate);
554 }
555 #else
556 if (IS_965(intelScreen->deviceID))
557 success = brwCreateContext(api, mesaVis,
558 driContextPriv,
559 sharedContextPrivate);
560 #endif
561
562 if (success) {
563 struct gl_context *ctx =
564 (struct gl_context *) driContextPriv->driverPrivate;
565
566 _mesa_compute_version(ctx);
567 if (ctx->VersionMajor > major_version
568 || (ctx->VersionMajor == major_version
569 && ctx->VersionMinor >= minor_version)) {
570 *error = __DRI_CTX_ERROR_BAD_VERSION;
571 return true;
572 }
573
574 intelDestroyContext(driContextPriv);
575 } else {
576 *error = __DRI_CTX_ERROR_NO_MEMORY;
577 fprintf(stderr, "Unrecognized deviceID 0x%x\n", intelScreen->deviceID);
578 }
579
580 return false;
581 }
582
583 static bool
584 intel_init_bufmgr(struct intel_screen *intelScreen)
585 {
586 __DRIscreen *spriv = intelScreen->driScrnPriv;
587 int num_fences = 0;
588
589 intelScreen->no_hw = (getenv("INTEL_NO_HW") != NULL ||
590 getenv("INTEL_DEVID_OVERRIDE") != NULL);
591
592 intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
593 if (intelScreen->bufmgr == NULL) {
594 fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
595 __func__, __LINE__);
596 return false;
597 }
598
599 if (!intel_get_param(spriv, I915_PARAM_NUM_FENCES_AVAIL, &num_fences) ||
600 num_fences == 0) {
601 fprintf(stderr, "[%s: %u] Kernel 2.6.29 required.\n", __func__, __LINE__);
602 return false;
603 }
604
605 drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
606
607 intelScreen->named_regions = _mesa_NewHashTable();
608
609 intelScreen->relaxed_relocations = 0;
610 intelScreen->relaxed_relocations |=
611 intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA) << 0;
612
613 return true;
614 }
615
616 /**
617 * Override intel_screen.hw_has_hiz with environment variable INTEL_HIZ.
618 *
619 * Valid values for INTEL_HIZ are "0" and "1". If an invalid valid value is
620 * encountered, a warning is emitted and INTEL_HIZ is ignored.
621 */
622 static void
623 intel_override_hiz(struct intel_screen *intel)
624 {
625 const char *s = getenv("INTEL_HIZ");
626 if (!s) {
627 return;
628 } else if (!strncmp("0", s, 2)) {
629 intel->hw_has_hiz = false;
630 } else if (!strncmp("1", s, 2)) {
631 intel->hw_has_hiz = true;
632 } else {
633 fprintf(stderr,
634 "warning: env variable INTEL_HIZ=\"%s\" has invalid value "
635 "and is ignored", s);
636 }
637 }
638
639 /**
640 * Override intel_screen.hw_has_separate_stencil with environment variable
641 * INTEL_SEPARATE_STENCIL.
642 *
643 * Valid values for INTEL_SEPARATE_STENCIL are "0" and "1". If an invalid
644 * valid value is encountered, a warning is emitted and INTEL_SEPARATE_STENCIL
645 * is ignored.
646 */
647 static void
648 intel_override_separate_stencil(struct intel_screen *screen)
649 {
650 const char *s = getenv("INTEL_SEPARATE_STENCIL");
651 if (!s) {
652 return;
653 } else if (!strncmp("0", s, 2)) {
654 screen->hw_has_separate_stencil = false;
655 } else if (!strncmp("1", s, 2)) {
656 screen->hw_has_separate_stencil = true;
657 } else {
658 fprintf(stderr,
659 "warning: env variable INTEL_SEPARATE_STENCIL=\"%s\" has "
660 "invalid value and is ignored", s);
661 }
662 }
663
664 /**
665 * This is the driver specific part of the createNewScreen entry point.
666 * Called when using DRI2.
667 *
668 * \return the struct gl_config supported by this driver
669 */
670 static const
671 __DRIconfig **intelInitScreen2(__DRIscreen *psp)
672 {
673 struct intel_screen *intelScreen;
674 GLenum fb_format[3];
675 GLenum fb_type[3];
676 unsigned int api_mask;
677 char *devid_override;
678
679 static const GLenum back_buffer_modes[] = {
680 GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
681 };
682 uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
683 int color;
684 __DRIconfig **configs = NULL;
685
686 /* Allocate the private area */
687 intelScreen = CALLOC(sizeof *intelScreen);
688 if (!intelScreen) {
689 fprintf(stderr, "\nERROR! Allocating private area failed\n");
690 return false;
691 }
692 /* parse information in __driConfigOptions */
693 driParseOptionInfo(&intelScreen->optionCache,
694 __driConfigOptions, __driNConfigOptions);
695
696 intelScreen->driScrnPriv = psp;
697 psp->driverPrivate = (void *) intelScreen;
698
699 /* Determine chipset ID */
700 if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID,
701 &intelScreen->deviceID))
702 return false;
703
704 /* Allow an override of the device ID for the purpose of making the
705 * driver produce dumps for debugging of new chipset enablement.
706 * This implies INTEL_NO_HW, to avoid programming your actual GPU
707 * incorrectly.
708 */
709 devid_override = getenv("INTEL_DEVID_OVERRIDE");
710 if (devid_override) {
711 intelScreen->deviceID = strtod(devid_override, NULL);
712 }
713
714 intelScreen->kernel_has_gen7_sol_reset =
715 intel_get_boolean(intelScreen->driScrnPriv,
716 I915_PARAM_HAS_GEN7_SOL_RESET);
717
718 if (IS_GEN7(intelScreen->deviceID)) {
719 intelScreen->gen = 7;
720 } else if (IS_GEN6(intelScreen->deviceID)) {
721 intelScreen->gen = 6;
722 } else if (IS_GEN5(intelScreen->deviceID)) {
723 intelScreen->gen = 5;
724 } else if (IS_965(intelScreen->deviceID)) {
725 intelScreen->gen = 4;
726 } else if (IS_9XX(intelScreen->deviceID)) {
727 intelScreen->gen = 3;
728 } else {
729 intelScreen->gen = 2;
730 }
731
732 intelScreen->hw_has_separate_stencil = intelScreen->gen >= 6;
733 intelScreen->hw_must_use_separate_stencil = intelScreen->gen >= 7;
734 intelScreen->hw_has_hiz = intelScreen->gen >= 6;
735 intelScreen->dri2_has_hiz = INTEL_DRI2_HAS_HIZ_UNKNOWN;
736
737 intel_override_hiz(intelScreen);
738 intel_override_separate_stencil(intelScreen);
739
740 api_mask = (1 << __DRI_API_OPENGL);
741 #if FEATURE_ES1
742 api_mask |= (1 << __DRI_API_GLES);
743 #endif
744 #if FEATURE_ES2
745 api_mask |= (1 << __DRI_API_GLES2);
746 #endif
747
748 if (IS_9XX(intelScreen->deviceID) || IS_965(intelScreen->deviceID))
749 psp->api_mask = api_mask;
750
751 if (!intel_init_bufmgr(intelScreen))
752 return false;
753
754 psp->extensions = intelScreenExtensions;
755
756 msaa_samples_array[0] = 0;
757
758 fb_format[0] = GL_RGB;
759 fb_type[0] = GL_UNSIGNED_SHORT_5_6_5;
760
761 fb_format[1] = GL_BGR;
762 fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV;
763
764 fb_format[2] = GL_BGRA;
765 fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV;
766
767 depth_bits[0] = 0;
768 stencil_bits[0] = 0;
769
770 /* Generate a rich set of useful configs that do not include an
771 * accumulation buffer.
772 */
773 for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
774 __DRIconfig **new_configs;
775 int depth_factor;
776
777 /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
778 * buffer that has a diffferent number of bits per pixel than the color
779 * buffer. This isn't yet supported here.
780 */
781 if (fb_type[color] == GL_UNSIGNED_SHORT_5_6_5) {
782 depth_bits[1] = 16;
783 stencil_bits[1] = 0;
784 } else {
785 depth_bits[1] = 24;
786 stencil_bits[1] = 8;
787 }
788
789 depth_factor = 2;
790
791 new_configs = driCreateConfigs(fb_format[color], fb_type[color],
792 depth_bits,
793 stencil_bits,
794 depth_factor,
795 back_buffer_modes,
796 ARRAY_SIZE(back_buffer_modes),
797 msaa_samples_array,
798 ARRAY_SIZE(msaa_samples_array),
799 false);
800 if (configs == NULL)
801 configs = new_configs;
802 else
803 configs = driConcatConfigs(configs, new_configs);
804 }
805
806 /* Generate the minimum possible set of configs that include an
807 * accumulation buffer.
808 */
809 for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
810 __DRIconfig **new_configs;
811
812 if (fb_type[color] == GL_UNSIGNED_SHORT_5_6_5) {
813 depth_bits[0] = 16;
814 stencil_bits[0] = 0;
815 } else {
816 depth_bits[0] = 24;
817 stencil_bits[0] = 8;
818 }
819
820 new_configs = driCreateConfigs(fb_format[color], fb_type[color],
821 depth_bits, stencil_bits, 1,
822 back_buffer_modes + 1, 1,
823 msaa_samples_array, 1,
824 true);
825 if (configs == NULL)
826 configs = new_configs;
827 else
828 configs = driConcatConfigs(configs, new_configs);
829 }
830
831 if (configs == NULL) {
832 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
833 __LINE__);
834 return NULL;
835 }
836
837 return (const __DRIconfig **)configs;
838 }
839
840 struct intel_buffer {
841 __DRIbuffer base;
842 struct intel_region *region;
843 };
844
845 /**
846 * \brief Get tiling format for a DRI buffer.
847 *
848 * \param attachment is the buffer's attachmet point, such as
849 * __DRI_BUFFER_DEPTH.
850 * \param out_tiling is the returned tiling format for buffer.
851 * \return false if attachment is unrecognized or is incompatible with screen.
852 */
853 static bool
854 intel_get_dri_buffer_tiling(struct intel_screen *screen,
855 uint32_t attachment,
856 uint32_t *out_tiling)
857 {
858 if (screen->gen < 4) {
859 *out_tiling = I915_TILING_X;
860 return true;
861 }
862
863 switch (attachment) {
864 case __DRI_BUFFER_DEPTH:
865 case __DRI_BUFFER_DEPTH_STENCIL:
866 case __DRI_BUFFER_HIZ:
867 *out_tiling = I915_TILING_Y;
868 return true;
869 case __DRI_BUFFER_ACCUM:
870 case __DRI_BUFFER_FRONT_LEFT:
871 case __DRI_BUFFER_FRONT_RIGHT:
872 case __DRI_BUFFER_BACK_LEFT:
873 case __DRI_BUFFER_BACK_RIGHT:
874 case __DRI_BUFFER_FAKE_FRONT_LEFT:
875 case __DRI_BUFFER_FAKE_FRONT_RIGHT:
876 *out_tiling = I915_TILING_X;
877 return true;
878 case __DRI_BUFFER_STENCIL:
879 /* The stencil buffer is W tiled. However, we request from the kernel
880 * a non-tiled buffer because the GTT is incapable of W fencing.
881 */
882 *out_tiling = I915_TILING_NONE;
883 return true;
884 default:
885 if(unlikely(INTEL_DEBUG & DEBUG_DRI)) {
886 fprintf(stderr, "error: %s: unrecognized DRI buffer attachment 0x%x\n",
887 __FUNCTION__, attachment);
888 }
889 return false;
890 }
891 }
892
893 static __DRIbuffer *
894 intelAllocateBuffer(__DRIscreen *screen,
895 unsigned attachment, unsigned format,
896 int width, int height)
897 {
898 struct intel_buffer *intelBuffer;
899 struct intel_screen *intelScreen = screen->driverPrivate;
900
901 uint32_t tiling;
902 uint32_t region_width;
903 uint32_t region_height;
904 uint32_t region_cpp;
905
906 bool ok = true;
907
908 ok = intel_get_dri_buffer_tiling(intelScreen, attachment, &tiling);
909 if (!ok)
910 return NULL;
911
912 intelBuffer = CALLOC(sizeof *intelBuffer);
913 if (intelBuffer == NULL)
914 return NULL;
915
916 if (attachment == __DRI_BUFFER_STENCIL) {
917 /* The stencil buffer has quirky pitch requirements. From Vol 2a,
918 * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
919 * The pitch must be set to 2x the value computed based on width, as
920 * the stencil buffer is stored with two rows interleaved.
921 * To accomplish this, we resort to the nasty hack of doubling the
922 * region's cpp and halving its height.
923 */
924 region_width = ALIGN(width, 64);
925 region_height = ALIGN(ALIGN(height, 2) / 2, 64);
926 region_cpp = format / 4;
927 } else {
928 region_width = width;
929 region_height = height;
930 region_cpp = format / 8;
931 }
932
933 intelBuffer->region = intel_region_alloc(intelScreen,
934 tiling,
935 region_cpp,
936 region_width,
937 region_height,
938 true);
939
940 if (intelBuffer->region == NULL) {
941 FREE(intelBuffer);
942 return NULL;
943 }
944
945 intel_region_flink(intelBuffer->region, &intelBuffer->base.name);
946
947 intelBuffer->base.attachment = attachment;
948 intelBuffer->base.cpp = intelBuffer->region->cpp;
949 intelBuffer->base.pitch =
950 intelBuffer->region->pitch * intelBuffer->region->cpp;
951
952 return &intelBuffer->base;
953 }
954
955 static void
956 intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
957 {
958 struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
959
960 intel_region_release(&intelBuffer->region);
961 free(intelBuffer);
962 }
963
964
965 const struct __DriverAPIRec driDriverAPI = {
966 .InitScreen = intelInitScreen2,
967 .DestroyScreen = intelDestroyScreen,
968 .CreateContext = intelCreateContext,
969 .DestroyContext = intelDestroyContext,
970 .CreateBuffer = intelCreateBuffer,
971 .DestroyBuffer = intelDestroyBuffer,
972 .MakeCurrent = intelMakeCurrent,
973 .UnbindContext = intelUnbindContext,
974 .AllocateBuffer = intelAllocateBuffer,
975 .ReleaseBuffer = intelReleaseBuffer
976 };
977
978 /* This is the table of extensions that the loader will dlsym() for. */
979 PUBLIC const __DRIextension *__driDriverExtensions[] = {
980 &driCoreExtension.base,
981 &driDRI2Extension.base,
982 NULL
983 };