1 /**************************************************************************
3 Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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 **************************************************************************/
27 /* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810screen.c,v 1.2 2002/10/30 12:51:33 alanh Exp $ */
31 * Keith Whitwell <keith@tungstengraphics.com>
40 #include "simple_list.h"
43 #include "i810screen.h"
46 #include "i810state.h"
50 #include "i810ioctl.h"
52 #include "GL/internal/dri_interface.h"
54 #ifdef USE_NEW_INTERFACE
55 static PFNGLXCREATECONTEXTMODES create_context_modes
= NULL
;
56 #endif /* USE_NEW_INTERFACE */
58 #ifdef USE_NEW_INTERFACE
59 static __GLcontextModes
*fill_in_modes( __GLcontextModes
*modes
,
62 unsigned stencil_bits
,
63 const GLenum
* db_modes
,
64 unsigned num_db_modes
,
67 static const uint8_t bits
[1][4] = {
71 static const uint32_t masks
[1][4] = {
72 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }
77 const unsigned index
= 0;
79 for ( i
= 0 ; i
< num_db_modes
; i
++ ) {
80 for ( j
= 0 ; j
< 2 ; j
++ ) {
82 modes
->redBits
= bits
[index
][0];
83 modes
->greenBits
= bits
[index
][1];
84 modes
->blueBits
= bits
[index
][2];
85 modes
->alphaBits
= bits
[index
][3];
86 modes
->redMask
= masks
[index
][0];
87 modes
->greenMask
= masks
[index
][1];
88 modes
->blueMask
= masks
[index
][2];
89 modes
->alphaMask
= masks
[index
][3];
90 modes
->rgbBits
= modes
->redBits
+ modes
->greenBits
91 + modes
->blueBits
+ modes
->alphaBits
;
93 modes
->accumRedBits
= 16 * j
;
94 modes
->accumGreenBits
= 16 * j
;
95 modes
->accumBlueBits
= 16 * j
;
96 modes
->accumAlphaBits
= (masks
[index
][3] != 0) ? 16 * j
: 0;
97 modes
->visualRating
= (j
== 0) ? GLX_NONE
: GLX_SLOW_CONFIG
;
99 modes
->stencilBits
= stencil_bits
;
100 modes
->depthBits
= depth_bits
;
102 modes
->visualType
= visType
;
103 modes
->renderType
= GLX_RGBA_BIT
;
104 modes
->drawableType
= GLX_WINDOW_BIT
;
105 modes
->rgbMode
= GL_TRUE
;
107 if ( db_modes
[i
] == GLX_NONE
) {
108 modes
->doubleBufferMode
= GL_FALSE
;
111 modes
->doubleBufferMode
= GL_TRUE
;
112 modes
->swapMethod
= db_modes
[i
];
122 #endif /* USE_NEW_INTERFACE */
124 #ifdef USE_NEW_INTERFACE
125 static __GLcontextModes
*
126 i810FillInModes( unsigned pixel_bits
, unsigned depth_bits
,
127 unsigned stencil_bits
, GLboolean have_back_buffer
)
128 { __GLcontextModes
* modes
;
129 __GLcontextModes
* m
;
131 unsigned depth_buffer_factor
;
132 unsigned back_buffer_factor
;
135 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
136 * enough to add support. Basically, if a context is created with an
137 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
138 * will never be used.
140 static const GLenum back_buffer_modes
[] = {
141 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
/*, GLX_SWAP_COPY_OML */
144 int depth_buffer_modes
[2][2];
147 depth_buffer_modes
[0][0] = depth_bits
;
148 depth_buffer_modes
[1][0] = depth_bits
;
150 /* Just like with the accumulation buffer, always provide some modes
151 * with a stencil buffer. It will be a sw fallback, but some apps won't
154 depth_buffer_modes
[0][1] = 0;
155 depth_buffer_modes
[1][1] = (stencil_bits
== 0) ? 8 : stencil_bits
;
157 depth_buffer_factor
= ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 2 : 1;
158 back_buffer_factor
= (have_back_buffer
) ? 2 : 1;
160 num_modes
= depth_buffer_factor
* back_buffer_factor
* 4;
162 modes
= (*create_context_modes
)( num_modes
, sizeof( __GLcontextModes
) );
164 for ( i
= 0 ; i
< depth_buffer_factor
; i
++ ) {
165 m
= fill_in_modes( m
, pixel_bits
,
166 depth_buffer_modes
[i
][0], depth_buffer_modes
[i
][1],
167 back_buffer_modes
, back_buffer_factor
,
171 for ( i
= 0 ; i
< depth_buffer_factor
; i
++ ) {
172 m
= fill_in_modes( m
, pixel_bits
,
173 depth_buffer_modes
[i
][0], depth_buffer_modes
[i
][1],
174 back_buffer_modes
, back_buffer_factor
,
178 /* Mark the visual as slow if there are "fake" stencil bits.
180 for ( m
= modes
; m
!= NULL
; m
= m
->next
) {
181 if ( (m
->stencilBits
!= 0) && (m
->stencilBits
!= stencil_bits
) ) {
182 m
->visualRating
= GLX_SLOW_CONFIG
;
189 #endif /* USE_NEW_INTERFACE */
193 /* static int i810_malloc_proxy_buf(drmBufMapPtr buffers) */
199 /* buffer = CALLOC(I810_DMA_BUF_SZ); */
200 /* if(buffer == NULL) return -1; */
201 /* for(i = 0; i < I810_DMA_BUF_NR; i++) { */
202 /* buf = &(buffers->list[i]); */
203 /* buf->address = (drmAddress)buffer; */
208 static drmBufMapPtr
i810_create_empty_buffers(void)
212 retval
= (drmBufMapPtr
)ALIGN_MALLOC(sizeof(drmBufMap
), 32);
213 if(retval
== NULL
) return NULL
;
214 memset(retval
, 0, sizeof(drmBufMap
));
215 retval
->list
= (drmBufPtr
)ALIGN_MALLOC(sizeof(drmBuf
) * I810_DMA_BUF_NR
, 32);
216 if(retval
->list
== NULL
) {
220 memset(retval
->list
, 0, sizeof(drmBuf
) * I810_DMA_BUF_NR
);
226 i810InitDriver(__DRIscreenPrivate
*sPriv
)
228 i810ScreenPrivate
*i810Screen
;
229 I810DRIPtr gDRIPriv
= (I810DRIPtr
)sPriv
->pDevPriv
;
232 /* Allocate the private area */
233 i810Screen
= (i810ScreenPrivate
*)CALLOC(sizeof(i810ScreenPrivate
));
235 __driUtilMessage("i810InitDriver: alloc i810ScreenPrivate struct failed");
239 i810Screen
->driScrnPriv
= sPriv
;
240 sPriv
->private = (void *)i810Screen
;
242 i810Screen
->deviceID
=gDRIPriv
->deviceID
;
243 i810Screen
->width
=gDRIPriv
->width
;
244 i810Screen
->height
=gDRIPriv
->height
;
245 i810Screen
->mem
=gDRIPriv
->mem
;
246 i810Screen
->cpp
=gDRIPriv
->cpp
;
247 i810Screen
->fbStride
=gDRIPriv
->fbStride
;
248 i810Screen
->fbOffset
=gDRIPriv
->fbOffset
;
250 if (gDRIPriv
->bitsPerPixel
== 15)
251 i810Screen
->fbFormat
= DV_PF_555
;
253 i810Screen
->fbFormat
= DV_PF_565
;
255 i810Screen
->backOffset
=gDRIPriv
->backOffset
;
256 i810Screen
->depthOffset
=gDRIPriv
->depthOffset
;
257 i810Screen
->backPitch
= gDRIPriv
->auxPitch
;
258 i810Screen
->backPitchBits
= gDRIPriv
->auxPitchBits
;
259 i810Screen
->textureOffset
=gDRIPriv
->textureOffset
;
260 i810Screen
->textureSize
=gDRIPriv
->textureSize
;
261 i810Screen
->logTextureGranularity
= gDRIPriv
->logTextureGranularity
;
263 i810Screen
->bufs
= i810_create_empty_buffers();
264 if (i810Screen
->bufs
== NULL
) {
265 __driUtilMessage("i810InitDriver: i810_create_empty_buffers() failed");
270 i810Screen
->back
.handle
= gDRIPriv
->backbuffer
;
271 i810Screen
->back
.size
= gDRIPriv
->backbufferSize
;
273 if (drmMap(sPriv
->fd
,
274 i810Screen
->back
.handle
,
275 i810Screen
->back
.size
,
276 (drmAddress
*)&i810Screen
->back
.map
) != 0) {
278 sPriv
->private = NULL
;
279 __driUtilMessage("i810InitDriver: drmMap failed");
283 i810Screen
->depth
.handle
= gDRIPriv
->depthbuffer
;
284 i810Screen
->depth
.size
= gDRIPriv
->depthbufferSize
;
286 if (drmMap(sPriv
->fd
,
287 i810Screen
->depth
.handle
,
288 i810Screen
->depth
.size
,
289 (drmAddress
*)&i810Screen
->depth
.map
) != 0) {
291 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
292 sPriv
->private = NULL
;
293 __driUtilMessage("i810InitDriver: drmMap (2) failed");
297 i810Screen
->tex
.handle
= gDRIPriv
->textures
;
298 i810Screen
->tex
.size
= gDRIPriv
->textureSize
;
300 if (drmMap(sPriv
->fd
,
301 i810Screen
->tex
.handle
,
302 i810Screen
->tex
.size
,
303 (drmAddress
*)&i810Screen
->tex
.map
) != 0) {
305 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
306 drmUnmap(i810Screen
->depth
.map
, i810Screen
->depth
.size
);
307 sPriv
->private = NULL
;
308 __driUtilMessage("i810InitDriver: drmMap (3) failed");
312 i810Screen
->sarea_priv_offset
= gDRIPriv
->sarea_priv_offset
;
318 i810DestroyScreen(__DRIscreenPrivate
*sPriv
)
320 i810ScreenPrivate
*i810Screen
= (i810ScreenPrivate
*)sPriv
->private;
322 /* Need to unmap all the bufs and maps here:
324 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
325 drmUnmap(i810Screen
->depth
.map
, i810Screen
->depth
.size
);
326 drmUnmap(i810Screen
->tex
.map
, i810Screen
->tex
.size
);
329 sPriv
->private = NULL
;
334 i810CreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
335 __DRIdrawablePrivate
*driDrawPriv
,
336 const __GLcontextModes
*mesaVis
,
340 return GL_FALSE
; /* not implemented */
343 driDrawPriv
->driverPrivate
= (void *)
344 _mesa_create_framebuffer(mesaVis
,
345 GL_FALSE
, /* software depth buffer? */
346 mesaVis
->stencilBits
> 0,
347 mesaVis
->accumRedBits
> 0,
348 GL_FALSE
/* s/w alpha planes */);
349 return (driDrawPriv
->driverPrivate
!= NULL
);
355 i810DestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
357 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->driverPrivate
));
361 static const struct __DriverAPIRec i810API
= {
362 .InitDriver
= i810InitDriver
,
363 .DestroyScreen
= i810DestroyScreen
,
364 .CreateContext
= i810CreateContext
,
365 .DestroyContext
= i810DestroyContext
,
366 .CreateBuffer
= i810CreateBuffer
,
367 .DestroyBuffer
= i810DestroyBuffer
,
368 .SwapBuffers
= i810SwapBuffers
,
369 .MakeCurrent
= i810MakeCurrent
,
370 .UnbindContext
= i810UnbindContext
,
375 .SwapBuffersMSC
= NULL
380 * This is the bootstrap function for the driver.
381 * The __driCreateScreen name is the symbol that libGL.so fetches.
382 * Return: pointer to a __DRIscreenPrivate.
384 #if !defined(DRI_NEW_INTERFACE_ONLY)
385 void *__driCreateScreen(Display
*dpy
, int scrn
, __DRIscreen
*psc
,
386 int numConfigs
, __GLXvisualConfig
*config
)
388 __DRIscreenPrivate
*psp
;
389 psp
= __driUtilCreateScreen(dpy
, scrn
, psc
, numConfigs
, config
, &i810API
);
392 #endif /* !defined(DRI_NEW_INTERFACE_ONLY) */
395 * This is the bootstrap function for the driver. libGL supplies all of the
396 * requisite information about the system, and the driver initializes itself.
397 * This routine also fills in the linked list pointed to by \c driver_modes
398 * with the \c __GLcontextModes that the driver can support for windows or
401 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
404 #ifdef USE_NEW_INTERFACE
405 void * __driCreateNewScreen( __DRInativeDisplay
*dpy
, int scrn
, __DRIscreen
*psc
,
406 const __GLcontextModes
* modes
,
407 const __DRIversion
* ddx_version
,
408 const __DRIversion
* dri_version
,
409 const __DRIversion
* drm_version
,
410 const __DRIframebuffer
* frame_buffer
,
411 drmAddress pSAREA
, int fd
,
412 int internal_api_version
,
413 __GLcontextModes
** driver_modes
)
416 __DRIscreenPrivate
*psp
;
417 static const __DRIversion ddx_expected
= { 1, 0, 0 };
418 static const __DRIversion dri_expected
= { 4, 0, 0 };
419 static const __DRIversion drm_expected
= { 1, 2, 0 };
421 if ( ! driCheckDriDdxDrmVersions2( "i810",
422 dri_version
, & dri_expected
,
423 ddx_version
, & ddx_expected
,
424 drm_version
, & drm_expected
) ) {
428 psp
= __driUtilCreateNewScreen(dpy
, scrn
, psc
, NULL
,
429 ddx_version
, dri_version
, drm_version
,
430 frame_buffer
, pSAREA
, fd
,
431 internal_api_version
, &i810API
);
433 create_context_modes
= (PFNGLXCREATECONTEXTMODES
)
434 glXGetProcAddress( (const GLubyte
*) "__glXCreateContextModes" );
435 if ( create_context_modes
!= NULL
) {
436 *driver_modes
= i810FillInModes( 16,
444 #endif /* USE_NEW_INTERFACE */