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>
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/context.h"
38 #include "main/framebuffer.h"
39 #include "main/renderbuffer.h"
40 #include "main/simple_list.h"
43 #include "i810screen.h"
46 #include "i810state.h"
50 #include "GL/internal/dri_interface.h"
52 static const __DRIconfig
**
53 i810FillInModes( __DRIscreen
*psp
,
54 unsigned pixel_bits
, unsigned depth_bits
,
55 unsigned stencil_bits
, GLboolean have_back_buffer
)
57 __DRIconfig
**configs
;
59 unsigned depth_buffer_factor
;
60 unsigned back_buffer_factor
;
63 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
64 * enough to add support. Basically, if a context is created with an
65 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
68 static const GLenum back_buffer_modes
[] = {
69 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
/*, GLX_SWAP_COPY_OML */
72 uint8_t depth_bits_array
[2];
73 uint8_t stencil_bits_array
[2];
74 uint8_t msaa_samples_array
[1];
76 depth_bits_array
[0] = depth_bits
;
77 depth_bits_array
[1] = depth_bits
;
79 /* Just like with the accumulation buffer, always provide some modes
80 * with a stencil buffer. It will be a sw fallback, but some apps won't
83 stencil_bits_array
[0] = 0;
84 stencil_bits_array
[1] = (stencil_bits
== 0) ? 8 : stencil_bits
;
86 msaa_samples_array
[0] = 0;
88 depth_buffer_factor
= ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 2 : 1;
89 back_buffer_factor
= (have_back_buffer
) ? 2 : 1;
91 configs
= driCreateConfigs(GL_RGB
, GL_UNSIGNED_SHORT_5_6_5
,
92 depth_bits_array
, stencil_bits_array
,
94 back_buffer_modes
, back_buffer_factor
,
95 msaa_samples_array
, 1, GL_TRUE
);
96 if (configs
== NULL
) {
97 fprintf( stderr
, "[%s:%u] Error creating FBConfig!\n",
102 /* Mark the visual as slow if there are "fake" stencil bits.
104 for (i
= 0; configs
[i
]; i
++) {
105 m
= &configs
[i
]->modes
;
106 if ((m
->stencilBits
!= 0) && (m
->stencilBits
!= stencil_bits
)) {
107 m
->visualRating
= GLX_SLOW_CONFIG
;
111 return (const __DRIconfig
**) configs
;
115 /* static int i810_malloc_proxy_buf(drmBufMapPtr buffers) */
121 /* buffer = CALLOC(I810_DMA_BUF_SZ); */
122 /* if(buffer == NULL) return -1; */
123 /* for(i = 0; i < I810_DMA_BUF_NR; i++) { */
124 /* buf = &(buffers->list[i]); */
125 /* buf->address = (drmAddress)buffer; */
130 static drmBufMapPtr
i810_create_empty_buffers(void)
134 retval
= (drmBufMapPtr
)_mesa_align_malloc(sizeof(drmBufMap
), 32);
135 if(retval
== NULL
) return NULL
;
136 memset(retval
, 0, sizeof(drmBufMap
));
137 retval
->list
= (drmBufPtr
)_mesa_align_malloc(sizeof(drmBuf
) * I810_DMA_BUF_NR
, 32);
138 if(retval
->list
== NULL
) {
139 _mesa_align_free(retval
);
142 memset(retval
->list
, 0, sizeof(drmBuf
) * I810_DMA_BUF_NR
);
147 static const __DRIconfig
**
148 i810InitScreen(__DRIscreen
*sPriv
)
150 static const __DRIversion ddx_expected
= { 1, 0, 0 };
151 static const __DRIversion dri_expected
= { 4, 0, 0 };
152 static const __DRIversion drm_expected
= { 1, 2, 0 };
153 i810ScreenPrivate
*i810Screen
;
154 I810DRIPtr gDRIPriv
= (I810DRIPtr
)sPriv
->pDevPriv
;
156 if ( ! driCheckDriDdxDrmVersions2( "i810",
157 &sPriv
->dri_version
, & dri_expected
,
158 &sPriv
->ddx_version
, & ddx_expected
,
159 &sPriv
->drm_version
, & drm_expected
) ) {
163 if (sPriv
->devPrivSize
!= sizeof(I810DRIRec
)) {
164 fprintf(stderr
,"\nERROR! sizeof(I810DRIRec) does not match passed size from device driver\n");
168 /* Allocate the private area */
169 i810Screen
= (i810ScreenPrivate
*)CALLOC(sizeof(i810ScreenPrivate
));
171 __driUtilMessage("i810InitDriver: alloc i810ScreenPrivate struct failed");
175 i810Screen
->driScrnPriv
= sPriv
;
176 sPriv
->private = (void *)i810Screen
;
178 i810Screen
->deviceID
=gDRIPriv
->deviceID
;
179 i810Screen
->width
=gDRIPriv
->width
;
180 i810Screen
->height
=gDRIPriv
->height
;
181 i810Screen
->mem
=gDRIPriv
->mem
;
182 i810Screen
->cpp
=gDRIPriv
->cpp
;
183 i810Screen
->fbStride
=gDRIPriv
->fbStride
;
184 i810Screen
->fbOffset
=gDRIPriv
->fbOffset
;
186 if (gDRIPriv
->bitsPerPixel
== 15)
187 i810Screen
->fbFormat
= DV_PF_555
;
189 i810Screen
->fbFormat
= DV_PF_565
;
191 i810Screen
->backOffset
=gDRIPriv
->backOffset
;
192 i810Screen
->depthOffset
=gDRIPriv
->depthOffset
;
193 i810Screen
->backPitch
= gDRIPriv
->auxPitch
;
194 i810Screen
->backPitchBits
= gDRIPriv
->auxPitchBits
;
195 i810Screen
->textureOffset
=gDRIPriv
->textureOffset
;
196 i810Screen
->textureSize
=gDRIPriv
->textureSize
;
197 i810Screen
->logTextureGranularity
= gDRIPriv
->logTextureGranularity
;
199 i810Screen
->bufs
= i810_create_empty_buffers();
200 if (i810Screen
->bufs
== NULL
) {
201 __driUtilMessage("i810InitDriver: i810_create_empty_buffers() failed");
206 i810Screen
->back
.handle
= gDRIPriv
->backbuffer
;
207 i810Screen
->back
.size
= gDRIPriv
->backbufferSize
;
209 if (drmMap(sPriv
->fd
,
210 i810Screen
->back
.handle
,
211 i810Screen
->back
.size
,
212 (drmAddress
*)&i810Screen
->back
.map
) != 0) {
214 sPriv
->private = NULL
;
215 __driUtilMessage("i810InitDriver: drmMap failed");
219 i810Screen
->depth
.handle
= gDRIPriv
->depthbuffer
;
220 i810Screen
->depth
.size
= gDRIPriv
->depthbufferSize
;
222 if (drmMap(sPriv
->fd
,
223 i810Screen
->depth
.handle
,
224 i810Screen
->depth
.size
,
225 (drmAddress
*)&i810Screen
->depth
.map
) != 0) {
226 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
228 sPriv
->private = NULL
;
229 __driUtilMessage("i810InitDriver: drmMap (2) failed");
233 i810Screen
->tex
.handle
= gDRIPriv
->textures
;
234 i810Screen
->tex
.size
= gDRIPriv
->textureSize
;
236 if (drmMap(sPriv
->fd
,
237 i810Screen
->tex
.handle
,
238 i810Screen
->tex
.size
,
239 (drmAddress
*)&i810Screen
->tex
.map
) != 0) {
240 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
241 drmUnmap(i810Screen
->depth
.map
, i810Screen
->depth
.size
);
243 sPriv
->private = NULL
;
244 __driUtilMessage("i810InitDriver: drmMap (3) failed");
248 i810Screen
->sarea_priv_offset
= gDRIPriv
->sarea_priv_offset
;
250 return i810FillInModes(sPriv
, 16, 16, 0, 1);
254 i810DestroyScreen(__DRIscreen
*sPriv
)
256 i810ScreenPrivate
*i810Screen
= (i810ScreenPrivate
*)sPriv
->private;
258 /* Need to unmap all the bufs and maps here:
260 drmUnmap(i810Screen
->back
.map
, i810Screen
->back
.size
);
261 drmUnmap(i810Screen
->depth
.map
, i810Screen
->depth
.size
);
262 drmUnmap(i810Screen
->tex
.map
, i810Screen
->tex
.size
);
265 sPriv
->private = NULL
;
270 * Create a buffer which corresponds to the window.
273 i810CreateBuffer( __DRIscreen
*driScrnPriv
,
274 __DRIdrawable
*driDrawPriv
,
275 const struct gl_config
*mesaVis
,
278 i810ScreenPrivate
*screen
= (i810ScreenPrivate
*) driScrnPriv
->private;
281 return GL_FALSE
; /* not implemented */
284 struct gl_framebuffer
*fb
= _mesa_create_framebuffer(mesaVis
);
287 driRenderbuffer
*frontRb
288 = driNewRenderbuffer(MESA_FORMAT_ARGB8888
,
291 /*screen->frontOffset*/0, screen
->backPitch
,
293 i810SetSpanFunctions(frontRb
, mesaVis
);
294 _mesa_add_renderbuffer(fb
, BUFFER_FRONT_LEFT
, &frontRb
->Base
);
297 if (mesaVis
->doubleBufferMode
) {
298 driRenderbuffer
*backRb
299 = driNewRenderbuffer(MESA_FORMAT_ARGB8888
,
302 screen
->backOffset
, screen
->backPitch
,
304 i810SetSpanFunctions(backRb
, mesaVis
);
305 _mesa_add_renderbuffer(fb
, BUFFER_BACK_LEFT
, &backRb
->Base
);
308 if (mesaVis
->depthBits
== 16) {
309 driRenderbuffer
*depthRb
310 = driNewRenderbuffer(MESA_FORMAT_Z16
,
313 screen
->depthOffset
, screen
->backPitch
,
315 i810SetSpanFunctions(depthRb
, mesaVis
);
316 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &depthRb
->Base
);
319 _mesa_add_soft_renderbuffers(fb
,
320 GL_FALSE
, /* color */
321 GL_FALSE
, /* depth */
322 mesaVis
->stencilBits
> 0,
323 mesaVis
->accumRedBits
> 0,
324 GL_FALSE
, /* alpha */
326 driDrawPriv
->driverPrivate
= (void *) fb
;
328 return (driDrawPriv
->driverPrivate
!= NULL
);
334 i810DestroyBuffer(__DRIdrawable
*driDrawPriv
)
336 _mesa_reference_framebuffer((struct gl_framebuffer
**)(&(driDrawPriv
->driverPrivate
)), NULL
);
339 const struct __DriverAPIRec driDriverAPI
= {
340 .InitScreen
= i810InitScreen
,
341 .DestroyScreen
= i810DestroyScreen
,
342 .CreateContext
= i810CreateContext
,
343 .DestroyContext
= i810DestroyContext
,
344 .CreateBuffer
= i810CreateBuffer
,
345 .DestroyBuffer
= i810DestroyBuffer
,
346 .SwapBuffers
= i810SwapBuffers
,
347 .MakeCurrent
= i810MakeCurrent
,
348 .UnbindContext
= i810UnbindContext
,
350 .GetDrawableMSC
= NULL
,
353 .SwapBuffersMSC
= NULL
356 /* This is the table of extensions that the loader will dlsym() for. */
357 PUBLIC
const __DRIextension
*__driDriverExtensions
[] = {
358 &driCoreExtension
.base
,
359 &driLegacyExtension
.base
,