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 0x4f14
332 if depth test is not enabled it should be 0x00000000
333 if depth is enabled and alpha not it should be 0x00000001
334 if depth and alpha is enabled it should be 0x00000000
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] = 0x00000000;
343 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
)
345 r300
->hw
.unk4F10
.cmd
[2] = 0x00000001;
347 /* disable early Z */
348 r300
->hw
.unk4F10
.cmd
[2] = 0x00000000;
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 WARN_ONCE("TODO - double side stencil !\n");
513 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
514 R300_RB3D_STENCIL_ENABLE
;
516 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
517 ~R300_RB3D_STENCIL_ENABLE
;
521 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
527 r300UpdateCulling(ctx
);
530 case GL_POLYGON_OFFSET_POINT
:
531 case GL_POLYGON_OFFSET_LINE
:
534 case GL_POLYGON_OFFSET_FILL
:
535 R300_STATECHANGE(r300
, unk42B4
);
537 r300
->hw
.unk42B4
.cmd
[1] |= (3<<0);
539 r300
->hw
.unk42B4
.cmd
[1] &= ~(3<<0);
543 radeonEnable(ctx
, cap
, state
);
549 static void r300UpdatePolygonMode(GLcontext
*ctx
)
551 r300ContextPtr r300
= R300_CONTEXT(ctx
);
554 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
555 ctx
->Polygon
.BackMode
!= GL_FILL
) {
558 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
559 f
= ctx
->Polygon
.FrontMode
;
560 b
= ctx
->Polygon
.BackMode
;
562 f
= ctx
->Polygon
.BackMode
;
563 b
= ctx
->Polygon
.FrontMode
;
566 hw_mode
|= R300_PM_ENABLED
;
570 hw_mode
|= R300_PM_FRONT_LINE
;
572 case GL_POINT
: /* noop */
573 hw_mode
|= R300_PM_FRONT_POINT
;
576 hw_mode
|= R300_PM_FRONT_FILL
;
582 hw_mode
|= R300_PM_BACK_LINE
;
584 case GL_POINT
: /* noop */
585 hw_mode
|= R300_PM_BACK_POINT
;
588 hw_mode
|= R300_PM_BACK_FILL
;
593 if (r300
->hw
.unk4288
.cmd
[1] != hw_mode
) {
594 R300_STATECHANGE(r300
, unk4288
);
595 r300
->hw
.unk4288
.cmd
[1] = hw_mode
;
600 * Change the culling mode.
602 * \note Mesa already filters redundant calls to this function.
604 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
608 r300UpdateCulling(ctx
);
613 * Change the polygon orientation.
615 * \note Mesa already filters redundant calls to this function.
617 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
621 r300UpdateCulling(ctx
);
622 r300UpdatePolygonMode(ctx
);
627 * Change the depth testing function.
629 * \note Mesa already filters redundant calls to this function.
631 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
639 * Enable/Disable depth writing.
641 * \note Mesa already filters redundant calls to this function.
643 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
651 * Handle glColorMask()
653 static void r300ColorMask(GLcontext
* ctx
,
654 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
656 r300ContextPtr r300
= R300_CONTEXT(ctx
);
657 int mask
= (r
? R300_COLORMASK0_R
: 0) |
658 (g
? R300_COLORMASK0_G
: 0) |
659 (b
? R300_COLORMASK0_B
: 0) |
660 (a
? R300_COLORMASK0_A
: 0);
662 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
663 R300_STATECHANGE(r300
, cmk
);
664 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
668 /* =============================================================
671 static void r300Fogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
673 r300ContextPtr r300
= R300_CONTEXT(ctx
);
674 union { int i
; float f
; } fogScale
, fogStart
;
678 fogScale
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
];
679 fogStart
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_START
];
683 if (!ctx
->Fog
.Enabled
)
685 switch (ctx
->Fog
.Mode
) {
687 R300_STATECHANGE(r300
, fogs
);
688 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
689 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_LINEAR
;
691 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
696 fogScale
.f
= 1.0 / (ctx
->Fog
.End
-ctx
->Fog
.Start
);
697 fogStart
.f
= -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-ctx
->Fog
.Start
);
701 R300_STATECHANGE(r300
, fogs
);
702 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
703 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_EXP
;
704 fogScale
.f
= 0.0933*ctx
->Fog
.Density
;
708 R300_STATECHANGE(r300
, fogs
);
709 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
710 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_EXP2
;
711 fogScale
.f
= 0.3*ctx
->Fog
.Density
;
718 switch (ctx
->Fog
.Mode
) {
720 fogScale
.f
= 0.0933*ctx
->Fog
.Density
;
724 fogScale
.f
= 0.3*ctx
->Fog
.Density
;
732 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
733 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
738 fogScale
.f
= 1.0 / (ctx
->Fog
.End
-ctx
->Fog
.Start
);
739 fogStart
.f
= -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-ctx
->Fog
.Start
);
744 R300_STATECHANGE(r300
, fogc
);
745 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] = (GLuint
) (ctx
->Fog
.Color
[0]*1023.0F
) & 0x3FF;
746 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] = (GLuint
) (ctx
->Fog
.Color
[1]*1023.0F
) & 0x3FF;
747 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] = (GLuint
) (ctx
->Fog
.Color
[2]*1023.0F
) & 0x3FF;
749 case GL_FOG_COORD_SRC
:
755 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
756 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
757 R300_STATECHANGE(r300
, fogp
);
758 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
759 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
763 /* =============================================================
766 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
768 r300ContextPtr r300
= R300_CONTEXT(ctx
);
770 size
= ctx
->Point
._Size
;
772 R300_STATECHANGE(r300
, ps
);
773 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
774 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
775 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
778 /* =============================================================
781 static void r300LineWidth(GLcontext
*ctx
, GLfloat widthf
)
783 r300ContextPtr r300
= R300_CONTEXT(ctx
);
785 widthf
= ctx
->Line
._Width
;
787 R300_STATECHANGE(r300
, lcntl
);
788 r300
->hw
.lcntl
.cmd
[1] = (int)(widthf
* 6.0);
789 r300
->hw
.lcntl
.cmd
[1] |= R300_LINE_CNT_VE
;
792 static void r300PolygonMode(GLcontext
*ctx
, GLenum face
, GLenum mode
)
797 r300UpdatePolygonMode(ctx
);
800 /* =============================================================
804 static int translate_stencil_op(int op
)
812 return R300_ZS_REPLACE
;
817 case GL_INCR_WRAP_EXT
:
818 return R300_ZS_INCR_WRAP
;
819 case GL_DECR_WRAP_EXT
:
820 return R300_ZS_DECR_WRAP
;
822 return R300_ZS_INVERT
;
824 WARN_ONCE("Do not know how to translate stencil op");
830 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
832 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
834 R300_STATECHANGE(rmesa
, unk4274
);
837 rmesa
->hw
.unk4274
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
840 rmesa
->hw
.unk4274
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
847 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
848 GLenum func
, GLint ref
, GLuint mask
)
850 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
851 GLuint refmask
= (((ctx
->Stencil
.Ref
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
852 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
856 R300_STATECHANGE(rmesa
, zs
);
858 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(
859 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
)
860 | (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
862 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &= ~((R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
863 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
865 flag
= translate_func(ctx
->Stencil
.Function
[0]);
867 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= (flag
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
)
868 | (flag
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
869 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
872 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
874 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
876 R300_STATECHANGE(rmesa
, zs
);
877 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &= ~(R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
);
878 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= (ctx
->Stencil
.WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
;
882 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
, GLenum fail
,
883 GLenum zfail
, GLenum zpass
)
885 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
887 R300_STATECHANGE(rmesa
, zs
);
888 /* It is easier to mask what's left.. */
889 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
890 (R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
) |
891 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
892 (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
894 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
895 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
)
896 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
)
897 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
)
898 |(translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
899 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
900 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
903 static void r300ClearStencil(GLcontext
* ctx
, GLint s
)
905 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
907 rmesa
->state
.stencil
.clear
=
908 ((GLuint
) (ctx
->Stencil
.Clear
& 0xff) |
909 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
) |
910 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
));
913 /* =============================================================
914 * Window position and viewport transformation
918 * To correctly position primitives:
920 #define SUBPIXEL_X 0.125
921 #define SUBPIXEL_Y 0.125
923 void r300UpdateWindow(GLcontext
* ctx
)
925 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
926 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
927 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
928 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
929 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
931 GLfloat sx
= v
[MAT_SX
];
932 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
933 GLfloat sy
= -v
[MAT_SY
];
934 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
935 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
936 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
938 R300_FIREVERTICES(rmesa
);
939 R300_STATECHANGE(rmesa
, vpt
);
941 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
942 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
943 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
944 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
945 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
946 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
949 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
950 GLsizei width
, GLsizei height
)
952 /* Don't pipeline viewport changes, conflict with window offset
953 * setting below. Could apply deltas to rescue pipelined viewport
954 * values, or keep the originals hanging around.
956 r300UpdateWindow(ctx
);
959 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
961 r300UpdateWindow(ctx
);
964 void r300UpdateViewportOffset( GLcontext
*ctx
)
966 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
967 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
)rmesa
)->dri
.drawable
;
968 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
969 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
970 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
972 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
973 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
975 if ( rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
976 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
))
978 /* Note: this should also modify whatever data the context reset
981 R300_STATECHANGE( rmesa
, vpt
);
982 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
983 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
987 radeonUpdateScissor( ctx
);
991 * Tell the card where to render (offset, pitch).
992 * Effected by glDrawBuffer, etc
995 r300UpdateDrawBuffer(GLcontext
*ctx
)
997 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
998 r300ContextPtr r300
= rmesa
;
999 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1000 driRenderbuffer
*drb
;
1002 if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
) {
1004 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
1006 else if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_BACK_LEFT
) {
1008 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1011 /* drawing to multiple buffers, or none */
1016 assert(drb
->flippedPitch
);
1019 R300_STATECHANGE( rmesa
, cb
);
1021 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = drb
->flippedOffset
+ //r300->radeon.state.color.drawOffset +
1022 r300
->radeon
.radeonScreen
->fbLocation
;
1023 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = drb
->flippedPitch
;//r300->radeon.state.color.drawPitch;
1025 if (r300
->radeon
.radeonScreen
->cpp
== 4)
1026 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
1028 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
1030 if (r300
->radeon
.sarea
->tiling_enabled
)
1031 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
1033 R200_STATECHANGE( rmesa
, ctx
);
1035 /* Note: we used the (possibly) page-flipped values */
1036 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
1037 = ((drb
->flippedOffset
+ rmesa
->r200Screen
->fbLocation
)
1038 & R200_COLOROFFSET_MASK
);
1039 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
1041 if (rmesa
->sarea
->tiling_enabled
) {
1042 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |= R200_COLOR_TILE_ENABLE
;
1047 static void r300FetchStateParameter(GLcontext
*ctx
, const enum state_index state
[],
1050 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1054 case STATE_INTERNAL
:
1057 case STATE_R300_WINDOW_DIMENSION
:
1058 value
[0] = r300
->radeon
.dri
.drawable
->w
; /* width */
1059 value
[1] = r300
->radeon
.dri
.drawable
->h
; /* height */
1060 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1061 value
[3] = 1.0F
; /* not used */
1070 * Update R300's own internal state parameters.
1071 * For now just STATE_R300_WINDOW_DIMENSION
1073 static void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1075 struct r300_vertex_program_cont
*vpc
;
1076 struct gl_program_parameter_list
*paramList
;
1079 if(!(new_state
& (_NEW_BUFFERS
|_NEW_PROGRAM
)))
1082 vpc
= (struct r300_vertex_program_cont
*)ctx
->VertexProgram
._Current
;
1086 paramList
= vpc
->mesa_program
.Base
.Parameters
;
1091 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1092 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
){
1093 r300FetchStateParameter(ctx
,
1094 paramList
->Parameters
[i
].StateIndexes
,
1095 paramList
->ParameterValues
[i
]);
1100 /* =============================================================
1103 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1105 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1106 GLfloat constant
= units
;
1108 switch (ctx
->Visual
.depthBits
) {
1119 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1121 R300_STATECHANGE(rmesa
, zbs
);
1122 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1123 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1124 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1125 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1128 /* Routing and texture-related */
1131 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1132 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1133 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1134 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1135 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1136 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1137 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1138 * combinations where only one of them is nearest.
1140 static unsigned long gen_fixed_filter(unsigned long f
)
1142 unsigned long mag
, min
, needs_fixing
=0;
1145 /* We ignore MIRROR bit so we dont have to do everything twice */
1146 if((f
& ((7-1) << R300_TX_WRAP_S_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)){
1149 if((f
& ((7-1) << R300_TX_WRAP_T_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)){
1152 if((f
& ((7-1) << R300_TX_WRAP_Q_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_Q_SHIFT
)){
1159 mag
=f
& R300_TX_MAG_FILTER_MASK
;
1160 min
=f
& R300_TX_MIN_FILTER_MASK
;
1162 /* TODO: Check for anisto filters too */
1163 if((mag
!= R300_TX_MAG_FILTER_NEAREST
) && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1166 /* r300 cant handle these modes hence we force nearest to linear */
1167 if((mag
== R300_TX_MAG_FILTER_NEAREST
) && (min
!= R300_TX_MIN_FILTER_NEAREST
)){
1168 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1169 f
|= R300_TX_MAG_FILTER_LINEAR
;
1173 if((min
== R300_TX_MIN_FILTER_NEAREST
) && (mag
!= R300_TX_MAG_FILTER_NEAREST
)){
1174 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1175 f
|= R300_TX_MIN_FILTER_LINEAR
;
1179 /* Both are nearest */
1180 if(needs_fixing
& 1){
1181 f
&= ~((7-1) << R300_TX_WRAP_S_SHIFT
);
1182 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1184 if(needs_fixing
& 2){
1185 f
&= ~((7-1) << R300_TX_WRAP_T_SHIFT
);
1186 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1188 if(needs_fixing
& 4){
1189 f
&= ~((7-1) << R300_TX_WRAP_Q_SHIFT
);
1190 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_Q_SHIFT
;
1195 void r300_setup_textures(GLcontext
*ctx
)
1198 struct r300_tex_obj
*t
;
1199 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1201 int last_hw_tmu
=-1; /* -1 translates into no setup costs for fields */
1202 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1 };
1203 struct r300_fragment_program
*rp
=
1204 (struct r300_fragment_program
*)
1205 (char *)ctx
->FragmentProgram
._Current
;
1207 R300_STATECHANGE(r300
, txe
);
1208 R300_STATECHANGE(r300
, tex
.filter
);
1209 R300_STATECHANGE(r300
, tex
.unknown1
);
1210 R300_STATECHANGE(r300
, tex
.size
);
1211 R300_STATECHANGE(r300
, tex
.format
);
1212 R300_STATECHANGE(r300
, tex
.pitch
);
1213 R300_STATECHANGE(r300
, tex
.offset
);
1214 R300_STATECHANGE(r300
, tex
.unknown4
);
1215 R300_STATECHANGE(r300
, tex
.border_color
);
1217 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
]=0x0;
1219 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1220 if (RADEON_DEBUG
& DEBUG_STATE
)
1221 fprintf(stderr
, "mtu=%d\n", mtu
);
1223 if(mtu
> R300_MAX_TEXTURE_UNITS
) {
1224 fprintf(stderr
, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1225 mtu
, R300_MAX_TEXTURE_UNITS
);
1229 /* We cannot let disabled tmu offsets pass DRM */
1230 for(i
=0; i
< mtu
; i
++) {
1231 if(TMU_ENABLED(ctx
, i
)) {
1233 #if 0 /* Enables old behaviour */
1236 tmu_mappings
[i
] = hw_tmu
;
1238 t
=r300
->state
.texture
.unit
[i
].texobj
;
1240 if((t
->format
& 0xffffff00)==0xffffff00) {
1241 WARN_ONCE("unknown texture format (entry %x) encountered. Help me !\n", t
->format
& 0xff);
1244 if (RADEON_DEBUG
& DEBUG_STATE
)
1245 fprintf(stderr
, "Activating texture unit %d\n", i
);
1247 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1249 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = gen_fixed_filter(t
->filter
) | (hw_tmu
<< 28);
1250 /* Currently disabled! */
1251 r300
->hw
.tex
.unknown1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0; //0x20501f80;
1252 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->size
;
1253 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->format
;
1254 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->pitch_reg
;
1255 r300
->hw
.tex
.offset
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->offset
;
1257 if(t
->offset
& R300_TXO_MACRO_TILE
) {
1258 WARN_ONCE("macro tiling enabled!\n");
1261 if(t
->offset
& R300_TXO_MICRO_TILE
) {
1262 WARN_ONCE("micro tiling enabled!\n");
1265 r300
->hw
.tex
.unknown4
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0;
1266 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->pp_border_color
;
1268 last_hw_tmu
= hw_tmu
;
1274 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FILTER_0
, last_hw_tmu
+ 1);
1275 r300
->hw
.tex
.unknown1
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1276 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1277 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1278 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_PITCH_0
, last_hw_tmu
+ 1);
1279 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1280 r300
->hw
.tex
.unknown4
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1281 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1284 if (!rp
) /* should only happenen once, just after context is created */
1287 R300_STATECHANGE(r300
, fpt
);
1289 for(i
= 0; i
< rp
->tex
.length
; i
++){
1293 unit
= rp
->tex
.inst
[i
] >> R300_FPITX_IMAGE_SHIFT
;
1296 val
= rp
->tex
.inst
[i
];
1297 val
&= ~R300_FPITX_IMAGE_MASK
;
1299 assert(tmu_mappings
[unit
] >= 0);
1301 val
|= tmu_mappings
[unit
] << R300_FPITX_IMAGE_SHIFT
;
1302 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+i
] = val
;
1305 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] = cmdpacket0(R300_PFS_TEXI_0
, rp
->tex
.length
);
1307 if (RADEON_DEBUG
& DEBUG_STATE
)
1308 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n", r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1311 union r300_outputs_written
{
1312 GLuint vp_outputs
; /* hw_tcl_on */
1313 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1316 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1317 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1318 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1320 void r300_setup_rs_unit(GLcontext
*ctx
)
1322 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1323 /* I'm still unsure if these are needed */
1324 GLuint interp_magic
[8] = {
1334 union r300_outputs_written OutputsWritten
;
1336 int fp_reg
, high_rr
;
1337 int in_texcoords
, col_interp_nr
;
1341 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1343 RENDERINPUTS_COPY( OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1345 if (ctx
->FragmentProgram
._Current
)
1346 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1348 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1349 return; /* This should only ever happen once.. */
1352 R300_STATECHANGE(r300
, ri
);
1353 R300_STATECHANGE(r300
, rc
);
1354 R300_STATECHANGE(r300
, rr
);
1356 fp_reg
= in_texcoords
= col_interp_nr
= high_rr
= 0;
1358 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] = 0;
1360 if (InputsRead
& FRAG_BIT_WPOS
){
1361 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1362 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1365 if(i
== ctx
->Const
.MaxTextureUnits
){
1366 fprintf(stderr
, "\tno free texcoord found...\n");
1370 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1371 InputsRead
&= ~FRAG_BIT_WPOS
;
1374 for (i
=0;i
<ctx
->Const
.MaxTextureUnits
;i
++) {
1375 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+i
] = 0
1376 | R300_RS_INTERP_USED
1377 | (in_texcoords
<< R300_RS_INTERP_SRC_SHIFT
)
1380 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] = 0;
1381 if (InputsRead
& (FRAG_BIT_TEX0
<<i
)) {
1382 //assert(r300->state.texture.tc_count != 0);
1383 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] |=
1384 R300_RS_ROUTE_ENABLE
1385 | i
/* source INTERP */
1386 | (fp_reg
<< R300_RS_ROUTE_DEST_SHIFT
);
1389 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_TEX0
+i
, _TNL_ATTRIB_TEX(i
) )) {
1390 /* Passing invalid data here can lock the GPU. */
1391 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1392 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1395 InputsRead
&= ~(FRAG_BIT_TEX0
<<i
);
1398 /* Need to count all coords enabled at vof */
1399 if (R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_TEX0
+i
, _TNL_ATTRIB_TEX(i
) ))
1403 if (InputsRead
& FRAG_BIT_COL0
) {
1404 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1405 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1406 goto out
; /* FIXME */
1407 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1411 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1412 | R300_RS_ROUTE_0_COLOR
1413 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1414 InputsRead
&= ~FRAG_BIT_COL0
;
1419 if (InputsRead
& FRAG_BIT_COL1
) {
1420 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1421 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1425 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] |= R300_RS_ROUTE_1_UNKNOWN11
1426 | R300_RS_ROUTE_1_COLOR1
1427 | (fp_reg
++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT
);
1428 InputsRead
&= ~FRAG_BIT_COL1
;
1429 if (high_rr
< 1) high_rr
= 1;
1433 /* Need at least one. This might still lock as the values are undefined... */
1434 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1435 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1436 | R300_RS_ROUTE_0_COLOR
1437 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1441 r300
->hw
.rc
.cmd
[1] = 0
1442 | (in_texcoords
<< R300_RS_CNTL_TC_CNT_SHIFT
)
1443 | (col_interp_nr
<< R300_RS_CNTL_CI_CNT_SHIFT
)
1444 | R300_RS_CNTL_0_UNKNOWN_18
;
1446 assert(high_rr
>= 0);
1447 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R300_RS_ROUTE_0
, high_rr
+1);
1448 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1451 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1454 #define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
1456 #define bump_vpu_count(ptr, new_count) do{\
1457 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1458 int _nc=(new_count)/4; \
1459 assert(_nc < 256); \
1460 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1463 void static inline setup_vertex_shader_fragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1467 if(vsf
->length
==0)return;
1469 if(vsf
->length
& 0x3){
1470 fprintf(stderr
,"VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1474 switch((dest
>>8) & 0xf){
1476 R300_STATECHANGE(r300
, vpi
);
1477 for(i
=0;i
<vsf
->length
;i
++)
1478 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1479 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+4*(dest
& 0xff));
1483 R300_STATECHANGE(r300
, vpp
);
1484 for(i
=0;i
<vsf
->length
;i
++)
1485 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1486 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+4*(dest
& 0xff));
1489 R300_STATECHANGE(r300
, vps
);
1490 for(i
=0;i
<vsf
->length
;i
++)
1491 r300
->hw
.vps
.cmd
[1+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1492 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+4*(dest
& 0xff));
1495 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1500 void r300SetupVertexProgram(r300ContextPtr rmesa
);
1502 /* just a skeleton for now.. */
1504 /* Generate a vertex shader that simply transforms vertex and texture coordinates,
1505 while leaving colors intact. Nothing fancy (like lights)
1507 If implementing lights make a copy first, so it is easy to switch between the two versions */
1508 static void r300GenerateSimpleVertexShader(r300ContextPtr r300
)
1513 /* Allocate parameters */
1514 r300
->state
.vap_param
.transform_offset
=0x0; /* transform matrix */
1515 r300
->state
.vertex_shader
.param_offset
=0x0;
1516 r300
->state
.vertex_shader
.param_count
=0x4; /* 4 vector values - 4x4 matrix */
1518 r300
->state
.vertex_shader
.program_start
=0x0;
1519 r300
->state
.vertex_shader
.unknown_ptr1
=0x4; /* magic value ? */
1520 r300
->state
.vertex_shader
.program_end
=0x0;
1522 r300
->state
.vertex_shader
.unknown_ptr2
=0x0; /* magic value */
1523 r300
->state
.vertex_shader
.unknown_ptr3
=0x4; /* magic value */
1525 /* Initialize matrix and vector parameters.. these should really be restructured */
1526 /* TODO: fix vertex_shader structure */
1527 r300
->state
.vertex_shader
.matrix
[0].length
=16;
1528 r300
->state
.vertex_shader
.matrix
[1].length
=0;
1529 r300
->state
.vertex_shader
.matrix
[2].length
=0;
1530 r300
->state
.vertex_shader
.vector
[0].length
=0;
1531 r300
->state
.vertex_shader
.vector
[1].length
=0;
1532 r300
->state
.vertex_shader
.unknown1
.length
=0;
1533 r300
->state
.vertex_shader
.unknown2
.length
=0;
1535 #define WRITE_OP(oper,source1,source2,source3) {\
1536 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].op=(oper); \
1537 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src1=(source1); \
1538 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src2=(source2); \
1539 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src3=(source3); \
1540 r300->state.vertex_shader.program_end++; \
1543 /* Multiply vertex coordinates with transform matrix */
1546 EASY_VSF_OP(MUL
, 0, ALL
, TMP
),
1549 EASY_VSF_SOURCE(0, W
, W
, W
, W
, NONE
, NONE
)
1553 EASY_VSF_OP(MUL
, 1, ALL
, RESULT
),
1560 EASY_VSF_OP(MAD
, 0, ALL
, TMP
),
1567 EASY_VSF_OP(MAD
, 0, ALL
, TMP
),
1574 EASY_VSF_OP(MAD
, 0, ALL
, RESULT
),
1581 for (i
= VERT_ATTRIB_COLOR1
; i
< VERT_ATTRIB_MAX
; i
++)
1582 if (r300
->state
.sw_tcl_inputs
[i
] != -1) {
1584 EASY_VSF_OP(MUL
, o_reg
++ /* 2+i */, ALL
, RESULT
),
1585 VSF_REG(r300
->state
.sw_tcl_inputs
[i
]),
1586 VSF_ATTR_UNITY(r300
->state
.sw_tcl_inputs
[i
]),
1587 VSF_UNITY(r300
->state
.sw_tcl_inputs
[i
])
1592 r300
->state
.vertex_shader
.program_end
--; /* r300 wants program length to be one more - no idea why */
1593 r300
->state
.vertex_shader
.program
.length
=(r300
->state
.vertex_shader
.program_end
+1)*4;
1595 r300
->state
.vertex_shader
.unknown_ptr1
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1596 r300
->state
.vertex_shader
.unknown_ptr2
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1597 r300
->state
.vertex_shader
.unknown_ptr3
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1602 void r300SetupVertexShader(r300ContextPtr rmesa
)
1604 GLcontext
* ctx
= rmesa
->radeon
.glCtx
;
1606 /* Reset state, in case we don't use something */
1607 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1608 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1609 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1611 /* Not sure why this doesnt work...
1612 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
1613 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. */
1614 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
1615 if(hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
){
1616 r300SetupVertexProgram(rmesa
);
1620 /* This needs to be replaced by vertex shader generation code */
1624 /* textures enabled ? */
1625 if(rmesa
->state
.texture
.tc_count
>0){
1626 rmesa
->state
.vertex_shader
=SINGLE_TEXTURE_VERTEX_SHADER
;
1628 rmesa
->state
.vertex_shader
=FLAT_COLOR_VERTEX_SHADER
;
1632 r300GenerateSimpleVertexShader(rmesa
);
1634 rmesa
->state
.vertex_shader
.matrix
[0].length
=16;
1635 memcpy(rmesa
->state
.vertex_shader
.matrix
[0].body
.f
, ctx
->_ModelProjectMatrix
.m
, 16*4);
1637 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(rmesa
->state
.vertex_shader
.program
));
1639 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX0
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1641 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX1
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1642 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX2
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1644 setup_vertex_shader_fragment(rmesa
, VSF_DEST_VECTOR0
, &(rmesa
->state
.vertex_shader
.vector
[0]));
1645 setup_vertex_shader_fragment(rmesa
, VSF_DEST_VECTOR1
, &(rmesa
->state
.vertex_shader
.vector
[1]));
1649 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
, &(rmesa
->state
.vertex_shader
.unknown1
));
1650 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
, &(rmesa
->state
.vertex_shader
.unknown2
));
1653 R300_STATECHANGE(rmesa
, pvs
);
1654 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
]=(rmesa
->state
.vertex_shader
.program_start
<< R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1655 | (rmesa
->state
.vertex_shader
.unknown_ptr1
<< R300_PVS_CNTL_1_POS_END_SHIFT
)
1656 | (rmesa
->state
.vertex_shader
.program_end
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1657 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
]=(rmesa
->state
.vertex_shader
.param_offset
<< R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1658 | (rmesa
->state
.vertex_shader
.param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1659 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
]=(rmesa
->state
.vertex_shader
.unknown_ptr2
<< R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1660 | (rmesa
->state
.vertex_shader
.unknown_ptr3
<< 0);
1662 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1663 so I leave it as a reminder */
1665 reg_start(R300_VAP_PVS_WAITIDLE
,0);
1670 void r300SetupVertexProgram(r300ContextPtr rmesa
)
1672 GLcontext
* ctx
= rmesa
->radeon
.glCtx
;
1675 struct r300_vertex_program
*prog
=(struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1678 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1679 R300_STATECHANGE(rmesa
, vpp
);
1680 param_count
= r300VertexProgUpdateParams(ctx
, (struct r300_vertex_program_cont
*)ctx
->VertexProgram
._Current
/*prog*/, (float *)&rmesa
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
]);
1681 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
1684 /* Reset state, in case we don't use something */
1685 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1686 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1688 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(prog
->program
));
1691 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
, &(rmesa
->state
.vertex_shader
.unknown1
));
1692 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
, &(rmesa
->state
.vertex_shader
.unknown2
));
1695 inst_count
=prog
->program
.length
/4 - 1;
1697 R300_STATECHANGE(rmesa
, pvs
);
1698 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
]=(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1699 | (inst_count
/*pos_end*/ << R300_PVS_CNTL_1_POS_END_SHIFT
)
1700 | (inst_count
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1701 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
]=(0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1702 | (param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1703 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
]=(0/*rmesa->state.vertex_shader.unknown_ptr2*/ << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1704 | (inst_count
/*rmesa->state.vertex_shader.unknown_ptr3*/ << 0);
1706 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1707 so I leave it as a reminder */
1709 reg_start(R300_VAP_PVS_WAITIDLE
,0);
1714 extern void _tnl_UpdateFixedFunctionProgram( GLcontext
*ctx
);
1716 extern int future_hw_tcl_on
;
1717 void r300UpdateShaders(r300ContextPtr rmesa
)
1720 struct r300_vertex_program
*vp
;
1723 ctx
= rmesa
->radeon
.glCtx
;
1725 if (rmesa
->NewGLState
&& hw_tcl_on
) {
1726 rmesa
->NewGLState
= 0;
1728 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1729 rmesa
->temp_attrib
[i
] = TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
1730 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] = &rmesa
->dummy_attrib
[i
];
1733 _tnl_UpdateFixedFunctionProgram(ctx
);
1735 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1736 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] = rmesa
->temp_attrib
[i
];
1739 r300_select_vertex_shader(rmesa
);
1740 vp
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1741 /*if (vp->translated == GL_FALSE)
1742 r300_translate_vertex_shader(vp);*/
1743 if (vp
->translated
== GL_FALSE
) {
1744 fprintf(stderr
, "Failing back to sw-tcl\n");
1745 hw_tcl_on
= future_hw_tcl_on
= 0;
1746 r300ResetHwState(rmesa
);
1750 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
1755 void r300UpdateShaderStates(r300ContextPtr rmesa
)
1758 ctx
= rmesa
->radeon
.glCtx
;
1761 r300UpdateTextureState(ctx
);
1764 r300SetupPixelShader(rmesa
);
1765 r300_setup_textures(ctx
);
1767 r300SetupVertexShader(rmesa
);
1768 r300_setup_rs_unit(ctx
);
1771 /* This is probably wrong for some values, I need to test this
1772 * some more. Range checking would be a good idea also..
1774 * But it works for most things. I'll fix it later if someone
1775 * else with a better clue doesn't
1777 static unsigned int r300PackFloat24(float f
)
1781 unsigned int float24
= 0;
1783 if (f
== 0.0) return 0;
1785 mantissa
= frexpf(f
, &exponent
);
1790 mantissa
= mantissa
* -1.0;
1792 /* Handle exponent, bias of 63 */
1794 float24
|= (exponent
<< 16);
1795 /* Kill 7 LSB of mantissa */
1796 float24
|= (r300PackFloat32(mantissa
) & 0x7FFFFF) >> 7;
1801 void r300SetupPixelShader(r300ContextPtr rmesa
)
1803 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1804 struct r300_fragment_program
*rp
=
1805 (struct r300_fragment_program
*)
1806 (char *)ctx
->FragmentProgram
._Current
;
1809 if (!rp
) /* should only happenen once, just after context is created */
1812 r300_translate_fragment_shader(rp
);
1813 if (!rp
->translated
) {
1814 fprintf(stderr
, "%s: No valid fragment shader, exiting\n", __func__
);
1818 #define OUTPUT_FIELD(st, reg, field) \
1819 R300_STATECHANGE(rmesa, st); \
1820 for(i=0;i<=rp->alu_end;i++) \
1821 rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=rp->alu.inst[i].field;\
1822 rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmdpacket0(reg, rp->alu_end+1);
1824 OUTPUT_FIELD(fpi
[0], R300_PFS_INSTR0_0
, inst0
);
1825 OUTPUT_FIELD(fpi
[1], R300_PFS_INSTR1_0
, inst1
);
1826 OUTPUT_FIELD(fpi
[2], R300_PFS_INSTR2_0
, inst2
);
1827 OUTPUT_FIELD(fpi
[3], R300_PFS_INSTR3_0
, inst3
);
1830 R300_STATECHANGE(rmesa
, fp
);
1831 /* I just want to say, the way these nodes are stored.. weird.. */
1832 for (i
=0,k
=(4-(rp
->cur_node
+1));i
<4;i
++,k
++) {
1833 if (i
<(rp
->cur_node
+1)) {
1834 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+k
]=
1835 (rp
->node
[i
].alu_offset
<< R300_PFS_NODE_ALU_OFFSET_SHIFT
)
1836 | (rp
->node
[i
].alu_end
<< R300_PFS_NODE_ALU_END_SHIFT
)
1837 | (rp
->node
[i
].tex_offset
<< R300_PFS_NODE_TEX_OFFSET_SHIFT
)
1838 | (rp
->node
[i
].tex_end
<< R300_PFS_NODE_TEX_END_SHIFT
)
1839 | rp
->node
[i
].flags
; /* ( (k==3) ? R300_PFS_NODE_LAST_NODE : 0); */
1841 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+(3-i
)] = 0;
1846 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
]=
1848 | (rp
->first_node_has_tex
<<3);
1850 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
]=rp
->max_temp_idx
;
1852 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
]=
1853 (rp
->alu_offset
<< R300_PFS_CNTL_ALU_OFFSET_SHIFT
)
1854 | (rp
->alu_end
<< R300_PFS_CNTL_ALU_END_SHIFT
)
1855 | (rp
->tex_offset
<< R300_PFS_CNTL_TEX_OFFSET_SHIFT
)
1856 | (rp
->tex_end
<< R300_PFS_CNTL_TEX_END_SHIFT
);
1858 R300_STATECHANGE(rmesa
, fpp
);
1859 for(i
=0;i
<rp
->const_nr
;i
++){
1860 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+0]=r300PackFloat24(rp
->constant
[i
][0]);
1861 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+1]=r300PackFloat24(rp
->constant
[i
][1]);
1862 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+2]=r300PackFloat24(rp
->constant
[i
][2]);
1863 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+3]=r300PackFloat24(rp
->constant
[i
][3]);
1865 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
]=cmdpacket0(R300_PFS_PARAM_0_X
, rp
->const_nr
*4);
1869 * Called by Mesa after an internal state update.
1871 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
1873 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1875 _swrast_InvalidateState(ctx
, new_state
);
1876 _swsetup_InvalidateState(ctx
, new_state
);
1877 _vbo_InvalidateState(ctx
, new_state
);
1878 _tnl_InvalidateState(ctx
, new_state
);
1879 _ae_invalidate_state(ctx
, new_state
);
1881 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
1882 r300UpdateDrawBuffer(ctx
);
1885 r300UpdateStateParameters(ctx
, new_state
);
1888 /* Go inefficiency! */
1889 r300ResetHwState(r300
);
1892 if(new_state
& _NEW_ARRAY
)
1893 r300
->state
.VB
.lock_uptodate
= GL_FALSE
;
1895 r300
->NewGLState
|= new_state
;
1899 * Completely recalculates hardware state based on the Mesa state.
1901 void r300ResetHwState(r300ContextPtr r300
)
1903 GLcontext
* ctx
= r300
->radeon
.glCtx
;
1905 if (RADEON_DEBUG
& DEBUG_STATE
)
1906 fprintf(stderr
, "%s\n", __FUNCTION__
);
1908 /* This is a place to initialize registers which
1909 have bitfields accessed by different functions
1910 and not all bits are used */
1912 /* initialize similiar to r200 */
1913 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] = 0;
1914 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] =
1915 (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
1916 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
) |
1917 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
) |
1918 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
) |
1919 (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
) |
1920 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
) |
1921 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
) |
1922 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
);
1923 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] = 0x00ffff00;
1926 /* go and compute register values from GL state */
1928 r300UpdateWindow(ctx
);
1931 ctx
->Color
.ColorMask
[RCOMP
],
1932 ctx
->Color
.ColorMask
[GCOMP
],
1933 ctx
->Color
.ColorMask
[BCOMP
],
1934 ctx
->Color
.ColorMask
[ACOMP
]);
1936 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
1937 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
1938 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
1941 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
1942 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
1943 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0], ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
1944 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0], ctx
->Stencil
.ZFailFunc
[0], ctx
->Stencil
.ZPassFunc
[0]);
1946 r300UpdateCulling(ctx
);
1948 r300UpdateTextureState(ctx
);
1950 // r300_setup_routing(ctx, GL_TRUE);
1952 #if 0 /* Done in prior to rendering */
1953 if(hw_tcl_on
== GL_FALSE
){
1954 r300EmitArrays(ctx
, GL_TRUE
); /* Just do the routing */
1955 r300_setup_textures(ctx
);
1956 r300_setup_rs_unit(ctx
);
1958 r300SetupVertexShader(r300
);
1959 r300SetupPixelShader(r300
);
1963 r300_set_blend_state(ctx
);
1965 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
1966 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
1968 /* Initialize magic registers
1969 TODO : learn what they really do, or get rid of
1970 those we don't have to touch */
1971 r300
->hw
.unk2080
.cmd
[1] = 0x0030045A; //0x0030065a /* Dangerous */
1973 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
1974 | R300_VPORT_X_OFFSET_ENA
1975 | R300_VPORT_Y_SCALE_ENA
1976 | R300_VPORT_Y_OFFSET_ENA
1977 | R300_VPORT_Z_SCALE_ENA
1978 | R300_VPORT_Z_OFFSET_ENA
1980 r300
->hw
.vte
.cmd
[2] = 0x00000008;
1982 r300
->hw
.unk2134
.cmd
[1] = 0x00FFFFFF;
1983 r300
->hw
.unk2134
.cmd
[2] = 0x00000000;
1984 if (_mesa_little_endian())
1985 r300
->hw
.unk2140
.cmd
[1] = 0x00000000;
1987 r300
->hw
.unk2140
.cmd
[1] = 0x00000002;
1989 #if 0 /* Done in setup routing */
1990 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[0].cmd
)->packet0
.count
= 1;
1991 r300
->hw
.vir
[0].cmd
[1] = 0x21030003;
1993 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[1].cmd
)->packet0
.count
= 1;
1994 r300
->hw
.vir
[1].cmd
[1] = 0xF688F688;
1996 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_0
] = 0x00000001;
1997 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_1
] = 0x00000405;
2000 r300
->hw
.unk21DC
.cmd
[1] = 0xAAAAAAAA;
2002 r300
->hw
.unk221C
.cmd
[1] = R300_221C_NORMAL
;
2004 r300
->hw
.unk2220
.cmd
[1] = r300PackFloat32(1.0);
2005 r300
->hw
.unk2220
.cmd
[2] = r300PackFloat32(1.0);
2006 r300
->hw
.unk2220
.cmd
[3] = r300PackFloat32(1.0);
2007 r300
->hw
.unk2220
.cmd
[4] = r300PackFloat32(1.0);
2009 /* what about other chips than r300 or rv350??? */
2010 if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
)
2011 r300
->hw
.unk2288
.cmd
[1] = R300_2288_R300
;
2013 r300
->hw
.unk2288
.cmd
[1] = R300_2288_RV350
;
2016 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_0
] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
2017 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
;
2018 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_1
] = 0; /* no textures */
2021 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] = 0;
2022 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] = 0;
2023 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] = 0;
2026 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2027 | R300_GB_LINE_STUFF_ENABLE
2028 | R300_GB_TRIANGLE_STUFF_ENABLE
/*| R300_GB_UNK31*/;
2030 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2031 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2032 if ((r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
) ||
2033 (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R350
))
2034 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2035 | R300_GB_TILE_PIPE_COUNT_R300
2036 | R300_GB_TILE_SIZE_16
;
2037 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
)
2038 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2039 | R300_GB_TILE_PIPE_COUNT_RV410
2040 | R300_GB_TILE_SIZE_16
;
2041 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
)
2042 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2043 | R300_GB_TILE_PIPE_COUNT_R420
2044 | R300_GB_TILE_SIZE_16
;
2046 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2047 | R300_GB_TILE_PIPE_COUNT_RV300
2048 | R300_GB_TILE_SIZE_16
;
2049 /* set to 0 when fog is disabled? */
2050 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2051 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = 0x00000000; /* No antialiasing */
2053 //r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
2055 r300
->hw
.unk4200
.cmd
[1] = r300PackFloat32(0.0);
2056 r300
->hw
.unk4200
.cmd
[2] = r300PackFloat32(0.0);
2057 r300
->hw
.unk4200
.cmd
[3] = r300PackFloat32(1.0);
2058 r300
->hw
.unk4200
.cmd
[4] = r300PackFloat32(1.0);
2060 r300
->hw
.unk4214
.cmd
[1] = 0x00050005;
2062 r300PointSize(ctx
, 0.0);
2064 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] = (6 << R300_POINTSIZE_X_SHIFT
) |
2065 (6 << R300_POINTSIZE_Y_SHIFT
);
2068 r300
->hw
.unk4230
.cmd
[1] = 0x18000006;
2069 r300
->hw
.unk4230
.cmd
[2] = 0x00020006;
2070 r300
->hw
.unk4230
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2072 r300LineWidth(ctx
, 0.0);
2074 r300
->hw
.unk4260
.cmd
[1] = 0;
2075 r300
->hw
.unk4260
.cmd
[2] = r300PackFloat32(0.0);
2076 r300
->hw
.unk4260
.cmd
[3] = r300PackFloat32(1.0);
2078 r300
->hw
.unk4274
.cmd
[1] = 0x00000002;
2079 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2080 r300
->hw
.unk4274
.cmd
[3] = 0x00000000;
2081 r300
->hw
.unk4274
.cmd
[4] = 0x00000000;
2083 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2084 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2085 r300
->hw
.unk4288
.cmd
[2] = 0x00000001;
2086 r300
->hw
.unk4288
.cmd
[3] = 0x00000000;
2087 r300
->hw
.unk42A0
.cmd
[1] = 0x00000000;
2089 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
, ctx
->Polygon
.OffsetUnits
);
2090 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2092 r300
->hw
.unk42C0
.cmd
[1] = 0x4B7FFFFF;
2093 r300
->hw
.unk42C0
.cmd
[2] = 0x00000000;
2096 r300
->hw
.unk43A4
.cmd
[1] = 0x0000001C;
2097 r300
->hw
.unk43A4
.cmd
[2] = 0x2DA49525;
2099 r300
->hw
.unk43E8
.cmd
[1] = 0x00FFFFFF;
2102 r300
->hw
.fp
.cmd
[R300_FP_CNTL0
] = 0;
2103 r300
->hw
.fp
.cmd
[R300_FP_CNTL1
] = 0;
2104 r300
->hw
.fp
.cmd
[R300_FP_CNTL2
] = 0;
2105 r300
->hw
.fp
.cmd
[R300_FP_NODE0
] = 0;
2106 r300
->hw
.fp
.cmd
[R300_FP_NODE1
] = 0;
2107 r300
->hw
.fp
.cmd
[R300_FP_NODE2
] = 0;
2108 r300
->hw
.fp
.cmd
[R300_FP_NODE3
] = 0;
2111 r300
->hw
.unk46A4
.cmd
[1] = 0x00001B01;
2112 r300
->hw
.unk46A4
.cmd
[2] = 0x00001B0F;
2113 r300
->hw
.unk46A4
.cmd
[3] = 0x00001B0F;
2114 r300
->hw
.unk46A4
.cmd
[4] = 0x00001B0F;
2115 r300
->hw
.unk46A4
.cmd
[5] = 0x00000001;
2118 for(i
= 1; i
<= 64; ++i
) {
2119 /* create NOP instructions */
2120 r300
->hw
.fpi
[0].cmd
[i
] = FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
));
2121 r300
->hw
.fpi
[1].cmd
[i
] = FP_SELC(0,XYZ
,NO
,FP_TMP(0),0,0);
2122 r300
->hw
.fpi
[2].cmd
[i
] = FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
));
2123 r300
->hw
.fpi
[3].cmd
[i
] = FP_SELA(0,W
,NO
,FP_TMP(0),0,0);
2126 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2127 ctx
->Driver
.Fogfv( ctx
, GL_FOG_MODE
, NULL
);
2128 ctx
->Driver
.Fogfv( ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2129 ctx
->Driver
.Fogfv( ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2130 ctx
->Driver
.Fogfv( ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2131 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2132 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2134 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
2135 r300
->hw
.unk4BD8
.cmd
[1] = 0;
2137 r300
->hw
.unk4E00
.cmd
[1] = 0;
2140 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = 0;
2141 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = 0;
2144 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2145 r300
->hw
.unk4E10
.cmd
[2] = 0;
2146 r300
->hw
.unk4E10
.cmd
[3] = 0;
2148 /* Again, r300ClearBuffer uses this */
2149 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = r300
->radeon
.state
.color
.drawOffset
+
2150 r300
->radeon
.radeonScreen
->fbLocation
;
2151 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.state
.color
.drawPitch
;
2153 if (r300
->radeon
.radeonScreen
->cpp
== 4)
2154 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
2156 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
2158 if (r300
->radeon
.sarea
->tiling_enabled
)
2159 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
2161 r300
->hw
.unk4E50
.cmd
[1] = 0;
2162 r300
->hw
.unk4E50
.cmd
[2] = 0;
2163 r300
->hw
.unk4E50
.cmd
[3] = 0;
2164 r300
->hw
.unk4E50
.cmd
[4] = 0;
2165 r300
->hw
.unk4E50
.cmd
[5] = 0;
2166 r300
->hw
.unk4E50
.cmd
[6] = 0;
2167 r300
->hw
.unk4E50
.cmd
[7] = 0;
2168 r300
->hw
.unk4E50
.cmd
[8] = 0;
2169 r300
->hw
.unk4E50
.cmd
[9] = 0;
2171 r300
->hw
.unk4E88
.cmd
[1] = 0;
2173 r300
->hw
.unk4EA0
.cmd
[1] = 0x00000000;
2174 r300
->hw
.unk4EA0
.cmd
[2] = 0xffffffff;
2176 switch (ctx
->Visual
.depthBits
) {
2178 r300
->hw
.unk4F10
.cmd
[1] = R300_DEPTH_FORMAT_16BIT_INT_Z
;
2181 r300
->hw
.unk4F10
.cmd
[1] = R300_DEPTH_FORMAT_24BIT_INT_Z
;
2184 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2185 ctx
->Visual
.depthBits
);
2190 //r300->hw.unk4F10.cmd[1] |= R300_DEPTH_FORMAT_UNK32;
2192 r300
->hw
.unk4F10
.cmd
[3] = 0x00000003;
2193 r300
->hw
.unk4F10
.cmd
[4] = 0x00000000;
2195 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
2196 r300
->radeon
.radeonScreen
->depthOffset
+
2197 r300
->radeon
.radeonScreen
->fbLocation
;
2198 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
2200 if (r300
->radeon
.sarea
->tiling_enabled
) {
2201 /* Turn off when clearing buffers ? */
2202 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_TILE_ENABLE
;
2204 if (ctx
->Visual
.depthBits
== 24)
2205 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_MICROTILE_ENABLE
;
2208 r300
->hw
.unk4F28
.cmd
[1] = 0;
2210 r300
->hw
.unk4F30
.cmd
[1] = 0;
2211 r300
->hw
.unk4F30
.cmd
[2] = 0;
2213 r300
->hw
.unk4F44
.cmd
[1] = 0;
2215 r300
->hw
.unk4F54
.cmd
[1] = 0;
2218 ((drm_r300_cmd_header_t
*)r300
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2219 for(i
= 1; i
< R300_VPI_CMDSIZE
; i
+= 4) {
2221 r300
->hw
.vpi
.cmd
[i
+0] = VP_OUT(ADD
,TMP
,0,XYZW
);
2222 r300
->hw
.vpi
.cmd
[i
+1] = VP_IN(TMP
,0);
2223 r300
->hw
.vpi
.cmd
[i
+2] = VP_ZERO();
2224 r300
->hw
.vpi
.cmd
[i
+3] = VP_ZERO();
2227 ((drm_r300_cmd_header_t
*)r300
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2228 for(i
= 1; i
< R300_VPP_CMDSIZE
; ++i
)
2229 r300
->hw
.vpp
.cmd
[i
] = 0;
2232 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2233 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2234 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2235 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2238 r300
->hw
.all_dirty
= GL_TRUE
;
2244 * Calculate initial hardware state and register state functions.
2245 * Assumes that the command buffer and state atoms have been
2246 * initialized already.
2248 void r300InitState(r300ContextPtr r300
)
2250 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2253 radeonInitState(&r300
->radeon
);
2255 switch (ctx
->Visual
.depthBits
) {
2257 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2258 depth_fmt
= R300_DEPTH_FORMAT_16BIT_INT_Z
;
2259 r300
->state
.stencil
.clear
= 0x00000000;
2262 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2263 depth_fmt
= R300_DEPTH_FORMAT_24BIT_INT_Z
;
2264 r300
->state
.stencil
.clear
= 0x00ff0000;
2267 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2268 ctx
->Visual
.depthBits
);
2272 /* Only have hw stencil when depth buffer is 24 bits deep */
2273 r300
->state
.stencil
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2274 ctx
->Visual
.depthBits
== 24);
2276 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2278 r300ResetHwState(r300
);
2281 static void r300RenderMode( GLcontext
*ctx
, GLenum mode
)
2283 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2289 * Initialize driver's state callback functions
2291 void r300InitStateFuncs(struct dd_function_table
* functions
)
2293 radeonInitStateFuncs(functions
);
2295 functions
->UpdateState
= r300InvalidateState
;
2296 functions
->AlphaFunc
= r300AlphaFunc
;
2297 functions
->BlendColor
= r300BlendColor
;
2298 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2299 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2300 functions
->Enable
= r300Enable
;
2301 functions
->ColorMask
= r300ColorMask
;
2302 functions
->DepthFunc
= r300DepthFunc
;
2303 functions
->DepthMask
= r300DepthMask
;
2304 functions
->CullFace
= r300CullFace
;
2305 functions
->Fogfv
= r300Fogfv
;
2306 functions
->FrontFace
= r300FrontFace
;
2307 functions
->ShadeModel
= r300ShadeModel
;
2309 /* Stencil related */
2310 functions
->ClearStencil
= r300ClearStencil
;
2311 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2312 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2313 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2315 /* Viewport related */
2316 functions
->Viewport
= r300Viewport
;
2317 functions
->DepthRange
= r300DepthRange
;
2318 functions
->PointSize
= r300PointSize
;
2319 functions
->LineWidth
= r300LineWidth
;
2321 functions
->PolygonOffset
= r300PolygonOffset
;
2322 functions
->PolygonMode
= r300PolygonMode
;
2324 functions
->RenderMode
= r300RenderMode
;