Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5563 | serge | 1 | /************************************************************************** |
2 | |||
3 | Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California. |
||
4 | |||
5 | All Rights Reserved. |
||
6 | |||
7 | Permission is hereby granted, free of charge, to any person obtaining |
||
8 | a copy of this software and associated documentation files (the |
||
9 | "Software"), to deal in the Software without restriction, including |
||
10 | without limitation the rights to use, copy, modify, merge, publish, |
||
11 | distribute, sublicense, and/or sell copies of the Software, and to |
||
12 | permit persons to whom the Software is furnished to do so, subject to |
||
13 | the following conditions: |
||
14 | |||
15 | The above copyright notice and this permission notice (including the |
||
16 | next paragraph) shall be included in all copies or substantial |
||
17 | portions of the Software. |
||
18 | |||
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
||
22 | IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE |
||
23 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
||
24 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
||
25 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||
26 | |||
27 | **************************************************************************/ |
||
28 | |||
29 | /* |
||
30 | * Authors: |
||
31 | * Gareth Hughes |
||
32 | * Keith Whitwell |
||
33 | */ |
||
34 | |||
35 | #include "main/glheader.h" |
||
36 | #include "main/imports.h" |
||
37 | #include "main/api_arrayelt.h" |
||
38 | #include "main/enums.h" |
||
39 | #include "main/light.h" |
||
40 | #include "main/context.h" |
||
41 | #include "main/framebuffer.h" |
||
42 | #include "main/fbobject.h" |
||
43 | #include "main/simple_list.h" |
||
44 | #include "main/state.h" |
||
45 | #include "main/core.h" |
||
46 | #include "main/stencil.h" |
||
47 | |||
48 | #include "vbo/vbo.h" |
||
49 | #include "tnl/tnl.h" |
||
50 | #include "tnl/t_pipeline.h" |
||
51 | #include "swrast_setup/swrast_setup.h" |
||
52 | #include "drivers/common/meta.h" |
||
53 | |||
54 | #include "radeon_context.h" |
||
55 | #include "radeon_mipmap_tree.h" |
||
56 | #include "radeon_ioctl.h" |
||
57 | #include "radeon_state.h" |
||
58 | #include "radeon_tcl.h" |
||
59 | #include "radeon_tex.h" |
||
60 | #include "radeon_swtcl.h" |
||
61 | |||
62 | static void radeonUpdateSpecular( struct gl_context *ctx ); |
||
63 | |||
64 | /* ============================================================= |
||
65 | * Alpha blending |
||
66 | */ |
||
67 | |||
68 | static void radeonAlphaFunc( struct gl_context *ctx, GLenum func, GLfloat ref ) |
||
69 | { |
||
70 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
71 | int pp_misc = rmesa->hw.ctx.cmd[CTX_PP_MISC]; |
||
72 | GLubyte refByte; |
||
73 | |||
74 | CLAMPED_FLOAT_TO_UBYTE(refByte, ref); |
||
75 | |||
76 | RADEON_STATECHANGE( rmesa, ctx ); |
||
77 | |||
78 | pp_misc &= ~(RADEON_ALPHA_TEST_OP_MASK | RADEON_REF_ALPHA_MASK); |
||
79 | pp_misc |= (refByte & RADEON_REF_ALPHA_MASK); |
||
80 | |||
81 | switch ( func ) { |
||
82 | case GL_NEVER: |
||
83 | pp_misc |= RADEON_ALPHA_TEST_FAIL; |
||
84 | break; |
||
85 | case GL_LESS: |
||
86 | pp_misc |= RADEON_ALPHA_TEST_LESS; |
||
87 | break; |
||
88 | case GL_EQUAL: |
||
89 | pp_misc |= RADEON_ALPHA_TEST_EQUAL; |
||
90 | break; |
||
91 | case GL_LEQUAL: |
||
92 | pp_misc |= RADEON_ALPHA_TEST_LEQUAL; |
||
93 | break; |
||
94 | case GL_GREATER: |
||
95 | pp_misc |= RADEON_ALPHA_TEST_GREATER; |
||
96 | break; |
||
97 | case GL_NOTEQUAL: |
||
98 | pp_misc |= RADEON_ALPHA_TEST_NEQUAL; |
||
99 | break; |
||
100 | case GL_GEQUAL: |
||
101 | pp_misc |= RADEON_ALPHA_TEST_GEQUAL; |
||
102 | break; |
||
103 | case GL_ALWAYS: |
||
104 | pp_misc |= RADEON_ALPHA_TEST_PASS; |
||
105 | break; |
||
106 | } |
||
107 | |||
108 | rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc; |
||
109 | } |
||
110 | |||
111 | static void radeonBlendEquationSeparate( struct gl_context *ctx, |
||
112 | GLenum modeRGB, GLenum modeA ) |
||
113 | { |
||
114 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
115 | GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~RADEON_COMB_FCN_MASK; |
||
116 | GLboolean fallback = GL_FALSE; |
||
117 | |||
118 | assert( modeRGB == modeA ); |
||
119 | |||
120 | switch ( modeRGB ) { |
||
121 | case GL_FUNC_ADD: |
||
122 | case GL_LOGIC_OP: |
||
123 | b |= RADEON_COMB_FCN_ADD_CLAMP; |
||
124 | break; |
||
125 | |||
126 | case GL_FUNC_SUBTRACT: |
||
127 | b |= RADEON_COMB_FCN_SUB_CLAMP; |
||
128 | break; |
||
129 | |||
130 | default: |
||
131 | if (ctx->Color.BlendEnabled) |
||
132 | fallback = GL_TRUE; |
||
133 | else |
||
134 | b |= RADEON_COMB_FCN_ADD_CLAMP; |
||
135 | break; |
||
136 | } |
||
137 | |||
138 | FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, fallback ); |
||
139 | if ( !fallback ) { |
||
140 | RADEON_STATECHANGE( rmesa, ctx ); |
||
141 | rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b; |
||
142 | if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled |
||
143 | && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) { |
||
144 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE; |
||
145 | } else { |
||
146 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE; |
||
147 | } |
||
148 | } |
||
149 | } |
||
150 | |||
151 | static void radeonBlendFuncSeparate( struct gl_context *ctx, |
||
152 | GLenum sfactorRGB, GLenum dfactorRGB, |
||
153 | GLenum sfactorA, GLenum dfactorA ) |
||
154 | { |
||
155 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
156 | GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & |
||
157 | ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK); |
||
158 | GLboolean fallback = GL_FALSE; |
||
159 | |||
160 | switch ( ctx->Color.Blend[0].SrcRGB ) { |
||
161 | case GL_ZERO: |
||
162 | b |= RADEON_SRC_BLEND_GL_ZERO; |
||
163 | break; |
||
164 | case GL_ONE: |
||
165 | b |= RADEON_SRC_BLEND_GL_ONE; |
||
166 | break; |
||
167 | case GL_DST_COLOR: |
||
168 | b |= RADEON_SRC_BLEND_GL_DST_COLOR; |
||
169 | break; |
||
170 | case GL_ONE_MINUS_DST_COLOR: |
||
171 | b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR; |
||
172 | break; |
||
173 | case GL_SRC_COLOR: |
||
174 | b |= RADEON_SRC_BLEND_GL_SRC_COLOR; |
||
175 | break; |
||
176 | case GL_ONE_MINUS_SRC_COLOR: |
||
177 | b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR; |
||
178 | break; |
||
179 | case GL_SRC_ALPHA: |
||
180 | b |= RADEON_SRC_BLEND_GL_SRC_ALPHA; |
||
181 | break; |
||
182 | case GL_ONE_MINUS_SRC_ALPHA: |
||
183 | b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA; |
||
184 | break; |
||
185 | case GL_DST_ALPHA: |
||
186 | b |= RADEON_SRC_BLEND_GL_DST_ALPHA; |
||
187 | break; |
||
188 | case GL_ONE_MINUS_DST_ALPHA: |
||
189 | b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA; |
||
190 | break; |
||
191 | case GL_SRC_ALPHA_SATURATE: |
||
192 | b |= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE; |
||
193 | break; |
||
194 | case GL_CONSTANT_COLOR: |
||
195 | case GL_ONE_MINUS_CONSTANT_COLOR: |
||
196 | case GL_CONSTANT_ALPHA: |
||
197 | case GL_ONE_MINUS_CONSTANT_ALPHA: |
||
198 | if (ctx->Color.BlendEnabled) |
||
199 | fallback = GL_TRUE; |
||
200 | else |
||
201 | b |= RADEON_SRC_BLEND_GL_ONE; |
||
202 | break; |
||
203 | default: |
||
204 | break; |
||
205 | } |
||
206 | |||
207 | switch ( ctx->Color.Blend[0].DstRGB ) { |
||
208 | case GL_ZERO: |
||
209 | b |= RADEON_DST_BLEND_GL_ZERO; |
||
210 | break; |
||
211 | case GL_ONE: |
||
212 | b |= RADEON_DST_BLEND_GL_ONE; |
||
213 | break; |
||
214 | case GL_SRC_COLOR: |
||
215 | b |= RADEON_DST_BLEND_GL_SRC_COLOR; |
||
216 | break; |
||
217 | case GL_ONE_MINUS_SRC_COLOR: |
||
218 | b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR; |
||
219 | break; |
||
220 | case GL_SRC_ALPHA: |
||
221 | b |= RADEON_DST_BLEND_GL_SRC_ALPHA; |
||
222 | break; |
||
223 | case GL_ONE_MINUS_SRC_ALPHA: |
||
224 | b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA; |
||
225 | break; |
||
226 | case GL_DST_COLOR: |
||
227 | b |= RADEON_DST_BLEND_GL_DST_COLOR; |
||
228 | break; |
||
229 | case GL_ONE_MINUS_DST_COLOR: |
||
230 | b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR; |
||
231 | break; |
||
232 | case GL_DST_ALPHA: |
||
233 | b |= RADEON_DST_BLEND_GL_DST_ALPHA; |
||
234 | break; |
||
235 | case GL_ONE_MINUS_DST_ALPHA: |
||
236 | b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA; |
||
237 | break; |
||
238 | case GL_CONSTANT_COLOR: |
||
239 | case GL_ONE_MINUS_CONSTANT_COLOR: |
||
240 | case GL_CONSTANT_ALPHA: |
||
241 | case GL_ONE_MINUS_CONSTANT_ALPHA: |
||
242 | if (ctx->Color.BlendEnabled) |
||
243 | fallback = GL_TRUE; |
||
244 | else |
||
245 | b |= RADEON_DST_BLEND_GL_ZERO; |
||
246 | break; |
||
247 | default: |
||
248 | break; |
||
249 | } |
||
250 | |||
251 | FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, fallback ); |
||
252 | if ( !fallback ) { |
||
253 | RADEON_STATECHANGE( rmesa, ctx ); |
||
254 | rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b; |
||
255 | } |
||
256 | } |
||
257 | |||
258 | |||
259 | /* ============================================================= |
||
260 | * Depth testing |
||
261 | */ |
||
262 | |||
263 | static void radeonDepthFunc( struct gl_context *ctx, GLenum func ) |
||
264 | { |
||
265 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
266 | |||
267 | RADEON_STATECHANGE( rmesa, ctx ); |
||
268 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_TEST_MASK; |
||
269 | |||
270 | switch ( ctx->Depth.Func ) { |
||
271 | case GL_NEVER: |
||
272 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEVER; |
||
273 | break; |
||
274 | case GL_LESS: |
||
275 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LESS; |
||
276 | break; |
||
277 | case GL_EQUAL: |
||
278 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_EQUAL; |
||
279 | break; |
||
280 | case GL_LEQUAL: |
||
281 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LEQUAL; |
||
282 | break; |
||
283 | case GL_GREATER: |
||
284 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GREATER; |
||
285 | break; |
||
286 | case GL_NOTEQUAL: |
||
287 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEQUAL; |
||
288 | break; |
||
289 | case GL_GEQUAL: |
||
290 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GEQUAL; |
||
291 | break; |
||
292 | case GL_ALWAYS: |
||
293 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_ALWAYS; |
||
294 | break; |
||
295 | } |
||
296 | } |
||
297 | |||
298 | |||
299 | static void radeonDepthMask( struct gl_context *ctx, GLboolean flag ) |
||
300 | { |
||
301 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
302 | RADEON_STATECHANGE( rmesa, ctx ); |
||
303 | |||
304 | if ( ctx->Depth.Mask ) { |
||
305 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_WRITE_ENABLE; |
||
306 | } else { |
||
307 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_WRITE_ENABLE; |
||
308 | } |
||
309 | } |
||
310 | |||
311 | |||
312 | /* ============================================================= |
||
313 | * Fog |
||
314 | */ |
||
315 | |||
316 | |||
317 | static void radeonFogfv( struct gl_context *ctx, GLenum pname, const GLfloat *param ) |
||
318 | { |
||
319 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
320 | union { int i; float f; } c, d; |
||
321 | GLubyte col[4]; |
||
322 | |||
323 | switch (pname) { |
||
324 | case GL_FOG_MODE: |
||
325 | if (!ctx->Fog.Enabled) |
||
326 | return; |
||
327 | RADEON_STATECHANGE(rmesa, tcl); |
||
328 | rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK; |
||
329 | switch (ctx->Fog.Mode) { |
||
330 | case GL_LINEAR: |
||
331 | rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR; |
||
332 | break; |
||
333 | case GL_EXP: |
||
334 | rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP; |
||
335 | break; |
||
336 | case GL_EXP2: |
||
337 | rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2; |
||
338 | break; |
||
339 | default: |
||
340 | return; |
||
341 | } |
||
342 | /* fallthrough */ |
||
343 | case GL_FOG_DENSITY: |
||
344 | case GL_FOG_START: |
||
345 | case GL_FOG_END: |
||
346 | if (!ctx->Fog.Enabled) |
||
347 | return; |
||
348 | c.i = rmesa->hw.fog.cmd[FOG_C]; |
||
349 | d.i = rmesa->hw.fog.cmd[FOG_D]; |
||
350 | switch (ctx->Fog.Mode) { |
||
351 | case GL_EXP: |
||
352 | c.f = 0.0; |
||
353 | /* While this is the opposite sign from the DDK, it makes the fog test |
||
354 | * pass, and matches r200. |
||
355 | */ |
||
356 | d.f = -ctx->Fog.Density; |
||
357 | break; |
||
358 | case GL_EXP2: |
||
359 | c.f = 0.0; |
||
360 | d.f = -(ctx->Fog.Density * ctx->Fog.Density); |
||
361 | break; |
||
362 | case GL_LINEAR: |
||
363 | if (ctx->Fog.Start == ctx->Fog.End) { |
||
364 | c.f = 1.0F; |
||
365 | d.f = 1.0F; |
||
366 | } else { |
||
367 | c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start); |
||
368 | /* While this is the opposite sign from the DDK, it makes the fog |
||
369 | * test pass, and matches r200. |
||
370 | */ |
||
371 | d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start); |
||
372 | } |
||
373 | break; |
||
374 | default: |
||
375 | break; |
||
376 | } |
||
377 | if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) { |
||
378 | RADEON_STATECHANGE( rmesa, fog ); |
||
379 | rmesa->hw.fog.cmd[FOG_C] = c.i; |
||
380 | rmesa->hw.fog.cmd[FOG_D] = d.i; |
||
381 | } |
||
382 | break; |
||
383 | case GL_FOG_COLOR: |
||
384 | RADEON_STATECHANGE( rmesa, ctx ); |
||
385 | _mesa_unclamped_float_rgba_to_ubyte(col, ctx->Fog.Color ); |
||
386 | rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~RADEON_FOG_COLOR_MASK; |
||
387 | rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= |
||
388 | radeonPackColor( 4, col[0], col[1], col[2], 0 ); |
||
389 | break; |
||
390 | case GL_FOG_COORD_SRC: |
||
391 | radeonUpdateSpecular( ctx ); |
||
392 | break; |
||
393 | default: |
||
394 | return; |
||
395 | } |
||
396 | } |
||
397 | |||
398 | /* ============================================================= |
||
399 | * Culling |
||
400 | */ |
||
401 | |||
402 | static void radeonCullFace( struct gl_context *ctx, GLenum unused ) |
||
403 | { |
||
404 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
405 | GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL]; |
||
406 | GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL]; |
||
407 | |||
408 | s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID; |
||
409 | t &= ~(RADEON_CULL_FRONT | RADEON_CULL_BACK); |
||
410 | |||
411 | if ( ctx->Polygon.CullFlag ) { |
||
412 | switch ( ctx->Polygon.CullFaceMode ) { |
||
413 | case GL_FRONT: |
||
414 | s &= ~RADEON_FFACE_SOLID; |
||
415 | t |= RADEON_CULL_FRONT; |
||
416 | break; |
||
417 | case GL_BACK: |
||
418 | s &= ~RADEON_BFACE_SOLID; |
||
419 | t |= RADEON_CULL_BACK; |
||
420 | break; |
||
421 | case GL_FRONT_AND_BACK: |
||
422 | s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID); |
||
423 | t |= (RADEON_CULL_FRONT | RADEON_CULL_BACK); |
||
424 | break; |
||
425 | } |
||
426 | } |
||
427 | |||
428 | if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) { |
||
429 | RADEON_STATECHANGE(rmesa, set ); |
||
430 | rmesa->hw.set.cmd[SET_SE_CNTL] = s; |
||
431 | } |
||
432 | |||
433 | if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) { |
||
434 | RADEON_STATECHANGE(rmesa, tcl ); |
||
435 | rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t; |
||
436 | } |
||
437 | } |
||
438 | |||
439 | static void radeonFrontFace( struct gl_context *ctx, GLenum mode ) |
||
440 | { |
||
441 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
442 | int cull_face = (mode == GL_CW) ? RADEON_FFACE_CULL_CW : RADEON_FFACE_CULL_CCW; |
||
443 | |||
444 | RADEON_STATECHANGE( rmesa, set ); |
||
445 | rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_FFACE_CULL_DIR_MASK; |
||
446 | |||
447 | RADEON_STATECHANGE( rmesa, tcl ); |
||
448 | rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_CULL_FRONT_IS_CCW; |
||
449 | |||
450 | /* Winding is inverted when rendering to FBO */ |
||
451 | if (ctx->DrawBuffer && _mesa_is_user_fbo(ctx->DrawBuffer)) |
||
452 | cull_face = (mode == GL_CCW) ? RADEON_FFACE_CULL_CW : RADEON_FFACE_CULL_CCW; |
||
453 | rmesa->hw.set.cmd[SET_SE_CNTL] |= cull_face; |
||
454 | |||
455 | if ( mode == GL_CCW ) |
||
456 | rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_CULL_FRONT_IS_CCW; |
||
457 | } |
||
458 | |||
459 | |||
460 | /* ============================================================= |
||
461 | * Line state |
||
462 | */ |
||
463 | static void radeonLineWidth( struct gl_context *ctx, GLfloat widthf ) |
||
464 | { |
||
465 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
466 | |||
467 | RADEON_STATECHANGE( rmesa, lin ); |
||
468 | RADEON_STATECHANGE( rmesa, set ); |
||
469 | |||
470 | /* Line width is stored in U6.4 format. |
||
471 | */ |
||
472 | rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (GLuint)(widthf * 16.0); |
||
473 | if ( widthf > 1.0 ) { |
||
474 | rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_WIDELINE_ENABLE; |
||
475 | } else { |
||
476 | rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_WIDELINE_ENABLE; |
||
477 | } |
||
478 | } |
||
479 | |||
480 | static void radeonLineStipple( struct gl_context *ctx, GLint factor, GLushort pattern ) |
||
481 | { |
||
482 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
483 | |||
484 | RADEON_STATECHANGE( rmesa, lin ); |
||
485 | rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] = |
||
486 | ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern)); |
||
487 | } |
||
488 | |||
489 | |||
490 | /* ============================================================= |
||
491 | * Masks |
||
492 | */ |
||
493 | static void radeonColorMask( struct gl_context *ctx, |
||
494 | GLboolean r, GLboolean g, |
||
495 | GLboolean b, GLboolean a ) |
||
496 | { |
||
497 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
498 | struct radeon_renderbuffer *rrb; |
||
499 | GLuint mask; |
||
500 | |||
501 | rrb = radeon_get_colorbuffer(&rmesa->radeon); |
||
502 | if (!rrb) |
||
503 | return; |
||
504 | |||
505 | mask = radeonPackColor( rrb->cpp, |
||
506 | ctx->Color.ColorMask[0][RCOMP], |
||
507 | ctx->Color.ColorMask[0][GCOMP], |
||
508 | ctx->Color.ColorMask[0][BCOMP], |
||
509 | ctx->Color.ColorMask[0][ACOMP] ); |
||
510 | |||
511 | if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) { |
||
512 | RADEON_STATECHANGE( rmesa, msk ); |
||
513 | rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask; |
||
514 | } |
||
515 | } |
||
516 | |||
517 | |||
518 | /* ============================================================= |
||
519 | * Polygon state |
||
520 | */ |
||
521 | |||
522 | static void radeonPolygonOffset( struct gl_context *ctx, |
||
523 | GLfloat factor, GLfloat units ) |
||
524 | { |
||
525 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
526 | const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; |
||
527 | float_ui32_type constant = { units * depthScale }; |
||
528 | float_ui32_type factoru = { factor }; |
||
529 | |||
530 | RADEON_STATECHANGE( rmesa, zbs ); |
||
531 | rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR] = factoru.ui32; |
||
532 | rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32; |
||
533 | } |
||
534 | |||
535 | static void radeonPolygonMode( struct gl_context *ctx, GLenum face, GLenum mode ) |
||
536 | { |
||
537 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
538 | GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL || |
||
539 | ctx->Polygon.BackMode != GL_FILL); |
||
540 | |||
541 | /* Can't generally do unfilled via tcl, but some good special |
||
542 | * cases work. |
||
543 | */ |
||
544 | TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_UNFILLED, unfilled); |
||
545 | if (rmesa->radeon.TclFallback) { |
||
546 | radeonChooseRenderState( ctx ); |
||
547 | radeonChooseVertexState( ctx ); |
||
548 | } |
||
549 | } |
||
550 | |||
551 | |||
552 | /* ============================================================= |
||
553 | * Rendering attributes |
||
554 | * |
||
555 | * We really don't want to recalculate all this every time we bind a |
||
556 | * texture. These things shouldn't change all that often, so it makes |
||
557 | * sense to break them out of the core texture state update routines. |
||
558 | */ |
||
559 | |||
560 | /* Examine lighting and texture state to determine if separate specular |
||
561 | * should be enabled. |
||
562 | */ |
||
563 | static void radeonUpdateSpecular( struct gl_context *ctx ) |
||
564 | { |
||
565 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
566 | uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL]; |
||
567 | GLuint flag = 0; |
||
568 | |||
569 | RADEON_STATECHANGE( rmesa, tcl ); |
||
570 | |||
571 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; |
||
572 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; |
||
573 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC; |
||
574 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_DIFFUSE; |
||
575 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE; |
||
576 | |||
577 | p &= ~RADEON_SPECULAR_ENABLE; |
||
578 | |||
579 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_DIFFUSE_SPECULAR_COMBINE; |
||
580 | |||
581 | |||
582 | if (ctx->Light.Enabled && |
||
583 | ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) { |
||
584 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; |
||
585 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; |
||
586 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; |
||
587 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; |
||
588 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; |
||
589 | p |= RADEON_SPECULAR_ENABLE; |
||
590 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= |
||
591 | ~RADEON_DIFFUSE_SPECULAR_COMBINE; |
||
592 | } |
||
593 | else if (ctx->Light.Enabled) { |
||
594 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; |
||
595 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; |
||
596 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; |
||
597 | } else if (ctx->Fog.ColorSumEnabled ) { |
||
598 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; |
||
599 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; |
||
600 | p |= RADEON_SPECULAR_ENABLE; |
||
601 | } else { |
||
602 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; |
||
603 | } |
||
604 | |||
605 | if (ctx->Fog.Enabled) { |
||
606 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; |
||
607 | if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH) { |
||
608 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; |
||
609 | /* Bizzare: have to leave lighting enabled to get fog. */ |
||
610 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; |
||
611 | } |
||
612 | else { |
||
613 | /* cannot do tcl fog factor calculation with fog coord source |
||
614 | * (send precomputed factors). Cannot use precomputed fog |
||
615 | * factors together with tcl spec light (need tcl fallback) */ |
||
616 | flag = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] & |
||
617 | RADEON_TCL_COMPUTE_SPECULAR) != 0; |
||
618 | } |
||
619 | } |
||
620 | |||
621 | TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_FOGCOORDSPEC, flag); |
||
622 | |||
623 | if (_mesa_need_secondary_color(ctx)) { |
||
624 | assert( (p & RADEON_SPECULAR_ENABLE) != 0 ); |
||
625 | } else { |
||
626 | assert( (p & RADEON_SPECULAR_ENABLE) == 0 ); |
||
627 | } |
||
628 | |||
629 | if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) { |
||
630 | RADEON_STATECHANGE( rmesa, ctx ); |
||
631 | rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p; |
||
632 | } |
||
633 | |||
634 | /* Update vertex/render formats |
||
635 | */ |
||
636 | if (rmesa->radeon.TclFallback) { |
||
637 | radeonChooseRenderState( ctx ); |
||
638 | radeonChooseVertexState( ctx ); |
||
639 | } |
||
640 | } |
||
641 | |||
642 | |||
643 | /* ============================================================= |
||
644 | * Materials |
||
645 | */ |
||
646 | |||
647 | |||
648 | /* Update on colormaterial, material emmissive/ambient, |
||
649 | * lightmodel.globalambient |
||
650 | */ |
||
651 | static void update_global_ambient( struct gl_context *ctx ) |
||
652 | { |
||
653 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
654 | float *fcmd = (float *)RADEON_DB_STATE( glt ); |
||
655 | |||
656 | /* Need to do more if both emmissive & ambient are PREMULT: |
||
657 | * Hope this is not needed for MULT |
||
658 | */ |
||
659 | if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] & |
||
660 | ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) | |
||
661 | (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0) |
||
662 | { |
||
663 | COPY_3V( &fcmd[GLT_RED], |
||
664 | ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]); |
||
665 | ACC_SCALE_3V( &fcmd[GLT_RED], |
||
666 | ctx->Light.Model.Ambient, |
||
667 | ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]); |
||
668 | } |
||
669 | else |
||
670 | { |
||
671 | COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient ); |
||
672 | } |
||
673 | |||
674 | RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt); |
||
675 | } |
||
676 | |||
677 | /* Update on change to |
||
678 | * - light[p].colors |
||
679 | * - light[p].enabled |
||
680 | */ |
||
681 | static void update_light_colors( struct gl_context *ctx, GLuint p ) |
||
682 | { |
||
683 | struct gl_light *l = &ctx->Light.Light[p]; |
||
684 | |||
685 | /* fprintf(stderr, "%s\n", __FUNCTION__); */ |
||
686 | |||
687 | if (l->Enabled) { |
||
688 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
689 | float *fcmd = (float *)RADEON_DB_STATE( lit[p] ); |
||
690 | |||
691 | COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient ); |
||
692 | COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse ); |
||
693 | COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular ); |
||
694 | |||
695 | RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); |
||
696 | } |
||
697 | } |
||
698 | |||
699 | /* Also fallback for asym colormaterial mode in twoside lighting... |
||
700 | */ |
||
701 | static void check_twoside_fallback( struct gl_context *ctx ) |
||
702 | { |
||
703 | GLboolean fallback = GL_FALSE; |
||
704 | GLint i; |
||
705 | |||
706 | if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) { |
||
707 | if (ctx->Light.ColorMaterialEnabled && |
||
708 | (ctx->Light._ColorMaterialBitmask & BACK_MATERIAL_BITS) != |
||
709 | ((ctx->Light._ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1)) |
||
710 | fallback = GL_TRUE; |
||
711 | else { |
||
712 | for (i = MAT_ATTRIB_FRONT_AMBIENT; i < MAT_ATTRIB_FRONT_INDEXES; i+=2) |
||
713 | if (memcmp( ctx->Light.Material.Attrib[i], |
||
714 | ctx->Light.Material.Attrib[i+1], |
||
715 | sizeof(GLfloat)*4) != 0) { |
||
716 | fallback = GL_TRUE; |
||
717 | break; |
||
718 | } |
||
719 | } |
||
720 | } |
||
721 | |||
722 | TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback ); |
||
723 | } |
||
724 | |||
725 | |||
726 | static void radeonColorMaterial( struct gl_context *ctx, GLenum face, GLenum mode ) |
||
727 | { |
||
728 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
729 | GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]; |
||
730 | |||
731 | light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) | |
||
732 | (3 << RADEON_AMBIENT_SOURCE_SHIFT) | |
||
733 | (3 << RADEON_DIFFUSE_SOURCE_SHIFT) | |
||
734 | (3 << RADEON_SPECULAR_SOURCE_SHIFT)); |
||
735 | |||
736 | if (ctx->Light.ColorMaterialEnabled) { |
||
737 | GLuint mask = ctx->Light._ColorMaterialBitmask; |
||
738 | |||
739 | if (mask & MAT_BIT_FRONT_EMISSION) { |
||
740 | light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << |
||
741 | RADEON_EMISSIVE_SOURCE_SHIFT); |
||
742 | } |
||
743 | else { |
||
744 | light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << |
||
745 | RADEON_EMISSIVE_SOURCE_SHIFT); |
||
746 | } |
||
747 | |||
748 | if (mask & MAT_BIT_FRONT_AMBIENT) { |
||
749 | light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << |
||
750 | RADEON_AMBIENT_SOURCE_SHIFT); |
||
751 | } |
||
752 | else { |
||
753 | light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << |
||
754 | RADEON_AMBIENT_SOURCE_SHIFT); |
||
755 | } |
||
756 | |||
757 | if (mask & MAT_BIT_FRONT_DIFFUSE) { |
||
758 | light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << |
||
759 | RADEON_DIFFUSE_SOURCE_SHIFT); |
||
760 | } |
||
761 | else { |
||
762 | light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << |
||
763 | RADEON_DIFFUSE_SOURCE_SHIFT); |
||
764 | } |
||
765 | |||
766 | if (mask & MAT_BIT_FRONT_SPECULAR) { |
||
767 | light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << |
||
768 | RADEON_SPECULAR_SOURCE_SHIFT); |
||
769 | } |
||
770 | else { |
||
771 | light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << |
||
772 | RADEON_SPECULAR_SOURCE_SHIFT); |
||
773 | } |
||
774 | } |
||
775 | else { |
||
776 | /* Default to MULT: |
||
777 | */ |
||
778 | light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_EMISSIVE_SOURCE_SHIFT) | |
||
779 | (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT) | |
||
780 | (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) | |
||
781 | (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT); |
||
782 | } |
||
783 | |||
784 | if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) { |
||
785 | RADEON_STATECHANGE( rmesa, tcl ); |
||
786 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl1; |
||
787 | } |
||
788 | } |
||
789 | |||
790 | void radeonUpdateMaterial( struct gl_context *ctx ) |
||
791 | { |
||
792 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
793 | GLfloat (*mat)[4] = ctx->Light.Material.Attrib; |
||
794 | GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl ); |
||
795 | GLuint mask = ~0; |
||
796 | |||
797 | if (ctx->Light.ColorMaterialEnabled) |
||
798 | mask &= ~ctx->Light._ColorMaterialBitmask; |
||
799 | |||
800 | if (RADEON_DEBUG & RADEON_STATE) |
||
801 | fprintf(stderr, "%s\n", __FUNCTION__); |
||
802 | |||
803 | |||
804 | if (mask & MAT_BIT_FRONT_EMISSION) { |
||
805 | fcmd[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_FRONT_EMISSION][0]; |
||
806 | fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1]; |
||
807 | fcmd[MTL_EMMISSIVE_BLUE] = mat[MAT_ATTRIB_FRONT_EMISSION][2]; |
||
808 | fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3]; |
||
809 | } |
||
810 | if (mask & MAT_BIT_FRONT_AMBIENT) { |
||
811 | fcmd[MTL_AMBIENT_RED] = mat[MAT_ATTRIB_FRONT_AMBIENT][0]; |
||
812 | fcmd[MTL_AMBIENT_GREEN] = mat[MAT_ATTRIB_FRONT_AMBIENT][1]; |
||
813 | fcmd[MTL_AMBIENT_BLUE] = mat[MAT_ATTRIB_FRONT_AMBIENT][2]; |
||
814 | fcmd[MTL_AMBIENT_ALPHA] = mat[MAT_ATTRIB_FRONT_AMBIENT][3]; |
||
815 | } |
||
816 | if (mask & MAT_BIT_FRONT_DIFFUSE) { |
||
817 | fcmd[MTL_DIFFUSE_RED] = mat[MAT_ATTRIB_FRONT_DIFFUSE][0]; |
||
818 | fcmd[MTL_DIFFUSE_GREEN] = mat[MAT_ATTRIB_FRONT_DIFFUSE][1]; |
||
819 | fcmd[MTL_DIFFUSE_BLUE] = mat[MAT_ATTRIB_FRONT_DIFFUSE][2]; |
||
820 | fcmd[MTL_DIFFUSE_ALPHA] = mat[MAT_ATTRIB_FRONT_DIFFUSE][3]; |
||
821 | } |
||
822 | if (mask & MAT_BIT_FRONT_SPECULAR) { |
||
823 | fcmd[MTL_SPECULAR_RED] = mat[MAT_ATTRIB_FRONT_SPECULAR][0]; |
||
824 | fcmd[MTL_SPECULAR_GREEN] = mat[MAT_ATTRIB_FRONT_SPECULAR][1]; |
||
825 | fcmd[MTL_SPECULAR_BLUE] = mat[MAT_ATTRIB_FRONT_SPECULAR][2]; |
||
826 | fcmd[MTL_SPECULAR_ALPHA] = mat[MAT_ATTRIB_FRONT_SPECULAR][3]; |
||
827 | } |
||
828 | if (mask & MAT_BIT_FRONT_SHININESS) { |
||
829 | fcmd[MTL_SHININESS] = mat[MAT_ATTRIB_FRONT_SHININESS][0]; |
||
830 | } |
||
831 | |||
832 | RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl ); |
||
833 | |||
834 | check_twoside_fallback( ctx ); |
||
835 | /* update_global_ambient( ctx );*/ |
||
836 | } |
||
837 | |||
838 | /* _NEW_LIGHT |
||
839 | * _NEW_MODELVIEW |
||
840 | * _MESA_NEW_NEED_EYE_COORDS |
||
841 | * |
||
842 | * Uses derived state from mesa: |
||
843 | * _VP_inf_norm |
||
844 | * _h_inf_norm |
||
845 | * _Position |
||
846 | * _NormSpotDirection |
||
847 | * _ModelViewInvScale |
||
848 | * _NeedEyeCoords |
||
849 | * _EyeZDir |
||
850 | * |
||
851 | * which are calculated in light.c and are correct for the current |
||
852 | * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW |
||
853 | * and _MESA_NEW_NEED_EYE_COORDS. |
||
854 | */ |
||
855 | static void update_light( struct gl_context *ctx ) |
||
856 | { |
||
857 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
858 | |||
859 | /* Have to check these, or have an automatic shortcircuit mechanism |
||
860 | * to remove noop statechanges. (Or just do a better job on the |
||
861 | * front end). |
||
862 | */ |
||
863 | { |
||
864 | GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]; |
||
865 | |||
866 | if (ctx->_NeedEyeCoords) |
||
867 | tmp &= ~RADEON_LIGHT_IN_MODELSPACE; |
||
868 | else |
||
869 | tmp |= RADEON_LIGHT_IN_MODELSPACE; |
||
870 | |||
871 | |||
872 | /* Leave this test disabled: (unexplained q3 lockup) (even with |
||
873 | new packets) |
||
874 | */ |
||
875 | if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) |
||
876 | { |
||
877 | RADEON_STATECHANGE( rmesa, tcl ); |
||
878 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp; |
||
879 | } |
||
880 | } |
||
881 | |||
882 | { |
||
883 | GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye ); |
||
884 | fcmd[EYE_X] = ctx->_EyeZDir[0]; |
||
885 | fcmd[EYE_Y] = ctx->_EyeZDir[1]; |
||
886 | fcmd[EYE_Z] = - ctx->_EyeZDir[2]; |
||
887 | fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale; |
||
888 | RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye ); |
||
889 | } |
||
890 | |||
891 | |||
892 | |||
893 | if (ctx->Light.Enabled) { |
||
894 | GLint p; |
||
895 | for (p = 0 ; p < MAX_LIGHTS; p++) { |
||
896 | if (ctx->Light.Light[p].Enabled) { |
||
897 | struct gl_light *l = &ctx->Light.Light[p]; |
||
898 | GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] ); |
||
899 | |||
900 | if (l->EyePosition[3] == 0.0) { |
||
901 | COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm ); |
||
902 | COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm ); |
||
903 | fcmd[LIT_POSITION_W] = 0; |
||
904 | fcmd[LIT_DIRECTION_W] = 0; |
||
905 | } else { |
||
906 | COPY_4V( &fcmd[LIT_POSITION_X], l->_Position ); |
||
907 | fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0]; |
||
908 | fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1]; |
||
909 | fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2]; |
||
910 | fcmd[LIT_DIRECTION_W] = 0; |
||
911 | } |
||
912 | |||
913 | RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); |
||
914 | } |
||
915 | } |
||
916 | } |
||
917 | } |
||
918 | |||
919 | static void radeonLightfv( struct gl_context *ctx, GLenum light, |
||
920 | GLenum pname, const GLfloat *params ) |
||
921 | { |
||
922 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
923 | GLint p = light - GL_LIGHT0; |
||
924 | struct gl_light *l = &ctx->Light.Light[p]; |
||
925 | GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd; |
||
926 | |||
927 | |||
928 | switch (pname) { |
||
929 | case GL_AMBIENT: |
||
930 | case GL_DIFFUSE: |
||
931 | case GL_SPECULAR: |
||
932 | update_light_colors( ctx, p ); |
||
933 | break; |
||
934 | |||
935 | case GL_SPOT_DIRECTION: |
||
936 | /* picked up in update_light */ |
||
937 | break; |
||
938 | |||
939 | case GL_POSITION: { |
||
940 | /* positions picked up in update_light, but can do flag here */ |
||
941 | GLuint flag; |
||
942 | GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; |
||
943 | |||
944 | /* FIXME: Set RANGE_ATTEN only when needed */ |
||
945 | if (p&1) |
||
946 | flag = RADEON_LIGHT_1_IS_LOCAL; |
||
947 | else |
||
948 | flag = RADEON_LIGHT_0_IS_LOCAL; |
||
949 | |||
950 | RADEON_STATECHANGE(rmesa, tcl); |
||
951 | if (l->EyePosition[3] != 0.0F) |
||
952 | rmesa->hw.tcl.cmd[idx] |= flag; |
||
953 | else |
||
954 | rmesa->hw.tcl.cmd[idx] &= ~flag; |
||
955 | break; |
||
956 | } |
||
957 | |||
958 | case GL_SPOT_EXPONENT: |
||
959 | RADEON_STATECHANGE(rmesa, lit[p]); |
||
960 | fcmd[LIT_SPOT_EXPONENT] = params[0]; |
||
961 | break; |
||
962 | |||
963 | case GL_SPOT_CUTOFF: { |
||
964 | GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT; |
||
965 | GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; |
||
966 | |||
967 | RADEON_STATECHANGE(rmesa, lit[p]); |
||
968 | fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff; |
||
969 | |||
970 | RADEON_STATECHANGE(rmesa, tcl); |
||
971 | if (l->SpotCutoff != 180.0F) |
||
972 | rmesa->hw.tcl.cmd[idx] |= flag; |
||
973 | else |
||
974 | rmesa->hw.tcl.cmd[idx] &= ~flag; |
||
975 | |||
976 | break; |
||
977 | } |
||
978 | |||
979 | case GL_CONSTANT_ATTENUATION: |
||
980 | RADEON_STATECHANGE(rmesa, lit[p]); |
||
981 | fcmd[LIT_ATTEN_CONST] = params[0]; |
||
982 | if ( params[0] == 0.0 ) |
||
983 | fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX; |
||
984 | else |
||
985 | fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0]; |
||
986 | break; |
||
987 | case GL_LINEAR_ATTENUATION: |
||
988 | RADEON_STATECHANGE(rmesa, lit[p]); |
||
989 | fcmd[LIT_ATTEN_LINEAR] = params[0]; |
||
990 | break; |
||
991 | case GL_QUADRATIC_ATTENUATION: |
||
992 | RADEON_STATECHANGE(rmesa, lit[p]); |
||
993 | fcmd[LIT_ATTEN_QUADRATIC] = params[0]; |
||
994 | break; |
||
995 | default: |
||
996 | return; |
||
997 | } |
||
998 | |||
999 | /* Set RANGE_ATTEN only when needed */ |
||
1000 | switch (pname) { |
||
1001 | case GL_POSITION: |
||
1002 | case GL_CONSTANT_ATTENUATION: |
||
1003 | case GL_LINEAR_ATTENUATION: |
||
1004 | case GL_QUADRATIC_ATTENUATION: |
||
1005 | { |
||
1006 | GLuint *icmd = (GLuint *)RADEON_DB_STATE( tcl ); |
||
1007 | GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; |
||
1008 | GLuint atten_flag = ( p&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN |
||
1009 | : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN; |
||
1010 | GLuint atten_const_flag = ( p&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN |
||
1011 | : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN; |
||
1012 | |||
1013 | if ( l->EyePosition[3] == 0.0F || |
||
1014 | ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) && |
||
1015 | fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) { |
||
1016 | /* Disable attenuation */ |
||
1017 | icmd[idx] &= ~atten_flag; |
||
1018 | } else { |
||
1019 | if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) { |
||
1020 | /* Enable only constant portion of attenuation calculation */ |
||
1021 | icmd[idx] |= ( atten_flag | atten_const_flag ); |
||
1022 | } else { |
||
1023 | /* Enable full attenuation calculation */ |
||
1024 | icmd[idx] &= ~atten_const_flag; |
||
1025 | icmd[idx] |= atten_flag; |
||
1026 | } |
||
1027 | } |
||
1028 | |||
1029 | RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tcl ); |
||
1030 | break; |
||
1031 | } |
||
1032 | default: |
||
1033 | break; |
||
1034 | } |
||
1035 | } |
||
1036 | |||
1037 | |||
1038 | |||
1039 | |||
1040 | static void radeonLightModelfv( struct gl_context *ctx, GLenum pname, |
||
1041 | const GLfloat *param ) |
||
1042 | { |
||
1043 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
1044 | |||
1045 | switch (pname) { |
||
1046 | case GL_LIGHT_MODEL_AMBIENT: |
||
1047 | update_global_ambient( ctx ); |
||
1048 | break; |
||
1049 | |||
1050 | case GL_LIGHT_MODEL_LOCAL_VIEWER: |
||
1051 | RADEON_STATECHANGE( rmesa, tcl ); |
||
1052 | if (ctx->Light.Model.LocalViewer) |
||
1053 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER; |
||
1054 | else |
||
1055 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER; |
||
1056 | break; |
||
1057 | |||
1058 | case GL_LIGHT_MODEL_TWO_SIDE: |
||
1059 | RADEON_STATECHANGE( rmesa, tcl ); |
||
1060 | if (ctx->Light.Model.TwoSide) |
||
1061 | rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE; |
||
1062 | else |
||
1063 | rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE; |
||
1064 | |||
1065 | check_twoside_fallback( ctx ); |
||
1066 | |||
1067 | if (rmesa->radeon.TclFallback) { |
||
1068 | radeonChooseRenderState( ctx ); |
||
1069 | radeonChooseVertexState( ctx ); |
||
1070 | } |
||
1071 | break; |
||
1072 | |||
1073 | case GL_LIGHT_MODEL_COLOR_CONTROL: |
||
1074 | radeonUpdateSpecular(ctx); |
||
1075 | break; |
||
1076 | |||
1077 | default: |
||
1078 | break; |
||
1079 | } |
||
1080 | } |
||
1081 | |||
1082 | static void radeonShadeModel( struct gl_context *ctx, GLenum mode ) |
||
1083 | { |
||
1084 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
1085 | GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL]; |
||
1086 | |||
1087 | s &= ~(RADEON_DIFFUSE_SHADE_MASK | |
||
1088 | RADEON_ALPHA_SHADE_MASK | |
||
1089 | RADEON_SPECULAR_SHADE_MASK | |
||
1090 | RADEON_FOG_SHADE_MASK); |
||
1091 | |||
1092 | switch ( mode ) { |
||
1093 | case GL_FLAT: |
||
1094 | s |= (RADEON_DIFFUSE_SHADE_FLAT | |
||
1095 | RADEON_ALPHA_SHADE_FLAT | |
||
1096 | RADEON_SPECULAR_SHADE_FLAT | |
||
1097 | RADEON_FOG_SHADE_FLAT); |
||
1098 | break; |
||
1099 | case GL_SMOOTH: |
||
1100 | s |= (RADEON_DIFFUSE_SHADE_GOURAUD | |
||
1101 | RADEON_ALPHA_SHADE_GOURAUD | |
||
1102 | RADEON_SPECULAR_SHADE_GOURAUD | |
||
1103 | RADEON_FOG_SHADE_GOURAUD); |
||
1104 | break; |
||
1105 | default: |
||
1106 | return; |
||
1107 | } |
||
1108 | |||
1109 | if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) { |
||
1110 | RADEON_STATECHANGE( rmesa, set ); |
||
1111 | rmesa->hw.set.cmd[SET_SE_CNTL] = s; |
||
1112 | } |
||
1113 | } |
||
1114 | |||
1115 | |||
1116 | /* ============================================================= |
||
1117 | * User clip planes |
||
1118 | */ |
||
1119 | |||
1120 | static void radeonClipPlane( struct gl_context *ctx, GLenum plane, const GLfloat *eq ) |
||
1121 | { |
||
1122 | GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0; |
||
1123 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
1124 | GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p]; |
||
1125 | |||
1126 | RADEON_STATECHANGE( rmesa, ucp[p] ); |
||
1127 | rmesa->hw.ucp[p].cmd[UCP_X] = ip[0]; |
||
1128 | rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1]; |
||
1129 | rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2]; |
||
1130 | rmesa->hw.ucp[p].cmd[UCP_W] = ip[3]; |
||
1131 | } |
||
1132 | |||
1133 | static void radeonUpdateClipPlanes( struct gl_context *ctx ) |
||
1134 | { |
||
1135 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
1136 | GLuint p; |
||
1137 | |||
1138 | for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { |
||
1139 | if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { |
||
1140 | GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p]; |
||
1141 | |||
1142 | RADEON_STATECHANGE( rmesa, ucp[p] ); |
||
1143 | rmesa->hw.ucp[p].cmd[UCP_X] = ip[0]; |
||
1144 | rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1]; |
||
1145 | rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2]; |
||
1146 | rmesa->hw.ucp[p].cmd[UCP_W] = ip[3]; |
||
1147 | } |
||
1148 | } |
||
1149 | } |
||
1150 | |||
1151 | |||
1152 | /* ============================================================= |
||
1153 | * Stencil |
||
1154 | */ |
||
1155 | |||
1156 | static void |
||
1157 | radeonStencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func, |
||
1158 | GLint ref, GLuint mask ) |
||
1159 | { |
||
1160 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
1161 | GLuint refmask = ((_mesa_get_stencil_ref(ctx, 0) << RADEON_STENCIL_REF_SHIFT) | |
||
1162 | ((ctx->Stencil.ValueMask[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT)); |
||
1163 | |||
1164 | RADEON_STATECHANGE( rmesa, ctx ); |
||
1165 | RADEON_STATECHANGE( rmesa, msk ); |
||
1166 | |||
1167 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_STENCIL_TEST_MASK; |
||
1168 | rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(RADEON_STENCIL_REF_MASK| |
||
1169 | RADEON_STENCIL_VALUE_MASK); |
||
1170 | |||
1171 | switch ( ctx->Stencil.Function[0] ) { |
||
1172 | case GL_NEVER: |
||
1173 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEVER; |
||
1174 | break; |
||
1175 | case GL_LESS: |
||
1176 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LESS; |
||
1177 | break; |
||
1178 | case GL_EQUAL: |
||
1179 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_EQUAL; |
||
1180 | break; |
||
1181 | case GL_LEQUAL: |
||
1182 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LEQUAL; |
||
1183 | break; |
||
1184 | case GL_GREATER: |
||
1185 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GREATER; |
||
1186 | break; |
||
1187 | case GL_NOTEQUAL: |
||
1188 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEQUAL; |
||
1189 | break; |
||
1190 | case GL_GEQUAL: |
||
1191 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GEQUAL; |
||
1192 | break; |
||
1193 | case GL_ALWAYS: |
||
1194 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_ALWAYS; |
||
1195 | break; |
||
1196 | } |
||
1197 | |||
1198 | rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask; |
||
1199 | } |
||
1200 | |||
1201 | static void |
||
1202 | radeonStencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask ) |
||
1203 | { |
||
1204 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
1205 | |||
1206 | RADEON_STATECHANGE( rmesa, msk ); |
||
1207 | rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK; |
||
1208 | rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= |
||
1209 | ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT); |
||
1210 | } |
||
1211 | |||
1212 | static void radeonStencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum fail, |
||
1213 | GLenum zfail, GLenum zpass ) |
||
1214 | { |
||
1215 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
1216 | |||
1217 | /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP, |
||
1218 | and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC, |
||
1219 | but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */ |
||
1220 | |||
1221 | GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP; |
||
1222 | GLuint tempRADEON_STENCIL_FAIL_INC_WRAP; |
||
1223 | GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP; |
||
1224 | GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP; |
||
1225 | GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP; |
||
1226 | GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP; |
||
1227 | |||
1228 | if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) { |
||
1229 | tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC; |
||
1230 | tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC; |
||
1231 | tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC; |
||
1232 | tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC; |
||
1233 | tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC; |
||
1234 | tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC; |
||
1235 | } |
||
1236 | else { |
||
1237 | tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC_WRAP; |
||
1238 | tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC_WRAP; |
||
1239 | tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC_WRAP; |
||
1240 | tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC_WRAP; |
||
1241 | tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC_WRAP; |
||
1242 | tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC_WRAP; |
||
1243 | } |
||
1244 | |||
1245 | RADEON_STATECHANGE( rmesa, ctx ); |
||
1246 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK | |
||
1247 | RADEON_STENCIL_ZFAIL_MASK | |
||
1248 | RADEON_STENCIL_ZPASS_MASK); |
||
1249 | |||
1250 | switch ( ctx->Stencil.FailFunc[0] ) { |
||
1251 | case GL_KEEP: |
||
1252 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_KEEP; |
||
1253 | break; |
||
1254 | case GL_ZERO: |
||
1255 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_ZERO; |
||
1256 | break; |
||
1257 | case GL_REPLACE: |
||
1258 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_REPLACE; |
||
1259 | break; |
||
1260 | case GL_INCR: |
||
1261 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INC; |
||
1262 | break; |
||
1263 | case GL_DECR: |
||
1264 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_DEC; |
||
1265 | break; |
||
1266 | case GL_INCR_WRAP: |
||
1267 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_INC_WRAP; |
||
1268 | break; |
||
1269 | case GL_DECR_WRAP: |
||
1270 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_DEC_WRAP; |
||
1271 | break; |
||
1272 | case GL_INVERT: |
||
1273 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INVERT; |
||
1274 | break; |
||
1275 | } |
||
1276 | |||
1277 | switch ( ctx->Stencil.ZFailFunc[0] ) { |
||
1278 | case GL_KEEP: |
||
1279 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_KEEP; |
||
1280 | break; |
||
1281 | case GL_ZERO: |
||
1282 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_ZERO; |
||
1283 | break; |
||
1284 | case GL_REPLACE: |
||
1285 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_REPLACE; |
||
1286 | break; |
||
1287 | case GL_INCR: |
||
1288 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INC; |
||
1289 | break; |
||
1290 | case GL_DECR: |
||
1291 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_DEC; |
||
1292 | break; |
||
1293 | case GL_INCR_WRAP: |
||
1294 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP; |
||
1295 | break; |
||
1296 | case GL_DECR_WRAP: |
||
1297 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP; |
||
1298 | break; |
||
1299 | case GL_INVERT: |
||
1300 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INVERT; |
||
1301 | break; |
||
1302 | } |
||
1303 | |||
1304 | switch ( ctx->Stencil.ZPassFunc[0] ) { |
||
1305 | case GL_KEEP: |
||
1306 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_KEEP; |
||
1307 | break; |
||
1308 | case GL_ZERO: |
||
1309 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_ZERO; |
||
1310 | break; |
||
1311 | case GL_REPLACE: |
||
1312 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_REPLACE; |
||
1313 | break; |
||
1314 | case GL_INCR: |
||
1315 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INC; |
||
1316 | break; |
||
1317 | case GL_DECR: |
||
1318 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_DEC; |
||
1319 | break; |
||
1320 | case GL_INCR_WRAP: |
||
1321 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_INC_WRAP; |
||
1322 | break; |
||
1323 | case GL_DECR_WRAP: |
||
1324 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP; |
||
1325 | break; |
||
1326 | case GL_INVERT: |
||
1327 | rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INVERT; |
||
1328 | break; |
||
1329 | } |
||
1330 | } |
||
1331 | |||
1332 | |||
1333 | |||
1334 | /* ============================================================= |
||
1335 | * Window position and viewport transformation |
||
1336 | */ |
||
1337 | |||
1338 | /* |
||
1339 | * To correctly position primitives: |
||
1340 | */ |
||
1341 | #define SUBPIXEL_X 0.125 |
||
1342 | #define SUBPIXEL_Y 0.125 |
||
1343 | |||
1344 | |||
1345 | /** |
||
1346 | * Called when window size or position changes or viewport or depth range |
||
1347 | * state is changed. We update the hardware viewport state here. |
||
1348 | */ |
||
1349 | void radeonUpdateWindow( struct gl_context *ctx ) |
||
1350 | { |
||
1351 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
1352 | __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon); |
||
1353 | GLfloat xoffset = 0.0; |
||
1354 | GLfloat yoffset = dPriv ? (GLfloat) dPriv->h : 0; |
||
1355 | const GLfloat *v = ctx->Viewport._WindowMap.m; |
||
1356 | const GLboolean render_to_fbo = (ctx->DrawBuffer ? _mesa_is_user_fbo(ctx->DrawBuffer) : 0); |
||
1357 | const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; |
||
1358 | GLfloat y_scale, y_bias; |
||
1359 | |||
1360 | if (render_to_fbo) { |
||
1361 | y_scale = 1.0; |
||
1362 | y_bias = 0; |
||
1363 | } else { |
||
1364 | y_scale = -1.0; |
||
1365 | y_bias = yoffset; |
||
1366 | } |
||
1367 | |||
1368 | float_ui32_type sx = { v[MAT_SX] }; |
||
1369 | float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X }; |
||
1370 | float_ui32_type sy = { v[MAT_SY] * y_scale }; |
||
1371 | float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y }; |
||
1372 | float_ui32_type sz = { v[MAT_SZ] * depthScale }; |
||
1373 | float_ui32_type tz = { v[MAT_TZ] * depthScale }; |
||
1374 | |||
1375 | RADEON_STATECHANGE( rmesa, vpt ); |
||
1376 | |||
1377 | rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = sx.ui32; |
||
1378 | rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32; |
||
1379 | rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = sy.ui32; |
||
1380 | rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32; |
||
1381 | rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = sz.ui32; |
||
1382 | rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32; |
||
1383 | } |
||
1384 | |||
1385 | |||
1386 | static void radeonViewport( struct gl_context *ctx, GLint x, GLint y, |
||
1387 | GLsizei width, GLsizei height ) |
||
1388 | { |
||
1389 | /* Don't pipeline viewport changes, conflict with window offset |
||
1390 | * setting below. Could apply deltas to rescue pipelined viewport |
||
1391 | * values, or keep the originals hanging around. |
||
1392 | */ |
||
1393 | radeonUpdateWindow( ctx ); |
||
1394 | |||
1395 | radeon_viewport(ctx, x, y, width, height); |
||
1396 | } |
||
1397 | |||
1398 | static void radeonDepthRange( struct gl_context *ctx, GLclampd nearval, |
||
1399 | GLclampd farval ) |
||
1400 | { |
||
1401 | radeonUpdateWindow( ctx ); |
||
1402 | } |
||
1403 | |||
1404 | void radeonUpdateViewportOffset( struct gl_context *ctx ) |
||
1405 | { |
||
1406 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
1407 | __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon); |
||
1408 | GLfloat xoffset = 0.0; |
||
1409 | GLfloat yoffset = (GLfloat)dPriv->h; |
||
1410 | const GLfloat *v = ctx->Viewport._WindowMap.m; |
||
1411 | |||
1412 | float_ui32_type tx; |
||
1413 | float_ui32_type ty; |
||
1414 | |||
1415 | tx.f = v[MAT_TX] + xoffset + SUBPIXEL_X; |
||
1416 | ty.f = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y; |
||
1417 | |||
1418 | if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != tx.ui32 || |
||
1419 | rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != ty.ui32 ) |
||
1420 | { |
||
1421 | /* Note: this should also modify whatever data the context reset |
||
1422 | * code uses... |
||
1423 | */ |
||
1424 | RADEON_STATECHANGE( rmesa, vpt ); |
||
1425 | rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32; |
||
1426 | rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32; |
||
1427 | |||
1428 | /* update polygon stipple x/y screen offset */ |
||
1429 | { |
||
1430 | GLuint stx, sty; |
||
1431 | GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC]; |
||
1432 | |||
1433 | m &= ~(RADEON_STIPPLE_X_OFFSET_MASK | |
||
1434 | RADEON_STIPPLE_Y_OFFSET_MASK); |
||
1435 | |||
1436 | /* add magic offsets, then invert */ |
||
1437 | stx = 31 - ((-1) & RADEON_STIPPLE_COORD_MASK); |
||
1438 | sty = 31 - ((dPriv->h - 1) |
||
1439 | & RADEON_STIPPLE_COORD_MASK); |
||
1440 | |||
1441 | m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) | |
||
1442 | (sty << RADEON_STIPPLE_Y_OFFSET_SHIFT)); |
||
1443 | |||
1444 | if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) { |
||
1445 | RADEON_STATECHANGE( rmesa, msc ); |
||
1446 | rmesa->hw.msc.cmd[MSC_RE_MISC] = m; |
||
1447 | } |
||
1448 | } |
||
1449 | } |
||
1450 | |||
1451 | radeonUpdateScissor( ctx ); |
||
1452 | } |
||
1453 | |||
1454 | |||
1455 | |||
1456 | /* ============================================================= |
||
1457 | * Miscellaneous |
||
1458 | */ |
||
1459 | |||
1460 | static void radeonRenderMode( struct gl_context *ctx, GLenum mode ) |
||
1461 | { |
||
1462 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
1463 | FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) ); |
||
1464 | } |
||
1465 | |||
1466 | |||
1467 | static GLuint radeon_rop_tab[] = { |
||
1468 | RADEON_ROP_CLEAR, |
||
1469 | RADEON_ROP_AND, |
||
1470 | RADEON_ROP_AND_REVERSE, |
||
1471 | RADEON_ROP_COPY, |
||
1472 | RADEON_ROP_AND_INVERTED, |
||
1473 | RADEON_ROP_NOOP, |
||
1474 | RADEON_ROP_XOR, |
||
1475 | RADEON_ROP_OR, |
||
1476 | RADEON_ROP_NOR, |
||
1477 | RADEON_ROP_EQUIV, |
||
1478 | RADEON_ROP_INVERT, |
||
1479 | RADEON_ROP_OR_REVERSE, |
||
1480 | RADEON_ROP_COPY_INVERTED, |
||
1481 | RADEON_ROP_OR_INVERTED, |
||
1482 | RADEON_ROP_NAND, |
||
1483 | RADEON_ROP_SET, |
||
1484 | }; |
||
1485 | |||
1486 | static void radeonLogicOpCode( struct gl_context *ctx, GLenum opcode ) |
||
1487 | { |
||
1488 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
1489 | GLuint rop = (GLuint)opcode - GL_CLEAR; |
||
1490 | |||
1491 | ASSERT( rop < 16 ); |
||
1492 | |||
1493 | RADEON_STATECHANGE( rmesa, msk ); |
||
1494 | rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop]; |
||
1495 | } |
||
1496 | |||
1497 | /* ============================================================= |
||
1498 | * State enable/disable |
||
1499 | */ |
||
1500 | |||
1501 | static void radeonEnable( struct gl_context *ctx, GLenum cap, GLboolean state ) |
||
1502 | { |
||
1503 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
1504 | GLuint p, flag; |
||
1505 | |||
1506 | if ( RADEON_DEBUG & RADEON_STATE ) |
||
1507 | fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__, |
||
1508 | _mesa_lookup_enum_by_nr( cap ), |
||
1509 | state ? "GL_TRUE" : "GL_FALSE" ); |
||
1510 | |||
1511 | switch ( cap ) { |
||
1512 | /* Fast track this one... |
||
1513 | */ |
||
1514 | case GL_TEXTURE_1D: |
||
1515 | case GL_TEXTURE_2D: |
||
1516 | case GL_TEXTURE_3D: |
||
1517 | break; |
||
1518 | |||
1519 | case GL_ALPHA_TEST: |
||
1520 | RADEON_STATECHANGE( rmesa, ctx ); |
||
1521 | if (state) { |
||
1522 | rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE; |
||
1523 | } else { |
||
1524 | rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE; |
||
1525 | } |
||
1526 | break; |
||
1527 | |||
1528 | case GL_BLEND: |
||
1529 | RADEON_STATECHANGE( rmesa, ctx ); |
||
1530 | if (state) { |
||
1531 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ALPHA_BLEND_ENABLE; |
||
1532 | } else { |
||
1533 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE; |
||
1534 | } |
||
1535 | if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled |
||
1536 | && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) { |
||
1537 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE; |
||
1538 | } else { |
||
1539 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE; |
||
1540 | } |
||
1541 | |||
1542 | /* Catch a possible fallback: |
||
1543 | */ |
||
1544 | if (state) { |
||
1545 | ctx->Driver.BlendEquationSeparate( ctx, |
||
1546 | ctx->Color.Blend[0].EquationRGB, |
||
1547 | ctx->Color.Blend[0].EquationA ); |
||
1548 | ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.Blend[0].SrcRGB, |
||
1549 | ctx->Color.Blend[0].DstRGB, |
||
1550 | ctx->Color.Blend[0].SrcA, |
||
1551 | ctx->Color.Blend[0].DstA ); |
||
1552 | } |
||
1553 | else { |
||
1554 | FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE ); |
||
1555 | FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, GL_FALSE ); |
||
1556 | } |
||
1557 | break; |
||
1558 | |||
1559 | case GL_CLIP_PLANE0: |
||
1560 | case GL_CLIP_PLANE1: |
||
1561 | case GL_CLIP_PLANE2: |
||
1562 | case GL_CLIP_PLANE3: |
||
1563 | case GL_CLIP_PLANE4: |
||
1564 | case GL_CLIP_PLANE5: |
||
1565 | p = cap-GL_CLIP_PLANE0; |
||
1566 | RADEON_STATECHANGE( rmesa, tcl ); |
||
1567 | if (state) { |
||
1568 | rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0< |
||
1569 | radeonClipPlane( ctx, cap, NULL ); |
||
1570 | } |
||
1571 | else { |
||
1572 | rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0< |
||
1573 | } |
||
1574 | break; |
||
1575 | |||
1576 | case GL_COLOR_MATERIAL: |
||
1577 | radeonColorMaterial( ctx, 0, 0 ); |
||
1578 | radeonUpdateMaterial( ctx ); |
||
1579 | break; |
||
1580 | |||
1581 | case GL_CULL_FACE: |
||
1582 | radeonCullFace( ctx, 0 ); |
||
1583 | break; |
||
1584 | |||
1585 | case GL_DEPTH_TEST: |
||
1586 | RADEON_STATECHANGE(rmesa, ctx ); |
||
1587 | if ( state ) { |
||
1588 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_Z_ENABLE; |
||
1589 | } else { |
||
1590 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE; |
||
1591 | } |
||
1592 | break; |
||
1593 | |||
1594 | case GL_DITHER: |
||
1595 | RADEON_STATECHANGE(rmesa, ctx ); |
||
1596 | if ( state ) { |
||
1597 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE; |
||
1598 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable; |
||
1599 | } else { |
||
1600 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE; |
||
1601 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable; |
||
1602 | } |
||
1603 | break; |
||
1604 | |||
1605 | case GL_FOG: |
||
1606 | RADEON_STATECHANGE(rmesa, ctx ); |
||
1607 | if ( state ) { |
||
1608 | rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE; |
||
1609 | radeonFogfv( ctx, GL_FOG_MODE, NULL ); |
||
1610 | } else { |
||
1611 | rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE; |
||
1612 | RADEON_STATECHANGE(rmesa, tcl); |
||
1613 | rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK; |
||
1614 | } |
||
1615 | radeonUpdateSpecular( ctx ); /* for PK_SPEC */ |
||
1616 | _mesa_allow_light_in_model( ctx, !state ); |
||
1617 | break; |
||
1618 | |||
1619 | case GL_LIGHT0: |
||
1620 | case GL_LIGHT1: |
||
1621 | case GL_LIGHT2: |
||
1622 | case GL_LIGHT3: |
||
1623 | case GL_LIGHT4: |
||
1624 | case GL_LIGHT5: |
||
1625 | case GL_LIGHT6: |
||
1626 | case GL_LIGHT7: |
||
1627 | RADEON_STATECHANGE(rmesa, tcl); |
||
1628 | p = cap - GL_LIGHT0; |
||
1629 | if (p&1) |
||
1630 | flag = (RADEON_LIGHT_1_ENABLE | |
||
1631 | RADEON_LIGHT_1_ENABLE_AMBIENT | |
||
1632 | RADEON_LIGHT_1_ENABLE_SPECULAR); |
||
1633 | else |
||
1634 | flag = (RADEON_LIGHT_0_ENABLE | |
||
1635 | RADEON_LIGHT_0_ENABLE_AMBIENT | |
||
1636 | RADEON_LIGHT_0_ENABLE_SPECULAR); |
||
1637 | |||
1638 | if (state) |
||
1639 | rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag; |
||
1640 | else |
||
1641 | rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag; |
||
1642 | |||
1643 | /* |
||
1644 | */ |
||
1645 | update_light_colors( ctx, p ); |
||
1646 | break; |
||
1647 | |||
1648 | case GL_LIGHTING: |
||
1649 | RADEON_STATECHANGE(rmesa, tcl); |
||
1650 | radeonUpdateSpecular(ctx); |
||
1651 | check_twoside_fallback( ctx ); |
||
1652 | break; |
||
1653 | |||
1654 | case GL_LINE_SMOOTH: |
||
1655 | RADEON_STATECHANGE( rmesa, ctx ); |
||
1656 | if ( state ) { |
||
1657 | rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_LINE; |
||
1658 | } else { |
||
1659 | rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE; |
||
1660 | } |
||
1661 | break; |
||
1662 | |||
1663 | case GL_LINE_STIPPLE: |
||
1664 | RADEON_STATECHANGE( rmesa, ctx ); |
||
1665 | if ( state ) { |
||
1666 | rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_PATTERN_ENABLE; |
||
1667 | } else { |
||
1668 | rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE; |
||
1669 | } |
||
1670 | break; |
||
1671 | |||
1672 | case GL_COLOR_LOGIC_OP: |
||
1673 | RADEON_STATECHANGE( rmesa, ctx ); |
||
1674 | if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled |
||
1675 | && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) { |
||
1676 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE; |
||
1677 | } else { |
||
1678 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE; |
||
1679 | } |
||
1680 | break; |
||
1681 | |||
1682 | case GL_NORMALIZE: |
||
1683 | RADEON_STATECHANGE( rmesa, tcl ); |
||
1684 | if ( state ) { |
||
1685 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_NORMALIZE_NORMALS; |
||
1686 | } else { |
||
1687 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS; |
||
1688 | } |
||
1689 | break; |
||
1690 | |||
1691 | case GL_POLYGON_OFFSET_POINT: |
||
1692 | RADEON_STATECHANGE( rmesa, set ); |
||
1693 | if ( state ) { |
||
1694 | rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_POINT; |
||
1695 | } else { |
||
1696 | rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT; |
||
1697 | } |
||
1698 | break; |
||
1699 | |||
1700 | case GL_POLYGON_OFFSET_LINE: |
||
1701 | RADEON_STATECHANGE( rmesa, set ); |
||
1702 | if ( state ) { |
||
1703 | rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_LINE; |
||
1704 | } else { |
||
1705 | rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE; |
||
1706 | } |
||
1707 | break; |
||
1708 | |||
1709 | case GL_POLYGON_OFFSET_FILL: |
||
1710 | RADEON_STATECHANGE( rmesa, set ); |
||
1711 | if ( state ) { |
||
1712 | rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_TRI; |
||
1713 | } else { |
||
1714 | rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI; |
||
1715 | } |
||
1716 | break; |
||
1717 | |||
1718 | case GL_POLYGON_SMOOTH: |
||
1719 | RADEON_STATECHANGE( rmesa, ctx ); |
||
1720 | if ( state ) { |
||
1721 | rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ANTI_ALIAS_POLY; |
||
1722 | } else { |
||
1723 | rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY; |
||
1724 | } |
||
1725 | break; |
||
1726 | |||
1727 | case GL_POLYGON_STIPPLE: |
||
1728 | RADEON_STATECHANGE(rmesa, ctx ); |
||
1729 | if ( state ) { |
||
1730 | rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_STIPPLE_ENABLE; |
||
1731 | } else { |
||
1732 | rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE; |
||
1733 | } |
||
1734 | break; |
||
1735 | |||
1736 | case GL_RESCALE_NORMAL_EXT: { |
||
1737 | GLboolean tmp = ctx->_NeedEyeCoords ? state : !state; |
||
1738 | RADEON_STATECHANGE( rmesa, tcl ); |
||
1739 | if ( tmp ) { |
||
1740 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS; |
||
1741 | } else { |
||
1742 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS; |
||
1743 | } |
||
1744 | break; |
||
1745 | } |
||
1746 | |||
1747 | case GL_SCISSOR_TEST: |
||
1748 | radeon_firevertices(&rmesa->radeon); |
||
1749 | rmesa->radeon.state.scissor.enabled = state; |
||
1750 | radeonUpdateScissor( ctx ); |
||
1751 | break; |
||
1752 | |||
1753 | case GL_STENCIL_TEST: |
||
1754 | { |
||
1755 | GLboolean hw_stencil = GL_FALSE; |
||
1756 | if (ctx->DrawBuffer) { |
||
1757 | struct radeon_renderbuffer *rrbStencil |
||
1758 | = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); |
||
1759 | hw_stencil = (rrbStencil && rrbStencil->bo); |
||
1760 | } |
||
1761 | |||
1762 | if (hw_stencil) { |
||
1763 | RADEON_STATECHANGE( rmesa, ctx ); |
||
1764 | if ( state ) { |
||
1765 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_STENCIL_ENABLE; |
||
1766 | } else { |
||
1767 | rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE; |
||
1768 | } |
||
1769 | } else { |
||
1770 | FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state ); |
||
1771 | } |
||
1772 | } |
||
1773 | break; |
||
1774 | |||
1775 | case GL_TEXTURE_GEN_Q: |
||
1776 | case GL_TEXTURE_GEN_R: |
||
1777 | case GL_TEXTURE_GEN_S: |
||
1778 | case GL_TEXTURE_GEN_T: |
||
1779 | /* Picked up in radeonUpdateTextureState. |
||
1780 | */ |
||
1781 | rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE; |
||
1782 | break; |
||
1783 | |||
1784 | case GL_COLOR_SUM_EXT: |
||
1785 | radeonUpdateSpecular ( ctx ); |
||
1786 | break; |
||
1787 | |||
1788 | default: |
||
1789 | return; |
||
1790 | } |
||
1791 | } |
||
1792 | |||
1793 | |||
1794 | static void radeonLightingSpaceChange( struct gl_context *ctx ) |
||
1795 | { |
||
1796 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
1797 | GLboolean tmp; |
||
1798 | RADEON_STATECHANGE( rmesa, tcl ); |
||
1799 | |||
1800 | if (RADEON_DEBUG & RADEON_STATE) |
||
1801 | fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords, |
||
1802 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]); |
||
1803 | |||
1804 | if (ctx->_NeedEyeCoords) |
||
1805 | tmp = ctx->Transform.RescaleNormals; |
||
1806 | else |
||
1807 | tmp = !ctx->Transform.RescaleNormals; |
||
1808 | |||
1809 | if ( tmp ) { |
||
1810 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS; |
||
1811 | } else { |
||
1812 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS; |
||
1813 | } |
||
1814 | |||
1815 | if (RADEON_DEBUG & RADEON_STATE) |
||
1816 | fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords, |
||
1817 | rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]); |
||
1818 | } |
||
1819 | |||
1820 | /* ============================================================= |
||
1821 | * Deferred state management - matrices, textures, other? |
||
1822 | */ |
||
1823 | |||
1824 | |||
1825 | void radeonUploadTexMatrix( r100ContextPtr rmesa, |
||
1826 | int unit, GLboolean swapcols ) |
||
1827 | { |
||
1828 | /* Here's how this works: on r100, only 3 tex coords can be submitted, so the |
||
1829 | vector looks like this probably: (s t r|q 0) (not sure if the last coord |
||
1830 | is hardwired to 0, could be 1 too). Interestingly, it actually looks like |
||
1831 | texgen generates all 4 coords, at least tests with projtex indicated that. |
||
1832 | So: if we need the q coord in the end (solely determined by the texture |
||
1833 | target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row. |
||
1834 | Additionally, if we don't have texgen but 4 tex coords submitted, we swap |
||
1835 | column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord |
||
1836 | will get submitted in the "wrong", i.e. 3rd, slot. |
||
1837 | If an app submits 3 coords for 2d targets, we assume it is saving on vertex |
||
1838 | size and using the texture matrix to swap the r and q coords around (ut2k3 |
||
1839 | does exactly that), so we don't need the 3rd / 4th column swap - still need |
||
1840 | the 3rd / 4th row swap of course. This will potentially break for apps which |
||
1841 | use TexCoord3x just for fun. Additionally, it will never work if an app uses |
||
1842 | an "advanced" texture matrix and relies on all 4 texcoord inputs to generate |
||
1843 | the maximum needed 3. This seems impossible to do with hw tcl on r100, and |
||
1844 | incredibly hard to detect so we can't just fallback in such a case. Assume |
||
1845 | it never happens... - rs |
||
1846 | */ |
||
1847 | |||
1848 | int idx = TEXMAT_0 + unit; |
||
1849 | float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0; |
||
1850 | int i; |
||
1851 | struct gl_texture_unit tUnit = rmesa->radeon.glCtx.Texture.Unit[unit]; |
||
1852 | GLfloat *src = rmesa->tmpmat[unit].m; |
||
1853 | |||
1854 | rmesa->TexMatColSwap &= ~(1 << unit); |
||
1855 | if ((tUnit._ReallyEnabled & (TEXTURE_3D_BIT | TEXTURE_CUBE_BIT)) == 0) { |
||
1856 | if (swapcols) { |
||
1857 | rmesa->TexMatColSwap |= 1 << unit; |
||
1858 | /* attention some elems are swapped 2 times! */ |
||
1859 | *dest++ = src[0]; |
||
1860 | *dest++ = src[4]; |
||
1861 | *dest++ = src[12]; |
||
1862 | *dest++ = src[8]; |
||
1863 | *dest++ = src[1]; |
||
1864 | *dest++ = src[5]; |
||
1865 | *dest++ = src[13]; |
||
1866 | *dest++ = src[9]; |
||
1867 | *dest++ = src[2]; |
||
1868 | *dest++ = src[6]; |
||
1869 | *dest++ = src[15]; |
||
1870 | *dest++ = src[11]; |
||
1871 | /* those last 4 are probably never used */ |
||
1872 | *dest++ = src[3]; |
||
1873 | *dest++ = src[7]; |
||
1874 | *dest++ = src[14]; |
||
1875 | *dest++ = src[10]; |
||
1876 | } |
||
1877 | else { |
||
1878 | for (i = 0; i < 2; i++) { |
||
1879 | *dest++ = src[i]; |
||
1880 | *dest++ = src[i+4]; |
||
1881 | *dest++ = src[i+8]; |
||
1882 | *dest++ = src[i+12]; |
||
1883 | } |
||
1884 | for (i = 3; i >= 2; i--) { |
||
1885 | *dest++ = src[i]; |
||
1886 | *dest++ = src[i+4]; |
||
1887 | *dest++ = src[i+8]; |
||
1888 | *dest++ = src[i+12]; |
||
1889 | } |
||
1890 | } |
||
1891 | } |
||
1892 | else { |
||
1893 | for (i = 0 ; i < 4 ; i++) { |
||
1894 | *dest++ = src[i]; |
||
1895 | *dest++ = src[i+4]; |
||
1896 | *dest++ = src[i+8]; |
||
1897 | *dest++ = src[i+12]; |
||
1898 | } |
||
1899 | } |
||
1900 | |||
1901 | RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] ); |
||
1902 | } |
||
1903 | |||
1904 | |||
1905 | static void upload_matrix( r100ContextPtr rmesa, GLfloat *src, int idx ) |
||
1906 | { |
||
1907 | float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0; |
||
1908 | int i; |
||
1909 | |||
1910 | |||
1911 | for (i = 0 ; i < 4 ; i++) { |
||
1912 | *dest++ = src[i]; |
||
1913 | *dest++ = src[i+4]; |
||
1914 | *dest++ = src[i+8]; |
||
1915 | *dest++ = src[i+12]; |
||
1916 | } |
||
1917 | |||
1918 | RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] ); |
||
1919 | } |
||
1920 | |||
1921 | static void upload_matrix_t( r100ContextPtr rmesa, GLfloat *src, int idx ) |
||
1922 | { |
||
1923 | float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0; |
||
1924 | memcpy(dest, src, 16*sizeof(float)); |
||
1925 | RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] ); |
||
1926 | } |
||
1927 | |||
1928 | |||
1929 | static void update_texturematrix( struct gl_context *ctx ) |
||
1930 | { |
||
1931 | r100ContextPtr rmesa = R100_CONTEXT( ctx ); |
||
1932 | GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL]; |
||
1933 | GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]; |
||
1934 | int unit; |
||
1935 | GLuint texMatEnabled = 0; |
||
1936 | rmesa->NeedTexMatrix = 0; |
||
1937 | rmesa->TexMatColSwap = 0; |
||
1938 | |||
1939 | for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { |
||
1940 | if (ctx->Texture.Unit[unit]._ReallyEnabled) { |
||
1941 | GLboolean needMatrix = GL_FALSE; |
||
1942 | if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) { |
||
1943 | needMatrix = GL_TRUE; |
||
1944 | texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE | |
||
1945 | RADEON_TEXMAT_0_ENABLE) << unit; |
||
1946 | |||
1947 | if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) { |
||
1948 | /* Need to preconcatenate any active texgen |
||
1949 | * obj/eyeplane matrices: |
||
1950 | */ |
||
1951 | _math_matrix_mul_matrix( &rmesa->tmpmat[unit], |
||
1952 | ctx->TextureMatrixStack[unit].Top, |
||
1953 | &rmesa->TexGenMatrix[unit] ); |
||
1954 | } |
||
1955 | else { |
||
1956 | _math_matrix_copy( &rmesa->tmpmat[unit], |
||
1957 | ctx->TextureMatrixStack[unit].Top ); |
||
1958 | } |
||
1959 | } |
||
1960 | else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) { |
||
1961 | _math_matrix_copy( &rmesa->tmpmat[unit], &rmesa->TexGenMatrix[unit] ); |
||
1962 | needMatrix = GL_TRUE; |
||
1963 | } |
||
1964 | if (needMatrix) { |
||
1965 | rmesa->NeedTexMatrix |= 1 << unit; |
||
1966 | radeonUploadTexMatrix( rmesa, unit, |
||
1967 | !ctx->Texture.Unit[unit].TexGenEnabled ); |
||
1968 | } |
||
1969 | } |
||
1970 | } |
||
1971 | |||
1972 | tpc = (texMatEnabled | rmesa->TexGenEnabled); |
||
1973 | |||
1974 | /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */ |
||
1975 | vs &= ~((RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) | |
||
1976 | (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) | |
||
1977 | (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_2_OUTPUT_SHIFT)); |
||
1978 | |||
1979 | vs |= (((tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE) << |
||
1980 | (RADEON_TCL_TEX_0_OUTPUT_SHIFT + 3)) | |
||
1981 | ((tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE) << |
||
1982 | (RADEON_TCL_TEX_1_OUTPUT_SHIFT + 2)) | |
||
1983 | ((tpc & RADEON_TEXGEN_TEXMAT_2_ENABLE) << |
||
1984 | (RADEON_TCL_TEX_2_OUTPUT_SHIFT + 1))); |
||
1985 | |||
1986 | if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] || |
||
1987 | vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) { |
||
1988 | |||
1989 | RADEON_STATECHANGE(rmesa, tcl); |
||
1990 | rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc; |
||
1991 | rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs; |
||
1992 | } |
||
1993 | } |
||
1994 | |||
1995 | static GLboolean r100ValidateBuffers(struct gl_context *ctx) |
||
1996 | { |
||
1997 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
1998 | struct radeon_renderbuffer *rrb; |
||
1999 | int i, ret; |
||
2000 | |||
2001 | radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs); |
||
2002 | |||
2003 | rrb = radeon_get_colorbuffer(&rmesa->radeon); |
||
2004 | /* color buffer */ |
||
2005 | if (rrb && rrb->bo) { |
||
2006 | radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo, |
||
2007 | 0, RADEON_GEM_DOMAIN_VRAM); |
||
2008 | } |
||
2009 | |||
2010 | /* depth buffer */ |
||
2011 | rrb = radeon_get_depthbuffer(&rmesa->radeon); |
||
2012 | /* color buffer */ |
||
2013 | if (rrb && rrb->bo) { |
||
2014 | radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo, |
||
2015 | 0, RADEON_GEM_DOMAIN_VRAM); |
||
2016 | } |
||
2017 | |||
2018 | for (i = 0; i < ctx->Const.FragmentProgram.MaxTextureImageUnits; ++i) { |
||
2019 | radeonTexObj *t; |
||
2020 | |||
2021 | if (!ctx->Texture.Unit[i]._ReallyEnabled) |
||
2022 | continue; |
||
2023 | |||
2024 | t = rmesa->state.texture.unit[i].texobj; |
||
2025 | |||
2026 | if (!t) |
||
2027 | continue; |
||
2028 | if (t->image_override && t->bo) |
||
2029 | radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo, |
||
2030 | RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); |
||
2031 | else if (t->mt->bo) |
||
2032 | radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo, |
||
2033 | RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); |
||
2034 | } |
||
2035 | |||
2036 | ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0); |
||
2037 | if (ret) |
||
2038 | return GL_FALSE; |
||
2039 | return GL_TRUE; |
||
2040 | } |
||
2041 | |||
2042 | GLboolean radeonValidateState( struct gl_context *ctx ) |
||
2043 | { |
||
2044 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
2045 | GLuint new_state = rmesa->radeon.NewGLState; |
||
2046 | |||
2047 | if (new_state & _NEW_BUFFERS) { |
||
2048 | _mesa_update_framebuffer(ctx); |
||
2049 | /* this updates the DrawBuffer's Width/Height if it's a FBO */ |
||
2050 | _mesa_update_draw_buffer_bounds(ctx); |
||
2051 | RADEON_STATECHANGE(rmesa, ctx); |
||
2052 | } |
||
2053 | |||
2054 | if (new_state & _NEW_TEXTURE) { |
||
2055 | radeonUpdateTextureState( ctx ); |
||
2056 | new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */ |
||
2057 | } |
||
2058 | |||
2059 | /* we need to do a space check here */ |
||
2060 | if (!r100ValidateBuffers(ctx)) |
||
2061 | return GL_FALSE; |
||
2062 | |||
2063 | /* Need an event driven matrix update? |
||
2064 | */ |
||
2065 | if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) |
||
2066 | upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ ); |
||
2067 | |||
2068 | /* Need these for lighting (shouldn't upload otherwise) |
||
2069 | */ |
||
2070 | if (new_state & (_NEW_MODELVIEW)) { |
||
2071 | upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, MODEL ); |
||
2072 | upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, MODEL_IT ); |
||
2073 | } |
||
2074 | |||
2075 | /* Does this need to be triggered on eg. modelview for |
||
2076 | * texgen-derived objplane/eyeplane matrices? |
||
2077 | */ |
||
2078 | if (new_state & _NEW_TEXTURE_MATRIX) { |
||
2079 | update_texturematrix( ctx ); |
||
2080 | } |
||
2081 | |||
2082 | if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) { |
||
2083 | update_light( ctx ); |
||
2084 | } |
||
2085 | |||
2086 | /* emit all active clip planes if projection matrix changes. |
||
2087 | */ |
||
2088 | if (new_state & (_NEW_PROJECTION)) { |
||
2089 | if (ctx->Transform.ClipPlanesEnabled) |
||
2090 | radeonUpdateClipPlanes( ctx ); |
||
2091 | } |
||
2092 | |||
2093 | |||
2094 | rmesa->radeon.NewGLState = 0; |
||
2095 | |||
2096 | return GL_TRUE; |
||
2097 | } |
||
2098 | |||
2099 | |||
2100 | static void radeonInvalidateState( struct gl_context *ctx, GLuint new_state ) |
||
2101 | { |
||
2102 | _swrast_InvalidateState( ctx, new_state ); |
||
2103 | _swsetup_InvalidateState( ctx, new_state ); |
||
2104 | _vbo_InvalidateState( ctx, new_state ); |
||
2105 | _tnl_InvalidateState( ctx, new_state ); |
||
2106 | _ae_invalidate_state( ctx, new_state ); |
||
2107 | R100_CONTEXT(ctx)->radeon.NewGLState |= new_state; |
||
2108 | } |
||
2109 | |||
2110 | |||
2111 | /* A hack. Need a faster way to find this out. |
||
2112 | */ |
||
2113 | static GLboolean check_material( struct gl_context *ctx ) |
||
2114 | { |
||
2115 | TNLcontext *tnl = TNL_CONTEXT(ctx); |
||
2116 | GLint i; |
||
2117 | |||
2118 | for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; |
||
2119 | i < _TNL_ATTRIB_MAT_BACK_INDEXES; |
||
2120 | i++) |
||
2121 | if (tnl->vb.AttribPtr[i] && |
||
2122 | tnl->vb.AttribPtr[i]->stride) |
||
2123 | return GL_TRUE; |
||
2124 | |||
2125 | return GL_FALSE; |
||
2126 | } |
||
2127 | |||
2128 | |||
2129 | static void radeonWrapRunPipeline( struct gl_context *ctx ) |
||
2130 | { |
||
2131 | r100ContextPtr rmesa = R100_CONTEXT(ctx); |
||
2132 | GLboolean has_material; |
||
2133 | |||
2134 | if (0) |
||
2135 | fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState); |
||
2136 | |||
2137 | /* Validate state: |
||
2138 | */ |
||
2139 | if (rmesa->radeon.NewGLState) |
||
2140 | if (!radeonValidateState( ctx )) |
||
2141 | FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE); |
||
2142 | |||
2143 | has_material = (ctx->Light.Enabled && check_material( ctx )); |
||
2144 | |||
2145 | if (has_material) { |
||
2146 | TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE ); |
||
2147 | } |
||
2148 | |||
2149 | /* Run the pipeline. |
||
2150 | */ |
||
2151 | _tnl_run_pipeline( ctx ); |
||
2152 | |||
2153 | if (has_material) { |
||
2154 | TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE ); |
||
2155 | } |
||
2156 | } |
||
2157 | |||
2158 | static void radeonPolygonStipple( struct gl_context *ctx, const GLubyte *mask ) |
||
2159 | { |
||
2160 | r100ContextPtr r100 = R100_CONTEXT(ctx); |
||
2161 | GLint i; |
||
2162 | |||
2163 | radeon_firevertices(&r100->radeon); |
||
2164 | |||
2165 | RADEON_STATECHANGE(r100, stp); |
||
2166 | |||
2167 | /* Must flip pattern upside down. |
||
2168 | */ |
||
2169 | for ( i = 31 ; i >= 0; i--) { |
||
2170 | r100->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i]; |
||
2171 | } |
||
2172 | } |
||
2173 | |||
2174 | |||
2175 | /* Initialize the driver's state functions. |
||
2176 | * Many of the ctx->Driver functions might have been initialized to |
||
2177 | * software defaults in the earlier _mesa_init_driver_functions() call. |
||
2178 | */ |
||
2179 | void radeonInitStateFuncs( struct gl_context *ctx ) |
||
2180 | { |
||
2181 | ctx->Driver.UpdateState = radeonInvalidateState; |
||
2182 | ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange; |
||
2183 | |||
2184 | ctx->Driver.DrawBuffer = radeonDrawBuffer; |
||
2185 | ctx->Driver.ReadBuffer = radeonReadBuffer; |
||
2186 | ctx->Driver.CopyPixels = _mesa_meta_CopyPixels; |
||
2187 | ctx->Driver.DrawPixels = _mesa_meta_DrawPixels; |
||
2188 | ctx->Driver.ReadPixels = radeonReadPixels; |
||
2189 | |||
2190 | ctx->Driver.AlphaFunc = radeonAlphaFunc; |
||
2191 | ctx->Driver.BlendEquationSeparate = radeonBlendEquationSeparate; |
||
2192 | ctx->Driver.BlendFuncSeparate = radeonBlendFuncSeparate; |
||
2193 | ctx->Driver.ClipPlane = radeonClipPlane; |
||
2194 | ctx->Driver.ColorMask = radeonColorMask; |
||
2195 | ctx->Driver.CullFace = radeonCullFace; |
||
2196 | ctx->Driver.DepthFunc = radeonDepthFunc; |
||
2197 | ctx->Driver.DepthMask = radeonDepthMask; |
||
2198 | ctx->Driver.DepthRange = radeonDepthRange; |
||
2199 | ctx->Driver.Enable = radeonEnable; |
||
2200 | ctx->Driver.Fogfv = radeonFogfv; |
||
2201 | ctx->Driver.FrontFace = radeonFrontFace; |
||
2202 | ctx->Driver.Hint = NULL; |
||
2203 | ctx->Driver.LightModelfv = radeonLightModelfv; |
||
2204 | ctx->Driver.Lightfv = radeonLightfv; |
||
2205 | ctx->Driver.LineStipple = radeonLineStipple; |
||
2206 | ctx->Driver.LineWidth = radeonLineWidth; |
||
2207 | ctx->Driver.LogicOpcode = radeonLogicOpCode; |
||
2208 | ctx->Driver.PolygonMode = radeonPolygonMode; |
||
2209 | ctx->Driver.PolygonOffset = radeonPolygonOffset; |
||
2210 | ctx->Driver.PolygonStipple = radeonPolygonStipple; |
||
2211 | ctx->Driver.RenderMode = radeonRenderMode; |
||
2212 | ctx->Driver.Scissor = radeonScissor; |
||
2213 | ctx->Driver.ShadeModel = radeonShadeModel; |
||
2214 | ctx->Driver.StencilFuncSeparate = radeonStencilFuncSeparate; |
||
2215 | ctx->Driver.StencilMaskSeparate = radeonStencilMaskSeparate; |
||
2216 | ctx->Driver.StencilOpSeparate = radeonStencilOpSeparate; |
||
2217 | ctx->Driver.Viewport = radeonViewport; |
||
2218 | |||
2219 | TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial; |
||
2220 | TNL_CONTEXT(ctx)->Driver.RunPipeline = radeonWrapRunPipeline; |
||
2221 | }>> |