intel: include version.h in intel_screen.c to silence warning
[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;
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 if (IS_GEN7(intelScreen->deviceID)) {
701 intelScreen->gen = 7;
702 } else if (IS_GEN6(intelScreen->deviceID)) {
703 intelScreen->gen = 6;
704 } else if (IS_GEN5(intelScreen->deviceID)) {
705 intelScreen->gen = 5;
706 } else if (IS_965(intelScreen->deviceID)) {
707 intelScreen->gen = 4;
708 } else if (IS_9XX(intelScreen->deviceID)) {
709 intelScreen->gen = 3;
710 } else {
711 intelScreen->gen = 2;
712 }
713
714 intelScreen->hw_has_separate_stencil = intelScreen->gen >= 6;
715 intelScreen->hw_must_use_separate_stencil = intelScreen->gen >= 7;
716 intelScreen->hw_has_hiz = intelScreen->gen == 6; /* Not yet for gen7. */
717 intelScreen->dri2_has_hiz = INTEL_DRI2_HAS_HIZ_UNKNOWN;
718
719 intel_override_hiz(intelScreen);
720 intel_override_separate_stencil(intelScreen);
721
722 api_mask = (1 << __DRI_API_OPENGL);
723 #if FEATURE_ES1
724 api_mask |= (1 << __DRI_API_GLES);
725 #endif
726 #if FEATURE_ES2
727 api_mask |= (1 << __DRI_API_GLES2);
728 #endif
729
730 if (IS_9XX(intelScreen->deviceID) || IS_965(intelScreen->deviceID))
731 psp->api_mask = api_mask;
732
733 if (!intel_init_bufmgr(intelScreen))
734 return false;
735
736 psp->extensions = intelScreenExtensions;
737
738 msaa_samples_array[0] = 0;
739
740 fb_format[0] = GL_RGB;
741 fb_type[0] = GL_UNSIGNED_SHORT_5_6_5;
742
743 fb_format[1] = GL_BGR;
744 fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV;
745
746 fb_format[2] = GL_BGRA;
747 fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV;
748
749 depth_bits[0] = 0;
750 stencil_bits[0] = 0;
751
752 /* Generate a rich set of useful configs that do not include an
753 * accumulation buffer.
754 */
755 for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
756 __DRIconfig **new_configs;
757 int depth_factor;
758
759 /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
760 * buffer that has a diffferent number of bits per pixel than the color
761 * buffer. This isn't yet supported here.
762 */
763 if (fb_type[color] == GL_UNSIGNED_SHORT_5_6_5) {
764 depth_bits[1] = 16;
765 stencil_bits[1] = 0;
766 } else {
767 depth_bits[1] = 24;
768 stencil_bits[1] = 8;
769 }
770
771 depth_factor = 2;
772
773 new_configs = driCreateConfigs(fb_format[color], fb_type[color],
774 depth_bits,
775 stencil_bits,
776 depth_factor,
777 back_buffer_modes,
778 ARRAY_SIZE(back_buffer_modes),
779 msaa_samples_array,
780 ARRAY_SIZE(msaa_samples_array),
781 false);
782 if (configs == NULL)
783 configs = new_configs;
784 else
785 configs = driConcatConfigs(configs, new_configs);
786 }
787
788 /* Generate the minimum possible set of configs that include an
789 * accumulation buffer.
790 */
791 for (color = 0; color < ARRAY_SIZE(fb_format); color++) {
792 __DRIconfig **new_configs;
793
794 if (fb_type[color] == GL_UNSIGNED_SHORT_5_6_5) {
795 depth_bits[0] = 16;
796 stencil_bits[0] = 0;
797 } else {
798 depth_bits[0] = 24;
799 stencil_bits[0] = 8;
800 }
801
802 new_configs = driCreateConfigs(fb_format[color], fb_type[color],
803 depth_bits, stencil_bits, 1,
804 back_buffer_modes + 1, 1,
805 msaa_samples_array, 1,
806 true);
807 if (configs == NULL)
808 configs = new_configs;
809 else
810 configs = driConcatConfigs(configs, new_configs);
811 }
812
813 if (configs == NULL) {
814 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
815 __LINE__);
816 return NULL;
817 }
818
819 return (const __DRIconfig **)configs;
820 }
821
822 struct intel_buffer {
823 __DRIbuffer base;
824 struct intel_region *region;
825 };
826
827 /**
828 * \brief Get tiling format for a DRI buffer.
829 *
830 * \param attachment is the buffer's attachmet point, such as
831 * __DRI_BUFFER_DEPTH.
832 * \param out_tiling is the returned tiling format for buffer.
833 * \return false if attachment is unrecognized or is incompatible with screen.
834 */
835 static bool
836 intel_get_dri_buffer_tiling(struct intel_screen *screen,
837 uint32_t attachment,
838 uint32_t *out_tiling)
839 {
840 if (screen->gen < 4) {
841 *out_tiling = I915_TILING_X;
842 return true;
843 }
844
845 switch (attachment) {
846 case __DRI_BUFFER_DEPTH:
847 case __DRI_BUFFER_DEPTH_STENCIL:
848 case __DRI_BUFFER_HIZ:
849 *out_tiling = I915_TILING_Y;
850 return true;
851 case __DRI_BUFFER_ACCUM:
852 case __DRI_BUFFER_FRONT_LEFT:
853 case __DRI_BUFFER_FRONT_RIGHT:
854 case __DRI_BUFFER_BACK_LEFT:
855 case __DRI_BUFFER_BACK_RIGHT:
856 case __DRI_BUFFER_FAKE_FRONT_LEFT:
857 case __DRI_BUFFER_FAKE_FRONT_RIGHT:
858 *out_tiling = I915_TILING_X;
859 return true;
860 case __DRI_BUFFER_STENCIL:
861 /* The stencil buffer is W tiled. However, we request from the kernel
862 * a non-tiled buffer because the GTT is incapable of W fencing.
863 */
864 *out_tiling = I915_TILING_NONE;
865 return true;
866 default:
867 if(unlikely(INTEL_DEBUG & DEBUG_DRI)) {
868 fprintf(stderr, "error: %s: unrecognized DRI buffer attachment 0x%x\n",
869 __FUNCTION__, attachment);
870 }
871 return false;
872 }
873 }
874
875 static __DRIbuffer *
876 intelAllocateBuffer(__DRIscreen *screen,
877 unsigned attachment, unsigned format,
878 int width, int height)
879 {
880 struct intel_buffer *intelBuffer;
881 struct intel_screen *intelScreen = screen->driverPrivate;
882
883 uint32_t tiling;
884 uint32_t region_width;
885 uint32_t region_height;
886 uint32_t region_cpp;
887
888 bool ok = true;
889
890 ok = intel_get_dri_buffer_tiling(intelScreen, attachment, &tiling);
891 if (!ok)
892 return NULL;
893
894 intelBuffer = CALLOC(sizeof *intelBuffer);
895 if (intelBuffer == NULL)
896 return NULL;
897
898 if (attachment == __DRI_BUFFER_STENCIL) {
899 /* The stencil buffer has quirky pitch requirements. From Vol 2a,
900 * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
901 * The pitch must be set to 2x the value computed based on width, as
902 * the stencil buffer is stored with two rows interleaved.
903 * To accomplish this, we resort to the nasty hack of doubling the
904 * region's cpp and halving its height.
905 */
906 region_width = ALIGN(width, 64);
907 region_height = ALIGN(ALIGN(height, 2) / 2, 64);
908 region_cpp = format / 4;
909 } else {
910 region_width = width;
911 region_height = height;
912 region_cpp = format / 8;
913 }
914
915 intelBuffer->region = intel_region_alloc(intelScreen,
916 tiling,
917 region_cpp,
918 region_width,
919 region_height,
920 true);
921
922 if (intelBuffer->region == NULL) {
923 FREE(intelBuffer);
924 return NULL;
925 }
926
927 intel_region_flink(intelBuffer->region, &intelBuffer->base.name);
928
929 intelBuffer->base.attachment = attachment;
930 intelBuffer->base.cpp = intelBuffer->region->cpp;
931 intelBuffer->base.pitch =
932 intelBuffer->region->pitch * intelBuffer->region->cpp;
933
934 return &intelBuffer->base;
935 }
936
937 static void
938 intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
939 {
940 struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
941
942 intel_region_release(&intelBuffer->region);
943 free(intelBuffer);
944 }
945
946
947 const struct __DriverAPIRec driDriverAPI = {
948 .InitScreen = intelInitScreen2,
949 .DestroyScreen = intelDestroyScreen,
950 .CreateContext = intelCreateContext,
951 .DestroyContext = intelDestroyContext,
952 .CreateBuffer = intelCreateBuffer,
953 .DestroyBuffer = intelDestroyBuffer,
954 .MakeCurrent = intelMakeCurrent,
955 .UnbindContext = intelUnbindContext,
956 .AllocateBuffer = intelAllocateBuffer,
957 .ReleaseBuffer = intelReleaseBuffer
958 };
959
960 /* This is the table of extensions that the loader will dlsym() for. */
961 PUBLIC const __DRIextension *__driDriverExtensions[] = {
962 &driCoreExtension.base,
963 &driDRI2Extension.base,
964 NULL
965 };