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/i830/i830_screen.c,v 1.3 2002/12/10 01:26:53 dawes Exp $ */
31 * Keith Whitwell <keith@tungstengraphics.com>
32 * Adapted for use on the I830M:
33 * Jeff Hartmann <jhartmann@2d3d.com>
40 #include "simple_list.h"
42 #include "i830_screen.h"
45 #include "i830_state.h"
47 #include "i830_span.h"
48 #include "i830_tris.h"
49 #include "i830_ioctl.h"
54 static int i830_malloc_proxy_buf(drmBufMapPtr buffers
)
60 buffer
= ALIGN_MALLOC(I830_DMA_BUF_SZ
, 32);
61 if(buffer
== NULL
) return -1;
62 for(i
= 0; i
< I830_DMA_BUF_NR
; i
++) {
63 buf
= &(buffers
->list
[i
]);
64 buf
->address
= (drmAddress
)buffer
;
70 static drmBufMapPtr
i830_create_empty_buffers(void)
74 retval
= (drmBufMapPtr
)ALIGN_MALLOC(sizeof(drmBufMap
), 32);
75 if(retval
== NULL
) return NULL
;
76 memset(retval
, 0, sizeof(drmBufMap
));
77 retval
->list
= (drmBufPtr
)ALIGN_MALLOC(sizeof(drmBuf
) * I830_DMA_BUF_NR
, 32);
78 if(retval
->list
== NULL
) {
83 memset(retval
->list
, 0, sizeof(drmBuf
) * I830_DMA_BUF_NR
);
87 static void i830PrintDRIInfo(i830ScreenPrivate
*i830Screen
,
88 __DRIscreenPrivate
*sPriv
,
91 GLuint size
= (gDRIPriv
->ringSize
+
92 i830Screen
->textureSize
+
93 i830Screen
->depth
.size
+
94 i830Screen
->back
.size
+
96 I830_DMA_BUF_NR
* I830_DMA_BUF_SZ
+
97 32768 /* Context Memory */ +
98 16*4096 /* Ring buffer */ +
99 64*1024 /* Scratch buffer */ +
101 GLuint size_low
= (gDRIPriv
->ringSize
+
102 i830Screen
->textureSize
+
104 I830_DMA_BUF_NR
* I830_DMA_BUF_SZ
+
105 32768 /* Context Memory */ +
106 16*4096 /* Ring buffer */ +
107 64*1024 /* Scratch buffer */);
109 fprintf(stderr
, "\nFront size : 0x%x\n", sPriv
->fbSize
);
110 fprintf(stderr
, "Front offset : 0x%x\n", i830Screen
->fbOffset
);
111 fprintf(stderr
, "Back size : 0x%x\n", i830Screen
->back
.size
);
112 fprintf(stderr
, "Back offset : 0x%x\n", i830Screen
->backOffset
);
113 fprintf(stderr
, "Depth size : 0x%x\n", i830Screen
->depth
.size
);
114 fprintf(stderr
, "Depth offset : 0x%x\n", i830Screen
->depthOffset
);
115 fprintf(stderr
, "Texture size : 0x%x\n", i830Screen
->textureSize
);
116 fprintf(stderr
, "Texture offset : 0x%x\n", i830Screen
->textureOffset
);
117 fprintf(stderr
, "Ring offset : 0x%x\n", gDRIPriv
->ringOffset
);
118 fprintf(stderr
, "Ring size : 0x%x\n", gDRIPriv
->ringSize
);
119 fprintf(stderr
, "Memory : 0x%x\n", gDRIPriv
->mem
);
120 fprintf(stderr
, "Used Memory : low(0x%x) high(0x%x)\n", size_low
, size
);
123 static GLboolean
i830InitDriver(__DRIscreenPrivate
*sPriv
)
125 i830ScreenPrivate
*i830Screen
;
126 I830DRIPtr gDRIPriv
= (I830DRIPtr
)sPriv
->pDevPriv
;
128 /* Check the DRI externsion version */
129 if ( sPriv
->driMajor
!= 4 || sPriv
->driMinor
< 0 ) {
130 __driUtilMessage( "i830 DRI driver expected DRI version 4.0.x "
131 "but got version %d.%d.%d",
132 sPriv
->driMajor
, sPriv
->driMinor
, sPriv
->driPatch
);
136 /* Check that the DDX driver version is compatible */
137 if (sPriv
->ddxMajor
!= 1 || sPriv
->ddxMinor
< 0) {
138 __driUtilMessage("i830 DRI driver expected DDX driver version 1.0.x but got version %d.%d.%d", sPriv
->ddxMajor
, sPriv
->ddxMinor
, sPriv
->ddxPatch
);
142 /* Check that the DRM driver version is compatible */
143 if (sPriv
->drmMajor
!= 1 || sPriv
->drmMinor
< 3) {
144 __driUtilMessage("i830 DRI driver expected DRM driver version 1.3.x but got version %d.%d.%d", sPriv
->drmMajor
, sPriv
->drmMinor
, sPriv
->drmPatch
);
148 /* Allocate the private area */
149 i830Screen
= (i830ScreenPrivate
*)CALLOC(sizeof(i830ScreenPrivate
));
151 fprintf(stderr
,"\nERROR! Allocating private area failed\n");
155 i830Screen
->driScrnPriv
= sPriv
;
156 sPriv
->private = (void *)i830Screen
;
158 i830Screen
->deviceID
= gDRIPriv
->deviceID
;
159 i830Screen
->width
= gDRIPriv
->width
;
160 i830Screen
->height
= gDRIPriv
->height
;
161 i830Screen
->mem
= gDRIPriv
->mem
;
162 i830Screen
->cpp
= gDRIPriv
->cpp
;
163 i830Screen
->fbStride
= gDRIPriv
->fbStride
;
164 i830Screen
->fbOffset
= gDRIPriv
->fbOffset
;
166 switch (gDRIPriv
->bitsPerPixel
) {
167 case 15: i830Screen
->fbFormat
= DV_PF_555
; break;
168 case 16: i830Screen
->fbFormat
= DV_PF_565
; break;
169 case 32: i830Screen
->fbFormat
= DV_PF_8888
; break;
172 i830Screen
->backOffset
= gDRIPriv
->backOffset
;
173 i830Screen
->depthOffset
= gDRIPriv
->depthOffset
;
174 i830Screen
->backPitch
= gDRIPriv
->auxPitch
;
175 i830Screen
->backPitchBits
= gDRIPriv
->auxPitchBits
;
176 i830Screen
->textureOffset
= gDRIPriv
->textureOffset
;
177 i830Screen
->textureSize
= gDRIPriv
->textureSize
;
178 i830Screen
->logTextureGranularity
= gDRIPriv
->logTextureGranularity
;
181 i830Screen
->bufs
= i830_create_empty_buffers();
182 if(i830Screen
->bufs
== NULL
) {
183 fprintf(stderr
,"\nERROR: Failed to create empty buffers in %s \n",
189 /* Check if you need to create a fake buffer */
190 if(i830_check_copy(sPriv
->fd
) == 1) {
191 i830_malloc_proxy_buf(i830Screen
->bufs
);
192 i830Screen
->use_copy_buf
= 1;
194 i830Screen
->use_copy_buf
= 0;
197 i830Screen
->back
.handle
= gDRIPriv
->backbuffer
;
198 i830Screen
->back
.size
= gDRIPriv
->backbufferSize
;
200 if (drmMap(sPriv
->fd
,
201 i830Screen
->back
.handle
,
202 i830Screen
->back
.size
,
203 (drmAddress
*)&i830Screen
->back
.map
) != 0) {
204 fprintf(stderr
, "\nERROR: line %d, Function %s, File %s\n",
205 __LINE__
, __FUNCTION__
, __FILE__
);
207 sPriv
->private = NULL
;
211 i830Screen
->depth
.handle
= gDRIPriv
->depthbuffer
;
212 i830Screen
->depth
.size
= gDRIPriv
->depthbufferSize
;
214 if (drmMap(sPriv
->fd
,
215 i830Screen
->depth
.handle
,
216 i830Screen
->depth
.size
,
217 (drmAddress
*)&i830Screen
->depth
.map
) != 0) {
218 fprintf(stderr
, "\nERROR: line %d, Function %s, File %s\n",
219 __LINE__
, __FUNCTION__
, __FILE__
);
221 drmUnmap(i830Screen
->back
.map
, i830Screen
->back
.size
);
222 sPriv
->private = NULL
;
226 i830Screen
->tex
.handle
= gDRIPriv
->textures
;
227 i830Screen
->tex
.size
= gDRIPriv
->textureSize
;
229 if (drmMap(sPriv
->fd
,
230 i830Screen
->tex
.handle
,
231 i830Screen
->tex
.size
,
232 (drmAddress
*)&i830Screen
->tex
.map
) != 0) {
233 fprintf(stderr
, "\nERROR: line %d, Function %s, File %s\n",
234 __LINE__
, __FUNCTION__
, __FILE__
);
236 drmUnmap(i830Screen
->back
.map
, i830Screen
->back
.size
);
237 drmUnmap(i830Screen
->depth
.map
, i830Screen
->depth
.size
);
238 sPriv
->private = NULL
;
242 i830Screen
->sarea_priv_offset
= gDRIPriv
->sarea_priv_offset
;
244 if (0) i830PrintDRIInfo(i830Screen
, sPriv
, gDRIPriv
);
246 i830Screen
->drmMinor
= sPriv
->drmMinor
;
248 if (sPriv
->drmMinor
>= 3) {
252 gp
.param
= I830_PARAM_IRQ_ACTIVE
;
253 gp
.value
= &i830Screen
->irq_active
;
255 ret
= drmCommandWriteRead( sPriv
->fd
, DRM_I830_GETPARAM
,
258 fprintf(stderr
, "drmI830GetParam: %d\n", ret
);
264 if (sPriv
->drmMinor
>= 3) {
268 sp
.param
= I830_SETPARAM_PERF_BOXES
;
269 sp
.value
= (getenv("I830_DO_BOXES") != 0);
271 ret
= drmCommandWrite( sPriv
->fd
, DRM_I830_SETPARAM
,
274 fprintf(stderr
, "Couldn't set perfboxes: %d\n", ret
);
282 static void i830DestroyScreen(__DRIscreenPrivate
*sPriv
)
284 i830ScreenPrivate
*i830Screen
= (i830ScreenPrivate
*)sPriv
->private;
286 /* Need to unmap all the bufs and maps here:
288 drmUnmap(i830Screen
->back
.map
, i830Screen
->back
.size
);
289 drmUnmap(i830Screen
->depth
.map
, i830Screen
->depth
.size
);
290 drmUnmap(i830Screen
->tex
.map
, i830Screen
->tex
.size
);
292 sPriv
->private = NULL
;
295 static GLboolean
i830CreateBuffer(__DRIscreenPrivate
*driScrnPriv
,
296 __DRIdrawablePrivate
*driDrawPriv
,
297 const __GLcontextModes
*mesaVis
,
301 return GL_FALSE
; /* not implemented */
304 GLboolean swStencil
= (mesaVis
->stencilBits
> 0 &&
305 mesaVis
->depthBits
!= 24);
307 GLboolean swStencil
= mesaVis
->stencilBits
> 0;
309 driDrawPriv
->driverPrivate
= (void *)
310 _mesa_create_framebuffer(mesaVis
,
311 GL_FALSE
, /* software depth buffer? */
313 mesaVis
->accumRedBits
> 0,
314 GL_FALSE
/* s/w alpha planes */);
316 return (driDrawPriv
->driverPrivate
!= NULL
);
320 static void i830DestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
322 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->driverPrivate
));
325 static GLboolean
i830OpenCloseFullScreen (__DRIcontextPrivate
*driContextPriv
)
330 static const struct __DriverAPIRec i830API
= {
331 .InitDriver
= i830InitDriver
,
332 .DestroyScreen
= i830DestroyScreen
,
333 .CreateContext
= i830CreateContext
,
334 .DestroyContext
= i830DestroyContext
,
335 .CreateBuffer
= i830CreateBuffer
,
336 .DestroyBuffer
= i830DestroyBuffer
,
337 .SwapBuffers
= i830SwapBuffers
,
338 .MakeCurrent
= i830MakeCurrent
,
339 .UnbindContext
= i830UnbindContext
,
340 .OpenFullScreen
= i830OpenCloseFullScreen
,
341 .CloseFullScreen
= i830OpenCloseFullScreen
,
346 .SwapBuffersMSC
= NULL
351 * This is the bootstrap function for the driver.
352 * The __driCreateScreen name is the symbol that libGL.so fetches.
353 * Return: pointer to a __DRIscreenPrivate.
356 void *__driCreateScreen(Display
*dpy
, int scrn
, __DRIscreen
*psc
,
357 int numConfigs
, __GLXvisualConfig
*config
)
359 __DRIscreenPrivate
*psp
;
360 psp
= __driUtilCreateScreen(dpy
, scrn
, psc
, numConfigs
, config
, &i830API
);
364 void *__driCreateScreen(struct DRIDriverRec
*driver
,
365 struct DRIDriverContextRec
*driverContext
)
367 __DRIscreenPrivate
*psp
;
368 psp
= __driUtilCreateScreen(driver
, driverContext
, &i830API
);