Merge branch 'mesa_7_7_branch'
[mesa.git] / src / mesa / drivers / dri / ffb / ffb_stencil.c
1 /*
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 "main/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 #undef STENCIL_TRACE
36
37 static void FFBWriteStencilSpan( GLcontext *ctx,
38 struct gl_renderbuffer *rb,
39 GLuint n, GLint x, GLint y,
40 const void *values, const GLubyte mask[] )
41 {
42 const GLubyte *stencil = (const GLubyte *) values;
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 __DRIdrawable *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 FFBWriteStencilPixels( GLcontext *ctx,
83 struct gl_renderbuffer *rb,
84 GLuint n,
85 const GLint x[], const GLint y[],
86 const void *values, const GLubyte mask[] )
87 {
88 const GLubyte *stencil = (const GLubyte *) values;
89 #ifdef STENCIL_TRACE
90 fprintf(stderr, "FFBWriteStencilPixels: n(%d)\n", (int) n);
91 #endif
92 if (ctx->Depth.Mask) {
93 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
94 __DRIdrawable *dPriv = fmesa->driDrawable;
95 char *zbase;
96 GLuint i;
97
98 if (!fmesa->hw_locked)
99 LOCK_HARDWARE(fmesa);
100 FFBFifo(fmesa, 2);
101 fmesa->regs->fbc = (FFB_FBC_WB_C | FFB_FBC_ZE_OFF |
102 FFB_FBC_YE_ON | FFB_FBC_RGBE_OFF);
103 fmesa->regs->ppc = FFB_PPC_YS_VAR;
104 fmesa->ffbScreen->rp_active = 1;
105 FFBWait(fmesa, fmesa->regs);
106
107 zbase = ((char *)fmesa->sfb32 +
108 (dPriv->x << 2) + (dPriv->y << 13));
109
110 for (i = 0; i < n; i++) {
111 GLint y1 = (dPriv->h - y[i]);
112 GLint x1 = x[i];
113 GLuint *zptr;
114
115 zptr = (GLuint *)
116 (zbase + (x1 << 2) + (y1 << 13));
117 if (mask[i])
118 *zptr = (stencil[i] & 0xf) << 28;
119 }
120
121 FFBFifo(fmesa, 2);
122 fmesa->regs->fbc = fmesa->fbc;
123 fmesa->regs->ppc = fmesa->ppc;
124 fmesa->ffbScreen->rp_active = 1;
125 if (!fmesa->hw_locked)
126 UNLOCK_HARDWARE(fmesa);
127 }
128 }
129
130 static void FFBReadStencilSpan( GLcontext *ctx,
131 struct gl_renderbuffer *rb,
132 GLuint n, GLint x, GLint y,
133 void *values)
134 {
135 GLubyte *stencil = (GLubyte *) values;
136 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
137 __DRIdrawable *dPriv = fmesa->driDrawable;
138 GLuint *zptr;
139 GLuint i;
140
141 #ifdef STENCIL_TRACE
142 fprintf(stderr, "FFBReadStencilSpan: n(%d) x(%d) y(%d)\n",
143 (int) n, x, y);
144 #endif
145 if (!fmesa->hw_locked)
146 LOCK_HARDWARE(fmesa);
147 FFBFifo(fmesa, 1);
148 fmesa->regs->fbc = FFB_FBC_RB_C;
149 fmesa->ffbScreen->rp_active = 1;
150 FFBWait(fmesa, fmesa->regs);
151
152 y = (dPriv->h - y);
153 zptr = (GLuint *)
154 ((char *)fmesa->sfb32 +
155 ((dPriv->x + x) << 2) +
156 ((dPriv->y + y) << 13));
157
158 for (i = 0; i < n; i++) {
159 stencil[i] = (*zptr >> 28) & 0xf;
160 zptr++;
161 }
162
163 FFBFifo(fmesa, 1);
164 fmesa->regs->fbc = fmesa->fbc;
165 fmesa->ffbScreen->rp_active = 1;
166 if (!fmesa->hw_locked)
167 UNLOCK_HARDWARE(fmesa);
168 }
169
170 static void FFBReadStencilPixels( GLcontext *ctx,
171 struct gl_renderbuffer *rb,
172 GLuint n, const GLint x[], const GLint y[],
173 void *values )
174 {
175 GLubyte *stencil = (GLubyte *) values;
176 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
177 __DRIdrawable *dPriv = fmesa->driDrawable;
178 char *zbase;
179 GLuint i;
180
181 #ifdef STENCIL_TRACE
182 fprintf(stderr, "FFBReadStencilPixels: n(%d)\n", (int) n);
183 #endif
184 if (!fmesa->hw_locked)
185 LOCK_HARDWARE(fmesa);
186 FFBFifo(fmesa, 1);
187 fmesa->regs->fbc = FFB_FBC_RB_C;
188 fmesa->ffbScreen->rp_active = 1;
189 FFBWait(fmesa, fmesa->regs);
190
191 zbase = ((char *)fmesa->sfb32 +
192 (dPriv->x << 2) + (dPriv->y << 13));
193
194 for (i = 0; i < n; i++) {
195 GLint y1 = (dPriv->h - y[i]);
196 GLint x1 = x[i];
197 GLuint *zptr;
198
199 zptr = (GLuint *)
200 (zbase + (x1 << 2) + (y1 << 13));
201 stencil[i] = (*zptr >> 28) & 0xf;
202 }
203
204 FFBFifo(fmesa, 1);
205 fmesa->regs->fbc = fmesa->fbc;
206 fmesa->ffbScreen->rp_active = 1;
207 if (!fmesa->hw_locked)
208 UNLOCK_HARDWARE(fmesa);
209 }
210
211 /**
212 * Plug in the Get/Put routines for the given driRenderbuffer.
213 */
214 void
215 ffbSetStencilFunctions(driRenderbuffer *drb, const GLvisual *vis)
216 {
217 assert(drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT);
218 drb->Base.GetRow = FFBReadStencilSpan;
219 drb->Base.GetValues = FFBReadStencilPixels;
220 drb->Base.PutRow = FFBWriteStencilSpan;
221 /*drb->Base.PutMonoRow = FFBWriteMonoStencilSpan;*/
222 drb->Base.PutValues = FFBWriteStencilPixels;
223 drb->Base.PutMonoValues = NULL;
224 }