2 Copyright (C) The Weather Channel, Inc. 2002.
3 Copyright (C) 2004 Nicolai Haehnle.
6 The Weather Channel (TM) funded Tungsten Graphics to develop the
7 initial release of the Radeon 8500 driver under the XFree86 license.
8 This notice must be preserved.
10 Permission is hereby granted, free of charge, to any person obtaining
11 a copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sublicense, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial
20 portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
34 * Nicolai Haehnle <prefect_@gmx.net>
44 #include "simple_list.h"
46 #include "api_arrayelt.h"
47 #include "swrast/swrast.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "shader/prog_parameter.h"
50 #include "shader/prog_statevars.h"
53 #include "texformat.h"
55 #include "radeon_ioctl.h"
56 #include "radeon_state.h"
57 #include "r300_context.h"
58 #include "r300_ioctl.h"
59 #include "r300_state.h"
61 #include "r300_emit.h"
62 #include "r300_fragprog.h"
64 #include "r300_maos.h"
66 #include "drirenderbuffer.h"
68 static void r300BlendColor(GLcontext
* ctx
, const GLfloat cf
[4])
71 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
73 R300_STATECHANGE(rmesa
, blend_color
);
75 CLAMPED_FLOAT_TO_UBYTE(color
[0], cf
[0]);
76 CLAMPED_FLOAT_TO_UBYTE(color
[1], cf
[1]);
77 CLAMPED_FLOAT_TO_UBYTE(color
[2], cf
[2]);
78 CLAMPED_FLOAT_TO_UBYTE(color
[3], cf
[3]);
80 rmesa
->hw
.blend_color
.cmd
[1] = PACK_COLOR_8888(color
[3], color
[0],
85 * Calculate the hardware blend factor setting. This same function is used
86 * for source and destination of both alpha and RGB.
89 * The hardware register value for the specified blend factor. This value
90 * will need to be shifted into the correct position for either source or
94 * Since the two cases where source and destination are handled differently
95 * are essentially error cases, they should never happen. Determine if these
96 * cases can be removed.
98 static int blend_factor(GLenum factor
, GLboolean is_src
)
104 func
= R300_BLEND_GL_ZERO
;
107 func
= R300_BLEND_GL_ONE
;
110 func
= R300_BLEND_GL_DST_COLOR
;
112 case GL_ONE_MINUS_DST_COLOR
:
113 func
= R300_BLEND_GL_ONE_MINUS_DST_COLOR
;
116 func
= R300_BLEND_GL_SRC_COLOR
;
118 case GL_ONE_MINUS_SRC_COLOR
:
119 func
= R300_BLEND_GL_ONE_MINUS_SRC_COLOR
;
122 func
= R300_BLEND_GL_SRC_ALPHA
;
124 case GL_ONE_MINUS_SRC_ALPHA
:
125 func
= R300_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
128 func
= R300_BLEND_GL_DST_ALPHA
;
130 case GL_ONE_MINUS_DST_ALPHA
:
131 func
= R300_BLEND_GL_ONE_MINUS_DST_ALPHA
;
133 case GL_SRC_ALPHA_SATURATE
:
134 func
= (is_src
) ? R300_BLEND_GL_SRC_ALPHA_SATURATE
:
137 case GL_CONSTANT_COLOR
:
138 func
= R300_BLEND_GL_CONST_COLOR
;
140 case GL_ONE_MINUS_CONSTANT_COLOR
:
141 func
= R300_BLEND_GL_ONE_MINUS_CONST_COLOR
;
143 case GL_CONSTANT_ALPHA
:
144 func
= R300_BLEND_GL_CONST_ALPHA
;
146 case GL_ONE_MINUS_CONSTANT_ALPHA
:
147 func
= R300_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
150 fprintf(stderr
, "unknown blend factor %x\n", factor
);
151 func
= (is_src
) ? R300_BLEND_GL_ONE
: R300_BLEND_GL_ZERO
;
157 * Sets both the blend equation and the blend function.
158 * This is done in a single
159 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
160 * change the interpretation of the blend function.
161 * Also, make sure that blend function and blend equation are set to their
162 * default value if color blending is not enabled, since at least blend
163 * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results
164 * otherwise for unknown reasons.
167 /* helper function */
168 static void r300SetBlendCntl(r300ContextPtr r300
, int func
, int eqn
,
169 int cbits
, int funcA
, int eqnA
)
171 GLuint new_ablend
, new_cblend
;
175 "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n",
176 eqnA
, funcA
, eqn
, func
, cbits
);
178 new_ablend
= eqnA
| funcA
;
179 new_cblend
= eqn
| func
;
181 /* Some blend factor combinations don't seem to work when the
182 * BLEND_NO_SEPARATE bit is set.
184 * Especially problematic candidates are the ONE_MINUS_* flags,
185 * but I can't see a real pattern.
188 if (new_ablend
== new_cblend
) {
189 new_cblend
|= R300_BLEND_NO_SEPARATE
;
194 if ((new_ablend
!= r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]) ||
195 (new_cblend
!= r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
])) {
196 R300_STATECHANGE(r300
, bld
);
197 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = new_ablend
;
198 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = new_cblend
;
202 static void r300SetBlendState(GLcontext
* ctx
)
204 r300ContextPtr r300
= R300_CONTEXT(ctx
);
205 int func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
206 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
207 int eqn
= R300_COMB_FCN_ADD_CLAMP
;
208 int funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
209 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
210 int eqnA
= R300_COMB_FCN_ADD_CLAMP
;
212 if (RGBA_LOGICOP_ENABLED(ctx
) || !ctx
->Color
.BlendEnabled
) {
213 r300SetBlendCntl(r300
, func
, eqn
, 0, func
, eqn
);
218 (blend_factor(ctx
->Color
.BlendSrcRGB
, GL_TRUE
) <<
219 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstRGB
,
221 R300_DST_BLEND_SHIFT
);
223 switch (ctx
->Color
.BlendEquationRGB
) {
225 eqn
= R300_COMB_FCN_ADD_CLAMP
;
228 case GL_FUNC_SUBTRACT
:
229 eqn
= R300_COMB_FCN_SUB_CLAMP
;
232 case GL_FUNC_REVERSE_SUBTRACT
:
233 eqn
= R300_COMB_FCN_RSUB_CLAMP
;
237 eqn
= R300_COMB_FCN_MIN
;
238 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
239 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
243 eqn
= R300_COMB_FCN_MAX
;
244 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
245 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
250 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
251 __func__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
256 (blend_factor(ctx
->Color
.BlendSrcA
, GL_TRUE
) <<
257 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstA
,
259 R300_DST_BLEND_SHIFT
);
261 switch (ctx
->Color
.BlendEquationA
) {
263 eqnA
= R300_COMB_FCN_ADD_CLAMP
;
266 case GL_FUNC_SUBTRACT
:
267 eqnA
= R300_COMB_FCN_SUB_CLAMP
;
270 case GL_FUNC_REVERSE_SUBTRACT
:
271 eqnA
= R300_COMB_FCN_RSUB_CLAMP
;
275 eqnA
= R300_COMB_FCN_MIN
;
276 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
277 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
281 eqnA
= R300_COMB_FCN_MAX
;
282 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
283 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
288 "[%s:%u] Invalid A blend equation (0x%04x).\n",
289 __func__
, __LINE__
, ctx
->Color
.BlendEquationA
);
293 r300SetBlendCntl(r300
,
295 R300_BLEND_UNKNOWN
| R300_BLEND_ENABLE
, funcA
, eqnA
);
298 static void r300BlendEquationSeparate(GLcontext
* ctx
,
299 GLenum modeRGB
, GLenum modeA
)
301 r300SetBlendState(ctx
);
304 static void r300BlendFuncSeparate(GLcontext
* ctx
,
305 GLenum sfactorRGB
, GLenum dfactorRGB
,
306 GLenum sfactorA
, GLenum dfactorA
)
308 r300SetBlendState(ctx
);
312 * Update our tracked culling state based on Mesa's state.
314 static void r300UpdateCulling(GLcontext
* ctx
)
316 r300ContextPtr r300
= R300_CONTEXT(ctx
);
319 R300_STATECHANGE(r300
, cul
);
320 if (ctx
->Polygon
.CullFlag
) {
321 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
)
322 val
= R300_CULL_FRONT
| R300_CULL_BACK
;
323 else if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
324 val
= R300_CULL_FRONT
;
326 val
= R300_CULL_BACK
;
328 if (ctx
->Polygon
.FrontFace
== GL_CW
)
329 val
|= R300_FRONT_FACE_CW
;
331 val
|= R300_FRONT_FACE_CCW
;
333 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
336 static void update_early_z(GLcontext
* ctx
)
338 /* updates register R300_RB3D_EARLY_Z (0x4F14)
339 if depth test is not enabled it should be R300_EARLY_Z_DISABLE
340 if depth is enabled and alpha not it should be R300_EARLY_Z_ENABLE
341 if depth and alpha is enabled it should be R300_EARLY_Z_DISABLE
343 r300ContextPtr r300
= R300_CONTEXT(ctx
);
345 R300_STATECHANGE(r300
, zstencil_format
);
346 if (ctx
->Color
.AlphaEnabled
&& ctx
->Color
.AlphaFunc
!= GL_ALWAYS
)
347 /* disable early Z */
348 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_DISABLE
;
350 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
)
352 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_ENABLE
;
354 /* disable early Z */
355 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_DISABLE
;
359 static void update_alpha(GLcontext
* ctx
)
361 r300ContextPtr r300
= R300_CONTEXT(ctx
);
363 uint32_t pp_misc
= 0x0;
364 GLboolean really_enabled
= ctx
->Color
.AlphaEnabled
;
366 CLAMPED_FLOAT_TO_UBYTE(refByte
, ctx
->Color
.AlphaRef
);
368 switch (ctx
->Color
.AlphaFunc
) {
370 pp_misc
|= R300_ALPHA_TEST_FAIL
;
373 pp_misc
|= R300_ALPHA_TEST_LESS
;
376 pp_misc
|= R300_ALPHA_TEST_EQUAL
;
379 pp_misc
|= R300_ALPHA_TEST_LEQUAL
;
382 pp_misc
|= R300_ALPHA_TEST_GREATER
;
385 pp_misc
|= R300_ALPHA_TEST_NEQUAL
;
388 pp_misc
|= R300_ALPHA_TEST_GEQUAL
;
391 /*pp_misc |= R300_ALPHA_TEST_PASS; */
392 really_enabled
= GL_FALSE
;
396 if (really_enabled
) {
397 pp_misc
|= R300_ALPHA_TEST_ENABLE
;
398 pp_misc
|= (refByte
& R300_REF_ALPHA_MASK
);
403 R300_STATECHANGE(r300
, at
);
404 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
408 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
415 static int translate_func(int func
)
419 return R300_ZS_NEVER
;
423 return R300_ZS_EQUAL
;
425 return R300_ZS_LEQUAL
;
427 return R300_ZS_GREATER
;
429 return R300_ZS_NOTEQUAL
;
431 return R300_ZS_GEQUAL
;
433 return R300_ZS_ALWAYS
;
438 static void update_depth(GLcontext
* ctx
)
440 r300ContextPtr r300
= R300_CONTEXT(ctx
);
442 R300_STATECHANGE(r300
, zs
);
443 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_RB3D_STENCIL_ENABLE
;
444 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
445 ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
447 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
) {
449 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
450 R300_RB3D_Z_TEST_AND_WRITE
;
452 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_TEST
;
454 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
455 translate_func(ctx
->Depth
.
456 Func
) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
458 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_DISABLED_1
;
459 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
460 translate_func(GL_NEVER
) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
467 * Handle glEnable()/glDisable().
469 * \note Mesa already filters redundant calls to glEnable/glDisable.
471 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
473 r300ContextPtr r300
= R300_CONTEXT(ctx
);
475 if (RADEON_DEBUG
& DEBUG_STATE
)
476 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
477 _mesa_lookup_enum_by_nr(cap
),
478 state
? "GL_TRUE" : "GL_FALSE");
481 /* Fast track this one...
489 R300_STATECHANGE(r300
, fogs
);
491 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] |= R300_FOG_ENABLE
;
493 ctx
->Driver
.Fogfv(ctx
, GL_FOG_MODE
, NULL
);
494 ctx
->Driver
.Fogfv(ctx
, GL_FOG_DENSITY
,
496 ctx
->Driver
.Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
497 ctx
->Driver
.Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
498 ctx
->Driver
.Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
500 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] &= ~R300_FOG_ENABLE
;
510 case GL_COLOR_LOGIC_OP
:
511 r300SetBlendState(ctx
);
518 case GL_STENCIL_TEST
:
519 if (r300
->state
.stencil
.hw_stencil
) {
520 R300_STATECHANGE(r300
, zs
);
522 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
523 R300_RB3D_STENCIL_ENABLE
;
525 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
526 ~R300_RB3D_STENCIL_ENABLE
;
530 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
536 r300UpdateCulling(ctx
);
539 case GL_POLYGON_OFFSET_POINT
:
540 case GL_POLYGON_OFFSET_LINE
:
543 case GL_POLYGON_OFFSET_FILL
:
544 R300_STATECHANGE(r300
, occlusion_cntl
);
546 r300
->hw
.occlusion_cntl
.cmd
[1] |= (3 << 0);
548 r300
->hw
.occlusion_cntl
.cmd
[1] &= ~(3 << 0);
552 radeonEnable(ctx
, cap
, state
);
557 static void r300UpdatePolygonMode(GLcontext
* ctx
)
559 r300ContextPtr r300
= R300_CONTEXT(ctx
);
560 uint32_t hw_mode
= 0;
562 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
563 ctx
->Polygon
.BackMode
!= GL_FILL
) {
566 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
567 f
= ctx
->Polygon
.FrontMode
;
568 b
= ctx
->Polygon
.BackMode
;
570 f
= ctx
->Polygon
.BackMode
;
571 b
= ctx
->Polygon
.FrontMode
;
574 hw_mode
|= R300_PM_ENABLED
;
578 hw_mode
|= R300_PM_FRONT_LINE
;
580 case GL_POINT
: /* noop */
581 hw_mode
|= R300_PM_FRONT_POINT
;
584 hw_mode
|= R300_PM_FRONT_FILL
;
590 hw_mode
|= R300_PM_BACK_LINE
;
592 case GL_POINT
: /* noop */
593 hw_mode
|= R300_PM_BACK_POINT
;
596 hw_mode
|= R300_PM_BACK_FILL
;
601 if (r300
->hw
.polygon_mode
.cmd
[1] != hw_mode
) {
602 R300_STATECHANGE(r300
, polygon_mode
);
603 r300
->hw
.polygon_mode
.cmd
[1] = hw_mode
;
608 * Change the culling mode.
610 * \note Mesa already filters redundant calls to this function.
612 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
616 r300UpdateCulling(ctx
);
620 * Change the polygon orientation.
622 * \note Mesa already filters redundant calls to this function.
624 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
628 r300UpdateCulling(ctx
);
629 r300UpdatePolygonMode(ctx
);
633 * Change the depth testing function.
635 * \note Mesa already filters redundant calls to this function.
637 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
644 * Enable/Disable depth writing.
646 * \note Mesa already filters redundant calls to this function.
648 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
655 * Handle glColorMask()
657 static void r300ColorMask(GLcontext
* ctx
,
658 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
660 r300ContextPtr r300
= R300_CONTEXT(ctx
);
661 int mask
= (r
? R300_COLORMASK0_R
: 0) |
662 (g
? R300_COLORMASK0_G
: 0) |
663 (b
? R300_COLORMASK0_B
: 0) | (a
? R300_COLORMASK0_A
: 0);
665 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
666 R300_STATECHANGE(r300
, cmk
);
667 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
671 /* =============================================================
674 static void r300Fogfv(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
676 r300ContextPtr r300
= R300_CONTEXT(ctx
);
680 } fogScale
, fogStart
;
684 fogScale
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
];
685 fogStart
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_START
];
689 if (!ctx
->Fog
.Enabled
)
691 switch (ctx
->Fog
.Mode
) {
693 R300_STATECHANGE(r300
, fogs
);
694 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
696 cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) |
697 R300_FOG_MODE_LINEAR
;
699 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
704 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
706 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
711 R300_STATECHANGE(r300
, fogs
);
712 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
714 cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) |
716 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
720 R300_STATECHANGE(r300
, fogs
);
721 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
723 cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) |
725 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
732 switch (ctx
->Fog
.Mode
) {
734 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
738 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
746 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
747 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
752 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
754 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
760 R300_STATECHANGE(r300
, fogc
);
761 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] =
762 (GLuint
) (ctx
->Fog
.Color
[0] * 1023.0F
) & 0x3FF;
763 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] =
764 (GLuint
) (ctx
->Fog
.Color
[1] * 1023.0F
) & 0x3FF;
765 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] =
766 (GLuint
) (ctx
->Fog
.Color
[2] * 1023.0F
) & 0x3FF;
768 case GL_FOG_COORD_SRC
:
774 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
775 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
776 R300_STATECHANGE(r300
, fogp
);
777 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
778 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
782 /* =============================================================
785 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
787 r300ContextPtr r300
= R300_CONTEXT(ctx
);
789 size
= ctx
->Point
._Size
;
791 R300_STATECHANGE(r300
, ps
);
792 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
793 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
794 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
797 /* =============================================================
800 static void r300LineWidth(GLcontext
* ctx
, GLfloat widthf
)
802 r300ContextPtr r300
= R300_CONTEXT(ctx
);
804 widthf
= ctx
->Line
._Width
;
806 R300_STATECHANGE(r300
, lcntl
);
807 r300
->hw
.lcntl
.cmd
[1] = (int)(widthf
* 6.0);
808 r300
->hw
.lcntl
.cmd
[1] |= R300_LINE_CNT_VE
;
811 static void r300PolygonMode(GLcontext
* ctx
, GLenum face
, GLenum mode
)
816 r300UpdatePolygonMode(ctx
);
819 /* =============================================================
823 static int translate_stencil_op(int op
)
831 return R300_ZS_REPLACE
;
836 case GL_INCR_WRAP_EXT
:
837 return R300_ZS_INCR_WRAP
;
838 case GL_DECR_WRAP_EXT
:
839 return R300_ZS_DECR_WRAP
;
841 return R300_ZS_INVERT
;
843 WARN_ONCE("Do not know how to translate stencil op");
849 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
851 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
853 R300_STATECHANGE(rmesa
, shade
);
856 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
859 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
866 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
867 GLenum func
, GLint ref
, GLuint mask
)
869 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
872 Ref
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_REF_SHIFT
) | ((ctx
->
878 R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
882 R300_STATECHANGE(rmesa
, zs
);
884 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~((R300_ZS_MASK
<<
885 R300_RB3D_ZS1_FRONT_FUNC_SHIFT
)
887 R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
889 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
890 ~((R300_RB3D_ZS2_STENCIL_MASK
<<
891 R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
892 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
894 flag
= translate_func(ctx
->Stencil
.Function
[0]);
895 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
896 (flag
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
);
898 if (ctx
->Stencil
._TestTwoSide
)
899 flag
= translate_func(ctx
->Stencil
.Function
[1]);
901 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
902 (flag
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
903 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
906 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
908 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
910 R300_STATECHANGE(rmesa
, zs
);
911 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
912 ~(R300_RB3D_ZS2_STENCIL_MASK
<<
913 R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
);
914 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |=
916 WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
;
919 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
,
920 GLenum fail
, GLenum zfail
, GLenum zpass
)
922 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
924 R300_STATECHANGE(rmesa
, zs
);
925 /* It is easier to mask what's left.. */
926 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
927 (R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
) |
928 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
929 (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
931 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
932 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
933 R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
)
934 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
935 R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
)
936 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
937 R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
);
939 if (ctx
->Stencil
._TestTwoSide
) {
940 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
941 (translate_stencil_op(ctx
->Stencil
.FailFunc
[1]) <<
942 R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
943 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[1]) <<
944 R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
945 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[1]) <<
946 R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
948 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
949 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
950 R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
951 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
952 R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
953 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
954 R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
958 static void r300ClearStencil(GLcontext
* ctx
, GLint s
)
960 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
962 rmesa
->state
.stencil
.clear
=
963 ((GLuint
) (ctx
->Stencil
.Clear
& 0xff) |
964 (R300_RB3D_ZS2_STENCIL_MASK
<<
965 R300_RB3D_ZS2_STENCIL_MASK_SHIFT
) | ((ctx
->Stencil
.
966 WriteMask
[0] & 0xff) <<
967 R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
));
970 /* =============================================================
971 * Window position and viewport transformation
975 * To correctly position primitives:
977 #define SUBPIXEL_X 0.125
978 #define SUBPIXEL_Y 0.125
980 void r300UpdateWindow(GLcontext
* ctx
)
982 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
983 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
984 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
985 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
986 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
988 GLfloat sx
= v
[MAT_SX
];
989 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
990 GLfloat sy
= -v
[MAT_SY
];
991 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
992 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
993 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
995 R300_FIREVERTICES(rmesa
);
996 R300_STATECHANGE(rmesa
, vpt
);
998 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
999 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1000 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
1001 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1002 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
1003 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
1006 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
1007 GLsizei width
, GLsizei height
)
1009 /* Don't pipeline viewport changes, conflict with window offset
1010 * setting below. Could apply deltas to rescue pipelined viewport
1011 * values, or keep the originals hanging around.
1013 r300UpdateWindow(ctx
);
1016 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
1018 r300UpdateWindow(ctx
);
1021 void r300UpdateViewportOffset(GLcontext
* ctx
)
1023 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1024 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
) rmesa
)->dri
.drawable
;
1025 GLfloat xoffset
= (GLfloat
) dPriv
->x
;
1026 GLfloat yoffset
= (GLfloat
) dPriv
->y
+ dPriv
->h
;
1027 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1029 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1030 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1032 if (rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
1033 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
)) {
1034 /* Note: this should also modify whatever data the context reset
1037 R300_STATECHANGE(rmesa
, vpt
);
1038 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1039 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1043 radeonUpdateScissor(ctx
);
1047 * Tell the card where to render (offset, pitch).
1048 * Effected by glDrawBuffer, etc
1050 void r300UpdateDrawBuffer(GLcontext
* ctx
)
1052 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1053 r300ContextPtr r300
= rmesa
;
1054 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1055 driRenderbuffer
*drb
;
1057 if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
) {
1060 (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].
1062 } else if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_BACK_LEFT
) {
1065 (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].
1068 /* drawing to multiple buffers, or none */
1073 assert(drb
->flippedPitch
);
1075 R300_STATECHANGE(rmesa
, cb
);
1077 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = drb
->flippedOffset
+ //r300->radeon.state.color.drawOffset +
1078 r300
->radeon
.radeonScreen
->fbLocation
;
1079 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = drb
->flippedPitch
; //r300->radeon.state.color.drawPitch;
1081 if (r300
->radeon
.radeonScreen
->cpp
== 4)
1082 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
1084 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
1086 if (r300
->radeon
.sarea
->tiling_enabled
)
1087 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
1089 R200_STATECHANGE(rmesa
, ctx
);
1091 /* Note: we used the (possibly) page-flipped values */
1092 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
1093 = ((drb
->flippedOffset
+ rmesa
->r200Screen
->fbLocation
)
1094 & R200_COLOROFFSET_MASK
);
1095 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
1097 if (rmesa
->sarea
->tiling_enabled
) {
1098 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |=
1099 R200_COLOR_TILE_ENABLE
;
1105 r300FetchStateParameter(GLcontext
* ctx
,
1106 const gl_state_index state
[STATE_LENGTH
],
1109 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1112 case STATE_INTERNAL
:
1114 case STATE_R300_WINDOW_DIMENSION
:
1115 value
[0] = r300
->radeon
.dri
.drawable
->w
* 0.5f
; /* width*0.5 */
1116 value
[1] = r300
->radeon
.dri
.drawable
->h
* 0.5f
; /* height*0.5 */
1117 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1118 value
[3] = 1.0F
; /* not used */
1121 case STATE_R300_TEXRECT_FACTOR
:{
1122 struct gl_texture_object
*t
=
1123 ctx
->Texture
.Unit
[state
[2]].CurrentRect
;
1125 if (t
&& t
->Image
[0][t
->BaseLevel
]) {
1126 struct gl_texture_image
*image
=
1127 t
->Image
[0][t
->BaseLevel
];
1128 value
[0] = 1.0 / image
->Width2
;
1129 value
[1] = 1.0 / image
->Height2
;
1150 * Update R300's own internal state parameters.
1151 * For now just STATE_R300_WINDOW_DIMENSION
1153 void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1155 struct r300_fragment_program
*fp
;
1156 struct gl_program_parameter_list
*paramList
;
1159 if (!(new_state
& (_NEW_BUFFERS
| _NEW_PROGRAM
)))
1162 fp
= (struct r300_fragment_program
*)ctx
->FragmentProgram
._Current
;
1166 paramList
= fp
->mesa_program
.Base
.Parameters
;
1171 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1172 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
) {
1173 r300FetchStateParameter(ctx
,
1174 paramList
->Parameters
[i
].
1176 paramList
->ParameterValues
[i
]);
1181 /* =============================================================
1184 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1186 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1187 GLfloat constant
= units
;
1189 switch (ctx
->Visual
.depthBits
) {
1200 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1202 R300_STATECHANGE(rmesa
, zbs
);
1203 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1204 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1205 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1206 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1209 /* Routing and texture-related */
1211 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1212 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1213 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1214 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1215 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1216 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1217 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1218 * combinations where only one of them is nearest.
1220 static unsigned long gen_fixed_filter(unsigned long f
)
1222 unsigned long mag
, min
, needs_fixing
= 0;
1225 /* We ignore MIRROR bit so we dont have to do everything twice */
1226 if ((f
& ((7 - 1) << R300_TX_WRAP_S_SHIFT
)) ==
1227 (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)) {
1230 if ((f
& ((7 - 1) << R300_TX_WRAP_T_SHIFT
)) ==
1231 (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)) {
1234 if ((f
& ((7 - 1) << R300_TX_WRAP_Q_SHIFT
)) ==
1235 (R300_TX_CLAMP
<< R300_TX_WRAP_Q_SHIFT
)) {
1242 mag
= f
& R300_TX_MAG_FILTER_MASK
;
1243 min
= f
& R300_TX_MIN_FILTER_MASK
;
1245 /* TODO: Check for anisto filters too */
1246 if ((mag
!= R300_TX_MAG_FILTER_NEAREST
)
1247 && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1250 /* r300 cant handle these modes hence we force nearest to linear */
1251 if ((mag
== R300_TX_MAG_FILTER_NEAREST
)
1252 && (min
!= R300_TX_MIN_FILTER_NEAREST
)) {
1253 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1254 f
|= R300_TX_MAG_FILTER_LINEAR
;
1258 if ((min
== R300_TX_MIN_FILTER_NEAREST
)
1259 && (mag
!= R300_TX_MAG_FILTER_NEAREST
)) {
1260 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1261 f
|= R300_TX_MIN_FILTER_LINEAR
;
1265 /* Both are nearest */
1266 if (needs_fixing
& 1) {
1267 f
&= ~((7 - 1) << R300_TX_WRAP_S_SHIFT
);
1268 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1270 if (needs_fixing
& 2) {
1271 f
&= ~((7 - 1) << R300_TX_WRAP_T_SHIFT
);
1272 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1274 if (needs_fixing
& 4) {
1275 f
&= ~((7 - 1) << R300_TX_WRAP_Q_SHIFT
);
1276 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_Q_SHIFT
;
1281 static void r300SetupTextures(GLcontext
* ctx
)
1284 struct r300_tex_obj
*t
;
1285 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1287 int last_hw_tmu
= -1; /* -1 translates into no setup costs for fields */
1288 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1, };
1289 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1290 (char *)ctx
->FragmentProgram
._Current
;
1292 R300_STATECHANGE(r300
, txe
);
1293 R300_STATECHANGE(r300
, tex
.filter
);
1294 R300_STATECHANGE(r300
, tex
.filter_1
);
1295 R300_STATECHANGE(r300
, tex
.size
);
1296 R300_STATECHANGE(r300
, tex
.format
);
1297 R300_STATECHANGE(r300
, tex
.pitch
);
1298 R300_STATECHANGE(r300
, tex
.offset
);
1299 R300_STATECHANGE(r300
, tex
.chroma_key
);
1300 R300_STATECHANGE(r300
, tex
.border_color
);
1302 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] = 0x0;
1304 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1305 if (RADEON_DEBUG
& DEBUG_STATE
)
1306 fprintf(stderr
, "mtu=%d\n", mtu
);
1308 if (mtu
> R300_MAX_TEXTURE_UNITS
) {
1310 "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1311 mtu
, R300_MAX_TEXTURE_UNITS
);
1315 /* We cannot let disabled tmu offsets pass DRM */
1316 for (i
= 0; i
< mtu
; i
++) {
1317 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
1319 #if 0 /* Enables old behaviour */
1322 tmu_mappings
[i
] = hw_tmu
;
1324 t
= r300
->state
.texture
.unit
[i
].texobj
;
1325 /* XXX questionable fix for bug 9170: */
1329 if ((t
->format
& 0xffffff00) == 0xffffff00) {
1331 ("unknown texture format (entry %x) encountered. Help me !\n",
1335 if (RADEON_DEBUG
& DEBUG_STATE
)
1337 "Activating texture unit %d\n", i
);
1339 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1341 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+
1343 gen_fixed_filter(t
->filter
) | (hw_tmu
<< 28);
1344 /* Currently disabled! */
1345 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0; //0x20501f80;
1346 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1348 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+
1349 hw_tmu
] = t
->format
;
1350 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1352 r300
->hw
.tex
.offset
.cmd
[R300_TEX_VALUE_0
+
1353 hw_tmu
] = t
->offset
;
1355 if (t
->offset
& R300_TXO_MACRO_TILE
) {
1356 WARN_ONCE("macro tiling enabled!\n");
1359 if (t
->offset
& R300_TXO_MICRO_TILE
) {
1360 WARN_ONCE("micro tiling enabled!\n");
1363 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_VALUE_0
+
1365 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+
1369 last_hw_tmu
= hw_tmu
;
1375 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1376 cmdpacket0(R300_TX_FILTER_0
, last_hw_tmu
+ 1);
1377 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] =
1378 cmdpacket0(R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1379 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] =
1380 cmdpacket0(R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1381 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] =
1382 cmdpacket0(R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1383 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] =
1384 cmdpacket0(R300_TX_PITCH_0
, last_hw_tmu
+ 1);
1385 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] =
1386 cmdpacket0(R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1387 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] =
1388 cmdpacket0(R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1389 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] =
1390 cmdpacket0(R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1392 if (!fp
) /* should only happenen once, just after context is created */
1395 R300_STATECHANGE(r300
, fpt
);
1397 for (i
= 0; i
< fp
->tex
.length
; i
++) {
1402 unit
= fp
->tex
.inst
[i
] >> R300_FPITX_IMAGE_SHIFT
;
1405 val
= fp
->tex
.inst
[i
];
1406 val
&= ~R300_FPITX_IMAGE_MASK
;
1409 (val
& R300_FPITX_OPCODE_MASK
) >> R300_FPITX_OPCODE_SHIFT
;
1410 if (opcode
== R300_FPITX_OP_KIL
) {
1411 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1413 if (tmu_mappings
[unit
] >= 0) {
1415 tmu_mappings
[unit
] <<
1416 R300_FPITX_IMAGE_SHIFT
;
1417 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1419 // We get here when the corresponding texture image is incomplete
1420 // (e.g. incomplete mipmaps etc.)
1421 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1426 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] =
1427 cmdpacket0(R300_PFS_TEXI_0
, fp
->tex
.length
);
1429 if (RADEON_DEBUG
& DEBUG_STATE
)
1430 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n",
1431 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1434 union r300_outputs_written
{
1435 GLuint vp_outputs
; /* hw_tcl_on */
1436 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1439 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1440 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1441 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1443 void r300SetupRSUnit(GLcontext
* ctx
)
1445 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1446 /* I'm still unsure if these are needed */
1447 GLuint interp_magic
[8] = {
1457 union r300_outputs_written OutputsWritten
;
1459 int fp_reg
, high_rr
;
1460 int in_texcoords
, col_interp_nr
;
1464 OutputsWritten
.vp_outputs
=
1465 CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1467 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
,
1468 r300
->state
.render_inputs_bitset
);
1470 if (ctx
->FragmentProgram
._Current
)
1471 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1473 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1474 return; /* This should only ever happen once.. */
1477 R300_STATECHANGE(r300
, ri
);
1478 R300_STATECHANGE(r300
, rc
);
1479 R300_STATECHANGE(r300
, rr
);
1481 fp_reg
= in_texcoords
= col_interp_nr
= high_rr
= 0;
1483 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] = 0;
1485 if (InputsRead
& FRAG_BIT_WPOS
) {
1486 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1487 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1490 if (i
== ctx
->Const
.MaxTextureUnits
) {
1491 fprintf(stderr
, "\tno free texcoord found...\n");
1495 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1496 InputsRead
&= ~FRAG_BIT_WPOS
;
1499 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1500 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = 0
1501 | R300_RS_INTERP_USED
1502 | (in_texcoords
<< R300_RS_INTERP_SRC_SHIFT
)
1505 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] = 0;
1506 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1507 //assert(r300->state.texture.tc_count != 0);
1508 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] |= R300_RS_ROUTE_ENABLE
| i
/* source INTERP */
1509 | (fp_reg
<< R300_RS_ROUTE_DEST_SHIFT
);
1512 if (!R300_OUTPUTS_WRITTEN_TEST
1513 (OutputsWritten
, VERT_RESULT_TEX0
+ i
,
1514 _TNL_ATTRIB_TEX(i
))) {
1515 /* Passing invalid data here can lock the GPU. */
1517 ("fragprog wants coords for tex%d, vp doesn't provide them!\n",
1519 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1522 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1525 /* Need to count all coords enabled at vof */
1526 if (R300_OUTPUTS_WRITTEN_TEST
1527 (OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
)))
1531 if (InputsRead
& FRAG_BIT_COL0
) {
1532 if (!R300_OUTPUTS_WRITTEN_TEST
1533 (OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1535 ("fragprog wants col0, vp doesn't provide it\n");
1536 goto out
; /* FIXME */
1537 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1541 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1542 | R300_RS_ROUTE_0_COLOR
1543 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1544 InputsRead
&= ~FRAG_BIT_COL0
;
1549 if (InputsRead
& FRAG_BIT_COL1
) {
1550 if (!R300_OUTPUTS_WRITTEN_TEST
1551 (OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1553 ("fragprog wants col1, vp doesn't provide it\n");
1557 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] |=
1558 R300_RS_ROUTE_1_UNKNOWN11
| R300_RS_ROUTE_1_COLOR1
|
1559 (fp_reg
++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT
);
1560 InputsRead
&= ~FRAG_BIT_COL1
;
1566 /* Need at least one. This might still lock as the values are undefined... */
1567 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1568 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1569 | R300_RS_ROUTE_0_COLOR
1570 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1574 r300
->hw
.rc
.cmd
[1] = 0 | (in_texcoords
<< R300_RS_CNTL_TC_CNT_SHIFT
)
1575 | (col_interp_nr
<< R300_RS_CNTL_CI_CNT_SHIFT
)
1576 | R300_RS_CNTL_0_UNKNOWN_18
;
1578 assert(high_rr
>= 0);
1579 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] =
1580 cmdpacket0(R300_RS_ROUTE_0
, high_rr
+ 1);
1581 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1584 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n",
1588 #define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
1590 #define bump_vpu_count(ptr, new_count) do{\
1591 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1592 int _nc=(new_count)/4; \
1593 assert(_nc < 256); \
1594 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1597 void static inline setup_vertex_shader_fragment(r300ContextPtr r300
, int dest
, struct
1598 r300_vertex_shader_fragment
1603 if (vsf
->length
== 0)
1606 if (vsf
->length
& 0x3) {
1608 "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1612 switch ((dest
>> 8) & 0xf) {
1614 R300_STATECHANGE(r300
, vpi
);
1615 for (i
= 0; i
< vsf
->length
; i
++)
1616 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+ i
+
1617 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1618 bump_vpu_count(r300
->hw
.vpi
.cmd
,
1619 vsf
->length
+ 4 * (dest
& 0xff));
1623 R300_STATECHANGE(r300
, vpp
);
1624 for (i
= 0; i
< vsf
->length
; i
++)
1625 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+ i
+
1626 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1627 bump_vpu_count(r300
->hw
.vpp
.cmd
,
1628 vsf
->length
+ 4 * (dest
& 0xff));
1631 R300_STATECHANGE(r300
, vps
);
1632 for (i
= 0; i
< vsf
->length
; i
++)
1633 r300
->hw
.vps
.cmd
[1 + i
+ 4 * (dest
& 0xff)] =
1635 bump_vpu_count(r300
->hw
.vps
.cmd
,
1636 vsf
->length
+ 4 * (dest
& 0xff));
1640 "%s:%s don't know how to handle dest %04x\n",
1641 __FILE__
, __FUNCTION__
, dest
);
1646 void r300SetupVertexProgram(r300ContextPtr rmesa
);
1648 /* just a skeleton for now.. */
1650 /* Generate a vertex shader that simply transforms vertex and texture coordinates,
1651 while leaving colors intact. Nothing fancy (like lights)
1653 If implementing lights make a copy first, so it is easy to switch between the two versions */
1654 static void r300GenerateSimpleVertexShader(r300ContextPtr r300
)
1659 /* Allocate parameters */
1660 r300
->state
.vap_param
.transform_offset
= 0x0; /* transform matrix */
1661 r300
->state
.vertex_shader
.param_offset
= 0x0;
1662 r300
->state
.vertex_shader
.param_count
= 0x4; /* 4 vector values - 4x4 matrix */
1664 r300
->state
.vertex_shader
.program_start
= 0x0;
1665 r300
->state
.vertex_shader
.unknown_ptr1
= 0x4; /* magic value ? */
1666 r300
->state
.vertex_shader
.program_end
= 0x0;
1668 r300
->state
.vertex_shader
.unknown_ptr2
= 0x0; /* magic value */
1669 r300
->state
.vertex_shader
.unknown_ptr3
= 0x4; /* magic value */
1671 r300
->state
.vertex_shader
.unknown1
.length
= 0;
1672 r300
->state
.vertex_shader
.unknown2
.length
= 0;
1674 #define WRITE_OP(oper,source1,source2,source3) {\
1675 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].op=(oper); \
1676 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src[0]=(source1); \
1677 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src[1]=(source2); \
1678 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src[2]=(source3); \
1679 r300->state.vertex_shader.program_end++; \
1682 for (i
= VERT_ATTRIB_POS
; i
< VERT_ATTRIB_MAX
; i
++)
1683 if (r300
->state
.sw_tcl_inputs
[i
] != -1) {
1684 WRITE_OP(EASY_VSF_OP(MUL
, o_reg
++, ALL
, RESULT
),
1685 VSF_REG(r300
->state
.sw_tcl_inputs
[i
]),
1686 VSF_ATTR_UNITY(r300
->state
.
1688 VSF_UNITY(r300
->state
.sw_tcl_inputs
[i
])
1693 r300
->state
.vertex_shader
.program_end
--; /* r300 wants program length to be one more - no idea why */
1694 r300
->state
.vertex_shader
.program
.length
=
1695 (r300
->state
.vertex_shader
.program_end
+ 1) * 4;
1697 r300
->state
.vertex_shader
.unknown_ptr1
= r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1698 r300
->state
.vertex_shader
.unknown_ptr2
= r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1699 r300
->state
.vertex_shader
.unknown_ptr3
= r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1703 void r300SetupVertexShader(r300ContextPtr rmesa
)
1705 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1707 /* Reset state, in case we don't use something */
1708 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1709 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1710 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1712 /* Not sure why this doesnt work...
1713 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
1714 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. */
1715 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
1717 && ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->
1719 r300SetupVertexProgram(rmesa
);
1723 /* This needs to be replaced by vertex shader generation code */
1724 r300GenerateSimpleVertexShader(rmesa
);
1726 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
,
1727 &(rmesa
->state
.vertex_shader
.program
));
1730 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
,
1731 &(rmesa
->state
.vertex_shader
.unknown1
));
1732 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
,
1733 &(rmesa
->state
.vertex_shader
.unknown2
));
1736 R300_STATECHANGE(rmesa
, pvs
);
1737 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
1738 (rmesa
->state
.vertex_shader
.
1739 program_start
<< R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1740 | (rmesa
->state
.vertex_shader
.
1741 unknown_ptr1
<< R300_PVS_CNTL_1_POS_END_SHIFT
)
1742 | (rmesa
->state
.vertex_shader
.
1743 program_end
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1744 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
1745 (rmesa
->state
.vertex_shader
.
1746 param_offset
<< R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1747 | (rmesa
->state
.vertex_shader
.
1748 param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1749 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
1750 (rmesa
->state
.vertex_shader
.
1751 unknown_ptr2
<< R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1752 | (rmesa
->state
.vertex_shader
.unknown_ptr3
<< 0);
1754 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1755 so I leave it as a reminder */
1757 reg_start(R300_VAP_PVS_WAITIDLE
, 0);
1762 void r300SetupVertexProgram(r300ContextPtr rmesa
)
1764 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1767 struct r300_vertex_program
*prog
=
1768 (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1770 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1771 R300_STATECHANGE(rmesa
, vpp
);
1773 r300VertexProgUpdateParams(ctx
, (struct r300_vertex_program_cont
*)
1774 ctx
->VertexProgram
._Current
/*prog */ ,
1775 (float *)&rmesa
->hw
.vpp
.
1776 cmd
[R300_VPP_PARAM_0
]);
1777 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
1780 /* Reset state, in case we don't use something */
1781 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1782 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1784 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(prog
->program
));
1787 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
,
1788 &(rmesa
->state
.vertex_shader
.unknown1
));
1789 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
,
1790 &(rmesa
->state
.vertex_shader
.unknown2
));
1793 inst_count
= prog
->program
.length
/ 4 - 1;
1795 R300_STATECHANGE(rmesa
, pvs
);
1796 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
1797 (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1798 | (inst_count
/*pos_end */ << R300_PVS_CNTL_1_POS_END_SHIFT
)
1799 | (inst_count
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1800 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
1801 (0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1802 | (param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1803 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
1804 (0 /*rmesa->state.vertex_shader.unknown_ptr2 */ <<
1805 R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1806 | (inst_count
/*rmesa->state.vertex_shader.unknown_ptr3 */ <<
1809 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1810 so I leave it as a reminder */
1812 reg_start(R300_VAP_PVS_WAITIDLE
, 0);
1817 extern void _tnl_UpdateFixedFunctionProgram(GLcontext
* ctx
);
1819 extern int future_hw_tcl_on
;
1820 void r300UpdateShaders(r300ContextPtr rmesa
)
1823 struct r300_vertex_program
*vp
;
1826 ctx
= rmesa
->radeon
.glCtx
;
1828 if (rmesa
->NewGLState
&& hw_tcl_on
) {
1829 rmesa
->NewGLState
= 0;
1831 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1832 rmesa
->temp_attrib
[i
] =
1833 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
1834 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
1835 &rmesa
->dummy_attrib
[i
];
1838 _tnl_UpdateFixedFunctionProgram(ctx
);
1840 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1841 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
1842 rmesa
->temp_attrib
[i
];
1845 r300SelectVertexShader(rmesa
);
1846 vp
= (struct r300_vertex_program
*)
1847 CURRENT_VERTEX_SHADER(ctx
);
1848 /*if (vp->translated == GL_FALSE)
1849 r300TranslateVertexShader(vp); */
1850 if (vp
->translated
== GL_FALSE
) {
1851 fprintf(stderr
, "Failing back to sw-tcl\n");
1852 hw_tcl_on
= future_hw_tcl_on
= 0;
1853 r300ResetHwState(rmesa
);
1857 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
1862 void r300UpdateShaderStates(r300ContextPtr rmesa
)
1865 ctx
= rmesa
->radeon
.glCtx
;
1867 r300UpdateTextureState(ctx
);
1869 r300SetupPixelShader(rmesa
);
1870 r300SetupTextures(ctx
);
1872 if ((rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
1873 r300SetupVertexShader(rmesa
);
1874 r300SetupRSUnit(ctx
);
1877 /* This is probably wrong for some values, I need to test this
1878 * some more. Range checking would be a good idea also..
1880 * But it works for most things. I'll fix it later if someone
1881 * else with a better clue doesn't
1883 static unsigned int r300PackFloat24(float f
)
1887 unsigned int float24
= 0;
1892 mantissa
= frexpf(f
, &exponent
);
1896 float24
|= (1 << 23);
1897 mantissa
= mantissa
* -1.0;
1899 /* Handle exponent, bias of 63 */
1901 float24
|= (exponent
<< 16);
1902 /* Kill 7 LSB of mantissa */
1903 float24
|= (r300PackFloat32(mantissa
) & 0x7FFFFF) >> 7;
1908 void r300SetupPixelShader(r300ContextPtr rmesa
)
1910 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1911 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1912 (char *)ctx
->FragmentProgram
._Current
;
1915 if (!fp
) /* should only happenen once, just after context is created */
1918 r300TranslateFragmentShader(rmesa
, fp
);
1919 if (!fp
->translated
) {
1920 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
1924 #define OUTPUT_FIELD(st, reg, field) \
1925 R300_STATECHANGE(rmesa, st); \
1926 for(i=0;i<=fp->alu_end;i++) \
1927 rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=fp->alu.inst[i].field;\
1928 rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmdpacket0(reg, fp->alu_end+1);
1930 OUTPUT_FIELD(fpi
[0], R300_PFS_INSTR0_0
, inst0
);
1931 OUTPUT_FIELD(fpi
[1], R300_PFS_INSTR1_0
, inst1
);
1932 OUTPUT_FIELD(fpi
[2], R300_PFS_INSTR2_0
, inst2
);
1933 OUTPUT_FIELD(fpi
[3], R300_PFS_INSTR3_0
, inst3
);
1936 R300_STATECHANGE(rmesa
, fp
);
1937 /* I just want to say, the way these nodes are stored.. weird.. */
1938 for (i
= 0, k
= (4 - (fp
->cur_node
+ 1)); i
< 4; i
++, k
++) {
1939 if (i
< (fp
->cur_node
+ 1)) {
1940 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ k
] =
1942 alu_offset
<< R300_PFS_NODE_ALU_OFFSET_SHIFT
)
1944 alu_end
<< R300_PFS_NODE_ALU_END_SHIFT
)
1946 tex_offset
<< R300_PFS_NODE_TEX_OFFSET_SHIFT
)
1948 tex_end
<< R300_PFS_NODE_TEX_END_SHIFT
)
1949 | fp
->node
[i
].flags
; /* ( (k==3) ? R300_PFS_NODE_LAST_NODE : 0); */
1951 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ (3 - i
)] = 0;
1956 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
] =
1957 fp
->cur_node
| (fp
->first_node_has_tex
<< 3);
1959 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
] = fp
->max_temp_idx
;
1961 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
] =
1962 (fp
->alu_offset
<< R300_PFS_CNTL_ALU_OFFSET_SHIFT
)
1963 | (fp
->alu_end
<< R300_PFS_CNTL_ALU_END_SHIFT
)
1964 | (fp
->tex_offset
<< R300_PFS_CNTL_TEX_OFFSET_SHIFT
)
1965 | (fp
->tex_end
<< R300_PFS_CNTL_TEX_END_SHIFT
);
1967 R300_STATECHANGE(rmesa
, fpp
);
1968 for (i
= 0; i
< fp
->const_nr
; i
++) {
1969 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] =
1970 r300PackFloat24(fp
->constant
[i
][0]);
1971 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] =
1972 r300PackFloat24(fp
->constant
[i
][1]);
1973 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] =
1974 r300PackFloat24(fp
->constant
[i
][2]);
1975 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] =
1976 r300PackFloat24(fp
->constant
[i
][3]);
1978 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
] =
1979 cmdpacket0(R300_PFS_PARAM_0_X
, fp
->const_nr
* 4);
1983 * Called by Mesa after an internal state update.
1985 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
1987 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1989 _swrast_InvalidateState(ctx
, new_state
);
1990 _swsetup_InvalidateState(ctx
, new_state
);
1991 _vbo_InvalidateState(ctx
, new_state
);
1992 _tnl_InvalidateState(ctx
, new_state
);
1993 _ae_invalidate_state(ctx
, new_state
);
1995 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
1996 r300UpdateDrawBuffer(ctx
);
1999 r300UpdateStateParameters(ctx
, new_state
);
2001 r300
->NewGLState
|= new_state
;
2005 * Completely recalculates hardware state based on the Mesa state.
2007 void r300ResetHwState(r300ContextPtr r300
)
2009 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2012 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2015 if (RADEON_DEBUG
& DEBUG_STATE
)
2016 fprintf(stderr
, "%s\n", __FUNCTION__
);
2018 /* This is a place to initialize registers which
2019 have bitfields accessed by different functions
2020 and not all bits are used */
2022 /* go and compute register values from GL state */
2024 r300UpdateWindow(ctx
);
2027 ctx
->Color
.ColorMask
[RCOMP
],
2028 ctx
->Color
.ColorMask
[GCOMP
],
2029 ctx
->Color
.ColorMask
[BCOMP
], ctx
->Color
.ColorMask
[ACOMP
]);
2031 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
2032 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
2033 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
2036 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
2037 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
2038 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0],
2039 ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
2040 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0],
2041 ctx
->Stencil
.ZFailFunc
[0],
2042 ctx
->Stencil
.ZPassFunc
[0]);
2044 r300UpdateCulling(ctx
);
2046 r300UpdateTextureState(ctx
);
2048 r300SetBlendState(ctx
);
2050 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
2051 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
2053 /* Initialize magic registers
2054 TODO : learn what they really do, or get rid of
2055 those we don't have to touch */
2057 r300
->hw
.vap_cntl
.cmd
[1] = 0x0014045a;
2059 r300
->hw
.vap_cntl
.cmd
[1] = 0x0030045A; //0x0030065a /* Dangerous */
2060 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
2061 | R300_VPORT_X_OFFSET_ENA
2062 | R300_VPORT_Y_SCALE_ENA
2063 | R300_VPORT_Y_OFFSET_ENA
2064 | R300_VPORT_Z_SCALE_ENA
2065 | R300_VPORT_Z_OFFSET_ENA
| R300_VTX_W0_FMT
;
2066 r300
->hw
.vte
.cmd
[2] = 0x00000008;
2068 r300
->hw
.unk2134
.cmd
[1] = 0x00FFFFFF;
2069 r300
->hw
.unk2134
.cmd
[2] = 0x00000000;
2070 if (_mesa_little_endian())
2071 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_NO_SWAP
;
2073 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_32BIT_SWAP
;
2075 /* disable VAP/TCL on non-TCL capable chips */
2077 r300
->hw
.vap_cntl_status
.cmd
[1] |= R300_VAP_TCL_BYPASS
;
2079 r300
->hw
.unk21DC
.cmd
[1] = 0xAAAAAAAA;
2081 r300
->hw
.unk221C
.cmd
[1] = R300_221C_NORMAL
;
2083 r300
->hw
.unk2220
.cmd
[1] = r300PackFloat32(1.0);
2084 r300
->hw
.unk2220
.cmd
[2] = r300PackFloat32(1.0);
2085 r300
->hw
.unk2220
.cmd
[3] = r300PackFloat32(1.0);
2086 r300
->hw
.unk2220
.cmd
[4] = r300PackFloat32(1.0);
2088 /* what about other chips than r300 or rv350??? */
2089 if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
)
2090 r300
->hw
.unk2288
.cmd
[1] = R300_2288_R300
;
2092 r300
->hw
.unk2288
.cmd
[1] = R300_2288_RV350
;
2094 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2095 | R300_GB_LINE_STUFF_ENABLE
2096 | R300_GB_TRIANGLE_STUFF_ENABLE
/*| R300_GB_UNK31 */ ;
2098 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2099 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2100 if ((r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
) ||
2101 (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R350
))
2102 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2103 R300_GB_TILE_ENABLE
| R300_GB_TILE_PIPE_COUNT_R300
|
2104 R300_GB_TILE_SIZE_16
;
2105 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
)
2106 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2107 R300_GB_TILE_ENABLE
| R300_GB_TILE_PIPE_COUNT_RV410
|
2108 R300_GB_TILE_SIZE_16
;
2109 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
)
2110 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2111 R300_GB_TILE_ENABLE
| R300_GB_TILE_PIPE_COUNT_R420
|
2112 R300_GB_TILE_SIZE_16
;
2114 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2115 R300_GB_TILE_ENABLE
| R300_GB_TILE_PIPE_COUNT_RV300
|
2116 R300_GB_TILE_SIZE_16
;
2117 /* set to 0 when fog is disabled? */
2118 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2119 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = R300_AA_DISABLE
; /* No antialiasing */
2121 r300
->hw
.unk4200
.cmd
[1] = r300PackFloat32(0.0);
2122 r300
->hw
.unk4200
.cmd
[2] = r300PackFloat32(0.0);
2123 r300
->hw
.unk4200
.cmd
[3] = r300PackFloat32(1.0);
2124 r300
->hw
.unk4200
.cmd
[4] = r300PackFloat32(1.0);
2126 r300
->hw
.unk4214
.cmd
[1] = 0x00050005;
2128 r300PointSize(ctx
, 0.0);
2130 r300
->hw
.unk4230
.cmd
[1] = 0x18000006;
2131 r300
->hw
.unk4230
.cmd
[2] = 0x00020006;
2132 r300
->hw
.unk4230
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2134 r300LineWidth(ctx
, 0.0);
2136 r300
->hw
.unk4260
.cmd
[1] = 0;
2137 r300
->hw
.unk4260
.cmd
[2] = r300PackFloat32(0.0);
2138 r300
->hw
.unk4260
.cmd
[3] = r300PackFloat32(1.0);
2140 r300
->hw
.shade
.cmd
[1] = 0x00000002;
2141 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2142 r300
->hw
.shade
.cmd
[3] = 0x00000000;
2143 r300
->hw
.shade
.cmd
[4] = 0x00000000;
2145 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2146 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2147 r300
->hw
.polygon_mode
.cmd
[2] = 0x00000001;
2148 r300
->hw
.polygon_mode
.cmd
[3] = 0x00000000;
2149 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
2151 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
,
2152 ctx
->Polygon
.OffsetUnits
);
2153 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2155 r300
->hw
.unk42C0
.cmd
[1] = 0x4B7FFFFF;
2156 r300
->hw
.unk42C0
.cmd
[2] = 0x00000000;
2158 r300
->hw
.unk43A4
.cmd
[1] = 0x0000001C;
2159 r300
->hw
.unk43A4
.cmd
[2] = 0x2DA49525;
2161 r300
->hw
.unk43E8
.cmd
[1] = 0x00FFFFFF;
2163 r300
->hw
.unk46A4
.cmd
[1] = 0x00001B01;
2164 r300
->hw
.unk46A4
.cmd
[2] = 0x00001B0F;
2165 r300
->hw
.unk46A4
.cmd
[3] = 0x00001B0F;
2166 r300
->hw
.unk46A4
.cmd
[4] = 0x00001B0F;
2167 r300
->hw
.unk46A4
.cmd
[5] = 0x00000001;
2169 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2170 ctx
->Driver
.Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2171 ctx
->Driver
.Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2172 ctx
->Driver
.Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2173 ctx
->Driver
.Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2174 ctx
->Driver
.Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2175 ctx
->Driver
.Fogfv(ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2177 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
2178 r300
->hw
.unk4BD8
.cmd
[1] = 0;
2180 r300
->hw
.unk4E00
.cmd
[1] = 0;
2182 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2183 r300
->hw
.blend_color
.cmd
[2] = 0;
2184 r300
->hw
.blend_color
.cmd
[3] = 0;
2186 /* Again, r300ClearBuffer uses this */
2187 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] =
2188 r300
->radeon
.state
.color
.drawOffset
+
2189 r300
->radeon
.radeonScreen
->fbLocation
;
2190 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.state
.color
.drawPitch
;
2192 if (r300
->radeon
.radeonScreen
->cpp
== 4)
2193 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
2195 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
2197 if (r300
->radeon
.sarea
->tiling_enabled
)
2198 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
2200 r300
->hw
.unk4E50
.cmd
[1] = 0;
2201 r300
->hw
.unk4E50
.cmd
[2] = 0;
2202 r300
->hw
.unk4E50
.cmd
[3] = 0;
2203 r300
->hw
.unk4E50
.cmd
[4] = 0;
2204 r300
->hw
.unk4E50
.cmd
[5] = 0;
2205 r300
->hw
.unk4E50
.cmd
[6] = 0;
2206 r300
->hw
.unk4E50
.cmd
[7] = 0;
2207 r300
->hw
.unk4E50
.cmd
[8] = 0;
2208 r300
->hw
.unk4E50
.cmd
[9] = 0;
2210 r300
->hw
.unk4E88
.cmd
[1] = 0;
2212 r300
->hw
.unk4EA0
.cmd
[1] = 0x00000000;
2213 r300
->hw
.unk4EA0
.cmd
[2] = 0xffffffff;
2215 switch (ctx
->Visual
.depthBits
) {
2217 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTH_FORMAT_16BIT_INT_Z
;
2220 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTH_FORMAT_24BIT_INT_Z
;
2223 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2224 ctx
->Visual
.depthBits
);
2229 //r300->hw.zstencil_format.cmd[1] |= R300_DEPTH_FORMAT_UNK32;
2231 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
2232 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
2234 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
2235 r300
->radeon
.radeonScreen
->depthOffset
+
2236 r300
->radeon
.radeonScreen
->fbLocation
;
2237 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
2239 if (r300
->radeon
.sarea
->tiling_enabled
) {
2240 /* Turn off when clearing buffers ? */
2241 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_TILE_ENABLE
;
2243 if (ctx
->Visual
.depthBits
== 24)
2244 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |=
2245 R300_DEPTH_MICROTILE_ENABLE
;
2248 r300
->hw
.unk4F28
.cmd
[1] = 0;
2250 r300
->hw
.unk4F30
.cmd
[1] = 0;
2251 r300
->hw
.unk4F30
.cmd
[2] = 0;
2253 r300
->hw
.unk4F44
.cmd
[1] = 0;
2255 r300
->hw
.unk4F54
.cmd
[1] = 0;
2258 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2259 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2260 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2261 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2264 r300
->hw
.all_dirty
= GL_TRUE
;
2268 * Calculate initial hardware state and register state functions.
2269 * Assumes that the command buffer and state atoms have been
2270 * initialized already.
2272 void r300InitState(r300ContextPtr r300
)
2274 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2277 radeonInitState(&r300
->radeon
);
2279 switch (ctx
->Visual
.depthBits
) {
2281 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2282 depth_fmt
= R300_DEPTH_FORMAT_16BIT_INT_Z
;
2283 r300
->state
.stencil
.clear
= 0x00000000;
2286 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2287 depth_fmt
= R300_DEPTH_FORMAT_24BIT_INT_Z
;
2288 r300
->state
.stencil
.clear
= 0x00ff0000;
2291 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2292 ctx
->Visual
.depthBits
);
2296 /* Only have hw stencil when depth buffer is 24 bits deep */
2297 r300
->state
.stencil
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2298 ctx
->Visual
.depthBits
== 24);
2300 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2302 r300ResetHwState(r300
);
2305 static void r300RenderMode(GLcontext
* ctx
, GLenum mode
)
2307 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2313 * Initialize driver's state callback functions
2315 void r300InitStateFuncs(struct dd_function_table
*functions
)
2317 radeonInitStateFuncs(functions
);
2319 functions
->UpdateState
= r300InvalidateState
;
2320 functions
->AlphaFunc
= r300AlphaFunc
;
2321 functions
->BlendColor
= r300BlendColor
;
2322 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2323 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2324 functions
->Enable
= r300Enable
;
2325 functions
->ColorMask
= r300ColorMask
;
2326 functions
->DepthFunc
= r300DepthFunc
;
2327 functions
->DepthMask
= r300DepthMask
;
2328 functions
->CullFace
= r300CullFace
;
2329 functions
->Fogfv
= r300Fogfv
;
2330 functions
->FrontFace
= r300FrontFace
;
2331 functions
->ShadeModel
= r300ShadeModel
;
2333 /* Stencil related */
2334 functions
->ClearStencil
= r300ClearStencil
;
2335 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2336 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2337 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2339 /* Viewport related */
2340 functions
->Viewport
= r300Viewport
;
2341 functions
->DepthRange
= r300DepthRange
;
2342 functions
->PointSize
= r300PointSize
;
2343 functions
->LineWidth
= r300LineWidth
;
2345 functions
->PolygonOffset
= r300PolygonOffset
;
2346 functions
->PolygonMode
= r300PolygonMode
;
2348 functions
->RenderMode
= r300RenderMode
;