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 **************************************************************************/
30 * Keith Whitwell <keith@tungstengraphics.com>
38 #include "framebuffer.h"
41 #include "renderbuffer.h"
42 #include "simple_list.h"
45 #include "i810screen.h"
48 #include "i810state.h"
52 #include "i810ioctl.h"
54 #include "GL/internal/dri_interface.h"
56 extern const struct dri_extension card_extensions
[];
58 static __GLcontextModes
*fill_in_modes( __GLcontextModes
*modes
,
61 unsigned stencil_bits
,
62 const GLenum
* db_modes
,
63 unsigned num_db_modes
,
66 static const u_int8_t bits
[1][4] = {
70 static const u_int32_t masks
[1][4] = {
71 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }
76 const unsigned index
= 0;
78 for ( i
= 0 ; i
< num_db_modes
; i
++ ) {
79 for ( j
= 0 ; j
< 2 ; j
++ ) {
81 modes
->redBits
= bits
[index
][0];
82 modes
->greenBits
= bits
[index
][1];
83 modes
->blueBits
= bits
[index
][2];
84 modes
->alphaBits
= bits
[index
][3];
85 modes
->redMask
= masks
[index
][0];
86 modes
->greenMask
= masks
[index
][1];
87 modes
->blueMask
= masks
[index
][2];
88 modes
->alphaMask
= masks
[index
][3];
89 modes
->rgbBits
= modes
->redBits
+ modes
->greenBits
90 + modes
->blueBits
+ modes
->alphaBits
;
92 modes
->accumRedBits
= 16 * j
;
93 modes
->accumGreenBits
= 16 * j
;
94 modes
->accumBlueBits
= 16 * j
;
95 modes
->accumAlphaBits
= (masks
[index
][3] != 0) ? 16 * j
: 0;
96 modes
->visualRating
= (j
== 0) ? GLX_NONE
: GLX_SLOW_CONFIG
;
98 modes
->stencilBits
= stencil_bits
;
99 modes
->depthBits
= depth_bits
;
101 modes
->visualType
= visType
;
102 modes
->renderType
= GLX_RGBA_BIT
;
103 modes
->drawableType
= GLX_WINDOW_BIT
;
104 modes
->rgbMode
= GL_TRUE
;
106 if ( db_modes
[i
] == GLX_NONE
) {
107 modes
->doubleBufferMode
= GL_FALSE
;
110 modes
->doubleBufferMode
= GL_TRUE
;
111 modes
->swapMethod
= db_modes
[i
];
123 static __GLcontextModes
*
124 i810FillInModes( unsigned pixel_bits
, unsigned depth_bits
,
125 unsigned stencil_bits
, GLboolean have_back_buffer
)
126 { __GLcontextModes
* modes
;
127 __GLcontextModes
* m
;
129 unsigned depth_buffer_factor
;
130 unsigned back_buffer_factor
;
133 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
134 * enough to add support. Basically, if a context is created with an
135 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
136 * will never be used.
138 static const GLenum back_buffer_modes
[] = {
139 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
/*, GLX_SWAP_COPY_OML */
142 int depth_buffer_modes
[2][2];
145 depth_buffer_modes
[0][0] = depth_bits
;
146 depth_buffer_modes
[1][0] = depth_bits
;
148 /* Just like with the accumulation buffer, always provide some modes
149 * with a stencil buffer. It will be a sw fallback, but some apps won't
152 depth_buffer_modes
[0][1] = 0;
153 depth_buffer_modes
[1][1] = (stencil_bits
== 0) ? 8 : stencil_bits
;
155 depth_buffer_factor
= ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 2 : 1;
156 back_buffer_factor
= (have_back_buffer
) ? 2 : 1;
158 num_modes
= depth_buffer_factor
* back_buffer_factor
* 4;
160 modes
= (*dri_interface
->createContextModes
)( num_modes
, sizeof( __GLcontextModes
) );
162 for ( i
= 0 ; i
< depth_buffer_factor
; i
++ ) {
163 m
= fill_in_modes( m
, pixel_bits
,
164 depth_buffer_modes
[i
][0], depth_buffer_modes
[i
][1],
165 back_buffer_modes
, back_buffer_factor
,
169 for ( i
= 0 ; i
< depth_buffer_factor
; i
++ ) {
170 m
= fill_in_modes( m
, pixel_bits
,
171 depth_buffer_modes
[i
][0], depth_buffer_modes
[i
][1],
172 back_buffer_modes
, back_buffer_factor
,
176 /* Mark the visual as slow if there are "fake" stencil bits.
178 for ( m
= modes
; m
!= NULL
; m
= m
->next
) {
179 if ( (m
->stencilBits
!= 0) && (m
->stencilBits
!= stencil_bits
) ) {
180 m
->visualRating
= GLX_SLOW_CONFIG
;
189 /* static int i810_malloc_proxy_buf(drmBufMapPtr buffers) */
195 /* buffer = CALLOC(I810_DMA_BUF_SZ); */
196 /* if(buffer == NULL) return -1; */
197 /* for(i = 0; i < I810_DMA_BUF_NR; i++) { */
198 /* buf = &(buffers->list[i]); */
199 /* buf->address = (drmAddress)buffer; */
204 static drmBufMapPtr
i810_create_empty_buffers(void)
208 retval
= (drmBufMapPtr
)ALIGN_MALLOC(sizeof(drmBufMap
), 32);
209 if(retval
== NULL
) return NULL
;
210 memset(retval
, 0, sizeof(drmBufMap
));
211 retval
->list
= (drmBufPtr
)ALIGN_MALLOC(sizeof(drmBuf
) * I810_DMA_BUF_NR
, 32);
212 if(retval
->list
== NULL
) {
216 memset(retval
->list
, 0, sizeof(drmBuf
) * I810_DMA_BUF_NR
);
222 i810InitDriver(__DRIscreenPrivate
*sPriv
)
224 i810ScreenPrivate
*i810Screen
;
225 I810DRIPtr gDRIPriv
= (I810DRIPtr
)sPriv
->pDevPriv
;
227 if (sPriv
->devPrivSize
!= sizeof(I810DRIRec
)) {
228 fprintf(stderr
,"\nERROR! sizeof(I810DRIRec) does not match passed size from device driver\n");
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) {
304 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
305 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 * Create a buffer which corresponds to the window.
337 i810CreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
338 __DRIdrawablePrivate
*driDrawPriv
,
339 const __GLcontextModes
*mesaVis
,
342 i810ScreenPrivate
*screen
= (i810ScreenPrivate
*) driScrnPriv
->private;
345 return GL_FALSE
; /* not implemented */
348 struct gl_framebuffer
*fb
= _mesa_create_framebuffer(mesaVis
);
351 driRenderbuffer
*frontRb
352 = driNewRenderbuffer(GL_RGBA
,
355 /*screen->frontOffset*/0, screen
->backPitch
,
357 i810SetSpanFunctions(frontRb
, mesaVis
);
358 _mesa_add_renderbuffer(fb
, BUFFER_FRONT_LEFT
, &frontRb
->Base
);
361 if (mesaVis
->doubleBufferMode
) {
362 driRenderbuffer
*backRb
363 = driNewRenderbuffer(GL_RGBA
,
366 screen
->backOffset
, screen
->backPitch
,
368 i810SetSpanFunctions(backRb
, mesaVis
);
369 _mesa_add_renderbuffer(fb
, BUFFER_BACK_LEFT
, &backRb
->Base
);
372 if (mesaVis
->depthBits
== 16) {
373 driRenderbuffer
*depthRb
374 = driNewRenderbuffer(GL_DEPTH_COMPONENT16
,
377 screen
->depthOffset
, screen
->backPitch
,
379 i810SetSpanFunctions(depthRb
, mesaVis
);
380 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &depthRb
->Base
);
383 _mesa_add_soft_renderbuffers(fb
,
384 GL_FALSE
, /* color */
385 GL_FALSE
, /* depth */
386 mesaVis
->stencilBits
> 0,
387 mesaVis
->accumRedBits
> 0,
388 GL_FALSE
, /* alpha */
390 driDrawPriv
->driverPrivate
= (void *) fb
;
392 return (driDrawPriv
->driverPrivate
!= NULL
);
398 i810DestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
400 _mesa_unreference_framebuffer((GLframebuffer
**)(&(driDrawPriv
->driverPrivate
)));
404 static const struct __DriverAPIRec i810API
= {
405 .InitDriver
= i810InitDriver
,
406 .DestroyScreen
= i810DestroyScreen
,
407 .CreateContext
= i810CreateContext
,
408 .DestroyContext
= i810DestroyContext
,
409 .CreateBuffer
= i810CreateBuffer
,
410 .DestroyBuffer
= i810DestroyBuffer
,
411 .SwapBuffers
= i810SwapBuffers
,
412 .MakeCurrent
= i810MakeCurrent
,
413 .UnbindContext
= i810UnbindContext
,
418 .SwapBuffersMSC
= NULL
423 * This is the bootstrap function for the driver. libGL supplies all of the
424 * requisite information about the system, and the driver initializes itself.
425 * This routine also fills in the linked list pointed to by \c driver_modes
426 * with the \c __GLcontextModes that the driver can support for windows or
429 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
433 void * __driCreateNewScreen_20050727( __DRInativeDisplay
*dpy
, int scrn
, __DRIscreen
*psc
,
434 const __GLcontextModes
* modes
,
435 const __DRIversion
* ddx_version
,
436 const __DRIversion
* dri_version
,
437 const __DRIversion
* drm_version
,
438 const __DRIframebuffer
* frame_buffer
,
439 drmAddress pSAREA
, int fd
,
440 int internal_api_version
,
441 const __DRIinterfaceMethods
* interface
,
442 __GLcontextModes
** driver_modes
)
445 __DRIscreenPrivate
*psp
;
446 static const __DRIversion ddx_expected
= { 1, 0, 0 };
447 static const __DRIversion dri_expected
= { 4, 0, 0 };
448 static const __DRIversion drm_expected
= { 1, 2, 0 };
450 dri_interface
= interface
;
452 if ( ! driCheckDriDdxDrmVersions2( "i810",
453 dri_version
, & dri_expected
,
454 ddx_version
, & ddx_expected
,
455 drm_version
, & drm_expected
) ) {
459 psp
= __driUtilCreateNewScreen(dpy
, scrn
, psc
, NULL
,
460 ddx_version
, dri_version
, drm_version
,
461 frame_buffer
, pSAREA
, fd
,
462 internal_api_version
, &i810API
);
464 *driver_modes
= i810FillInModes( 16,
467 driInitExtensions( NULL
, card_extensions
, GL_TRUE
);