1 /* -*- mode: c; c-basic-offset: 3 -*- */
3 * Copyright 2000 Gareth Hughes
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Gareth Hughes <gareth@valinux.com>
28 * Leif Delgass <ldelgass@retinalburn.net>
29 * Jos�Fonseca <j_r_fonseca@yahoo.co.uk>
32 #include "mach64_context.h"
33 #include "mach64_ioctl.h"
34 #include "mach64_span.h"
36 #include "main/context.h"
37 #include "main/imports.h"
38 #include "main/framebuffer.h"
39 #include "main/renderbuffer.h"
44 #include "GL/internal/dri_interface.h"
46 /* Mach64 configuration
50 PUBLIC
const char __driConfigOptions
[] =
52 DRI_CONF_SECTION_PERFORMANCE
53 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0
)
55 DRI_CONF_SECTION_DEBUG
56 DRI_CONF_NO_RAST(false)
58 DRI_CONF_PERFORMANCE_BOXES(false)
63 static const GLuint __driNConfigOptions
= 3;
65 static const GLuint __driNConfigOptions
= 2;
68 static const __DRIconfig
**
69 mach64FillInModes( __DRIscreen
*psp
,
70 unsigned pixel_bits
, unsigned depth_bits
,
71 unsigned stencil_bits
, GLboolean have_back_buffer
)
73 __DRIconfig
**configs
;
77 unsigned depth_buffer_factor
;
78 unsigned back_buffer_factor
;
81 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
82 * enough to add support. Basically, if a context is created with an
83 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
86 static const GLenum back_buffer_modes
[] = {
87 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
/*, GLX_SWAP_COPY_OML */
90 uint8_t depth_bits_array
[2];
91 uint8_t stencil_bits_array
[2];
92 uint8_t msaa_samples_array
[1];
94 depth_bits_array
[0] = depth_bits
;
95 depth_bits_array
[1] = depth_bits
;
97 /* Just like with the accumulation buffer, always provide some modes
98 * with a stencil buffer. It will be a sw fallback, but some apps won't
101 stencil_bits_array
[0] = 0;
102 stencil_bits_array
[1] = (stencil_bits
== 0) ? 8 : stencil_bits
;
104 msaa_samples_array
[0] = 0;
106 depth_buffer_factor
= ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 2 : 1;
107 back_buffer_factor
= (have_back_buffer
) ? 2 : 1;
109 if (pixel_bits
== 16) {
111 fb_type
= GL_UNSIGNED_SHORT_5_6_5
;
115 fb_type
= GL_UNSIGNED_INT_8_8_8_8_REV
;
118 configs
= driCreateConfigs(fb_format
, fb_type
,
119 depth_bits_array
, stencil_bits_array
,
120 depth_buffer_factor
, back_buffer_modes
,
122 msaa_samples_array
, 1);
123 if (configs
== NULL
) {
124 fprintf(stderr
, "[%s:%u] Error creating FBConfig!\n",
129 /* Mark the visual as slow if there are "fake" stencil bits.
131 for (i
= 0; configs
[i
]; i
++) {
132 m
= &configs
[i
]->modes
;
133 if ((m
->stencilBits
!= 0) && (m
->stencilBits
!= stencil_bits
)) {
134 m
->visualRating
= GLX_SLOW_CONFIG
;
138 return (const __DRIconfig
**) configs
;
142 /* Create the device specific screen private data struct.
144 static mach64ScreenRec
*
145 mach64CreateScreen( __DRIscreen
*sPriv
)
147 mach64ScreenPtr mach64Screen
;
148 ATIDRIPtr serverInfo
= (ATIDRIPtr
)sPriv
->pDevPriv
;
151 if (sPriv
->devPrivSize
!= sizeof(ATIDRIRec
)) {
152 fprintf(stderr
,"\nERROR! sizeof(ATIDRIRec) does not match passed size from device driver\n");
156 if ( MACH64_DEBUG
& DEBUG_VERBOSE_DRI
)
157 fprintf( stderr
, "%s\n", __FUNCTION__
);
159 /* Allocate the private area */
160 mach64Screen
= (mach64ScreenPtr
) CALLOC( sizeof(*mach64Screen
) );
161 if ( !mach64Screen
) return NULL
;
163 /* parse information in __driConfigOptions */
164 driParseOptionInfo (&mach64Screen
->optionCache
,
165 __driConfigOptions
, __driNConfigOptions
);
167 mach64Screen
->IsPCI
= serverInfo
->IsPCI
;
170 drm_mach64_getparam_t gp
;
173 gp
.param
= MACH64_PARAM_IRQ_NR
;
174 gp
.value
= (void *) &mach64Screen
->irq
;
176 ret
= drmCommandWriteRead( sPriv
->fd
, DRM_MACH64_GETPARAM
,
179 fprintf(stderr
, "DRM_MACH64_GETPARAM (MACH64_PARAM_IRQ_NR): %d\n", ret
);
180 FREE( mach64Screen
);
185 mach64Screen
->mmio
.handle
= serverInfo
->regs
;
186 mach64Screen
->mmio
.size
= serverInfo
->regsSize
;
187 if ( drmMap( sPriv
->fd
,
188 mach64Screen
->mmio
.handle
,
189 mach64Screen
->mmio
.size
,
190 (drmAddressPtr
)&mach64Screen
->mmio
.map
) != 0 ) {
191 FREE( mach64Screen
);
195 mach64Screen
->buffers
= drmMapBufs( sPriv
->fd
);
196 if ( !mach64Screen
->buffers
) {
197 drmUnmap( (drmAddress
)mach64Screen
->mmio
.map
,
198 mach64Screen
->mmio
.size
);
199 FREE( mach64Screen
);
203 if ( !mach64Screen
->IsPCI
) {
204 mach64Screen
->agpTextures
.handle
= serverInfo
->agp
;
205 mach64Screen
->agpTextures
.size
= serverInfo
->agpSize
;
206 if ( drmMap( sPriv
->fd
,
207 mach64Screen
->agpTextures
.handle
,
208 mach64Screen
->agpTextures
.size
,
209 (drmAddressPtr
)&mach64Screen
->agpTextures
.map
) ) {
210 drmUnmapBufs( mach64Screen
->buffers
);
211 drmUnmap( (drmAddress
)mach64Screen
->mmio
.map
, mach64Screen
->mmio
.size
);
212 FREE( mach64Screen
);
217 mach64Screen
->AGPMode
= serverInfo
->AGPMode
;
219 mach64Screen
->chipset
= serverInfo
->chipset
;
220 mach64Screen
->width
= serverInfo
->width
;
221 mach64Screen
->height
= serverInfo
->height
;
222 mach64Screen
->mem
= serverInfo
->mem
;
223 mach64Screen
->cpp
= serverInfo
->cpp
;
225 mach64Screen
->frontOffset
= serverInfo
->frontOffset
;
226 mach64Screen
->frontPitch
= serverInfo
->frontPitch
;
227 mach64Screen
->backOffset
= serverInfo
->backOffset
;
228 mach64Screen
->backPitch
= serverInfo
->backPitch
;
229 mach64Screen
->depthOffset
= serverInfo
->depthOffset
;
230 mach64Screen
->depthPitch
= serverInfo
->depthPitch
;
232 mach64Screen
->texOffset
[MACH64_CARD_HEAP
] = serverInfo
->textureOffset
;
233 mach64Screen
->texSize
[MACH64_CARD_HEAP
] = serverInfo
->textureSize
;
234 mach64Screen
->logTexGranularity
[MACH64_CARD_HEAP
] =
235 serverInfo
->logTextureGranularity
;
237 if ( mach64Screen
->IsPCI
) {
238 mach64Screen
->numTexHeaps
= MACH64_NR_TEX_HEAPS
- 1;
239 mach64Screen
->firstTexHeap
= MACH64_CARD_HEAP
;
240 mach64Screen
->texOffset
[MACH64_AGP_HEAP
] = 0;
241 mach64Screen
->texSize
[MACH64_AGP_HEAP
] = 0;
242 mach64Screen
->logTexGranularity
[MACH64_AGP_HEAP
] = 0;
244 if (serverInfo
->textureSize
> 0) {
245 mach64Screen
->numTexHeaps
= MACH64_NR_TEX_HEAPS
;
246 mach64Screen
->firstTexHeap
= MACH64_CARD_HEAP
;
248 mach64Screen
->numTexHeaps
= MACH64_NR_TEX_HEAPS
- 1;
249 mach64Screen
->firstTexHeap
= MACH64_AGP_HEAP
;
251 mach64Screen
->texOffset
[MACH64_AGP_HEAP
] = serverInfo
->agpTextureOffset
;
252 mach64Screen
->texSize
[MACH64_AGP_HEAP
] = serverInfo
->agpSize
;
253 mach64Screen
->logTexGranularity
[MACH64_AGP_HEAP
] = serverInfo
->logAgpTextureGranularity
;
256 mach64Screen
->driScreen
= sPriv
;
259 mach64Screen
->extensions
[i
++] = &driFrameTrackingExtension
.base
;
260 if ( mach64Screen
->irq
!= 0 ) {
261 mach64Screen
->extensions
[i
++] = &driSwapControlExtension
.base
;
262 mach64Screen
->extensions
[i
++] = &driMediaStreamCounterExtension
.base
;
264 mach64Screen
->extensions
[i
++] = NULL
;
265 sPriv
->extensions
= mach64Screen
->extensions
;
270 /* Destroy the device specific screen private data struct.
273 mach64DestroyScreen( __DRIscreen
*driScreen
)
275 mach64ScreenRec
*mach64Screen
= (mach64ScreenRec
*) driScreen
->private;
280 if ( MACH64_DEBUG
& DEBUG_VERBOSE_DRI
)
281 fprintf( stderr
, "%s\n", __FUNCTION__
);
283 if ( !mach64Screen
->IsPCI
) {
284 drmUnmap( (drmAddress
)mach64Screen
->agpTextures
.map
,
285 mach64Screen
->agpTextures
.size
);
288 drmUnmapBufs( mach64Screen
->buffers
);
289 drmUnmap( (drmAddress
)mach64Screen
->mmio
.map
, mach64Screen
->mmio
.size
);
291 FREE( mach64Screen
);
292 driScreen
->private = NULL
;
296 /* Create and initialize the Mesa and driver specific pixmap buffer
300 mach64CreateBuffer( __DRIscreen
*driScrnPriv
,
301 __DRIdrawable
*driDrawPriv
,
302 const __GLcontextModes
*mesaVis
,
305 mach64ScreenPtr screen
= (mach64ScreenPtr
) driScrnPriv
->private;
308 return GL_FALSE
; /* not implemented */
311 struct gl_framebuffer
*fb
= _mesa_create_framebuffer(mesaVis
);
314 driRenderbuffer
*frontRb
315 = driNewRenderbuffer(MESA_FORMAT_ARGB8888
,
318 screen
->frontOffset
, screen
->frontPitch
,
320 mach64SetSpanFunctions(frontRb
, mesaVis
);
321 _mesa_add_renderbuffer(fb
, BUFFER_FRONT_LEFT
, &frontRb
->Base
);
324 if (mesaVis
->doubleBufferMode
) {
325 driRenderbuffer
*backRb
326 = driNewRenderbuffer(MESA_FORMAT_ARGB8888
,
329 screen
->backOffset
, screen
->backPitch
,
331 mach64SetSpanFunctions(backRb
, mesaVis
);
332 _mesa_add_renderbuffer(fb
, BUFFER_BACK_LEFT
, &backRb
->Base
);
335 if (mesaVis
->depthBits
== 16) {
336 driRenderbuffer
*depthRb
337 = driNewRenderbuffer(MESA_FORMAT_Z16
,
339 screen
->depthOffset
, screen
->depthPitch
,
341 mach64SetSpanFunctions(depthRb
, mesaVis
);
342 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &depthRb
->Base
);
344 else if (mesaVis
->depthBits
== 24) {
345 /* XXX I don't think 24-bit Z is supported - so this isn't used */
346 driRenderbuffer
*depthRb
347 = driNewRenderbuffer(MESA_FORMAT_Z24_S8
,
350 screen
->depthOffset
, screen
->depthPitch
,
352 mach64SetSpanFunctions(depthRb
, mesaVis
);
353 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &depthRb
->Base
);
356 _mesa_add_soft_renderbuffers(fb
,
357 GL_FALSE
, /* color */
358 GL_FALSE
, /* depth */
359 mesaVis
->stencilBits
> 0,
360 mesaVis
->accumRedBits
> 0,
361 GL_FALSE
, /* alpha */
363 driDrawPriv
->driverPrivate
= (void *) fb
;
365 return (driDrawPriv
->driverPrivate
!= NULL
);
371 mach64DestroyBuffer(__DRIdrawable
*driDrawPriv
)
373 _mesa_reference_framebuffer((GLframebuffer
**)(&(driDrawPriv
->driverPrivate
)), NULL
);
377 /* Copy the back color buffer to the front color buffer */
379 mach64SwapBuffers(__DRIdrawable
*dPriv
)
381 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
382 mach64ContextPtr mmesa
;
384 mmesa
= (mach64ContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
386 if (ctx
->Visual
.doubleBufferMode
) {
387 _mesa_notifySwapBuffers( ctx
); /* flush pending rendering comands */
388 mach64CopyBuffer( dPriv
);
392 /* XXX this shouldn't be an error but we can't handle it for now */
393 _mesa_problem(NULL
, "%s: drawable has no context!", __FUNCTION__
);
398 /* Initialize the driver specific screen private data.
401 mach64InitDriver( __DRIscreen
*driScreen
)
403 driScreen
->private = (void *) mach64CreateScreen( driScreen
);
405 if ( !driScreen
->private ) {
406 mach64DestroyScreen( driScreen
);
414 * This is the driver specific part of the createNewScreen entry point.
416 * \todo maybe fold this into intelInitDriver
418 * \return the __GLcontextModes supported by this driver
420 static const __DRIconfig
**
421 mach64InitScreen(__DRIscreen
*psp
)
423 static const __DRIversion ddx_expected
= { 6, 4, 0 };
424 static const __DRIversion dri_expected
= { 4, 0, 0 };
425 static const __DRIversion drm_expected
= { 2, 0, 0 };
426 ATIDRIPtr dri_priv
= (ATIDRIPtr
) psp
->pDevPriv
;
428 if ( ! driCheckDriDdxDrmVersions2( "Mach64",
429 &psp
->dri_version
, & dri_expected
,
430 &psp
->ddx_version
, & ddx_expected
,
431 &psp
->drm_version
, & drm_expected
) ) {
435 if (!mach64InitDriver(psp
))
438 return mach64FillInModes( psp
, dri_priv
->cpp
* 8, 16, 0, 1);
441 const struct __DriverAPIRec driDriverAPI
= {
442 .InitScreen
= mach64InitScreen
,
443 .DestroyScreen
= mach64DestroyScreen
,
444 .CreateContext
= mach64CreateContext
,
445 .DestroyContext
= mach64DestroyContext
,
446 .CreateBuffer
= mach64CreateBuffer
,
447 .DestroyBuffer
= mach64DestroyBuffer
,
448 .SwapBuffers
= mach64SwapBuffers
,
449 .MakeCurrent
= mach64MakeCurrent
,
450 .UnbindContext
= mach64UnbindContext
,
452 .GetDrawableMSC
= driDrawableGetMSC32
,
453 .WaitForMSC
= driWaitForMSC32
,
455 .SwapBuffersMSC
= NULL
458 /* This is the table of extensions that the loader will dlsym() for. */
459 PUBLIC
const __DRIextension
*__driDriverExtensions
[] = {
460 &driCoreExtension
.base
,
461 &driLegacyExtension
.base
,