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>
39 #include "framebuffer.h"
42 #include "renderbuffer.h"
43 #include "simple_list.h"
46 #include "i810screen.h"
49 #include "i810state.h"
53 #include "i810ioctl.h"
55 #include "GL/internal/dri_interface.h"
57 extern const struct dri_extension card_extensions
[];
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 u_int8_t bits
[1][4] = {
71 static const u_int32_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
];
124 static __GLcontextModes
*
125 i810FillInModes( unsigned pixel_bits
, unsigned depth_bits
,
126 unsigned stencil_bits
, GLboolean have_back_buffer
)
127 { __GLcontextModes
* modes
;
128 __GLcontextModes
* m
;
130 unsigned depth_buffer_factor
;
131 unsigned back_buffer_factor
;
134 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
135 * enough to add support. Basically, if a context is created with an
136 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
137 * will never be used.
139 static const GLenum back_buffer_modes
[] = {
140 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
/*, GLX_SWAP_COPY_OML */
143 int depth_buffer_modes
[2][2];
146 depth_buffer_modes
[0][0] = depth_bits
;
147 depth_buffer_modes
[1][0] = depth_bits
;
149 /* Just like with the accumulation buffer, always provide some modes
150 * with a stencil buffer. It will be a sw fallback, but some apps won't
153 depth_buffer_modes
[0][1] = 0;
154 depth_buffer_modes
[1][1] = (stencil_bits
== 0) ? 8 : stencil_bits
;
156 depth_buffer_factor
= ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 2 : 1;
157 back_buffer_factor
= (have_back_buffer
) ? 2 : 1;
159 num_modes
= depth_buffer_factor
* back_buffer_factor
* 4;
161 modes
= (*dri_interface
->createContextModes
)( num_modes
, sizeof( __GLcontextModes
) );
163 for ( i
= 0 ; i
< depth_buffer_factor
; i
++ ) {
164 m
= fill_in_modes( m
, pixel_bits
,
165 depth_buffer_modes
[i
][0], depth_buffer_modes
[i
][1],
166 back_buffer_modes
, back_buffer_factor
,
170 for ( i
= 0 ; i
< depth_buffer_factor
; i
++ ) {
171 m
= fill_in_modes( m
, pixel_bits
,
172 depth_buffer_modes
[i
][0], depth_buffer_modes
[i
][1],
173 back_buffer_modes
, back_buffer_factor
,
177 /* Mark the visual as slow if there are "fake" stencil bits.
179 for ( m
= modes
; m
!= NULL
; m
= m
->next
) {
180 if ( (m
->stencilBits
!= 0) && (m
->stencilBits
!= stencil_bits
) ) {
181 m
->visualRating
= GLX_SLOW_CONFIG
;
190 /* static int i810_malloc_proxy_buf(drmBufMapPtr buffers) */
196 /* buffer = CALLOC(I810_DMA_BUF_SZ); */
197 /* if(buffer == NULL) return -1; */
198 /* for(i = 0; i < I810_DMA_BUF_NR; i++) { */
199 /* buf = &(buffers->list[i]); */
200 /* buf->address = (drmAddress)buffer; */
205 static drmBufMapPtr
i810_create_empty_buffers(void)
209 retval
= (drmBufMapPtr
)ALIGN_MALLOC(sizeof(drmBufMap
), 32);
210 if(retval
== NULL
) return NULL
;
211 memset(retval
, 0, sizeof(drmBufMap
));
212 retval
->list
= (drmBufPtr
)ALIGN_MALLOC(sizeof(drmBuf
) * I810_DMA_BUF_NR
, 32);
213 if(retval
->list
== NULL
) {
217 memset(retval
->list
, 0, sizeof(drmBuf
) * I810_DMA_BUF_NR
);
223 i810InitDriver(__DRIscreenPrivate
*sPriv
)
225 i810ScreenPrivate
*i810Screen
;
226 I810DRIPtr gDRIPriv
= (I810DRIPtr
)sPriv
->pDevPriv
;
228 if (sPriv
->devPrivSize
!= sizeof(I810DRIRec
)) {
229 fprintf(stderr
,"\nERROR! sizeof(I810DRIRec) does not match passed size from device driver\n");
233 /* Allocate the private area */
234 i810Screen
= (i810ScreenPrivate
*)CALLOC(sizeof(i810ScreenPrivate
));
236 __driUtilMessage("i810InitDriver: alloc i810ScreenPrivate struct failed");
240 i810Screen
->driScrnPriv
= sPriv
;
241 sPriv
->private = (void *)i810Screen
;
243 i810Screen
->deviceID
=gDRIPriv
->deviceID
;
244 i810Screen
->width
=gDRIPriv
->width
;
245 i810Screen
->height
=gDRIPriv
->height
;
246 i810Screen
->mem
=gDRIPriv
->mem
;
247 i810Screen
->cpp
=gDRIPriv
->cpp
;
248 i810Screen
->fbStride
=gDRIPriv
->fbStride
;
249 i810Screen
->fbOffset
=gDRIPriv
->fbOffset
;
251 if (gDRIPriv
->bitsPerPixel
== 15)
252 i810Screen
->fbFormat
= DV_PF_555
;
254 i810Screen
->fbFormat
= DV_PF_565
;
256 i810Screen
->backOffset
=gDRIPriv
->backOffset
;
257 i810Screen
->depthOffset
=gDRIPriv
->depthOffset
;
258 i810Screen
->backPitch
= gDRIPriv
->auxPitch
;
259 i810Screen
->backPitchBits
= gDRIPriv
->auxPitchBits
;
260 i810Screen
->textureOffset
=gDRIPriv
->textureOffset
;
261 i810Screen
->textureSize
=gDRIPriv
->textureSize
;
262 i810Screen
->logTextureGranularity
= gDRIPriv
->logTextureGranularity
;
264 i810Screen
->bufs
= i810_create_empty_buffers();
265 if (i810Screen
->bufs
== NULL
) {
266 __driUtilMessage("i810InitDriver: i810_create_empty_buffers() failed");
271 i810Screen
->back
.handle
= gDRIPriv
->backbuffer
;
272 i810Screen
->back
.size
= gDRIPriv
->backbufferSize
;
274 if (drmMap(sPriv
->fd
,
275 i810Screen
->back
.handle
,
276 i810Screen
->back
.size
,
277 (drmAddress
*)&i810Screen
->back
.map
) != 0) {
279 sPriv
->private = NULL
;
280 __driUtilMessage("i810InitDriver: drmMap failed");
284 i810Screen
->depth
.handle
= gDRIPriv
->depthbuffer
;
285 i810Screen
->depth
.size
= gDRIPriv
->depthbufferSize
;
287 if (drmMap(sPriv
->fd
,
288 i810Screen
->depth
.handle
,
289 i810Screen
->depth
.size
,
290 (drmAddress
*)&i810Screen
->depth
.map
) != 0) {
292 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
293 sPriv
->private = NULL
;
294 __driUtilMessage("i810InitDriver: drmMap (2) failed");
298 i810Screen
->tex
.handle
= gDRIPriv
->textures
;
299 i810Screen
->tex
.size
= gDRIPriv
->textureSize
;
301 if (drmMap(sPriv
->fd
,
302 i810Screen
->tex
.handle
,
303 i810Screen
->tex
.size
,
304 (drmAddress
*)&i810Screen
->tex
.map
) != 0) {
305 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
306 drmUnmap(i810Screen
->depth
.map
, i810Screen
->depth
.size
);
308 sPriv
->private = NULL
;
309 __driUtilMessage("i810InitDriver: drmMap (3) failed");
313 i810Screen
->sarea_priv_offset
= gDRIPriv
->sarea_priv_offset
;
319 i810DestroyScreen(__DRIscreenPrivate
*sPriv
)
321 i810ScreenPrivate
*i810Screen
= (i810ScreenPrivate
*)sPriv
->private;
323 /* Need to unmap all the bufs and maps here:
325 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
326 drmUnmap(i810Screen
->depth
.map
, i810Screen
->depth
.size
);
327 drmUnmap(i810Screen
->tex
.map
, i810Screen
->tex
.size
);
330 sPriv
->private = NULL
;
335 * Create a buffer which corresponds to the window.
338 i810CreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
339 __DRIdrawablePrivate
*driDrawPriv
,
340 const __GLcontextModes
*mesaVis
,
343 i810ScreenPrivate
*screen
= (i810ScreenPrivate
*) driScrnPriv
->private;
346 return GL_FALSE
; /* not implemented */
349 struct gl_framebuffer
*fb
= _mesa_create_framebuffer(mesaVis
);
352 driRenderbuffer
*frontRb
353 = driNewRenderbuffer(GL_RGBA
,
356 /*screen->frontOffset*/0, screen
->backPitch
,
358 i810SetSpanFunctions(frontRb
, mesaVis
);
359 _mesa_add_renderbuffer(fb
, BUFFER_FRONT_LEFT
, &frontRb
->Base
);
362 if (mesaVis
->doubleBufferMode
) {
363 driRenderbuffer
*backRb
364 = driNewRenderbuffer(GL_RGBA
,
367 screen
->backOffset
, screen
->backPitch
,
369 i810SetSpanFunctions(backRb
, mesaVis
);
370 _mesa_add_renderbuffer(fb
, BUFFER_BACK_LEFT
, &backRb
->Base
);
373 if (mesaVis
->depthBits
== 16) {
374 driRenderbuffer
*depthRb
375 = driNewRenderbuffer(GL_DEPTH_COMPONENT16
,
378 screen
->depthOffset
, screen
->backPitch
,
380 i810SetSpanFunctions(depthRb
, mesaVis
);
381 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &depthRb
->Base
);
384 _mesa_add_soft_renderbuffers(fb
,
385 GL_FALSE
, /* color */
386 GL_FALSE
, /* depth */
387 mesaVis
->stencilBits
> 0,
388 mesaVis
->accumRedBits
> 0,
389 GL_FALSE
, /* alpha */
391 driDrawPriv
->driverPrivate
= (void *) fb
;
393 return (driDrawPriv
->driverPrivate
!= NULL
);
399 i810DestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
401 _mesa_unreference_framebuffer((GLframebuffer
**)(&(driDrawPriv
->driverPrivate
)));
405 static const struct __DriverAPIRec i810API
= {
406 .InitDriver
= i810InitDriver
,
407 .DestroyScreen
= i810DestroyScreen
,
408 .CreateContext
= i810CreateContext
,
409 .DestroyContext
= i810DestroyContext
,
410 .CreateBuffer
= i810CreateBuffer
,
411 .DestroyBuffer
= i810DestroyBuffer
,
412 .SwapBuffers
= i810SwapBuffers
,
413 .MakeCurrent
= i810MakeCurrent
,
414 .UnbindContext
= i810UnbindContext
,
419 .SwapBuffersMSC
= NULL
424 * This is the bootstrap function for the driver. libGL supplies all of the
425 * requisite information about the system, and the driver initializes itself.
426 * This routine also fills in the linked list pointed to by \c driver_modes
427 * with the \c __GLcontextModes that the driver can support for windows or
430 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
434 void * __driCreateNewScreen_20050727( __DRInativeDisplay
*dpy
, int scrn
, __DRIscreen
*psc
,
435 const __GLcontextModes
* modes
,
436 const __DRIversion
* ddx_version
,
437 const __DRIversion
* dri_version
,
438 const __DRIversion
* drm_version
,
439 const __DRIframebuffer
* frame_buffer
,
440 drmAddress pSAREA
, int fd
,
441 int internal_api_version
,
442 const __DRIinterfaceMethods
* interface
,
443 __GLcontextModes
** driver_modes
)
446 __DRIscreenPrivate
*psp
;
447 static const __DRIversion ddx_expected
= { 1, 0, 0 };
448 static const __DRIversion dri_expected
= { 4, 0, 0 };
449 static const __DRIversion drm_expected
= { 1, 2, 0 };
451 dri_interface
= interface
;
453 if ( ! driCheckDriDdxDrmVersions2( "i810",
454 dri_version
, & dri_expected
,
455 ddx_version
, & ddx_expected
,
456 drm_version
, & drm_expected
) ) {
460 psp
= __driUtilCreateNewScreen(dpy
, scrn
, psc
, NULL
,
461 ddx_version
, dri_version
, drm_version
,
462 frame_buffer
, pSAREA
, fd
,
463 internal_api_version
, &i810API
);
465 *driver_modes
= i810FillInModes( 16,
468 driInitExtensions( NULL
, card_extensions
, GL_TRUE
);