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"
53 #include "GL/internal/dri_interface.h"
56 #ifdef USE_NEW_INTERFACE
57 static PFNGLXCREATECONTEXTMODES create_context_modes
= NULL
;
58 #endif /* USE_NEW_INTERFACE */
60 #ifdef USE_NEW_INTERFACE
61 static __GLcontextModes
*fill_in_modes( __GLcontextModes
*modes
,
64 unsigned stencil_bits
,
65 const GLenum
* db_modes
,
66 unsigned num_db_modes
,
69 static const uint8_t bits
[1][4] = {
73 static const uint32_t masks
[1][4] = {
74 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }
79 const unsigned index
= 0;
81 for ( i
= 0 ; i
< num_db_modes
; i
++ ) {
82 for ( j
= 0 ; j
< 2 ; j
++ ) {
84 modes
->redBits
= bits
[index
][0];
85 modes
->greenBits
= bits
[index
][1];
86 modes
->blueBits
= bits
[index
][2];
87 modes
->alphaBits
= bits
[index
][3];
88 modes
->redMask
= masks
[index
][0];
89 modes
->greenMask
= masks
[index
][1];
90 modes
->blueMask
= masks
[index
][2];
91 modes
->alphaMask
= masks
[index
][3];
92 modes
->rgbBits
= modes
->redBits
+ modes
->greenBits
93 + modes
->blueBits
+ modes
->alphaBits
;
95 modes
->accumRedBits
= 16 * j
;
96 modes
->accumGreenBits
= 16 * j
;
97 modes
->accumBlueBits
= 16 * j
;
98 modes
->accumAlphaBits
= (masks
[index
][3] != 0) ? 16 * j
: 0;
99 modes
->visualRating
= (j
== 0) ? GLX_NONE
: GLX_SLOW_CONFIG
;
101 modes
->stencilBits
= stencil_bits
;
102 modes
->depthBits
= depth_bits
;
104 modes
->visualType
= visType
;
105 modes
->renderType
= GLX_RGBA_BIT
;
106 modes
->drawableType
= GLX_WINDOW_BIT
;
107 modes
->rgbMode
= GL_TRUE
;
109 if ( db_modes
[i
] == GLX_NONE
) {
110 modes
->doubleBufferMode
= GL_FALSE
;
113 modes
->doubleBufferMode
= GL_TRUE
;
114 modes
->swapMethod
= db_modes
[i
];
124 #endif /* USE_NEW_INTERFACE */
126 #ifdef USE_NEW_INTERFACE
127 static __GLcontextModes
*
128 i810FillInModes( unsigned pixel_bits
, unsigned depth_bits
,
129 unsigned stencil_bits
, GLboolean have_back_buffer
)
130 { __GLcontextModes
* modes
;
131 __GLcontextModes
* m
;
133 unsigned depth_buffer_factor
;
134 unsigned back_buffer_factor
;
137 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
138 * enough to add support. Basically, if a context is created with an
139 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
140 * will never be used.
142 static const GLenum back_buffer_modes
[] = {
143 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
/*, GLX_SWAP_COPY_OML */
146 int depth_buffer_modes
[2][2];
149 depth_buffer_modes
[0][0] = depth_bits
;
150 depth_buffer_modes
[1][0] = depth_bits
;
152 /* Just like with the accumulation buffer, always provide some modes
153 * with a stencil buffer. It will be a sw fallback, but some apps won't
156 depth_buffer_modes
[0][1] = 0;
157 depth_buffer_modes
[1][1] = (stencil_bits
== 0) ? 8 : stencil_bits
;
159 depth_buffer_factor
= ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 2 : 1;
160 back_buffer_factor
= (have_back_buffer
) ? 2 : 1;
162 num_modes
= depth_buffer_factor
* back_buffer_factor
* 4;
164 modes
= (*create_context_modes
)( num_modes
, sizeof( __GLcontextModes
) );
166 for ( i
= 0 ; i
< depth_buffer_factor
; i
++ ) {
167 m
= fill_in_modes( m
, pixel_bits
,
168 depth_buffer_modes
[i
][0], depth_buffer_modes
[i
][1],
169 back_buffer_modes
, back_buffer_factor
,
173 for ( i
= 0 ; i
< depth_buffer_factor
; i
++ ) {
174 m
= fill_in_modes( m
, pixel_bits
,
175 depth_buffer_modes
[i
][0], depth_buffer_modes
[i
][1],
176 back_buffer_modes
, back_buffer_factor
,
180 /* Mark the visual as slow if there are "fake" stencil bits.
182 for ( m
= modes
; m
!= NULL
; m
= m
->next
) {
183 if ( (m
->stencilBits
!= 0) && (m
->stencilBits
!= stencil_bits
) ) {
184 m
->visualRating
= GLX_SLOW_CONFIG
;
191 #endif /* USE_NEW_INTERFACE */
195 /* static int i810_malloc_proxy_buf(drmBufMapPtr buffers) */
201 /* buffer = CALLOC(I810_DMA_BUF_SZ); */
202 /* if(buffer == NULL) return -1; */
203 /* for(i = 0; i < I810_DMA_BUF_NR; i++) { */
204 /* buf = &(buffers->list[i]); */
205 /* buf->address = (drmAddress)buffer; */
210 static drmBufMapPtr
i810_create_empty_buffers(void)
214 retval
= (drmBufMapPtr
)ALIGN_MALLOC(sizeof(drmBufMap
), 32);
215 if(retval
== NULL
) return NULL
;
216 memset(retval
, 0, sizeof(drmBufMap
));
217 retval
->list
= (drmBufPtr
)ALIGN_MALLOC(sizeof(drmBuf
) * I810_DMA_BUF_NR
, 32);
218 if(retval
->list
== NULL
) {
222 memset(retval
->list
, 0, sizeof(drmBuf
) * I810_DMA_BUF_NR
);
228 i810InitDriver(__DRIscreenPrivate
*sPriv
)
230 i810ScreenPrivate
*i810Screen
;
231 I810DRIPtr gDRIPriv
= (I810DRIPtr
)sPriv
->pDevPriv
;
233 if ( ! driCheckDriDdxDrmVersions( sPriv
, "i810", 4, 0, 1, 0, 1, 2 ) )
236 /* Allocate the private area */
237 i810Screen
= (i810ScreenPrivate
*)CALLOC(sizeof(i810ScreenPrivate
));
239 __driUtilMessage("i810InitDriver: alloc i810ScreenPrivate struct failed");
243 i810Screen
->driScrnPriv
= sPriv
;
244 sPriv
->private = (void *)i810Screen
;
246 i810Screen
->deviceID
=gDRIPriv
->deviceID
;
247 i810Screen
->width
=gDRIPriv
->width
;
248 i810Screen
->height
=gDRIPriv
->height
;
249 i810Screen
->mem
=gDRIPriv
->mem
;
250 i810Screen
->cpp
=gDRIPriv
->cpp
;
251 i810Screen
->fbStride
=gDRIPriv
->fbStride
;
252 i810Screen
->fbOffset
=gDRIPriv
->fbOffset
;
254 if (gDRIPriv
->bitsPerPixel
== 15)
255 i810Screen
->fbFormat
= DV_PF_555
;
257 i810Screen
->fbFormat
= DV_PF_565
;
259 i810Screen
->backOffset
=gDRIPriv
->backOffset
;
260 i810Screen
->depthOffset
=gDRIPriv
->depthOffset
;
261 i810Screen
->backPitch
= gDRIPriv
->auxPitch
;
262 i810Screen
->backPitchBits
= gDRIPriv
->auxPitchBits
;
263 i810Screen
->textureOffset
=gDRIPriv
->textureOffset
;
264 i810Screen
->textureSize
=gDRIPriv
->textureSize
;
265 i810Screen
->logTextureGranularity
= gDRIPriv
->logTextureGranularity
;
267 i810Screen
->bufs
= i810_create_empty_buffers();
268 if (i810Screen
->bufs
== NULL
) {
269 __driUtilMessage("i810InitDriver: i810_create_empty_buffers() failed");
274 i810Screen
->back
.handle
= gDRIPriv
->backbuffer
;
275 i810Screen
->back
.size
= gDRIPriv
->backbufferSize
;
277 if (drmMap(sPriv
->fd
,
278 i810Screen
->back
.handle
,
279 i810Screen
->back
.size
,
280 (drmAddress
*)&i810Screen
->back
.map
) != 0) {
282 sPriv
->private = NULL
;
283 __driUtilMessage("i810InitDriver: drmMap failed");
287 i810Screen
->depth
.handle
= gDRIPriv
->depthbuffer
;
288 i810Screen
->depth
.size
= gDRIPriv
->depthbufferSize
;
290 if (drmMap(sPriv
->fd
,
291 i810Screen
->depth
.handle
,
292 i810Screen
->depth
.size
,
293 (drmAddress
*)&i810Screen
->depth
.map
) != 0) {
295 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
296 sPriv
->private = NULL
;
297 __driUtilMessage("i810InitDriver: drmMap (2) failed");
301 i810Screen
->tex
.handle
= gDRIPriv
->textures
;
302 i810Screen
->tex
.size
= gDRIPriv
->textureSize
;
304 if (drmMap(sPriv
->fd
,
305 i810Screen
->tex
.handle
,
306 i810Screen
->tex
.size
,
307 (drmAddress
*)&i810Screen
->tex
.map
) != 0) {
309 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
310 drmUnmap(i810Screen
->depth
.map
, i810Screen
->depth
.size
);
311 sPriv
->private = NULL
;
312 __driUtilMessage("i810InitDriver: drmMap (3) failed");
316 i810Screen
->sarea_priv_offset
= gDRIPriv
->sarea_priv_offset
;
322 i810DestroyScreen(__DRIscreenPrivate
*sPriv
)
324 i810ScreenPrivate
*i810Screen
= (i810ScreenPrivate
*)sPriv
->private;
326 /* Need to unmap all the bufs and maps here:
328 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
329 drmUnmap(i810Screen
->depth
.map
, i810Screen
->depth
.size
);
330 drmUnmap(i810Screen
->tex
.map
, i810Screen
->tex
.size
);
333 sPriv
->private = NULL
;
338 i810CreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
339 __DRIdrawablePrivate
*driDrawPriv
,
340 const __GLcontextModes
*mesaVis
,
344 return GL_FALSE
; /* not implemented */
347 driDrawPriv
->driverPrivate
= (void *)
348 _mesa_create_framebuffer(mesaVis
,
349 GL_FALSE
, /* software depth buffer? */
350 mesaVis
->stencilBits
> 0,
351 mesaVis
->accumRedBits
> 0,
352 GL_FALSE
/* s/w alpha planes */);
353 return (driDrawPriv
->driverPrivate
!= NULL
);
359 i810DestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
361 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->driverPrivate
));
366 i810OpenCloseFullScreen(__DRIcontextPrivate
*driContextPriv
)
371 static const struct __DriverAPIRec i810API
= {
372 .InitDriver
= i810InitDriver
,
373 .DestroyScreen
= i810DestroyScreen
,
374 .CreateContext
= i810CreateContext
,
375 .DestroyContext
= i810DestroyContext
,
376 .CreateBuffer
= i810CreateBuffer
,
377 .DestroyBuffer
= i810DestroyBuffer
,
378 .SwapBuffers
= i810SwapBuffers
,
379 .MakeCurrent
= i810MakeCurrent
,
380 .UnbindContext
= i810UnbindContext
,
381 .OpenFullScreen
= i810OpenCloseFullScreen
,
382 .CloseFullScreen
= i810OpenCloseFullScreen
,
387 .SwapBuffersMSC
= NULL
392 * This is the bootstrap function for the driver.
393 * The __driCreateScreen name is the symbol that libGL.so fetches.
394 * Return: pointer to a __DRIscreenPrivate.
396 #if !defined(DRI_NEW_INTERFACE_ONLY)
398 void *__driCreateScreen(Display
*dpy
, int scrn
, __DRIscreen
*psc
,
399 int numConfigs
, __GLXvisualConfig
*config
)
401 __DRIscreenPrivate
*psp
;
402 psp
= __driUtilCreateScreen(dpy
, scrn
, psc
, numConfigs
, config
, &i810API
);
406 void *__driCreateScreen(struct DRIDriverRec
*driver
,
407 struct DRIDriverContextRec
*driverContext
)
409 __DRIscreenPrivate
*psp
;
410 psp
= __driUtilCreateScreen(driver
, driverContext
, &i810API
);
414 #endif /* !defined(DRI_NEW_INTERFACE_ONLY) */
417 * This is the bootstrap function for the driver. libGL supplies all of the
418 * requisite information about the system, and the driver initializes itself.
419 * This routine also fills in the linked list pointed to by \c driver_modes
420 * with the \c __GLcontextModes that the driver can support for windows or
423 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
426 #ifdef USE_NEW_INTERFACE
427 void * __driCreateNewScreen( __DRInativeDisplay
*dpy
, int scrn
, __DRIscreen
*psc
,
428 const __GLcontextModes
* modes
,
429 const __DRIversion
* ddx_version
,
430 const __DRIversion
* dri_version
,
431 const __DRIversion
* drm_version
,
432 const __DRIframebuffer
* frame_buffer
,
433 drmAddress pSAREA
, int fd
,
434 int internal_api_version
,
435 __GLcontextModes
** driver_modes
)
438 __DRIscreenPrivate
*psp
;
440 psp
= __driUtilCreateNewScreen(dpy
, scrn
, psc
, NULL
,
441 ddx_version
, dri_version
, drm_version
,
442 frame_buffer
, pSAREA
, fd
,
443 internal_api_version
, &i810API
);
445 create_context_modes
= (PFNGLXCREATECONTEXTMODES
)
446 glXGetProcAddress( (const GLubyte
*) "__glXCreateContextModes" );
447 if ( create_context_modes
!= NULL
) {
448 *driver_modes
= i810FillInModes( 16,
456 #endif /* USE_NEW_INTERFACE */