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 "shader/prog_parameter.h"
50 #include "shader/prog_statevars.h"
53 #include "texformat.h"
55 #include "radeon_ioctl.h"
56 #include "radeon_state.h"
57 #include "r300_context.h"
58 #include "r300_ioctl.h"
59 #include "r300_state.h"
61 #include "r300_program.h"
62 #include "r300_emit.h"
63 #include "r300_fragprog.h"
65 #include "r300_maos.h"
67 #include "drirenderbuffer.h"
69 static void r300BlendColor(GLcontext
* ctx
, const GLfloat cf
[4])
72 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
74 R300_STATECHANGE(rmesa
, unk4E10
);
76 CLAMPED_FLOAT_TO_UBYTE(color
[0], cf
[0]);
77 CLAMPED_FLOAT_TO_UBYTE(color
[1], cf
[1]);
78 CLAMPED_FLOAT_TO_UBYTE(color
[2], cf
[2]);
79 CLAMPED_FLOAT_TO_UBYTE(color
[3], cf
[3]);
81 rmesa
->hw
.unk4E10
.cmd
[1] = r300PackColor(4, color
[3], color
[0],
86 * Calculate the hardware blend factor setting. This same function is used
87 * for source and destination of both alpha and RGB.
90 * The hardware register value for the specified blend factor. This value
91 * will need to be shifted into the correct position for either source or
95 * Since the two cases where source and destination are handled differently
96 * are essentially error cases, they should never happen. Determine if these
97 * cases can be removed.
99 static int blend_factor(GLenum factor
, GLboolean is_src
)
105 func
= R300_BLEND_GL_ZERO
;
108 func
= R300_BLEND_GL_ONE
;
111 func
= R300_BLEND_GL_DST_COLOR
;
113 case GL_ONE_MINUS_DST_COLOR
:
114 func
= R300_BLEND_GL_ONE_MINUS_DST_COLOR
;
117 func
= R300_BLEND_GL_SRC_COLOR
;
119 case GL_ONE_MINUS_SRC_COLOR
:
120 func
= R300_BLEND_GL_ONE_MINUS_SRC_COLOR
;
123 func
= R300_BLEND_GL_SRC_ALPHA
;
125 case GL_ONE_MINUS_SRC_ALPHA
:
126 func
= R300_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
129 func
= R300_BLEND_GL_DST_ALPHA
;
131 case GL_ONE_MINUS_DST_ALPHA
:
132 func
= R300_BLEND_GL_ONE_MINUS_DST_ALPHA
;
134 case GL_SRC_ALPHA_SATURATE
:
135 func
= (is_src
) ? R300_BLEND_GL_SRC_ALPHA_SATURATE
:
138 case GL_CONSTANT_COLOR
:
139 func
= R300_BLEND_GL_CONST_COLOR
;
141 case GL_ONE_MINUS_CONSTANT_COLOR
:
142 func
= R300_BLEND_GL_ONE_MINUS_CONST_COLOR
;
144 case GL_CONSTANT_ALPHA
:
145 func
= R300_BLEND_GL_CONST_ALPHA
;
147 case GL_ONE_MINUS_CONSTANT_ALPHA
:
148 func
= R300_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
151 fprintf(stderr
, "unknown blend factor %x\n", factor
);
152 func
= (is_src
) ? R300_BLEND_GL_ONE
: R300_BLEND_GL_ZERO
;
158 * Sets both the blend equation and the blend function.
159 * This is done in a single
160 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
161 * change the interpretation of the blend function.
162 * Also, make sure that blend function and blend equation are set to their
163 * default value if color blending is not enabled, since at least blend
164 * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results
165 * otherwise for unknown reasons.
168 /* helper function */
169 static void r300_set_blend_cntl(r300ContextPtr r300
, int func
, int eqn
, int cbits
, int funcA
, int eqnA
)
171 GLuint new_ablend
, new_cblend
;
174 fprintf(stderr
, "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n", eqnA
, funcA
, eqn
, func
, cbits
);
176 new_ablend
= eqnA
| funcA
;
177 new_cblend
= eqn
| func
;
179 /* Some blend factor combinations don't seem to work when the
180 * BLEND_NO_SEPARATE bit is set.
182 * Especially problematic candidates are the ONE_MINUS_* flags,
183 * but I can't see a real pattern.
186 if (new_ablend
== new_cblend
) {
187 new_cblend
|= R300_BLEND_NO_SEPARATE
;
192 if((new_ablend
!= r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]) ||
193 (new_cblend
!= r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
])) {
194 R300_STATECHANGE(r300
, bld
);
195 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]=new_ablend
;
196 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
]=new_cblend
;
201 static void r300_set_blend_state(GLcontext
* ctx
)
203 r300ContextPtr r300
= R300_CONTEXT(ctx
);
204 int func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
205 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
206 int eqn
= R300_COMB_FCN_ADD_CLAMP
;
207 int funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
208 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
209 int eqnA
= R300_COMB_FCN_ADD_CLAMP
;
211 if (RGBA_LOGICOP_ENABLED(ctx
) || !ctx
->Color
.BlendEnabled
) {
212 r300_set_blend_cntl(r300
,
218 func
= (blend_factor(ctx
->Color
.BlendSrcRGB
, GL_TRUE
) << R300_SRC_BLEND_SHIFT
) |
219 (blend_factor(ctx
->Color
.BlendDstRGB
, GL_FALSE
) << R300_DST_BLEND_SHIFT
);
221 switch (ctx
->Color
.BlendEquationRGB
) {
223 eqn
= R300_COMB_FCN_ADD_CLAMP
;
226 case GL_FUNC_SUBTRACT
:
227 eqn
= R300_COMB_FCN_SUB_CLAMP
;
230 case GL_FUNC_REVERSE_SUBTRACT
:
231 eqn
= R300_COMB_FCN_RSUB_CLAMP
;
235 eqn
= R300_COMB_FCN_MIN
;
236 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
237 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
241 eqn
= R300_COMB_FCN_MAX
;
242 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
243 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
248 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
249 __func__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
254 funcA
= (blend_factor(ctx
->Color
.BlendSrcA
, GL_TRUE
) << R300_SRC_BLEND_SHIFT
) |
255 (blend_factor(ctx
->Color
.BlendDstA
, GL_FALSE
) << R300_DST_BLEND_SHIFT
);
257 switch (ctx
->Color
.BlendEquationA
) {
259 eqnA
= R300_COMB_FCN_ADD_CLAMP
;
262 case GL_FUNC_SUBTRACT
:
263 eqnA
= R300_COMB_FCN_SUB_CLAMP
;
266 case GL_FUNC_REVERSE_SUBTRACT
:
267 eqnA
= R300_COMB_FCN_RSUB_CLAMP
;
271 eqnA
= R300_COMB_FCN_MIN
;
272 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
273 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
277 eqnA
= R300_COMB_FCN_MAX
;
278 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
279 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
283 fprintf(stderr
, "[%s:%u] Invalid A blend equation (0x%04x).\n",
284 __func__
, __LINE__
, ctx
->Color
.BlendEquationA
);
288 r300_set_blend_cntl(r300
,
289 func
, eqn
, R300_BLEND_UNKNOWN
| R300_BLEND_ENABLE
,
293 static void r300BlendEquationSeparate(GLcontext
* ctx
,
294 GLenum modeRGB
, GLenum modeA
)
296 r300_set_blend_state(ctx
);
299 static void r300BlendFuncSeparate(GLcontext
* ctx
,
300 GLenum sfactorRGB
, GLenum dfactorRGB
,
301 GLenum sfactorA
, GLenum dfactorA
)
303 r300_set_blend_state(ctx
);
307 * Update our tracked culling state based on Mesa's state.
309 static void r300UpdateCulling(GLcontext
* ctx
)
311 r300ContextPtr r300
= R300_CONTEXT(ctx
);
314 R300_STATECHANGE(r300
, cul
);
315 if (ctx
->Polygon
.CullFlag
) {
316 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
)
317 val
= R300_CULL_FRONT
|R300_CULL_BACK
;
318 else if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
319 val
= R300_CULL_FRONT
;
321 val
= R300_CULL_BACK
;
323 if (ctx
->Polygon
.FrontFace
== GL_CW
)
324 val
|= R300_FRONT_FACE_CW
;
326 val
|= R300_FRONT_FACE_CCW
;
328 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
331 static void update_early_z(GLcontext
*ctx
)
333 /* updates register R300_RB3D_EARLY_Z (0x4F14)
334 if depth test is not enabled it should be R300_EARLY_Z_DISABLE
335 if depth is enabled and alpha not it should be R300_EARLY_Z_ENABLE
336 if depth and alpha is enabled it should be R300_EARLY_Z_DISABLE
338 r300ContextPtr r300
= R300_CONTEXT(ctx
);
340 R300_STATECHANGE(r300
, unk4F10
);
341 if (ctx
->Color
.AlphaEnabled
&& ctx
->Color
.AlphaFunc
!= GL_ALWAYS
)
342 /* disable early Z */
343 r300
->hw
.unk4F10
.cmd
[2] = R300_EARLY_Z_DISABLE
;
345 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
)
347 r300
->hw
.unk4F10
.cmd
[2] = R300_EARLY_Z_ENABLE
;
349 /* disable early Z */
350 r300
->hw
.unk4F10
.cmd
[2] = R300_EARLY_Z_DISABLE
;
354 static void update_alpha(GLcontext
*ctx
)
356 r300ContextPtr r300
= R300_CONTEXT(ctx
);
358 uint32_t pp_misc
= 0x0;
359 GLboolean really_enabled
= ctx
->Color
.AlphaEnabled
;
361 CLAMPED_FLOAT_TO_UBYTE(refByte
, ctx
->Color
.AlphaRef
);
363 switch (ctx
->Color
.AlphaFunc
) {
365 pp_misc
|= R300_ALPHA_TEST_FAIL
;
368 pp_misc
|= R300_ALPHA_TEST_LESS
;
371 pp_misc
|= R300_ALPHA_TEST_EQUAL
;
374 pp_misc
|= R300_ALPHA_TEST_LEQUAL
;
377 pp_misc
|= R300_ALPHA_TEST_GREATER
;
380 pp_misc
|= R300_ALPHA_TEST_NEQUAL
;
383 pp_misc
|= R300_ALPHA_TEST_GEQUAL
;
386 /*pp_misc |= R300_ALPHA_TEST_PASS;*/
387 really_enabled
= GL_FALSE
;
391 if (really_enabled
) {
392 pp_misc
|= R300_ALPHA_TEST_ENABLE
;
393 pp_misc
|= (refByte
& R300_REF_ALPHA_MASK
);
399 R300_STATECHANGE(r300
, at
);
400 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
404 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
411 static int translate_func(int func
)
415 return R300_ZS_NEVER
;
419 return R300_ZS_EQUAL
;
421 return R300_ZS_LEQUAL
;
423 return R300_ZS_GREATER
;
425 return R300_ZS_NOTEQUAL
;
427 return R300_ZS_GEQUAL
;
429 return R300_ZS_ALWAYS
;
434 static void update_depth(GLcontext
* ctx
)
436 r300ContextPtr r300
= R300_CONTEXT(ctx
);
438 R300_STATECHANGE(r300
, zs
);
439 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_RB3D_STENCIL_ENABLE
;
440 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
442 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
) {
444 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_TEST_AND_WRITE
;
446 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_TEST
;
448 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= translate_func(ctx
->Depth
.Func
) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
450 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_DISABLED_1
;
451 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= translate_func(GL_NEVER
) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
458 * Handle glEnable()/glDisable().
460 * \note Mesa already filters redundant calls to glEnable/glDisable.
462 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
464 r300ContextPtr r300
= R300_CONTEXT(ctx
);
466 if (RADEON_DEBUG
& DEBUG_STATE
)
467 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
468 _mesa_lookup_enum_by_nr(cap
),
469 state
? "GL_TRUE" : "GL_FALSE");
472 /* Fast track this one...
480 R300_STATECHANGE(r300
, fogs
);
482 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] |=
485 ctx
->Driver
.Fogfv( ctx
, GL_FOG_MODE
, NULL
);
486 ctx
->Driver
.Fogfv( ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
487 ctx
->Driver
.Fogfv( ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
488 ctx
->Driver
.Fogfv( ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
489 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
491 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] &=
502 case GL_COLOR_LOGIC_OP
:
503 r300_set_blend_state(ctx
);
510 case GL_STENCIL_TEST
:
511 if (r300
->state
.stencil
.hw_stencil
) {
512 R300_STATECHANGE(r300
, zs
);
514 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
515 R300_RB3D_STENCIL_ENABLE
;
517 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
518 ~R300_RB3D_STENCIL_ENABLE
;
522 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
528 r300UpdateCulling(ctx
);
531 case GL_POLYGON_OFFSET_POINT
:
532 case GL_POLYGON_OFFSET_LINE
:
535 case GL_POLYGON_OFFSET_FILL
:
536 R300_STATECHANGE(r300
, unk42B4
);
538 r300
->hw
.unk42B4
.cmd
[1] |= (3<<0);
540 r300
->hw
.unk42B4
.cmd
[1] &= ~(3<<0);
544 radeonEnable(ctx
, cap
, state
);
550 static void r300UpdatePolygonMode(GLcontext
*ctx
)
552 r300ContextPtr r300
= R300_CONTEXT(ctx
);
555 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
556 ctx
->Polygon
.BackMode
!= GL_FILL
) {
559 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
560 f
= ctx
->Polygon
.FrontMode
;
561 b
= ctx
->Polygon
.BackMode
;
563 f
= ctx
->Polygon
.BackMode
;
564 b
= ctx
->Polygon
.FrontMode
;
567 hw_mode
|= R300_PM_ENABLED
;
571 hw_mode
|= R300_PM_FRONT_LINE
;
573 case GL_POINT
: /* noop */
574 hw_mode
|= R300_PM_FRONT_POINT
;
577 hw_mode
|= R300_PM_FRONT_FILL
;
583 hw_mode
|= R300_PM_BACK_LINE
;
585 case GL_POINT
: /* noop */
586 hw_mode
|= R300_PM_BACK_POINT
;
589 hw_mode
|= R300_PM_BACK_FILL
;
594 if (r300
->hw
.unk4288
.cmd
[1] != hw_mode
) {
595 R300_STATECHANGE(r300
, unk4288
);
596 r300
->hw
.unk4288
.cmd
[1] = hw_mode
;
601 * Change the culling mode.
603 * \note Mesa already filters redundant calls to this function.
605 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
609 r300UpdateCulling(ctx
);
614 * Change the polygon orientation.
616 * \note Mesa already filters redundant calls to this function.
618 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
622 r300UpdateCulling(ctx
);
623 r300UpdatePolygonMode(ctx
);
628 * Change the depth testing function.
630 * \note Mesa already filters redundant calls to this function.
632 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
640 * Enable/Disable depth writing.
642 * \note Mesa already filters redundant calls to this function.
644 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
652 * Handle glColorMask()
654 static void r300ColorMask(GLcontext
* ctx
,
655 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
657 r300ContextPtr r300
= R300_CONTEXT(ctx
);
658 int mask
= (r
? R300_COLORMASK0_R
: 0) |
659 (g
? R300_COLORMASK0_G
: 0) |
660 (b
? R300_COLORMASK0_B
: 0) |
661 (a
? R300_COLORMASK0_A
: 0);
663 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
664 R300_STATECHANGE(r300
, cmk
);
665 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
669 /* =============================================================
672 static void r300Fogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
674 r300ContextPtr r300
= R300_CONTEXT(ctx
);
675 union { int i
; float f
; } fogScale
, fogStart
;
679 fogScale
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
];
680 fogStart
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_START
];
684 if (!ctx
->Fog
.Enabled
)
686 switch (ctx
->Fog
.Mode
) {
688 R300_STATECHANGE(r300
, fogs
);
689 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
690 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_LINEAR
;
692 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
697 fogScale
.f
= 1.0 / (ctx
->Fog
.End
-ctx
->Fog
.Start
);
698 fogStart
.f
= -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-ctx
->Fog
.Start
);
702 R300_STATECHANGE(r300
, fogs
);
703 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
704 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_EXP
;
705 fogScale
.f
= 0.0933*ctx
->Fog
.Density
;
709 R300_STATECHANGE(r300
, fogs
);
710 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
711 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_EXP2
;
712 fogScale
.f
= 0.3*ctx
->Fog
.Density
;
719 switch (ctx
->Fog
.Mode
) {
721 fogScale
.f
= 0.0933*ctx
->Fog
.Density
;
725 fogScale
.f
= 0.3*ctx
->Fog
.Density
;
733 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
734 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
739 fogScale
.f
= 1.0 / (ctx
->Fog
.End
-ctx
->Fog
.Start
);
740 fogStart
.f
= -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-ctx
->Fog
.Start
);
745 R300_STATECHANGE(r300
, fogc
);
746 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] = (GLuint
) (ctx
->Fog
.Color
[0]*1023.0F
) & 0x3FF;
747 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] = (GLuint
) (ctx
->Fog
.Color
[1]*1023.0F
) & 0x3FF;
748 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] = (GLuint
) (ctx
->Fog
.Color
[2]*1023.0F
) & 0x3FF;
750 case GL_FOG_COORD_SRC
:
756 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
757 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
758 R300_STATECHANGE(r300
, fogp
);
759 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
760 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
764 /* =============================================================
767 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
769 r300ContextPtr r300
= R300_CONTEXT(ctx
);
771 size
= ctx
->Point
._Size
;
773 R300_STATECHANGE(r300
, ps
);
774 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
775 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
776 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
779 /* =============================================================
782 static void r300LineWidth(GLcontext
*ctx
, GLfloat widthf
)
784 r300ContextPtr r300
= R300_CONTEXT(ctx
);
786 widthf
= ctx
->Line
._Width
;
788 R300_STATECHANGE(r300
, lcntl
);
789 r300
->hw
.lcntl
.cmd
[1] = (int)(widthf
* 6.0);
790 r300
->hw
.lcntl
.cmd
[1] |= R300_LINE_CNT_VE
;
793 static void r300PolygonMode(GLcontext
*ctx
, GLenum face
, GLenum mode
)
798 r300UpdatePolygonMode(ctx
);
801 /* =============================================================
805 static int translate_stencil_op(int op
)
813 return R300_ZS_REPLACE
;
818 case GL_INCR_WRAP_EXT
:
819 return R300_ZS_INCR_WRAP
;
820 case GL_DECR_WRAP_EXT
:
821 return R300_ZS_DECR_WRAP
;
823 return R300_ZS_INVERT
;
825 WARN_ONCE("Do not know how to translate stencil op");
831 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
833 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
835 R300_STATECHANGE(rmesa
, unk4274
);
838 rmesa
->hw
.unk4274
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
841 rmesa
->hw
.unk4274
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
848 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
849 GLenum func
, GLint ref
, GLuint mask
)
851 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
852 GLuint refmask
= (((ctx
->Stencil
.Ref
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
853 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
857 R300_STATECHANGE(rmesa
, zs
);
859 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(
860 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
)
861 | (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
863 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &= ~((R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
864 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
866 flag
= translate_func(ctx
->Stencil
.Function
[0]);
867 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= (flag
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
);
869 if (ctx
->Stencil
._TestTwoSide
)
870 flag
= translate_func(ctx
->Stencil
.Function
[1]);
872 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= (flag
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
873 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
876 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
878 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
880 R300_STATECHANGE(rmesa
, zs
);
881 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &= ~(R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
);
882 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= (ctx
->Stencil
.WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
;
886 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
, GLenum fail
,
887 GLenum zfail
, GLenum zpass
)
889 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
891 R300_STATECHANGE(rmesa
, zs
);
892 /* It is easier to mask what's left.. */
893 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
894 (R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
) |
895 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
896 (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
898 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
899 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
)
900 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
)
901 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
);
903 if (ctx
->Stencil
._TestTwoSide
) {
904 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
905 (translate_stencil_op(ctx
->Stencil
.FailFunc
[1]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
906 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[1]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
907 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[1]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
909 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
910 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
911 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
912 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
916 static void r300ClearStencil(GLcontext
* ctx
, GLint s
)
918 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
920 rmesa
->state
.stencil
.clear
=
921 ((GLuint
) (ctx
->Stencil
.Clear
& 0xff) |
922 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
) |
923 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
));
926 /* =============================================================
927 * Window position and viewport transformation
931 * To correctly position primitives:
933 #define SUBPIXEL_X 0.125
934 #define SUBPIXEL_Y 0.125
936 void r300UpdateWindow(GLcontext
* ctx
)
938 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
939 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
940 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
941 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
942 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
944 GLfloat sx
= v
[MAT_SX
];
945 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
946 GLfloat sy
= -v
[MAT_SY
];
947 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
948 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
949 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
951 R300_FIREVERTICES(rmesa
);
952 R300_STATECHANGE(rmesa
, vpt
);
954 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
955 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
956 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
957 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
958 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
959 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
962 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
963 GLsizei width
, GLsizei height
)
965 /* Don't pipeline viewport changes, conflict with window offset
966 * setting below. Could apply deltas to rescue pipelined viewport
967 * values, or keep the originals hanging around.
969 r300UpdateWindow(ctx
);
972 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
974 r300UpdateWindow(ctx
);
977 void r300UpdateViewportOffset( GLcontext
*ctx
)
979 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
980 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
)rmesa
)->dri
.drawable
;
981 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
982 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
983 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
985 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
986 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
988 if ( rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
989 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
))
991 /* Note: this should also modify whatever data the context reset
994 R300_STATECHANGE( rmesa
, vpt
);
995 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
996 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1000 radeonUpdateScissor( ctx
);
1004 * Tell the card where to render (offset, pitch).
1005 * Effected by glDrawBuffer, etc
1008 r300UpdateDrawBuffer(GLcontext
*ctx
)
1010 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1011 r300ContextPtr r300
= rmesa
;
1012 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1013 driRenderbuffer
*drb
;
1015 if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
) {
1017 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
1019 else if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_BACK_LEFT
) {
1021 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1024 /* drawing to multiple buffers, or none */
1029 assert(drb
->flippedPitch
);
1032 R300_STATECHANGE( rmesa
, cb
);
1034 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = drb
->flippedOffset
+ //r300->radeon.state.color.drawOffset +
1035 r300
->radeon
.radeonScreen
->fbLocation
;
1036 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = drb
->flippedPitch
;//r300->radeon.state.color.drawPitch;
1038 if (r300
->radeon
.radeonScreen
->cpp
== 4)
1039 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
1041 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
1043 if (r300
->radeon
.sarea
->tiling_enabled
)
1044 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
1046 R200_STATECHANGE( rmesa
, ctx
);
1048 /* Note: we used the (possibly) page-flipped values */
1049 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
1050 = ((drb
->flippedOffset
+ rmesa
->r200Screen
->fbLocation
)
1051 & R200_COLOROFFSET_MASK
);
1052 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
1054 if (rmesa
->sarea
->tiling_enabled
) {
1055 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |= R200_COLOR_TILE_ENABLE
;
1061 r300FetchStateParameter(GLcontext
*ctx
,
1062 const gl_state_index state
[STATE_LENGTH
],
1065 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1069 case STATE_INTERNAL
:
1072 case STATE_R300_WINDOW_DIMENSION
:
1073 value
[0] = r300
->radeon
.dri
.drawable
->w
; /* width */
1074 value
[1] = r300
->radeon
.dri
.drawable
->h
; /* height */
1075 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1076 value
[3] = 1.0F
; /* not used */
1085 * Update R300's own internal state parameters.
1086 * For now just STATE_R300_WINDOW_DIMENSION
1088 static void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1090 struct r300_vertex_program_cont
*vpc
;
1091 struct gl_program_parameter_list
*paramList
;
1094 if(!(new_state
& (_NEW_BUFFERS
|_NEW_PROGRAM
)))
1097 vpc
= (struct r300_vertex_program_cont
*)ctx
->VertexProgram
._Current
;
1101 paramList
= vpc
->mesa_program
.Base
.Parameters
;
1106 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1107 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
){
1108 r300FetchStateParameter(ctx
,
1109 paramList
->Parameters
[i
].StateIndexes
,
1110 paramList
->ParameterValues
[i
]);
1115 /* =============================================================
1118 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1120 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1121 GLfloat constant
= units
;
1123 switch (ctx
->Visual
.depthBits
) {
1134 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1136 R300_STATECHANGE(rmesa
, zbs
);
1137 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1138 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1139 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1140 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1143 /* Routing and texture-related */
1146 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1147 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1148 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1149 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1150 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1151 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1152 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1153 * combinations where only one of them is nearest.
1155 static unsigned long gen_fixed_filter(unsigned long f
)
1157 unsigned long mag
, min
, needs_fixing
=0;
1160 /* We ignore MIRROR bit so we dont have to do everything twice */
1161 if((f
& ((7-1) << R300_TX_WRAP_S_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)){
1164 if((f
& ((7-1) << R300_TX_WRAP_T_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)){
1167 if((f
& ((7-1) << R300_TX_WRAP_Q_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_Q_SHIFT
)){
1174 mag
=f
& R300_TX_MAG_FILTER_MASK
;
1175 min
=f
& R300_TX_MIN_FILTER_MASK
;
1177 /* TODO: Check for anisto filters too */
1178 if((mag
!= R300_TX_MAG_FILTER_NEAREST
) && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1181 /* r300 cant handle these modes hence we force nearest to linear */
1182 if((mag
== R300_TX_MAG_FILTER_NEAREST
) && (min
!= R300_TX_MIN_FILTER_NEAREST
)){
1183 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1184 f
|= R300_TX_MAG_FILTER_LINEAR
;
1188 if((min
== R300_TX_MIN_FILTER_NEAREST
) && (mag
!= R300_TX_MAG_FILTER_NEAREST
)){
1189 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1190 f
|= R300_TX_MIN_FILTER_LINEAR
;
1194 /* Both are nearest */
1195 if(needs_fixing
& 1){
1196 f
&= ~((7-1) << R300_TX_WRAP_S_SHIFT
);
1197 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1199 if(needs_fixing
& 2){
1200 f
&= ~((7-1) << R300_TX_WRAP_T_SHIFT
);
1201 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1203 if(needs_fixing
& 4){
1204 f
&= ~((7-1) << R300_TX_WRAP_Q_SHIFT
);
1205 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_Q_SHIFT
;
1210 void r300_setup_textures(GLcontext
*ctx
)
1213 struct r300_tex_obj
*t
;
1214 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1216 int last_hw_tmu
=-1; /* -1 translates into no setup costs for fields */
1217 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1 };
1218 struct r300_fragment_program
*rp
=
1219 (struct r300_fragment_program
*)
1220 (char *)ctx
->FragmentProgram
._Current
;
1222 R300_STATECHANGE(r300
, txe
);
1223 R300_STATECHANGE(r300
, tex
.filter
);
1224 R300_STATECHANGE(r300
, tex
.unknown1
);
1225 R300_STATECHANGE(r300
, tex
.size
);
1226 R300_STATECHANGE(r300
, tex
.format
);
1227 R300_STATECHANGE(r300
, tex
.pitch
);
1228 R300_STATECHANGE(r300
, tex
.offset
);
1229 R300_STATECHANGE(r300
, tex
.unknown4
);
1230 R300_STATECHANGE(r300
, tex
.border_color
);
1232 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
]=0x0;
1234 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1235 if (RADEON_DEBUG
& DEBUG_STATE
)
1236 fprintf(stderr
, "mtu=%d\n", mtu
);
1238 if(mtu
> R300_MAX_TEXTURE_UNITS
) {
1239 fprintf(stderr
, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1240 mtu
, R300_MAX_TEXTURE_UNITS
);
1244 /* We cannot let disabled tmu offsets pass DRM */
1245 for(i
=0; i
< mtu
; i
++) {
1246 if(TMU_ENABLED(ctx
, i
)) {
1248 #if 0 /* Enables old behaviour */
1251 tmu_mappings
[i
] = hw_tmu
;
1253 t
=r300
->state
.texture
.unit
[i
].texobj
;
1255 if((t
->format
& 0xffffff00)==0xffffff00) {
1256 WARN_ONCE("unknown texture format (entry %x) encountered. Help me !\n", t
->format
& 0xff);
1259 if (RADEON_DEBUG
& DEBUG_STATE
)
1260 fprintf(stderr
, "Activating texture unit %d\n", i
);
1262 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1264 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = gen_fixed_filter(t
->filter
) | (hw_tmu
<< 28);
1265 /* Currently disabled! */
1266 r300
->hw
.tex
.unknown1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0; //0x20501f80;
1267 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->size
;
1268 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->format
;
1269 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->pitch_reg
;
1270 r300
->hw
.tex
.offset
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->offset
;
1272 if(t
->offset
& R300_TXO_MACRO_TILE
) {
1273 WARN_ONCE("macro tiling enabled!\n");
1276 if(t
->offset
& R300_TXO_MICRO_TILE
) {
1277 WARN_ONCE("micro tiling enabled!\n");
1280 r300
->hw
.tex
.unknown4
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0;
1281 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->pp_border_color
;
1283 last_hw_tmu
= hw_tmu
;
1289 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FILTER_0
, last_hw_tmu
+ 1);
1290 r300
->hw
.tex
.unknown1
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1291 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1292 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1293 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_PITCH_0
, last_hw_tmu
+ 1);
1294 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1295 r300
->hw
.tex
.unknown4
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1296 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1299 if (!rp
) /* should only happenen once, just after context is created */
1302 R300_STATECHANGE(r300
, fpt
);
1304 for(i
= 0; i
< rp
->tex
.length
; i
++){
1308 unit
= rp
->tex
.inst
[i
] >> R300_FPITX_IMAGE_SHIFT
;
1311 val
= rp
->tex
.inst
[i
];
1312 val
&= ~R300_FPITX_IMAGE_MASK
;
1314 assert(tmu_mappings
[unit
] >= 0);
1316 val
|= tmu_mappings
[unit
] << R300_FPITX_IMAGE_SHIFT
;
1317 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+i
] = val
;
1320 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] = cmdpacket0(R300_PFS_TEXI_0
, rp
->tex
.length
);
1322 if (RADEON_DEBUG
& DEBUG_STATE
)
1323 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n", r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1326 union r300_outputs_written
{
1327 GLuint vp_outputs
; /* hw_tcl_on */
1328 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1331 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1332 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1333 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1335 void r300_setup_rs_unit(GLcontext
*ctx
)
1337 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1338 /* I'm still unsure if these are needed */
1339 GLuint interp_magic
[8] = {
1349 union r300_outputs_written OutputsWritten
;
1351 int fp_reg
, high_rr
;
1352 int in_texcoords
, col_interp_nr
;
1356 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1358 RENDERINPUTS_COPY( OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1360 if (ctx
->FragmentProgram
._Current
)
1361 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1363 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1364 return; /* This should only ever happen once.. */
1367 R300_STATECHANGE(r300
, ri
);
1368 R300_STATECHANGE(r300
, rc
);
1369 R300_STATECHANGE(r300
, rr
);
1371 fp_reg
= in_texcoords
= col_interp_nr
= high_rr
= 0;
1373 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] = 0;
1375 if (InputsRead
& FRAG_BIT_WPOS
){
1376 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1377 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1380 if(i
== ctx
->Const
.MaxTextureUnits
){
1381 fprintf(stderr
, "\tno free texcoord found...\n");
1385 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1386 InputsRead
&= ~FRAG_BIT_WPOS
;
1389 for (i
=0;i
<ctx
->Const
.MaxTextureUnits
;i
++) {
1390 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+i
] = 0
1391 | R300_RS_INTERP_USED
1392 | (in_texcoords
<< R300_RS_INTERP_SRC_SHIFT
)
1395 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] = 0;
1396 if (InputsRead
& (FRAG_BIT_TEX0
<<i
)) {
1397 //assert(r300->state.texture.tc_count != 0);
1398 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] |=
1399 R300_RS_ROUTE_ENABLE
1400 | i
/* source INTERP */
1401 | (fp_reg
<< R300_RS_ROUTE_DEST_SHIFT
);
1404 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_TEX0
+i
, _TNL_ATTRIB_TEX(i
) )) {
1405 /* Passing invalid data here can lock the GPU. */
1406 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1407 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1410 InputsRead
&= ~(FRAG_BIT_TEX0
<<i
);
1413 /* Need to count all coords enabled at vof */
1414 if (R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_TEX0
+i
, _TNL_ATTRIB_TEX(i
) ))
1418 if (InputsRead
& FRAG_BIT_COL0
) {
1419 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1420 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1421 goto out
; /* FIXME */
1422 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1426 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1427 | R300_RS_ROUTE_0_COLOR
1428 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1429 InputsRead
&= ~FRAG_BIT_COL0
;
1434 if (InputsRead
& FRAG_BIT_COL1
) {
1435 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1436 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1440 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] |= R300_RS_ROUTE_1_UNKNOWN11
1441 | R300_RS_ROUTE_1_COLOR1
1442 | (fp_reg
++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT
);
1443 InputsRead
&= ~FRAG_BIT_COL1
;
1444 if (high_rr
< 1) high_rr
= 1;
1448 /* Need at least one. This might still lock as the values are undefined... */
1449 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1450 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1451 | R300_RS_ROUTE_0_COLOR
1452 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1456 r300
->hw
.rc
.cmd
[1] = 0
1457 | (in_texcoords
<< R300_RS_CNTL_TC_CNT_SHIFT
)
1458 | (col_interp_nr
<< R300_RS_CNTL_CI_CNT_SHIFT
)
1459 | R300_RS_CNTL_0_UNKNOWN_18
;
1461 assert(high_rr
>= 0);
1462 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R300_RS_ROUTE_0
, high_rr
+1);
1463 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1466 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1469 #define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
1471 #define bump_vpu_count(ptr, new_count) do{\
1472 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1473 int _nc=(new_count)/4; \
1474 assert(_nc < 256); \
1475 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1478 void static inline setup_vertex_shader_fragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1482 if(vsf
->length
==0)return;
1484 if(vsf
->length
& 0x3){
1485 fprintf(stderr
,"VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1489 switch((dest
>>8) & 0xf){
1491 R300_STATECHANGE(r300
, vpi
);
1492 for(i
=0;i
<vsf
->length
;i
++)
1493 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1494 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+4*(dest
& 0xff));
1498 R300_STATECHANGE(r300
, vpp
);
1499 for(i
=0;i
<vsf
->length
;i
++)
1500 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1501 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+4*(dest
& 0xff));
1504 R300_STATECHANGE(r300
, vps
);
1505 for(i
=0;i
<vsf
->length
;i
++)
1506 r300
->hw
.vps
.cmd
[1+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1507 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+4*(dest
& 0xff));
1510 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1515 void r300SetupVertexProgram(r300ContextPtr rmesa
);
1517 /* just a skeleton for now.. */
1519 /* Generate a vertex shader that simply transforms vertex and texture coordinates,
1520 while leaving colors intact. Nothing fancy (like lights)
1522 If implementing lights make a copy first, so it is easy to switch between the two versions */
1523 static void r300GenerateSimpleVertexShader(r300ContextPtr r300
)
1528 /* Allocate parameters */
1529 r300
->state
.vap_param
.transform_offset
=0x0; /* transform matrix */
1530 r300
->state
.vertex_shader
.param_offset
=0x0;
1531 r300
->state
.vertex_shader
.param_count
=0x4; /* 4 vector values - 4x4 matrix */
1533 r300
->state
.vertex_shader
.program_start
=0x0;
1534 r300
->state
.vertex_shader
.unknown_ptr1
=0x4; /* magic value ? */
1535 r300
->state
.vertex_shader
.program_end
=0x0;
1537 r300
->state
.vertex_shader
.unknown_ptr2
=0x0; /* magic value */
1538 r300
->state
.vertex_shader
.unknown_ptr3
=0x4; /* magic value */
1540 /* Initialize matrix and vector parameters.. these should really be restructured */
1541 /* TODO: fix vertex_shader structure */
1542 r300
->state
.vertex_shader
.matrix
[0].length
=16;
1543 r300
->state
.vertex_shader
.matrix
[1].length
=0;
1544 r300
->state
.vertex_shader
.matrix
[2].length
=0;
1545 r300
->state
.vertex_shader
.vector
[0].length
=0;
1546 r300
->state
.vertex_shader
.vector
[1].length
=0;
1547 r300
->state
.vertex_shader
.unknown1
.length
=0;
1548 r300
->state
.vertex_shader
.unknown2
.length
=0;
1550 #define WRITE_OP(oper,source1,source2,source3) {\
1551 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].op=(oper); \
1552 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src1=(source1); \
1553 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src2=(source2); \
1554 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src3=(source3); \
1555 r300->state.vertex_shader.program_end++; \
1558 /* Multiply vertex coordinates with transform matrix */
1561 EASY_VSF_OP(MUL
, 0, ALL
, TMP
),
1564 EASY_VSF_SOURCE(0, W
, W
, W
, W
, NONE
, NONE
)
1568 EASY_VSF_OP(MUL
, 1, ALL
, RESULT
),
1575 EASY_VSF_OP(MAD
, 0, ALL
, TMP
),
1582 EASY_VSF_OP(MAD
, 0, ALL
, TMP
),
1589 EASY_VSF_OP(MAD
, 0, ALL
, RESULT
),
1596 for (i
= VERT_ATTRIB_COLOR1
; i
< VERT_ATTRIB_MAX
; i
++)
1597 if (r300
->state
.sw_tcl_inputs
[i
] != -1) {
1599 EASY_VSF_OP(MUL
, o_reg
++ /* 2+i */, ALL
, RESULT
),
1600 VSF_REG(r300
->state
.sw_tcl_inputs
[i
]),
1601 VSF_ATTR_UNITY(r300
->state
.sw_tcl_inputs
[i
]),
1602 VSF_UNITY(r300
->state
.sw_tcl_inputs
[i
])
1607 r300
->state
.vertex_shader
.program_end
--; /* r300 wants program length to be one more - no idea why */
1608 r300
->state
.vertex_shader
.program
.length
=(r300
->state
.vertex_shader
.program_end
+1)*4;
1610 r300
->state
.vertex_shader
.unknown_ptr1
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1611 r300
->state
.vertex_shader
.unknown_ptr2
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1612 r300
->state
.vertex_shader
.unknown_ptr3
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1617 void r300SetupVertexShader(r300ContextPtr rmesa
)
1619 GLcontext
* ctx
= rmesa
->radeon
.glCtx
;
1621 /* Reset state, in case we don't use something */
1622 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1623 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1624 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1626 /* Not sure why this doesnt work...
1627 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
1628 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. */
1629 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
1630 if(hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
){
1631 r300SetupVertexProgram(rmesa
);
1635 /* This needs to be replaced by vertex shader generation code */
1639 /* textures enabled ? */
1640 if(rmesa
->state
.texture
.tc_count
>0){
1641 rmesa
->state
.vertex_shader
=SINGLE_TEXTURE_VERTEX_SHADER
;
1643 rmesa
->state
.vertex_shader
=FLAT_COLOR_VERTEX_SHADER
;
1647 r300GenerateSimpleVertexShader(rmesa
);
1649 rmesa
->state
.vertex_shader
.matrix
[0].length
=16;
1650 memcpy(rmesa
->state
.vertex_shader
.matrix
[0].body
.f
, ctx
->_ModelProjectMatrix
.m
, 16*4);
1652 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(rmesa
->state
.vertex_shader
.program
));
1654 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX0
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1656 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX1
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1657 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX2
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1659 setup_vertex_shader_fragment(rmesa
, VSF_DEST_VECTOR0
, &(rmesa
->state
.vertex_shader
.vector
[0]));
1660 setup_vertex_shader_fragment(rmesa
, VSF_DEST_VECTOR1
, &(rmesa
->state
.vertex_shader
.vector
[1]));
1664 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
, &(rmesa
->state
.vertex_shader
.unknown1
));
1665 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
, &(rmesa
->state
.vertex_shader
.unknown2
));
1668 R300_STATECHANGE(rmesa
, pvs
);
1669 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
]=(rmesa
->state
.vertex_shader
.program_start
<< R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1670 | (rmesa
->state
.vertex_shader
.unknown_ptr1
<< R300_PVS_CNTL_1_POS_END_SHIFT
)
1671 | (rmesa
->state
.vertex_shader
.program_end
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1672 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
]=(rmesa
->state
.vertex_shader
.param_offset
<< R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1673 | (rmesa
->state
.vertex_shader
.param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1674 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
]=(rmesa
->state
.vertex_shader
.unknown_ptr2
<< R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1675 | (rmesa
->state
.vertex_shader
.unknown_ptr3
<< 0);
1677 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1678 so I leave it as a reminder */
1680 reg_start(R300_VAP_PVS_WAITIDLE
,0);
1685 void r300SetupVertexProgram(r300ContextPtr rmesa
)
1687 GLcontext
* ctx
= rmesa
->radeon
.glCtx
;
1690 struct r300_vertex_program
*prog
=(struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1693 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1694 R300_STATECHANGE(rmesa
, vpp
);
1695 param_count
= r300VertexProgUpdateParams(ctx
, (struct r300_vertex_program_cont
*)ctx
->VertexProgram
._Current
/*prog*/, (float *)&rmesa
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
]);
1696 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
1699 /* Reset state, in case we don't use something */
1700 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1701 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1703 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(prog
->program
));
1706 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
, &(rmesa
->state
.vertex_shader
.unknown1
));
1707 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
, &(rmesa
->state
.vertex_shader
.unknown2
));
1710 inst_count
=prog
->program
.length
/4 - 1;
1712 R300_STATECHANGE(rmesa
, pvs
);
1713 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
]=(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1714 | (inst_count
/*pos_end*/ << R300_PVS_CNTL_1_POS_END_SHIFT
)
1715 | (inst_count
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1716 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
]=(0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1717 | (param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1718 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
]=(0/*rmesa->state.vertex_shader.unknown_ptr2*/ << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1719 | (inst_count
/*rmesa->state.vertex_shader.unknown_ptr3*/ << 0);
1721 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1722 so I leave it as a reminder */
1724 reg_start(R300_VAP_PVS_WAITIDLE
,0);
1729 extern void _tnl_UpdateFixedFunctionProgram( GLcontext
*ctx
);
1731 extern int future_hw_tcl_on
;
1732 void r300UpdateShaders(r300ContextPtr rmesa
)
1735 struct r300_vertex_program
*vp
;
1738 ctx
= rmesa
->radeon
.glCtx
;
1740 if (rmesa
->NewGLState
&& hw_tcl_on
) {
1741 rmesa
->NewGLState
= 0;
1743 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1744 rmesa
->temp_attrib
[i
] = TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
1745 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] = &rmesa
->dummy_attrib
[i
];
1748 _tnl_UpdateFixedFunctionProgram(ctx
);
1750 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1751 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] = rmesa
->temp_attrib
[i
];
1754 r300_select_vertex_shader(rmesa
);
1755 vp
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1756 /*if (vp->translated == GL_FALSE)
1757 r300_translate_vertex_shader(vp);*/
1758 if (vp
->translated
== GL_FALSE
) {
1759 fprintf(stderr
, "Failing back to sw-tcl\n");
1760 hw_tcl_on
= future_hw_tcl_on
= 0;
1761 r300ResetHwState(rmesa
);
1765 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
1770 void r300UpdateShaderStates(r300ContextPtr rmesa
)
1773 ctx
= rmesa
->radeon
.glCtx
;
1775 r300UpdateTextureState(ctx
);
1777 r300SetupPixelShader(rmesa
);
1778 r300_setup_textures(ctx
);
1780 r300SetupVertexShader(rmesa
);
1781 r300_setup_rs_unit(ctx
);
1784 /* This is probably wrong for some values, I need to test this
1785 * some more. Range checking would be a good idea also..
1787 * But it works for most things. I'll fix it later if someone
1788 * else with a better clue doesn't
1790 static unsigned int r300PackFloat24(float f
)
1794 unsigned int float24
= 0;
1796 if (f
== 0.0) return 0;
1798 mantissa
= frexpf(f
, &exponent
);
1803 mantissa
= mantissa
* -1.0;
1805 /* Handle exponent, bias of 63 */
1807 float24
|= (exponent
<< 16);
1808 /* Kill 7 LSB of mantissa */
1809 float24
|= (r300PackFloat32(mantissa
) & 0x7FFFFF) >> 7;
1814 void r300SetupPixelShader(r300ContextPtr rmesa
)
1816 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1817 struct r300_fragment_program
*rp
=
1818 (struct r300_fragment_program
*)
1819 (char *)ctx
->FragmentProgram
._Current
;
1822 if (!rp
) /* should only happenen once, just after context is created */
1825 r300_translate_fragment_shader(rmesa
, rp
);
1826 if (!rp
->translated
) {
1827 fprintf(stderr
, "%s: No valid fragment shader, exiting\n", __func__
);
1831 #define OUTPUT_FIELD(st, reg, field) \
1832 R300_STATECHANGE(rmesa, st); \
1833 for(i=0;i<=rp->alu_end;i++) \
1834 rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=rp->alu.inst[i].field;\
1835 rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmdpacket0(reg, rp->alu_end+1);
1837 OUTPUT_FIELD(fpi
[0], R300_PFS_INSTR0_0
, inst0
);
1838 OUTPUT_FIELD(fpi
[1], R300_PFS_INSTR1_0
, inst1
);
1839 OUTPUT_FIELD(fpi
[2], R300_PFS_INSTR2_0
, inst2
);
1840 OUTPUT_FIELD(fpi
[3], R300_PFS_INSTR3_0
, inst3
);
1843 R300_STATECHANGE(rmesa
, fp
);
1844 /* I just want to say, the way these nodes are stored.. weird.. */
1845 for (i
=0,k
=(4-(rp
->cur_node
+1));i
<4;i
++,k
++) {
1846 if (i
<(rp
->cur_node
+1)) {
1847 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+k
]=
1848 (rp
->node
[i
].alu_offset
<< R300_PFS_NODE_ALU_OFFSET_SHIFT
)
1849 | (rp
->node
[i
].alu_end
<< R300_PFS_NODE_ALU_END_SHIFT
)
1850 | (rp
->node
[i
].tex_offset
<< R300_PFS_NODE_TEX_OFFSET_SHIFT
)
1851 | (rp
->node
[i
].tex_end
<< R300_PFS_NODE_TEX_END_SHIFT
)
1852 | rp
->node
[i
].flags
; /* ( (k==3) ? R300_PFS_NODE_LAST_NODE : 0); */
1854 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+(3-i
)] = 0;
1859 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
]=
1861 | (rp
->first_node_has_tex
<<3);
1863 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
]=rp
->max_temp_idx
;
1865 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
]=
1866 (rp
->alu_offset
<< R300_PFS_CNTL_ALU_OFFSET_SHIFT
)
1867 | (rp
->alu_end
<< R300_PFS_CNTL_ALU_END_SHIFT
)
1868 | (rp
->tex_offset
<< R300_PFS_CNTL_TEX_OFFSET_SHIFT
)
1869 | (rp
->tex_end
<< R300_PFS_CNTL_TEX_END_SHIFT
);
1871 R300_STATECHANGE(rmesa
, fpp
);
1872 for(i
=0;i
<rp
->const_nr
;i
++){
1873 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+0]=r300PackFloat24(rp
->constant
[i
][0]);
1874 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+1]=r300PackFloat24(rp
->constant
[i
][1]);
1875 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+2]=r300PackFloat24(rp
->constant
[i
][2]);
1876 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+3]=r300PackFloat24(rp
->constant
[i
][3]);
1878 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
]=cmdpacket0(R300_PFS_PARAM_0_X
, rp
->const_nr
*4);
1882 * Called by Mesa after an internal state update.
1884 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
1886 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1888 _swrast_InvalidateState(ctx
, new_state
);
1889 _swsetup_InvalidateState(ctx
, new_state
);
1890 _vbo_InvalidateState(ctx
, new_state
);
1891 _tnl_InvalidateState(ctx
, new_state
);
1892 _ae_invalidate_state(ctx
, new_state
);
1894 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
1895 r300UpdateDrawBuffer(ctx
);
1898 r300UpdateStateParameters(ctx
, new_state
);
1901 if(new_state
& _NEW_ARRAY
)
1902 r300
->state
.VB
.lock_uptodate
= GL_FALSE
;
1904 r300
->NewGLState
|= new_state
;
1908 * Completely recalculates hardware state based on the Mesa state.
1910 void r300ResetHwState(r300ContextPtr r300
)
1912 GLcontext
* ctx
= r300
->radeon
.glCtx
;
1914 if (RADEON_DEBUG
& DEBUG_STATE
)
1915 fprintf(stderr
, "%s\n", __FUNCTION__
);
1917 /* This is a place to initialize registers which
1918 have bitfields accessed by different functions
1919 and not all bits are used */
1921 /* initialize similiar to r200 */
1922 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] = 0;
1923 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] =
1924 (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
1925 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
) |
1926 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
) |
1927 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
) |
1928 (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
) |
1929 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
) |
1930 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
) |
1931 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
);
1932 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] = 0x00ffff00;
1935 /* go and compute register values from GL state */
1937 r300UpdateWindow(ctx
);
1940 ctx
->Color
.ColorMask
[RCOMP
],
1941 ctx
->Color
.ColorMask
[GCOMP
],
1942 ctx
->Color
.ColorMask
[BCOMP
],
1943 ctx
->Color
.ColorMask
[ACOMP
]);
1945 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
1946 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
1947 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
1950 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
1951 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
1952 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0], ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
1953 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0], ctx
->Stencil
.ZFailFunc
[0], ctx
->Stencil
.ZPassFunc
[0]);
1955 r300UpdateCulling(ctx
);
1957 r300UpdateTextureState(ctx
);
1959 // r300_setup_routing(ctx, GL_TRUE);
1961 #if 0 /* Done in prior to rendering */
1962 if(hw_tcl_on
== GL_FALSE
){
1963 r300EmitArrays(ctx
, GL_TRUE
); /* Just do the routing */
1964 r300_setup_textures(ctx
);
1965 r300_setup_rs_unit(ctx
);
1967 r300SetupVertexShader(r300
);
1968 r300SetupPixelShader(r300
);
1972 r300_set_blend_state(ctx
);
1974 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
1975 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
1977 /* Initialize magic registers
1978 TODO : learn what they really do, or get rid of
1979 those we don't have to touch */
1980 r300
->hw
.unk2080
.cmd
[1] = 0x0030045A; //0x0030065a /* Dangerous */
1982 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
1983 | R300_VPORT_X_OFFSET_ENA
1984 | R300_VPORT_Y_SCALE_ENA
1985 | R300_VPORT_Y_OFFSET_ENA
1986 | R300_VPORT_Z_SCALE_ENA
1987 | R300_VPORT_Z_OFFSET_ENA
1989 r300
->hw
.vte
.cmd
[2] = 0x00000008;
1991 r300
->hw
.unk2134
.cmd
[1] = 0x00FFFFFF;
1992 r300
->hw
.unk2134
.cmd
[2] = 0x00000000;
1993 if (_mesa_little_endian())
1994 r300
->hw
.unk2140
.cmd
[1] = 0x00000000;
1996 r300
->hw
.unk2140
.cmd
[1] = 0x00000002;
1998 #if 0 /* Done in setup routing */
1999 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[0].cmd
)->packet0
.count
= 1;
2000 r300
->hw
.vir
[0].cmd
[1] = 0x21030003;
2002 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[1].cmd
)->packet0
.count
= 1;
2003 r300
->hw
.vir
[1].cmd
[1] = 0xF688F688;
2005 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_0
] = 0x00000001;
2006 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_1
] = 0x00000405;
2009 r300
->hw
.unk21DC
.cmd
[1] = 0xAAAAAAAA;
2011 r300
->hw
.unk221C
.cmd
[1] = R300_221C_NORMAL
;
2013 r300
->hw
.unk2220
.cmd
[1] = r300PackFloat32(1.0);
2014 r300
->hw
.unk2220
.cmd
[2] = r300PackFloat32(1.0);
2015 r300
->hw
.unk2220
.cmd
[3] = r300PackFloat32(1.0);
2016 r300
->hw
.unk2220
.cmd
[4] = r300PackFloat32(1.0);
2018 /* what about other chips than r300 or rv350??? */
2019 if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
)
2020 r300
->hw
.unk2288
.cmd
[1] = R300_2288_R300
;
2022 r300
->hw
.unk2288
.cmd
[1] = R300_2288_RV350
;
2025 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_0
] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
2026 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
;
2027 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_1
] = 0; /* no textures */
2030 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] = 0;
2031 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] = 0;
2032 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] = 0;
2035 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2036 | R300_GB_LINE_STUFF_ENABLE
2037 | R300_GB_TRIANGLE_STUFF_ENABLE
/*| R300_GB_UNK31*/;
2039 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2040 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2041 if ((r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
) ||
2042 (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R350
))
2043 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2044 | R300_GB_TILE_PIPE_COUNT_R300
2045 | R300_GB_TILE_SIZE_16
;
2046 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
)
2047 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2048 | R300_GB_TILE_PIPE_COUNT_RV410
2049 | R300_GB_TILE_SIZE_16
;
2050 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
)
2051 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2052 | R300_GB_TILE_PIPE_COUNT_R420
2053 | R300_GB_TILE_SIZE_16
;
2055 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2056 | R300_GB_TILE_PIPE_COUNT_RV300
2057 | R300_GB_TILE_SIZE_16
;
2058 /* set to 0 when fog is disabled? */
2059 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2060 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = 0x00000000; /* No antialiasing */
2062 //r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
2064 r300
->hw
.unk4200
.cmd
[1] = r300PackFloat32(0.0);
2065 r300
->hw
.unk4200
.cmd
[2] = r300PackFloat32(0.0);
2066 r300
->hw
.unk4200
.cmd
[3] = r300PackFloat32(1.0);
2067 r300
->hw
.unk4200
.cmd
[4] = r300PackFloat32(1.0);
2069 r300
->hw
.unk4214
.cmd
[1] = 0x00050005;
2071 r300PointSize(ctx
, 0.0);
2073 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] = (6 << R300_POINTSIZE_X_SHIFT
) |
2074 (6 << R300_POINTSIZE_Y_SHIFT
);
2077 r300
->hw
.unk4230
.cmd
[1] = 0x18000006;
2078 r300
->hw
.unk4230
.cmd
[2] = 0x00020006;
2079 r300
->hw
.unk4230
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2081 r300LineWidth(ctx
, 0.0);
2083 r300
->hw
.unk4260
.cmd
[1] = 0;
2084 r300
->hw
.unk4260
.cmd
[2] = r300PackFloat32(0.0);
2085 r300
->hw
.unk4260
.cmd
[3] = r300PackFloat32(1.0);
2087 r300
->hw
.unk4274
.cmd
[1] = 0x00000002;
2088 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2089 r300
->hw
.unk4274
.cmd
[3] = 0x00000000;
2090 r300
->hw
.unk4274
.cmd
[4] = 0x00000000;
2092 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2093 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2094 r300
->hw
.unk4288
.cmd
[2] = 0x00000001;
2095 r300
->hw
.unk4288
.cmd
[3] = 0x00000000;
2096 r300
->hw
.unk42A0
.cmd
[1] = 0x00000000;
2098 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
, ctx
->Polygon
.OffsetUnits
);
2099 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2101 r300
->hw
.unk42C0
.cmd
[1] = 0x4B7FFFFF;
2102 r300
->hw
.unk42C0
.cmd
[2] = 0x00000000;
2105 r300
->hw
.unk43A4
.cmd
[1] = 0x0000001C;
2106 r300
->hw
.unk43A4
.cmd
[2] = 0x2DA49525;
2108 r300
->hw
.unk43E8
.cmd
[1] = 0x00FFFFFF;
2111 r300
->hw
.fp
.cmd
[R300_FP_CNTL0
] = 0;
2112 r300
->hw
.fp
.cmd
[R300_FP_CNTL1
] = 0;
2113 r300
->hw
.fp
.cmd
[R300_FP_CNTL2
] = 0;
2114 r300
->hw
.fp
.cmd
[R300_FP_NODE0
] = 0;
2115 r300
->hw
.fp
.cmd
[R300_FP_NODE1
] = 0;
2116 r300
->hw
.fp
.cmd
[R300_FP_NODE2
] = 0;
2117 r300
->hw
.fp
.cmd
[R300_FP_NODE3
] = 0;
2120 r300
->hw
.unk46A4
.cmd
[1] = 0x00001B01;
2121 r300
->hw
.unk46A4
.cmd
[2] = 0x00001B0F;
2122 r300
->hw
.unk46A4
.cmd
[3] = 0x00001B0F;
2123 r300
->hw
.unk46A4
.cmd
[4] = 0x00001B0F;
2124 r300
->hw
.unk46A4
.cmd
[5] = 0x00000001;
2127 for(i
= 1; i
<= 64; ++i
) {
2128 /* create NOP instructions */
2129 r300
->hw
.fpi
[0].cmd
[i
] = FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
));
2130 r300
->hw
.fpi
[1].cmd
[i
] = FP_SELC(0,XYZ
,NO
,FP_TMP(0),0,0);
2131 r300
->hw
.fpi
[2].cmd
[i
] = FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
));
2132 r300
->hw
.fpi
[3].cmd
[i
] = FP_SELA(0,W
,NO
,FP_TMP(0),0,0);
2135 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2136 ctx
->Driver
.Fogfv( ctx
, GL_FOG_MODE
, NULL
);
2137 ctx
->Driver
.Fogfv( ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2138 ctx
->Driver
.Fogfv( ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2139 ctx
->Driver
.Fogfv( ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2140 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2141 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2143 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
2144 r300
->hw
.unk4BD8
.cmd
[1] = 0;
2146 r300
->hw
.unk4E00
.cmd
[1] = 0;
2149 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = 0;
2150 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = 0;
2153 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2154 r300
->hw
.unk4E10
.cmd
[2] = 0;
2155 r300
->hw
.unk4E10
.cmd
[3] = 0;
2157 /* Again, r300ClearBuffer uses this */
2158 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = r300
->radeon
.state
.color
.drawOffset
+
2159 r300
->radeon
.radeonScreen
->fbLocation
;
2160 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.state
.color
.drawPitch
;
2162 if (r300
->radeon
.radeonScreen
->cpp
== 4)
2163 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
2165 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
2167 if (r300
->radeon
.sarea
->tiling_enabled
)
2168 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
2170 r300
->hw
.unk4E50
.cmd
[1] = 0;
2171 r300
->hw
.unk4E50
.cmd
[2] = 0;
2172 r300
->hw
.unk4E50
.cmd
[3] = 0;
2173 r300
->hw
.unk4E50
.cmd
[4] = 0;
2174 r300
->hw
.unk4E50
.cmd
[5] = 0;
2175 r300
->hw
.unk4E50
.cmd
[6] = 0;
2176 r300
->hw
.unk4E50
.cmd
[7] = 0;
2177 r300
->hw
.unk4E50
.cmd
[8] = 0;
2178 r300
->hw
.unk4E50
.cmd
[9] = 0;
2180 r300
->hw
.unk4E88
.cmd
[1] = 0;
2182 r300
->hw
.unk4EA0
.cmd
[1] = 0x00000000;
2183 r300
->hw
.unk4EA0
.cmd
[2] = 0xffffffff;
2185 switch (ctx
->Visual
.depthBits
) {
2187 r300
->hw
.unk4F10
.cmd
[1] = R300_DEPTH_FORMAT_16BIT_INT_Z
;
2190 r300
->hw
.unk4F10
.cmd
[1] = R300_DEPTH_FORMAT_24BIT_INT_Z
;
2193 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2194 ctx
->Visual
.depthBits
);
2199 //r300->hw.unk4F10.cmd[1] |= R300_DEPTH_FORMAT_UNK32;
2201 r300
->hw
.unk4F10
.cmd
[3] = 0x00000003;
2202 r300
->hw
.unk4F10
.cmd
[4] = 0x00000000;
2204 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
2205 r300
->radeon
.radeonScreen
->depthOffset
+
2206 r300
->radeon
.radeonScreen
->fbLocation
;
2207 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
2209 if (r300
->radeon
.sarea
->tiling_enabled
) {
2210 /* Turn off when clearing buffers ? */
2211 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_TILE_ENABLE
;
2213 if (ctx
->Visual
.depthBits
== 24)
2214 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_MICROTILE_ENABLE
;
2217 r300
->hw
.unk4F28
.cmd
[1] = 0;
2219 r300
->hw
.unk4F30
.cmd
[1] = 0;
2220 r300
->hw
.unk4F30
.cmd
[2] = 0;
2222 r300
->hw
.unk4F44
.cmd
[1] = 0;
2224 r300
->hw
.unk4F54
.cmd
[1] = 0;
2227 ((drm_r300_cmd_header_t
*)r300
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2228 for(i
= 1; i
< R300_VPI_CMDSIZE
; i
+= 4) {
2230 r300
->hw
.vpi
.cmd
[i
+0] = VP_OUT(ADD
,TMP
,0,XYZW
);
2231 r300
->hw
.vpi
.cmd
[i
+1] = VP_IN(TMP
,0);
2232 r300
->hw
.vpi
.cmd
[i
+2] = VP_ZERO();
2233 r300
->hw
.vpi
.cmd
[i
+3] = VP_ZERO();
2236 ((drm_r300_cmd_header_t
*)r300
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2237 for(i
= 1; i
< R300_VPP_CMDSIZE
; ++i
)
2238 r300
->hw
.vpp
.cmd
[i
] = 0;
2241 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2242 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2243 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2244 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2247 r300
->hw
.all_dirty
= GL_TRUE
;
2253 * Calculate initial hardware state and register state functions.
2254 * Assumes that the command buffer and state atoms have been
2255 * initialized already.
2257 void r300InitState(r300ContextPtr r300
)
2259 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2262 radeonInitState(&r300
->radeon
);
2264 switch (ctx
->Visual
.depthBits
) {
2266 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2267 depth_fmt
= R300_DEPTH_FORMAT_16BIT_INT_Z
;
2268 r300
->state
.stencil
.clear
= 0x00000000;
2271 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2272 depth_fmt
= R300_DEPTH_FORMAT_24BIT_INT_Z
;
2273 r300
->state
.stencil
.clear
= 0x00ff0000;
2276 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2277 ctx
->Visual
.depthBits
);
2281 /* Only have hw stencil when depth buffer is 24 bits deep */
2282 r300
->state
.stencil
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2283 ctx
->Visual
.depthBits
== 24);
2285 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2287 r300ResetHwState(r300
);
2290 static void r300RenderMode( GLcontext
*ctx
, GLenum mode
)
2292 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2298 * Initialize driver's state callback functions
2300 void r300InitStateFuncs(struct dd_function_table
* functions
)
2302 radeonInitStateFuncs(functions
);
2304 functions
->UpdateState
= r300InvalidateState
;
2305 functions
->AlphaFunc
= r300AlphaFunc
;
2306 functions
->BlendColor
= r300BlendColor
;
2307 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2308 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2309 functions
->Enable
= r300Enable
;
2310 functions
->ColorMask
= r300ColorMask
;
2311 functions
->DepthFunc
= r300DepthFunc
;
2312 functions
->DepthMask
= r300DepthMask
;
2313 functions
->CullFace
= r300CullFace
;
2314 functions
->Fogfv
= r300Fogfv
;
2315 functions
->FrontFace
= r300FrontFace
;
2316 functions
->ShadeModel
= r300ShadeModel
;
2318 /* Stencil related */
2319 functions
->ClearStencil
= r300ClearStencil
;
2320 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2321 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2322 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2324 /* Viewport related */
2325 functions
->Viewport
= r300Viewport
;
2326 functions
->DepthRange
= r300DepthRange
;
2327 functions
->PointSize
= r300PointSize
;
2328 functions
->LineWidth
= r300LineWidth
;
2330 functions
->PolygonOffset
= r300PolygonOffset
;
2331 functions
->PolygonMode
= r300PolygonMode
;
2333 functions
->RenderMode
= r300RenderMode
;