2 Copyright (C) The Weather Channel, Inc. 2002.
3 Copyright (C) 2004 Nicolai Haehnle.
6 The Weather Channel (TM) funded Tungsten Graphics to develop the
7 initial release of the Radeon 8500 driver under the XFree86 license.
8 This notice must be preserved.
10 Permission is hereby granted, free of charge, to any person obtaining
11 a copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sublicense, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial
20 portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
34 * Nicolai Haehnle <prefect_@gmx.net>
44 #include "simple_list.h"
46 #include "api_arrayelt.h"
47 #include "swrast/swrast.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "shader/prog_parameter.h"
50 #include "shader/prog_statevars.h"
53 #include "texformat.h"
55 #include "radeon_ioctl.h"
56 #include "radeon_state.h"
57 #include "r300_context.h"
58 #include "r300_ioctl.h"
59 #include "r300_state.h"
61 #include "r300_program.h"
62 #include "r300_emit.h"
63 #include "r300_fragprog.h"
65 #include "r300_maos.h"
67 #include "drirenderbuffer.h"
69 static void r300BlendColor(GLcontext
* ctx
, const GLfloat cf
[4])
72 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
74 R300_STATECHANGE(rmesa
, 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] = r300PackColor(4, color
[3], color
[0],
86 * Calculate the hardware blend factor setting. This same function is used
87 * for source and destination of both alpha and RGB.
90 * The hardware register value for the specified blend factor. This value
91 * will need to be shifted into the correct position for either source or
95 * Since the two cases where source and destination are handled differently
96 * are essentially error cases, they should never happen. Determine if these
97 * cases can be removed.
99 static int blend_factor(GLenum factor
, GLboolean is_src
)
105 func
= R300_BLEND_GL_ZERO
;
108 func
= R300_BLEND_GL_ONE
;
111 func
= R300_BLEND_GL_DST_COLOR
;
113 case GL_ONE_MINUS_DST_COLOR
:
114 func
= R300_BLEND_GL_ONE_MINUS_DST_COLOR
;
117 func
= R300_BLEND_GL_SRC_COLOR
;
119 case GL_ONE_MINUS_SRC_COLOR
:
120 func
= R300_BLEND_GL_ONE_MINUS_SRC_COLOR
;
123 func
= R300_BLEND_GL_SRC_ALPHA
;
125 case GL_ONE_MINUS_SRC_ALPHA
:
126 func
= R300_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
129 func
= R300_BLEND_GL_DST_ALPHA
;
131 case GL_ONE_MINUS_DST_ALPHA
:
132 func
= R300_BLEND_GL_ONE_MINUS_DST_ALPHA
;
134 case GL_SRC_ALPHA_SATURATE
:
135 func
= (is_src
) ? R300_BLEND_GL_SRC_ALPHA_SATURATE
:
138 case GL_CONSTANT_COLOR
:
139 func
= R300_BLEND_GL_CONST_COLOR
;
141 case GL_ONE_MINUS_CONSTANT_COLOR
:
142 func
= R300_BLEND_GL_ONE_MINUS_CONST_COLOR
;
144 case GL_CONSTANT_ALPHA
:
145 func
= R300_BLEND_GL_CONST_ALPHA
;
147 case GL_ONE_MINUS_CONSTANT_ALPHA
:
148 func
= R300_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
151 fprintf(stderr
, "unknown blend factor %x\n", factor
);
152 func
= (is_src
) ? R300_BLEND_GL_ONE
: R300_BLEND_GL_ZERO
;
158 * Sets both the blend equation and the blend function.
159 * This is done in a single
160 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
161 * change the interpretation of the blend function.
162 * Also, make sure that blend function and blend equation are set to their
163 * default value if color blending is not enabled, since at least blend
164 * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results
165 * otherwise for unknown reasons.
168 /* helper function */
169 static void r300_set_blend_cntl(r300ContextPtr r300
, int func
, int eqn
, int cbits
, int funcA
, int eqnA
)
171 GLuint new_ablend
, new_cblend
;
174 fprintf(stderr
, "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n", eqnA
, funcA
, eqn
, func
, cbits
);
176 new_ablend
= eqnA
| funcA
;
177 new_cblend
= eqn
| func
;
179 /* Some blend factor combinations don't seem to work when the
180 * BLEND_NO_SEPARATE bit is set.
182 * Especially problematic candidates are the ONE_MINUS_* flags,
183 * but I can't see a real pattern.
186 if (new_ablend
== new_cblend
) {
187 new_cblend
|= R300_BLEND_NO_SEPARATE
;
192 if((new_ablend
!= r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]) ||
193 (new_cblend
!= r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
])) {
194 R300_STATECHANGE(r300
, bld
);
195 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]=new_ablend
;
196 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
]=new_cblend
;
201 static void r300_set_blend_state(GLcontext
* ctx
)
203 r300ContextPtr r300
= R300_CONTEXT(ctx
);
204 int func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
205 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
206 int eqn
= R300_COMB_FCN_ADD_CLAMP
;
207 int funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
208 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
209 int eqnA
= R300_COMB_FCN_ADD_CLAMP
;
211 if (RGBA_LOGICOP_ENABLED(ctx
) || !ctx
->Color
.BlendEnabled
) {
212 r300_set_blend_cntl(r300
,
218 func
= (blend_factor(ctx
->Color
.BlendSrcRGB
, GL_TRUE
) << R300_SRC_BLEND_SHIFT
) |
219 (blend_factor(ctx
->Color
.BlendDstRGB
, GL_FALSE
) << R300_DST_BLEND_SHIFT
);
221 switch (ctx
->Color
.BlendEquationRGB
) {
223 eqn
= R300_COMB_FCN_ADD_CLAMP
;
226 case GL_FUNC_SUBTRACT
:
227 eqn
= R300_COMB_FCN_SUB_CLAMP
;
230 case GL_FUNC_REVERSE_SUBTRACT
:
231 eqn
= R300_COMB_FCN_RSUB_CLAMP
;
235 eqn
= R300_COMB_FCN_MIN
;
236 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
237 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
241 eqn
= R300_COMB_FCN_MAX
;
242 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
243 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
248 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
249 __func__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
254 funcA
= (blend_factor(ctx
->Color
.BlendSrcA
, GL_TRUE
) << R300_SRC_BLEND_SHIFT
) |
255 (blend_factor(ctx
->Color
.BlendDstA
, GL_FALSE
) << R300_DST_BLEND_SHIFT
);
257 switch (ctx
->Color
.BlendEquationA
) {
259 eqnA
= R300_COMB_FCN_ADD_CLAMP
;
262 case GL_FUNC_SUBTRACT
:
263 eqnA
= R300_COMB_FCN_SUB_CLAMP
;
266 case GL_FUNC_REVERSE_SUBTRACT
:
267 eqnA
= R300_COMB_FCN_RSUB_CLAMP
;
271 eqnA
= R300_COMB_FCN_MIN
;
272 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
273 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
277 eqnA
= R300_COMB_FCN_MAX
;
278 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
279 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
283 fprintf(stderr
, "[%s:%u] Invalid A blend equation (0x%04x).\n",
284 __func__
, __LINE__
, ctx
->Color
.BlendEquationA
);
288 r300_set_blend_cntl(r300
,
289 func
, eqn
, R300_BLEND_UNKNOWN
| R300_BLEND_ENABLE
,
293 static void r300BlendEquationSeparate(GLcontext
* ctx
,
294 GLenum modeRGB
, GLenum modeA
)
296 r300_set_blend_state(ctx
);
299 static void r300BlendFuncSeparate(GLcontext
* ctx
,
300 GLenum sfactorRGB
, GLenum dfactorRGB
,
301 GLenum sfactorA
, GLenum dfactorA
)
303 r300_set_blend_state(ctx
);
307 * Update our tracked culling state based on Mesa's state.
309 static void r300UpdateCulling(GLcontext
* ctx
)
311 r300ContextPtr r300
= R300_CONTEXT(ctx
);
314 R300_STATECHANGE(r300
, cul
);
315 if (ctx
->Polygon
.CullFlag
) {
316 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
)
317 val
= R300_CULL_FRONT
|R300_CULL_BACK
;
318 else if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
319 val
= R300_CULL_FRONT
;
321 val
= R300_CULL_BACK
;
323 if (ctx
->Polygon
.FrontFace
== GL_CW
)
324 val
|= R300_FRONT_FACE_CW
;
326 val
|= R300_FRONT_FACE_CCW
;
328 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
331 static void update_early_z(GLcontext
*ctx
)
333 /* updates register R300_RB3D_EARLY_Z (0x4F14)
334 if depth test is not enabled it should be R300_EARLY_Z_DISABLE
335 if depth is enabled and alpha not it should be R300_EARLY_Z_ENABLE
336 if depth and alpha is enabled it should be R300_EARLY_Z_DISABLE
338 r300ContextPtr r300
= R300_CONTEXT(ctx
);
340 R300_STATECHANGE(r300
, zstencil_format
);
341 if (ctx
->Color
.AlphaEnabled
&& ctx
->Color
.AlphaFunc
!= GL_ALWAYS
)
342 /* disable early Z */
343 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_DISABLE
;
345 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
)
347 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_ENABLE
;
349 /* disable early Z */
350 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_DISABLE
;
354 static void update_alpha(GLcontext
*ctx
)
356 r300ContextPtr r300
= R300_CONTEXT(ctx
);
358 uint32_t pp_misc
= 0x0;
359 GLboolean really_enabled
= ctx
->Color
.AlphaEnabled
;
361 CLAMPED_FLOAT_TO_UBYTE(refByte
, ctx
->Color
.AlphaRef
);
363 switch (ctx
->Color
.AlphaFunc
) {
365 pp_misc
|= R300_ALPHA_TEST_FAIL
;
368 pp_misc
|= R300_ALPHA_TEST_LESS
;
371 pp_misc
|= R300_ALPHA_TEST_EQUAL
;
374 pp_misc
|= R300_ALPHA_TEST_LEQUAL
;
377 pp_misc
|= R300_ALPHA_TEST_GREATER
;
380 pp_misc
|= R300_ALPHA_TEST_NEQUAL
;
383 pp_misc
|= R300_ALPHA_TEST_GEQUAL
;
386 /*pp_misc |= R300_ALPHA_TEST_PASS;*/
387 really_enabled
= GL_FALSE
;
391 if (really_enabled
) {
392 pp_misc
|= R300_ALPHA_TEST_ENABLE
;
393 pp_misc
|= (refByte
& R300_REF_ALPHA_MASK
);
399 R300_STATECHANGE(r300
, at
);
400 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
404 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
411 static int translate_func(int func
)
415 return R300_ZS_NEVER
;
419 return R300_ZS_EQUAL
;
421 return R300_ZS_LEQUAL
;
423 return R300_ZS_GREATER
;
425 return R300_ZS_NOTEQUAL
;
427 return R300_ZS_GEQUAL
;
429 return R300_ZS_ALWAYS
;
434 static void update_depth(GLcontext
* ctx
)
436 r300ContextPtr r300
= R300_CONTEXT(ctx
);
438 R300_STATECHANGE(r300
, zs
);
439 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_RB3D_STENCIL_ENABLE
;
440 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
442 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
) {
444 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_TEST_AND_WRITE
;
446 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_TEST
;
448 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= translate_func(ctx
->Depth
.Func
) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
450 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_DISABLED_1
;
451 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= translate_func(GL_NEVER
) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
458 * Handle glEnable()/glDisable().
460 * \note Mesa already filters redundant calls to glEnable/glDisable.
462 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
464 r300ContextPtr r300
= R300_CONTEXT(ctx
);
466 if (RADEON_DEBUG
& DEBUG_STATE
)
467 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
468 _mesa_lookup_enum_by_nr(cap
),
469 state
? "GL_TRUE" : "GL_FALSE");
472 /* Fast track this one...
480 R300_STATECHANGE(r300
, fogs
);
482 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] |=
485 ctx
->Driver
.Fogfv( ctx
, GL_FOG_MODE
, NULL
);
486 ctx
->Driver
.Fogfv( ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
487 ctx
->Driver
.Fogfv( ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
488 ctx
->Driver
.Fogfv( ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
489 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
491 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] &=
502 case GL_COLOR_LOGIC_OP
:
503 r300_set_blend_state(ctx
);
510 case GL_STENCIL_TEST
:
511 if (r300
->state
.stencil
.hw_stencil
) {
512 R300_STATECHANGE(r300
, zs
);
514 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
515 R300_RB3D_STENCIL_ENABLE
;
517 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
518 ~R300_RB3D_STENCIL_ENABLE
;
522 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
528 r300UpdateCulling(ctx
);
531 case GL_POLYGON_OFFSET_POINT
:
532 case GL_POLYGON_OFFSET_LINE
:
535 case GL_POLYGON_OFFSET_FILL
:
536 R300_STATECHANGE(r300
, occlusion_cntl
);
538 r300
->hw
.occlusion_cntl
.cmd
[1] |= (3<<0);
540 r300
->hw
.occlusion_cntl
.cmd
[1] &= ~(3<<0);
544 radeonEnable(ctx
, cap
, state
);
550 static void r300UpdatePolygonMode(GLcontext
*ctx
)
552 r300ContextPtr r300
= R300_CONTEXT(ctx
);
555 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
556 ctx
->Polygon
.BackMode
!= GL_FILL
) {
559 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
560 f
= ctx
->Polygon
.FrontMode
;
561 b
= ctx
->Polygon
.BackMode
;
563 f
= ctx
->Polygon
.BackMode
;
564 b
= ctx
->Polygon
.FrontMode
;
567 hw_mode
|= R300_PM_ENABLED
;
571 hw_mode
|= R300_PM_FRONT_LINE
;
573 case GL_POINT
: /* noop */
574 hw_mode
|= R300_PM_FRONT_POINT
;
577 hw_mode
|= R300_PM_FRONT_FILL
;
583 hw_mode
|= R300_PM_BACK_LINE
;
585 case GL_POINT
: /* noop */
586 hw_mode
|= R300_PM_BACK_POINT
;
589 hw_mode
|= R300_PM_BACK_FILL
;
594 if (r300
->hw
.polygon_mode
.cmd
[1] != hw_mode
) {
595 R300_STATECHANGE(r300
, polygon_mode
);
596 r300
->hw
.polygon_mode
.cmd
[1] = hw_mode
;
601 * Change the culling mode.
603 * \note Mesa already filters redundant calls to this function.
605 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
609 r300UpdateCulling(ctx
);
614 * Change the polygon orientation.
616 * \note Mesa already filters redundant calls to this function.
618 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
622 r300UpdateCulling(ctx
);
623 r300UpdatePolygonMode(ctx
);
628 * Change the depth testing function.
630 * \note Mesa already filters redundant calls to this function.
632 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
640 * Enable/Disable depth writing.
642 * \note Mesa already filters redundant calls to this function.
644 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
652 * Handle glColorMask()
654 static void r300ColorMask(GLcontext
* ctx
,
655 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
657 r300ContextPtr r300
= R300_CONTEXT(ctx
);
658 int mask
= (r
? R300_COLORMASK0_R
: 0) |
659 (g
? R300_COLORMASK0_G
: 0) |
660 (b
? R300_COLORMASK0_B
: 0) |
661 (a
? R300_COLORMASK0_A
: 0);
663 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
664 R300_STATECHANGE(r300
, cmk
);
665 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
669 /* =============================================================
672 static void r300Fogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
674 r300ContextPtr r300
= R300_CONTEXT(ctx
);
675 union { int i
; float f
; } fogScale
, fogStart
;
679 fogScale
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
];
680 fogStart
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_START
];
684 if (!ctx
->Fog
.Enabled
)
686 switch (ctx
->Fog
.Mode
) {
688 R300_STATECHANGE(r300
, fogs
);
689 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
690 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_LINEAR
;
692 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
697 fogScale
.f
= 1.0 / (ctx
->Fog
.End
-ctx
->Fog
.Start
);
698 fogStart
.f
= -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-ctx
->Fog
.Start
);
702 R300_STATECHANGE(r300
, fogs
);
703 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
704 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_EXP
;
705 fogScale
.f
= 0.0933*ctx
->Fog
.Density
;
709 R300_STATECHANGE(r300
, fogs
);
710 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
711 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_EXP2
;
712 fogScale
.f
= 0.3*ctx
->Fog
.Density
;
719 switch (ctx
->Fog
.Mode
) {
721 fogScale
.f
= 0.0933*ctx
->Fog
.Density
;
725 fogScale
.f
= 0.3*ctx
->Fog
.Density
;
733 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
734 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
739 fogScale
.f
= 1.0 / (ctx
->Fog
.End
-ctx
->Fog
.Start
);
740 fogStart
.f
= -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-ctx
->Fog
.Start
);
745 R300_STATECHANGE(r300
, fogc
);
746 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] = (GLuint
) (ctx
->Fog
.Color
[0]*1023.0F
) & 0x3FF;
747 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] = (GLuint
) (ctx
->Fog
.Color
[1]*1023.0F
) & 0x3FF;
748 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] = (GLuint
) (ctx
->Fog
.Color
[2]*1023.0F
) & 0x3FF;
750 case GL_FOG_COORD_SRC
:
756 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
757 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
758 R300_STATECHANGE(r300
, fogp
);
759 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
760 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
764 /* =============================================================
767 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
769 r300ContextPtr r300
= R300_CONTEXT(ctx
);
771 size
= ctx
->Point
._Size
;
773 R300_STATECHANGE(r300
, ps
);
774 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
775 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
776 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
779 /* =============================================================
782 static void r300LineWidth(GLcontext
*ctx
, GLfloat widthf
)
784 r300ContextPtr r300
= R300_CONTEXT(ctx
);
786 widthf
= ctx
->Line
._Width
;
788 R300_STATECHANGE(r300
, lcntl
);
789 r300
->hw
.lcntl
.cmd
[1] = (int)(widthf
* 6.0);
790 r300
->hw
.lcntl
.cmd
[1] |= R300_LINE_CNT_VE
;
793 static void r300PolygonMode(GLcontext
*ctx
, GLenum face
, GLenum mode
)
798 r300UpdatePolygonMode(ctx
);
801 /* =============================================================
805 static int translate_stencil_op(int op
)
813 return R300_ZS_REPLACE
;
818 case GL_INCR_WRAP_EXT
:
819 return R300_ZS_INCR_WRAP
;
820 case GL_DECR_WRAP_EXT
:
821 return R300_ZS_DECR_WRAP
;
823 return R300_ZS_INVERT
;
825 WARN_ONCE("Do not know how to translate stencil op");
831 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
833 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
835 R300_STATECHANGE(rmesa
, shade
);
838 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
841 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
848 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
849 GLenum func
, GLint ref
, GLuint mask
)
851 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
852 GLuint refmask
= (((ctx
->Stencil
.Ref
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
853 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
857 R300_STATECHANGE(rmesa
, zs
);
859 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(
860 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
)
861 | (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
863 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &= ~((R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
864 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
866 flag
= translate_func(ctx
->Stencil
.Function
[0]);
867 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= (flag
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
);
869 if (ctx
->Stencil
._TestTwoSide
)
870 flag
= translate_func(ctx
->Stencil
.Function
[1]);
872 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= (flag
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
873 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
876 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
878 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
880 R300_STATECHANGE(rmesa
, zs
);
881 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &= ~(R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
);
882 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= (ctx
->Stencil
.WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
;
886 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
, GLenum fail
,
887 GLenum zfail
, GLenum zpass
)
889 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
891 R300_STATECHANGE(rmesa
, zs
);
892 /* It is easier to mask what's left.. */
893 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
894 (R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
) |
895 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
896 (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
898 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
899 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
)
900 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
)
901 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
);
903 if (ctx
->Stencil
._TestTwoSide
) {
904 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
905 (translate_stencil_op(ctx
->Stencil
.FailFunc
[1]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
906 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[1]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
907 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[1]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
909 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
910 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
911 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
912 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
916 static void r300ClearStencil(GLcontext
* ctx
, GLint s
)
918 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
920 rmesa
->state
.stencil
.clear
=
921 ((GLuint
) (ctx
->Stencil
.Clear
& 0xff) |
922 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
) |
923 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
));
926 /* =============================================================
927 * Window position and viewport transformation
931 * To correctly position primitives:
933 #define SUBPIXEL_X 0.125
934 #define SUBPIXEL_Y 0.125
936 void r300UpdateWindow(GLcontext
* ctx
)
938 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
939 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
940 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
941 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
942 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
944 GLfloat sx
= v
[MAT_SX
];
945 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
946 GLfloat sy
= -v
[MAT_SY
];
947 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
948 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
949 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
951 R300_FIREVERTICES(rmesa
);
952 R300_STATECHANGE(rmesa
, vpt
);
954 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
955 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
956 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
957 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
958 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
959 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
962 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
963 GLsizei width
, GLsizei height
)
965 /* Don't pipeline viewport changes, conflict with window offset
966 * setting below. Could apply deltas to rescue pipelined viewport
967 * values, or keep the originals hanging around.
969 r300UpdateWindow(ctx
);
972 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
974 r300UpdateWindow(ctx
);
977 void r300UpdateViewportOffset( GLcontext
*ctx
)
979 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
980 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
)rmesa
)->dri
.drawable
;
981 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
982 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
983 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
985 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
986 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
988 if ( rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
989 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
))
991 /* Note: this should also modify whatever data the context reset
994 R300_STATECHANGE( rmesa
, vpt
);
995 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
996 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1000 radeonUpdateScissor( ctx
);
1004 * Tell the card where to render (offset, pitch).
1005 * Effected by glDrawBuffer, etc
1008 r300UpdateDrawBuffer(GLcontext
*ctx
)
1010 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1011 r300ContextPtr r300
= rmesa
;
1012 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1013 driRenderbuffer
*drb
;
1015 if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
) {
1017 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
1019 else if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_BACK_LEFT
) {
1021 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1024 /* drawing to multiple buffers, or none */
1029 assert(drb
->flippedPitch
);
1032 R300_STATECHANGE( rmesa
, cb
);
1034 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = drb
->flippedOffset
+ //r300->radeon.state.color.drawOffset +
1035 r300
->radeon
.radeonScreen
->fbLocation
;
1036 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = drb
->flippedPitch
;//r300->radeon.state.color.drawPitch;
1038 if (r300
->radeon
.radeonScreen
->cpp
== 4)
1039 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
1041 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
1043 if (r300
->radeon
.sarea
->tiling_enabled
)
1044 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
1046 R200_STATECHANGE( rmesa
, ctx
);
1048 /* Note: we used the (possibly) page-flipped values */
1049 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
1050 = ((drb
->flippedOffset
+ rmesa
->r200Screen
->fbLocation
)
1051 & R200_COLOROFFSET_MASK
);
1052 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
1054 if (rmesa
->sarea
->tiling_enabled
) {
1055 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |= R200_COLOR_TILE_ENABLE
;
1061 r300FetchStateParameter(GLcontext
*ctx
,
1062 const gl_state_index state
[STATE_LENGTH
],
1065 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1068 case STATE_INTERNAL
:
1070 case STATE_R300_WINDOW_DIMENSION
:
1071 value
[0] = r300
->radeon
.dri
.drawable
->w
*0.5f
;/* width*0.5 */
1072 value
[1] = r300
->radeon
.dri
.drawable
->h
*0.5f
;/* height*0.5 */
1073 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1074 value
[3] = 1.0F
; /* not used */
1077 case STATE_R300_TEXRECT_FACTOR
: {
1078 struct gl_texture_object
* t
= ctx
->Texture
.Unit
[state
[2]].CurrentRect
;
1080 if (t
&& t
->Image
[0][t
->BaseLevel
]) {
1081 struct gl_texture_image
* image
= t
->Image
[0][t
->BaseLevel
];
1082 value
[0] = 1.0 / image
->Width2
;
1083 value
[1] = 1.0 / image
->Height2
;
1103 * Update R300's own internal state parameters.
1104 * For now just STATE_R300_WINDOW_DIMENSION
1106 void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1108 struct r300_fragment_program
*fp
;
1109 struct gl_program_parameter_list
*paramList
;
1112 if(!(new_state
& (_NEW_BUFFERS
|_NEW_PROGRAM
)))
1115 fp
= (struct r300_fragment_program
*)ctx
->FragmentProgram
._Current
;
1119 paramList
= fp
->mesa_program
.Base
.Parameters
;
1124 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1125 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
){
1126 r300FetchStateParameter(ctx
,
1127 paramList
->Parameters
[i
].StateIndexes
,
1128 paramList
->ParameterValues
[i
]);
1133 /* =============================================================
1136 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1138 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1139 GLfloat constant
= units
;
1141 switch (ctx
->Visual
.depthBits
) {
1152 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1154 R300_STATECHANGE(rmesa
, zbs
);
1155 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1156 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1157 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1158 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1161 /* Routing and texture-related */
1164 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1165 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1166 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1167 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1168 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1169 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1170 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1171 * combinations where only one of them is nearest.
1173 static unsigned long gen_fixed_filter(unsigned long f
)
1175 unsigned long mag
, min
, needs_fixing
=0;
1178 /* We ignore MIRROR bit so we dont have to do everything twice */
1179 if((f
& ((7-1) << R300_TX_WRAP_S_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)){
1182 if((f
& ((7-1) << R300_TX_WRAP_T_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)){
1185 if((f
& ((7-1) << R300_TX_WRAP_Q_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_Q_SHIFT
)){
1192 mag
=f
& R300_TX_MAG_FILTER_MASK
;
1193 min
=f
& R300_TX_MIN_FILTER_MASK
;
1195 /* TODO: Check for anisto filters too */
1196 if((mag
!= R300_TX_MAG_FILTER_NEAREST
) && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1199 /* r300 cant handle these modes hence we force nearest to linear */
1200 if((mag
== R300_TX_MAG_FILTER_NEAREST
) && (min
!= R300_TX_MIN_FILTER_NEAREST
)){
1201 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1202 f
|= R300_TX_MAG_FILTER_LINEAR
;
1206 if((min
== R300_TX_MIN_FILTER_NEAREST
) && (mag
!= R300_TX_MAG_FILTER_NEAREST
)){
1207 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1208 f
|= R300_TX_MIN_FILTER_LINEAR
;
1212 /* Both are nearest */
1213 if(needs_fixing
& 1){
1214 f
&= ~((7-1) << R300_TX_WRAP_S_SHIFT
);
1215 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1217 if(needs_fixing
& 2){
1218 f
&= ~((7-1) << R300_TX_WRAP_T_SHIFT
);
1219 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1221 if(needs_fixing
& 4){
1222 f
&= ~((7-1) << R300_TX_WRAP_Q_SHIFT
);
1223 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_Q_SHIFT
;
1228 void r300_setup_textures(GLcontext
*ctx
)
1231 struct r300_tex_obj
*t
;
1232 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1234 int last_hw_tmu
=-1; /* -1 translates into no setup costs for fields */
1235 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1, };
1236 struct r300_fragment_program
*rp
=
1237 (struct r300_fragment_program
*)
1238 (char *)ctx
->FragmentProgram
._Current
;
1240 R300_STATECHANGE(r300
, txe
);
1241 R300_STATECHANGE(r300
, tex
.filter
);
1242 R300_STATECHANGE(r300
, tex
.filter_1
);
1243 R300_STATECHANGE(r300
, tex
.size
);
1244 R300_STATECHANGE(r300
, tex
.format
);
1245 R300_STATECHANGE(r300
, tex
.pitch
);
1246 R300_STATECHANGE(r300
, tex
.offset
);
1247 R300_STATECHANGE(r300
, tex
.chroma_key
);
1248 R300_STATECHANGE(r300
, tex
.border_color
);
1250 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
]=0x0;
1252 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1253 if (RADEON_DEBUG
& DEBUG_STATE
)
1254 fprintf(stderr
, "mtu=%d\n", mtu
);
1256 if(mtu
> R300_MAX_TEXTURE_UNITS
) {
1257 fprintf(stderr
, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1258 mtu
, R300_MAX_TEXTURE_UNITS
);
1262 /* We cannot let disabled tmu offsets pass DRM */
1263 for(i
=0; i
< mtu
; i
++) {
1264 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
1266 #if 0 /* Enables old behaviour */
1269 tmu_mappings
[i
] = hw_tmu
;
1271 t
=r300
->state
.texture
.unit
[i
].texobj
;
1273 if((t
->format
& 0xffffff00)==0xffffff00) {
1274 WARN_ONCE("unknown texture format (entry %x) encountered. Help me !\n", t
->format
& 0xff);
1277 if (RADEON_DEBUG
& DEBUG_STATE
)
1278 fprintf(stderr
, "Activating texture unit %d\n", i
);
1280 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1282 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = gen_fixed_filter(t
->filter
) | (hw_tmu
<< 28);
1283 /* Currently disabled! */
1284 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0; //0x20501f80;
1285 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->size
;
1286 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->format
;
1287 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->pitch_reg
;
1288 r300
->hw
.tex
.offset
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->offset
;
1290 if(t
->offset
& R300_TXO_MACRO_TILE
) {
1291 WARN_ONCE("macro tiling enabled!\n");
1294 if(t
->offset
& R300_TXO_MICRO_TILE
) {
1295 WARN_ONCE("micro tiling enabled!\n");
1298 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0;
1299 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->pp_border_color
;
1301 last_hw_tmu
= hw_tmu
;
1307 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FILTER_0
, last_hw_tmu
+ 1);
1308 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1309 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1310 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1311 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_PITCH_0
, last_hw_tmu
+ 1);
1312 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1313 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1314 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1317 if (!rp
) /* should only happenen once, just after context is created */
1320 R300_STATECHANGE(r300
, fpt
);
1322 for(i
= 0; i
< rp
->tex
.length
; i
++){
1327 unit
= rp
->tex
.inst
[i
] >> R300_FPITX_IMAGE_SHIFT
;
1330 val
= rp
->tex
.inst
[i
];
1331 val
&= ~R300_FPITX_IMAGE_MASK
;
1333 opcode
= (val
& R300_FPITX_OPCODE_MASK
) >> R300_FPITX_OPCODE_SHIFT
;
1334 if (opcode
== R300_FPITX_OP_KIL
) {
1335 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+i
] = val
;
1337 if (tmu_mappings
[unit
] >= 0) {
1338 val
|= tmu_mappings
[unit
] << R300_FPITX_IMAGE_SHIFT
;
1339 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+i
] = val
;
1341 // We get here when the corresponding texture image is incomplete
1342 // (e.g. incomplete mipmaps etc.)
1343 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+i
] = val
;
1348 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] = cmdpacket0(R300_PFS_TEXI_0
, rp
->tex
.length
);
1350 if (RADEON_DEBUG
& DEBUG_STATE
)
1351 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n", r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1354 union r300_outputs_written
{
1355 GLuint vp_outputs
; /* hw_tcl_on */
1356 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1359 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1360 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1361 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1363 void r300_setup_rs_unit(GLcontext
*ctx
)
1365 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1366 /* I'm still unsure if these are needed */
1367 GLuint interp_magic
[8] = {
1377 union r300_outputs_written OutputsWritten
;
1379 int fp_reg
, high_rr
;
1380 int in_texcoords
, col_interp_nr
;
1384 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1386 RENDERINPUTS_COPY( OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1388 if (ctx
->FragmentProgram
._Current
)
1389 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1391 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1392 return; /* This should only ever happen once.. */
1395 R300_STATECHANGE(r300
, ri
);
1396 R300_STATECHANGE(r300
, rc
);
1397 R300_STATECHANGE(r300
, rr
);
1399 fp_reg
= in_texcoords
= col_interp_nr
= high_rr
= 0;
1401 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] = 0;
1403 if (InputsRead
& FRAG_BIT_WPOS
){
1404 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1405 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1408 if(i
== ctx
->Const
.MaxTextureUnits
){
1409 fprintf(stderr
, "\tno free texcoord found...\n");
1413 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1414 InputsRead
&= ~FRAG_BIT_WPOS
;
1417 for (i
=0;i
<ctx
->Const
.MaxTextureUnits
;i
++) {
1418 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+i
] = 0
1419 | R300_RS_INTERP_USED
1420 | (in_texcoords
<< R300_RS_INTERP_SRC_SHIFT
)
1423 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] = 0;
1424 if (InputsRead
& (FRAG_BIT_TEX0
<<i
)) {
1425 //assert(r300->state.texture.tc_count != 0);
1426 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] |=
1427 R300_RS_ROUTE_ENABLE
1428 | i
/* source INTERP */
1429 | (fp_reg
<< R300_RS_ROUTE_DEST_SHIFT
);
1432 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_TEX0
+i
, _TNL_ATTRIB_TEX(i
) )) {
1433 /* Passing invalid data here can lock the GPU. */
1434 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1435 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1438 InputsRead
&= ~(FRAG_BIT_TEX0
<<i
);
1441 /* Need to count all coords enabled at vof */
1442 if (R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_TEX0
+i
, _TNL_ATTRIB_TEX(i
) ))
1446 if (InputsRead
& FRAG_BIT_COL0
) {
1447 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1448 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1449 goto out
; /* FIXME */
1450 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1454 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1455 | R300_RS_ROUTE_0_COLOR
1456 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1457 InputsRead
&= ~FRAG_BIT_COL0
;
1462 if (InputsRead
& FRAG_BIT_COL1
) {
1463 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1464 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1468 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] |= R300_RS_ROUTE_1_UNKNOWN11
1469 | R300_RS_ROUTE_1_COLOR1
1470 | (fp_reg
++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT
);
1471 InputsRead
&= ~FRAG_BIT_COL1
;
1472 if (high_rr
< 1) high_rr
= 1;
1476 /* Need at least one. This might still lock as the values are undefined... */
1477 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1478 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1479 | R300_RS_ROUTE_0_COLOR
1480 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1484 r300
->hw
.rc
.cmd
[1] = 0
1485 | (in_texcoords
<< R300_RS_CNTL_TC_CNT_SHIFT
)
1486 | (col_interp_nr
<< R300_RS_CNTL_CI_CNT_SHIFT
)
1487 | R300_RS_CNTL_0_UNKNOWN_18
;
1489 assert(high_rr
>= 0);
1490 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R300_RS_ROUTE_0
, high_rr
+1);
1491 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1494 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1497 #define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
1499 #define bump_vpu_count(ptr, new_count) do{\
1500 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1501 int _nc=(new_count)/4; \
1502 assert(_nc < 256); \
1503 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1506 void static inline setup_vertex_shader_fragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1510 if(vsf
->length
==0)return;
1512 if(vsf
->length
& 0x3){
1513 fprintf(stderr
,"VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1517 switch((dest
>>8) & 0xf){
1519 R300_STATECHANGE(r300
, vpi
);
1520 for(i
=0;i
<vsf
->length
;i
++)
1521 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1522 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+4*(dest
& 0xff));
1526 R300_STATECHANGE(r300
, vpp
);
1527 for(i
=0;i
<vsf
->length
;i
++)
1528 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1529 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+4*(dest
& 0xff));
1532 R300_STATECHANGE(r300
, vps
);
1533 for(i
=0;i
<vsf
->length
;i
++)
1534 r300
->hw
.vps
.cmd
[1+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1535 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+4*(dest
& 0xff));
1538 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1543 void r300SetupVertexProgram(r300ContextPtr rmesa
);
1545 /* just a skeleton for now.. */
1547 /* Generate a vertex shader that simply transforms vertex and texture coordinates,
1548 while leaving colors intact. Nothing fancy (like lights)
1550 If implementing lights make a copy first, so it is easy to switch between the two versions */
1551 static void r300GenerateSimpleVertexShader(r300ContextPtr r300
)
1556 /* Allocate parameters */
1557 r300
->state
.vap_param
.transform_offset
=0x0; /* transform matrix */
1558 r300
->state
.vertex_shader
.param_offset
=0x0;
1559 r300
->state
.vertex_shader
.param_count
=0x4; /* 4 vector values - 4x4 matrix */
1561 r300
->state
.vertex_shader
.program_start
=0x0;
1562 r300
->state
.vertex_shader
.unknown_ptr1
=0x4; /* magic value ? */
1563 r300
->state
.vertex_shader
.program_end
=0x0;
1565 r300
->state
.vertex_shader
.unknown_ptr2
=0x0; /* magic value */
1566 r300
->state
.vertex_shader
.unknown_ptr3
=0x4; /* magic value */
1568 /* Initialize matrix and vector parameters.. these should really be restructured */
1569 /* TODO: fix vertex_shader structure */
1570 r300
->state
.vertex_shader
.matrix
[0].length
=16;
1571 r300
->state
.vertex_shader
.matrix
[1].length
=0;
1572 r300
->state
.vertex_shader
.matrix
[2].length
=0;
1573 r300
->state
.vertex_shader
.vector
[0].length
=0;
1574 r300
->state
.vertex_shader
.vector
[1].length
=0;
1575 r300
->state
.vertex_shader
.unknown1
.length
=0;
1576 r300
->state
.vertex_shader
.unknown2
.length
=0;
1578 #define WRITE_OP(oper,source1,source2,source3) {\
1579 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].op=(oper); \
1580 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src1=(source1); \
1581 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src2=(source2); \
1582 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src3=(source3); \
1583 r300->state.vertex_shader.program_end++; \
1586 /* Multiply vertex coordinates with transform matrix */
1589 EASY_VSF_OP(MUL
, 0, ALL
, TMP
),
1592 EASY_VSF_SOURCE(0, W
, W
, W
, W
, NONE
, NONE
)
1596 EASY_VSF_OP(MUL
, 1, ALL
, RESULT
),
1603 EASY_VSF_OP(MAD
, 0, ALL
, TMP
),
1610 EASY_VSF_OP(MAD
, 0, ALL
, TMP
),
1617 EASY_VSF_OP(MAD
, 0, ALL
, RESULT
),
1624 for (i
= VERT_ATTRIB_COLOR1
; i
< VERT_ATTRIB_MAX
; i
++)
1625 if (r300
->state
.sw_tcl_inputs
[i
] != -1) {
1627 EASY_VSF_OP(MUL
, o_reg
++ /* 2+i */, ALL
, RESULT
),
1628 VSF_REG(r300
->state
.sw_tcl_inputs
[i
]),
1629 VSF_ATTR_UNITY(r300
->state
.sw_tcl_inputs
[i
]),
1630 VSF_UNITY(r300
->state
.sw_tcl_inputs
[i
])
1635 r300
->state
.vertex_shader
.program_end
--; /* r300 wants program length to be one more - no idea why */
1636 r300
->state
.vertex_shader
.program
.length
=(r300
->state
.vertex_shader
.program_end
+1)*4;
1638 r300
->state
.vertex_shader
.unknown_ptr1
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1639 r300
->state
.vertex_shader
.unknown_ptr2
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1640 r300
->state
.vertex_shader
.unknown_ptr3
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1645 void r300SetupVertexShader(r300ContextPtr rmesa
)
1647 GLcontext
* ctx
= rmesa
->radeon
.glCtx
;
1649 /* Reset state, in case we don't use something */
1650 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1651 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1652 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1654 /* Not sure why this doesnt work...
1655 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
1656 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. */
1657 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
1658 if(hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
){
1659 r300SetupVertexProgram(rmesa
);
1663 /* This needs to be replaced by vertex shader generation code */
1667 /* textures enabled ? */
1668 if(rmesa
->state
.texture
.tc_count
>0){
1669 rmesa
->state
.vertex_shader
=SINGLE_TEXTURE_VERTEX_SHADER
;
1671 rmesa
->state
.vertex_shader
=FLAT_COLOR_VERTEX_SHADER
;
1675 r300GenerateSimpleVertexShader(rmesa
);
1677 rmesa
->state
.vertex_shader
.matrix
[0].length
=16;
1678 memcpy(rmesa
->state
.vertex_shader
.matrix
[0].body
.f
, ctx
->_ModelProjectMatrix
.m
, 16*4);
1680 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(rmesa
->state
.vertex_shader
.program
));
1682 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX0
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1684 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX1
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1685 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX2
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1687 setup_vertex_shader_fragment(rmesa
, VSF_DEST_VECTOR0
, &(rmesa
->state
.vertex_shader
.vector
[0]));
1688 setup_vertex_shader_fragment(rmesa
, VSF_DEST_VECTOR1
, &(rmesa
->state
.vertex_shader
.vector
[1]));
1692 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
, &(rmesa
->state
.vertex_shader
.unknown1
));
1693 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
, &(rmesa
->state
.vertex_shader
.unknown2
));
1696 R300_STATECHANGE(rmesa
, pvs
);
1697 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
]=(rmesa
->state
.vertex_shader
.program_start
<< R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1698 | (rmesa
->state
.vertex_shader
.unknown_ptr1
<< R300_PVS_CNTL_1_POS_END_SHIFT
)
1699 | (rmesa
->state
.vertex_shader
.program_end
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1700 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
]=(rmesa
->state
.vertex_shader
.param_offset
<< R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1701 | (rmesa
->state
.vertex_shader
.param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1702 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
]=(rmesa
->state
.vertex_shader
.unknown_ptr2
<< R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1703 | (rmesa
->state
.vertex_shader
.unknown_ptr3
<< 0);
1705 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1706 so I leave it as a reminder */
1708 reg_start(R300_VAP_PVS_WAITIDLE
,0);
1713 void r300SetupVertexProgram(r300ContextPtr rmesa
)
1715 GLcontext
* ctx
= rmesa
->radeon
.glCtx
;
1718 struct r300_vertex_program
*prog
=(struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1721 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1722 R300_STATECHANGE(rmesa
, vpp
);
1723 param_count
= r300VertexProgUpdateParams(ctx
, (struct r300_vertex_program_cont
*)ctx
->VertexProgram
._Current
/*prog*/, (float *)&rmesa
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
]);
1724 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
1727 /* Reset state, in case we don't use something */
1728 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1729 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1731 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(prog
->program
));
1734 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
, &(rmesa
->state
.vertex_shader
.unknown1
));
1735 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
, &(rmesa
->state
.vertex_shader
.unknown2
));
1738 inst_count
=prog
->program
.length
/4 - 1;
1740 R300_STATECHANGE(rmesa
, pvs
);
1741 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
]=(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1742 | (inst_count
/*pos_end*/ << R300_PVS_CNTL_1_POS_END_SHIFT
)
1743 | (inst_count
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1744 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
]=(0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1745 | (param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1746 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
]=(0/*rmesa->state.vertex_shader.unknown_ptr2*/ << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1747 | (inst_count
/*rmesa->state.vertex_shader.unknown_ptr3*/ << 0);
1749 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1750 so I leave it as a reminder */
1752 reg_start(R300_VAP_PVS_WAITIDLE
,0);
1757 extern void _tnl_UpdateFixedFunctionProgram( GLcontext
*ctx
);
1759 extern int future_hw_tcl_on
;
1760 void r300UpdateShaders(r300ContextPtr rmesa
)
1763 struct r300_vertex_program
*vp
;
1766 ctx
= rmesa
->radeon
.glCtx
;
1768 if (rmesa
->NewGLState
&& hw_tcl_on
) {
1769 rmesa
->NewGLState
= 0;
1771 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1772 rmesa
->temp_attrib
[i
] = TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
1773 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] = &rmesa
->dummy_attrib
[i
];
1776 _tnl_UpdateFixedFunctionProgram(ctx
);
1778 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1779 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] = rmesa
->temp_attrib
[i
];
1782 r300_select_vertex_shader(rmesa
);
1783 vp
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1784 /*if (vp->translated == GL_FALSE)
1785 r300_translate_vertex_shader(vp);*/
1786 if (vp
->translated
== GL_FALSE
) {
1787 fprintf(stderr
, "Failing back to sw-tcl\n");
1788 hw_tcl_on
= future_hw_tcl_on
= 0;
1789 r300ResetHwState(rmesa
);
1793 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
1798 void r300UpdateShaderStates(r300ContextPtr rmesa
)
1801 ctx
= rmesa
->radeon
.glCtx
;
1803 r300UpdateTextureState(ctx
);
1805 r300SetupPixelShader(rmesa
);
1806 r300_setup_textures(ctx
);
1808 r300SetupVertexShader(rmesa
);
1809 r300_setup_rs_unit(ctx
);
1812 /* This is probably wrong for some values, I need to test this
1813 * some more. Range checking would be a good idea also..
1815 * But it works for most things. I'll fix it later if someone
1816 * else with a better clue doesn't
1818 static unsigned int r300PackFloat24(float f
)
1822 unsigned int float24
= 0;
1824 if (f
== 0.0) return 0;
1826 mantissa
= frexpf(f
, &exponent
);
1831 mantissa
= mantissa
* -1.0;
1833 /* Handle exponent, bias of 63 */
1835 float24
|= (exponent
<< 16);
1836 /* Kill 7 LSB of mantissa */
1837 float24
|= (r300PackFloat32(mantissa
) & 0x7FFFFF) >> 7;
1842 void r300SetupPixelShader(r300ContextPtr rmesa
)
1844 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1845 struct r300_fragment_program
*rp
=
1846 (struct r300_fragment_program
*)
1847 (char *)ctx
->FragmentProgram
._Current
;
1850 if (!rp
) /* should only happenen once, just after context is created */
1853 r300_translate_fragment_shader(rmesa
, rp
);
1854 if (!rp
->translated
) {
1855 fprintf(stderr
, "%s: No valid fragment shader, exiting\n", __func__
);
1859 #define OUTPUT_FIELD(st, reg, field) \
1860 R300_STATECHANGE(rmesa, st); \
1861 for(i=0;i<=rp->alu_end;i++) \
1862 rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=rp->alu.inst[i].field;\
1863 rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmdpacket0(reg, rp->alu_end+1);
1865 OUTPUT_FIELD(fpi
[0], R300_PFS_INSTR0_0
, inst0
);
1866 OUTPUT_FIELD(fpi
[1], R300_PFS_INSTR1_0
, inst1
);
1867 OUTPUT_FIELD(fpi
[2], R300_PFS_INSTR2_0
, inst2
);
1868 OUTPUT_FIELD(fpi
[3], R300_PFS_INSTR3_0
, inst3
);
1871 R300_STATECHANGE(rmesa
, fp
);
1872 /* I just want to say, the way these nodes are stored.. weird.. */
1873 for (i
=0,k
=(4-(rp
->cur_node
+1));i
<4;i
++,k
++) {
1874 if (i
<(rp
->cur_node
+1)) {
1875 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+k
]=
1876 (rp
->node
[i
].alu_offset
<< R300_PFS_NODE_ALU_OFFSET_SHIFT
)
1877 | (rp
->node
[i
].alu_end
<< R300_PFS_NODE_ALU_END_SHIFT
)
1878 | (rp
->node
[i
].tex_offset
<< R300_PFS_NODE_TEX_OFFSET_SHIFT
)
1879 | (rp
->node
[i
].tex_end
<< R300_PFS_NODE_TEX_END_SHIFT
)
1880 | rp
->node
[i
].flags
; /* ( (k==3) ? R300_PFS_NODE_LAST_NODE : 0); */
1882 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+(3-i
)] = 0;
1887 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
]=
1889 | (rp
->first_node_has_tex
<<3);
1891 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
]=rp
->max_temp_idx
;
1893 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
]=
1894 (rp
->alu_offset
<< R300_PFS_CNTL_ALU_OFFSET_SHIFT
)
1895 | (rp
->alu_end
<< R300_PFS_CNTL_ALU_END_SHIFT
)
1896 | (rp
->tex_offset
<< R300_PFS_CNTL_TEX_OFFSET_SHIFT
)
1897 | (rp
->tex_end
<< R300_PFS_CNTL_TEX_END_SHIFT
);
1899 R300_STATECHANGE(rmesa
, fpp
);
1900 for(i
=0;i
<rp
->const_nr
;i
++){
1901 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+0]=r300PackFloat24(rp
->constant
[i
][0]);
1902 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+1]=r300PackFloat24(rp
->constant
[i
][1]);
1903 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+2]=r300PackFloat24(rp
->constant
[i
][2]);
1904 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+3]=r300PackFloat24(rp
->constant
[i
][3]);
1906 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
]=cmdpacket0(R300_PFS_PARAM_0_X
, rp
->const_nr
*4);
1910 * Called by Mesa after an internal state update.
1912 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
1914 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1916 _swrast_InvalidateState(ctx
, new_state
);
1917 _swsetup_InvalidateState(ctx
, new_state
);
1918 _vbo_InvalidateState(ctx
, new_state
);
1919 _tnl_InvalidateState(ctx
, new_state
);
1920 _ae_invalidate_state(ctx
, new_state
);
1922 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
1923 r300UpdateDrawBuffer(ctx
);
1926 r300UpdateStateParameters(ctx
, new_state
);
1929 if(new_state
& _NEW_ARRAY
)
1930 r300
->state
.VB
.lock_uptodate
= GL_FALSE
;
1932 r300
->NewGLState
|= new_state
;
1936 * Completely recalculates hardware state based on the Mesa state.
1938 void r300ResetHwState(r300ContextPtr r300
)
1940 GLcontext
* ctx
= r300
->radeon
.glCtx
;
1942 if (RADEON_DEBUG
& DEBUG_STATE
)
1943 fprintf(stderr
, "%s\n", __FUNCTION__
);
1945 /* This is a place to initialize registers which
1946 have bitfields accessed by different functions
1947 and not all bits are used */
1949 /* initialize similiar to r200 */
1950 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] = 0;
1951 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] =
1952 (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
1953 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
) |
1954 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
) |
1955 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
) |
1956 (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
) |
1957 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
) |
1958 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
) |
1959 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
);
1960 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] = 0x00ffff00;
1963 /* go and compute register values from GL state */
1965 r300UpdateWindow(ctx
);
1968 ctx
->Color
.ColorMask
[RCOMP
],
1969 ctx
->Color
.ColorMask
[GCOMP
],
1970 ctx
->Color
.ColorMask
[BCOMP
],
1971 ctx
->Color
.ColorMask
[ACOMP
]);
1973 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
1974 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
1975 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
1978 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
1979 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
1980 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0], ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
1981 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0], ctx
->Stencil
.ZFailFunc
[0], ctx
->Stencil
.ZPassFunc
[0]);
1983 r300UpdateCulling(ctx
);
1985 r300UpdateTextureState(ctx
);
1987 // r300_setup_routing(ctx, GL_TRUE);
1989 #if 0 /* Done in prior to rendering */
1990 if(hw_tcl_on
== GL_FALSE
){
1991 r300EmitArrays(ctx
, GL_TRUE
); /* Just do the routing */
1992 r300_setup_textures(ctx
);
1993 r300_setup_rs_unit(ctx
);
1995 r300SetupVertexShader(r300
);
1996 r300SetupPixelShader(r300
);
2000 r300_set_blend_state(ctx
);
2002 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
2003 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
2005 /* Initialize magic registers
2006 TODO : learn what they really do, or get rid of
2007 those we don't have to touch */
2008 r300
->hw
.vap_cntl
.cmd
[1] = 0x0030045A; //0x0030065a /* Dangerous */
2010 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
2011 | R300_VPORT_X_OFFSET_ENA
2012 | R300_VPORT_Y_SCALE_ENA
2013 | R300_VPORT_Y_OFFSET_ENA
2014 | R300_VPORT_Z_SCALE_ENA
2015 | R300_VPORT_Z_OFFSET_ENA
2017 r300
->hw
.vte
.cmd
[2] = 0x00000008;
2019 r300
->hw
.unk2134
.cmd
[1] = 0x00FFFFFF;
2020 r300
->hw
.unk2134
.cmd
[2] = 0x00000000;
2021 if (_mesa_little_endian())
2022 r300
->hw
.vap_cntl_status
.cmd
[1] = 0x00000000;
2024 r300
->hw
.vap_cntl_status
.cmd
[1] = 0x00000002;
2026 #if 0 /* Done in setup routing */
2027 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[0].cmd
)->packet0
.count
= 1;
2028 r300
->hw
.vir
[0].cmd
[1] = 0x21030003;
2030 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[1].cmd
)->packet0
.count
= 1;
2031 r300
->hw
.vir
[1].cmd
[1] = 0xF688F688;
2033 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_0
] = 0x00000001;
2034 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_1
] = 0x00000405;
2037 r300
->hw
.unk21DC
.cmd
[1] = 0xAAAAAAAA;
2039 r300
->hw
.unk221C
.cmd
[1] = R300_221C_NORMAL
;
2041 r300
->hw
.unk2220
.cmd
[1] = r300PackFloat32(1.0);
2042 r300
->hw
.unk2220
.cmd
[2] = r300PackFloat32(1.0);
2043 r300
->hw
.unk2220
.cmd
[3] = r300PackFloat32(1.0);
2044 r300
->hw
.unk2220
.cmd
[4] = r300PackFloat32(1.0);
2046 /* what about other chips than r300 or rv350??? */
2047 if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
)
2048 r300
->hw
.unk2288
.cmd
[1] = R300_2288_R300
;
2050 r300
->hw
.unk2288
.cmd
[1] = R300_2288_RV350
;
2053 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_0
] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
2054 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
;
2055 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_1
] = 0; /* no textures */
2058 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] = 0;
2059 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] = 0;
2060 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] = 0;
2063 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2064 | R300_GB_LINE_STUFF_ENABLE
2065 | R300_GB_TRIANGLE_STUFF_ENABLE
/*| R300_GB_UNK31*/;
2067 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2068 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2069 if ((r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
) ||
2070 (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R350
))
2071 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2072 | R300_GB_TILE_PIPE_COUNT_R300
2073 | R300_GB_TILE_SIZE_16
;
2074 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
)
2075 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2076 | R300_GB_TILE_PIPE_COUNT_RV410
2077 | R300_GB_TILE_SIZE_16
;
2078 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
)
2079 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2080 | R300_GB_TILE_PIPE_COUNT_R420
2081 | R300_GB_TILE_SIZE_16
;
2083 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
2084 | R300_GB_TILE_PIPE_COUNT_RV300
2085 | R300_GB_TILE_SIZE_16
;
2086 /* set to 0 when fog is disabled? */
2087 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2088 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = 0x00000000; /* No antialiasing */
2090 //r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
2092 r300
->hw
.unk4200
.cmd
[1] = r300PackFloat32(0.0);
2093 r300
->hw
.unk4200
.cmd
[2] = r300PackFloat32(0.0);
2094 r300
->hw
.unk4200
.cmd
[3] = r300PackFloat32(1.0);
2095 r300
->hw
.unk4200
.cmd
[4] = r300PackFloat32(1.0);
2097 r300
->hw
.unk4214
.cmd
[1] = 0x00050005;
2099 r300PointSize(ctx
, 0.0);
2101 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] = (6 << R300_POINTSIZE_X_SHIFT
) |
2102 (6 << R300_POINTSIZE_Y_SHIFT
);
2105 r300
->hw
.unk4230
.cmd
[1] = 0x18000006;
2106 r300
->hw
.unk4230
.cmd
[2] = 0x00020006;
2107 r300
->hw
.unk4230
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2109 r300LineWidth(ctx
, 0.0);
2111 r300
->hw
.unk4260
.cmd
[1] = 0;
2112 r300
->hw
.unk4260
.cmd
[2] = r300PackFloat32(0.0);
2113 r300
->hw
.unk4260
.cmd
[3] = r300PackFloat32(1.0);
2115 r300
->hw
.shade
.cmd
[1] = 0x00000002;
2116 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2117 r300
->hw
.shade
.cmd
[3] = 0x00000000;
2118 r300
->hw
.shade
.cmd
[4] = 0x00000000;
2120 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2121 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2122 r300
->hw
.polygon_mode
.cmd
[2] = 0x00000001;
2123 r300
->hw
.polygon_mode
.cmd
[3] = 0x00000000;
2124 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
2126 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
, ctx
->Polygon
.OffsetUnits
);
2127 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2129 r300
->hw
.unk42C0
.cmd
[1] = 0x4B7FFFFF;
2130 r300
->hw
.unk42C0
.cmd
[2] = 0x00000000;
2133 r300
->hw
.unk43A4
.cmd
[1] = 0x0000001C;
2134 r300
->hw
.unk43A4
.cmd
[2] = 0x2DA49525;
2136 r300
->hw
.unk43E8
.cmd
[1] = 0x00FFFFFF;
2139 r300
->hw
.fp
.cmd
[R300_FP_CNTL0
] = 0;
2140 r300
->hw
.fp
.cmd
[R300_FP_CNTL1
] = 0;
2141 r300
->hw
.fp
.cmd
[R300_FP_CNTL2
] = 0;
2142 r300
->hw
.fp
.cmd
[R300_FP_NODE0
] = 0;
2143 r300
->hw
.fp
.cmd
[R300_FP_NODE1
] = 0;
2144 r300
->hw
.fp
.cmd
[R300_FP_NODE2
] = 0;
2145 r300
->hw
.fp
.cmd
[R300_FP_NODE3
] = 0;
2148 r300
->hw
.unk46A4
.cmd
[1] = 0x00001B01;
2149 r300
->hw
.unk46A4
.cmd
[2] = 0x00001B0F;
2150 r300
->hw
.unk46A4
.cmd
[3] = 0x00001B0F;
2151 r300
->hw
.unk46A4
.cmd
[4] = 0x00001B0F;
2152 r300
->hw
.unk46A4
.cmd
[5] = 0x00000001;
2155 for(i
= 1; i
<= 64; ++i
) {
2156 /* create NOP instructions */
2157 r300
->hw
.fpi
[0].cmd
[i
] = FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
));
2158 r300
->hw
.fpi
[1].cmd
[i
] = FP_SELC(0,XYZ
,NO
,FP_TMP(0),0,0);
2159 r300
->hw
.fpi
[2].cmd
[i
] = FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
));
2160 r300
->hw
.fpi
[3].cmd
[i
] = FP_SELA(0,W
,NO
,FP_TMP(0),0,0);
2163 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2164 ctx
->Driver
.Fogfv( ctx
, GL_FOG_MODE
, NULL
);
2165 ctx
->Driver
.Fogfv( ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2166 ctx
->Driver
.Fogfv( ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2167 ctx
->Driver
.Fogfv( ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2168 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2169 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2171 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
2172 r300
->hw
.unk4BD8
.cmd
[1] = 0;
2174 r300
->hw
.unk4E00
.cmd
[1] = 0;
2177 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = 0;
2178 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = 0;
2181 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2182 r300
->hw
.blend_color
.cmd
[2] = 0;
2183 r300
->hw
.blend_color
.cmd
[3] = 0;
2185 /* Again, r300ClearBuffer uses this */
2186 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = r300
->radeon
.state
.color
.drawOffset
+
2187 r300
->radeon
.radeonScreen
->fbLocation
;
2188 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.state
.color
.drawPitch
;
2190 if (r300
->radeon
.radeonScreen
->cpp
== 4)
2191 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
2193 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
2195 if (r300
->radeon
.sarea
->tiling_enabled
)
2196 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
2198 r300
->hw
.unk4E50
.cmd
[1] = 0;
2199 r300
->hw
.unk4E50
.cmd
[2] = 0;
2200 r300
->hw
.unk4E50
.cmd
[3] = 0;
2201 r300
->hw
.unk4E50
.cmd
[4] = 0;
2202 r300
->hw
.unk4E50
.cmd
[5] = 0;
2203 r300
->hw
.unk4E50
.cmd
[6] = 0;
2204 r300
->hw
.unk4E50
.cmd
[7] = 0;
2205 r300
->hw
.unk4E50
.cmd
[8] = 0;
2206 r300
->hw
.unk4E50
.cmd
[9] = 0;
2208 r300
->hw
.unk4E88
.cmd
[1] = 0;
2210 r300
->hw
.unk4EA0
.cmd
[1] = 0x00000000;
2211 r300
->hw
.unk4EA0
.cmd
[2] = 0xffffffff;
2213 switch (ctx
->Visual
.depthBits
) {
2215 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTH_FORMAT_16BIT_INT_Z
;
2218 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTH_FORMAT_24BIT_INT_Z
;
2221 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2222 ctx
->Visual
.depthBits
);
2227 //r300->hw.zstencil_format.cmd[1] |= R300_DEPTH_FORMAT_UNK32;
2229 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
2230 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
2232 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
2233 r300
->radeon
.radeonScreen
->depthOffset
+
2234 r300
->radeon
.radeonScreen
->fbLocation
;
2235 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
2237 if (r300
->radeon
.sarea
->tiling_enabled
) {
2238 /* Turn off when clearing buffers ? */
2239 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_TILE_ENABLE
;
2241 if (ctx
->Visual
.depthBits
== 24)
2242 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_MICROTILE_ENABLE
;
2245 r300
->hw
.unk4F28
.cmd
[1] = 0;
2247 r300
->hw
.unk4F30
.cmd
[1] = 0;
2248 r300
->hw
.unk4F30
.cmd
[2] = 0;
2250 r300
->hw
.unk4F44
.cmd
[1] = 0;
2252 r300
->hw
.unk4F54
.cmd
[1] = 0;
2255 ((drm_r300_cmd_header_t
*)r300
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2256 for(i
= 1; i
< R300_VPI_CMDSIZE
; i
+= 4) {
2258 r300
->hw
.vpi
.cmd
[i
+0] = VP_OUT(ADD
,TMP
,0,XYZW
);
2259 r300
->hw
.vpi
.cmd
[i
+1] = VP_IN(TMP
,0);
2260 r300
->hw
.vpi
.cmd
[i
+2] = VP_ZERO();
2261 r300
->hw
.vpi
.cmd
[i
+3] = VP_ZERO();
2264 ((drm_r300_cmd_header_t
*)r300
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2265 for(i
= 1; i
< R300_VPP_CMDSIZE
; ++i
)
2266 r300
->hw
.vpp
.cmd
[i
] = 0;
2269 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2270 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2271 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2272 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2275 r300
->hw
.all_dirty
= GL_TRUE
;
2281 * Calculate initial hardware state and register state functions.
2282 * Assumes that the command buffer and state atoms have been
2283 * initialized already.
2285 void r300InitState(r300ContextPtr r300
)
2287 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2290 radeonInitState(&r300
->radeon
);
2292 switch (ctx
->Visual
.depthBits
) {
2294 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2295 depth_fmt
= R300_DEPTH_FORMAT_16BIT_INT_Z
;
2296 r300
->state
.stencil
.clear
= 0x00000000;
2299 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2300 depth_fmt
= R300_DEPTH_FORMAT_24BIT_INT_Z
;
2301 r300
->state
.stencil
.clear
= 0x00ff0000;
2304 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2305 ctx
->Visual
.depthBits
);
2309 /* Only have hw stencil when depth buffer is 24 bits deep */
2310 r300
->state
.stencil
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2311 ctx
->Visual
.depthBits
== 24);
2313 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2315 r300ResetHwState(r300
);
2318 static void r300RenderMode( GLcontext
*ctx
, GLenum mode
)
2320 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2326 * Initialize driver's state callback functions
2328 void r300InitStateFuncs(struct dd_function_table
* functions
)
2330 radeonInitStateFuncs(functions
);
2332 functions
->UpdateState
= r300InvalidateState
;
2333 functions
->AlphaFunc
= r300AlphaFunc
;
2334 functions
->BlendColor
= r300BlendColor
;
2335 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2336 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2337 functions
->Enable
= r300Enable
;
2338 functions
->ColorMask
= r300ColorMask
;
2339 functions
->DepthFunc
= r300DepthFunc
;
2340 functions
->DepthMask
= r300DepthMask
;
2341 functions
->CullFace
= r300CullFace
;
2342 functions
->Fogfv
= r300Fogfv
;
2343 functions
->FrontFace
= r300FrontFace
;
2344 functions
->ShadeModel
= r300ShadeModel
;
2346 /* Stencil related */
2347 functions
->ClearStencil
= r300ClearStencil
;
2348 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2349 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2350 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2352 /* Viewport related */
2353 functions
->Viewport
= r300Viewport
;
2354 functions
->DepthRange
= r300DepthRange
;
2355 functions
->PointSize
= r300PointSize
;
2356 functions
->LineWidth
= r300LineWidth
;
2358 functions
->PolygonOffset
= r300PolygonOffset
;
2359 functions
->PolygonMode
= r300PolygonMode
;
2361 functions
->RenderMode
= r300RenderMode
;