88863471d4745e6d7dd9d9046d3c3e6f1a557529
[mesa.git] / src / mesa / drivers / dri / mach64 / mach64_span.c
1 /* $XFree86$ */ /* -*- mode: c; c-basic-offset: 3 -*- */
2 /*
3 * Copyright 2000 Gareth Hughes
4 * All Rights Reserved.
5 *
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:
12 *
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
15 * Software.
16 *
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.
23 */
24
25 /*
26 * Authors:
27 * Gareth Hughes <gareth@valinux.com>
28 * Leif Delgass <ldelgass@retinalburn.net>
29 * Jos�Fonseca <j_r_fonseca@yahoo.co.uk>
30 */
31
32 #include "mach64_context.h"
33 #include "mach64_ioctl.h"
34 #include "mach64_state.h"
35 #include "mach64_span.h"
36
37 #include "swrast/swrast.h"
38
39 #define DBG 0
40
41 #define LOCAL_VARS \
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 + \
49 mmesa->drawOffset + \
50 (dPriv->x * mach64Screen->cpp) + \
51 (dPriv->y * pitch)); \
52 char *read_buf = (char *)(driScreen->pFB + \
53 mmesa->readOffset + \
54 (dPriv->x * mach64Screen->cpp) + \
55 (dPriv->y * pitch)); \
56 GLushort p; \
57 (void) read_buf; (void) buf; (void) p
58
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 + \
68 dPriv->x * 2 + \
69 dPriv->y * pitch)
70
71 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
72
73 #define Y_FLIP( _y ) (height - _y - 1)
74
75 #define HW_LOCK()
76
77 /* FIXME could/should we use dPriv->numClipRects like the other drivers? */
78 #define HW_CLIPLOOP() \
79 do { \
80 int _nc = mmesa->numClipRects; \
81 \
82 while ( _nc-- ) { \
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;
87
88 #define HW_ENDCLIPLOOP() \
89 } \
90 } while (0)
91
92 #define HW_UNLOCK()
93
94
95
96 /* ================================================================
97 * Color buffer
98 */
99
100 /* 16 bit, RGB565 color spanline and pixel functions
101 */
102 #define SPANTMP_PIXEL_FMT GL_RGB
103 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
104
105 #define TAG(x) mach64##x##_RGB565
106 #define TAG2(x,y) mach64##x##_RGB565##y
107 #include "spantmp2.h"
108
109
110 /* 32 bit, ARGB8888 color spanline and pixel functions
111 */
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
116
117 #define TAG(x) mach64##x##_ARGB8888
118 #define TAG2(x,y) mach64##x##_ARGB8888##y
119 #include "spantmp2.h"
120
121
122 /* ================================================================
123 * Depth buffer
124 */
125
126 /* 16 bit depthbuffer functions.
127 */
128 #define WRITE_DEPTH( _x, _y, d ) \
129 *(GLushort *)(buf + (_x)*2 + (_y)*pitch) = d;
130
131 #define READ_DEPTH( d, _x, _y ) \
132 d = *(GLushort *)(buf + (_x)*2 + (_y)*pitch);
133
134 #define TAG(x) mach64##x##_16
135 #include "depthtmp.h"
136
137
138 /*
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.
142 */
143 static void mach64DDSetBuffer( GLcontext *ctx,
144 GLframebuffer *colorBuffer,
145 GLuint bufferBit )
146 {
147 mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
148
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;
155 break;
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;
161 break;
162 default:
163 break;
164 }
165 }
166
167 static void mach64SpanRenderStart( GLcontext *ctx )
168 {
169 mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
170 LOCK_HARDWARE( mmesa );
171 FINISH_DMA_LOCKED( mmesa );
172 }
173
174 static void mach64SpanRenderFinish( GLcontext *ctx )
175 {
176 mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
177 _swrast_flush( ctx );
178 UNLOCK_HARDWARE( mmesa );
179 }
180
181 void mach64DDInitSpanFuncs( GLcontext *ctx )
182 {
183 #if 0
184 mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
185 #endif
186 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
187
188 swdd->SetBuffer = mach64DDSetBuffer;
189
190 #if 0
191 switch ( mmesa->mach64Screen->cpp ) {
192 case 2:
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;
200 break;
201
202 case 4:
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;
210
211 break;
212
213 default:
214 break;
215 }
216 #endif
217
218 /* Depth buffer is always 16 bit */
219 #if 0
220 swdd->ReadDepthSpan = mach64ReadDepthSpan_16;
221 swdd->WriteDepthSpan = mach64WriteDepthSpan_16;
222 swdd->ReadDepthPixels = mach64ReadDepthPixels_16;
223 swdd->WriteDepthPixels = mach64WriteDepthPixels_16;
224 #endif
225 #if 0
226 /* No hardware stencil buffer */
227 swdd->ReadStencilSpan = NULL;
228 swdd->WriteStencilSpan = NULL;
229 swdd->ReadStencilPixels = NULL;
230 swdd->WriteStencilPixels = NULL;
231
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;
239 #endif
240 swdd->SpanRenderStart = mach64SpanRenderStart;
241 swdd->SpanRenderFinish = mach64SpanRenderFinish;
242 }
243
244
245 /**
246 * Plug in the Get/Put routines for the given driRenderbuffer.
247 */
248 void
249 mach64SetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
250 {
251 if (drb->Base.InternalFormat == GL_RGBA) {
252 if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
253 mach64InitPointers_RGB565(&drb->Base);
254 }
255 else {
256 mach64InitPointers_ARGB8888(&drb->Base);
257 }
258 }
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;
266 }
267 else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) {
268 /* never */
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;
275 }
276 else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) {
277 /* never */
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;
284 }
285 }