1 /* $XFree86$ */ /* -*- 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_state.h"
35 #include "mach64_span.h"
37 #include "swrast/swrast.h"
42 mach64ContextPtr mmesa = MACH64_CONTEXT(ctx); \
43 mach64ScreenRec *mach64Screen = mmesa->mach64Screen; \
44 __DRIscreenPrivate *driScreen = mmesa->driScreen; \
45 __DRIdrawablePrivate *dPriv = mmesa->driDrawable; \
46 GLuint pitch = mmesa->drawPitch * mach64Screen->cpp; \
47 GLuint height = dPriv->h; \
48 char *buf = (char *)(driScreen->pFB + \
50 (dPriv->x * mach64Screen->cpp) + \
51 (dPriv->y * pitch)); \
52 char *read_buf = (char *)(driScreen->pFB + \
54 (dPriv->x * mach64Screen->cpp) + \
55 (dPriv->y * pitch)); \
57 (void) read_buf; (void) buf; (void) p
59 #define LOCAL_DEPTH_VARS \
60 mach64ContextPtr mmesa = MACH64_CONTEXT(ctx); \
61 mach64ScreenRec *mach64Screen = mmesa->mach64Screen; \
62 __DRIdrawablePrivate *dPriv = mmesa->driDrawable; \
63 __DRIscreenPrivate *driScreen = mmesa->driScreen; \
64 GLuint pitch = mach64Screen->depthPitch * 2; \
65 GLuint height = dPriv->h; \
66 char *buf = (char *)(driScreen->pFB + \
67 mach64Screen->depthOffset + \
71 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
73 #define Y_FLIP( _y ) (height - _y - 1)
77 /* FIXME could/should we use dPriv->numClipRects like the other drivers? */
78 #define HW_CLIPLOOP() \
80 int _nc = mmesa->numClipRects; \
83 int minx = mmesa->pClipRects[_nc].x1 - mmesa->drawX; \
84 int miny = mmesa->pClipRects[_nc].y1 - mmesa->drawY; \
85 int maxx = mmesa->pClipRects[_nc].x2 - mmesa->drawX; \
86 int maxy = mmesa->pClipRects[_nc].y2 - mmesa->drawY;
88 #define HW_ENDCLIPLOOP() \
96 /* ================================================================
100 /* 16 bit, RGB565 color spanline and pixel functions
102 #define SPANTMP_PIXEL_FMT GL_RGB
103 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
105 #define TAG(x) mach64##x##_RGB565
106 #define TAG2(x,y) mach64##x##_RGB565##y
107 #include "spantmp2.h"
110 /* 32 bit, ARGB8888 color spanline and pixel functions
112 /* FIXME the old code always read back alpha as 0xff, i.e. fully opaque.
113 Was there a reason to do so ? If so that'll won't work with that template... */
114 #define SPANTMP_PIXEL_FMT GL_BGRA
115 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
117 #define TAG(x) mach64##x##_ARGB8888
118 #define TAG2(x,y) mach64##x##_ARGB8888##y
119 #include "spantmp2.h"
122 /* ================================================================
126 /* 16 bit depthbuffer functions.
128 #define WRITE_DEPTH( _x, _y, d ) \
129 *(GLushort *)(buf + (_x)*2 + (_y)*pitch) = d;
131 #define READ_DEPTH( d, _x, _y ) \
132 d = *(GLushort *)(buf + (_x)*2 + (_y)*pitch);
134 #define TAG(x) mach64##x##_16
135 #include "depthtmp.h"
139 * This function is called to specify which buffer to read and write
140 * for software rasterization (swrast) fallbacks. This doesn't necessarily
141 * correspond to glDrawBuffer() or glReadBuffer() calls.
143 static void mach64DDSetBuffer( GLcontext
*ctx
,
144 GLframebuffer
*colorBuffer
,
147 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
149 switch ( bufferBit
) {
150 case BUFFER_BIT_FRONT_LEFT
:
151 if (MACH64_DEBUG
& DEBUG_VERBOSE_MSG
)
152 fprintf(stderr
,"%s: BUFFER_BIT_FRONT_LEFT\n", __FUNCTION__
);
153 mmesa
->drawOffset
= mmesa
->readOffset
= mmesa
->mach64Screen
->frontOffset
;
154 mmesa
->drawPitch
= mmesa
->readPitch
= mmesa
->mach64Screen
->frontPitch
;
156 case BUFFER_BIT_BACK_LEFT
:
157 if (MACH64_DEBUG
& DEBUG_VERBOSE_MSG
)
158 fprintf(stderr
,"%s: BUFFER_BIT_BACK_LEFT\n", __FUNCTION__
);
159 mmesa
->drawOffset
= mmesa
->readOffset
= mmesa
->mach64Screen
->backOffset
;
160 mmesa
->drawPitch
= mmesa
->readPitch
= mmesa
->mach64Screen
->backPitch
;
167 static void mach64SpanRenderStart( GLcontext
*ctx
)
169 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
170 LOCK_HARDWARE( mmesa
);
171 FINISH_DMA_LOCKED( mmesa
);
174 static void mach64SpanRenderFinish( GLcontext
*ctx
)
176 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
177 _swrast_flush( ctx
);
178 UNLOCK_HARDWARE( mmesa
);
181 void mach64DDInitSpanFuncs( GLcontext
*ctx
)
184 mach64ContextPtr mmesa
= MACH64_CONTEXT(ctx
);
186 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference(ctx
);
188 swdd
->SetBuffer
= mach64DDSetBuffer
;
191 switch ( mmesa
->mach64Screen
->cpp
) {
193 swdd
->WriteRGBASpan
= mach64WriteRGBASpan_RGB565
;
194 swdd
->WriteRGBSpan
= mach64WriteRGBSpan_RGB565
;
195 swdd
->WriteMonoRGBASpan
= mach64WriteMonoRGBASpan_RGB565
;
196 swdd
->WriteRGBAPixels
= mach64WriteRGBAPixels_RGB565
;
197 swdd
->WriteMonoRGBAPixels
= mach64WriteMonoRGBAPixels_RGB565
;
198 swdd
->ReadRGBASpan
= mach64ReadRGBASpan_RGB565
;
199 swdd
->ReadRGBAPixels
= mach64ReadRGBAPixels_RGB565
;
203 swdd
->WriteRGBASpan
= mach64WriteRGBASpan_ARGB8888
;
204 swdd
->WriteRGBSpan
= mach64WriteRGBSpan_ARGB8888
;
205 swdd
->WriteMonoRGBASpan
= mach64WriteMonoRGBASpan_ARGB8888
;
206 swdd
->WriteRGBAPixels
= mach64WriteRGBAPixels_ARGB8888
;
207 swdd
->WriteMonoRGBAPixels
= mach64WriteMonoRGBAPixels_ARGB8888
;
208 swdd
->ReadRGBASpan
= mach64ReadRGBASpan_ARGB8888
;
209 swdd
->ReadRGBAPixels
= mach64ReadRGBAPixels_ARGB8888
;
218 /* Depth buffer is always 16 bit */
220 swdd
->ReadDepthSpan
= mach64ReadDepthSpan_16
;
221 swdd
->WriteDepthSpan
= mach64WriteDepthSpan_16
;
222 swdd
->ReadDepthPixels
= mach64ReadDepthPixels_16
;
223 swdd
->WriteDepthPixels
= mach64WriteDepthPixels_16
;
226 /* No hardware stencil buffer */
227 swdd
->ReadStencilSpan
= NULL
;
228 swdd
->WriteStencilSpan
= NULL
;
229 swdd
->ReadStencilPixels
= NULL
;
230 swdd
->WriteStencilPixels
= NULL
;
232 swdd
->WriteCI8Span
= NULL
;
233 swdd
->WriteCI32Span
= NULL
;
234 swdd
->WriteMonoCISpan
= NULL
;
235 swdd
->WriteCI32Pixels
= NULL
;
236 swdd
->WriteMonoCIPixels
= NULL
;
237 swdd
->ReadCI32Span
= NULL
;
238 swdd
->ReadCI32Pixels
= NULL
;
240 swdd
->SpanRenderStart
= mach64SpanRenderStart
;
241 swdd
->SpanRenderFinish
= mach64SpanRenderFinish
;
246 * Plug in the Get/Put routines for the given driRenderbuffer.
249 mach64SetSpanFunctions(driRenderbuffer
*drb
, const GLvisual
*vis
)
251 if (drb
->Base
.InternalFormat
== GL_RGBA
) {
252 if (vis
->redBits
== 5 && vis
->greenBits
== 6 && vis
->blueBits
== 5) {
253 mach64InitPointers_RGB565(&drb
->Base
);
256 mach64InitPointers_ARGB8888(&drb
->Base
);
259 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT16
) {
260 drb
->Base
.GetRow
= mach64ReadDepthSpan_16
;
261 drb
->Base
.GetValues
= mach64ReadDepthPixels_16
;
262 drb
->Base
.PutRow
= mach64WriteDepthSpan_16
;
263 drb
->Base
.PutMonoRow
= mach64WriteMonoDepthSpan_16
;
264 drb
->Base
.PutValues
= mach64WriteDepthPixels_16
;
265 drb
->Base
.PutMonoValues
= NULL
;
267 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT24
) {
269 drb
->Base
.GetRow
= NULL
;
270 drb
->Base
.GetValues
= NULL
;
271 drb
->Base
.PutRow
= NULL
;
272 drb
->Base
.PutMonoRow
= NULL
;
273 drb
->Base
.PutValues
= NULL
;
274 drb
->Base
.PutMonoValues
= NULL
;
276 else if (drb
->Base
.InternalFormat
== GL_STENCIL_INDEX8_EXT
) {
278 drb
->Base
.GetRow
= NULL
;
279 drb
->Base
.GetValues
= NULL
;
280 drb
->Base
.PutRow
= NULL
;
281 drb
->Base
.PutMonoRow
= NULL
;
282 drb
->Base
.PutValues
= NULL
;
283 drb
->Base
.PutMonoValues
= NULL
;