2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
29 #include "via_context.h"
31 #include "via_ioctl.h"
32 #include "swrast/swrast.h"
36 #define Y_FLIP(_y) (height - _y - 1)
44 struct via_context *vmesa = VIA_CONTEXT(ctx); \
45 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
46 GLuint draw_pitch = vmesa->drawBuffer->pitch; \
47 GLuint read_pitch = vmesa->readBuffer->pitch; \
48 GLuint height = dPriv->h; \
50 char *buf = (char *)(vmesa->drawBuffer->origMap + vmesa->drawXoff * vmesa->viaScreen->bytesPerPixel); \
51 char *read_buf = (char *)(vmesa->readBuffer->origMap + vmesa->drawXoff * vmesa->viaScreen->bytesPerPixel); \
52 (void) (read_pitch && draw_pitch && buf && read_buf && p);
54 /* ================================================================
58 /* 16 bit, RGB565 color spanline and pixel functions
60 #define GET_SRC_PTR(_x, _y) (read_buf + (_x) * 2 + (_y) * read_pitch)
61 #define GET_DST_PTR(_x, _y) ( buf + (_x) * 2 + (_y) * draw_pitch)
62 #define SPANTMP_PIXEL_FMT GL_RGB
63 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
65 #define TAG(x) via##x##_565
66 #define TAG2(x,y) via##x##_565##y
70 /* 32 bit, ARGB8888 color spanline and pixel functions
72 #define GET_SRC_PTR(_x, _y) (read_buf + (_x) * 4 + (_y) * read_pitch)
73 #define GET_DST_PTR(_x, _y) ( buf + (_x) * 4 + (_y) * draw_pitch)
74 #define SPANTMP_PIXEL_FMT GL_BGRA
75 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
77 #define TAG(x) via##x##_8888
78 #define TAG2(x,y) via##x##_8888##y
82 /* 16 bit depthbuffer functions.
84 #define LOCAL_DEPTH_VARS \
85 struct via_context *vmesa = VIA_CONTEXT(ctx); \
86 __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
87 GLuint depth_pitch = vmesa->depth.pitch; \
88 GLuint height = dPriv->h; \
89 char *buf = (char *)(vmesa->depth.map + (vmesa->drawXoff * vmesa->depth.bpp/8))
91 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
94 #define WRITE_DEPTH(_x, _y, d) \
95 *(GLushort *)(buf + (_x) * 2 + (_y) * depth_pitch) = d;
97 #define READ_DEPTH(d, _x, _y) \
98 d = *(volatile GLushort *)(buf + (_x) * 2 + (_y) * depth_pitch);
100 #define TAG(x) via##x##_16
101 #include "depthtmp.h"
103 /* 32 bit depthbuffer functions.
105 #define WRITE_DEPTH(_x, _y, d) \
106 *(GLuint *)(buf + (_x) * 4 + (_y) * depth_pitch) = d;
108 #define READ_DEPTH(d, _x, _y) \
109 d = *(volatile GLuint *)(buf + (_x) * 4 + (_y) * depth_pitch);
111 #define TAG(x) via##x##_32
112 #include "depthtmp.h"
116 /* 24/8 bit interleaved depth/stencil functions
118 #define WRITE_DEPTH( _x, _y, d ) { \
119 GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch); \
122 *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) = tmp; \
125 #define READ_DEPTH( d, _x, _y ) \
126 d = (*(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch)) >> 8;
129 #define TAG(x) via##x##_24_8
130 #include "depthtmp.h"
132 #define WRITE_STENCIL( _x, _y, d ) { \
133 GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch); \
136 *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) = tmp; \
139 #define READ_STENCIL( d, _x, _y ) \
140 d = *(GLuint *)(buf + (_x)*4 + (_y)*depth_pitch) & 0xff;
142 #define TAG(x) via##x##_24_8
143 #include "stenciltmp.h"
147 static void viaSetBuffer(GLcontext
*ctx
, GLframebuffer
*colorBuffer
,
150 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
152 if (bufferBit
== BUFFER_BIT_FRONT_LEFT
) {
153 vmesa
->drawBuffer
= vmesa
->readBuffer
= &vmesa
->front
;
155 else if (bufferBit
== BUFFER_BIT_BACK_LEFT
) {
156 vmesa
->drawBuffer
= vmesa
->readBuffer
= &vmesa
->back
;
163 /* Move locking out to get reasonable span performance.
165 void viaSpanRenderStart( GLcontext
*ctx
)
167 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
169 LOCK_HARDWARE(vmesa
);
172 void viaSpanRenderFinish( GLcontext
*ctx
)
174 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
175 _swrast_flush( ctx
);
176 UNLOCK_HARDWARE( vmesa
);
179 void viaInitSpanFuncs(GLcontext
*ctx
)
182 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
184 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference(ctx
);
186 swdd
->SetBuffer
= viaSetBuffer
;
188 if (vmesa
->viaScreen
->bitsPerPixel
== 16) {
189 viaInitPointers_565( swdd
);
191 else if (vmesa
->viaScreen
->bitsPerPixel
== 32) {
192 viaInitPointers_8888( swdd
);
199 if (vmesa
->glCtx
->Visual
.depthBits
== 16) {
200 swdd
->ReadDepthSpan
= viaReadDepthSpan_16
;
201 swdd
->WriteDepthSpan
= viaWriteDepthSpan_16
;
202 swdd
->WriteMonoDepthSpan
= viaWriteMonoDepthSpan_16
;
203 swdd
->ReadDepthPixels
= viaReadDepthPixels_16
;
204 swdd
->WriteDepthPixels
= viaWriteDepthPixels_16
;
206 else if (vmesa
->glCtx
->Visual
.depthBits
== 24) {
207 swdd
->ReadDepthSpan
= viaReadDepthSpan_24_8
;
208 swdd
->WriteDepthSpan
= viaWriteDepthSpan_24_8
;
209 swdd
->WriteMonoDepthSpan
= viaWriteMonoDepthSpan_24_8
;
210 swdd
->ReadDepthPixels
= viaReadDepthPixels_24_8
;
211 swdd
->WriteDepthPixels
= viaWriteDepthPixels_24_8
;
213 swdd
->WriteStencilSpan
= viaWriteStencilSpan_24_8
;
214 swdd
->ReadStencilSpan
= viaReadStencilSpan_24_8
;
215 swdd
->WriteStencilPixels
= viaWriteStencilPixels_24_8
;
216 swdd
->ReadStencilPixels
= viaReadStencilPixels_24_8
;
218 else if (vmesa
->glCtx
->Visual
.depthBits
== 32) {
219 swdd
->ReadDepthSpan
= viaReadDepthSpan_32
;
220 swdd
->WriteDepthSpan
= viaWriteDepthSpan_32
;
221 swdd
->WriteMonoDepthSpan
= viaWriteMonoDepthSpan_32
;
222 swdd
->ReadDepthPixels
= viaReadDepthPixels_32
;
223 swdd
->WriteDepthPixels
= viaWriteDepthPixels_32
;
227 swdd
->SpanRenderStart
= viaSpanRenderStart
;
228 swdd
->SpanRenderFinish
= viaSpanRenderFinish
;
231 swdd
->WriteCI8Span
= NULL
;
232 swdd
->WriteCI32Span
= NULL
;
233 swdd
->WriteMonoCISpan
= NULL
;
234 swdd
->WriteCI32Pixels
= NULL
;
235 swdd
->WriteMonoCIPixels
= NULL
;
236 swdd
->ReadCI32Span
= NULL
;
237 swdd
->ReadCI32Pixels
= NULL
;
244 * Plug in the Get/Put routines for the given driRenderbuffer.
247 viaSetSpanFunctions(driRenderbuffer
*drb
, const GLvisual
*vis
)
249 if (drb
->Base
.InternalFormat
== GL_RGBA
) {
250 if (vis
->redBits
== 5 && vis
->greenBits
== 6 && vis
->blueBits
== 5) {
251 viaInitPointers_565(&drb
->Base
);
254 viaInitPointers_8888(&drb
->Base
);
257 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT16
) {
258 drb
->Base
.GetRow
= viaReadDepthSpan_16
;
259 drb
->Base
.GetValues
= viaReadDepthPixels_16
;
260 drb
->Base
.PutRow
= viaWriteDepthSpan_16
;
261 drb
->Base
.PutMonoRow
= viaWriteMonoDepthSpan_16
;
262 drb
->Base
.PutValues
= viaWriteDepthPixels_16
;
263 drb
->Base
.PutMonoValues
= NULL
;
265 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT24
) {
266 drb
->Base
.GetRow
= viaReadDepthSpan_24_8
;
267 drb
->Base
.GetValues
= viaReadDepthPixels_24_8
;
268 drb
->Base
.PutRow
= viaWriteDepthSpan_24_8
;
269 drb
->Base
.PutMonoRow
= viaWriteMonoDepthSpan_24_8
;
270 drb
->Base
.PutValues
= viaWriteDepthPixels_24_8
;
271 drb
->Base
.PutMonoValues
= NULL
;
273 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT32
) {
274 drb
->Base
.GetRow
= viaReadDepthSpan_32
;
275 drb
->Base
.GetValues
= viaReadDepthPixels_32
;
276 drb
->Base
.PutRow
= viaWriteDepthSpan_32
;
277 drb
->Base
.PutMonoRow
= viaWriteMonoDepthSpan_32
;
278 drb
->Base
.PutValues
= viaWriteDepthPixels_32
;
279 drb
->Base
.PutMonoValues
= NULL
;
281 else if (drb
->Base
.InternalFormat
== GL_STENCIL_INDEX8_EXT
) {
282 drb
->Base
.GetRow
= viaReadStencilSpan_24_8
;
283 drb
->Base
.GetValues
= viaReadStencilPixels_24_8
;
284 drb
->Base
.PutRow
= viaWriteStencilSpan_24_8
;
285 drb
->Base
.PutMonoRow
= viaWriteMonoStencilSpan_24_8
;
286 drb
->Base
.PutValues
= viaWriteStencilPixels_24_8
;
287 drb
->Base
.PutMonoValues
= NULL
;