2 /**************************************************************************
4 Copyright 2003 Eric Anholt
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ERIC ANHOLT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 **************************************************************************/
29 * Eric Anholt <anholt@FreeBSD.org>
38 #include "sis_context.h"
44 const char __driConfigOptions
[] =
46 DRI_CONF_SECTION_DEBUG
47 DRI_CONF_OPT_BEGIN(agp_disable
,bool,false)
48 DRI_CONF_DESC(en
,"Disable AGP vertex dispatch")
50 DRI_CONF_OPT_BEGIN(fallback_force
,bool,false)
51 DRI_CONF_DESC(en
,"Force software fallback")
55 static const GLuint __driNConfigOptions
= 2;
57 /* Create the device specific screen private data struct.
60 sisCreateScreen( __DRIscreenPrivate
*sPriv
)
62 sisScreenPtr sisScreen
;
63 SISDRIPtr sisDRIPriv
= (SISDRIPtr
)sPriv
->pDevPriv
;
65 if ( !driCheckDriDdxDrmVersions( sPriv
, "SiS", 4, 0, 0, 1, 1, 0 ) )
68 /* Allocate the private area */
69 sisScreen
= (sisScreenPtr
)CALLOC( sizeof(*sisScreen
) );
70 if ( sisScreen
== NULL
)
73 sisScreen
->screenX
= sisDRIPriv
->width
;
74 sisScreen
->screenY
= sisDRIPriv
->height
;
75 sisScreen
->cpp
= sisDRIPriv
->bytesPerPixel
;
76 sisScreen
->irqEnabled
= sisDRIPriv
->bytesPerPixel
;
77 sisScreen
->deviceID
= sisDRIPriv
->deviceID
;
78 sisScreen
->AGPCmdBufOffset
= sisDRIPriv
->AGPCmdBufOffset
;
79 sisScreen
->AGPCmdBufSize
= sisDRIPriv
->AGPCmdBufSize
;
80 sisScreen
->sarea_priv_offset
= sizeof(drm_sarea_t
);
82 sisScreen
->mmio
.handle
= sisDRIPriv
->regs
.handle
;
83 sisScreen
->mmio
.size
= sisDRIPriv
->regs
.size
;
84 if ( drmMap( sPriv
->fd
, sisScreen
->mmio
.handle
, sisScreen
->mmio
.size
,
85 &sisScreen
->mmio
.map
) )
91 if (sisDRIPriv
->agp
.size
) {
92 sisScreen
->agp
.handle
= sisDRIPriv
->agp
.handle
;
93 sisScreen
->agp
.size
= sisDRIPriv
->agp
.size
;
94 if ( drmMap( sPriv
->fd
, sisScreen
->agp
.handle
, sisScreen
->agp
.size
,
95 &sisScreen
->agp
.map
) )
97 sisScreen
->agp
.size
= 0;
101 sisScreen
->driScreen
= sPriv
;
103 /* parse information in __driConfigOptions */
104 driParseOptionInfo(&sisScreen
->optionCache
,
105 __driConfigOptions
, __driNConfigOptions
);
110 /* Destroy the device specific screen private data struct.
113 sisDestroyScreen( __DRIscreenPrivate
*sPriv
)
115 sisScreenPtr sisScreen
= (sisScreenPtr
)sPriv
->private;
117 if ( sisScreen
== NULL
)
120 if (sisScreen
->agp
.size
!= 0)
121 drmUnmap( sisScreen
->agp
.map
, sisScreen
->agp
.size
);
122 drmUnmap( sisScreen
->mmio
.map
, sisScreen
->mmio
.size
);
125 sPriv
->private = NULL
;
128 /* Create and initialize the Mesa and driver specific pixmap buffer
132 sisCreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
133 __DRIdrawablePrivate
*driDrawPriv
,
134 const __GLcontextModes
*mesaVis
,
138 return GL_FALSE
; /* not implemented */
140 driDrawPriv
->driverPrivate
= (void *)_mesa_create_framebuffer(
142 GL_FALSE
, /* software depth buffer? */
143 mesaVis
->stencilBits
> 0,
144 mesaVis
->accumRedBits
> 0,
145 mesaVis
->alphaBits
> 0 ); /* XXX */
146 return (driDrawPriv
->driverPrivate
!= NULL
);
151 sisDestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
153 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->driverPrivate
));
156 __inline__
static void
157 sis_bitblt_copy_cmd (sisContextPtr smesa
, ENGPACKET
* pkt
)
159 GLint
*lpdwDest
, *lpdwSrc
;
162 lpdwSrc
= (GLint
*) pkt
;
163 lpdwDest
= (GLint
*) (GET_IOBase (smesa
) + REG_SRC_ADDR
);
165 mWait3DCmdQueue (10);
167 for (i
= 0; i
< 7; i
++)
168 *lpdwDest
++ = *lpdwSrc
++;
170 MMIO(REG_CMD0
, *(GLint
*)&pkt
->stdwCmd
);
171 MMIO(REG_CommandQueue
, -1);
174 static void sisCopyBuffer( __DRIdrawablePrivate
*dPriv
)
176 sisContextPtr smesa
= (sisContextPtr
)dPriv
->driContextPriv
->driverPrivate
;
178 ENGPACKET stEngPacket
;
180 while ((*smesa
->FrameCountPtr
) - MMIO_READ(0x8a2c) > SIS_MAX_FRAME_LENGTH
)
185 stEngPacket
.dwSrcBaseAddr
= smesa
->backOffset
;
186 stEngPacket
.dwSrcPitch
= smesa
->backPitch
|
187 ((smesa
->bytesPerPixel
== 2) ? 0x80000000 : 0xc0000000);
188 stEngPacket
.dwDestBaseAddr
= 0;
189 stEngPacket
.wDestPitch
= smesa
->frontPitch
;
190 /* TODO: set maximum value? */
191 stEngPacket
.wDestHeight
= smesa
->virtualY
;
193 stEngPacket
.stdwCmd
.cRop
= 0xcc;
195 if (smesa
->blockWrite
)
196 stEngPacket
.stdwCmd
.cCmd0
= CMD0_PAT_FG_COLOR
;
198 stEngPacket
.stdwCmd
.cCmd0
= 0;
199 stEngPacket
.stdwCmd
.cCmd1
= CMD1_DIR_X_INC
| CMD1_DIR_Y_INC
;
201 for (i
= 0; i
< dPriv
->numClipRects
; i
++) {
202 drm_clip_rect_t
*box
= &dPriv
->pClipRects
[i
];
203 stEngPacket
.stdwSrcPos
.wY
= box
->y1
- dPriv
->y
;
204 stEngPacket
.stdwSrcPos
.wX
= box
->x1
- dPriv
->x
;
205 stEngPacket
.stdwDestPos
.wY
= box
->y1
;
206 stEngPacket
.stdwDestPos
.wX
= box
->x1
;
208 stEngPacket
.stdwDim
.wWidth
= (GLshort
) box
->x2
- box
->x1
;
209 stEngPacket
.stdwDim
.wHeight
= (GLshort
) box
->y2
- box
->y1
;
210 sis_bitblt_copy_cmd( smesa
, &stEngPacket
);
213 *(GLint
*)(smesa
->IOBase
+0x8a2c) = *smesa
->FrameCountPtr
;
214 (*smesa
->FrameCountPtr
)++;
220 /* Copy the back color buffer to the front color buffer */
222 sisSwapBuffers(__DRIdrawablePrivate
*dPriv
)
224 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
225 sisContextPtr smesa
= (sisContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
226 GLcontext
*ctx
= smesa
->glCtx
;
228 if (ctx
->Visual
.doubleBufferMode
) {
229 _mesa_notifySwapBuffers( ctx
); /* flush pending rendering comands */
230 sisCopyBuffer( dPriv
);
233 /* XXX this shouldn't be an error but we can't handle it for now */
234 _mesa_problem(NULL
, "%s: drawable has no context!", __FUNCTION__
);
239 /* Initialize the driver specific screen private data.
242 sisInitDriver( __DRIscreenPrivate
*sPriv
)
244 sPriv
->private = (void *) sisCreateScreen( sPriv
);
246 if ( !sPriv
->private ) {
247 sisDestroyScreen( sPriv
);
254 static struct __DriverAPIRec sisAPI
= {
255 .InitDriver
= sisInitDriver
,
256 .DestroyScreen
= sisDestroyScreen
,
257 .CreateContext
= sisCreateContext
,
258 .DestroyContext
= sisDestroyContext
,
259 .CreateBuffer
= sisCreateBuffer
,
260 .DestroyBuffer
= sisDestroyBuffer
,
261 .SwapBuffers
= sisSwapBuffers
,
262 .MakeCurrent
= sisMakeCurrent
,
263 .UnbindContext
= sisUnbindContext
,
268 .SwapBuffersMSC
= NULL
273 * This is the bootstrap function for the driver.
274 * The __driCreateScreen name is the symbol that libGL.so fetches.
275 * Return: pointer to a __DRIscreenPrivate.
278 void *__driCreateScreen(Display
*dpy
, int scrn
, __DRIscreen
*psc
,
279 int numConfigs
, __GLXvisualConfig
*config
)
281 __DRIscreenPrivate
*psp
;
282 psp
= __driUtilCreateScreen( dpy
, scrn
, psc
, numConfigs
, config
, &sisAPI
);
286 void *__driCreateScreen(struct DRIDriverRec
*driver
,
287 struct DRIDriverContextRec
*driverContext
)
289 __DRIscreenPrivate
*psp
;
290 psp
= __driUtilCreateScreen(driver
, driverContext
, &sisAPI
);