(Stephane Marchesin, me) add hyperz support to radeon and r200 drivers. Only fast...
[mesa.git] / src / mesa / drivers / dri / ffb / ffb_stencil.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_stencil.c,v 1.2 2002/02/22 21:32:59 dawes Exp $
2 *
3 * GLX Hardware Device Driver for Sun Creator/Creator3D
4 * Copyright (C) 2000 David S. Miller
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 shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * DAVID MILLER, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 *
25 * David S. Miller <davem@redhat.com>
26 */
27
28 #include "mtypes.h"
29 #include "ffb_dd.h"
30 #include "ffb_span.h"
31 #include "ffb_context.h"
32 #include "ffb_stencil.h"
33 #include "ffb_lock.h"
34
35 #include "swrast/swrast.h"
36
37 #undef STENCIL_TRACE
38
39 static void
40 FFBWriteStencilSpan(GLcontext *ctx, GLuint n, GLint x, GLint y,
41 const GLstencil stencil[], const GLubyte mask[])
42 {
43 #ifdef STENCIL_TRACE
44 fprintf(stderr, "FFBWriteStencilSpan: n(%d) x(%d) y(%d)\n",
45 (int) n, x, y);
46 #endif
47 if (ctx->Depth.Mask) {
48 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
49 __DRIdrawablePrivate *dPriv = fmesa->driDrawable;
50 GLuint *zptr;
51 GLuint i;
52
53 if (!fmesa->hw_locked)
54 LOCK_HARDWARE(fmesa);
55 FFBFifo(fmesa, 2);
56 fmesa->regs->fbc = (FFB_FBC_WB_C | FFB_FBC_ZE_OFF |
57 FFB_FBC_YE_ON | FFB_FBC_RGBE_OFF);
58 fmesa->regs->ppc = FFB_PPC_YS_VAR;
59 FFBWait(fmesa, fmesa->regs);
60
61 y = (dPriv->h - y);
62 zptr = (GLuint *)
63 ((char *)fmesa->sfb32 +
64 ((dPriv->x + x) << 2) +
65 ((dPriv->y + y) << 13));
66
67 for (i = 0; i < n; i++) {
68 if (mask[i])
69 *zptr = (stencil[i] & 0xf) << 28;
70 zptr++;
71 }
72
73 FFBFifo(fmesa, 2);
74 fmesa->regs->fbc = fmesa->fbc;
75 fmesa->regs->ppc = fmesa->ppc;
76 fmesa->ffbScreen->rp_active = 1;
77 if (!fmesa->hw_locked)
78 UNLOCK_HARDWARE(fmesa);
79 }
80 }
81
82 static void
83 FFBWriteStencilPixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[],
84 const GLstencil stencil[], const GLubyte mask[])
85 {
86 #ifdef STENCIL_TRACE
87 fprintf(stderr, "FFBWriteStencilPixels: n(%d)\n", (int) n);
88 #endif
89 if (ctx->Depth.Mask) {
90 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
91 __DRIdrawablePrivate *dPriv = fmesa->driDrawable;
92 char *zbase;
93 GLuint i;
94
95 if (!fmesa->hw_locked)
96 LOCK_HARDWARE(fmesa);
97 FFBFifo(fmesa, 2);
98 fmesa->regs->fbc = (FFB_FBC_WB_C | FFB_FBC_ZE_OFF |
99 FFB_FBC_YE_ON | FFB_FBC_RGBE_OFF);
100 fmesa->regs->ppc = FFB_PPC_YS_VAR;
101 fmesa->ffbScreen->rp_active = 1;
102 FFBWait(fmesa, fmesa->regs);
103
104 zbase = ((char *)fmesa->sfb32 +
105 (dPriv->x << 2) + (dPriv->y << 13));
106
107 for (i = 0; i < n; i++) {
108 GLint y1 = (dPriv->h - y[i]);
109 GLint x1 = x[i];
110 GLuint *zptr;
111
112 zptr = (GLuint *)
113 (zbase + (x1 << 2) + (y1 << 13));
114 if (mask[i])
115 *zptr = (stencil[i] & 0xf) << 28;
116 }
117
118 FFBFifo(fmesa, 2);
119 fmesa->regs->fbc = fmesa->fbc;
120 fmesa->regs->ppc = fmesa->ppc;
121 fmesa->ffbScreen->rp_active = 1;
122 if (!fmesa->hw_locked)
123 UNLOCK_HARDWARE(fmesa);
124 }
125 }
126
127 static void
128 FFBReadStencilSpan(GLcontext *ctx, GLuint n, GLint x, GLint y, GLstencil stencil[])
129 {
130 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
131 __DRIdrawablePrivate *dPriv = fmesa->driDrawable;
132 GLuint *zptr;
133 GLuint i;
134
135 #ifdef STENCIL_TRACE
136 fprintf(stderr, "FFBReadStencilSpan: n(%d) x(%d) y(%d)\n",
137 (int) n, x, y);
138 #endif
139 if (!fmesa->hw_locked)
140 LOCK_HARDWARE(fmesa);
141 FFBFifo(fmesa, 1);
142 fmesa->regs->fbc = FFB_FBC_RB_C;
143 fmesa->ffbScreen->rp_active = 1;
144 FFBWait(fmesa, fmesa->regs);
145
146 y = (dPriv->h - y);
147 zptr = (GLuint *)
148 ((char *)fmesa->sfb32 +
149 ((dPriv->x + x) << 2) +
150 ((dPriv->y + y) << 13));
151
152 for (i = 0; i < n; i++) {
153 stencil[i] = (*zptr >> 28) & 0xf;
154 zptr++;
155 }
156
157 FFBFifo(fmesa, 1);
158 fmesa->regs->fbc = fmesa->fbc;
159 fmesa->ffbScreen->rp_active = 1;
160 if (!fmesa->hw_locked)
161 UNLOCK_HARDWARE(fmesa);
162 }
163
164 static void
165 FFBReadStencilPixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[],
166 GLstencil stencil[])
167 {
168 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
169 __DRIdrawablePrivate *dPriv = fmesa->driDrawable;
170 char *zbase;
171 GLuint i;
172
173 #ifdef STENCIL_TRACE
174 fprintf(stderr, "FFBReadStencilPixels: n(%d)\n", (int) n);
175 #endif
176 if (!fmesa->hw_locked)
177 LOCK_HARDWARE(fmesa);
178 FFBFifo(fmesa, 1);
179 fmesa->regs->fbc = FFB_FBC_RB_C;
180 fmesa->ffbScreen->rp_active = 1;
181 FFBWait(fmesa, fmesa->regs);
182
183 zbase = ((char *)fmesa->sfb32 +
184 (dPriv->x << 2) + (dPriv->y << 13));
185
186 for (i = 0; i < n; i++) {
187 GLint y1 = (dPriv->h - y[i]);
188 GLint x1 = x[i];
189 GLuint *zptr;
190
191 zptr = (GLuint *)
192 (zbase + (x1 << 2) + (y1 << 13));
193 stencil[i] = (*zptr >> 28) & 0xf;
194 }
195
196 FFBFifo(fmesa, 1);
197 fmesa->regs->fbc = fmesa->fbc;
198 fmesa->ffbScreen->rp_active = 1;
199 if (!fmesa->hw_locked)
200 UNLOCK_HARDWARE(fmesa);
201 }
202
203 void ffbDDInitStencilFuncs(GLcontext *ctx)
204 {
205 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
206
207 struct swrast_device_driver *swdd =
208 _swrast_GetDeviceDriverReference(ctx);
209
210 if (fmesa->ffb_sarea->flags & FFB_DRI_FFB2PLUS) {
211 swdd->WriteStencilSpan = FFBWriteStencilSpan;
212 swdd->ReadStencilSpan = FFBReadStencilSpan;
213 swdd->WriteStencilPixels = FFBWriteStencilPixels;
214 swdd->ReadStencilPixels = FFBReadStencilPixels;
215 } else {
216 swdd->WriteStencilSpan = NULL;
217 swdd->ReadStencilSpan = NULL;
218 swdd->WriteStencilPixels = NULL;
219 swdd->ReadStencilPixels = NULL;
220 }
221 }