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 const __DRIconfig
**
60 i810FillInModes( __DRIscreenPrivate
*psp
,
61 unsigned pixel_bits
, unsigned depth_bits
,
62 unsigned stencil_bits
, GLboolean have_back_buffer
)
64 __DRIconfig
**configs
;
66 unsigned depth_buffer_factor
;
67 unsigned back_buffer_factor
;
70 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
71 * enough to add support. Basically, if a context is created with an
72 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
75 static const GLenum back_buffer_modes
[] = {
76 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
/*, GLX_SWAP_COPY_OML */
79 u_int8_t depth_bits_array
[2];
80 u_int8_t stencil_bits_array
[2];
82 depth_bits_array
[0] = depth_bits
;
83 depth_bits_array
[1] = depth_bits
;
85 /* Just like with the accumulation buffer, always provide some modes
86 * with a stencil buffer. It will be a sw fallback, but some apps won't
89 stencil_bits_array
[0] = 0;
90 stencil_bits_array
[1] = (stencil_bits
== 0) ? 8 : stencil_bits
;
92 depth_buffer_factor
= ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 2 : 1;
93 back_buffer_factor
= (have_back_buffer
) ? 2 : 1;
95 configs
= driCreateConfigs(GL_RGB
, GL_UNSIGNED_SHORT_5_6_5
,
96 depth_bits_array
, stencil_bits_array
,
98 back_buffer_modes
, back_buffer_factor
);
99 if (configs
== NULL
) {
100 fprintf( stderr
, "[%s:%u] Error creating FBConfig!\n",
101 __func__
, __LINE__
);
105 /* Mark the visual as slow if there are "fake" stencil bits.
107 for (i
= 0; configs
[i
]; i
++) {
108 m
= &configs
[i
]->modes
;
109 if ((m
->stencilBits
!= 0) && (m
->stencilBits
!= stencil_bits
)) {
110 m
->visualRating
= GLX_SLOW_CONFIG
;
114 return (const __DRIconfig
**) configs
;
118 /* static int i810_malloc_proxy_buf(drmBufMapPtr buffers) */
124 /* buffer = CALLOC(I810_DMA_BUF_SZ); */
125 /* if(buffer == NULL) return -1; */
126 /* for(i = 0; i < I810_DMA_BUF_NR; i++) { */
127 /* buf = &(buffers->list[i]); */
128 /* buf->address = (drmAddress)buffer; */
133 static drmBufMapPtr
i810_create_empty_buffers(void)
137 retval
= (drmBufMapPtr
)ALIGN_MALLOC(sizeof(drmBufMap
), 32);
138 if(retval
== NULL
) return NULL
;
139 memset(retval
, 0, sizeof(drmBufMap
));
140 retval
->list
= (drmBufPtr
)ALIGN_MALLOC(sizeof(drmBuf
) * I810_DMA_BUF_NR
, 32);
141 if(retval
->list
== NULL
) {
145 memset(retval
->list
, 0, sizeof(drmBuf
) * I810_DMA_BUF_NR
);
150 static const __DRIconfig
**
151 i810InitScreen(__DRIscreen
*sPriv
)
153 static const __DRIversion ddx_expected
= { 1, 0, 0 };
154 static const __DRIversion dri_expected
= { 4, 0, 0 };
155 static const __DRIversion drm_expected
= { 1, 2, 0 };
156 i810ScreenPrivate
*i810Screen
;
157 I810DRIPtr gDRIPriv
= (I810DRIPtr
)sPriv
->pDevPriv
;
159 if ( ! driCheckDriDdxDrmVersions2( "i810",
160 &sPriv
->dri_version
, & dri_expected
,
161 &sPriv
->ddx_version
, & ddx_expected
,
162 &sPriv
->drm_version
, & drm_expected
) ) {
166 driInitExtensions( NULL
, card_extensions
, GL_TRUE
);
168 if (sPriv
->devPrivSize
!= sizeof(I810DRIRec
)) {
169 fprintf(stderr
,"\nERROR! sizeof(I810DRIRec) does not match passed size from device driver\n");
173 /* Allocate the private area */
174 i810Screen
= (i810ScreenPrivate
*)CALLOC(sizeof(i810ScreenPrivate
));
176 __driUtilMessage("i810InitDriver: alloc i810ScreenPrivate struct failed");
180 i810Screen
->driScrnPriv
= sPriv
;
181 sPriv
->private = (void *)i810Screen
;
183 i810Screen
->deviceID
=gDRIPriv
->deviceID
;
184 i810Screen
->width
=gDRIPriv
->width
;
185 i810Screen
->height
=gDRIPriv
->height
;
186 i810Screen
->mem
=gDRIPriv
->mem
;
187 i810Screen
->cpp
=gDRIPriv
->cpp
;
188 i810Screen
->fbStride
=gDRIPriv
->fbStride
;
189 i810Screen
->fbOffset
=gDRIPriv
->fbOffset
;
191 if (gDRIPriv
->bitsPerPixel
== 15)
192 i810Screen
->fbFormat
= DV_PF_555
;
194 i810Screen
->fbFormat
= DV_PF_565
;
196 i810Screen
->backOffset
=gDRIPriv
->backOffset
;
197 i810Screen
->depthOffset
=gDRIPriv
->depthOffset
;
198 i810Screen
->backPitch
= gDRIPriv
->auxPitch
;
199 i810Screen
->backPitchBits
= gDRIPriv
->auxPitchBits
;
200 i810Screen
->textureOffset
=gDRIPriv
->textureOffset
;
201 i810Screen
->textureSize
=gDRIPriv
->textureSize
;
202 i810Screen
->logTextureGranularity
= gDRIPriv
->logTextureGranularity
;
204 i810Screen
->bufs
= i810_create_empty_buffers();
205 if (i810Screen
->bufs
== NULL
) {
206 __driUtilMessage("i810InitDriver: i810_create_empty_buffers() failed");
211 i810Screen
->back
.handle
= gDRIPriv
->backbuffer
;
212 i810Screen
->back
.size
= gDRIPriv
->backbufferSize
;
214 if (drmMap(sPriv
->fd
,
215 i810Screen
->back
.handle
,
216 i810Screen
->back
.size
,
217 (drmAddress
*)&i810Screen
->back
.map
) != 0) {
219 sPriv
->private = NULL
;
220 __driUtilMessage("i810InitDriver: drmMap failed");
224 i810Screen
->depth
.handle
= gDRIPriv
->depthbuffer
;
225 i810Screen
->depth
.size
= gDRIPriv
->depthbufferSize
;
227 if (drmMap(sPriv
->fd
,
228 i810Screen
->depth
.handle
,
229 i810Screen
->depth
.size
,
230 (drmAddress
*)&i810Screen
->depth
.map
) != 0) {
231 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
233 sPriv
->private = NULL
;
234 __driUtilMessage("i810InitDriver: drmMap (2) failed");
238 i810Screen
->tex
.handle
= gDRIPriv
->textures
;
239 i810Screen
->tex
.size
= gDRIPriv
->textureSize
;
241 if (drmMap(sPriv
->fd
,
242 i810Screen
->tex
.handle
,
243 i810Screen
->tex
.size
,
244 (drmAddress
*)&i810Screen
->tex
.map
) != 0) {
245 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
246 drmUnmap(i810Screen
->depth
.map
, i810Screen
->depth
.size
);
248 sPriv
->private = NULL
;
249 __driUtilMessage("i810InitDriver: drmMap (3) failed");
253 i810Screen
->sarea_priv_offset
= gDRIPriv
->sarea_priv_offset
;
255 return i810FillInModes(sPriv
, 16, 16, 0, 1);
259 i810DestroyScreen(__DRIscreenPrivate
*sPriv
)
261 i810ScreenPrivate
*i810Screen
= (i810ScreenPrivate
*)sPriv
->private;
263 /* Need to unmap all the bufs and maps here:
265 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
266 drmUnmap(i810Screen
->depth
.map
, i810Screen
->depth
.size
);
267 drmUnmap(i810Screen
->tex
.map
, i810Screen
->tex
.size
);
270 sPriv
->private = NULL
;
275 * Create a buffer which corresponds to the window.
278 i810CreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
279 __DRIdrawablePrivate
*driDrawPriv
,
280 const __GLcontextModes
*mesaVis
,
283 i810ScreenPrivate
*screen
= (i810ScreenPrivate
*) driScrnPriv
->private;
286 return GL_FALSE
; /* not implemented */
289 struct gl_framebuffer
*fb
= _mesa_create_framebuffer(mesaVis
);
292 driRenderbuffer
*frontRb
293 = driNewRenderbuffer(GL_RGBA
,
296 /*screen->frontOffset*/0, screen
->backPitch
,
298 i810SetSpanFunctions(frontRb
, mesaVis
);
299 _mesa_add_renderbuffer(fb
, BUFFER_FRONT_LEFT
, &frontRb
->Base
);
302 if (mesaVis
->doubleBufferMode
) {
303 driRenderbuffer
*backRb
304 = driNewRenderbuffer(GL_RGBA
,
307 screen
->backOffset
, screen
->backPitch
,
309 i810SetSpanFunctions(backRb
, mesaVis
);
310 _mesa_add_renderbuffer(fb
, BUFFER_BACK_LEFT
, &backRb
->Base
);
313 if (mesaVis
->depthBits
== 16) {
314 driRenderbuffer
*depthRb
315 = driNewRenderbuffer(GL_DEPTH_COMPONENT16
,
318 screen
->depthOffset
, screen
->backPitch
,
320 i810SetSpanFunctions(depthRb
, mesaVis
);
321 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &depthRb
->Base
);
324 _mesa_add_soft_renderbuffers(fb
,
325 GL_FALSE
, /* color */
326 GL_FALSE
, /* depth */
327 mesaVis
->stencilBits
> 0,
328 mesaVis
->accumRedBits
> 0,
329 GL_FALSE
, /* alpha */
331 driDrawPriv
->driverPrivate
= (void *) fb
;
333 return (driDrawPriv
->driverPrivate
!= NULL
);
339 i810DestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
341 _mesa_unreference_framebuffer((GLframebuffer
**)(&(driDrawPriv
->driverPrivate
)));
344 const struct __DriverAPIRec driDriverAPI
= {
345 .InitScreen
= i810InitScreen
,
346 .DestroyScreen
= i810DestroyScreen
,
347 .CreateContext
= i810CreateContext
,
348 .DestroyContext
= i810DestroyContext
,
349 .CreateBuffer
= i810CreateBuffer
,
350 .DestroyBuffer
= i810DestroyBuffer
,
351 .SwapBuffers
= i810SwapBuffers
,
352 .MakeCurrent
= i810MakeCurrent
,
353 .UnbindContext
= i810UnbindContext
,
355 .GetDrawableMSC
= NULL
,
358 .SwapBuffersMSC
= NULL