1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
30 #include "framebuffer.h"
32 #include "renderbuffer.h"
33 #include "simple_list.h"
39 #include "intel_screen.h"
41 #include "intel_buffers.h"
42 #include "intel_tex.h"
43 #include "intel_span.h"
44 #include "intel_ioctl.h"
45 #include "intel_fbo.h"
46 #include "intel_chipset.h"
50 #include "intel_regions.h"
51 #include "intel_batchbuffer.h"
52 #include "intel_bufmgr_ttm.h"
54 PUBLIC
const char __driConfigOptions
[] =
56 DRI_CONF_SECTION_PERFORMANCE
57 DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS
)
58 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0
)
60 DRI_CONF_SECTION_QUALITY
61 DRI_CONF_FORCE_S3TC_ENABLE(false)
62 DRI_CONF_ALLOW_LARGE_TEXTURES(1)
64 DRI_CONF_SECTION_DEBUG
65 DRI_CONF_NO_RAST(false)
69 const GLuint __driNConfigOptions
= 5;
71 #ifdef USE_NEW_INTERFACE
72 static PFNGLXCREATECONTEXTMODES create_context_modes
= NULL
;
73 #endif /*USE_NEW_INTERFACE */
76 * Map all the memory regions described by the screen.
77 * \return GL_TRUE if success, GL_FALSE if error.
80 intelMapScreenRegions(__DRIscreenPrivate
* sPriv
)
82 intelScreenPrivate
*intelScreen
= (intelScreenPrivate
*) sPriv
->private;
84 if (intelScreen
->front
.handle
) {
86 intelScreen
->front
.handle
,
87 intelScreen
->front
.size
,
88 (drmAddress
*) & intelScreen
->front
.map
) != 0) {
89 _mesa_problem(NULL
, "drmMap(frontbuffer) failed!");
94 _mesa_warning(NULL
, "no front buffer handle in intelMapScreenRegions!");
98 _mesa_printf("Back 0x%08x ", intelScreen
->back
.handle
);
100 intelScreen
->back
.handle
,
101 intelScreen
->back
.size
,
102 (drmAddress
*) & intelScreen
->back
.map
) != 0) {
103 intelUnmapScreenRegions(intelScreen
);
107 if (intelScreen
->third
.handle
) {
109 _mesa_printf("Third 0x%08x ", intelScreen
->third
.handle
);
110 if (drmMap(sPriv
->fd
,
111 intelScreen
->third
.handle
,
112 intelScreen
->third
.size
,
113 (drmAddress
*) & intelScreen
->third
.map
) != 0) {
114 intelUnmapScreenRegions(intelScreen
);
120 _mesa_printf("Depth 0x%08x ", intelScreen
->depth
.handle
);
121 if (drmMap(sPriv
->fd
,
122 intelScreen
->depth
.handle
,
123 intelScreen
->depth
.size
,
124 (drmAddress
*) & intelScreen
->depth
.map
) != 0) {
125 intelUnmapScreenRegions(intelScreen
);
130 _mesa_printf("TEX 0x%08x ", intelScreen
->tex
.handle
);
131 if (intelScreen
->tex
.size
!= 0) {
132 if (drmMap(sPriv
->fd
,
133 intelScreen
->tex
.handle
,
134 intelScreen
->tex
.size
,
135 (drmAddress
*) & intelScreen
->tex
.map
) != 0) {
136 intelUnmapScreenRegions(intelScreen
);
142 printf("Mappings: front: %p back: %p third: %p depth: %p tex: %p\n",
143 intelScreen
->front
.map
,
144 intelScreen
->back
.map
, intelScreen
->third
.map
,
145 intelScreen
->depth
.map
, intelScreen
->tex
.map
);
150 intelUnmapScreenRegions(intelScreenPrivate
* intelScreen
)
152 #define REALLY_UNMAP 1
153 if (intelScreen
->front
.map
) {
155 if (drmUnmap(intelScreen
->front
.map
, intelScreen
->front
.size
) != 0)
156 printf("drmUnmap front failed!\n");
158 intelScreen
->front
.map
= NULL
;
160 if (intelScreen
->back
.map
) {
162 if (drmUnmap(intelScreen
->back
.map
, intelScreen
->back
.size
) != 0)
163 printf("drmUnmap back failed!\n");
165 intelScreen
->back
.map
= NULL
;
167 if (intelScreen
->third
.map
) {
169 if (drmUnmap(intelScreen
->third
.map
, intelScreen
->third
.size
) != 0)
170 printf("drmUnmap third failed!\n");
172 intelScreen
->third
.map
= NULL
;
174 if (intelScreen
->depth
.map
) {
176 drmUnmap(intelScreen
->depth
.map
, intelScreen
->depth
.size
);
177 intelScreen
->depth
.map
= NULL
;
180 if (intelScreen
->tex
.map
) {
182 drmUnmap(intelScreen
->tex
.map
, intelScreen
->tex
.size
);
183 intelScreen
->tex
.map
= NULL
;
190 intelPrintDRIInfo(intelScreenPrivate
* intelScreen
,
191 __DRIscreenPrivate
* sPriv
, I830DRIPtr gDRIPriv
)
193 fprintf(stderr
, "*** Front size: 0x%x offset: 0x%x pitch: %d\n",
194 intelScreen
->front
.size
, intelScreen
->front
.offset
,
196 fprintf(stderr
, "*** Back size: 0x%x offset: 0x%x pitch: %d\n",
197 intelScreen
->back
.size
, intelScreen
->back
.offset
,
199 fprintf(stderr
, "*** Depth size: 0x%x offset: 0x%x pitch: %d\n",
200 intelScreen
->depth
.size
, intelScreen
->depth
.offset
,
202 fprintf(stderr
, "*** Texture size: 0x%x offset: 0x%x\n",
203 intelScreen
->tex
.size
, intelScreen
->tex
.offset
);
204 fprintf(stderr
, "*** Memory : 0x%x\n", gDRIPriv
->mem
);
209 intelPrintSAREA(const struct drm_i915_sarea
* sarea
)
211 fprintf(stderr
, "SAREA: sarea width %d height %d\n", sarea
->width
,
213 fprintf(stderr
, "SAREA: pitch: %d\n", sarea
->pitch
);
215 "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n",
216 sarea
->front_offset
, sarea
->front_size
,
217 (unsigned) sarea
->front_handle
);
219 "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n",
220 sarea
->back_offset
, sarea
->back_size
,
221 (unsigned) sarea
->back_handle
);
222 fprintf(stderr
, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n",
223 sarea
->depth_offset
, sarea
->depth_size
,
224 (unsigned) sarea
->depth_handle
);
225 fprintf(stderr
, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n",
226 sarea
->tex_offset
, sarea
->tex_size
, (unsigned) sarea
->tex_handle
);
231 * A number of the screen parameters are obtained/computed from
232 * information in the SAREA. This function updates those parameters.
235 intelUpdateScreenFromSAREA(intelScreenPrivate
* intelScreen
,
236 struct drm_i915_sarea
* sarea
)
238 intelScreen
->width
= sarea
->width
;
239 intelScreen
->height
= sarea
->height
;
240 intelScreen
->pitch
= sarea
->pitch
;
242 intelScreen
->front
.offset
= sarea
->front_offset
;
243 intelScreen
->front
.handle
= sarea
->front_handle
;
244 intelScreen
->front
.size
= sarea
->front_size
;
245 intelScreen
->front
.tiled
= sarea
->front_tiled
;
247 intelScreen
->back
.offset
= sarea
->back_offset
;
248 intelScreen
->back
.handle
= sarea
->back_handle
;
249 intelScreen
->back
.size
= sarea
->back_size
;
250 intelScreen
->back
.tiled
= sarea
->back_tiled
;
252 if (intelScreen
->driScrnPriv
->ddx_version
.minor
>= 8) {
253 intelScreen
->third
.offset
= sarea
->third_offset
;
254 intelScreen
->third
.handle
= sarea
->third_handle
;
255 intelScreen
->third
.size
= sarea
->third_size
;
256 intelScreen
->third
.tiled
= sarea
->third_tiled
;
259 intelScreen
->depth
.offset
= sarea
->depth_offset
;
260 intelScreen
->depth
.handle
= sarea
->depth_handle
;
261 intelScreen
->depth
.size
= sarea
->depth_size
;
262 intelScreen
->depth
.tiled
= sarea
->depth_tiled
;
264 if (intelScreen
->driScrnPriv
->ddx_version
.minor
>= 9) {
265 intelScreen
->front
.bo_handle
= sarea
->front_bo_handle
;
266 intelScreen
->back
.bo_handle
= sarea
->back_bo_handle
;
267 intelScreen
->third
.bo_handle
= sarea
->third_bo_handle
;
268 intelScreen
->depth
.bo_handle
= sarea
->depth_bo_handle
;
270 intelScreen
->front
.bo_handle
= -1;
271 intelScreen
->back
.bo_handle
= -1;
272 intelScreen
->third
.bo_handle
= -1;
273 intelScreen
->depth
.bo_handle
= -1;
276 intelScreen
->tex
.offset
= sarea
->tex_offset
;
277 intelScreen
->logTextureGranularity
= sarea
->log_tex_granularity
;
278 intelScreen
->tex
.handle
= sarea
->tex_handle
;
279 intelScreen
->tex
.size
= sarea
->tex_size
;
282 intelPrintSAREA(sarea
);
286 intelHandleDrawableConfig(__DRIdrawablePrivate
*dPriv
,
287 __DRIDrawableConfigEvent
*event
)
289 struct intel_framebuffer
*intel_fb
= dPriv
->driverPrivate
;
290 struct intel_region
*region
= NULL
;
291 struct intel_renderbuffer
*rb
, *depth_rb
, *stencil_rb
;
292 struct intel_context
*intel
= dPriv
->driContextPriv
->driverPrivate
;
293 int cpp
= intel
->ctx
.Visual
.rgbBits
/ 8;
294 GLuint pitch
= ((cpp
* dPriv
->w
+ 63) & ~63) / cpp
;
296 rb
= intel_fb
->color_rb
[1];
298 region
= intel_region_alloc(intel
, cpp
, pitch
, dPriv
->h
);
299 intel_renderbuffer_set_region(rb
, region
);
302 rb
= intel_fb
->color_rb
[2];
304 region
= intel_region_alloc(intel
, cpp
, pitch
, dPriv
->h
);
305 intel_renderbuffer_set_region(rb
, region
);
308 depth_rb
= intel_get_renderbuffer(&intel_fb
->Base
, BUFFER_DEPTH
);
309 stencil_rb
= intel_get_renderbuffer(&intel_fb
->Base
, BUFFER_STENCIL
);
310 if (depth_rb
|| stencil_rb
)
311 region
= intel_region_alloc(intel
, cpp
, pitch
, dPriv
->h
);
313 intel_renderbuffer_set_region(depth_rb
, region
);
315 intel_renderbuffer_set_region(stencil_rb
, region
);
317 /* FIXME: Tell the X server about the regions we just allocated and
321 #define BUFFER_FLAG_TILED 0x0100
324 intelHandleBufferAttach(__DRIdrawablePrivate
*dPriv
,
325 __DRIBufferAttachEvent
*ba
)
327 struct intel_framebuffer
*intel_fb
= dPriv
->driverPrivate
;
328 struct intel_renderbuffer
*rb
;
329 struct intel_region
*region
;
330 struct intel_context
*intel
= dPriv
->driContextPriv
->driverPrivate
;
333 switch (ba
->buffer
.attachment
) {
334 case DRI_DRAWABLE_BUFFER_FRONT_LEFT
:
335 rb
= intel_fb
->color_rb
[0];
338 case DRI_DRAWABLE_BUFFER_BACK_LEFT
:
339 rb
= intel_fb
->color_rb
[0];
342 case DRI_DRAWABLE_BUFFER_DEPTH
:
343 rb
= intel_get_renderbuffer(&intel_fb
->Base
, BUFFER_DEPTH
);
346 case DRI_DRAWABLE_BUFFER_STENCIL
:
347 rb
= intel_get_renderbuffer(&intel_fb
->Base
, BUFFER_STENCIL
);
350 case DRI_DRAWABLE_BUFFER_ACCUM
:
352 fprintf(stderr
, "unhandled buffer attach event, attacment type %d\n",
353 ba
->buffer
.attachment
);
358 /* FIXME: Add this so we can filter out when the X server sends us
359 * attachment events for the buffers we just allocated. Need to
360 * get the BO handle for a render buffer. */
361 if (intel_renderbuffer_get_region_handle(rb
) == ba
->buffer
.handle
)
365 tiled
= (ba
->buffer
.flags
& BUFFER_FLAG_TILED
) > 0;
366 region
= intel_region_alloc_for_handle(intel
, ba
->buffer
.cpp
,
367 ba
->buffer
.pitch
/ ba
->buffer
.cpp
,
371 intel_renderbuffer_set_region(rb
, region
);
375 intelUpdateBuffer(__DRIdrawablePrivate
*dPriv
, unsigned int *event
)
377 switch (DRI2_EVENT_TYPE(*event
)) {
378 case DRI2_EVENT_DRAWABLE_CONFIG
:
379 /* flush all current regions, allocate new ones, except front buffer */
380 intelHandleDrawableConfig(dPriv
, (__DRIDrawableConfigEvent
*) event
);
383 case DRI2_EVENT_BUFFER_ATTACH
:
384 /* attach buffer if different from what we have */
385 intelHandleBufferAttach(dPriv
, (__DRIBufferAttachEvent
*) event
);
390 static const __DRItexOffsetExtension intelTexOffsetExtension
= {
391 { __DRI_TEX_OFFSET
},
395 static const __DRItexBufferExtension intelTexBufferExtension
= {
396 { __DRI_TEX_BUFFER
, __DRI_TEX_BUFFER_VERSION
},
400 static const __DRIextension
*intelExtensions
[] = {
401 &driReadDrawableExtension
,
402 &driCopySubBufferExtension
.base
,
403 &driSwapControlExtension
.base
,
404 &driFrameTrackingExtension
.base
,
405 &driMediaStreamCounterExtension
.base
,
406 &intelTexOffsetExtension
.base
,
407 &intelTexBufferExtension
.base
,
412 intel_get_param(__DRIscreenPrivate
*psp
, int param
, int *value
)
415 struct drm_i915_getparam gp
;
420 ret
= drmCommandWriteRead(psp
->fd
, DRM_I915_GETPARAM
, &gp
, sizeof(gp
));
422 fprintf(stderr
, "drm_i915_getparam: %d\n", ret
);
429 static GLboolean
intelInitDriver(__DRIscreenPrivate
*sPriv
)
431 intelScreenPrivate
*intelScreen
;
432 I830DRIPtr gDRIPriv
= (I830DRIPtr
) sPriv
->pDevPriv
;
433 struct drm_i915_sarea
*sarea
;
435 if (sPriv
->devPrivSize
!= sizeof(I830DRIRec
)) {
437 "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n");
441 /* Allocate the private area */
442 intelScreen
= (intelScreenPrivate
*) CALLOC(sizeof(intelScreenPrivate
));
444 fprintf(stderr
, "\nERROR! Allocating private area failed\n");
447 /* parse information in __driConfigOptions */
448 driParseOptionInfo(&intelScreen
->optionCache
,
449 __driConfigOptions
, __driNConfigOptions
);
451 intelScreen
->driScrnPriv
= sPriv
;
452 sPriv
->private = (void *) intelScreen
;
453 intelScreen
->sarea_priv_offset
= gDRIPriv
->sarea_priv_offset
;
454 sarea
= (struct drm_i915_sarea
*)
455 (((GLubyte
*) sPriv
->pSAREA
) + intelScreen
->sarea_priv_offset
);
457 intelScreen
->deviceID
= gDRIPriv
->deviceID
;
459 intelUpdateScreenFromSAREA(intelScreen
, sarea
);
461 if (!intelMapScreenRegions(sPriv
)) {
462 fprintf(stderr
, "\nERROR! mapping regions\n");
463 _mesa_free(intelScreen
);
464 sPriv
->private = NULL
;
468 intelScreen
->sarea_priv_offset
= gDRIPriv
->sarea_priv_offset
;
471 intelPrintDRIInfo(intelScreen
, sPriv
, gDRIPriv
);
473 intelScreen
->drmMinor
= sPriv
->drm_version
.minor
;
475 /* Determine if IRQs are active? */
476 if (!intel_get_param(sPriv
, I915_PARAM_IRQ_ACTIVE
,
477 &intelScreen
->irq_active
))
480 /* Determine if batchbuffers are allowed */
481 if (!intel_get_param(sPriv
, I915_PARAM_ALLOW_BATCHBUFFER
,
482 &intelScreen
->allow_batchbuffer
))
485 sPriv
->extensions
= intelExtensions
;
492 intelDestroyScreen(__DRIscreenPrivate
* sPriv
)
494 intelScreenPrivate
*intelScreen
= (intelScreenPrivate
*) sPriv
->private;
496 intelUnmapScreenRegions(intelScreen
);
499 sPriv
->private = NULL
;
504 * This is called when we need to set up GL rendering to a new X window.
507 intelCreateBuffer(__DRIscreenPrivate
* driScrnPriv
,
508 __DRIdrawablePrivate
* driDrawPriv
,
509 const __GLcontextModes
* mesaVis
, GLboolean isPixmap
)
511 intelScreenPrivate
*screen
= (intelScreenPrivate
*) driScrnPriv
->private;
514 return GL_FALSE
; /* not implemented */
517 GLboolean swStencil
= (mesaVis
->stencilBits
> 0 &&
518 mesaVis
->depthBits
!= 24);
519 GLenum rgbFormat
= (mesaVis
->redBits
== 5 ? GL_RGB5
: GL_RGBA8
);
521 struct intel_framebuffer
*intel_fb
= CALLOC_STRUCT(intel_framebuffer
);
526 _mesa_initialize_framebuffer(&intel_fb
->Base
, mesaVis
);
528 /* setup the hardware-based renderbuffers */
530 intel_fb
->color_rb
[0] = intel_create_renderbuffer(rgbFormat
);
531 _mesa_add_renderbuffer(&intel_fb
->Base
, BUFFER_FRONT_LEFT
,
532 &intel_fb
->color_rb
[0]->Base
);
535 if (mesaVis
->doubleBufferMode
) {
536 intel_fb
->color_rb
[1] = intel_create_renderbuffer(rgbFormat
);
537 _mesa_add_renderbuffer(&intel_fb
->Base
, BUFFER_BACK_LEFT
,
538 &intel_fb
->color_rb
[1]->Base
);
540 if (screen
->third
.handle
) {
541 struct gl_renderbuffer
*tmp_rb
= NULL
;
543 intel_fb
->color_rb
[2] = intel_create_renderbuffer(rgbFormat
);
544 _mesa_reference_renderbuffer(&tmp_rb
, &intel_fb
->color_rb
[2]->Base
);
548 if (mesaVis
->depthBits
== 24) {
549 if (mesaVis
->stencilBits
== 8) {
550 /* combined depth/stencil buffer */
551 struct intel_renderbuffer
*depthStencilRb
552 = intel_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT
);
553 /* note: bind RB to two attachment points */
554 _mesa_add_renderbuffer(&intel_fb
->Base
, BUFFER_DEPTH
,
555 &depthStencilRb
->Base
);
556 _mesa_add_renderbuffer(&intel_fb
->Base
, BUFFER_STENCIL
,
557 &depthStencilRb
->Base
);
559 struct intel_renderbuffer
*depthRb
560 = intel_create_renderbuffer(GL_DEPTH_COMPONENT24
);
561 _mesa_add_renderbuffer(&intel_fb
->Base
, BUFFER_DEPTH
,
565 else if (mesaVis
->depthBits
== 16) {
566 /* just 16-bit depth buffer, no hw stencil */
567 struct intel_renderbuffer
*depthRb
568 = intel_create_renderbuffer(GL_DEPTH_COMPONENT16
);
569 _mesa_add_renderbuffer(&intel_fb
->Base
, BUFFER_DEPTH
, &depthRb
->Base
);
572 /* now add any/all software-based renderbuffers we may need */
573 _mesa_add_soft_renderbuffers(&intel_fb
->Base
,
574 GL_FALSE
, /* never sw color */
575 GL_FALSE
, /* never sw depth */
576 swStencil
, mesaVis
->accumRedBits
> 0,
577 GL_FALSE
, /* never sw alpha */
578 GL_FALSE
/* never sw aux */ );
579 driDrawPriv
->driverPrivate
= (void *) intel_fb
;
586 intelDestroyBuffer(__DRIdrawablePrivate
* driDrawPriv
)
588 _mesa_unreference_framebuffer((GLframebuffer
**)(&(driDrawPriv
->driverPrivate
)));
593 * Get information about previous buffer swaps.
596 intelGetSwapInfo(__DRIdrawablePrivate
* dPriv
, __DRIswapInfo
* sInfo
)
598 struct intel_framebuffer
*intel_fb
;
600 if ((dPriv
== NULL
) || (dPriv
->driverPrivate
== NULL
)
601 || (sInfo
== NULL
)) {
605 intel_fb
= dPriv
->driverPrivate
;
606 sInfo
->swap_count
= intel_fb
->swap_count
;
607 sInfo
->swap_ust
= intel_fb
->swap_ust
;
608 sInfo
->swap_missed_count
= intel_fb
->swap_missed_count
;
610 sInfo
->swap_missed_usage
= (sInfo
->swap_missed_count
!= 0)
611 ? driCalculateSwapUsage(dPriv
, 0, intel_fb
->swap_missed_ust
)
618 /* There are probably better ways to do this, such as an
619 * init-designated function to register chipids and createcontext
622 extern GLboolean
i830CreateContext(const __GLcontextModes
* mesaVis
,
623 __DRIcontextPrivate
* driContextPriv
,
624 void *sharedContextPrivate
);
626 extern GLboolean
i915CreateContext(const __GLcontextModes
* mesaVis
,
627 __DRIcontextPrivate
* driContextPriv
,
628 void *sharedContextPrivate
);
629 extern GLboolean
brwCreateContext(const __GLcontextModes
* mesaVis
,
630 __DRIcontextPrivate
* driContextPriv
,
631 void *sharedContextPrivate
);
634 intelCreateContext(const __GLcontextModes
* mesaVis
,
635 __DRIcontextPrivate
* driContextPriv
,
636 void *sharedContextPrivate
)
638 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
639 intelScreenPrivate
*intelScreen
= (intelScreenPrivate
*) sPriv
->private;
642 if (IS_9XX(intelScreen
->deviceID
)) {
643 if (!IS_965(intelScreen
->deviceID
)) {
644 return i915CreateContext(mesaVis
, driContextPriv
,
645 sharedContextPrivate
);
648 return i830CreateContext(mesaVis
, driContextPriv
, sharedContextPrivate
);
651 if (IS_965(intelScreen
->deviceID
))
652 return brwCreateContext(mesaVis
, driContextPriv
, sharedContextPrivate
);
654 fprintf(stderr
, "Unrecognized deviceID %x\n", intelScreen
->deviceID
);
659 static const struct __DriverAPIRec intelAPI
= {
660 .DestroyScreen
= intelDestroyScreen
,
661 .CreateContext
= intelCreateContext
,
662 .DestroyContext
= intelDestroyContext
,
663 .CreateBuffer
= intelCreateBuffer
,
664 .DestroyBuffer
= intelDestroyBuffer
,
665 .SwapBuffers
= intelSwapBuffers
,
666 .MakeCurrent
= intelMakeCurrent
,
667 .UnbindContext
= intelUnbindContext
,
668 .GetSwapInfo
= intelGetSwapInfo
,
669 .GetDrawableMSC
= driDrawableGetMSC32
,
670 .WaitForMSC
= driWaitForMSC32
,
672 .SwapBuffersMSC
= NULL
,
673 .CopySubBuffer
= intelCopySubBuffer
,
674 .UpdateBuffer
= intelUpdateBuffer
,
678 static __GLcontextModes
*
679 intelFillInModes(__DRIscreenPrivate
*psp
,
680 unsigned pixel_bits
, unsigned depth_bits
,
681 unsigned stencil_bits
, GLboolean have_back_buffer
)
683 __GLcontextModes
*modes
;
686 unsigned depth_buffer_factor
;
687 unsigned back_buffer_factor
;
691 /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
692 * support pageflipping at all.
694 static const GLenum back_buffer_modes
[] = {
695 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
, GLX_SWAP_COPY_OML
698 u_int8_t depth_bits_array
[3];
699 u_int8_t stencil_bits_array
[3];
702 depth_bits_array
[0] = 0;
703 depth_bits_array
[1] = depth_bits
;
704 depth_bits_array
[2] = depth_bits
;
706 /* Just like with the accumulation buffer, always provide some modes
707 * with a stencil buffer. It will be a sw fallback, but some apps won't
710 stencil_bits_array
[0] = 0;
711 stencil_bits_array
[1] = 0;
712 if (depth_bits
== 24)
713 stencil_bits_array
[1] = (stencil_bits
== 0) ? 8 : stencil_bits
;
715 stencil_bits_array
[2] = (stencil_bits
== 0) ? 8 : stencil_bits
;
717 depth_buffer_factor
= ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 3 : 1;
718 back_buffer_factor
= (have_back_buffer
) ? 3 : 1;
720 num_modes
= depth_buffer_factor
* back_buffer_factor
* 4;
722 if (pixel_bits
== 16) {
724 fb_type
= GL_UNSIGNED_SHORT_5_6_5
;
728 fb_type
= GL_UNSIGNED_INT_8_8_8_8_REV
;
732 (*psp
->contextModes
->createContextModes
) (num_modes
,
733 sizeof(__GLcontextModes
));
735 if (!driFillInModes(&m
, fb_format
, fb_type
,
736 depth_bits_array
, stencil_bits_array
,
737 depth_buffer_factor
, back_buffer_modes
,
738 back_buffer_factor
, GLX_TRUE_COLOR
)) {
739 fprintf(stderr
, "[%s:%u] Error creating FBConfig!\n", __func__
,
743 if (!driFillInModes(&m
, fb_format
, fb_type
,
744 depth_bits_array
, stencil_bits_array
,
745 depth_buffer_factor
, back_buffer_modes
,
746 back_buffer_factor
, GLX_DIRECT_COLOR
)) {
747 fprintf(stderr
, "[%s:%u] Error creating FBConfig!\n", __func__
,
752 /* Mark the visual as slow if there are "fake" stencil bits.
754 for (m
= modes
; m
!= NULL
; m
= m
->next
) {
755 if ((m
->stencilBits
!= 0) && (m
->stencilBits
!= stencil_bits
)) {
756 m
->visualRating
= GLX_SLOW_CONFIG
;
765 * This is the driver specific part of the createNewScreen entry point.
767 * \todo maybe fold this into intelInitDriver
769 * \return the __GLcontextModes supported by this driver
771 PUBLIC __GLcontextModes
*__driDriverInitScreen(__DRIscreenPrivate
*psp
)
774 static const __DRIversion ddx_expected
= { 1, 5, 0 };
776 static const __DRIversion ddx_expected
= { 1, 6, 0 };
778 static const __DRIversion dri_expected
= { 4, 0, 0 };
779 static const __DRIversion drm_expected
= { 1, 5, 0 };
780 I830DRIPtr dri_priv
= (I830DRIPtr
) psp
->pDevPriv
;
782 psp
->DriverAPI
= intelAPI
;
784 if (!driCheckDriDdxDrmVersions2("i915",
785 &psp
->dri_version
, &dri_expected
,
786 &psp
->ddx_version
, &ddx_expected
,
787 &psp
->drm_version
, &drm_expected
)) {
791 /* Calling driInitExtensions here, with a NULL context pointer,
792 * does not actually enable the extensions. It just makes sure
793 * that all the dispatch offsets for all the extensions that
794 * *might* be enables are known. This is needed because the
795 * dispatch offsets need to be known when _mesa_context_create is
796 * called, but we can't enable the extensions until we have a
799 * Hello chicken. Hello egg. How are you two today?
801 intelInitExtensions(NULL
, GL_TRUE
);
803 if (!intelInitDriver(psp
))
806 return intelFillInModes(psp
, dri_priv
->cpp
* 8,
807 (dri_priv
->cpp
== 2) ? 16 : 24,
808 (dri_priv
->cpp
== 2) ? 0 : 8, 1);
811 struct intel_context
*intelScreenContext(intelScreenPrivate
*intelScreen
)
814 * This should probably change to have the screen allocate a dummy
815 * context at screen creation. For now just use the current context.
818 GET_CURRENT_CONTEXT(ctx
);
820 _mesa_problem(NULL
, "No current context in intelScreenContext\n");
823 return intel_context(ctx
);
827 * This is the driver specific part of the createNewScreen entry point.
829 * \return the __GLcontextModes supported by this driver
831 PUBLIC __GLcontextModes
*__dri2DriverInitScreen(__DRIscreenPrivate
*psp
)
833 intelScreenPrivate
*intelScreen
;
834 __GLcontextModes
*modes
, *m
;
836 psp
->DriverAPI
= intelAPI
;
838 /* Calling driInitExtensions here, with a NULL context pointer,
839 * does not actually enable the extensions. It just makes sure
840 * that all the dispatch offsets for all the extensions that
841 * *might* be enables are known. This is needed because the
842 * dispatch offsets need to be known when _mesa_context_create is
843 * called, but we can't enable the extensions until we have a
846 * Hello chicken. Hello egg. How are you two today?
848 intelInitExtensions(NULL
, GL_TRUE
);
850 /* Allocate the private area */
851 intelScreen
= (intelScreenPrivate
*) CALLOC(sizeof(intelScreenPrivate
));
853 fprintf(stderr
, "\nERROR! Allocating private area failed\n");
856 /* parse information in __driConfigOptions */
857 driParseOptionInfo(&intelScreen
->optionCache
,
858 __driConfigOptions
, __driNConfigOptions
);
860 intelScreen
->driScrnPriv
= psp
;
861 psp
->private = (void *) intelScreen
;
863 intelScreen
->drmMinor
= psp
->drm_version
.minor
;
865 /* Determine chipset ID? */
866 if (!intel_get_param(psp
, I915_PARAM_CHIPSET_ID
,
867 &intelScreen
->deviceID
))
870 /* Determine if IRQs are active? */
871 if (!intel_get_param(psp
, I915_PARAM_IRQ_ACTIVE
,
872 &intelScreen
->irq_active
))
875 /* Determine if batchbuffers are allowed */
876 if (!intel_get_param(psp
, I915_PARAM_ALLOW_BATCHBUFFER
,
877 &intelScreen
->allow_batchbuffer
))
880 if (!intelScreen
->allow_batchbuffer
) {
881 fprintf(stderr
, "batch buffer not allowed\n");
885 psp
->extensions
= intelExtensions
;
887 modes
= intelFillInModes(psp
, 16, 16, 0, 1);
888 for (m
= modes
; m
->next
!= NULL
; m
= m
->next
)
890 m
->next
= intelFillInModes(psp
, 32, 24, 8, 1);