2 Copyright (C) The Weather Channel, Inc. 2002.
3 Copyright (C) 2004 Nicolai Haehnle.
6 The Weather Channel (TM) funded Tungsten Graphics to develop the
7 initial release of the Radeon 8500 driver under the XFree86 license.
8 This notice must be preserved.
10 Permission is hereby granted, free of charge, to any person obtaining
11 a copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sublicense, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial
20 portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
34 * Nicolai Haehnle <prefect_@gmx.net>
44 #include "simple_list.h"
46 #include "api_arrayelt.h"
47 #include "swrast/swrast.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "array_cache/acache.h"
52 #include "radeon_ioctl.h"
53 #include "radeon_state.h"
54 #include "r300_context.h"
55 #include "r300_ioctl.h"
56 #include "r300_state.h"
58 #include "r300_program.h"
62 * Update our tracked culling state based on Mesa's state.
64 static void r300UpdateCulling(GLcontext
* ctx
)
66 r300ContextPtr r300
= R300_CONTEXT(ctx
);
69 R300_STATECHANGE(r300
, cul
);
70 if (ctx
->Polygon
.CullFlag
) {
71 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
)
72 val
= R300_CULL_FRONT
|R300_CULL_BACK
;
73 else if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
74 val
= R300_CULL_FRONT
;
78 if (ctx
->Polygon
.FrontFace
== GL_CW
)
79 val
|= R300_FRONT_FACE_CW
;
81 val
|= R300_FRONT_FACE_CCW
;
84 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
89 * Handle glEnable()/glDisable().
91 * \note Mesa already filters redundant calls to glEnable/glDisable.
93 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
95 r300ContextPtr r300
= R300_CONTEXT(ctx
);
98 if (RADEON_DEBUG
& DEBUG_STATE
)
99 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
100 _mesa_lookup_enum_by_nr(cap
),
101 state
? "GL_TRUE" : "GL_FALSE");
105 R300_STATECHANGE(r300
, zc
);
109 newval
= R300_RB3D_Z_TEST_AND_WRITE
;
111 newval
= R300_RB3D_Z_TEST
;
115 r300
->hw
.zc
.cmd
[R300_ZC_CNTL_0
] = newval
;
119 r300UpdateCulling(ctx
);
123 radeonEnable(ctx
, cap
, state
);
130 * Change the culling mode.
132 * \note Mesa already filters redundant calls to this function.
134 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
138 r300UpdateCulling(ctx
);
143 * Change the polygon orientation.
145 * \note Mesa already filters redundant calls to this function.
147 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
151 r300UpdateCulling(ctx
);
156 * Change the depth testing function.
158 * \note Mesa already filters redundant calls to this function.
160 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
162 r300ContextPtr r300
= R300_CONTEXT(ctx
);
164 R300_STATECHANGE(r300
, zc
);
168 r300
->hw
.zc
.cmd
[R300_ZC_CNTL_1
] = R300_Z_TEST_NEVER
;
171 r300
->hw
.zc
.cmd
[R300_ZC_CNTL_1
] = R300_Z_TEST_LESS
;
174 r300
->hw
.zc
.cmd
[R300_ZC_CNTL_1
] = R300_Z_TEST_EQUAL
;
177 r300
->hw
.zc
.cmd
[R300_ZC_CNTL_1
] = R300_Z_TEST_LEQUAL
;
180 r300
->hw
.zc
.cmd
[R300_ZC_CNTL_1
] = R300_Z_TEST_GREATER
;
183 r300
->hw
.zc
.cmd
[R300_ZC_CNTL_1
] = R300_Z_TEST_NEQUAL
;
186 r300
->hw
.zc
.cmd
[R300_ZC_CNTL_1
] = R300_Z_TEST_GEQUAL
;
189 r300
->hw
.zc
.cmd
[R300_ZC_CNTL_1
] = R300_Z_TEST_ALWAYS
;
196 * Enable/Disable depth writing.
198 * \note Mesa already filters redundant calls to this function.
200 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
202 r300ContextPtr r300
= R300_CONTEXT(ctx
);
204 if (!ctx
->Depth
.Test
)
207 R300_STATECHANGE(r300
, zc
);
208 r300
->hw
.zc
.cmd
[R300_ZC_CNTL_0
] = mask
209 ? R300_RB3D_Z_TEST_AND_WRITE
: R300_RB3D_Z_TEST
;
214 * Handle glColorMask()
216 static void r300ColorMask(GLcontext
* ctx
,
217 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
219 r300ContextPtr r300
= R300_CONTEXT(ctx
);
220 int mask
= (b
<< 0) | (g
<< 1) | (r
<< 2) | (a
<< 3);
222 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
223 R300_STATECHANGE(r300
, cmk
);
224 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
228 /* =============================================================
229 * Window position and viewport transformation
233 * To correctly position primitives:
235 #define SUBPIXEL_X 0.125
236 #define SUBPIXEL_Y 0.125
238 void r300UpdateWindow(GLcontext
* ctx
)
240 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
241 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
242 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
243 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
244 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
246 GLfloat sx
= v
[MAT_SX
];
247 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
248 GLfloat sy
= -v
[MAT_SY
];
249 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
250 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
251 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
253 R300_FIREVERTICES(rmesa
);
254 R300_STATECHANGE(rmesa
, vpt
);
256 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
257 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
258 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
259 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
260 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
261 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
264 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
265 GLsizei width
, GLsizei height
)
267 /* Don't pipeline viewport changes, conflict with window offset
268 * setting below. Could apply deltas to rescue pipelined viewport
269 * values, or keep the originals hanging around.
271 R200_FIREVERTICES(R200_CONTEXT(ctx
));
272 r300UpdateWindow(ctx
);
275 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
277 r300UpdateWindow(ctx
);
282 * Called by Mesa after an internal state update.
284 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
286 r300ContextPtr r300
= R300_CONTEXT(ctx
);
288 _swrast_InvalidateState(ctx
, new_state
);
289 _swsetup_InvalidateState(ctx
, new_state
);
290 _ac_InvalidateState(ctx
, new_state
);
291 _tnl_InvalidateState(ctx
, new_state
);
292 _ae_invalidate_state(ctx
, new_state
);
294 /* Go inefficiency! */
295 r300ResetHwState(r300
);
300 * Completely recalculates hardware state based on the Mesa state.
302 void r300ResetHwState(r300ContextPtr r300
)
304 GLcontext
* ctx
= r300
->radeon
.glCtx
;
307 if (RADEON_DEBUG
& DEBUG_STATE
)
308 fprintf(stderr
, "%s\n", __FUNCTION__
);
310 r300UpdateWindow(ctx
);
313 ctx
->Color
.ColorMask
[RCOMP
],
314 ctx
->Color
.ColorMask
[GCOMP
],
315 ctx
->Color
.ColorMask
[BCOMP
],
316 ctx
->Color
.ColorMask
[ACOMP
]);
318 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
319 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
320 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
322 r300UpdateCulling(ctx
);
325 r300
->hw
.unk2080
.cmd
[1] = 0x0030045A;
327 r300
->hw
.ovf
.cmd
[R300_OVF_FMT_0
] = 0x00000003;
328 r300
->hw
.ovf
.cmd
[R300_OVF_FMT_1
] = 0x00000000;
330 r300
->hw
.unk20B0
.cmd
[1] = 0x0000040A;
331 r300
->hw
.unk20B0
.cmd
[2] = 0x00000008;
333 r300
->hw
.unk2134
.cmd
[1] = 0x00FFFFFF;
334 r300
->hw
.unk2134
.cmd
[2] = 0x00000000;
336 r300
->hw
.unk2140
.cmd
[1] = 0x00000000;
338 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[0].cmd
)->unchecked_state
.count
= 1;
339 r300
->hw
.vir
[0].cmd
[1] = 0x21030003;
341 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[1].cmd
)->unchecked_state
.count
= 1;
342 r300
->hw
.vir
[1].cmd
[1] = 0xF688F688;
344 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_0
] = 0x00000001;
345 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_1
] = 0x00000405;
347 r300
->hw
.unk21DC
.cmd
[1] = 0xAAAAAAAA;
349 r300
->hw
.unk221C
.cmd
[1] = R300_221C_NORMAL
;
351 r300
->hw
.unk2220
.cmd
[1] = r300PackFloat32(1.0);
352 r300
->hw
.unk2220
.cmd
[2] = r300PackFloat32(1.0);
353 r300
->hw
.unk2220
.cmd
[3] = r300PackFloat32(1.0);
354 r300
->hw
.unk2220
.cmd
[4] = r300PackFloat32(1.0);
356 if (GET_CHIP(r300
->radeon
.radeonScreen
) == RADEON_CHIP_R300
)
357 r300
->hw
.unk2288
.cmd
[1] = R300_2288_R300
;
359 r300
->hw
.unk2288
.cmd
[1] = R300_2288_RV350
;
361 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] = 0;
362 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] = 0;
363 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] = 0;
365 r300
->hw
.unk4008
.cmd
[1] = 0x00000007;
367 r300
->hw
.unk4010
.cmd
[1] = 0x66666666;
368 r300
->hw
.unk4010
.cmd
[2] = 0x06666666;
369 if (GET_CHIP(r300
->radeon
.radeonScreen
) == RADEON_CHIP_R300
)
370 r300
->hw
.unk4010
.cmd
[3] = 0x00000017;
372 r300
->hw
.unk4010
.cmd
[3] = 0x00000011;
373 r300
->hw
.unk4010
.cmd
[4] = 0x00000000;
374 r300
->hw
.unk4010
.cmd
[5] = 0x00000000;
376 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] = 0;
378 r300
->hw
.unk4200
.cmd
[1] = r300PackFloat32(0.0);
379 r300
->hw
.unk4200
.cmd
[2] = r300PackFloat32(0.0);
380 r300
->hw
.unk4200
.cmd
[3] = r300PackFloat32(1.0);
381 r300
->hw
.unk4200
.cmd
[4] = r300PackFloat32(1.0);
383 r300
->hw
.unk4214
.cmd
[1] = 0x00050005;
385 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] = (6 << R300_POINTSIZE_X_SHIFT
) |
386 (6 << R300_POINTSIZE_Y_SHIFT
);
388 r300
->hw
.unk4230
.cmd
[1] = 0x01800000;
389 r300
->hw
.unk4230
.cmd
[2] = 0x00020006;
390 r300
->hw
.unk4230
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
392 r300
->hw
.unk4260
.cmd
[1] = 0;
393 r300
->hw
.unk4260
.cmd
[2] = r300PackFloat32(0.0);
394 r300
->hw
.unk4260
.cmd
[3] = r300PackFloat32(1.0);
396 r300
->hw
.unk4274
.cmd
[1] = 0x00000002;
397 r300
->hw
.unk4274
.cmd
[2] = 0x0003AAAA;
398 r300
->hw
.unk4274
.cmd
[3] = 0x00000000;
399 r300
->hw
.unk4274
.cmd
[4] = 0x00000000;
401 r300
->hw
.unk4288
.cmd
[1] = 0x00000000;
402 r300
->hw
.unk4288
.cmd
[2] = 0x00000001;
403 r300
->hw
.unk4288
.cmd
[3] = 0x00000000;
404 r300
->hw
.unk4288
.cmd
[4] = 0x00000000;
405 r300
->hw
.unk4288
.cmd
[5] = 0x00000000;
407 r300
->hw
.unk42A0
.cmd
[1] = 0x00000000;
409 r300
->hw
.unk42B4
.cmd
[1] = 0x00000000;
411 r300
->hw
.unk42C0
.cmd
[1] = 0x4B7FFFFF;
412 r300
->hw
.unk42C0
.cmd
[2] = 0x00000000;
414 r300
->hw
.rc
.cmd
[1] = R300_RS_CNTL_0_UNKNOWN_7
;
415 r300
->hw
.rc
.cmd
[2] = 0;
417 for(i
= 1; i
<= 8; ++i
)
418 r300
->hw
.ri
.cmd
[i
] = 0;
420 ((drm_r300_cmd_header_t
*)r300
->hw
.rr
.cmd
)->unchecked_state
.count
= 1;
421 for(i
= 1; i
<= 8; ++i
)
422 r300
->hw
.rr
.cmd
[1] = 0;
424 r300
->hw
.unk43A4
.cmd
[1] = 0x0000001C;
425 r300
->hw
.unk43A4
.cmd
[2] = 0x2DA49525;
427 r300
->hw
.unk43E8
.cmd
[1] = 0x00FFFFFF;
429 r300
->hw
.fp
.cmd
[R300_FP_CNTL0
] = 0;
430 r300
->hw
.fp
.cmd
[R300_FP_CNTL1
] = 0;
431 r300
->hw
.fp
.cmd
[R300_FP_CNTL2
] = 0;
432 r300
->hw
.fp
.cmd
[R300_FP_NODE0
] = 0;
433 r300
->hw
.fp
.cmd
[R300_FP_NODE1
] = 0;
434 r300
->hw
.fp
.cmd
[R300_FP_NODE2
] = 0;
435 r300
->hw
.fp
.cmd
[R300_FP_NODE3
] = 0;
437 r300
->hw
.unk46A4
.cmd
[1] = 0x00001B01;
438 r300
->hw
.unk46A4
.cmd
[2] = 0x00001B0F;
439 r300
->hw
.unk46A4
.cmd
[3] = 0x00001B0F;
440 r300
->hw
.unk46A4
.cmd
[4] = 0x00001B0F;
441 r300
->hw
.unk46A4
.cmd
[5] = 0x00000001;
443 for(i
= 1; i
<= 64; ++i
) {
444 /* create NOP instructions */
445 r300
->hw
.fpi
[0].cmd
[i
] = FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
));
446 r300
->hw
.fpi
[1].cmd
[i
] = FP_SELC(0,XYZ
,NO
,FP_TMP(0),0,0);
447 r300
->hw
.fpi
[2].cmd
[i
] = FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
));
448 r300
->hw
.fpi
[3].cmd
[i
] = FP_SELA(0,W
,NO
,FP_TMP(0),0,0);
451 r300
->hw
.unk4BC0
.cmd
[1] = 0;
453 r300
->hw
.unk4BC8
.cmd
[1] = 0;
454 r300
->hw
.unk4BC8
.cmd
[2] = 0;
455 r300
->hw
.unk4BC8
.cmd
[3] = 0;
457 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = 0;
459 r300
->hw
.unk4BD8
.cmd
[1] = 0;
461 r300
->hw
.unk4E00
.cmd
[1] = 0;
463 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = 0;
464 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = 0;
466 r300
->hw
.unk4E10
.cmd
[1] = 0;
467 r300
->hw
.unk4E10
.cmd
[2] = 0;
468 r300
->hw
.unk4E10
.cmd
[3] = 0;
470 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] =
471 r300
->radeon
.radeonScreen
->backOffset
+
472 r300
->radeon
.radeonScreen
->fbLocation
;
473 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.radeonScreen
->backPitch
474 | R300_COLOR_UNKNOWN_22_23
;
476 r300
->hw
.unk4E50
.cmd
[1] = 0;
477 r300
->hw
.unk4E50
.cmd
[2] = 0;
478 r300
->hw
.unk4E50
.cmd
[3] = 0;
479 r300
->hw
.unk4E50
.cmd
[4] = 0;
480 r300
->hw
.unk4E50
.cmd
[5] = 0;
481 r300
->hw
.unk4E50
.cmd
[6] = 0;
482 r300
->hw
.unk4E50
.cmd
[7] = 0;
483 r300
->hw
.unk4E50
.cmd
[8] = 0;
484 r300
->hw
.unk4E50
.cmd
[9] = 0;
486 r300
->hw
.unk4E88
.cmd
[1] = 0;
488 r300
->hw
.unk4F08
.cmd
[1] = 0x00FFFF00;
490 r300
->hw
.unk4F10
.cmd
[1] = 0x00000002; // depthbuffer format?
491 r300
->hw
.unk4F10
.cmd
[2] = 0x00000000;
492 r300
->hw
.unk4F10
.cmd
[3] = 0x00000003;
493 r300
->hw
.unk4F10
.cmd
[4] = 0x00000000;
495 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
496 r300
->radeon
.radeonScreen
->depthOffset
+
497 r300
->radeon
.radeonScreen
->fbLocation
;
498 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
500 r300
->hw
.unk4F28
.cmd
[1] = 0;
502 r300
->hw
.unk4F30
.cmd
[1] = 0;
503 r300
->hw
.unk4F30
.cmd
[2] = 0;
505 r300
->hw
.unk4F44
.cmd
[1] = 0;
507 r300
->hw
.unk4F54
.cmd
[1] = 0;
509 ((drm_r300_cmd_header_t
*)r300
->hw
.vpi
.cmd
)->vpu
.count
= 0;
510 for(i
= 1; i
< R300_VPI_CMDSIZE
; i
+= 4) {
512 r300
->hw
.vpi
.cmd
[i
+0] = VP_OUT(ADD
,TMP
,0,XYZW
);
513 r300
->hw
.vpi
.cmd
[i
+1] = VP_IN(TMP
,0);
514 r300
->hw
.vpi
.cmd
[i
+2] = VP_ZERO();
515 r300
->hw
.vpi
.cmd
[i
+3] = VP_ZERO();
518 ((drm_r300_cmd_header_t
*)r300
->hw
.vpp
.cmd
)->vpu
.count
= 0;
519 for(i
= 1; i
< R300_VPP_CMDSIZE
; ++i
)
520 r300
->hw
.vpp
.cmd
[i
] = 0;
522 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
523 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
524 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
525 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
528 r300
->hw
.all_dirty
= GL_TRUE
;
534 * Calculate initial hardware state and register state functions.
535 * Assumes that the command buffer and state atoms have been
536 * initialized already.
538 void r300InitState(r300ContextPtr r300
)
540 radeonInitState(&r300
->radeon
);
542 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
544 r300ResetHwState(r300
);
550 * Initialize driver's state callback functions
552 void r300InitStateFuncs(struct dd_function_table
* functions
)
554 radeonInitStateFuncs(functions
);
556 functions
->UpdateState
= r300InvalidateState
;
557 functions
->Enable
= r300Enable
;
558 functions
->ColorMask
= r300ColorMask
;
559 functions
->DepthFunc
= r300DepthFunc
;
560 functions
->DepthMask
= r300DepthMask
;
561 functions
->CullFace
= r300CullFace
;
562 functions
->FrontFace
= r300FrontFace
;
564 /* Viewport related */
565 functions
->Viewport
= r300Viewport
;
566 functions
->DepthRange
= r300DepthRange
;