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 **************************************************************************/
35 * \author Nicolai Haehnle <prefect_@gmx.net>
45 #include "simple_list.h"
47 #include "api_arrayelt.h"
48 #include "swrast/swrast.h"
49 #include "swrast_setup/swrast_setup.h"
50 #include "shader/prog_parameter.h"
51 #include "shader/prog_statevars.h"
54 #include "texformat.h"
56 #include "radeon_ioctl.h"
57 #include "radeon_state.h"
58 #include "r300_context.h"
59 #include "r300_ioctl.h"
60 #include "r300_state.h"
62 #include "r300_emit.h"
63 #include "r300_fragprog.h"
65 #include "r300_maos.h"
67 #include "drirenderbuffer.h"
69 static void r300BlendColor(GLcontext
* ctx
, const GLfloat cf
[4])
72 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
74 R300_STATECHANGE(rmesa
, blend_color
);
76 CLAMPED_FLOAT_TO_UBYTE(color
[0], cf
[0]);
77 CLAMPED_FLOAT_TO_UBYTE(color
[1], cf
[1]);
78 CLAMPED_FLOAT_TO_UBYTE(color
[2], cf
[2]);
79 CLAMPED_FLOAT_TO_UBYTE(color
[3], cf
[3]);
81 rmesa
->hw
.blend_color
.cmd
[1] = PACK_COLOR_8888(color
[3], color
[0],
86 * Calculate the hardware blend factor setting. This same function is used
87 * for source and destination of both alpha and RGB.
90 * The hardware register value for the specified blend factor. This value
91 * will need to be shifted into the correct position for either source or
95 * Since the two cases where source and destination are handled differently
96 * are essentially error cases, they should never happen. Determine if these
97 * cases can be removed.
99 static int blend_factor(GLenum factor
, GLboolean is_src
)
105 func
= R300_BLEND_GL_ZERO
;
108 func
= R300_BLEND_GL_ONE
;
111 func
= R300_BLEND_GL_DST_COLOR
;
113 case GL_ONE_MINUS_DST_COLOR
:
114 func
= R300_BLEND_GL_ONE_MINUS_DST_COLOR
;
117 func
= R300_BLEND_GL_SRC_COLOR
;
119 case GL_ONE_MINUS_SRC_COLOR
:
120 func
= R300_BLEND_GL_ONE_MINUS_SRC_COLOR
;
123 func
= R300_BLEND_GL_SRC_ALPHA
;
125 case GL_ONE_MINUS_SRC_ALPHA
:
126 func
= R300_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
129 func
= R300_BLEND_GL_DST_ALPHA
;
131 case GL_ONE_MINUS_DST_ALPHA
:
132 func
= R300_BLEND_GL_ONE_MINUS_DST_ALPHA
;
134 case GL_SRC_ALPHA_SATURATE
:
135 func
= (is_src
) ? R300_BLEND_GL_SRC_ALPHA_SATURATE
:
138 case GL_CONSTANT_COLOR
:
139 func
= R300_BLEND_GL_CONST_COLOR
;
141 case GL_ONE_MINUS_CONSTANT_COLOR
:
142 func
= R300_BLEND_GL_ONE_MINUS_CONST_COLOR
;
144 case GL_CONSTANT_ALPHA
:
145 func
= R300_BLEND_GL_CONST_ALPHA
;
147 case GL_ONE_MINUS_CONSTANT_ALPHA
:
148 func
= R300_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
151 fprintf(stderr
, "unknown blend factor %x\n", factor
);
152 func
= (is_src
) ? R300_BLEND_GL_ONE
: R300_BLEND_GL_ZERO
;
158 * Sets both the blend equation and the blend function.
159 * This is done in a single
160 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
161 * change the interpretation of the blend function.
162 * Also, make sure that blend function and blend equation are set to their
163 * default value if color blending is not enabled, since at least blend
164 * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results
165 * otherwise for unknown reasons.
168 /* helper function */
169 static void r300SetBlendCntl(r300ContextPtr r300
, int func
, int eqn
,
170 int cbits
, int funcA
, int eqnA
)
172 GLuint new_ablend
, new_cblend
;
176 "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n",
177 eqnA
, funcA
, eqn
, func
, cbits
);
179 new_ablend
= eqnA
| funcA
;
180 new_cblend
= eqn
| func
;
182 /* Some blend factor combinations don't seem to work when the
183 * BLEND_NO_SEPARATE bit is set.
185 * Especially problematic candidates are the ONE_MINUS_* flags,
186 * but I can't see a real pattern.
189 if (new_ablend
== new_cblend
) {
190 new_cblend
|= R300_BLEND_NO_SEPARATE
;
195 if ((new_ablend
!= r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]) ||
196 (new_cblend
!= r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
])) {
197 R300_STATECHANGE(r300
, bld
);
198 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = new_ablend
;
199 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = new_cblend
;
203 static void r300SetBlendState(GLcontext
* ctx
)
205 r300ContextPtr r300
= R300_CONTEXT(ctx
);
206 int func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
207 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
208 int eqn
= R300_COMB_FCN_ADD_CLAMP
;
209 int funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
210 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
211 int eqnA
= R300_COMB_FCN_ADD_CLAMP
;
213 if (RGBA_LOGICOP_ENABLED(ctx
) || !ctx
->Color
.BlendEnabled
) {
214 r300SetBlendCntl(r300
, func
, eqn
, 0, func
, eqn
);
219 (blend_factor(ctx
->Color
.BlendSrcRGB
, GL_TRUE
) <<
220 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstRGB
,
222 R300_DST_BLEND_SHIFT
);
224 switch (ctx
->Color
.BlendEquationRGB
) {
226 eqn
= R300_COMB_FCN_ADD_CLAMP
;
229 case GL_FUNC_SUBTRACT
:
230 eqn
= R300_COMB_FCN_SUB_CLAMP
;
233 case GL_FUNC_REVERSE_SUBTRACT
:
234 eqn
= R300_COMB_FCN_RSUB_CLAMP
;
238 eqn
= R300_COMB_FCN_MIN
;
239 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
240 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
244 eqn
= R300_COMB_FCN_MAX
;
245 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
246 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
251 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
252 __func__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
257 (blend_factor(ctx
->Color
.BlendSrcA
, GL_TRUE
) <<
258 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstA
,
260 R300_DST_BLEND_SHIFT
);
262 switch (ctx
->Color
.BlendEquationA
) {
264 eqnA
= R300_COMB_FCN_ADD_CLAMP
;
267 case GL_FUNC_SUBTRACT
:
268 eqnA
= R300_COMB_FCN_SUB_CLAMP
;
271 case GL_FUNC_REVERSE_SUBTRACT
:
272 eqnA
= R300_COMB_FCN_RSUB_CLAMP
;
276 eqnA
= R300_COMB_FCN_MIN
;
277 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
278 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
282 eqnA
= R300_COMB_FCN_MAX
;
283 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
284 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
289 "[%s:%u] Invalid A blend equation (0x%04x).\n",
290 __func__
, __LINE__
, ctx
->Color
.BlendEquationA
);
294 r300SetBlendCntl(r300
,
296 R300_BLEND_UNKNOWN
| R300_BLEND_ENABLE
, funcA
, eqnA
);
299 static void r300BlendEquationSeparate(GLcontext
* ctx
,
300 GLenum modeRGB
, GLenum modeA
)
302 r300SetBlendState(ctx
);
305 static void r300BlendFuncSeparate(GLcontext
* ctx
,
306 GLenum sfactorRGB
, GLenum dfactorRGB
,
307 GLenum sfactorA
, GLenum dfactorA
)
309 r300SetBlendState(ctx
);
313 * Update our tracked culling state based on Mesa's state.
315 static void r300UpdateCulling(GLcontext
* ctx
)
317 r300ContextPtr r300
= R300_CONTEXT(ctx
);
320 R300_STATECHANGE(r300
, cul
);
321 if (ctx
->Polygon
.CullFlag
) {
322 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
)
323 val
= R300_CULL_FRONT
| R300_CULL_BACK
;
324 else if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
325 val
= R300_CULL_FRONT
;
327 val
= R300_CULL_BACK
;
329 if (ctx
->Polygon
.FrontFace
== GL_CW
)
330 val
|= R300_FRONT_FACE_CW
;
332 val
|= R300_FRONT_FACE_CCW
;
334 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
337 static void update_early_z(GLcontext
* ctx
)
339 /* updates register R300_RB3D_EARLY_Z (0x4F14)
340 if depth test is not enabled it should be R300_EARLY_Z_DISABLE
341 if depth is enabled and alpha not it should be R300_EARLY_Z_ENABLE
342 if depth and alpha is enabled it should be R300_EARLY_Z_DISABLE
344 r300ContextPtr r300
= R300_CONTEXT(ctx
);
346 R300_STATECHANGE(r300
, zstencil_format
);
347 if (ctx
->Color
.AlphaEnabled
&& ctx
->Color
.AlphaFunc
!= GL_ALWAYS
)
348 /* disable early Z */
349 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_DISABLE
;
351 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
)
353 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_ENABLE
;
355 /* disable early Z */
356 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_DISABLE
;
360 static void update_alpha(GLcontext
* ctx
)
362 r300ContextPtr r300
= R300_CONTEXT(ctx
);
364 uint32_t pp_misc
= 0x0;
365 GLboolean really_enabled
= ctx
->Color
.AlphaEnabled
;
367 CLAMPED_FLOAT_TO_UBYTE(refByte
, ctx
->Color
.AlphaRef
);
369 switch (ctx
->Color
.AlphaFunc
) {
371 pp_misc
|= R300_ALPHA_TEST_FAIL
;
374 pp_misc
|= R300_ALPHA_TEST_LESS
;
377 pp_misc
|= R300_ALPHA_TEST_EQUAL
;
380 pp_misc
|= R300_ALPHA_TEST_LEQUAL
;
383 pp_misc
|= R300_ALPHA_TEST_GREATER
;
386 pp_misc
|= R300_ALPHA_TEST_NEQUAL
;
389 pp_misc
|= R300_ALPHA_TEST_GEQUAL
;
392 /*pp_misc |= R300_ALPHA_TEST_PASS; */
393 really_enabled
= GL_FALSE
;
397 if (really_enabled
) {
398 pp_misc
|= R300_ALPHA_TEST_ENABLE
;
399 pp_misc
|= (refByte
& R300_REF_ALPHA_MASK
);
404 R300_STATECHANGE(r300
, at
);
405 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
409 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
416 static int translate_func(int func
)
420 return R300_ZS_NEVER
;
424 return R300_ZS_EQUAL
;
426 return R300_ZS_LEQUAL
;
428 return R300_ZS_GREATER
;
430 return R300_ZS_NOTEQUAL
;
432 return R300_ZS_GEQUAL
;
434 return R300_ZS_ALWAYS
;
439 static void update_depth(GLcontext
* ctx
)
441 r300ContextPtr r300
= R300_CONTEXT(ctx
);
443 R300_STATECHANGE(r300
, zs
);
444 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_RB3D_STENCIL_ENABLE
;
445 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
446 ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
448 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
) {
450 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
451 R300_RB3D_Z_TEST_AND_WRITE
;
453 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_TEST
;
455 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
456 translate_func(ctx
->Depth
.
457 Func
) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
459 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_DISABLED_1
;
460 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
461 translate_func(GL_NEVER
) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
468 * Handle glEnable()/glDisable().
470 * \note Mesa already filters redundant calls to glEnable/glDisable.
472 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
474 r300ContextPtr r300
= R300_CONTEXT(ctx
);
476 if (RADEON_DEBUG
& DEBUG_STATE
)
477 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
478 _mesa_lookup_enum_by_nr(cap
),
479 state
? "GL_TRUE" : "GL_FALSE");
482 /* Fast track this one...
490 R300_STATECHANGE(r300
, fogs
);
492 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] |= R300_FOG_ENABLE
;
494 ctx
->Driver
.Fogfv(ctx
, GL_FOG_MODE
, NULL
);
495 ctx
->Driver
.Fogfv(ctx
, GL_FOG_DENSITY
,
497 ctx
->Driver
.Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
498 ctx
->Driver
.Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
499 ctx
->Driver
.Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
501 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] &= ~R300_FOG_ENABLE
;
511 case GL_COLOR_LOGIC_OP
:
512 r300SetBlendState(ctx
);
519 case GL_STENCIL_TEST
:
520 if (r300
->state
.stencil
.hw_stencil
) {
521 R300_STATECHANGE(r300
, zs
);
523 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
524 R300_RB3D_STENCIL_ENABLE
;
526 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
527 ~R300_RB3D_STENCIL_ENABLE
;
531 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
537 r300UpdateCulling(ctx
);
540 case GL_POLYGON_OFFSET_POINT
:
541 case GL_POLYGON_OFFSET_LINE
:
544 case GL_POLYGON_OFFSET_FILL
:
545 R300_STATECHANGE(r300
, occlusion_cntl
);
547 r300
->hw
.occlusion_cntl
.cmd
[1] |= (3 << 0);
549 r300
->hw
.occlusion_cntl
.cmd
[1] &= ~(3 << 0);
553 radeonEnable(ctx
, cap
, state
);
558 static void r300UpdatePolygonMode(GLcontext
* ctx
)
560 r300ContextPtr r300
= R300_CONTEXT(ctx
);
561 uint32_t hw_mode
= 0;
563 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
564 ctx
->Polygon
.BackMode
!= GL_FILL
) {
567 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
568 f
= ctx
->Polygon
.FrontMode
;
569 b
= ctx
->Polygon
.BackMode
;
571 f
= ctx
->Polygon
.BackMode
;
572 b
= ctx
->Polygon
.FrontMode
;
575 hw_mode
|= R300_PM_ENABLED
;
579 hw_mode
|= R300_PM_FRONT_LINE
;
581 case GL_POINT
: /* noop */
582 hw_mode
|= R300_PM_FRONT_POINT
;
585 hw_mode
|= R300_PM_FRONT_FILL
;
591 hw_mode
|= R300_PM_BACK_LINE
;
593 case GL_POINT
: /* noop */
594 hw_mode
|= R300_PM_BACK_POINT
;
597 hw_mode
|= R300_PM_BACK_FILL
;
602 if (r300
->hw
.polygon_mode
.cmd
[1] != hw_mode
) {
603 R300_STATECHANGE(r300
, polygon_mode
);
604 r300
->hw
.polygon_mode
.cmd
[1] = hw_mode
;
609 * Change the culling mode.
611 * \note Mesa already filters redundant calls to this function.
613 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
617 r300UpdateCulling(ctx
);
621 * Change the polygon orientation.
623 * \note Mesa already filters redundant calls to this function.
625 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
629 r300UpdateCulling(ctx
);
630 r300UpdatePolygonMode(ctx
);
634 * Change the depth testing function.
636 * \note Mesa already filters redundant calls to this function.
638 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
645 * Enable/Disable depth writing.
647 * \note Mesa already filters redundant calls to this function.
649 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
656 * Handle glColorMask()
658 static void r300ColorMask(GLcontext
* ctx
,
659 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
661 r300ContextPtr r300
= R300_CONTEXT(ctx
);
662 int mask
= (r
? R300_COLORMASK0_R
: 0) |
663 (g
? R300_COLORMASK0_G
: 0) |
664 (b
? R300_COLORMASK0_B
: 0) | (a
? R300_COLORMASK0_A
: 0);
666 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
667 R300_STATECHANGE(r300
, cmk
);
668 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
672 /* =============================================================
675 static void r300Fogfv(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
677 r300ContextPtr r300
= R300_CONTEXT(ctx
);
681 } fogScale
, fogStart
;
685 fogScale
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
];
686 fogStart
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_START
];
690 if (!ctx
->Fog
.Enabled
)
692 switch (ctx
->Fog
.Mode
) {
694 R300_STATECHANGE(r300
, fogs
);
695 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
697 cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) |
698 R300_FOG_MODE_LINEAR
;
700 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
705 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
707 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
712 R300_STATECHANGE(r300
, fogs
);
713 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
715 cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) |
717 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
721 R300_STATECHANGE(r300
, fogs
);
722 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
724 cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) |
726 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
733 switch (ctx
->Fog
.Mode
) {
735 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
739 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
747 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
748 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
753 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
755 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
761 R300_STATECHANGE(r300
, fogc
);
762 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] =
763 (GLuint
) (ctx
->Fog
.Color
[0] * 1023.0F
) & 0x3FF;
764 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] =
765 (GLuint
) (ctx
->Fog
.Color
[1] * 1023.0F
) & 0x3FF;
766 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] =
767 (GLuint
) (ctx
->Fog
.Color
[2] * 1023.0F
) & 0x3FF;
769 case GL_FOG_COORD_SRC
:
775 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
776 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
777 R300_STATECHANGE(r300
, fogp
);
778 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
779 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
783 /* =============================================================
786 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
788 r300ContextPtr r300
= R300_CONTEXT(ctx
);
790 size
= ctx
->Point
._Size
;
792 R300_STATECHANGE(r300
, ps
);
793 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
794 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
795 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
798 /* =============================================================
801 static void r300LineWidth(GLcontext
* ctx
, GLfloat widthf
)
803 r300ContextPtr r300
= R300_CONTEXT(ctx
);
805 widthf
= ctx
->Line
._Width
;
807 R300_STATECHANGE(r300
, lcntl
);
808 r300
->hw
.lcntl
.cmd
[1] = (int)(widthf
* 6.0);
809 r300
->hw
.lcntl
.cmd
[1] |= R300_LINE_CNT_VE
;
812 static void r300PolygonMode(GLcontext
* ctx
, GLenum face
, GLenum mode
)
817 r300UpdatePolygonMode(ctx
);
820 /* =============================================================
824 static int translate_stencil_op(int op
)
832 return R300_ZS_REPLACE
;
837 case GL_INCR_WRAP_EXT
:
838 return R300_ZS_INCR_WRAP
;
839 case GL_DECR_WRAP_EXT
:
840 return R300_ZS_DECR_WRAP
;
842 return R300_ZS_INVERT
;
844 WARN_ONCE("Do not know how to translate stencil op");
850 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
852 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
854 R300_STATECHANGE(rmesa
, shade
);
857 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
860 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
867 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
868 GLenum func
, GLint ref
, GLuint mask
)
870 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
873 Ref
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_REF_SHIFT
) | ((ctx
->
879 R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
883 R300_STATECHANGE(rmesa
, zs
);
885 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~((R300_ZS_MASK
<<
886 R300_RB3D_ZS1_FRONT_FUNC_SHIFT
)
888 R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
890 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
891 ~((R300_RB3D_ZS2_STENCIL_MASK
<<
892 R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
893 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
895 flag
= translate_func(ctx
->Stencil
.Function
[0]);
896 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
897 (flag
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
);
899 if (ctx
->Stencil
._TestTwoSide
)
900 flag
= translate_func(ctx
->Stencil
.Function
[1]);
902 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
903 (flag
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
904 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
907 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
909 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
911 R300_STATECHANGE(rmesa
, zs
);
912 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
913 ~(R300_RB3D_ZS2_STENCIL_MASK
<<
914 R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
);
915 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |=
917 WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
;
920 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
,
921 GLenum fail
, GLenum zfail
, GLenum zpass
)
923 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
925 R300_STATECHANGE(rmesa
, zs
);
926 /* It is easier to mask what's left.. */
927 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
928 (R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
) |
929 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
930 (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
932 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
933 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
934 R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
)
935 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
936 R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
)
937 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
938 R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
);
940 if (ctx
->Stencil
._TestTwoSide
) {
941 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
942 (translate_stencil_op(ctx
->Stencil
.FailFunc
[1]) <<
943 R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
944 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[1]) <<
945 R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
946 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[1]) <<
947 R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
949 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
950 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
951 R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
952 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
953 R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
954 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
955 R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
959 static void r300ClearStencil(GLcontext
* ctx
, GLint s
)
961 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
963 rmesa
->state
.stencil
.clear
=
964 ((GLuint
) (ctx
->Stencil
.Clear
& 0xff) |
965 (R300_RB3D_ZS2_STENCIL_MASK
<<
966 R300_RB3D_ZS2_STENCIL_MASK_SHIFT
) | ((ctx
->Stencil
.
967 WriteMask
[0] & 0xff) <<
968 R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
));
971 /* =============================================================
972 * Window position and viewport transformation
976 * To correctly position primitives:
978 #define SUBPIXEL_X 0.125
979 #define SUBPIXEL_Y 0.125
981 void r300UpdateWindow(GLcontext
* ctx
)
983 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
984 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
985 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
986 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
987 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
989 GLfloat sx
= v
[MAT_SX
];
990 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
991 GLfloat sy
= -v
[MAT_SY
];
992 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
993 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
994 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
996 R300_FIREVERTICES(rmesa
);
997 R300_STATECHANGE(rmesa
, vpt
);
999 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
1000 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1001 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
1002 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1003 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
1004 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
1007 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
1008 GLsizei width
, GLsizei height
)
1010 /* Don't pipeline viewport changes, conflict with window offset
1011 * setting below. Could apply deltas to rescue pipelined viewport
1012 * values, or keep the originals hanging around.
1014 r300UpdateWindow(ctx
);
1017 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
1019 r300UpdateWindow(ctx
);
1022 void r300UpdateViewportOffset(GLcontext
* ctx
)
1024 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1025 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
) rmesa
)->dri
.drawable
;
1026 GLfloat xoffset
= (GLfloat
) dPriv
->x
;
1027 GLfloat yoffset
= (GLfloat
) dPriv
->y
+ dPriv
->h
;
1028 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1030 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1031 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1033 if (rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
1034 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
)) {
1035 /* Note: this should also modify whatever data the context reset
1038 R300_STATECHANGE(rmesa
, vpt
);
1039 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1040 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1044 radeonUpdateScissor(ctx
);
1048 * Tell the card where to render (offset, pitch).
1049 * Effected by glDrawBuffer, etc
1051 void r300UpdateDrawBuffer(GLcontext
* ctx
)
1053 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1054 r300ContextPtr r300
= rmesa
;
1055 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1056 driRenderbuffer
*drb
;
1058 if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
) {
1061 (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].
1063 } else if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_BACK_LEFT
) {
1066 (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].
1069 /* drawing to multiple buffers, or none */
1074 assert(drb
->flippedPitch
);
1076 R300_STATECHANGE(rmesa
, cb
);
1078 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = drb
->flippedOffset
+ //r300->radeon.state.color.drawOffset +
1079 r300
->radeon
.radeonScreen
->fbLocation
;
1080 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = drb
->flippedPitch
; //r300->radeon.state.color.drawPitch;
1082 if (r300
->radeon
.radeonScreen
->cpp
== 4)
1083 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
1085 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
1087 if (r300
->radeon
.sarea
->tiling_enabled
)
1088 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
1090 R200_STATECHANGE(rmesa
, ctx
);
1092 /* Note: we used the (possibly) page-flipped values */
1093 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
1094 = ((drb
->flippedOffset
+ rmesa
->r200Screen
->fbLocation
)
1095 & R200_COLOROFFSET_MASK
);
1096 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
1098 if (rmesa
->sarea
->tiling_enabled
) {
1099 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |=
1100 R200_COLOR_TILE_ENABLE
;
1106 r300FetchStateParameter(GLcontext
* ctx
,
1107 const gl_state_index state
[STATE_LENGTH
],
1110 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1113 case STATE_INTERNAL
:
1115 case STATE_R300_WINDOW_DIMENSION
:
1116 value
[0] = r300
->radeon
.dri
.drawable
->w
* 0.5f
; /* width*0.5 */
1117 value
[1] = r300
->radeon
.dri
.drawable
->h
* 0.5f
; /* height*0.5 */
1118 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1119 value
[3] = 1.0F
; /* not used */
1122 case STATE_R300_TEXRECT_FACTOR
:{
1123 struct gl_texture_object
*t
=
1124 ctx
->Texture
.Unit
[state
[2]].CurrentRect
;
1126 if (t
&& t
->Image
[0][t
->BaseLevel
]) {
1127 struct gl_texture_image
*image
=
1128 t
->Image
[0][t
->BaseLevel
];
1129 value
[0] = 1.0 / image
->Width2
;
1130 value
[1] = 1.0 / image
->Height2
;
1151 * Update R300's own internal state parameters.
1152 * For now just STATE_R300_WINDOW_DIMENSION
1154 void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1156 struct r300_fragment_program
*fp
;
1157 struct gl_program_parameter_list
*paramList
;
1160 if (!(new_state
& (_NEW_BUFFERS
| _NEW_PROGRAM
)))
1163 fp
= (struct r300_fragment_program
*)ctx
->FragmentProgram
._Current
;
1167 paramList
= fp
->mesa_program
.Base
.Parameters
;
1172 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1173 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
) {
1174 r300FetchStateParameter(ctx
,
1175 paramList
->Parameters
[i
].
1177 paramList
->ParameterValues
[i
]);
1182 /* =============================================================
1185 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1187 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1188 GLfloat constant
= units
;
1190 switch (ctx
->Visual
.depthBits
) {
1201 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1203 R300_STATECHANGE(rmesa
, zbs
);
1204 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1205 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1206 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1207 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1210 /* Routing and texture-related */
1212 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1213 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1214 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1215 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1216 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1217 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1218 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1219 * combinations where only one of them is nearest.
1221 static unsigned long gen_fixed_filter(unsigned long f
)
1223 unsigned long mag
, min
, needs_fixing
= 0;
1226 /* We ignore MIRROR bit so we dont have to do everything twice */
1227 if ((f
& ((7 - 1) << R300_TX_WRAP_S_SHIFT
)) ==
1228 (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)) {
1231 if ((f
& ((7 - 1) << R300_TX_WRAP_T_SHIFT
)) ==
1232 (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)) {
1235 if ((f
& ((7 - 1) << R300_TX_WRAP_Q_SHIFT
)) ==
1236 (R300_TX_CLAMP
<< R300_TX_WRAP_Q_SHIFT
)) {
1243 mag
= f
& R300_TX_MAG_FILTER_MASK
;
1244 min
= f
& R300_TX_MIN_FILTER_MASK
;
1246 /* TODO: Check for anisto filters too */
1247 if ((mag
!= R300_TX_MAG_FILTER_NEAREST
)
1248 && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1251 /* r300 cant handle these modes hence we force nearest to linear */
1252 if ((mag
== R300_TX_MAG_FILTER_NEAREST
)
1253 && (min
!= R300_TX_MIN_FILTER_NEAREST
)) {
1254 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1255 f
|= R300_TX_MAG_FILTER_LINEAR
;
1259 if ((min
== R300_TX_MIN_FILTER_NEAREST
)
1260 && (mag
!= R300_TX_MAG_FILTER_NEAREST
)) {
1261 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1262 f
|= R300_TX_MIN_FILTER_LINEAR
;
1266 /* Both are nearest */
1267 if (needs_fixing
& 1) {
1268 f
&= ~((7 - 1) << R300_TX_WRAP_S_SHIFT
);
1269 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1271 if (needs_fixing
& 2) {
1272 f
&= ~((7 - 1) << R300_TX_WRAP_T_SHIFT
);
1273 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1275 if (needs_fixing
& 4) {
1276 f
&= ~((7 - 1) << R300_TX_WRAP_Q_SHIFT
);
1277 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_Q_SHIFT
;
1282 static void r300SetupTextures(GLcontext
* ctx
)
1285 struct r300_tex_obj
*t
;
1286 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1288 int last_hw_tmu
= -1; /* -1 translates into no setup costs for fields */
1289 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1, };
1290 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1291 (char *)ctx
->FragmentProgram
._Current
;
1293 R300_STATECHANGE(r300
, txe
);
1294 R300_STATECHANGE(r300
, tex
.filter
);
1295 R300_STATECHANGE(r300
, tex
.filter_1
);
1296 R300_STATECHANGE(r300
, tex
.size
);
1297 R300_STATECHANGE(r300
, tex
.format
);
1298 R300_STATECHANGE(r300
, tex
.pitch
);
1299 R300_STATECHANGE(r300
, tex
.offset
);
1300 R300_STATECHANGE(r300
, tex
.chroma_key
);
1301 R300_STATECHANGE(r300
, tex
.border_color
);
1303 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] = 0x0;
1305 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1306 if (RADEON_DEBUG
& DEBUG_STATE
)
1307 fprintf(stderr
, "mtu=%d\n", mtu
);
1309 if (mtu
> R300_MAX_TEXTURE_UNITS
) {
1311 "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1312 mtu
, R300_MAX_TEXTURE_UNITS
);
1316 /* We cannot let disabled tmu offsets pass DRM */
1317 for (i
= 0; i
< mtu
; i
++) {
1318 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
1320 #if 0 /* Enables old behaviour */
1323 tmu_mappings
[i
] = hw_tmu
;
1325 t
= r300
->state
.texture
.unit
[i
].texobj
;
1326 /* XXX questionable fix for bug 9170: */
1330 if ((t
->format
& 0xffffff00) == 0xffffff00) {
1332 ("unknown texture format (entry %x) encountered. Help me !\n",
1336 if (RADEON_DEBUG
& DEBUG_STATE
)
1338 "Activating texture unit %d\n", i
);
1340 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1342 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+
1344 gen_fixed_filter(t
->filter
) | (hw_tmu
<< 28);
1345 /* Currently disabled! */
1346 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0; //0x20501f80;
1347 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1349 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+
1350 hw_tmu
] = t
->format
;
1351 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1353 r300
->hw
.tex
.offset
.cmd
[R300_TEX_VALUE_0
+
1354 hw_tmu
] = t
->offset
;
1356 if (t
->offset
& R300_TXO_MACRO_TILE
) {
1357 WARN_ONCE("macro tiling enabled!\n");
1360 if (t
->offset
& R300_TXO_MICRO_TILE
) {
1361 WARN_ONCE("micro tiling enabled!\n");
1364 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_VALUE_0
+
1366 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+
1370 last_hw_tmu
= hw_tmu
;
1376 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1377 cmdpacket0(R300_TX_FILTER_0
, last_hw_tmu
+ 1);
1378 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] =
1379 cmdpacket0(R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1380 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] =
1381 cmdpacket0(R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1382 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] =
1383 cmdpacket0(R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1384 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] =
1385 cmdpacket0(R300_TX_PITCH_0
, last_hw_tmu
+ 1);
1386 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] =
1387 cmdpacket0(R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1388 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] =
1389 cmdpacket0(R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1390 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] =
1391 cmdpacket0(R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1393 if (!fp
) /* should only happenen once, just after context is created */
1396 R300_STATECHANGE(r300
, fpt
);
1398 for (i
= 0; i
< fp
->tex
.length
; i
++) {
1403 unit
= fp
->tex
.inst
[i
] >> R300_FPITX_IMAGE_SHIFT
;
1406 val
= fp
->tex
.inst
[i
];
1407 val
&= ~R300_FPITX_IMAGE_MASK
;
1410 (val
& R300_FPITX_OPCODE_MASK
) >> R300_FPITX_OPCODE_SHIFT
;
1411 if (opcode
== R300_FPITX_OP_KIL
) {
1412 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1414 if (tmu_mappings
[unit
] >= 0) {
1416 tmu_mappings
[unit
] <<
1417 R300_FPITX_IMAGE_SHIFT
;
1418 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1420 // We get here when the corresponding texture image is incomplete
1421 // (e.g. incomplete mipmaps etc.)
1422 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1427 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] =
1428 cmdpacket0(R300_PFS_TEXI_0
, fp
->tex
.length
);
1430 if (RADEON_DEBUG
& DEBUG_STATE
)
1431 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n",
1432 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1435 union r300_outputs_written
{
1436 GLuint vp_outputs
; /* hw_tcl_on */
1437 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1440 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1441 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1442 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1444 void r300SetupRSUnit(GLcontext
* ctx
)
1446 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1447 /* I'm still unsure if these are needed */
1448 GLuint interp_magic
[8] = {
1458 union r300_outputs_written OutputsWritten
;
1460 int fp_reg
, high_rr
;
1461 int in_texcoords
, col_interp_nr
;
1465 OutputsWritten
.vp_outputs
=
1466 CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1468 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
,
1469 r300
->state
.render_inputs_bitset
);
1471 if (ctx
->FragmentProgram
._Current
)
1472 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1474 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1475 return; /* This should only ever happen once.. */
1478 R300_STATECHANGE(r300
, ri
);
1479 R300_STATECHANGE(r300
, rc
);
1480 R300_STATECHANGE(r300
, rr
);
1482 fp_reg
= in_texcoords
= col_interp_nr
= high_rr
= 0;
1484 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] = 0;
1486 if (InputsRead
& FRAG_BIT_WPOS
) {
1487 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1488 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1491 if (i
== ctx
->Const
.MaxTextureUnits
) {
1492 fprintf(stderr
, "\tno free texcoord found...\n");
1496 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1497 InputsRead
&= ~FRAG_BIT_WPOS
;
1500 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1501 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = 0
1502 | R300_RS_INTERP_USED
1503 | (in_texcoords
<< R300_RS_INTERP_SRC_SHIFT
)
1506 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] = 0;
1507 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1508 //assert(r300->state.texture.tc_count != 0);
1509 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] |= R300_RS_ROUTE_ENABLE
| i
/* source INTERP */
1510 | (fp_reg
<< R300_RS_ROUTE_DEST_SHIFT
);
1513 if (!R300_OUTPUTS_WRITTEN_TEST
1514 (OutputsWritten
, VERT_RESULT_TEX0
+ i
,
1515 _TNL_ATTRIB_TEX(i
))) {
1516 /* Passing invalid data here can lock the GPU. */
1518 ("fragprog wants coords for tex%d, vp doesn't provide them!\n",
1520 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1523 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1526 /* Need to count all coords enabled at vof */
1527 if (R300_OUTPUTS_WRITTEN_TEST
1528 (OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
)))
1532 if (InputsRead
& FRAG_BIT_COL0
) {
1533 if (!R300_OUTPUTS_WRITTEN_TEST
1534 (OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1536 ("fragprog wants col0, vp doesn't provide it\n");
1537 goto out
; /* FIXME */
1538 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1542 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1543 | R300_RS_ROUTE_0_COLOR
1544 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1545 InputsRead
&= ~FRAG_BIT_COL0
;
1550 if (InputsRead
& FRAG_BIT_COL1
) {
1551 if (!R300_OUTPUTS_WRITTEN_TEST
1552 (OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1554 ("fragprog wants col1, vp doesn't provide it\n");
1558 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] |=
1559 R300_RS_ROUTE_1_UNKNOWN11
| R300_RS_ROUTE_1_COLOR1
|
1560 (fp_reg
++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT
);
1561 InputsRead
&= ~FRAG_BIT_COL1
;
1567 /* Need at least one. This might still lock as the values are undefined... */
1568 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1569 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1570 | R300_RS_ROUTE_0_COLOR
1571 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1575 r300
->hw
.rc
.cmd
[1] = 0 | (in_texcoords
<< R300_RS_CNTL_TC_CNT_SHIFT
)
1576 | (col_interp_nr
<< R300_RS_CNTL_CI_CNT_SHIFT
)
1577 | R300_RS_CNTL_0_UNKNOWN_18
;
1579 assert(high_rr
>= 0);
1580 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] =
1581 cmdpacket0(R300_RS_ROUTE_0
, high_rr
+ 1);
1582 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1585 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n",
1589 #define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
1591 #define bump_vpu_count(ptr, new_count) do{\
1592 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1593 int _nc=(new_count)/4; \
1594 assert(_nc < 256); \
1595 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1598 void static inline setup_vertex_shader_fragment(r300ContextPtr r300
, int dest
, struct
1599 r300_vertex_shader_fragment
1604 if (vsf
->length
== 0)
1607 if (vsf
->length
& 0x3) {
1609 "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1613 switch ((dest
>> 8) & 0xf) {
1615 R300_STATECHANGE(r300
, vpi
);
1616 for (i
= 0; i
< vsf
->length
; i
++)
1617 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+ i
+
1618 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1619 bump_vpu_count(r300
->hw
.vpi
.cmd
,
1620 vsf
->length
+ 4 * (dest
& 0xff));
1624 R300_STATECHANGE(r300
, vpp
);
1625 for (i
= 0; i
< vsf
->length
; i
++)
1626 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+ i
+
1627 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1628 bump_vpu_count(r300
->hw
.vpp
.cmd
,
1629 vsf
->length
+ 4 * (dest
& 0xff));
1632 R300_STATECHANGE(r300
, vps
);
1633 for (i
= 0; i
< vsf
->length
; i
++)
1634 r300
->hw
.vps
.cmd
[1 + i
+ 4 * (dest
& 0xff)] =
1636 bump_vpu_count(r300
->hw
.vps
.cmd
,
1637 vsf
->length
+ 4 * (dest
& 0xff));
1641 "%s:%s don't know how to handle dest %04x\n",
1642 __FILE__
, __FUNCTION__
, dest
);
1647 void r300SetupVertexProgram(r300ContextPtr rmesa
);
1649 /* just a skeleton for now.. */
1651 /* Generate a vertex shader that simply transforms vertex and texture coordinates,
1652 while leaving colors intact. Nothing fancy (like lights)
1654 If implementing lights make a copy first, so it is easy to switch between the two versions */
1655 static void r300GenerateSimpleVertexShader(r300ContextPtr r300
)
1660 /* Allocate parameters */
1661 r300
->state
.vap_param
.transform_offset
= 0x0; /* transform matrix */
1662 r300
->state
.vertex_shader
.param_offset
= 0x0;
1663 r300
->state
.vertex_shader
.param_count
= 0x4; /* 4 vector values - 4x4 matrix */
1665 r300
->state
.vertex_shader
.program_start
= 0x0;
1666 r300
->state
.vertex_shader
.unknown_ptr1
= 0x4; /* magic value ? */
1667 r300
->state
.vertex_shader
.program_end
= 0x0;
1669 r300
->state
.vertex_shader
.unknown_ptr2
= 0x0; /* magic value */
1670 r300
->state
.vertex_shader
.unknown_ptr3
= 0x4; /* magic value */
1672 r300
->state
.vertex_shader
.unknown1
.length
= 0;
1673 r300
->state
.vertex_shader
.unknown2
.length
= 0;
1675 #define WRITE_OP(oper,source1,source2,source3) {\
1676 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].op=(oper); \
1677 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src[0]=(source1); \
1678 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src[1]=(source2); \
1679 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src[2]=(source3); \
1680 r300->state.vertex_shader.program_end++; \
1683 for (i
= VERT_ATTRIB_POS
; i
< VERT_ATTRIB_MAX
; i
++)
1684 if (r300
->state
.sw_tcl_inputs
[i
] != -1) {
1685 WRITE_OP(EASY_VSF_OP(MUL
, o_reg
++, ALL
, RESULT
),
1686 VSF_REG(r300
->state
.sw_tcl_inputs
[i
]),
1687 VSF_ATTR_UNITY(r300
->state
.
1689 VSF_UNITY(r300
->state
.sw_tcl_inputs
[i
])
1694 r300
->state
.vertex_shader
.program_end
--; /* r300 wants program length to be one more - no idea why */
1695 r300
->state
.vertex_shader
.program
.length
=
1696 (r300
->state
.vertex_shader
.program_end
+ 1) * 4;
1698 r300
->state
.vertex_shader
.unknown_ptr1
= r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1699 r300
->state
.vertex_shader
.unknown_ptr2
= r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1700 r300
->state
.vertex_shader
.unknown_ptr3
= r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1704 void r300SetupVertexShader(r300ContextPtr rmesa
)
1706 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1708 /* Reset state, in case we don't use something */
1709 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1710 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1711 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1713 /* Not sure why this doesnt work...
1714 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
1715 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. */
1716 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
1718 && ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->
1720 r300SetupVertexProgram(rmesa
);
1724 /* This needs to be replaced by vertex shader generation code */
1725 r300GenerateSimpleVertexShader(rmesa
);
1727 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
,
1728 &(rmesa
->state
.vertex_shader
.program
));
1731 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
,
1732 &(rmesa
->state
.vertex_shader
.unknown1
));
1733 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
,
1734 &(rmesa
->state
.vertex_shader
.unknown2
));
1737 R300_STATECHANGE(rmesa
, pvs
);
1738 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
1739 (rmesa
->state
.vertex_shader
.
1740 program_start
<< R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1741 | (rmesa
->state
.vertex_shader
.
1742 unknown_ptr1
<< R300_PVS_CNTL_1_POS_END_SHIFT
)
1743 | (rmesa
->state
.vertex_shader
.
1744 program_end
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1745 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
1746 (rmesa
->state
.vertex_shader
.
1747 param_offset
<< R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1748 | (rmesa
->state
.vertex_shader
.
1749 param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1750 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
1751 (rmesa
->state
.vertex_shader
.
1752 unknown_ptr2
<< R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1753 | (rmesa
->state
.vertex_shader
.unknown_ptr3
<< 0);
1755 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1756 so I leave it as a reminder */
1758 reg_start(R300_VAP_PVS_WAITIDLE
, 0);
1763 void r300SetupVertexProgram(r300ContextPtr rmesa
)
1765 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1768 struct r300_vertex_program
*prog
=
1769 (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1771 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1772 R300_STATECHANGE(rmesa
, vpp
);
1774 r300VertexProgUpdateParams(ctx
, (struct r300_vertex_program_cont
*)
1775 ctx
->VertexProgram
._Current
/*prog */ ,
1776 (float *)&rmesa
->hw
.vpp
.
1777 cmd
[R300_VPP_PARAM_0
]);
1778 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
1781 /* Reset state, in case we don't use something */
1782 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1783 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1785 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(prog
->program
));
1788 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
,
1789 &(rmesa
->state
.vertex_shader
.unknown1
));
1790 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
,
1791 &(rmesa
->state
.vertex_shader
.unknown2
));
1794 inst_count
= prog
->program
.length
/ 4 - 1;
1796 R300_STATECHANGE(rmesa
, pvs
);
1797 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
1798 (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1799 | (inst_count
/*pos_end */ << R300_PVS_CNTL_1_POS_END_SHIFT
)
1800 | (inst_count
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1801 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
1802 (0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1803 | (param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1804 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
1805 (0 /*rmesa->state.vertex_shader.unknown_ptr2 */ <<
1806 R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1807 | (inst_count
/*rmesa->state.vertex_shader.unknown_ptr3 */ <<
1810 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1811 so I leave it as a reminder */
1813 reg_start(R300_VAP_PVS_WAITIDLE
, 0);
1818 extern void _tnl_UpdateFixedFunctionProgram(GLcontext
* ctx
);
1820 extern int future_hw_tcl_on
;
1821 void r300UpdateShaders(r300ContextPtr rmesa
)
1824 struct r300_vertex_program
*vp
;
1827 ctx
= rmesa
->radeon
.glCtx
;
1829 if (rmesa
->NewGLState
&& hw_tcl_on
) {
1830 rmesa
->NewGLState
= 0;
1832 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1833 rmesa
->temp_attrib
[i
] =
1834 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
1835 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
1836 &rmesa
->dummy_attrib
[i
];
1839 _tnl_UpdateFixedFunctionProgram(ctx
);
1841 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1842 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
1843 rmesa
->temp_attrib
[i
];
1846 r300SelectVertexShader(rmesa
);
1847 vp
= (struct r300_vertex_program
*)
1848 CURRENT_VERTEX_SHADER(ctx
);
1849 /*if (vp->translated == GL_FALSE)
1850 r300TranslateVertexShader(vp); */
1851 if (vp
->translated
== GL_FALSE
) {
1852 fprintf(stderr
, "Failing back to sw-tcl\n");
1853 hw_tcl_on
= future_hw_tcl_on
= 0;
1854 r300ResetHwState(rmesa
);
1858 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
1863 void r300UpdateShaderStates(r300ContextPtr rmesa
)
1866 ctx
= rmesa
->radeon
.glCtx
;
1868 r300UpdateTextureState(ctx
);
1870 r300SetupPixelShader(rmesa
);
1871 r300SetupTextures(ctx
);
1873 if ((rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
1874 r300SetupVertexShader(rmesa
);
1875 r300SetupRSUnit(ctx
);
1878 /* This is probably wrong for some values, I need to test this
1879 * some more. Range checking would be a good idea also..
1881 * But it works for most things. I'll fix it later if someone
1882 * else with a better clue doesn't
1884 static unsigned int r300PackFloat24(float f
)
1888 unsigned int float24
= 0;
1893 mantissa
= frexpf(f
, &exponent
);
1897 float24
|= (1 << 23);
1898 mantissa
= mantissa
* -1.0;
1900 /* Handle exponent, bias of 63 */
1902 float24
|= (exponent
<< 16);
1903 /* Kill 7 LSB of mantissa */
1904 float24
|= (r300PackFloat32(mantissa
) & 0x7FFFFF) >> 7;
1909 void r300SetupPixelShader(r300ContextPtr rmesa
)
1911 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1912 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1913 (char *)ctx
->FragmentProgram
._Current
;
1916 if (!fp
) /* should only happenen once, just after context is created */
1919 r300TranslateFragmentShader(rmesa
, fp
);
1920 if (!fp
->translated
) {
1921 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
1925 #define OUTPUT_FIELD(st, reg, field) \
1926 R300_STATECHANGE(rmesa, st); \
1927 for(i=0;i<=fp->alu_end;i++) \
1928 rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=fp->alu.inst[i].field;\
1929 rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmdpacket0(reg, fp->alu_end+1);
1931 OUTPUT_FIELD(fpi
[0], R300_PFS_INSTR0_0
, inst0
);
1932 OUTPUT_FIELD(fpi
[1], R300_PFS_INSTR1_0
, inst1
);
1933 OUTPUT_FIELD(fpi
[2], R300_PFS_INSTR2_0
, inst2
);
1934 OUTPUT_FIELD(fpi
[3], R300_PFS_INSTR3_0
, inst3
);
1937 R300_STATECHANGE(rmesa
, fp
);
1938 /* I just want to say, the way these nodes are stored.. weird.. */
1939 for (i
= 0, k
= (4 - (fp
->cur_node
+ 1)); i
< 4; i
++, k
++) {
1940 if (i
< (fp
->cur_node
+ 1)) {
1941 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ k
] =
1943 alu_offset
<< R300_PFS_NODE_ALU_OFFSET_SHIFT
)
1945 alu_end
<< R300_PFS_NODE_ALU_END_SHIFT
)
1947 tex_offset
<< R300_PFS_NODE_TEX_OFFSET_SHIFT
)
1949 tex_end
<< R300_PFS_NODE_TEX_END_SHIFT
)
1950 | fp
->node
[i
].flags
; /* ( (k==3) ? R300_PFS_NODE_LAST_NODE : 0); */
1952 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ (3 - i
)] = 0;
1957 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
] =
1958 fp
->cur_node
| (fp
->first_node_has_tex
<< 3);
1960 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
] = fp
->max_temp_idx
;
1962 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
] =
1963 (fp
->alu_offset
<< R300_PFS_CNTL_ALU_OFFSET_SHIFT
)
1964 | (fp
->alu_end
<< R300_PFS_CNTL_ALU_END_SHIFT
)
1965 | (fp
->tex_offset
<< R300_PFS_CNTL_TEX_OFFSET_SHIFT
)
1966 | (fp
->tex_end
<< R300_PFS_CNTL_TEX_END_SHIFT
);
1968 R300_STATECHANGE(rmesa
, fpp
);
1969 for (i
= 0; i
< fp
->const_nr
; i
++) {
1970 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] =
1971 r300PackFloat24(fp
->constant
[i
][0]);
1972 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] =
1973 r300PackFloat24(fp
->constant
[i
][1]);
1974 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] =
1975 r300PackFloat24(fp
->constant
[i
][2]);
1976 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] =
1977 r300PackFloat24(fp
->constant
[i
][3]);
1979 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
] =
1980 cmdpacket0(R300_PFS_PARAM_0_X
, fp
->const_nr
* 4);
1984 * Called by Mesa after an internal state update.
1986 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
1988 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1990 _swrast_InvalidateState(ctx
, new_state
);
1991 _swsetup_InvalidateState(ctx
, new_state
);
1992 _vbo_InvalidateState(ctx
, new_state
);
1993 _tnl_InvalidateState(ctx
, new_state
);
1994 _ae_invalidate_state(ctx
, new_state
);
1996 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
1997 r300UpdateDrawBuffer(ctx
);
2000 r300UpdateStateParameters(ctx
, new_state
);
2002 r300
->NewGLState
|= new_state
;
2006 * Completely recalculates hardware state based on the Mesa state.
2008 void r300ResetHwState(r300ContextPtr r300
)
2010 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2013 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2016 if (RADEON_DEBUG
& DEBUG_STATE
)
2017 fprintf(stderr
, "%s\n", __FUNCTION__
);
2019 /* This is a place to initialize registers which
2020 have bitfields accessed by different functions
2021 and not all bits are used */
2023 /* go and compute register values from GL state */
2025 r300UpdateWindow(ctx
);
2028 ctx
->Color
.ColorMask
[RCOMP
],
2029 ctx
->Color
.ColorMask
[GCOMP
],
2030 ctx
->Color
.ColorMask
[BCOMP
], ctx
->Color
.ColorMask
[ACOMP
]);
2032 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
2033 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
2034 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
2037 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
2038 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
2039 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0],
2040 ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
2041 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0],
2042 ctx
->Stencil
.ZFailFunc
[0],
2043 ctx
->Stencil
.ZPassFunc
[0]);
2045 r300UpdateCulling(ctx
);
2047 r300UpdateTextureState(ctx
);
2049 r300SetBlendState(ctx
);
2051 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
2052 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
2054 /* Initialize magic registers
2055 TODO : learn what they really do, or get rid of
2056 those we don't have to touch */
2058 r300
->hw
.vap_cntl
.cmd
[1] = 0x0014045a;
2060 r300
->hw
.vap_cntl
.cmd
[1] = 0x0030045A; //0x0030065a /* Dangerous */
2061 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
2062 | R300_VPORT_X_OFFSET_ENA
2063 | R300_VPORT_Y_SCALE_ENA
2064 | R300_VPORT_Y_OFFSET_ENA
2065 | R300_VPORT_Z_SCALE_ENA
2066 | R300_VPORT_Z_OFFSET_ENA
| R300_VTX_W0_FMT
;
2067 r300
->hw
.vte
.cmd
[2] = 0x00000008;
2069 r300
->hw
.unk2134
.cmd
[1] = 0x00FFFFFF;
2070 r300
->hw
.unk2134
.cmd
[2] = 0x00000000;
2071 if (_mesa_little_endian())
2072 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_NO_SWAP
;
2074 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_32BIT_SWAP
;
2076 /* disable VAP/TCL on non-TCL capable chips */
2078 r300
->hw
.vap_cntl_status
.cmd
[1] |= R300_VAP_TCL_BYPASS
;
2080 r300
->hw
.unk21DC
.cmd
[1] = 0xAAAAAAAA;
2082 r300
->hw
.unk221C
.cmd
[1] = R300_221C_NORMAL
;
2084 r300
->hw
.unk2220
.cmd
[1] = r300PackFloat32(1.0);
2085 r300
->hw
.unk2220
.cmd
[2] = r300PackFloat32(1.0);
2086 r300
->hw
.unk2220
.cmd
[3] = r300PackFloat32(1.0);
2087 r300
->hw
.unk2220
.cmd
[4] = r300PackFloat32(1.0);
2089 /* what about other chips than r300 or rv350??? */
2090 if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
)
2091 r300
->hw
.unk2288
.cmd
[1] = R300_2288_R300
;
2093 r300
->hw
.unk2288
.cmd
[1] = R300_2288_RV350
;
2095 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2096 | R300_GB_LINE_STUFF_ENABLE
2097 | R300_GB_TRIANGLE_STUFF_ENABLE
/*| R300_GB_UNK31 */ ;
2099 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2100 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2101 if ((r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
) ||
2102 (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R350
))
2103 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2104 R300_GB_TILE_ENABLE
| R300_GB_TILE_PIPE_COUNT_R300
|
2105 R300_GB_TILE_SIZE_16
;
2106 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
)
2107 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2108 R300_GB_TILE_ENABLE
| R300_GB_TILE_PIPE_COUNT_RV410
|
2109 R300_GB_TILE_SIZE_16
;
2110 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
)
2111 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2112 R300_GB_TILE_ENABLE
| R300_GB_TILE_PIPE_COUNT_R420
|
2113 R300_GB_TILE_SIZE_16
;
2115 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2116 R300_GB_TILE_ENABLE
| R300_GB_TILE_PIPE_COUNT_RV300
|
2117 R300_GB_TILE_SIZE_16
;
2118 /* set to 0 when fog is disabled? */
2119 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2120 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = R300_AA_DISABLE
; /* No antialiasing */
2122 r300
->hw
.unk4200
.cmd
[1] = r300PackFloat32(0.0);
2123 r300
->hw
.unk4200
.cmd
[2] = r300PackFloat32(0.0);
2124 r300
->hw
.unk4200
.cmd
[3] = r300PackFloat32(1.0);
2125 r300
->hw
.unk4200
.cmd
[4] = r300PackFloat32(1.0);
2127 r300
->hw
.unk4214
.cmd
[1] = 0x00050005;
2129 r300PointSize(ctx
, 0.0);
2131 r300
->hw
.unk4230
.cmd
[1] = 0x18000006;
2132 r300
->hw
.unk4230
.cmd
[2] = 0x00020006;
2133 r300
->hw
.unk4230
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2135 r300LineWidth(ctx
, 0.0);
2137 r300
->hw
.unk4260
.cmd
[1] = 0;
2138 r300
->hw
.unk4260
.cmd
[2] = r300PackFloat32(0.0);
2139 r300
->hw
.unk4260
.cmd
[3] = r300PackFloat32(1.0);
2141 r300
->hw
.shade
.cmd
[1] = 0x00000002;
2142 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2143 r300
->hw
.shade
.cmd
[3] = 0x00000000;
2144 r300
->hw
.shade
.cmd
[4] = 0x00000000;
2146 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2147 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2148 r300
->hw
.polygon_mode
.cmd
[2] = 0x00000001;
2149 r300
->hw
.polygon_mode
.cmd
[3] = 0x00000000;
2150 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
2152 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
,
2153 ctx
->Polygon
.OffsetUnits
);
2154 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2156 r300
->hw
.unk42C0
.cmd
[1] = 0x4B7FFFFF;
2157 r300
->hw
.unk42C0
.cmd
[2] = 0x00000000;
2159 r300
->hw
.unk43A4
.cmd
[1] = 0x0000001C;
2160 r300
->hw
.unk43A4
.cmd
[2] = 0x2DA49525;
2162 r300
->hw
.unk43E8
.cmd
[1] = 0x00FFFFFF;
2164 r300
->hw
.unk46A4
.cmd
[1] = 0x00001B01;
2165 r300
->hw
.unk46A4
.cmd
[2] = 0x00001B0F;
2166 r300
->hw
.unk46A4
.cmd
[3] = 0x00001B0F;
2167 r300
->hw
.unk46A4
.cmd
[4] = 0x00001B0F;
2168 r300
->hw
.unk46A4
.cmd
[5] = 0x00000001;
2170 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2171 ctx
->Driver
.Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2172 ctx
->Driver
.Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2173 ctx
->Driver
.Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2174 ctx
->Driver
.Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2175 ctx
->Driver
.Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2176 ctx
->Driver
.Fogfv(ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2178 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
2179 r300
->hw
.unk4BD8
.cmd
[1] = 0;
2181 r300
->hw
.unk4E00
.cmd
[1] = 0;
2183 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2184 r300
->hw
.blend_color
.cmd
[2] = 0;
2185 r300
->hw
.blend_color
.cmd
[3] = 0;
2187 /* Again, r300ClearBuffer uses this */
2188 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] =
2189 r300
->radeon
.state
.color
.drawOffset
+
2190 r300
->radeon
.radeonScreen
->fbLocation
;
2191 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.state
.color
.drawPitch
;
2193 if (r300
->radeon
.radeonScreen
->cpp
== 4)
2194 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
2196 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
2198 if (r300
->radeon
.sarea
->tiling_enabled
)
2199 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
2201 r300
->hw
.unk4E50
.cmd
[1] = 0;
2202 r300
->hw
.unk4E50
.cmd
[2] = 0;
2203 r300
->hw
.unk4E50
.cmd
[3] = 0;
2204 r300
->hw
.unk4E50
.cmd
[4] = 0;
2205 r300
->hw
.unk4E50
.cmd
[5] = 0;
2206 r300
->hw
.unk4E50
.cmd
[6] = 0;
2207 r300
->hw
.unk4E50
.cmd
[7] = 0;
2208 r300
->hw
.unk4E50
.cmd
[8] = 0;
2209 r300
->hw
.unk4E50
.cmd
[9] = 0;
2211 r300
->hw
.unk4E88
.cmd
[1] = 0;
2213 r300
->hw
.unk4EA0
.cmd
[1] = 0x00000000;
2214 r300
->hw
.unk4EA0
.cmd
[2] = 0xffffffff;
2216 switch (ctx
->Visual
.depthBits
) {
2218 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTH_FORMAT_16BIT_INT_Z
;
2221 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTH_FORMAT_24BIT_INT_Z
;
2224 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2225 ctx
->Visual
.depthBits
);
2230 //r300->hw.zstencil_format.cmd[1] |= R300_DEPTH_FORMAT_UNK32;
2232 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
2233 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
2235 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
2236 r300
->radeon
.radeonScreen
->depthOffset
+
2237 r300
->radeon
.radeonScreen
->fbLocation
;
2238 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
2240 if (r300
->radeon
.sarea
->tiling_enabled
) {
2241 /* Turn off when clearing buffers ? */
2242 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_TILE_ENABLE
;
2244 if (ctx
->Visual
.depthBits
== 24)
2245 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |=
2246 R300_DEPTH_MICROTILE_ENABLE
;
2249 r300
->hw
.unk4F28
.cmd
[1] = 0;
2251 r300
->hw
.unk4F30
.cmd
[1] = 0;
2252 r300
->hw
.unk4F30
.cmd
[2] = 0;
2254 r300
->hw
.unk4F44
.cmd
[1] = 0;
2256 r300
->hw
.unk4F54
.cmd
[1] = 0;
2259 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2260 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2261 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2262 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2265 r300
->hw
.all_dirty
= GL_TRUE
;
2269 * Calculate initial hardware state and register state functions.
2270 * Assumes that the command buffer and state atoms have been
2271 * initialized already.
2273 void r300InitState(r300ContextPtr r300
)
2275 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2278 radeonInitState(&r300
->radeon
);
2280 switch (ctx
->Visual
.depthBits
) {
2282 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2283 depth_fmt
= R300_DEPTH_FORMAT_16BIT_INT_Z
;
2284 r300
->state
.stencil
.clear
= 0x00000000;
2287 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2288 depth_fmt
= R300_DEPTH_FORMAT_24BIT_INT_Z
;
2289 r300
->state
.stencil
.clear
= 0x00ff0000;
2292 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2293 ctx
->Visual
.depthBits
);
2297 /* Only have hw stencil when depth buffer is 24 bits deep */
2298 r300
->state
.stencil
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2299 ctx
->Visual
.depthBits
== 24);
2301 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2303 r300ResetHwState(r300
);
2306 static void r300RenderMode(GLcontext
* ctx
, GLenum mode
)
2308 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2314 * Initialize driver's state callback functions
2316 void r300InitStateFuncs(struct dd_function_table
*functions
)
2318 radeonInitStateFuncs(functions
);
2320 functions
->UpdateState
= r300InvalidateState
;
2321 functions
->AlphaFunc
= r300AlphaFunc
;
2322 functions
->BlendColor
= r300BlendColor
;
2323 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2324 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2325 functions
->Enable
= r300Enable
;
2326 functions
->ColorMask
= r300ColorMask
;
2327 functions
->DepthFunc
= r300DepthFunc
;
2328 functions
->DepthMask
= r300DepthMask
;
2329 functions
->CullFace
= r300CullFace
;
2330 functions
->Fogfv
= r300Fogfv
;
2331 functions
->FrontFace
= r300FrontFace
;
2332 functions
->ShadeModel
= r300ShadeModel
;
2334 /* Stencil related */
2335 functions
->ClearStencil
= r300ClearStencil
;
2336 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2337 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2338 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2340 /* Viewport related */
2341 functions
->Viewport
= r300Viewport
;
2342 functions
->DepthRange
= r300DepthRange
;
2343 functions
->PointSize
= r300PointSize
;
2344 functions
->LineWidth
= r300LineWidth
;
2346 functions
->PolygonOffset
= r300PolygonOffset
;
2347 functions
->PolygonMode
= r300PolygonMode
;
2349 functions
->RenderMode
= r300RenderMode
;