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