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
, blend_color
);
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
.blend_color
.cmd
[1] = r300PackColor(4, color
[3], color
[0],
84 * Calculate the hardware blend factor setting. This same function is used
85 * for source and destination of both alpha and RGB.
88 * The hardware register value for the specified blend factor. This value
89 * will need to be shifted into the correct position for either source or
93 * Since the two cases where source and destination are handled differently
94 * are essentially error cases, they should never happen. Determine if these
95 * cases can be removed.
97 static int blend_factor(GLenum factor
, GLboolean is_src
)
103 func
= R300_BLEND_GL_ZERO
;
106 func
= R300_BLEND_GL_ONE
;
109 func
= R300_BLEND_GL_DST_COLOR
;
111 case GL_ONE_MINUS_DST_COLOR
:
112 func
= R300_BLEND_GL_ONE_MINUS_DST_COLOR
;
115 func
= R300_BLEND_GL_SRC_COLOR
;
117 case GL_ONE_MINUS_SRC_COLOR
:
118 func
= R300_BLEND_GL_ONE_MINUS_SRC_COLOR
;
121 func
= R300_BLEND_GL_SRC_ALPHA
;
123 case GL_ONE_MINUS_SRC_ALPHA
:
124 func
= R300_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
127 func
= R300_BLEND_GL_DST_ALPHA
;
129 case GL_ONE_MINUS_DST_ALPHA
:
130 func
= R300_BLEND_GL_ONE_MINUS_DST_ALPHA
;
132 case GL_SRC_ALPHA_SATURATE
:
133 func
= (is_src
) ? R300_BLEND_GL_SRC_ALPHA_SATURATE
:
136 case GL_CONSTANT_COLOR
:
137 func
= R300_BLEND_GL_CONST_COLOR
;
139 case GL_ONE_MINUS_CONSTANT_COLOR
:
140 func
= R300_BLEND_GL_ONE_MINUS_CONST_COLOR
;
142 case GL_CONSTANT_ALPHA
:
143 func
= R300_BLEND_GL_CONST_ALPHA
;
145 case GL_ONE_MINUS_CONSTANT_ALPHA
:
146 func
= R300_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
149 fprintf(stderr
, "unknown blend factor %x\n", factor
);
150 func
= (is_src
) ? R300_BLEND_GL_ONE
: R300_BLEND_GL_ZERO
;
156 * Sets both the blend equation and the blend function.
157 * This is done in a single
158 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
159 * change the interpretation of the blend function.
160 * Also, make sure that blend function and blend equation are set to their
161 * default value if color blending is not enabled, since at least blend
162 * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results
163 * otherwise for unknown reasons.
166 /* helper function */
167 static void r300_set_blend_cntl(r300ContextPtr r300
, int func
, int eqn
, int cbits
, int funcA
, int eqnA
)
169 GLuint new_ablend
, new_cblend
;
172 fprintf(stderr
, "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n", eqnA
, funcA
, eqn
, func
, cbits
);
174 new_ablend
= eqnA
| funcA
;
175 new_cblend
= eqn
| func
;
177 /* Some blend factor combinations don't seem to work when the
178 * BLEND_NO_SEPARATE bit is set.
180 * Especially problematic candidates are the ONE_MINUS_* flags,
181 * but I can't see a real pattern.
184 if (new_ablend
== new_cblend
) {
185 new_cblend
|= R300_BLEND_NO_SEPARATE
;
190 if((new_ablend
!= r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]) ||
191 (new_cblend
!= r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
])) {
192 R300_STATECHANGE(r300
, bld
);
193 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]=new_ablend
;
194 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
]=new_cblend
;
199 static void r300_set_blend_state(GLcontext
* ctx
)
201 r300ContextPtr r300
= R300_CONTEXT(ctx
);
202 int func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
203 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
204 int eqn
= R300_COMB_FCN_ADD_CLAMP
;
205 int funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
206 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
207 int eqnA
= R300_COMB_FCN_ADD_CLAMP
;
209 if (RGBA_LOGICOP_ENABLED(ctx
) || !ctx
->Color
.BlendEnabled
) {
210 r300_set_blend_cntl(r300
,
216 func
= (blend_factor(ctx
->Color
.BlendSrcRGB
, GL_TRUE
) << R300_SRC_BLEND_SHIFT
) |
217 (blend_factor(ctx
->Color
.BlendDstRGB
, GL_FALSE
) << R300_DST_BLEND_SHIFT
);
219 switch (ctx
->Color
.BlendEquationRGB
) {
221 eqn
= R300_COMB_FCN_ADD_CLAMP
;
224 case GL_FUNC_SUBTRACT
:
225 eqn
= R300_COMB_FCN_SUB_CLAMP
;
228 case GL_FUNC_REVERSE_SUBTRACT
:
229 eqn
= R300_COMB_FCN_RSUB_CLAMP
;
233 eqn
= R300_COMB_FCN_MIN
;
234 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
235 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
239 eqn
= R300_COMB_FCN_MAX
;
240 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
241 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
246 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
247 __func__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
252 funcA
= (blend_factor(ctx
->Color
.BlendSrcA
, GL_TRUE
) << R300_SRC_BLEND_SHIFT
) |
253 (blend_factor(ctx
->Color
.BlendDstA
, GL_FALSE
) << R300_DST_BLEND_SHIFT
);
255 switch (ctx
->Color
.BlendEquationA
) {
257 eqnA
= R300_COMB_FCN_ADD_CLAMP
;
260 case GL_FUNC_SUBTRACT
:
261 eqnA
= R300_COMB_FCN_SUB_CLAMP
;
264 case GL_FUNC_REVERSE_SUBTRACT
:
265 eqnA
= R300_COMB_FCN_RSUB_CLAMP
;
269 eqnA
= R300_COMB_FCN_MIN
;
270 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
271 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
275 eqnA
= R300_COMB_FCN_MAX
;
276 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
277 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
281 fprintf(stderr
, "[%s:%u] Invalid A blend equation (0x%04x).\n",
282 __func__
, __LINE__
, ctx
->Color
.BlendEquationA
);
286 r300_set_blend_cntl(r300
,
287 func
, eqn
, R300_BLEND_UNKNOWN
| R300_BLEND_ENABLE
,
291 static void r300BlendEquationSeparate(GLcontext
* ctx
,
292 GLenum modeRGB
, GLenum modeA
)
294 r300_set_blend_state(ctx
);
297 static void r300BlendFuncSeparate(GLcontext
* ctx
,
298 GLenum sfactorRGB
, GLenum dfactorRGB
,
299 GLenum sfactorA
, GLenum dfactorA
)
301 r300_set_blend_state(ctx
);
305 * Update our tracked culling state based on Mesa's state.
307 static void r300UpdateCulling(GLcontext
* ctx
)
309 r300ContextPtr r300
= R300_CONTEXT(ctx
);
312 R300_STATECHANGE(r300
, cul
);
313 if (ctx
->Polygon
.CullFlag
) {
314 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
)
315 val
= R300_CULL_FRONT
|R300_CULL_BACK
;
316 else if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
317 val
= R300_CULL_FRONT
;
319 val
= R300_CULL_BACK
;
321 if (ctx
->Polygon
.FrontFace
== GL_CW
)
322 val
|= R300_FRONT_FACE_CW
;
324 val
|= R300_FRONT_FACE_CCW
;
326 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
329 static void update_early_z(GLcontext
*ctx
)
331 /* updates register R300_RB3D_EARLY_Z (0x4F14)
332 if depth test is not enabled it should be R300_EARLY_Z_DISABLE
333 if depth is enabled and alpha not it should be R300_EARLY_Z_ENABLE
334 if depth and alpha is enabled it should be R300_EARLY_Z_DISABLE
336 r300ContextPtr r300
= R300_CONTEXT(ctx
);
338 R300_STATECHANGE(r300
, zstencil_format
);
339 if (ctx
->Color
.AlphaEnabled
&& ctx
->Color
.AlphaFunc
!= GL_ALWAYS
)
340 /* disable early Z */
341 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_DISABLE
;
343 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
)
345 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_ENABLE
;
347 /* disable early Z */
348 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_DISABLE
;
352 static void update_alpha(GLcontext
*ctx
)
354 r300ContextPtr r300
= R300_CONTEXT(ctx
);
356 uint32_t pp_misc
= 0x0;
357 GLboolean really_enabled
= ctx
->Color
.AlphaEnabled
;
359 CLAMPED_FLOAT_TO_UBYTE(refByte
, ctx
->Color
.AlphaRef
);
361 switch (ctx
->Color
.AlphaFunc
) {
363 pp_misc
|= R300_ALPHA_TEST_FAIL
;
366 pp_misc
|= R300_ALPHA_TEST_LESS
;
369 pp_misc
|= R300_ALPHA_TEST_EQUAL
;
372 pp_misc
|= R300_ALPHA_TEST_LEQUAL
;
375 pp_misc
|= R300_ALPHA_TEST_GREATER
;
378 pp_misc
|= R300_ALPHA_TEST_NEQUAL
;
381 pp_misc
|= R300_ALPHA_TEST_GEQUAL
;
384 /*pp_misc |= R300_ALPHA_TEST_PASS;*/
385 really_enabled
= GL_FALSE
;
389 if (really_enabled
) {
390 pp_misc
|= R300_ALPHA_TEST_ENABLE
;
391 pp_misc
|= (refByte
& R300_REF_ALPHA_MASK
);
397 R300_STATECHANGE(r300
, at
);
398 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
402 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
409 static int translate_func(int func
)
413 return R300_ZS_NEVER
;
417 return R300_ZS_EQUAL
;
419 return R300_ZS_LEQUAL
;
421 return R300_ZS_GREATER
;
423 return R300_ZS_NOTEQUAL
;
425 return R300_ZS_GEQUAL
;
427 return R300_ZS_ALWAYS
;
432 static void update_depth(GLcontext
* ctx
)
434 r300ContextPtr r300
= R300_CONTEXT(ctx
);
436 R300_STATECHANGE(r300
, zs
);
437 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_RB3D_STENCIL_ENABLE
;
438 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
440 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
) {
442 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_TEST_AND_WRITE
;
444 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_TEST
;
446 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= translate_func(ctx
->Depth
.Func
) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
448 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_DISABLED_1
;
449 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= translate_func(GL_NEVER
) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
456 * Handle glEnable()/glDisable().
458 * \note Mesa already filters redundant calls to glEnable/glDisable.
460 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
462 r300ContextPtr r300
= R300_CONTEXT(ctx
);
464 if (RADEON_DEBUG
& DEBUG_STATE
)
465 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
466 _mesa_lookup_enum_by_nr(cap
),
467 state
? "GL_TRUE" : "GL_FALSE");
470 /* Fast track this one...
478 R300_STATECHANGE(r300
, fogs
);
480 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] |=
483 ctx
->Driver
.Fogfv( ctx
, GL_FOG_MODE
, NULL
);
484 ctx
->Driver
.Fogfv( ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
485 ctx
->Driver
.Fogfv( ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
486 ctx
->Driver
.Fogfv( ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
487 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
489 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] &=
500 case GL_COLOR_LOGIC_OP
:
501 r300_set_blend_state(ctx
);
508 case GL_STENCIL_TEST
:
509 if (r300
->state
.stencil
.hw_stencil
) {
510 R300_STATECHANGE(r300
, zs
);
512 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
513 R300_RB3D_STENCIL_ENABLE
;
515 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
516 ~R300_RB3D_STENCIL_ENABLE
;
520 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
526 r300UpdateCulling(ctx
);
529 case GL_POLYGON_OFFSET_POINT
:
530 case GL_POLYGON_OFFSET_LINE
:
533 case GL_POLYGON_OFFSET_FILL
:
534 R300_STATECHANGE(r300
, occlusion_cntl
);
536 r300
->hw
.occlusion_cntl
.cmd
[1] |= (3<<0);
538 r300
->hw
.occlusion_cntl
.cmd
[1] &= ~(3<<0);
542 radeonEnable(ctx
, cap
, state
);
548 static void r300UpdatePolygonMode(GLcontext
*ctx
)
550 r300ContextPtr r300
= R300_CONTEXT(ctx
);
553 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
554 ctx
->Polygon
.BackMode
!= GL_FILL
) {
557 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
558 f
= ctx
->Polygon
.FrontMode
;
559 b
= ctx
->Polygon
.BackMode
;
561 f
= ctx
->Polygon
.BackMode
;
562 b
= ctx
->Polygon
.FrontMode
;
565 hw_mode
|= R300_PM_ENABLED
;
569 hw_mode
|= R300_PM_FRONT_LINE
;
571 case GL_POINT
: /* noop */
572 hw_mode
|= R300_PM_FRONT_POINT
;
575 hw_mode
|= R300_PM_FRONT_FILL
;
581 hw_mode
|= R300_PM_BACK_LINE
;
583 case GL_POINT
: /* noop */
584 hw_mode
|= R300_PM_BACK_POINT
;
587 hw_mode
|= R300_PM_BACK_FILL
;
592 if (r300
->hw
.polygon_mode
.cmd
[1] != hw_mode
) {
593 R300_STATECHANGE(r300
, polygon_mode
);
594 r300
->hw
.polygon_mode
.cmd
[1] = hw_mode
;
599 * Change the culling mode.
601 * \note Mesa already filters redundant calls to this function.
603 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
607 r300UpdateCulling(ctx
);
612 * Change the polygon orientation.
614 * \note Mesa already filters redundant calls to this function.
616 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
620 r300UpdateCulling(ctx
);
621 r300UpdatePolygonMode(ctx
);
626 * Change the depth testing function.
628 * \note Mesa already filters redundant calls to this function.
630 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
638 * Enable/Disable depth writing.
640 * \note Mesa already filters redundant calls to this function.
642 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
650 * Handle glColorMask()
652 static void r300ColorMask(GLcontext
* ctx
,
653 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
655 r300ContextPtr r300
= R300_CONTEXT(ctx
);
656 int mask
= (r
? R300_COLORMASK0_R
: 0) |
657 (g
? R300_COLORMASK0_G
: 0) |
658 (b
? R300_COLORMASK0_B
: 0) |
659 (a
? R300_COLORMASK0_A
: 0);
661 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
662 R300_STATECHANGE(r300
, cmk
);
663 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
667 /* =============================================================
670 static void r300Fogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
672 r300ContextPtr r300
= R300_CONTEXT(ctx
);
673 union { int i
; float f
; } fogScale
, fogStart
;
677 fogScale
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
];
678 fogStart
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_START
];
682 if (!ctx
->Fog
.Enabled
)
684 switch (ctx
->Fog
.Mode
) {
686 R300_STATECHANGE(r300
, fogs
);
687 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
688 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_LINEAR
;
690 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
695 fogScale
.f
= 1.0 / (ctx
->Fog
.End
-ctx
->Fog
.Start
);
696 fogStart
.f
= -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-ctx
->Fog
.Start
);
700 R300_STATECHANGE(r300
, fogs
);
701 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
702 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_EXP
;
703 fogScale
.f
= 0.0933*ctx
->Fog
.Density
;
707 R300_STATECHANGE(r300
, fogs
);
708 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
709 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_EXP2
;
710 fogScale
.f
= 0.3*ctx
->Fog
.Density
;
717 switch (ctx
->Fog
.Mode
) {
719 fogScale
.f
= 0.0933*ctx
->Fog
.Density
;
723 fogScale
.f
= 0.3*ctx
->Fog
.Density
;
731 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
732 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
737 fogScale
.f
= 1.0 / (ctx
->Fog
.End
-ctx
->Fog
.Start
);
738 fogStart
.f
= -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-ctx
->Fog
.Start
);
743 R300_STATECHANGE(r300
, fogc
);
744 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] = (GLuint
) (ctx
->Fog
.Color
[0]*1023.0F
) & 0x3FF;
745 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] = (GLuint
) (ctx
->Fog
.Color
[1]*1023.0F
) & 0x3FF;
746 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] = (GLuint
) (ctx
->Fog
.Color
[2]*1023.0F
) & 0x3FF;
748 case GL_FOG_COORD_SRC
:
754 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
755 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
756 R300_STATECHANGE(r300
, fogp
);
757 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
758 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
762 /* =============================================================
765 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
767 r300ContextPtr r300
= R300_CONTEXT(ctx
);
769 size
= ctx
->Point
._Size
;
771 R300_STATECHANGE(r300
, ps
);
772 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
773 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
774 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
777 /* =============================================================
780 static void r300LineWidth(GLcontext
*ctx
, GLfloat widthf
)
782 r300ContextPtr r300
= R300_CONTEXT(ctx
);
784 widthf
= ctx
->Line
._Width
;
786 R300_STATECHANGE(r300
, lcntl
);
787 r300
->hw
.lcntl
.cmd
[1] = (int)(widthf
* 6.0);
788 r300
->hw
.lcntl
.cmd
[1] |= R300_LINE_CNT_VE
;
791 static void r300PolygonMode(GLcontext
*ctx
, GLenum face
, GLenum mode
)
796 r300UpdatePolygonMode(ctx
);
799 /* =============================================================
803 static int translate_stencil_op(int op
)
811 return R300_ZS_REPLACE
;
816 case GL_INCR_WRAP_EXT
:
817 return R300_ZS_INCR_WRAP
;
818 case GL_DECR_WRAP_EXT
:
819 return R300_ZS_DECR_WRAP
;
821 return R300_ZS_INVERT
;
823 WARN_ONCE("Do not know how to translate stencil op");
829 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
831 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
833 R300_STATECHANGE(rmesa
, shade
);
836 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
839 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
846 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
847 GLenum func
, GLint ref
, GLuint mask
)
849 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
850 GLuint refmask
= (((ctx
->Stencil
.Ref
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
851 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
855 R300_STATECHANGE(rmesa
, zs
);
857 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(
858 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
)
859 | (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
861 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &= ~((R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
862 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
864 flag
= translate_func(ctx
->Stencil
.Function
[0]);
865 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= (flag
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
);
867 if (ctx
->Stencil
._TestTwoSide
)
868 flag
= translate_func(ctx
->Stencil
.Function
[1]);
870 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= (flag
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
871 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
874 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
876 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
878 R300_STATECHANGE(rmesa
, zs
);
879 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &= ~(R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
);
880 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= (ctx
->Stencil
.WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
;
884 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
, GLenum fail
,
885 GLenum zfail
, GLenum zpass
)
887 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
889 R300_STATECHANGE(rmesa
, zs
);
890 /* It is easier to mask what's left.. */
891 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
892 (R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
) |
893 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
894 (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
896 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
897 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
)
898 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
)
899 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
);
901 if (ctx
->Stencil
._TestTwoSide
) {
902 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
903 (translate_stencil_op(ctx
->Stencil
.FailFunc
[1]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
904 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[1]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
905 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[1]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
907 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
908 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
909 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
910 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
914 static void r300ClearStencil(GLcontext
* ctx
, GLint s
)
916 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
918 rmesa
->state
.stencil
.clear
=
919 ((GLuint
) (ctx
->Stencil
.Clear
& 0xff) |
920 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
) |
921 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
));
924 /* =============================================================
925 * Window position and viewport transformation
929 * To correctly position primitives:
931 #define SUBPIXEL_X 0.125
932 #define SUBPIXEL_Y 0.125
934 void r300UpdateWindow(GLcontext
* ctx
)
936 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
937 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
938 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
939 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
940 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
942 GLfloat sx
= v
[MAT_SX
];
943 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
944 GLfloat sy
= -v
[MAT_SY
];
945 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
946 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
947 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
949 R300_FIREVERTICES(rmesa
);
950 R300_STATECHANGE(rmesa
, vpt
);
952 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
953 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
954 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
955 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
956 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
957 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
960 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
961 GLsizei width
, GLsizei height
)
963 /* Don't pipeline viewport changes, conflict with window offset
964 * setting below. Could apply deltas to rescue pipelined viewport
965 * values, or keep the originals hanging around.
967 r300UpdateWindow(ctx
);
970 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
972 r300UpdateWindow(ctx
);
975 void r300UpdateViewportOffset( GLcontext
*ctx
)
977 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
978 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
)rmesa
)->dri
.drawable
;
979 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
980 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
981 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
983 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
984 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
986 if ( rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
987 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
))
989 /* Note: this should also modify whatever data the context reset
992 R300_STATECHANGE( rmesa
, vpt
);
993 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
994 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
998 radeonUpdateScissor( ctx
);
1002 * Tell the card where to render (offset, pitch).
1003 * Effected by glDrawBuffer, etc
1006 r300UpdateDrawBuffer(GLcontext
*ctx
)
1008 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1009 r300ContextPtr r300
= rmesa
;
1010 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1011 driRenderbuffer
*drb
;
1013 if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
) {
1015 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
1017 else if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_BACK_LEFT
) {
1019 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1022 /* drawing to multiple buffers, or none */
1027 assert(drb
->flippedPitch
);
1030 R300_STATECHANGE( rmesa
, cb
);
1032 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = drb
->flippedOffset
+ //r300->radeon.state.color.drawOffset +
1033 r300
->radeon
.radeonScreen
->fbLocation
;
1034 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = drb
->flippedPitch
;//r300->radeon.state.color.drawPitch;
1036 if (r300
->radeon
.radeonScreen
->cpp
== 4)
1037 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
1039 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
1041 if (r300
->radeon
.sarea
->tiling_enabled
)
1042 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
1044 R200_STATECHANGE( rmesa
, ctx
);
1046 /* Note: we used the (possibly) page-flipped values */
1047 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
1048 = ((drb
->flippedOffset
+ rmesa
->r200Screen
->fbLocation
)
1049 & R200_COLOROFFSET_MASK
);
1050 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
1052 if (rmesa
->sarea
->tiling_enabled
) {
1053 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |= R200_COLOR_TILE_ENABLE
;
1058 static void r300FetchStateParameter(GLcontext
*ctx
, const enum state_index state
[],
1061 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1064 case STATE_INTERNAL
:
1066 case STATE_R300_WINDOW_DIMENSION
:
1067 value
[0] = r300
->radeon
.dri
.drawable
->w
*0.5f
;/* width*0.5 */
1068 value
[1] = r300
->radeon
.dri
.drawable
->h
*0.5f
;/* height*0.5 */
1069 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1070 value
[3] = 1.0F
; /* not used */
1073 case STATE_R300_TEXRECT_FACTOR
: {
1074 struct gl_texture_object
* t
= ctx
->Texture
.Unit
[state
[2]].CurrentRect
;
1076 if (t
&& t
->Image
[0][t
->BaseLevel
]) {
1077 struct gl_texture_image
* image
= t
->Image
[0][t
->BaseLevel
];
1078 value
[0] = 1.0 / image
->Width2
;
1079 value
[1] = 1.0 / image
->Height2
;
1099 * Update R300's own internal state parameters.
1100 * For now just STATE_R300_WINDOW_DIMENSION
1102 void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1104 struct r300_fragment_program
*fp
;
1105 struct gl_program_parameter_list
*paramList
;
1108 if(!(new_state
& (_NEW_BUFFERS
|_NEW_PROGRAM
)))
1111 fp
= (struct r300_fragment_program
*)ctx
->FragmentProgram
._Current
;
1115 paramList
= fp
->mesa_program
.Base
.Parameters
;
1120 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1121 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
){
1122 r300FetchStateParameter(ctx
,
1123 paramList
->Parameters
[i
].StateIndexes
,
1124 paramList
->ParameterValues
[i
]);
1129 /* =============================================================
1132 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1134 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1135 GLfloat constant
= units
;
1137 switch (ctx
->Visual
.depthBits
) {
1148 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1150 R300_STATECHANGE(rmesa
, zbs
);
1151 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1152 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1153 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1154 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1157 /* Routing and texture-related */
1160 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1161 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1162 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1163 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1164 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1165 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1166 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1167 * combinations where only one of them is nearest.
1169 static unsigned long gen_fixed_filter(unsigned long f
)
1171 unsigned long mag
, min
, needs_fixing
=0;
1174 /* We ignore MIRROR bit so we dont have to do everything twice */
1175 if((f
& ((7-1) << R300_TX_WRAP_S_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)){
1178 if((f
& ((7-1) << R300_TX_WRAP_T_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)){
1181 if((f
& ((7-1) << R300_TX_WRAP_Q_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_Q_SHIFT
)){
1188 mag
=f
& R300_TX_MAG_FILTER_MASK
;
1189 min
=f
& R300_TX_MIN_FILTER_MASK
;
1191 /* TODO: Check for anisto filters too */
1192 if((mag
!= R300_TX_MAG_FILTER_NEAREST
) && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1195 /* r300 cant handle these modes hence we force nearest to linear */
1196 if((mag
== R300_TX_MAG_FILTER_NEAREST
) && (min
!= R300_TX_MIN_FILTER_NEAREST
)){
1197 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1198 f
|= R300_TX_MAG_FILTER_LINEAR
;
1202 if((min
== R300_TX_MIN_FILTER_NEAREST
) && (mag
!= R300_TX_MAG_FILTER_NEAREST
)){
1203 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1204 f
|= R300_TX_MIN_FILTER_LINEAR
;
1208 /* Both are nearest */
1209 if(needs_fixing
& 1){
1210 f
&= ~((7-1) << R300_TX_WRAP_S_SHIFT
);
1211 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1213 if(needs_fixing
& 2){
1214 f
&= ~((7-1) << R300_TX_WRAP_T_SHIFT
);
1215 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1217 if(needs_fixing
& 4){
1218 f
&= ~((7-1) << R300_TX_WRAP_Q_SHIFT
);
1219 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_Q_SHIFT
;
1224 void r300_setup_textures(GLcontext
*ctx
)
1227 struct r300_tex_obj
*t
;
1228 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1230 int last_hw_tmu
=-1; /* -1 translates into no setup costs for fields */
1231 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1, };
1232 struct r300_fragment_program
*rp
=
1233 (struct r300_fragment_program
*)
1234 (char *)ctx
->FragmentProgram
._Current
;
1236 R300_STATECHANGE(r300
, txe
);
1237 R300_STATECHANGE(r300
, tex
.filter
);
1238 R300_STATECHANGE(r300
, tex
.filter_1
);
1239 R300_STATECHANGE(r300
, tex
.size
);
1240 R300_STATECHANGE(r300
, tex
.format
);
1241 R300_STATECHANGE(r300
, tex
.pitch
);
1242 R300_STATECHANGE(r300
, tex
.offset
);
1243 R300_STATECHANGE(r300
, tex
.chroma_key
);
1244 R300_STATECHANGE(r300
, tex
.border_color
);
1246 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
]=0x0;
1248 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1249 if (RADEON_DEBUG
& DEBUG_STATE
)
1250 fprintf(stderr
, "mtu=%d\n", mtu
);
1252 if(mtu
> R300_MAX_TEXTURE_UNITS
) {
1253 fprintf(stderr
, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1254 mtu
, R300_MAX_TEXTURE_UNITS
);
1258 /* We cannot let disabled tmu offsets pass DRM */
1259 for(i
=0; i
< mtu
; i
++) {
1260 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
1262 #if 0 /* Enables old behaviour */
1265 tmu_mappings
[i
] = hw_tmu
;
1267 t
=r300
->state
.texture
.unit
[i
].texobj
;
1269 if((t
->format
& 0xffffff00)==0xffffff00) {
1270 WARN_ONCE("unknown texture format (entry %x) encountered. Help me !\n", t
->format
& 0xff);
1273 if (RADEON_DEBUG
& DEBUG_STATE
)
1274 fprintf(stderr
, "Activating texture unit %d\n", i
);
1276 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1278 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = gen_fixed_filter(t
->filter
) | (hw_tmu
<< 28);
1279 /* Currently disabled! */
1280 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0; //0x20501f80;
1281 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->size
;
1282 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->format
;
1283 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->pitch_reg
;
1284 r300
->hw
.tex
.offset
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->offset
;
1286 if(t
->offset
& R300_TXO_MACRO_TILE
) {
1287 WARN_ONCE("macro tiling enabled!\n");
1290 if(t
->offset
& R300_TXO_MICRO_TILE
) {
1291 WARN_ONCE("micro tiling enabled!\n");
1294 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0;
1295 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->pp_border_color
;
1297 last_hw_tmu
= hw_tmu
;
1303 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FILTER_0
, last_hw_tmu
+ 1);
1304 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1305 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1306 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1307 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_PITCH_0
, last_hw_tmu
+ 1);
1308 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1309 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1310 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1313 if (!rp
) /* should only happenen once, just after context is created */
1316 R300_STATECHANGE(r300
, fpt
);
1318 for(i
= 0; i
< rp
->tex
.length
; i
++){
1323 unit
= rp
->tex
.inst
[i
] >> R300_FPITX_IMAGE_SHIFT
;
1326 val
= rp
->tex
.inst
[i
];
1327 val
&= ~R300_FPITX_IMAGE_MASK
;
1329 opcode
= (val
& R300_FPITX_OPCODE_MASK
) >> R300_FPITX_OPCODE_SHIFT
;
1330 if (opcode
== R300_FPITX_OP_KIL
) {
1331 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+i
] = val
;
1333 if (tmu_mappings
[unit
] >= 0) {
1334 val
|= tmu_mappings
[unit
] << R300_FPITX_IMAGE_SHIFT
;
1335 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+i
] = val
;
1337 // We get here when the corresponding texture image is incomplete
1338 // (e.g. incomplete mipmaps etc.)
1339 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+i
] = val
;
1344 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] = cmdpacket0(R300_PFS_TEXI_0
, rp
->tex
.length
);
1346 if (RADEON_DEBUG
& DEBUG_STATE
)
1347 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n", r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1350 union r300_outputs_written
{
1351 GLuint vp_outputs
; /* hw_tcl_on */
1352 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1355 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1356 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1357 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1359 void r300_setup_rs_unit(GLcontext
*ctx
)
1361 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1362 /* I'm still unsure if these are needed */
1363 GLuint interp_magic
[8] = {
1373 union r300_outputs_written OutputsWritten
;
1375 int fp_reg
, high_rr
;
1376 int in_texcoords
, col_interp_nr
;
1380 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1382 RENDERINPUTS_COPY( OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1384 if (ctx
->FragmentProgram
._Current
)
1385 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1387 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1388 return; /* This should only ever happen once.. */
1391 R300_STATECHANGE(r300
, ri
);
1392 R300_STATECHANGE(r300
, rc
);
1393 R300_STATECHANGE(r300
, rr
);
1395 fp_reg
= in_texcoords
= col_interp_nr
= high_rr
= 0;
1397 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] = 0;
1399 if (InputsRead
& FRAG_BIT_WPOS
){
1400 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1401 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1404 if(i
== ctx
->Const
.MaxTextureUnits
){
1405 fprintf(stderr
, "\tno free texcoord found...\n");
1409 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1410 InputsRead
&= ~FRAG_BIT_WPOS
;
1413 for (i
=0;i
<ctx
->Const
.MaxTextureUnits
;i
++) {
1414 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+i
] = 0
1415 | R300_RS_INTERP_USED
1416 | (in_texcoords
<< R300_RS_INTERP_SRC_SHIFT
)
1419 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] = 0;
1420 if (InputsRead
& (FRAG_BIT_TEX0
<<i
)) {
1421 //assert(r300->state.texture.tc_count != 0);
1422 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] |=
1423 R300_RS_ROUTE_ENABLE
1424 | i
/* source INTERP */
1425 | (fp_reg
<< R300_RS_ROUTE_DEST_SHIFT
);
1428 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_TEX0
+i
, _TNL_ATTRIB_TEX(i
) )) {
1429 /* Passing invalid data here can lock the GPU. */
1430 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1431 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1434 InputsRead
&= ~(FRAG_BIT_TEX0
<<i
);
1437 /* Need to count all coords enabled at vof */
1438 if (R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_TEX0
+i
, _TNL_ATTRIB_TEX(i
) ))
1442 if (InputsRead
& FRAG_BIT_COL0
) {
1443 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1444 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1445 goto out
; /* FIXME */
1446 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
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
);
1453 InputsRead
&= ~FRAG_BIT_COL0
;
1458 if (InputsRead
& FRAG_BIT_COL1
) {
1459 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1460 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1464 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] |= R300_RS_ROUTE_1_UNKNOWN11
1465 | R300_RS_ROUTE_1_COLOR1
1466 | (fp_reg
++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT
);
1467 InputsRead
&= ~FRAG_BIT_COL1
;
1468 if (high_rr
< 1) high_rr
= 1;
1472 /* Need at least one. This might still lock as the values are undefined... */
1473 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1474 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1475 | R300_RS_ROUTE_0_COLOR
1476 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1480 r300
->hw
.rc
.cmd
[1] = 0
1481 | (in_texcoords
<< R300_RS_CNTL_TC_CNT_SHIFT
)
1482 | (col_interp_nr
<< R300_RS_CNTL_CI_CNT_SHIFT
)
1483 | R300_RS_CNTL_0_UNKNOWN_18
;
1485 assert(high_rr
>= 0);
1486 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R300_RS_ROUTE_0
, high_rr
+1);
1487 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1490 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1493 #define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
1495 #define bump_vpu_count(ptr, new_count) do{\
1496 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1497 int _nc=(new_count)/4; \
1498 assert(_nc < 256); \
1499 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1502 void static inline setup_vertex_shader_fragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1506 if(vsf
->length
==0)return;
1508 if(vsf
->length
& 0x3){
1509 fprintf(stderr
,"VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1513 switch((dest
>>8) & 0xf){
1515 R300_STATECHANGE(r300
, vpi
);
1516 for(i
=0;i
<vsf
->length
;i
++)
1517 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1518 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+4*(dest
& 0xff));
1522 R300_STATECHANGE(r300
, vpp
);
1523 for(i
=0;i
<vsf
->length
;i
++)
1524 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1525 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+4*(dest
& 0xff));
1528 R300_STATECHANGE(r300
, vps
);
1529 for(i
=0;i
<vsf
->length
;i
++)
1530 r300
->hw
.vps
.cmd
[1+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1531 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+4*(dest
& 0xff));
1534 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1539 void r300SetupVertexProgram(r300ContextPtr rmesa
);
1541 /* just a skeleton for now.. */
1543 /* Generate a vertex shader that simply transforms vertex and texture coordinates,
1544 while leaving colors intact. Nothing fancy (like lights)
1546 If implementing lights make a copy first, so it is easy to switch between the two versions */
1547 static void r300GenerateSimpleVertexShader(r300ContextPtr r300
)
1552 /* Allocate parameters */
1553 r300
->state
.vap_param
.transform_offset
=0x0; /* transform matrix */
1554 r300
->state
.vertex_shader
.param_offset
=0x0;
1555 r300
->state
.vertex_shader
.param_count
=0x4; /* 4 vector values - 4x4 matrix */
1557 r300
->state
.vertex_shader
.program_start
=0x0;
1558 r300
->state
.vertex_shader
.unknown_ptr1
=0x4; /* magic value ? */
1559 r300
->state
.vertex_shader
.program_end
=0x0;
1561 r300
->state
.vertex_shader
.unknown_ptr2
=0x0; /* magic value */
1562 r300
->state
.vertex_shader
.unknown_ptr3
=0x4; /* magic value */
1564 /* Initialize matrix and vector parameters.. these should really be restructured */
1565 /* TODO: fix vertex_shader structure */
1566 r300
->state
.vertex_shader
.matrix
[0].length
=16;
1567 r300
->state
.vertex_shader
.matrix
[1].length
=0;
1568 r300
->state
.vertex_shader
.matrix
[2].length
=0;
1569 r300
->state
.vertex_shader
.vector
[0].length
=0;
1570 r300
->state
.vertex_shader
.vector
[1].length
=0;
1571 r300
->state
.vertex_shader
.unknown1
.length
=0;
1572 r300
->state
.vertex_shader
.unknown2
.length
=0;
1574 #define WRITE_OP(oper,source1,source2,source3) {\
1575 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].op=(oper); \
1576 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src1=(source1); \
1577 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src2=(source2); \
1578 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src3=(source3); \
1579 r300->state.vertex_shader.program_end++; \
1582 /* Multiply vertex coordinates with transform matrix */
1585 EASY_VSF_OP(MUL
, 0, ALL
, TMP
),
1588 EASY_VSF_SOURCE(0, W
, W
, W
, W
, NONE
, NONE
)
1592 EASY_VSF_OP(MUL
, 1, ALL
, RESULT
),
1599 EASY_VSF_OP(MAD
, 0, ALL
, TMP
),
1606 EASY_VSF_OP(MAD
, 0, ALL
, TMP
),
1613 EASY_VSF_OP(MAD
, 0, ALL
, RESULT
),
1620 for (i
= VERT_ATTRIB_COLOR1
; i
< VERT_ATTRIB_MAX
; i
++)
1621 if (r300
->state
.sw_tcl_inputs
[i
] != -1) {
1623 EASY_VSF_OP(MUL
, o_reg
++ /* 2+i */, ALL
, RESULT
),
1624 VSF_REG(r300
->state
.sw_tcl_inputs
[i
]),
1625 VSF_ATTR_UNITY(r300
->state
.sw_tcl_inputs
[i
]),
1626 VSF_UNITY(r300
->state
.sw_tcl_inputs
[i
])
1631 r300
->state
.vertex_shader
.program_end
--; /* r300 wants program length to be one more - no idea why */
1632 r300
->state
.vertex_shader
.program
.length
=(r300
->state
.vertex_shader
.program_end
+1)*4;
1634 r300
->state
.vertex_shader
.unknown_ptr1
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1635 r300
->state
.vertex_shader
.unknown_ptr2
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1636 r300
->state
.vertex_shader
.unknown_ptr3
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1641 void r300SetupVertexShader(r300ContextPtr rmesa
)
1643 GLcontext
* ctx
= rmesa
->radeon
.glCtx
;
1645 /* Reset state, in case we don't use something */
1646 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1647 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1648 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1650 /* Not sure why this doesnt work...
1651 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
1652 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. */
1653 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
1654 if(hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
){
1655 r300SetupVertexProgram(rmesa
);
1659 /* This needs to be replaced by vertex shader generation code */
1663 /* textures enabled ? */
1664 if(rmesa
->state
.texture
.tc_count
>0){
1665 rmesa
->state
.vertex_shader
=SINGLE_TEXTURE_VERTEX_SHADER
;
1667 rmesa
->state
.vertex_shader
=FLAT_COLOR_VERTEX_SHADER
;
1671 r300GenerateSimpleVertexShader(rmesa
);
1673 rmesa
->state
.vertex_shader
.matrix
[0].length
=16;
1674 memcpy(rmesa
->state
.vertex_shader
.matrix
[0].body
.f
, ctx
->_ModelProjectMatrix
.m
, 16*4);
1676 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(rmesa
->state
.vertex_shader
.program
));
1678 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX0
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1680 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX1
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1681 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX2
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1683 setup_vertex_shader_fragment(rmesa
, VSF_DEST_VECTOR0
, &(rmesa
->state
.vertex_shader
.vector
[0]));
1684 setup_vertex_shader_fragment(rmesa
, VSF_DEST_VECTOR1
, &(rmesa
->state
.vertex_shader
.vector
[1]));
1688 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
, &(rmesa
->state
.vertex_shader
.unknown1
));
1689 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
, &(rmesa
->state
.vertex_shader
.unknown2
));
1692 R300_STATECHANGE(rmesa
, pvs
);
1693 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
]=(rmesa
->state
.vertex_shader
.program_start
<< R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1694 | (rmesa
->state
.vertex_shader
.unknown_ptr1
<< R300_PVS_CNTL_1_POS_END_SHIFT
)
1695 | (rmesa
->state
.vertex_shader
.program_end
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1696 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
]=(rmesa
->state
.vertex_shader
.param_offset
<< R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1697 | (rmesa
->state
.vertex_shader
.param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1698 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
]=(rmesa
->state
.vertex_shader
.unknown_ptr2
<< R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1699 | (rmesa
->state
.vertex_shader
.unknown_ptr3
<< 0);
1701 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1702 so I leave it as a reminder */
1704 reg_start(R300_VAP_PVS_WAITIDLE
,0);
1709 void r300SetupVertexProgram(r300ContextPtr rmesa
)
1711 GLcontext
* ctx
= rmesa
->radeon
.glCtx
;
1714 struct r300_vertex_program
*prog
=(struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1717 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1718 R300_STATECHANGE(rmesa
, vpp
);
1719 param_count
= r300VertexProgUpdateParams(ctx
, (struct r300_vertex_program_cont
*)ctx
->VertexProgram
._Current
/*prog*/, (float *)&rmesa
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
]);
1720 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
1723 /* Reset state, in case we don't use something */
1724 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1725 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1727 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(prog
->program
));
1730 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
, &(rmesa
->state
.vertex_shader
.unknown1
));
1731 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
, &(rmesa
->state
.vertex_shader
.unknown2
));
1734 inst_count
=prog
->program
.length
/4 - 1;
1736 R300_STATECHANGE(rmesa
, pvs
);
1737 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
]=(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1738 | (inst_count
/*pos_end*/ << R300_PVS_CNTL_1_POS_END_SHIFT
)
1739 | (inst_count
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1740 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
]=(0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1741 | (param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1742 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
]=(0/*rmesa->state.vertex_shader.unknown_ptr2*/ << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1743 | (inst_count
/*rmesa->state.vertex_shader.unknown_ptr3*/ << 0);
1745 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1746 so I leave it as a reminder */
1748 reg_start(R300_VAP_PVS_WAITIDLE
,0);
1753 extern void _tnl_UpdateFixedFunctionProgram( GLcontext
*ctx
);
1755 extern int future_hw_tcl_on
;
1756 void r300UpdateShaders(r300ContextPtr rmesa
)
1759 struct r300_vertex_program
*vp
;
1762 ctx
= rmesa
->radeon
.glCtx
;
1764 if (rmesa
->NewGLState
&& hw_tcl_on
) {
1765 rmesa
->NewGLState
= 0;
1767 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1768 rmesa
->temp_attrib
[i
] = TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
1769 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] = &rmesa
->dummy_attrib
[i
];
1772 _tnl_UpdateFixedFunctionProgram(ctx
);
1774 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1775 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] = rmesa
->temp_attrib
[i
];
1778 r300_select_vertex_shader(rmesa
);
1779 vp
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1780 /*if (vp->translated == GL_FALSE)
1781 r300_translate_vertex_shader(vp);*/
1782 if (vp
->translated
== GL_FALSE
) {
1783 fprintf(stderr
, "Failing back to sw-tcl\n");
1784 hw_tcl_on
= future_hw_tcl_on
= 0;
1785 r300ResetHwState(rmesa
);
1789 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
1794 void r300UpdateShaderStates(r300ContextPtr rmesa
)
1797 ctx
= rmesa
->radeon
.glCtx
;
1799 r300UpdateTextureState(ctx
);
1801 r300SetupPixelShader(rmesa
);
1802 r300_setup_textures(ctx
);
1804 r300SetupVertexShader(rmesa
);
1805 r300_setup_rs_unit(ctx
);
1808 /* This is probably wrong for some values, I need to test this
1809 * some more. Range checking would be a good idea also..
1811 * But it works for most things. I'll fix it later if someone
1812 * else with a better clue doesn't
1814 static unsigned int r300PackFloat24(float f
)
1818 unsigned int float24
= 0;
1820 if (f
== 0.0) return 0;
1822 mantissa
= frexpf(f
, &exponent
);
1827 mantissa
= mantissa
* -1.0;
1829 /* Handle exponent, bias of 63 */
1831 float24
|= (exponent
<< 16);
1832 /* Kill 7 LSB of mantissa */
1833 float24
|= (r300PackFloat32(mantissa
) & 0x7FFFFF) >> 7;
1838 void r300SetupPixelShader(r300ContextPtr rmesa
)
1840 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1841 struct r300_fragment_program
*rp
=
1842 (struct r300_fragment_program
*)
1843 (char *)ctx
->FragmentProgram
._Current
;
1846 if (!rp
) /* should only happenen once, just after context is created */
1849 r300_translate_fragment_shader(rmesa
, rp
);
1850 if (!rp
->translated
) {
1851 fprintf(stderr
, "%s: No valid fragment shader, exiting\n", __func__
);
1855 #define OUTPUT_FIELD(st, reg, field) \
1856 R300_STATECHANGE(rmesa, st); \
1857 for(i=0;i<=rp->alu_end;i++) \
1858 rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=rp->alu.inst[i].field;\
1859 rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmdpacket0(reg, rp->alu_end+1);
1861 OUTPUT_FIELD(fpi
[0], R300_PFS_INSTR0_0
, inst0
);
1862 OUTPUT_FIELD(fpi
[1], R300_PFS_INSTR1_0
, inst1
);
1863 OUTPUT_FIELD(fpi
[2], R300_PFS_INSTR2_0
, inst2
);
1864 OUTPUT_FIELD(fpi
[3], R300_PFS_INSTR3_0
, inst3
);
1867 R300_STATECHANGE(rmesa
, fp
);
1868 /* I just want to say, the way these nodes are stored.. weird.. */
1869 for (i
=0,k
=(4-(rp
->cur_node
+1));i
<4;i
++,k
++) {
1870 if (i
<(rp
->cur_node
+1)) {
1871 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+k
]=
1872 (rp
->node
[i
].alu_offset
<< R300_PFS_NODE_ALU_OFFSET_SHIFT
)
1873 | (rp
->node
[i
].alu_end
<< R300_PFS_NODE_ALU_END_SHIFT
)
1874 | (rp
->node
[i
].tex_offset
<< R300_PFS_NODE_TEX_OFFSET_SHIFT
)
1875 | (rp
->node
[i
].tex_end
<< R300_PFS_NODE_TEX_END_SHIFT
)
1876 | rp
->node
[i
].flags
; /* ( (k==3) ? R300_PFS_NODE_LAST_NODE : 0); */
1878 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+(3-i
)] = 0;
1883 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
]=
1885 | (rp
->first_node_has_tex
<<3);
1887 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
]=rp
->max_temp_idx
;
1889 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
]=
1890 (rp
->alu_offset
<< R300_PFS_CNTL_ALU_OFFSET_SHIFT
)
1891 | (rp
->alu_end
<< R300_PFS_CNTL_ALU_END_SHIFT
)
1892 | (rp
->tex_offset
<< R300_PFS_CNTL_TEX_OFFSET_SHIFT
)
1893 | (rp
->tex_end
<< R300_PFS_CNTL_TEX_END_SHIFT
);
1895 R300_STATECHANGE(rmesa
, fpp
);
1896 for(i
=0;i
<rp
->const_nr
;i
++){
1897 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+0]=r300PackFloat24(rp
->constant
[i
][0]);
1898 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+1]=r300PackFloat24(rp
->constant
[i
][1]);
1899 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+2]=r300PackFloat24(rp
->constant
[i
][2]);
1900 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+3]=r300PackFloat24(rp
->constant
[i
][3]);
1902 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
]=cmdpacket0(R300_PFS_PARAM_0_X
, rp
->const_nr
*4);
1906 * Called by Mesa after an internal state update.
1908 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
1910 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1912 _swrast_InvalidateState(ctx
, new_state
);
1913 _swsetup_InvalidateState(ctx
, new_state
);
1914 _vbo_InvalidateState(ctx
, new_state
);
1915 _tnl_InvalidateState(ctx
, new_state
);
1916 _ae_invalidate_state(ctx
, new_state
);
1918 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
1919 r300UpdateDrawBuffer(ctx
);
1922 r300UpdateStateParameters(ctx
, new_state
);
1925 if(new_state
& _NEW_ARRAY
)
1926 r300
->state
.VB
.lock_uptodate
= GL_FALSE
;
1928 r300
->NewGLState
|= new_state
;
1932 * Completely recalculates hardware state based on the Mesa state.
1934 void r300ResetHwState(r300ContextPtr r300
)
1936 GLcontext
* ctx
= r300
->radeon
.glCtx
;
1938 if (RADEON_DEBUG
& DEBUG_STATE
)
1939 fprintf(stderr
, "%s\n", __FUNCTION__
);
1941 /* This is a place to initialize registers which
1942 have bitfields accessed by different functions
1943 and not all bits are used */
1945 /* initialize similiar to r200 */
1946 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] = 0;
1947 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] =
1948 (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
1949 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
) |
1950 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
) |
1951 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
) |
1952 (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
) |
1953 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
) |
1954 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
) |
1955 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
);
1956 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] = 0x00ffff00;
1959 /* go and compute register values from GL state */
1961 r300UpdateWindow(ctx
);
1964 ctx
->Color
.ColorMask
[RCOMP
],
1965 ctx
->Color
.ColorMask
[GCOMP
],
1966 ctx
->Color
.ColorMask
[BCOMP
],
1967 ctx
->Color
.ColorMask
[ACOMP
]);
1969 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
1970 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
1971 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
1974 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
1975 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
1976 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0], ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
1977 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0], ctx
->Stencil
.ZFailFunc
[0], ctx
->Stencil
.ZPassFunc
[0]);
1979 r300UpdateCulling(ctx
);
1981 r300UpdateTextureState(ctx
);
1983 // r300_setup_routing(ctx, GL_TRUE);
1985 #if 0 /* Done in prior to rendering */
1986 if(hw_tcl_on
== GL_FALSE
){
1987 r300EmitArrays(ctx
, GL_TRUE
); /* Just do the routing */
1988 r300_setup_textures(ctx
);
1989 r300_setup_rs_unit(ctx
);
1991 r300SetupVertexShader(r300
);
1992 r300SetupPixelShader(r300
);
1996 r300_set_blend_state(ctx
);
1998 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
1999 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
2001 /* Initialize magic registers
2002 TODO : learn what they really do, or get rid of
2003 those we don't have to touch */
2004 r300
->hw
.vap_cntl
.cmd
[1] = 0x0030045A; //0x0030065a /* Dangerous */
2006 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
2007 | R300_VPORT_X_OFFSET_ENA
2008 | R300_VPORT_Y_SCALE_ENA
2009 | R300_VPORT_Y_OFFSET_ENA
2010 | R300_VPORT_Z_SCALE_ENA
2011 | R300_VPORT_Z_OFFSET_ENA
2013 r300
->hw
.vte
.cmd
[2] = 0x00000008;
2015 r300
->hw
.unk2134
.cmd
[1] = 0x00FFFFFF;
2016 r300
->hw
.unk2134
.cmd
[2] = 0x00000000;
2017 if (_mesa_little_endian())
2018 r300
->hw
.vap_cntl_status
.cmd
[1] = 0x00000000;
2020 r300
->hw
.vap_cntl_status
.cmd
[1] = 0x00000002;
2022 #if 0 /* Done in setup routing */
2023 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[0].cmd
)->packet0
.count
= 1;
2024 r300
->hw
.vir
[0].cmd
[1] = 0x21030003;
2026 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[1].cmd
)->packet0
.count
= 1;
2027 r300
->hw
.vir
[1].cmd
[1] = 0xF688F688;
2029 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_0
] = 0x00000001;
2030 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_1
] = 0x00000405;
2033 r300
->hw
.unk21DC
.cmd
[1] = 0xAAAAAAAA;
2035 r300
->hw
.unk221C
.cmd
[1] = R300_221C_NORMAL
;
2037 r300
->hw
.unk2220
.cmd
[1] = r300PackFloat32(1.0);
2038 r300
->hw
.unk2220
.cmd
[2] = r300PackFloat32(1.0);
2039 r300
->hw
.unk2220
.cmd
[3] = r300PackFloat32(1.0);
2040 r300
->hw
.unk2220
.cmd
[4] = r300PackFloat32(1.0);
2042 /* what about other chips than r300 or rv350??? */
2043 if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
)
2044 r300
->hw
.unk2288
.cmd
[1] = R300_2288_R300
;
2046 r300
->hw
.unk2288
.cmd
[1] = R300_2288_RV350
;
2049 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_0
] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
2050 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
;
2051 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_1
] = 0; /* no textures */
2054 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] = 0;
2055 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] = 0;
2056 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] = 0;
2059 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2060 | R300_GB_LINE_STUFF_ENABLE
2061 | R300_GB_TRIANGLE_STUFF_ENABLE
/*| R300_GB_UNK31*/;
2063 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2064 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2065 if ((r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
) ||
2066 (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R350
))
2067 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2068 | R300_GB_TILE_PIPE_COUNT_R300
2069 | R300_GB_TILE_SIZE_16
;
2070 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
)
2071 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2072 | R300_GB_TILE_PIPE_COUNT_RV410
2073 | R300_GB_TILE_SIZE_16
;
2074 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
)
2075 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2076 | R300_GB_TILE_PIPE_COUNT_R420
2077 | R300_GB_TILE_SIZE_16
;
2079 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2080 | R300_GB_TILE_PIPE_COUNT_RV300
2081 | R300_GB_TILE_SIZE_16
;
2082 /* set to 0 when fog is disabled? */
2083 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2084 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = 0x00000000; /* No antialiasing */
2086 //r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
2088 r300
->hw
.unk4200
.cmd
[1] = r300PackFloat32(0.0);
2089 r300
->hw
.unk4200
.cmd
[2] = r300PackFloat32(0.0);
2090 r300
->hw
.unk4200
.cmd
[3] = r300PackFloat32(1.0);
2091 r300
->hw
.unk4200
.cmd
[4] = r300PackFloat32(1.0);
2093 r300
->hw
.unk4214
.cmd
[1] = 0x00050005;
2095 r300PointSize(ctx
, 0.0);
2097 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] = (6 << R300_POINTSIZE_X_SHIFT
) |
2098 (6 << R300_POINTSIZE_Y_SHIFT
);
2101 r300
->hw
.unk4230
.cmd
[1] = 0x18000006;
2102 r300
->hw
.unk4230
.cmd
[2] = 0x00020006;
2103 r300
->hw
.unk4230
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2105 r300LineWidth(ctx
, 0.0);
2107 r300
->hw
.unk4260
.cmd
[1] = 0;
2108 r300
->hw
.unk4260
.cmd
[2] = r300PackFloat32(0.0);
2109 r300
->hw
.unk4260
.cmd
[3] = r300PackFloat32(1.0);
2111 r300
->hw
.shade
.cmd
[1] = 0x00000002;
2112 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2113 r300
->hw
.shade
.cmd
[3] = 0x00000000;
2114 r300
->hw
.shade
.cmd
[4] = 0x00000000;
2116 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2117 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2118 r300
->hw
.polygon_mode
.cmd
[2] = 0x00000001;
2119 r300
->hw
.polygon_mode
.cmd
[3] = 0x00000000;
2120 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
2122 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
, ctx
->Polygon
.OffsetUnits
);
2123 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2125 r300
->hw
.unk42C0
.cmd
[1] = 0x4B7FFFFF;
2126 r300
->hw
.unk42C0
.cmd
[2] = 0x00000000;
2129 r300
->hw
.unk43A4
.cmd
[1] = 0x0000001C;
2130 r300
->hw
.unk43A4
.cmd
[2] = 0x2DA49525;
2132 r300
->hw
.unk43E8
.cmd
[1] = 0x00FFFFFF;
2135 r300
->hw
.fp
.cmd
[R300_FP_CNTL0
] = 0;
2136 r300
->hw
.fp
.cmd
[R300_FP_CNTL1
] = 0;
2137 r300
->hw
.fp
.cmd
[R300_FP_CNTL2
] = 0;
2138 r300
->hw
.fp
.cmd
[R300_FP_NODE0
] = 0;
2139 r300
->hw
.fp
.cmd
[R300_FP_NODE1
] = 0;
2140 r300
->hw
.fp
.cmd
[R300_FP_NODE2
] = 0;
2141 r300
->hw
.fp
.cmd
[R300_FP_NODE3
] = 0;
2144 r300
->hw
.unk46A4
.cmd
[1] = 0x00001B01;
2145 r300
->hw
.unk46A4
.cmd
[2] = 0x00001B0F;
2146 r300
->hw
.unk46A4
.cmd
[3] = 0x00001B0F;
2147 r300
->hw
.unk46A4
.cmd
[4] = 0x00001B0F;
2148 r300
->hw
.unk46A4
.cmd
[5] = 0x00000001;
2151 for(i
= 1; i
<= 64; ++i
) {
2152 /* create NOP instructions */
2153 r300
->hw
.fpi
[0].cmd
[i
] = FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
));
2154 r300
->hw
.fpi
[1].cmd
[i
] = FP_SELC(0,XYZ
,NO
,FP_TMP(0),0,0);
2155 r300
->hw
.fpi
[2].cmd
[i
] = FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
));
2156 r300
->hw
.fpi
[3].cmd
[i
] = FP_SELA(0,W
,NO
,FP_TMP(0),0,0);
2159 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2160 ctx
->Driver
.Fogfv( ctx
, GL_FOG_MODE
, NULL
);
2161 ctx
->Driver
.Fogfv( ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2162 ctx
->Driver
.Fogfv( ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2163 ctx
->Driver
.Fogfv( ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2164 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2165 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2167 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
2168 r300
->hw
.unk4BD8
.cmd
[1] = 0;
2170 r300
->hw
.unk4E00
.cmd
[1] = 0;
2173 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = 0;
2174 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = 0;
2177 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2178 r300
->hw
.blend_color
.cmd
[2] = 0;
2179 r300
->hw
.blend_color
.cmd
[3] = 0;
2181 /* Again, r300ClearBuffer uses this */
2182 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = r300
->radeon
.state
.color
.drawOffset
+
2183 r300
->radeon
.radeonScreen
->fbLocation
;
2184 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.state
.color
.drawPitch
;
2186 if (r300
->radeon
.radeonScreen
->cpp
== 4)
2187 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
2189 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
2191 if (r300
->radeon
.sarea
->tiling_enabled
)
2192 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
2194 r300
->hw
.unk4E50
.cmd
[1] = 0;
2195 r300
->hw
.unk4E50
.cmd
[2] = 0;
2196 r300
->hw
.unk4E50
.cmd
[3] = 0;
2197 r300
->hw
.unk4E50
.cmd
[4] = 0;
2198 r300
->hw
.unk4E50
.cmd
[5] = 0;
2199 r300
->hw
.unk4E50
.cmd
[6] = 0;
2200 r300
->hw
.unk4E50
.cmd
[7] = 0;
2201 r300
->hw
.unk4E50
.cmd
[8] = 0;
2202 r300
->hw
.unk4E50
.cmd
[9] = 0;
2204 r300
->hw
.unk4E88
.cmd
[1] = 0;
2206 r300
->hw
.unk4EA0
.cmd
[1] = 0x00000000;
2207 r300
->hw
.unk4EA0
.cmd
[2] = 0xffffffff;
2209 switch (ctx
->Visual
.depthBits
) {
2211 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTH_FORMAT_16BIT_INT_Z
;
2214 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTH_FORMAT_24BIT_INT_Z
;
2217 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2218 ctx
->Visual
.depthBits
);
2223 //r300->hw.zstencil_format.cmd[1] |= R300_DEPTH_FORMAT_UNK32;
2225 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
2226 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
2228 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
2229 r300
->radeon
.radeonScreen
->depthOffset
+
2230 r300
->radeon
.radeonScreen
->fbLocation
;
2231 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
2233 if (r300
->radeon
.sarea
->tiling_enabled
) {
2234 /* Turn off when clearing buffers ? */
2235 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_TILE_ENABLE
;
2237 if (ctx
->Visual
.depthBits
== 24)
2238 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_MICROTILE_ENABLE
;
2241 r300
->hw
.unk4F28
.cmd
[1] = 0;
2243 r300
->hw
.unk4F30
.cmd
[1] = 0;
2244 r300
->hw
.unk4F30
.cmd
[2] = 0;
2246 r300
->hw
.unk4F44
.cmd
[1] = 0;
2248 r300
->hw
.unk4F54
.cmd
[1] = 0;
2251 ((drm_r300_cmd_header_t
*)r300
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2252 for(i
= 1; i
< R300_VPI_CMDSIZE
; i
+= 4) {
2254 r300
->hw
.vpi
.cmd
[i
+0] = VP_OUT(ADD
,TMP
,0,XYZW
);
2255 r300
->hw
.vpi
.cmd
[i
+1] = VP_IN(TMP
,0);
2256 r300
->hw
.vpi
.cmd
[i
+2] = VP_ZERO();
2257 r300
->hw
.vpi
.cmd
[i
+3] = VP_ZERO();
2260 ((drm_r300_cmd_header_t
*)r300
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2261 for(i
= 1; i
< R300_VPP_CMDSIZE
; ++i
)
2262 r300
->hw
.vpp
.cmd
[i
] = 0;
2265 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2266 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2267 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2268 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2271 r300
->hw
.all_dirty
= GL_TRUE
;
2277 * Calculate initial hardware state and register state functions.
2278 * Assumes that the command buffer and state atoms have been
2279 * initialized already.
2281 void r300InitState(r300ContextPtr r300
)
2283 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2286 radeonInitState(&r300
->radeon
);
2288 switch (ctx
->Visual
.depthBits
) {
2290 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2291 depth_fmt
= R300_DEPTH_FORMAT_16BIT_INT_Z
;
2292 r300
->state
.stencil
.clear
= 0x00000000;
2295 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2296 depth_fmt
= R300_DEPTH_FORMAT_24BIT_INT_Z
;
2297 r300
->state
.stencil
.clear
= 0x00ff0000;
2300 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2301 ctx
->Visual
.depthBits
);
2305 /* Only have hw stencil when depth buffer is 24 bits deep */
2306 r300
->state
.stencil
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2307 ctx
->Visual
.depthBits
== 24);
2309 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2311 r300ResetHwState(r300
);
2314 static void r300RenderMode( GLcontext
*ctx
, GLenum mode
)
2316 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2322 * Initialize driver's state callback functions
2324 void r300InitStateFuncs(struct dd_function_table
* functions
)
2326 radeonInitStateFuncs(functions
);
2328 functions
->UpdateState
= r300InvalidateState
;
2329 functions
->AlphaFunc
= r300AlphaFunc
;
2330 functions
->BlendColor
= r300BlendColor
;
2331 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2332 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2333 functions
->Enable
= r300Enable
;
2334 functions
->ColorMask
= r300ColorMask
;
2335 functions
->DepthFunc
= r300DepthFunc
;
2336 functions
->DepthMask
= r300DepthMask
;
2337 functions
->CullFace
= r300CullFace
;
2338 functions
->Fogfv
= r300Fogfv
;
2339 functions
->FrontFace
= r300FrontFace
;
2340 functions
->ShadeModel
= r300ShadeModel
;
2342 /* Stencil related */
2343 functions
->ClearStencil
= r300ClearStencil
;
2344 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2345 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2346 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2348 /* Viewport related */
2349 functions
->Viewport
= r300Viewport
;
2350 functions
->DepthRange
= r300DepthRange
;
2351 functions
->PointSize
= r300PointSize
;
2352 functions
->LineWidth
= r300LineWidth
;
2354 functions
->PolygonOffset
= r300PolygonOffset
;
2355 functions
->PolygonMode
= r300PolygonMode
;
2357 functions
->RenderMode
= r300RenderMode
;