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"
51 #include "texformat.h"
53 #include "radeon_ioctl.h"
54 #include "radeon_state.h"
55 #include "r300_context.h"
56 #include "r300_ioctl.h"
57 #include "r300_state.h"
59 #include "r300_program.h"
60 #include "r300_emit.h"
61 #include "r300_fragprog.h"
63 #include "r300_maos.h"
65 #include "drirenderbuffer.h"
67 static void r300BlendColor(GLcontext
* ctx
, const GLfloat cf
[4])
70 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
72 R300_STATECHANGE(rmesa
, unk4E10
);
74 CLAMPED_FLOAT_TO_UBYTE(color
[0], cf
[0]);
75 CLAMPED_FLOAT_TO_UBYTE(color
[1], cf
[1]);
76 CLAMPED_FLOAT_TO_UBYTE(color
[2], cf
[2]);
77 CLAMPED_FLOAT_TO_UBYTE(color
[3], cf
[3]);
79 rmesa
->hw
.unk4E10
.cmd
[1] = r300PackColor(4, color
[3], color
[0],
84 * Calculate the hardware blend factor setting. This same function is used
85 * for source and destination of both alpha and RGB.
88 * The hardware register value for the specified blend factor. This value
89 * will need to be shifted into the correct position for either source or
93 * Since the two cases where source and destination are handled differently
94 * are essentially error cases, they should never happen. Determine if these
95 * cases can be removed.
97 static int blend_factor(GLenum factor
, GLboolean is_src
)
103 func
= R300_BLEND_GL_ZERO
;
106 func
= R300_BLEND_GL_ONE
;
109 func
= R300_BLEND_GL_DST_COLOR
;
111 case GL_ONE_MINUS_DST_COLOR
:
112 func
= R300_BLEND_GL_ONE_MINUS_DST_COLOR
;
115 func
= R300_BLEND_GL_SRC_COLOR
;
117 case GL_ONE_MINUS_SRC_COLOR
:
118 func
= R300_BLEND_GL_ONE_MINUS_SRC_COLOR
;
121 func
= R300_BLEND_GL_SRC_ALPHA
;
123 case GL_ONE_MINUS_SRC_ALPHA
:
124 func
= R300_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
127 func
= R300_BLEND_GL_DST_ALPHA
;
129 case GL_ONE_MINUS_DST_ALPHA
:
130 func
= R300_BLEND_GL_ONE_MINUS_DST_ALPHA
;
132 case GL_SRC_ALPHA_SATURATE
:
133 func
= (is_src
) ? R300_BLEND_GL_SRC_ALPHA_SATURATE
:
136 case GL_CONSTANT_COLOR
:
137 func
= R300_BLEND_GL_CONST_COLOR
;
139 case GL_ONE_MINUS_CONSTANT_COLOR
:
140 func
= R300_BLEND_GL_ONE_MINUS_CONST_COLOR
;
142 case GL_CONSTANT_ALPHA
:
143 func
= R300_BLEND_GL_CONST_ALPHA
;
145 case GL_ONE_MINUS_CONSTANT_ALPHA
:
146 func
= R300_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
149 fprintf(stderr
, "unknown blend factor %x\n", factor
);
150 func
= (is_src
) ? R300_BLEND_GL_ONE
: R300_BLEND_GL_ZERO
;
156 * Sets both the blend equation and the blend function.
157 * This is done in a single
158 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
159 * change the interpretation of the blend function.
160 * Also, make sure that blend function and blend equation are set to their
161 * default value if color blending is not enabled, since at least blend
162 * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results
163 * otherwise for unknown reasons.
166 /* helper function */
167 static void r300_set_blend_cntl(r300ContextPtr r300
, int func
, int eqn
, int cbits
, int funcA
, int eqnA
)
169 GLuint new_ablend
, new_cblend
;
172 fprintf(stderr
, "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n", eqnA
, funcA
, eqn
, func
, cbits
);
174 new_ablend
= eqnA
| funcA
;
175 new_cblend
= eqn
| func
;
177 /* Some blend factor combinations don't seem to work when the
178 * BLEND_NO_SEPARATE bit is set.
180 * Especially problematic candidates are the ONE_MINUS_* flags,
181 * but I can't see a real pattern.
184 if (new_ablend
== new_cblend
) {
185 new_cblend
|= R300_BLEND_NO_SEPARATE
;
190 if((new_ablend
!= r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]) ||
191 (new_cblend
!= r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
])) {
192 R300_STATECHANGE(r300
, bld
);
193 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]=new_ablend
;
194 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
]=new_cblend
;
199 static void r300_set_blend_state(GLcontext
* ctx
)
201 r300ContextPtr r300
= R300_CONTEXT(ctx
);
202 int func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
203 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
204 int eqn
= R300_COMB_FCN_ADD_CLAMP
;
205 int funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
206 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
207 int eqnA
= R300_COMB_FCN_ADD_CLAMP
;
209 if (RGBA_LOGICOP_ENABLED(ctx
) || !ctx
->Color
.BlendEnabled
) {
210 r300_set_blend_cntl(r300
,
216 func
= (blend_factor(ctx
->Color
.BlendSrcRGB
, GL_TRUE
) << R300_SRC_BLEND_SHIFT
) |
217 (blend_factor(ctx
->Color
.BlendDstRGB
, GL_FALSE
) << R300_DST_BLEND_SHIFT
);
219 switch (ctx
->Color
.BlendEquationRGB
) {
221 eqn
= R300_COMB_FCN_ADD_CLAMP
;
224 case GL_FUNC_SUBTRACT
:
225 eqn
= R300_COMB_FCN_SUB_CLAMP
;
228 case GL_FUNC_REVERSE_SUBTRACT
:
229 eqn
= R300_COMB_FCN_RSUB_CLAMP
;
233 eqn
= R300_COMB_FCN_MIN
;
234 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
235 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
239 eqn
= R300_COMB_FCN_MAX
;
240 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
241 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
246 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
247 __func__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
252 funcA
= (blend_factor(ctx
->Color
.BlendSrcA
, GL_TRUE
) << R300_SRC_BLEND_SHIFT
) |
253 (blend_factor(ctx
->Color
.BlendDstA
, GL_FALSE
) << R300_DST_BLEND_SHIFT
);
255 switch (ctx
->Color
.BlendEquationA
) {
257 eqnA
= R300_COMB_FCN_ADD_CLAMP
;
260 case GL_FUNC_SUBTRACT
:
261 eqnA
= R300_COMB_FCN_SUB_CLAMP
;
264 case GL_FUNC_REVERSE_SUBTRACT
:
265 eqnA
= R300_COMB_FCN_RSUB_CLAMP
;
269 eqnA
= R300_COMB_FCN_MIN
;
270 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
271 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
275 eqnA
= R300_COMB_FCN_MAX
;
276 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
277 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
281 fprintf(stderr
, "[%s:%u] Invalid A blend equation (0x%04x).\n",
282 __func__
, __LINE__
, ctx
->Color
.BlendEquationA
);
286 r300_set_blend_cntl(r300
,
287 func
, eqn
, R300_BLEND_UNKNOWN
| R300_BLEND_ENABLE
,
291 static void r300BlendEquationSeparate(GLcontext
* ctx
,
292 GLenum modeRGB
, GLenum modeA
)
294 r300_set_blend_state(ctx
);
297 static void r300BlendFuncSeparate(GLcontext
* ctx
,
298 GLenum sfactorRGB
, GLenum dfactorRGB
,
299 GLenum sfactorA
, GLenum dfactorA
)
301 r300_set_blend_state(ctx
);
305 * Update our tracked culling state based on Mesa's state.
307 static void r300UpdateCulling(GLcontext
* ctx
)
309 r300ContextPtr r300
= R300_CONTEXT(ctx
);
312 R300_STATECHANGE(r300
, cul
);
313 if (ctx
->Polygon
.CullFlag
) {
314 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
)
315 val
= R300_CULL_FRONT
|R300_CULL_BACK
;
316 else if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
317 val
= R300_CULL_FRONT
;
319 val
= R300_CULL_BACK
;
321 if (ctx
->Polygon
.FrontFace
== GL_CW
)
322 val
|= R300_FRONT_FACE_CW
;
324 val
|= R300_FRONT_FACE_CCW
;
326 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
329 static void update_early_z(GLcontext
*ctx
)
331 /* updates register R300_RB3D_EARLY_Z (0x4F14)
332 if depth test is not enabled it should be R300_EARLY_Z_DISABLE
333 if depth is enabled and alpha not it should be R300_EARLY_Z_ENABLE
334 if depth and alpha is enabled it should be R300_EARLY_Z_DISABLE
336 r300ContextPtr r300
= R300_CONTEXT(ctx
);
338 R300_STATECHANGE(r300
, unk4F10
);
339 if (ctx
->Color
.AlphaEnabled
&& ctx
->Color
.AlphaFunc
!= GL_ALWAYS
)
340 /* disable early Z */
341 r300
->hw
.unk4F10
.cmd
[2] = R300_EARLY_Z_DISABLE
;
343 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
)
345 r300
->hw
.unk4F10
.cmd
[2] = R300_EARLY_Z_ENABLE
;
347 /* disable early Z */
348 r300
->hw
.unk4F10
.cmd
[2] = R300_EARLY_Z_DISABLE
;
352 static void update_alpha(GLcontext
*ctx
)
354 r300ContextPtr r300
= R300_CONTEXT(ctx
);
356 uint32_t pp_misc
= 0x0;
357 GLboolean really_enabled
= ctx
->Color
.AlphaEnabled
;
359 CLAMPED_FLOAT_TO_UBYTE(refByte
, ctx
->Color
.AlphaRef
);
361 switch (ctx
->Color
.AlphaFunc
) {
363 pp_misc
|= R300_ALPHA_TEST_FAIL
;
366 pp_misc
|= R300_ALPHA_TEST_LESS
;
369 pp_misc
|= R300_ALPHA_TEST_EQUAL
;
372 pp_misc
|= R300_ALPHA_TEST_LEQUAL
;
375 pp_misc
|= R300_ALPHA_TEST_GREATER
;
378 pp_misc
|= R300_ALPHA_TEST_NEQUAL
;
381 pp_misc
|= R300_ALPHA_TEST_GEQUAL
;
384 /*pp_misc |= R300_ALPHA_TEST_PASS;*/
385 really_enabled
= GL_FALSE
;
389 if (really_enabled
) {
390 pp_misc
|= R300_ALPHA_TEST_ENABLE
;
391 pp_misc
|= (refByte
& R300_REF_ALPHA_MASK
);
397 R300_STATECHANGE(r300
, at
);
398 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
402 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
409 static int translate_func(int func
)
413 return R300_ZS_NEVER
;
417 return R300_ZS_EQUAL
;
419 return R300_ZS_LEQUAL
;
421 return R300_ZS_GREATER
;
423 return R300_ZS_NOTEQUAL
;
425 return R300_ZS_GEQUAL
;
427 return R300_ZS_ALWAYS
;
432 static void update_depth(GLcontext
* ctx
)
434 r300ContextPtr r300
= R300_CONTEXT(ctx
);
436 R300_STATECHANGE(r300
, zs
);
437 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_RB3D_STENCIL_ENABLE
;
438 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
440 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
) {
442 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_TEST_AND_WRITE
;
444 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_TEST
;
446 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= translate_func(ctx
->Depth
.Func
) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
448 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_DISABLED_1
;
449 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= translate_func(GL_NEVER
) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
456 * Handle glEnable()/glDisable().
458 * \note Mesa already filters redundant calls to glEnable/glDisable.
460 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
462 r300ContextPtr r300
= R300_CONTEXT(ctx
);
464 if (RADEON_DEBUG
& DEBUG_STATE
)
465 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
466 _mesa_lookup_enum_by_nr(cap
),
467 state
? "GL_TRUE" : "GL_FALSE");
470 /* Fast track this one...
478 R300_STATECHANGE(r300
, fogs
);
480 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] |=
483 ctx
->Driver
.Fogfv( ctx
, GL_FOG_MODE
, NULL
);
484 ctx
->Driver
.Fogfv( ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
485 ctx
->Driver
.Fogfv( ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
486 ctx
->Driver
.Fogfv( ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
487 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
489 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] &=
500 case GL_COLOR_LOGIC_OP
:
501 r300_set_blend_state(ctx
);
508 case GL_STENCIL_TEST
:
509 if (r300
->state
.stencil
.hw_stencil
) {
510 R300_STATECHANGE(r300
, zs
);
512 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
513 R300_RB3D_STENCIL_ENABLE
;
515 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
516 ~R300_RB3D_STENCIL_ENABLE
;
520 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
526 r300UpdateCulling(ctx
);
529 case GL_POLYGON_OFFSET_POINT
:
530 case GL_POLYGON_OFFSET_LINE
:
533 case GL_POLYGON_OFFSET_FILL
:
534 R300_STATECHANGE(r300
, unk42B4
);
536 r300
->hw
.unk42B4
.cmd
[1] |= (3<<0);
538 r300
->hw
.unk42B4
.cmd
[1] &= ~(3<<0);
542 radeonEnable(ctx
, cap
, state
);
548 static void r300UpdatePolygonMode(GLcontext
*ctx
)
550 r300ContextPtr r300
= R300_CONTEXT(ctx
);
553 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
554 ctx
->Polygon
.BackMode
!= GL_FILL
) {
557 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
558 f
= ctx
->Polygon
.FrontMode
;
559 b
= ctx
->Polygon
.BackMode
;
561 f
= ctx
->Polygon
.BackMode
;
562 b
= ctx
->Polygon
.FrontMode
;
565 hw_mode
|= R300_PM_ENABLED
;
569 hw_mode
|= R300_PM_FRONT_LINE
;
571 case GL_POINT
: /* noop */
572 hw_mode
|= R300_PM_FRONT_POINT
;
575 hw_mode
|= R300_PM_FRONT_FILL
;
581 hw_mode
|= R300_PM_BACK_LINE
;
583 case GL_POINT
: /* noop */
584 hw_mode
|= R300_PM_BACK_POINT
;
587 hw_mode
|= R300_PM_BACK_FILL
;
592 if (r300
->hw
.unk4288
.cmd
[1] != hw_mode
) {
593 R300_STATECHANGE(r300
, unk4288
);
594 r300
->hw
.unk4288
.cmd
[1] = hw_mode
;
599 * Change the culling mode.
601 * \note Mesa already filters redundant calls to this function.
603 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
607 r300UpdateCulling(ctx
);
612 * Change the polygon orientation.
614 * \note Mesa already filters redundant calls to this function.
616 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
620 r300UpdateCulling(ctx
);
621 r300UpdatePolygonMode(ctx
);
626 * Change the depth testing function.
628 * \note Mesa already filters redundant calls to this function.
630 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
638 * Enable/Disable depth writing.
640 * \note Mesa already filters redundant calls to this function.
642 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
650 * Handle glColorMask()
652 static void r300ColorMask(GLcontext
* ctx
,
653 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
655 r300ContextPtr r300
= R300_CONTEXT(ctx
);
656 int mask
= (r
? R300_COLORMASK0_R
: 0) |
657 (g
? R300_COLORMASK0_G
: 0) |
658 (b
? R300_COLORMASK0_B
: 0) |
659 (a
? R300_COLORMASK0_A
: 0);
661 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
662 R300_STATECHANGE(r300
, cmk
);
663 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
667 /* =============================================================
670 static void r300Fogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
672 r300ContextPtr r300
= R300_CONTEXT(ctx
);
673 union { int i
; float f
; } fogScale
, fogStart
;
677 fogScale
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
];
678 fogStart
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_START
];
682 if (!ctx
->Fog
.Enabled
)
684 switch (ctx
->Fog
.Mode
) {
686 R300_STATECHANGE(r300
, fogs
);
687 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
688 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_LINEAR
;
690 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
695 fogScale
.f
= 1.0 / (ctx
->Fog
.End
-ctx
->Fog
.Start
);
696 fogStart
.f
= -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-ctx
->Fog
.Start
);
700 R300_STATECHANGE(r300
, fogs
);
701 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
702 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_EXP
;
703 fogScale
.f
= 0.0933*ctx
->Fog
.Density
;
707 R300_STATECHANGE(r300
, fogs
);
708 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
709 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_EXP2
;
710 fogScale
.f
= 0.3*ctx
->Fog
.Density
;
717 switch (ctx
->Fog
.Mode
) {
719 fogScale
.f
= 0.0933*ctx
->Fog
.Density
;
723 fogScale
.f
= 0.3*ctx
->Fog
.Density
;
731 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
732 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
737 fogScale
.f
= 1.0 / (ctx
->Fog
.End
-ctx
->Fog
.Start
);
738 fogStart
.f
= -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-ctx
->Fog
.Start
);
743 R300_STATECHANGE(r300
, fogc
);
744 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] = (GLuint
) (ctx
->Fog
.Color
[0]*1023.0F
) & 0x3FF;
745 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] = (GLuint
) (ctx
->Fog
.Color
[1]*1023.0F
) & 0x3FF;
746 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] = (GLuint
) (ctx
->Fog
.Color
[2]*1023.0F
) & 0x3FF;
748 case GL_FOG_COORD_SRC
:
754 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
755 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
756 R300_STATECHANGE(r300
, fogp
);
757 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
758 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
762 /* =============================================================
765 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
767 r300ContextPtr r300
= R300_CONTEXT(ctx
);
769 size
= ctx
->Point
._Size
;
771 R300_STATECHANGE(r300
, ps
);
772 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
773 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
774 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
777 /* =============================================================
780 static void r300LineWidth(GLcontext
*ctx
, GLfloat widthf
)
782 r300ContextPtr r300
= R300_CONTEXT(ctx
);
784 widthf
= ctx
->Line
._Width
;
786 R300_STATECHANGE(r300
, lcntl
);
787 r300
->hw
.lcntl
.cmd
[1] = (int)(widthf
* 6.0);
788 r300
->hw
.lcntl
.cmd
[1] |= R300_LINE_CNT_VE
;
791 static void r300PolygonMode(GLcontext
*ctx
, GLenum face
, GLenum mode
)
796 r300UpdatePolygonMode(ctx
);
799 /* =============================================================
803 static int translate_stencil_op(int op
)
811 return R300_ZS_REPLACE
;
816 case GL_INCR_WRAP_EXT
:
817 return R300_ZS_INCR_WRAP
;
818 case GL_DECR_WRAP_EXT
:
819 return R300_ZS_DECR_WRAP
;
821 return R300_ZS_INVERT
;
823 WARN_ONCE("Do not know how to translate stencil op");
829 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
831 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
833 R300_STATECHANGE(rmesa
, unk4274
);
836 rmesa
->hw
.unk4274
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
839 rmesa
->hw
.unk4274
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
846 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
847 GLenum func
, GLint ref
, GLuint mask
)
849 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
850 GLuint refmask
= (((ctx
->Stencil
.Ref
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
851 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
855 R300_STATECHANGE(rmesa
, zs
);
857 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(
858 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
)
859 | (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
861 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &= ~((R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
862 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
864 flag
= translate_func(ctx
->Stencil
.Function
[0]);
865 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= (flag
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
);
867 if (ctx
->Stencil
._TestTwoSide
)
868 flag
= translate_func(ctx
->Stencil
.Function
[1]);
870 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= (flag
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
871 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
874 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
876 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
878 R300_STATECHANGE(rmesa
, zs
);
879 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &= ~(R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
);
880 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= (ctx
->Stencil
.WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
;
884 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
, GLenum fail
,
885 GLenum zfail
, GLenum zpass
)
887 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
889 R300_STATECHANGE(rmesa
, zs
);
890 /* It is easier to mask what's left.. */
891 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
892 (R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
) |
893 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
894 (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
896 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
897 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
)
898 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
)
899 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
);
901 if (ctx
->Stencil
._TestTwoSide
) {
902 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
903 (translate_stencil_op(ctx
->Stencil
.FailFunc
[1]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
904 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[1]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
905 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[1]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
907 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
908 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
909 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
910 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
914 static void r300ClearStencil(GLcontext
* ctx
, GLint s
)
916 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
918 rmesa
->state
.stencil
.clear
=
919 ((GLuint
) (ctx
->Stencil
.Clear
& 0xff) |
920 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
) |
921 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
));
924 /* =============================================================
925 * Window position and viewport transformation
929 * To correctly position primitives:
931 #define SUBPIXEL_X 0.125
932 #define SUBPIXEL_Y 0.125
934 void r300UpdateWindow(GLcontext
* ctx
)
936 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
937 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
938 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
939 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
940 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
942 GLfloat sx
= v
[MAT_SX
];
943 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
944 GLfloat sy
= -v
[MAT_SY
];
945 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
946 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
947 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
949 R300_FIREVERTICES(rmesa
);
950 R300_STATECHANGE(rmesa
, vpt
);
952 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
953 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
954 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
955 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
956 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
957 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
960 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
961 GLsizei width
, GLsizei height
)
963 /* Don't pipeline viewport changes, conflict with window offset
964 * setting below. Could apply deltas to rescue pipelined viewport
965 * values, or keep the originals hanging around.
967 r300UpdateWindow(ctx
);
970 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
972 r300UpdateWindow(ctx
);
975 void r300UpdateViewportOffset( GLcontext
*ctx
)
977 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
978 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
)rmesa
)->dri
.drawable
;
979 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
980 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
981 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
983 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
984 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
986 if ( rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
987 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
))
989 /* Note: this should also modify whatever data the context reset
992 R300_STATECHANGE( rmesa
, vpt
);
993 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
994 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
998 radeonUpdateScissor( ctx
);
1002 * Tell the card where to render (offset, pitch).
1003 * Effected by glDrawBuffer, etc
1006 r300UpdateDrawBuffer(GLcontext
*ctx
)
1008 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1009 r300ContextPtr r300
= rmesa
;
1010 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1011 driRenderbuffer
*drb
;
1013 if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
) {
1015 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
1017 else if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_BACK_LEFT
) {
1019 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1022 /* drawing to multiple buffers, or none */
1027 assert(drb
->flippedPitch
);
1030 R300_STATECHANGE( rmesa
, cb
);
1032 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = drb
->flippedOffset
+ //r300->radeon.state.color.drawOffset +
1033 r300
->radeon
.radeonScreen
->fbLocation
;
1034 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = drb
->flippedPitch
;//r300->radeon.state.color.drawPitch;
1036 if (r300
->radeon
.radeonScreen
->cpp
== 4)
1037 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
1039 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
1041 if (r300
->radeon
.sarea
->tiling_enabled
)
1042 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
1044 R200_STATECHANGE( rmesa
, ctx
);
1046 /* Note: we used the (possibly) page-flipped values */
1047 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
1048 = ((drb
->flippedOffset
+ rmesa
->r200Screen
->fbLocation
)
1049 & R200_COLOROFFSET_MASK
);
1050 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
1052 if (rmesa
->sarea
->tiling_enabled
) {
1053 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |= R200_COLOR_TILE_ENABLE
;
1058 static void r300FetchStateParameter(GLcontext
*ctx
, const enum state_index state
[],
1061 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1065 case STATE_INTERNAL
:
1068 case STATE_R300_WINDOW_DIMENSION
:
1069 value
[0] = r300
->radeon
.dri
.drawable
->w
; /* width */
1070 value
[1] = r300
->radeon
.dri
.drawable
->h
; /* height */
1071 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1072 value
[3] = 1.0F
; /* not used */
1081 * Update R300's own internal state parameters.
1082 * For now just STATE_R300_WINDOW_DIMENSION
1084 static void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1086 struct r300_vertex_program_cont
*vpc
;
1087 struct gl_program_parameter_list
*paramList
;
1090 if(!(new_state
& (_NEW_BUFFERS
|_NEW_PROGRAM
)))
1093 vpc
= (struct r300_vertex_program_cont
*)ctx
->VertexProgram
._Current
;
1097 paramList
= vpc
->mesa_program
.Base
.Parameters
;
1102 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1103 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
){
1104 r300FetchStateParameter(ctx
,
1105 paramList
->Parameters
[i
].StateIndexes
,
1106 paramList
->ParameterValues
[i
]);
1111 /* =============================================================
1114 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1116 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1117 GLfloat constant
= units
;
1119 switch (ctx
->Visual
.depthBits
) {
1130 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1132 R300_STATECHANGE(rmesa
, zbs
);
1133 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1134 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1135 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1136 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1139 /* Routing and texture-related */
1142 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1143 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1144 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1145 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1146 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1147 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1148 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1149 * combinations where only one of them is nearest.
1151 static unsigned long gen_fixed_filter(unsigned long f
)
1153 unsigned long mag
, min
, needs_fixing
=0;
1156 /* We ignore MIRROR bit so we dont have to do everything twice */
1157 if((f
& ((7-1) << R300_TX_WRAP_S_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)){
1160 if((f
& ((7-1) << R300_TX_WRAP_T_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)){
1163 if((f
& ((7-1) << R300_TX_WRAP_Q_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_Q_SHIFT
)){
1170 mag
=f
& R300_TX_MAG_FILTER_MASK
;
1171 min
=f
& R300_TX_MIN_FILTER_MASK
;
1173 /* TODO: Check for anisto filters too */
1174 if((mag
!= R300_TX_MAG_FILTER_NEAREST
) && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1177 /* r300 cant handle these modes hence we force nearest to linear */
1178 if((mag
== R300_TX_MAG_FILTER_NEAREST
) && (min
!= R300_TX_MIN_FILTER_NEAREST
)){
1179 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1180 f
|= R300_TX_MAG_FILTER_LINEAR
;
1184 if((min
== R300_TX_MIN_FILTER_NEAREST
) && (mag
!= R300_TX_MAG_FILTER_NEAREST
)){
1185 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1186 f
|= R300_TX_MIN_FILTER_LINEAR
;
1190 /* Both are nearest */
1191 if(needs_fixing
& 1){
1192 f
&= ~((7-1) << R300_TX_WRAP_S_SHIFT
);
1193 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1195 if(needs_fixing
& 2){
1196 f
&= ~((7-1) << R300_TX_WRAP_T_SHIFT
);
1197 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1199 if(needs_fixing
& 4){
1200 f
&= ~((7-1) << R300_TX_WRAP_Q_SHIFT
);
1201 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_Q_SHIFT
;
1206 void r300_setup_textures(GLcontext
*ctx
)
1209 struct r300_tex_obj
*t
;
1210 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1212 int last_hw_tmu
=-1; /* -1 translates into no setup costs for fields */
1213 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1 };
1214 struct r300_fragment_program
*rp
=
1215 (struct r300_fragment_program
*)
1216 (char *)ctx
->FragmentProgram
._Current
;
1218 R300_STATECHANGE(r300
, txe
);
1219 R300_STATECHANGE(r300
, tex
.filter
);
1220 R300_STATECHANGE(r300
, tex
.unknown1
);
1221 R300_STATECHANGE(r300
, tex
.size
);
1222 R300_STATECHANGE(r300
, tex
.format
);
1223 R300_STATECHANGE(r300
, tex
.pitch
);
1224 R300_STATECHANGE(r300
, tex
.offset
);
1225 R300_STATECHANGE(r300
, tex
.unknown4
);
1226 R300_STATECHANGE(r300
, tex
.border_color
);
1228 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
]=0x0;
1230 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1231 if (RADEON_DEBUG
& DEBUG_STATE
)
1232 fprintf(stderr
, "mtu=%d\n", mtu
);
1234 if(mtu
> R300_MAX_TEXTURE_UNITS
) {
1235 fprintf(stderr
, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1236 mtu
, R300_MAX_TEXTURE_UNITS
);
1240 /* We cannot let disabled tmu offsets pass DRM */
1241 for(i
=0; i
< mtu
; i
++) {
1242 if(TMU_ENABLED(ctx
, i
)) {
1244 #if 0 /* Enables old behaviour */
1247 tmu_mappings
[i
] = hw_tmu
;
1249 t
=r300
->state
.texture
.unit
[i
].texobj
;
1251 if((t
->format
& 0xffffff00)==0xffffff00) {
1252 WARN_ONCE("unknown texture format (entry %x) encountered. Help me !\n", t
->format
& 0xff);
1255 if (RADEON_DEBUG
& DEBUG_STATE
)
1256 fprintf(stderr
, "Activating texture unit %d\n", i
);
1258 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1260 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = gen_fixed_filter(t
->filter
) | (hw_tmu
<< 28);
1261 /* Currently disabled! */
1262 r300
->hw
.tex
.unknown1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0; //0x20501f80;
1263 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->size
;
1264 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->format
;
1265 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->pitch_reg
;
1266 r300
->hw
.tex
.offset
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->offset
;
1268 if(t
->offset
& R300_TXO_MACRO_TILE
) {
1269 WARN_ONCE("macro tiling enabled!\n");
1272 if(t
->offset
& R300_TXO_MICRO_TILE
) {
1273 WARN_ONCE("micro tiling enabled!\n");
1276 r300
->hw
.tex
.unknown4
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0;
1277 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->pp_border_color
;
1279 last_hw_tmu
= hw_tmu
;
1285 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FILTER_0
, last_hw_tmu
+ 1);
1286 r300
->hw
.tex
.unknown1
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1287 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1288 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1289 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_PITCH_0
, last_hw_tmu
+ 1);
1290 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1291 r300
->hw
.tex
.unknown4
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1292 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1295 if (!rp
) /* should only happenen once, just after context is created */
1298 R300_STATECHANGE(r300
, fpt
);
1300 for(i
= 0; i
< rp
->tex
.length
; i
++){
1304 unit
= rp
->tex
.inst
[i
] >> R300_FPITX_IMAGE_SHIFT
;
1307 val
= rp
->tex
.inst
[i
];
1308 val
&= ~R300_FPITX_IMAGE_MASK
;
1310 assert(tmu_mappings
[unit
] >= 0);
1312 val
|= tmu_mappings
[unit
] << R300_FPITX_IMAGE_SHIFT
;
1313 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+i
] = val
;
1316 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] = cmdpacket0(R300_PFS_TEXI_0
, rp
->tex
.length
);
1318 if (RADEON_DEBUG
& DEBUG_STATE
)
1319 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n", r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1322 union r300_outputs_written
{
1323 GLuint vp_outputs
; /* hw_tcl_on */
1324 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1327 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1328 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1329 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1331 void r300_setup_rs_unit(GLcontext
*ctx
)
1333 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1334 /* I'm still unsure if these are needed */
1335 GLuint interp_magic
[8] = {
1345 union r300_outputs_written OutputsWritten
;
1347 int fp_reg
, high_rr
;
1348 int in_texcoords
, col_interp_nr
;
1352 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1354 RENDERINPUTS_COPY( OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1356 if (ctx
->FragmentProgram
._Current
)
1357 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1359 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1360 return; /* This should only ever happen once.. */
1363 R300_STATECHANGE(r300
, ri
);
1364 R300_STATECHANGE(r300
, rc
);
1365 R300_STATECHANGE(r300
, rr
);
1367 fp_reg
= in_texcoords
= col_interp_nr
= high_rr
= 0;
1369 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] = 0;
1371 if (InputsRead
& FRAG_BIT_WPOS
){
1372 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1373 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1376 if(i
== ctx
->Const
.MaxTextureUnits
){
1377 fprintf(stderr
, "\tno free texcoord found...\n");
1381 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1382 InputsRead
&= ~FRAG_BIT_WPOS
;
1385 for (i
=0;i
<ctx
->Const
.MaxTextureUnits
;i
++) {
1386 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+i
] = 0
1387 | R300_RS_INTERP_USED
1388 | (in_texcoords
<< R300_RS_INTERP_SRC_SHIFT
)
1391 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] = 0;
1392 if (InputsRead
& (FRAG_BIT_TEX0
<<i
)) {
1393 //assert(r300->state.texture.tc_count != 0);
1394 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] |=
1395 R300_RS_ROUTE_ENABLE
1396 | i
/* source INTERP */
1397 | (fp_reg
<< R300_RS_ROUTE_DEST_SHIFT
);
1400 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_TEX0
+i
, _TNL_ATTRIB_TEX(i
) )) {
1401 /* Passing invalid data here can lock the GPU. */
1402 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1403 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1406 InputsRead
&= ~(FRAG_BIT_TEX0
<<i
);
1409 /* Need to count all coords enabled at vof */
1410 if (R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_TEX0
+i
, _TNL_ATTRIB_TEX(i
) ))
1414 if (InputsRead
& FRAG_BIT_COL0
) {
1415 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1416 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1417 goto out
; /* FIXME */
1418 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1422 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1423 | R300_RS_ROUTE_0_COLOR
1424 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1425 InputsRead
&= ~FRAG_BIT_COL0
;
1430 if (InputsRead
& FRAG_BIT_COL1
) {
1431 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1432 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1436 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] |= R300_RS_ROUTE_1_UNKNOWN11
1437 | R300_RS_ROUTE_1_COLOR1
1438 | (fp_reg
++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT
);
1439 InputsRead
&= ~FRAG_BIT_COL1
;
1440 if (high_rr
< 1) high_rr
= 1;
1444 /* Need at least one. This might still lock as the values are undefined... */
1445 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1446 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1447 | R300_RS_ROUTE_0_COLOR
1448 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1452 r300
->hw
.rc
.cmd
[1] = 0
1453 | (in_texcoords
<< R300_RS_CNTL_TC_CNT_SHIFT
)
1454 | (col_interp_nr
<< R300_RS_CNTL_CI_CNT_SHIFT
)
1455 | R300_RS_CNTL_0_UNKNOWN_18
;
1457 assert(high_rr
>= 0);
1458 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R300_RS_ROUTE_0
, high_rr
+1);
1459 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1462 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1465 #define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
1467 #define bump_vpu_count(ptr, new_count) do{\
1468 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1469 int _nc=(new_count)/4; \
1470 assert(_nc < 256); \
1471 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1474 void static inline setup_vertex_shader_fragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1478 if(vsf
->length
==0)return;
1480 if(vsf
->length
& 0x3){
1481 fprintf(stderr
,"VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1485 switch((dest
>>8) & 0xf){
1487 R300_STATECHANGE(r300
, vpi
);
1488 for(i
=0;i
<vsf
->length
;i
++)
1489 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1490 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+4*(dest
& 0xff));
1494 R300_STATECHANGE(r300
, vpp
);
1495 for(i
=0;i
<vsf
->length
;i
++)
1496 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1497 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+4*(dest
& 0xff));
1500 R300_STATECHANGE(r300
, vps
);
1501 for(i
=0;i
<vsf
->length
;i
++)
1502 r300
->hw
.vps
.cmd
[1+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1503 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+4*(dest
& 0xff));
1506 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1511 void r300SetupVertexProgram(r300ContextPtr rmesa
);
1513 /* just a skeleton for now.. */
1515 /* Generate a vertex shader that simply transforms vertex and texture coordinates,
1516 while leaving colors intact. Nothing fancy (like lights)
1518 If implementing lights make a copy first, so it is easy to switch between the two versions */
1519 static void r300GenerateSimpleVertexShader(r300ContextPtr r300
)
1524 /* Allocate parameters */
1525 r300
->state
.vap_param
.transform_offset
=0x0; /* transform matrix */
1526 r300
->state
.vertex_shader
.param_offset
=0x0;
1527 r300
->state
.vertex_shader
.param_count
=0x4; /* 4 vector values - 4x4 matrix */
1529 r300
->state
.vertex_shader
.program_start
=0x0;
1530 r300
->state
.vertex_shader
.unknown_ptr1
=0x4; /* magic value ? */
1531 r300
->state
.vertex_shader
.program_end
=0x0;
1533 r300
->state
.vertex_shader
.unknown_ptr2
=0x0; /* magic value */
1534 r300
->state
.vertex_shader
.unknown_ptr3
=0x4; /* magic value */
1536 /* Initialize matrix and vector parameters.. these should really be restructured */
1537 /* TODO: fix vertex_shader structure */
1538 r300
->state
.vertex_shader
.matrix
[0].length
=16;
1539 r300
->state
.vertex_shader
.matrix
[1].length
=0;
1540 r300
->state
.vertex_shader
.matrix
[2].length
=0;
1541 r300
->state
.vertex_shader
.vector
[0].length
=0;
1542 r300
->state
.vertex_shader
.vector
[1].length
=0;
1543 r300
->state
.vertex_shader
.unknown1
.length
=0;
1544 r300
->state
.vertex_shader
.unknown2
.length
=0;
1546 #define WRITE_OP(oper,source1,source2,source3) {\
1547 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].op=(oper); \
1548 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src1=(source1); \
1549 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src2=(source2); \
1550 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src3=(source3); \
1551 r300->state.vertex_shader.program_end++; \
1554 /* Multiply vertex coordinates with transform matrix */
1557 EASY_VSF_OP(MUL
, 0, ALL
, TMP
),
1560 EASY_VSF_SOURCE(0, W
, W
, W
, W
, NONE
, NONE
)
1564 EASY_VSF_OP(MUL
, 1, ALL
, RESULT
),
1571 EASY_VSF_OP(MAD
, 0, ALL
, TMP
),
1578 EASY_VSF_OP(MAD
, 0, ALL
, TMP
),
1585 EASY_VSF_OP(MAD
, 0, ALL
, RESULT
),
1592 for (i
= VERT_ATTRIB_COLOR1
; i
< VERT_ATTRIB_MAX
; i
++)
1593 if (r300
->state
.sw_tcl_inputs
[i
] != -1) {
1595 EASY_VSF_OP(MUL
, o_reg
++ /* 2+i */, ALL
, RESULT
),
1596 VSF_REG(r300
->state
.sw_tcl_inputs
[i
]),
1597 VSF_ATTR_UNITY(r300
->state
.sw_tcl_inputs
[i
]),
1598 VSF_UNITY(r300
->state
.sw_tcl_inputs
[i
])
1603 r300
->state
.vertex_shader
.program_end
--; /* r300 wants program length to be one more - no idea why */
1604 r300
->state
.vertex_shader
.program
.length
=(r300
->state
.vertex_shader
.program_end
+1)*4;
1606 r300
->state
.vertex_shader
.unknown_ptr1
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1607 r300
->state
.vertex_shader
.unknown_ptr2
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1608 r300
->state
.vertex_shader
.unknown_ptr3
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1613 void r300SetupVertexShader(r300ContextPtr rmesa
)
1615 GLcontext
* ctx
= rmesa
->radeon
.glCtx
;
1617 /* Reset state, in case we don't use something */
1618 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1619 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1620 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1622 /* Not sure why this doesnt work...
1623 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
1624 0x406 is set to { 0.0, 0.0, 1.0, 0.0 } most of the time but should change with smooth points and in other rare cases. */
1625 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
1626 if(hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
){
1627 r300SetupVertexProgram(rmesa
);
1631 /* This needs to be replaced by vertex shader generation code */
1635 /* textures enabled ? */
1636 if(rmesa
->state
.texture
.tc_count
>0){
1637 rmesa
->state
.vertex_shader
=SINGLE_TEXTURE_VERTEX_SHADER
;
1639 rmesa
->state
.vertex_shader
=FLAT_COLOR_VERTEX_SHADER
;
1643 r300GenerateSimpleVertexShader(rmesa
);
1645 rmesa
->state
.vertex_shader
.matrix
[0].length
=16;
1646 memcpy(rmesa
->state
.vertex_shader
.matrix
[0].body
.f
, ctx
->_ModelProjectMatrix
.m
, 16*4);
1648 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(rmesa
->state
.vertex_shader
.program
));
1650 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX0
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1652 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX1
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1653 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX2
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1655 setup_vertex_shader_fragment(rmesa
, VSF_DEST_VECTOR0
, &(rmesa
->state
.vertex_shader
.vector
[0]));
1656 setup_vertex_shader_fragment(rmesa
, VSF_DEST_VECTOR1
, &(rmesa
->state
.vertex_shader
.vector
[1]));
1660 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
, &(rmesa
->state
.vertex_shader
.unknown1
));
1661 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
, &(rmesa
->state
.vertex_shader
.unknown2
));
1664 R300_STATECHANGE(rmesa
, pvs
);
1665 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
]=(rmesa
->state
.vertex_shader
.program_start
<< R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1666 | (rmesa
->state
.vertex_shader
.unknown_ptr1
<< R300_PVS_CNTL_1_POS_END_SHIFT
)
1667 | (rmesa
->state
.vertex_shader
.program_end
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1668 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
]=(rmesa
->state
.vertex_shader
.param_offset
<< R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1669 | (rmesa
->state
.vertex_shader
.param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1670 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
]=(rmesa
->state
.vertex_shader
.unknown_ptr2
<< R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1671 | (rmesa
->state
.vertex_shader
.unknown_ptr3
<< 0);
1673 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1674 so I leave it as a reminder */
1676 reg_start(R300_VAP_PVS_WAITIDLE
,0);
1681 void r300SetupVertexProgram(r300ContextPtr rmesa
)
1683 GLcontext
* ctx
= rmesa
->radeon
.glCtx
;
1686 struct r300_vertex_program
*prog
=(struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1689 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1690 R300_STATECHANGE(rmesa
, vpp
);
1691 param_count
= r300VertexProgUpdateParams(ctx
, (struct r300_vertex_program_cont
*)ctx
->VertexProgram
._Current
/*prog*/, (float *)&rmesa
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
]);
1692 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
1695 /* Reset state, in case we don't use something */
1696 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1697 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1699 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(prog
->program
));
1702 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
, &(rmesa
->state
.vertex_shader
.unknown1
));
1703 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
, &(rmesa
->state
.vertex_shader
.unknown2
));
1706 inst_count
=prog
->program
.length
/4 - 1;
1708 R300_STATECHANGE(rmesa
, pvs
);
1709 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
]=(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1710 | (inst_count
/*pos_end*/ << R300_PVS_CNTL_1_POS_END_SHIFT
)
1711 | (inst_count
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1712 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
]=(0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1713 | (param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1714 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
]=(0/*rmesa->state.vertex_shader.unknown_ptr2*/ << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1715 | (inst_count
/*rmesa->state.vertex_shader.unknown_ptr3*/ << 0);
1717 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1718 so I leave it as a reminder */
1720 reg_start(R300_VAP_PVS_WAITIDLE
,0);
1725 extern void _tnl_UpdateFixedFunctionProgram( GLcontext
*ctx
);
1727 extern int future_hw_tcl_on
;
1728 void r300UpdateShaders(r300ContextPtr rmesa
)
1731 struct r300_vertex_program
*vp
;
1734 ctx
= rmesa
->radeon
.glCtx
;
1736 if (rmesa
->NewGLState
&& hw_tcl_on
) {
1737 rmesa
->NewGLState
= 0;
1739 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1740 rmesa
->temp_attrib
[i
] = TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
1741 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] = &rmesa
->dummy_attrib
[i
];
1744 _tnl_UpdateFixedFunctionProgram(ctx
);
1746 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1747 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] = rmesa
->temp_attrib
[i
];
1750 r300_select_vertex_shader(rmesa
);
1751 vp
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1752 /*if (vp->translated == GL_FALSE)
1753 r300_translate_vertex_shader(vp);*/
1754 if (vp
->translated
== GL_FALSE
) {
1755 fprintf(stderr
, "Failing back to sw-tcl\n");
1756 hw_tcl_on
= future_hw_tcl_on
= 0;
1757 r300ResetHwState(rmesa
);
1761 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
1766 void r300UpdateShaderStates(r300ContextPtr rmesa
)
1769 ctx
= rmesa
->radeon
.glCtx
;
1771 r300UpdateTextureState(ctx
);
1773 r300SetupPixelShader(rmesa
);
1774 r300_setup_textures(ctx
);
1776 r300SetupVertexShader(rmesa
);
1777 r300_setup_rs_unit(ctx
);
1780 /* This is probably wrong for some values, I need to test this
1781 * some more. Range checking would be a good idea also..
1783 * But it works for most things. I'll fix it later if someone
1784 * else with a better clue doesn't
1786 static unsigned int r300PackFloat24(float f
)
1790 unsigned int float24
= 0;
1792 if (f
== 0.0) return 0;
1794 mantissa
= frexpf(f
, &exponent
);
1799 mantissa
= mantissa
* -1.0;
1801 /* Handle exponent, bias of 63 */
1803 float24
|= (exponent
<< 16);
1804 /* Kill 7 LSB of mantissa */
1805 float24
|= (r300PackFloat32(mantissa
) & 0x7FFFFF) >> 7;
1810 void r300SetupPixelShader(r300ContextPtr rmesa
)
1812 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1813 struct r300_fragment_program
*rp
=
1814 (struct r300_fragment_program
*)
1815 (char *)ctx
->FragmentProgram
._Current
;
1818 if (!rp
) /* should only happenen once, just after context is created */
1821 r300_translate_fragment_shader(rmesa
, rp
);
1822 if (!rp
->translated
) {
1823 fprintf(stderr
, "%s: No valid fragment shader, exiting\n", __func__
);
1827 #define OUTPUT_FIELD(st, reg, field) \
1828 R300_STATECHANGE(rmesa, st); \
1829 for(i=0;i<=rp->alu_end;i++) \
1830 rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=rp->alu.inst[i].field;\
1831 rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmdpacket0(reg, rp->alu_end+1);
1833 OUTPUT_FIELD(fpi
[0], R300_PFS_INSTR0_0
, inst0
);
1834 OUTPUT_FIELD(fpi
[1], R300_PFS_INSTR1_0
, inst1
);
1835 OUTPUT_FIELD(fpi
[2], R300_PFS_INSTR2_0
, inst2
);
1836 OUTPUT_FIELD(fpi
[3], R300_PFS_INSTR3_0
, inst3
);
1839 R300_STATECHANGE(rmesa
, fp
);
1840 /* I just want to say, the way these nodes are stored.. weird.. */
1841 for (i
=0,k
=(4-(rp
->cur_node
+1));i
<4;i
++,k
++) {
1842 if (i
<(rp
->cur_node
+1)) {
1843 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+k
]=
1844 (rp
->node
[i
].alu_offset
<< R300_PFS_NODE_ALU_OFFSET_SHIFT
)
1845 | (rp
->node
[i
].alu_end
<< R300_PFS_NODE_ALU_END_SHIFT
)
1846 | (rp
->node
[i
].tex_offset
<< R300_PFS_NODE_TEX_OFFSET_SHIFT
)
1847 | (rp
->node
[i
].tex_end
<< R300_PFS_NODE_TEX_END_SHIFT
)
1848 | rp
->node
[i
].flags
; /* ( (k==3) ? R300_PFS_NODE_LAST_NODE : 0); */
1850 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+(3-i
)] = 0;
1855 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
]=
1857 | (rp
->first_node_has_tex
<<3);
1859 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
]=rp
->max_temp_idx
;
1861 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
]=
1862 (rp
->alu_offset
<< R300_PFS_CNTL_ALU_OFFSET_SHIFT
)
1863 | (rp
->alu_end
<< R300_PFS_CNTL_ALU_END_SHIFT
)
1864 | (rp
->tex_offset
<< R300_PFS_CNTL_TEX_OFFSET_SHIFT
)
1865 | (rp
->tex_end
<< R300_PFS_CNTL_TEX_END_SHIFT
);
1867 R300_STATECHANGE(rmesa
, fpp
);
1868 for(i
=0;i
<rp
->const_nr
;i
++){
1869 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+0]=r300PackFloat24(rp
->constant
[i
][0]);
1870 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+1]=r300PackFloat24(rp
->constant
[i
][1]);
1871 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+2]=r300PackFloat24(rp
->constant
[i
][2]);
1872 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+3]=r300PackFloat24(rp
->constant
[i
][3]);
1874 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
]=cmdpacket0(R300_PFS_PARAM_0_X
, rp
->const_nr
*4);
1878 * Called by Mesa after an internal state update.
1880 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
1882 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1884 _swrast_InvalidateState(ctx
, new_state
);
1885 _swsetup_InvalidateState(ctx
, new_state
);
1886 _vbo_InvalidateState(ctx
, new_state
);
1887 _tnl_InvalidateState(ctx
, new_state
);
1888 _ae_invalidate_state(ctx
, new_state
);
1890 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
1891 r300UpdateDrawBuffer(ctx
);
1894 r300UpdateStateParameters(ctx
, new_state
);
1897 if(new_state
& _NEW_ARRAY
)
1898 r300
->state
.VB
.lock_uptodate
= GL_FALSE
;
1900 r300
->NewGLState
|= new_state
;
1904 * Completely recalculates hardware state based on the Mesa state.
1906 void r300ResetHwState(r300ContextPtr r300
)
1908 GLcontext
* ctx
= r300
->radeon
.glCtx
;
1910 if (RADEON_DEBUG
& DEBUG_STATE
)
1911 fprintf(stderr
, "%s\n", __FUNCTION__
);
1913 /* This is a place to initialize registers which
1914 have bitfields accessed by different functions
1915 and not all bits are used */
1917 /* initialize similiar to r200 */
1918 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] = 0;
1919 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] =
1920 (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
1921 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
) |
1922 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
) |
1923 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
) |
1924 (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
) |
1925 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
) |
1926 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
) |
1927 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
);
1928 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] = 0x00ffff00;
1931 /* go and compute register values from GL state */
1933 r300UpdateWindow(ctx
);
1936 ctx
->Color
.ColorMask
[RCOMP
],
1937 ctx
->Color
.ColorMask
[GCOMP
],
1938 ctx
->Color
.ColorMask
[BCOMP
],
1939 ctx
->Color
.ColorMask
[ACOMP
]);
1941 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
1942 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
1943 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
1946 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
1947 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
1948 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0], ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
1949 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0], ctx
->Stencil
.ZFailFunc
[0], ctx
->Stencil
.ZPassFunc
[0]);
1951 r300UpdateCulling(ctx
);
1953 r300UpdateTextureState(ctx
);
1955 // r300_setup_routing(ctx, GL_TRUE);
1957 #if 0 /* Done in prior to rendering */
1958 if(hw_tcl_on
== GL_FALSE
){
1959 r300EmitArrays(ctx
, GL_TRUE
); /* Just do the routing */
1960 r300_setup_textures(ctx
);
1961 r300_setup_rs_unit(ctx
);
1963 r300SetupVertexShader(r300
);
1964 r300SetupPixelShader(r300
);
1968 r300_set_blend_state(ctx
);
1970 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
1971 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
1973 /* Initialize magic registers
1974 TODO : learn what they really do, or get rid of
1975 those we don't have to touch */
1976 r300
->hw
.unk2080
.cmd
[1] = 0x0030045A; //0x0030065a /* Dangerous */
1978 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
1979 | R300_VPORT_X_OFFSET_ENA
1980 | R300_VPORT_Y_SCALE_ENA
1981 | R300_VPORT_Y_OFFSET_ENA
1982 | R300_VPORT_Z_SCALE_ENA
1983 | R300_VPORT_Z_OFFSET_ENA
1985 r300
->hw
.vte
.cmd
[2] = 0x00000008;
1987 r300
->hw
.unk2134
.cmd
[1] = 0x00FFFFFF;
1988 r300
->hw
.unk2134
.cmd
[2] = 0x00000000;
1989 if (_mesa_little_endian())
1990 r300
->hw
.unk2140
.cmd
[1] = 0x00000000;
1992 r300
->hw
.unk2140
.cmd
[1] = 0x00000002;
1994 #if 0 /* Done in setup routing */
1995 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[0].cmd
)->packet0
.count
= 1;
1996 r300
->hw
.vir
[0].cmd
[1] = 0x21030003;
1998 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[1].cmd
)->packet0
.count
= 1;
1999 r300
->hw
.vir
[1].cmd
[1] = 0xF688F688;
2001 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_0
] = 0x00000001;
2002 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_1
] = 0x00000405;
2005 r300
->hw
.unk21DC
.cmd
[1] = 0xAAAAAAAA;
2007 r300
->hw
.unk221C
.cmd
[1] = R300_221C_NORMAL
;
2009 r300
->hw
.unk2220
.cmd
[1] = r300PackFloat32(1.0);
2010 r300
->hw
.unk2220
.cmd
[2] = r300PackFloat32(1.0);
2011 r300
->hw
.unk2220
.cmd
[3] = r300PackFloat32(1.0);
2012 r300
->hw
.unk2220
.cmd
[4] = r300PackFloat32(1.0);
2014 /* what about other chips than r300 or rv350??? */
2015 if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
)
2016 r300
->hw
.unk2288
.cmd
[1] = R300_2288_R300
;
2018 r300
->hw
.unk2288
.cmd
[1] = R300_2288_RV350
;
2021 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_0
] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
2022 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
;
2023 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_1
] = 0; /* no textures */
2026 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] = 0;
2027 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] = 0;
2028 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] = 0;
2031 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2032 | R300_GB_LINE_STUFF_ENABLE
2033 | R300_GB_TRIANGLE_STUFF_ENABLE
/*| R300_GB_UNK31*/;
2035 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2036 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2037 if ((r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
) ||
2038 (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R350
))
2039 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2040 | R300_GB_TILE_PIPE_COUNT_R300
2041 | R300_GB_TILE_SIZE_16
;
2042 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
)
2043 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2044 | R300_GB_TILE_PIPE_COUNT_RV410
2045 | R300_GB_TILE_SIZE_16
;
2046 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
)
2047 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2048 | R300_GB_TILE_PIPE_COUNT_R420
2049 | R300_GB_TILE_SIZE_16
;
2051 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2052 | R300_GB_TILE_PIPE_COUNT_RV300
2053 | R300_GB_TILE_SIZE_16
;
2054 /* set to 0 when fog is disabled? */
2055 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2056 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = 0x00000000; /* No antialiasing */
2058 //r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
2060 r300
->hw
.unk4200
.cmd
[1] = r300PackFloat32(0.0);
2061 r300
->hw
.unk4200
.cmd
[2] = r300PackFloat32(0.0);
2062 r300
->hw
.unk4200
.cmd
[3] = r300PackFloat32(1.0);
2063 r300
->hw
.unk4200
.cmd
[4] = r300PackFloat32(1.0);
2065 r300
->hw
.unk4214
.cmd
[1] = 0x00050005;
2067 r300PointSize(ctx
, 0.0);
2069 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] = (6 << R300_POINTSIZE_X_SHIFT
) |
2070 (6 << R300_POINTSIZE_Y_SHIFT
);
2073 r300
->hw
.unk4230
.cmd
[1] = 0x18000006;
2074 r300
->hw
.unk4230
.cmd
[2] = 0x00020006;
2075 r300
->hw
.unk4230
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2077 r300LineWidth(ctx
, 0.0);
2079 r300
->hw
.unk4260
.cmd
[1] = 0;
2080 r300
->hw
.unk4260
.cmd
[2] = r300PackFloat32(0.0);
2081 r300
->hw
.unk4260
.cmd
[3] = r300PackFloat32(1.0);
2083 r300
->hw
.unk4274
.cmd
[1] = 0x00000002;
2084 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2085 r300
->hw
.unk4274
.cmd
[3] = 0x00000000;
2086 r300
->hw
.unk4274
.cmd
[4] = 0x00000000;
2088 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2089 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2090 r300
->hw
.unk4288
.cmd
[2] = 0x00000001;
2091 r300
->hw
.unk4288
.cmd
[3] = 0x00000000;
2092 r300
->hw
.unk42A0
.cmd
[1] = 0x00000000;
2094 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
, ctx
->Polygon
.OffsetUnits
);
2095 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2097 r300
->hw
.unk42C0
.cmd
[1] = 0x4B7FFFFF;
2098 r300
->hw
.unk42C0
.cmd
[2] = 0x00000000;
2101 r300
->hw
.unk43A4
.cmd
[1] = 0x0000001C;
2102 r300
->hw
.unk43A4
.cmd
[2] = 0x2DA49525;
2104 r300
->hw
.unk43E8
.cmd
[1] = 0x00FFFFFF;
2107 r300
->hw
.fp
.cmd
[R300_FP_CNTL0
] = 0;
2108 r300
->hw
.fp
.cmd
[R300_FP_CNTL1
] = 0;
2109 r300
->hw
.fp
.cmd
[R300_FP_CNTL2
] = 0;
2110 r300
->hw
.fp
.cmd
[R300_FP_NODE0
] = 0;
2111 r300
->hw
.fp
.cmd
[R300_FP_NODE1
] = 0;
2112 r300
->hw
.fp
.cmd
[R300_FP_NODE2
] = 0;
2113 r300
->hw
.fp
.cmd
[R300_FP_NODE3
] = 0;
2116 r300
->hw
.unk46A4
.cmd
[1] = 0x00001B01;
2117 r300
->hw
.unk46A4
.cmd
[2] = 0x00001B0F;
2118 r300
->hw
.unk46A4
.cmd
[3] = 0x00001B0F;
2119 r300
->hw
.unk46A4
.cmd
[4] = 0x00001B0F;
2120 r300
->hw
.unk46A4
.cmd
[5] = 0x00000001;
2123 for(i
= 1; i
<= 64; ++i
) {
2124 /* create NOP instructions */
2125 r300
->hw
.fpi
[0].cmd
[i
] = FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
));
2126 r300
->hw
.fpi
[1].cmd
[i
] = FP_SELC(0,XYZ
,NO
,FP_TMP(0),0,0);
2127 r300
->hw
.fpi
[2].cmd
[i
] = FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
));
2128 r300
->hw
.fpi
[3].cmd
[i
] = FP_SELA(0,W
,NO
,FP_TMP(0),0,0);
2131 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2132 ctx
->Driver
.Fogfv( ctx
, GL_FOG_MODE
, NULL
);
2133 ctx
->Driver
.Fogfv( ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2134 ctx
->Driver
.Fogfv( ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2135 ctx
->Driver
.Fogfv( ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2136 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2137 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2139 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
2140 r300
->hw
.unk4BD8
.cmd
[1] = 0;
2142 r300
->hw
.unk4E00
.cmd
[1] = 0;
2145 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = 0;
2146 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = 0;
2149 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2150 r300
->hw
.unk4E10
.cmd
[2] = 0;
2151 r300
->hw
.unk4E10
.cmd
[3] = 0;
2153 /* Again, r300ClearBuffer uses this */
2154 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = r300
->radeon
.state
.color
.drawOffset
+
2155 r300
->radeon
.radeonScreen
->fbLocation
;
2156 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.state
.color
.drawPitch
;
2158 if (r300
->radeon
.radeonScreen
->cpp
== 4)
2159 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
2161 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
2163 if (r300
->radeon
.sarea
->tiling_enabled
)
2164 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
2166 r300
->hw
.unk4E50
.cmd
[1] = 0;
2167 r300
->hw
.unk4E50
.cmd
[2] = 0;
2168 r300
->hw
.unk4E50
.cmd
[3] = 0;
2169 r300
->hw
.unk4E50
.cmd
[4] = 0;
2170 r300
->hw
.unk4E50
.cmd
[5] = 0;
2171 r300
->hw
.unk4E50
.cmd
[6] = 0;
2172 r300
->hw
.unk4E50
.cmd
[7] = 0;
2173 r300
->hw
.unk4E50
.cmd
[8] = 0;
2174 r300
->hw
.unk4E50
.cmd
[9] = 0;
2176 r300
->hw
.unk4E88
.cmd
[1] = 0;
2178 r300
->hw
.unk4EA0
.cmd
[1] = 0x00000000;
2179 r300
->hw
.unk4EA0
.cmd
[2] = 0xffffffff;
2181 switch (ctx
->Visual
.depthBits
) {
2183 r300
->hw
.unk4F10
.cmd
[1] = R300_DEPTH_FORMAT_16BIT_INT_Z
;
2186 r300
->hw
.unk4F10
.cmd
[1] = R300_DEPTH_FORMAT_24BIT_INT_Z
;
2189 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2190 ctx
->Visual
.depthBits
);
2195 //r300->hw.unk4F10.cmd[1] |= R300_DEPTH_FORMAT_UNK32;
2197 r300
->hw
.unk4F10
.cmd
[3] = 0x00000003;
2198 r300
->hw
.unk4F10
.cmd
[4] = 0x00000000;
2200 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
2201 r300
->radeon
.radeonScreen
->depthOffset
+
2202 r300
->radeon
.radeonScreen
->fbLocation
;
2203 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
2205 if (r300
->radeon
.sarea
->tiling_enabled
) {
2206 /* Turn off when clearing buffers ? */
2207 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_TILE_ENABLE
;
2209 if (ctx
->Visual
.depthBits
== 24)
2210 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_MICROTILE_ENABLE
;
2213 r300
->hw
.unk4F28
.cmd
[1] = 0;
2215 r300
->hw
.unk4F30
.cmd
[1] = 0;
2216 r300
->hw
.unk4F30
.cmd
[2] = 0;
2218 r300
->hw
.unk4F44
.cmd
[1] = 0;
2220 r300
->hw
.unk4F54
.cmd
[1] = 0;
2223 ((drm_r300_cmd_header_t
*)r300
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2224 for(i
= 1; i
< R300_VPI_CMDSIZE
; i
+= 4) {
2226 r300
->hw
.vpi
.cmd
[i
+0] = VP_OUT(ADD
,TMP
,0,XYZW
);
2227 r300
->hw
.vpi
.cmd
[i
+1] = VP_IN(TMP
,0);
2228 r300
->hw
.vpi
.cmd
[i
+2] = VP_ZERO();
2229 r300
->hw
.vpi
.cmd
[i
+3] = VP_ZERO();
2232 ((drm_r300_cmd_header_t
*)r300
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2233 for(i
= 1; i
< R300_VPP_CMDSIZE
; ++i
)
2234 r300
->hw
.vpp
.cmd
[i
] = 0;
2237 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2238 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2239 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2240 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2243 r300
->hw
.all_dirty
= GL_TRUE
;
2249 * Calculate initial hardware state and register state functions.
2250 * Assumes that the command buffer and state atoms have been
2251 * initialized already.
2253 void r300InitState(r300ContextPtr r300
)
2255 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2258 radeonInitState(&r300
->radeon
);
2260 switch (ctx
->Visual
.depthBits
) {
2262 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2263 depth_fmt
= R300_DEPTH_FORMAT_16BIT_INT_Z
;
2264 r300
->state
.stencil
.clear
= 0x00000000;
2267 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2268 depth_fmt
= R300_DEPTH_FORMAT_24BIT_INT_Z
;
2269 r300
->state
.stencil
.clear
= 0x00ff0000;
2272 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2273 ctx
->Visual
.depthBits
);
2277 /* Only have hw stencil when depth buffer is 24 bits deep */
2278 r300
->state
.stencil
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2279 ctx
->Visual
.depthBits
== 24);
2281 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2283 r300ResetHwState(r300
);
2286 static void r300RenderMode( GLcontext
*ctx
, GLenum mode
)
2288 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2294 * Initialize driver's state callback functions
2296 void r300InitStateFuncs(struct dd_function_table
* functions
)
2298 radeonInitStateFuncs(functions
);
2300 functions
->UpdateState
= r300InvalidateState
;
2301 functions
->AlphaFunc
= r300AlphaFunc
;
2302 functions
->BlendColor
= r300BlendColor
;
2303 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2304 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2305 functions
->Enable
= r300Enable
;
2306 functions
->ColorMask
= r300ColorMask
;
2307 functions
->DepthFunc
= r300DepthFunc
;
2308 functions
->DepthMask
= r300DepthMask
;
2309 functions
->CullFace
= r300CullFace
;
2310 functions
->Fogfv
= r300Fogfv
;
2311 functions
->FrontFace
= r300FrontFace
;
2312 functions
->ShadeModel
= r300ShadeModel
;
2314 /* Stencil related */
2315 functions
->ClearStencil
= r300ClearStencil
;
2316 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2317 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2318 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2320 /* Viewport related */
2321 functions
->Viewport
= r300Viewport
;
2322 functions
->DepthRange
= r300DepthRange
;
2323 functions
->PointSize
= r300PointSize
;
2324 functions
->LineWidth
= r300LineWidth
;
2326 functions
->PolygonOffset
= r300PolygonOffset
;
2327 functions
->PolygonMode
= r300PolygonMode
;
2329 functions
->RenderMode
= r300RenderMode
;