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 "array_cache/acache.h"
51 #include "texformat.h"
53 #include "radeon_ioctl.h"
54 #include "radeon_state.h"
55 #include "r300_context.h"
56 #include "r300_ioctl.h"
57 #include "r300_state.h"
59 #include "r300_program.h"
60 #include "r300_emit.h"
61 #include "r300_fragprog.h"
63 #include "r300_maos.h"
65 #include "drirenderbuffer.h"
67 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
69 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
70 int pp_misc
= rmesa
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
];
73 CLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
75 R300_STATECHANGE(rmesa
, at
);
77 pp_misc
&= ~(R300_ALPHA_TEST_OP_MASK
| R300_REF_ALPHA_MASK
);
78 pp_misc
|= (refByte
& R300_REF_ALPHA_MASK
);
82 pp_misc
|= R300_ALPHA_TEST_FAIL
;
85 pp_misc
|= R300_ALPHA_TEST_LESS
;
88 pp_misc
|= R300_ALPHA_TEST_EQUAL
;
91 pp_misc
|= R300_ALPHA_TEST_LEQUAL
;
94 pp_misc
|= R300_ALPHA_TEST_GREATER
;
97 pp_misc
|= R300_ALPHA_TEST_NEQUAL
;
100 pp_misc
|= R300_ALPHA_TEST_GEQUAL
;
103 pp_misc
|= R300_ALPHA_TEST_PASS
;
104 //pp_misc &= ~R300_ALPHA_TEST_ENABLE;
108 rmesa
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
111 static void r300BlendColor(GLcontext
* ctx
, const GLfloat cf
[4])
114 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
116 R300_STATECHANGE(rmesa
, unk4E10
);
118 CLAMPED_FLOAT_TO_UBYTE(color
[0], cf
[0]);
119 CLAMPED_FLOAT_TO_UBYTE(color
[1], cf
[1]);
120 CLAMPED_FLOAT_TO_UBYTE(color
[2], cf
[2]);
121 CLAMPED_FLOAT_TO_UBYTE(color
[3], cf
[3]);
123 rmesa
->hw
.unk4E10
.cmd
[1] = r300PackColor(4, color
[3], color
[0],
128 * Calculate the hardware blend factor setting. This same function is used
129 * for source and destination of both alpha and RGB.
132 * The hardware register value for the specified blend factor. This value
133 * will need to be shifted into the correct position for either source or
134 * destination factor.
137 * Since the two cases where source and destination are handled differently
138 * are essentially error cases, they should never happen. Determine if these
139 * cases can be removed.
141 static int blend_factor(GLenum factor
, GLboolean is_src
)
147 func
= R200_BLEND_GL_ZERO
;
150 func
= R200_BLEND_GL_ONE
;
153 func
= R200_BLEND_GL_DST_COLOR
;
155 case GL_ONE_MINUS_DST_COLOR
:
156 func
= R200_BLEND_GL_ONE_MINUS_DST_COLOR
;
159 func
= R200_BLEND_GL_SRC_COLOR
;
161 case GL_ONE_MINUS_SRC_COLOR
:
162 func
= R200_BLEND_GL_ONE_MINUS_SRC_COLOR
;
165 func
= R200_BLEND_GL_SRC_ALPHA
;
167 case GL_ONE_MINUS_SRC_ALPHA
:
168 func
= R200_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
171 func
= R200_BLEND_GL_DST_ALPHA
;
173 case GL_ONE_MINUS_DST_ALPHA
:
174 func
= R200_BLEND_GL_ONE_MINUS_DST_ALPHA
;
176 case GL_SRC_ALPHA_SATURATE
:
178 (is_src
) ? R200_BLEND_GL_SRC_ALPHA_SATURATE
:
181 case GL_CONSTANT_COLOR
:
182 func
= R200_BLEND_GL_CONST_COLOR
;
184 case GL_ONE_MINUS_CONSTANT_COLOR
:
185 func
= R200_BLEND_GL_ONE_MINUS_CONST_COLOR
;
187 case GL_CONSTANT_ALPHA
:
188 func
= R200_BLEND_GL_CONST_ALPHA
;
190 case GL_ONE_MINUS_CONSTANT_ALPHA
:
191 func
= R200_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
194 fprintf(stderr
, "unknown blend factor %x\n", factor
);
195 func
= (is_src
) ? R200_BLEND_GL_ONE
: R200_BLEND_GL_ZERO
;
201 * Sets both the blend equation and the blend function.
202 * This is done in a single
203 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
204 * change the interpretation of the blend function.
205 * Also, make sure that blend function and blend equation are set to their default
206 * value if color blending is not enabled, since at least blend equations GL_MIN
207 * and GL_FUNC_REVERSE_SUBTRACT will cause wrong results otherwise for
211 /* helper function */
212 static void r300_set_blend_cntl(r300ContextPtr r300
, int func
, int eqn
, int cbits
, int funcA
, int eqnA
)
214 GLuint new_ablend
, new_cblend
;
217 fprintf(stderr
, "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n", eqnA
, funcA
, eqn
, func
, cbits
);
219 new_ablend
= eqnA
| funcA
;
220 new_cblend
= eqn
| func
;
222 /* Some blend factor combinations don't seem to work when the
223 * BLEND_NO_SEPARATE bit is set.
225 * Especially problematic candidates are the ONE_MINUS_* flags,
226 * but I can't see a real pattern.
229 if (new_ablend
== new_cblend
) {
230 new_cblend
|= R300_BLEND_NO_SEPARATE
;
235 if((new_ablend
!= r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]) ||
236 (new_cblend
!= r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
])) {
237 R300_STATECHANGE(r300
, bld
);
238 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]=new_ablend
;
239 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
]=new_cblend
;
244 static void r300_set_blend_state(GLcontext
* ctx
)
246 r300ContextPtr r300
= R300_CONTEXT(ctx
);
247 int func
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
248 (R200_BLEND_GL_ZERO
<< R200_DST_BLEND_SHIFT
);
249 int eqn
= R200_COMB_FCN_ADD_CLAMP
;
250 int funcA
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
251 (R200_BLEND_GL_ZERO
<< R200_DST_BLEND_SHIFT
);
252 int eqnA
= R200_COMB_FCN_ADD_CLAMP
;
254 if (ctx
->Color
._LogicOpEnabled
|| !ctx
->Color
.BlendEnabled
) {
255 r300_set_blend_cntl(r300
,
261 func
= (blend_factor(ctx
->Color
.BlendSrcRGB
, GL_TRUE
) << R200_SRC_BLEND_SHIFT
) |
262 (blend_factor(ctx
->Color
.BlendDstRGB
, GL_FALSE
) << R200_DST_BLEND_SHIFT
);
264 switch (ctx
->Color
.BlendEquationRGB
) {
266 eqn
= R300_COMB_FCN_ADD_CLAMP
;
269 case GL_FUNC_SUBTRACT
:
270 eqn
= R300_COMB_FCN_SUB_CLAMP
;
273 case GL_FUNC_REVERSE_SUBTRACT
:
274 eqn
= R200_COMB_FCN_RSUB_CLAMP
;
278 eqn
= R200_COMB_FCN_MIN
;
279 func
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
280 (R200_BLEND_GL_ONE
<< R200_DST_BLEND_SHIFT
);
284 eqn
= R200_COMB_FCN_MAX
;
285 func
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
286 (R200_BLEND_GL_ONE
<< R200_DST_BLEND_SHIFT
);
291 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
292 __func__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
297 funcA
= (blend_factor(ctx
->Color
.BlendSrcA
, GL_TRUE
) << R200_SRC_BLEND_SHIFT
) |
298 (blend_factor(ctx
->Color
.BlendDstA
, GL_FALSE
) << R200_DST_BLEND_SHIFT
);
300 switch (ctx
->Color
.BlendEquationA
) {
302 eqnA
= R300_COMB_FCN_ADD_CLAMP
;
305 case GL_FUNC_SUBTRACT
:
306 eqnA
= R300_COMB_FCN_SUB_CLAMP
;
309 case GL_FUNC_REVERSE_SUBTRACT
:
310 eqnA
= R200_COMB_FCN_RSUB_CLAMP
;
314 eqnA
= R200_COMB_FCN_MIN
;
315 funcA
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
316 (R200_BLEND_GL_ONE
<< R200_DST_BLEND_SHIFT
);
320 eqnA
= R200_COMB_FCN_MAX
;
321 funcA
= (R200_BLEND_GL_ONE
<< R200_SRC_BLEND_SHIFT
) |
322 (R200_BLEND_GL_ONE
<< R200_DST_BLEND_SHIFT
);
326 fprintf(stderr
, "[%s:%u] Invalid A blend equation (0x%04x).\n",
327 __func__
, __LINE__
, ctx
->Color
.BlendEquationA
);
331 r300_set_blend_cntl(r300
,
332 func
, eqn
, R300_BLEND_UNKNOWN
| R300_BLEND_ENABLE
,
336 static void r300BlendEquationSeparate(GLcontext
* ctx
,
337 GLenum modeRGB
, GLenum modeA
)
339 r300_set_blend_state(ctx
);
342 static void r300BlendFuncSeparate(GLcontext
* ctx
,
343 GLenum sfactorRGB
, GLenum dfactorRGB
,
344 GLenum sfactorA
, GLenum dfactorA
)
346 r300_set_blend_state(ctx
);
350 * Update our tracked culling state based on Mesa's state.
352 static void r300UpdateCulling(GLcontext
* ctx
)
354 r300ContextPtr r300
= R300_CONTEXT(ctx
);
357 R300_STATECHANGE(r300
, cul
);
358 if (ctx
->Polygon
.CullFlag
) {
359 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
)
360 val
= R300_CULL_FRONT
|R300_CULL_BACK
;
361 else if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
362 val
= R300_CULL_FRONT
;
364 val
= R300_CULL_BACK
;
366 if (ctx
->Polygon
.FrontFace
== GL_CW
)
367 val
|= R300_FRONT_FACE_CW
;
369 val
|= R300_FRONT_FACE_CCW
;
371 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
374 static void update_early_z(GLcontext
* ctx
)
376 /* updates register 0x4f14
377 if depth test is not enabled it should be 0x00000000
378 if depth is enabled and alpha not it should be 0x00000001
379 if depth and alpha is enabled it should be 0x00000000
381 r300ContextPtr r300
= R300_CONTEXT(ctx
);
383 R300_STATECHANGE(r300
, unk4F10
);
384 if (ctx
->Color
.AlphaEnabled
)
385 /* disable early Z */
386 r300
->hw
.unk4F10
.cmd
[2] = 0x00000000;
390 r300
->hw
.unk4F10
.cmd
[2] = 0x00000001;
392 /* disable early Z */
393 r300
->hw
.unk4F10
.cmd
[2] = 0x00000000;
398 * Handle glEnable()/glDisable().
400 * \note Mesa already filters redundant calls to glEnable/glDisable.
402 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
404 r300ContextPtr r300
= R300_CONTEXT(ctx
);
407 if (RADEON_DEBUG
& DEBUG_STATE
)
408 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
409 _mesa_lookup_enum_by_nr(cap
),
410 state
? "GL_TRUE" : "GL_FALSE");
413 /* Fast track this one...
421 R300_STATECHANGE(r300
, fogs
);
423 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] |=
426 ctx
->Driver
.Fogfv( ctx
, GL_FOG_MODE
, NULL
);
427 ctx
->Driver
.Fogfv( ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
428 ctx
->Driver
.Fogfv( ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
429 ctx
->Driver
.Fogfv( ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
430 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
432 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] &=
439 R300_STATECHANGE(r300
, at
);
441 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] |=
442 R300_ALPHA_TEST_ENABLE
;
444 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] &=
445 ~R300_ALPHA_TEST_ENABLE
;
451 case GL_COLOR_LOGIC_OP
:
452 r300_set_blend_state(ctx
);
456 R300_STATECHANGE(r300
, zs
);
460 newval
= R300_RB3D_Z_TEST_AND_WRITE
;
462 newval
= R300_RB3D_Z_TEST
;
464 newval
= R300_RB3D_Z_DISABLED_1
;
466 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_RB3D_STENCIL_ENABLE
;
467 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= newval
;
471 case GL_STENCIL_TEST
:
472 if (r300
->state
.stencil
.hw_stencil
) {
473 R300_STATECHANGE(r300
, zs
);
475 WARN_ONCE("TODO - double side stencil !\n");
476 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
477 R300_RB3D_STENCIL_ENABLE
;
479 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
480 ~R300_RB3D_STENCIL_ENABLE
;
484 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
490 r300UpdateCulling(ctx
);
493 case GL_POLYGON_OFFSET_POINT
:
494 case GL_POLYGON_OFFSET_LINE
:
497 case GL_POLYGON_OFFSET_FILL
:
498 R300_STATECHANGE(r300
, unk42B4
);
500 r300
->hw
.unk42B4
.cmd
[1] |= (3<<0);
502 r300
->hw
.unk42B4
.cmd
[1] &= ~(3<<0);
506 radeonEnable(ctx
, cap
, state
);
512 static void r300UpdatePolygonMode(GLcontext
*ctx
)
514 r300ContextPtr r300
= R300_CONTEXT(ctx
);
517 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
518 ctx
->Polygon
.BackMode
!= GL_FILL
) {
521 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
522 f
= ctx
->Polygon
.FrontMode
;
523 b
= ctx
->Polygon
.BackMode
;
525 f
= ctx
->Polygon
.BackMode
;
526 b
= ctx
->Polygon
.FrontMode
;
529 hw_mode
|= R300_PM_ENABLED
;
533 hw_mode
|= R300_PM_FRONT_LINE
;
535 case GL_POINT
: /* noop */
536 hw_mode
|= R300_PM_FRONT_POINT
;
539 hw_mode
|= R300_PM_FRONT_FILL
;
545 hw_mode
|= R300_PM_BACK_LINE
;
547 case GL_POINT
: /* noop */
548 hw_mode
|= R300_PM_BACK_POINT
;
551 hw_mode
|= R300_PM_BACK_FILL
;
556 if (r300
->hw
.unk4288
.cmd
[1] != hw_mode
) {
557 R300_STATECHANGE(r300
, unk4288
);
558 r300
->hw
.unk4288
.cmd
[1] = hw_mode
;
563 * Change the culling mode.
565 * \note Mesa already filters redundant calls to this function.
567 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
571 r300UpdateCulling(ctx
);
576 * Change the polygon orientation.
578 * \note Mesa already filters redundant calls to this function.
580 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
584 r300UpdateCulling(ctx
);
585 r300UpdatePolygonMode(ctx
);
590 * Change the depth testing function.
592 * \note Mesa already filters redundant calls to this function.
594 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
596 r300ContextPtr r300
= R300_CONTEXT(ctx
);
598 R300_STATECHANGE(r300
, zs
);
600 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
604 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_NEVER
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
607 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_LESS
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
610 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_EQUAL
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
613 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_LEQUAL
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
616 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_GREATER
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
619 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_NOTEQUAL
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
622 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_GEQUAL
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
625 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= R300_ZS_ALWAYS
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
632 * Enable/Disable depth writing.
634 * \note Mesa already filters redundant calls to this function.
636 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
638 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
643 * Handle glColorMask()
645 static void r300ColorMask(GLcontext
* ctx
,
646 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
648 r300ContextPtr r300
= R300_CONTEXT(ctx
);
649 int mask
= (r
? R300_COLORMASK0_R
: 0) |
650 (g
? R300_COLORMASK0_G
: 0) |
651 (b
? R300_COLORMASK0_B
: 0) |
652 (a
? R300_COLORMASK0_A
: 0);
654 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
655 R300_STATECHANGE(r300
, cmk
);
656 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
660 /* =============================================================
663 static void r300Fogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
665 r300ContextPtr r300
= R300_CONTEXT(ctx
);
666 union { int i
; float f
; } fogScale
, fogStart
;
670 fogScale
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
];
671 fogStart
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_START
];
675 if (!ctx
->Fog
.Enabled
)
677 switch (ctx
->Fog
.Mode
) {
679 R300_STATECHANGE(r300
, fogs
);
680 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
681 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_LINEAR
;
683 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
688 fogScale
.f
= 1.0 / (ctx
->Fog
.End
-ctx
->Fog
.Start
);
689 fogStart
.f
= -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-ctx
->Fog
.Start
);
693 R300_STATECHANGE(r300
, fogs
);
694 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
695 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_EXP
;
696 fogScale
.f
= 0.0933*ctx
->Fog
.Density
;
700 R300_STATECHANGE(r300
, fogs
);
701 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
702 (r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) | R300_FOG_MODE_EXP2
;
703 fogScale
.f
= 0.3*ctx
->Fog
.Density
;
710 switch (ctx
->Fog
.Mode
) {
712 fogScale
.f
= 0.0933*ctx
->Fog
.Density
;
716 fogScale
.f
= 0.3*ctx
->Fog
.Density
;
724 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
725 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
730 fogScale
.f
= 1.0 / (ctx
->Fog
.End
-ctx
->Fog
.Start
);
731 fogStart
.f
= -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-ctx
->Fog
.Start
);
736 R300_STATECHANGE(r300
, fogc
);
737 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] = (GLuint
) (ctx
->Fog
.Color
[0]*1023.0F
) & 0x3FF;
738 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] = (GLuint
) (ctx
->Fog
.Color
[1]*1023.0F
) & 0x3FF;
739 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] = (GLuint
) (ctx
->Fog
.Color
[2]*1023.0F
) & 0x3FF;
741 case GL_FOG_COORD_SRC
:
747 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
748 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
749 R300_STATECHANGE(r300
, fogp
);
750 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
751 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
755 /* =============================================================
758 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
760 r300ContextPtr r300
= R300_CONTEXT(ctx
);
762 size
= ctx
->Point
._Size
;
764 R300_STATECHANGE(r300
, ps
);
765 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
766 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
767 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
770 /* =============================================================
773 static void r300LineWidth(GLcontext
*ctx
, GLfloat widthf
)
775 r300ContextPtr r300
= R300_CONTEXT(ctx
);
777 widthf
= ctx
->Line
._Width
;
779 R300_STATECHANGE(r300
, lcntl
);
780 r300
->hw
.lcntl
.cmd
[1] = (int)(widthf
* 6.0);
781 r300
->hw
.lcntl
.cmd
[1] |= R300_LINE_CNT_VE
;
784 static void r300PolygonMode(GLcontext
*ctx
, GLenum face
, GLenum mode
)
789 r300UpdatePolygonMode(ctx
);
792 /* =============================================================
796 static int translate_stencil_func(int func
)
800 return R300_ZS_NEVER
;
804 return R300_ZS_EQUAL
;
806 return R300_ZS_LEQUAL
;
808 return R300_ZS_GREATER
;
810 return R300_ZS_NOTEQUAL
;
812 return R300_ZS_GEQUAL
;
814 return R300_ZS_ALWAYS
;
819 static int translate_stencil_op(int op
)
827 return R300_ZS_REPLACE
;
832 case GL_INCR_WRAP_EXT
:
833 return R300_ZS_INCR_WRAP
;
834 case GL_DECR_WRAP_EXT
:
835 return R300_ZS_DECR_WRAP
;
837 return R300_ZS_INVERT
;
839 WARN_ONCE("Do not know how to translate stencil op");
845 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
847 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
849 R300_STATECHANGE(rmesa
, unk4274
);
852 rmesa
->hw
.unk4274
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
855 rmesa
->hw
.unk4274
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
862 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
863 GLenum func
, GLint ref
, GLuint mask
)
865 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
866 GLuint refmask
= (((ctx
->Stencil
.Ref
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
867 ((ctx
->Stencil
.ValueMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
871 R300_STATECHANGE(rmesa
, zs
);
873 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(
874 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
)
875 | (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
877 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &= ~((R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
878 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
880 flag
= translate_stencil_func(ctx
->Stencil
.Function
[0]);
882 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |= (flag
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
)
883 | (flag
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
884 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
887 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
889 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
891 R300_STATECHANGE(rmesa
, zs
);
892 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &= ~(R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
);
893 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= (ctx
->Stencil
.WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
;
897 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
, GLenum fail
,
898 GLenum zfail
, GLenum zpass
)
900 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
902 R300_STATECHANGE(rmesa
, zs
);
903 /* It is easier to mask what's left.. */
904 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
905 (R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
) |
906 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
907 (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
909 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
910 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
)
911 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
)
912 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
)
913 |(translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
914 |(translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
915 |(translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
918 static void r300ClearStencil(GLcontext
* ctx
, GLint s
)
920 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
922 rmesa
->state
.stencil
.clear
=
923 ((GLuint
) (ctx
->Stencil
.Clear
& 0xff) |
924 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
) |
925 ((ctx
->Stencil
.WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
));
928 /* =============================================================
929 * Window position and viewport transformation
933 * To correctly position primitives:
935 #define SUBPIXEL_X 0.125
936 #define SUBPIXEL_Y 0.125
938 void r300UpdateWindow(GLcontext
* ctx
)
940 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
941 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
942 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
943 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
944 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
946 GLfloat sx
= v
[MAT_SX
];
947 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
948 GLfloat sy
= -v
[MAT_SY
];
949 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
950 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
951 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
953 R300_FIREVERTICES(rmesa
);
954 R300_STATECHANGE(rmesa
, vpt
);
956 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
957 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
958 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
959 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
960 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
961 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
964 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
965 GLsizei width
, GLsizei height
)
967 /* Don't pipeline viewport changes, conflict with window offset
968 * setting below. Could apply deltas to rescue pipelined viewport
969 * values, or keep the originals hanging around.
971 r300UpdateWindow(ctx
);
974 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
976 r300UpdateWindow(ctx
);
979 void r300UpdateViewportOffset( GLcontext
*ctx
)
981 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
982 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
)rmesa
)->dri
.drawable
;
983 GLfloat xoffset
= (GLfloat
)dPriv
->x
;
984 GLfloat yoffset
= (GLfloat
)dPriv
->y
+ dPriv
->h
;
985 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
987 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
988 GLfloat ty
= (- v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
990 if ( rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] != r300PackFloat32(tx
) ||
991 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] != r300PackFloat32(ty
))
993 /* Note: this should also modify whatever data the context reset
996 R300_STATECHANGE( rmesa
, vpt
);
997 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_XOFFSET
] = r300PackFloat32(tx
);
998 rmesa
->hw
.vpt
.cmd
[VPT_SE_VPORT_YOFFSET
] = r300PackFloat32(ty
);
1002 radeonUpdateScissor( ctx
);
1006 * Tell the card where to render (offset, pitch).
1007 * Effected by glDrawBuffer, etc
1010 r300UpdateDrawBuffer(GLcontext
*ctx
)
1012 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1013 r300ContextPtr r300
= rmesa
;
1014 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1015 driRenderbuffer
*drb
;
1017 if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
) {
1019 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
1021 else if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_BACK_LEFT
) {
1023 drb
= (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1026 /* drawing to multiple buffers, or none */
1031 assert(drb
->flippedPitch
);
1034 R300_STATECHANGE( rmesa
, cb
);
1036 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = drb
->flippedOffset
+ //r300->radeon.state.color.drawOffset +
1037 r300
->radeon
.radeonScreen
->fbLocation
;
1038 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = drb
->flippedPitch
;//r300->radeon.state.color.drawPitch;
1040 if (r300
->radeon
.radeonScreen
->cpp
== 4)
1041 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
1043 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
1045 if (r300
->radeon
.sarea
->tiling_enabled
)
1046 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
1048 R200_STATECHANGE( rmesa
, ctx
);
1050 /* Note: we used the (possibly) page-flipped values */
1051 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
1052 = ((drb
->flippedOffset
+ rmesa
->r200Screen
->fbLocation
)
1053 & R200_COLOROFFSET_MASK
);
1054 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
1056 if (rmesa
->sarea
->tiling_enabled
) {
1057 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |= R200_COLOR_TILE_ENABLE
;
1062 /* =============================================================
1065 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1067 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1068 GLfloat constant
= units
;
1070 switch (ctx
->Visual
.depthBits
) {
1081 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1083 R300_STATECHANGE(rmesa
, zbs
);
1084 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1085 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1086 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1087 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1090 /* Routing and texture-related */
1093 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1094 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1095 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1096 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1097 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1098 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1099 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1100 * combinations where only one of them is nearest.
1102 static unsigned long gen_fixed_filter(unsigned long f
)
1104 unsigned long mag
, min
, needs_fixing
=0;
1107 /* We ignore MIRROR bit so we dont have to do everything twice */
1108 if((f
& ((7-1) << R300_TX_WRAP_S_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)){
1111 if((f
& ((7-1) << R300_TX_WRAP_T_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)){
1114 if((f
& ((7-1) << R300_TX_WRAP_Q_SHIFT
)) == (R300_TX_CLAMP
<< R300_TX_WRAP_Q_SHIFT
)){
1121 mag
=f
& R300_TX_MAG_FILTER_MASK
;
1122 min
=f
& R300_TX_MIN_FILTER_MASK
;
1124 /* TODO: Check for anisto filters too */
1125 if((mag
!= R300_TX_MAG_FILTER_NEAREST
) && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1128 /* r300 cant handle these modes hence we force nearest to linear */
1129 if((mag
== R300_TX_MAG_FILTER_NEAREST
) && (min
!= R300_TX_MIN_FILTER_NEAREST
)){
1130 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1131 f
|= R300_TX_MAG_FILTER_LINEAR
;
1135 if((min
== R300_TX_MIN_FILTER_NEAREST
) && (mag
!= R300_TX_MAG_FILTER_NEAREST
)){
1136 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1137 f
|= R300_TX_MIN_FILTER_LINEAR
;
1141 /* Both are nearest */
1142 if(needs_fixing
& 1){
1143 f
&= ~((7-1) << R300_TX_WRAP_S_SHIFT
);
1144 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1146 if(needs_fixing
& 2){
1147 f
&= ~((7-1) << R300_TX_WRAP_T_SHIFT
);
1148 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1150 if(needs_fixing
& 4){
1151 f
&= ~((7-1) << R300_TX_WRAP_Q_SHIFT
);
1152 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_Q_SHIFT
;
1157 void r300_setup_textures(GLcontext
*ctx
)
1160 struct r300_tex_obj
*t
;
1161 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1163 int last_hw_tmu
=-1; /* -1 translates into no setup costs for fields */
1164 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1 };
1165 struct r300_fragment_program
*rp
=
1166 (struct r300_fragment_program
*)
1167 (char *)ctx
->FragmentProgram
._Current
;
1169 R300_STATECHANGE(r300
, txe
);
1170 R300_STATECHANGE(r300
, tex
.filter
);
1171 R300_STATECHANGE(r300
, tex
.unknown1
);
1172 R300_STATECHANGE(r300
, tex
.size
);
1173 R300_STATECHANGE(r300
, tex
.format
);
1174 R300_STATECHANGE(r300
, tex
.pitch
);
1175 R300_STATECHANGE(r300
, tex
.offset
);
1176 R300_STATECHANGE(r300
, tex
.unknown4
);
1177 R300_STATECHANGE(r300
, tex
.border_color
);
1179 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
]=0x0;
1181 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1182 if (RADEON_DEBUG
& DEBUG_STATE
)
1183 fprintf(stderr
, "mtu=%d\n", mtu
);
1185 if(mtu
> R300_MAX_TEXTURE_UNITS
) {
1186 fprintf(stderr
, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1187 mtu
, R300_MAX_TEXTURE_UNITS
);
1191 /* We cannot let disabled tmu offsets pass DRM */
1192 for(i
=0; i
< mtu
; i
++) {
1193 if(TMU_ENABLED(ctx
, i
)) {
1195 #if 0 /* Enables old behaviour */
1198 tmu_mappings
[i
] = hw_tmu
;
1200 t
=r300
->state
.texture
.unit
[i
].texobj
;
1202 if((t
->format
& 0xffffff00)==0xffffff00) {
1203 WARN_ONCE("unknown texture format (entry %x) encountered. Help me !\n", t
->format
& 0xff);
1206 if (RADEON_DEBUG
& DEBUG_STATE
)
1207 fprintf(stderr
, "Activating texture unit %d\n", i
);
1209 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1211 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = gen_fixed_filter(t
->filter
) | (hw_tmu
<< 28);
1212 /* Currently disabled! */
1213 r300
->hw
.tex
.unknown1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0; //0x20501f80;
1214 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->size
;
1215 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->format
;
1216 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->pitch_reg
;
1217 r300
->hw
.tex
.offset
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->offset
;
1219 if(t
->offset
& R300_TXO_MACRO_TILE
) {
1220 WARN_ONCE("macro tiling enabled!\n");
1223 if(t
->offset
& R300_TXO_MICRO_TILE
) {
1224 WARN_ONCE("micro tiling enabled!\n");
1227 r300
->hw
.tex
.unknown4
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0;
1228 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = t
->pp_border_color
;
1230 last_hw_tmu
= hw_tmu
;
1236 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FILTER_0
, last_hw_tmu
+ 1);
1237 r300
->hw
.tex
.unknown1
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1238 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1239 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1240 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_PITCH_0
, last_hw_tmu
+ 1);
1241 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1242 r300
->hw
.tex
.unknown4
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1243 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] = cmdpacket0(R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1246 if (!rp
) /* should only happenen once, just after context is created */
1249 R300_STATECHANGE(r300
, fpt
);
1251 for(i
= 0; i
< rp
->tex
.length
; i
++){
1255 unit
= rp
->tex
.inst
[i
] >> R300_FPITX_IMAGE_SHIFT
;
1258 val
= rp
->tex
.inst
[i
];
1259 val
&= ~R300_FPITX_IMAGE_MASK
;
1261 assert(tmu_mappings
[unit
] >= 0);
1263 val
|= tmu_mappings
[unit
] << R300_FPITX_IMAGE_SHIFT
;
1264 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+i
] = val
;
1267 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] = cmdpacket0(R300_PFS_TEXI_0
, rp
->tex
.length
);
1269 if (RADEON_DEBUG
& DEBUG_STATE
)
1270 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n", r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1273 union r300_outputs_written
{
1274 GLuint vp_outputs
; /* hw_tcl_on */
1275 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1278 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1279 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1280 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1282 void r300_setup_rs_unit(GLcontext
*ctx
)
1284 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1285 /* I'm still unsure if these are needed */
1286 GLuint interp_magic
[8] = {
1296 union r300_outputs_written OutputsWritten
;
1298 int fp_reg
, high_rr
;
1299 int in_texcoords
, col_interp_nr
;
1303 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->Base
.OutputsWritten
;
1305 RENDERINPUTS_COPY( OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1307 if (ctx
->FragmentProgram
._Current
)
1308 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1310 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1311 return; /* This should only ever happen once.. */
1314 R300_STATECHANGE(r300
, ri
);
1315 R300_STATECHANGE(r300
, rc
);
1316 R300_STATECHANGE(r300
, rr
);
1318 fp_reg
= in_texcoords
= col_interp_nr
= high_rr
= 0;
1319 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] = 0;
1320 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] = 0;
1322 for (i
=0;i
<ctx
->Const
.MaxTextureUnits
;i
++) {
1323 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+i
] = 0
1324 | R300_RS_INTERP_USED
1325 | (in_texcoords
<< R300_RS_INTERP_SRC_SHIFT
)
1328 if (InputsRead
& (FRAG_BIT_TEX0
<<i
)) {
1329 //assert(r300->state.texture.tc_count != 0);
1330 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] = 0
1331 | R300_RS_ROUTE_ENABLE
1332 | i
/* source INTERP */
1333 | (fp_reg
<< R300_RS_ROUTE_DEST_SHIFT
);
1336 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_TEX0
+i
, _TNL_ATTRIB_TEX(i
) )) {
1337 /* Passing invalid data here can lock the GPU. */
1338 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1339 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1342 InputsRead
&= ~(FRAG_BIT_TEX0
<<i
);
1345 /* Need to count all coords enabled at vof */
1346 if (R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_TEX0
+i
, _TNL_ATTRIB_TEX(i
) ))
1350 if (InputsRead
& FRAG_BIT_COL0
) {
1351 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1352 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1353 goto out
; /* FIXME */
1354 //_mesa_print_program(&CURRENT_VERTEX_SHADER(ctx)->Base);
1358 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1359 | R300_RS_ROUTE_0_COLOR
1360 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1361 InputsRead
&= ~FRAG_BIT_COL0
;
1366 if (InputsRead
& FRAG_BIT_COL1
) {
1367 if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1368 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1372 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] |= R300_RS_ROUTE_1_UNKNOWN11
1373 | R300_RS_ROUTE_1_COLOR1
1374 | (fp_reg
++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT
);
1375 InputsRead
&= ~FRAG_BIT_COL1
;
1376 if (high_rr
< 1) high_rr
= 1;
1380 /* Need at least one. This might still lock as the values are undefined... */
1381 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1382 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0
1383 | R300_RS_ROUTE_0_COLOR
1384 | (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1388 r300
->hw
.rc
.cmd
[1] = 0
1389 | (in_texcoords
<< R300_RS_CNTL_TC_CNT_SHIFT
)
1390 | (col_interp_nr
<< R300_RS_CNTL_CI_CNT_SHIFT
)
1391 | R300_RS_CNTL_0_UNKNOWN_18
;
1393 assert(high_rr
>= 0);
1394 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R300_RS_ROUTE_0
, high_rr
+1);
1395 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1398 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1401 #define vpucount(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
1403 #define bump_vpu_count(ptr, new_count) do{\
1404 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1405 int _nc=(new_count)/4; \
1406 assert(_nc < 256); \
1407 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1410 void static inline setup_vertex_shader_fragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1414 if(vsf
->length
==0)return;
1416 if(vsf
->length
& 0x3){
1417 fprintf(stderr
,"VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1421 switch((dest
>>8) & 0xf){
1423 R300_STATECHANGE(r300
, vpi
);
1424 for(i
=0;i
<vsf
->length
;i
++)
1425 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1426 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+4*(dest
& 0xff));
1430 R300_STATECHANGE(r300
, vpp
);
1431 for(i
=0;i
<vsf
->length
;i
++)
1432 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1433 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+4*(dest
& 0xff));
1436 R300_STATECHANGE(r300
, vps
);
1437 for(i
=0;i
<vsf
->length
;i
++)
1438 r300
->hw
.vps
.cmd
[1+i
+4*(dest
& 0xff)]=(vsf
->body
.d
[i
]);
1439 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+4*(dest
& 0xff));
1442 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1447 void r300SetupVertexProgram(r300ContextPtr rmesa
);
1449 /* just a skeleton for now.. */
1451 /* Generate a vertex shader that simply transforms vertex and texture coordinates,
1452 while leaving colors intact. Nothing fancy (like lights)
1454 If implementing lights make a copy first, so it is easy to switch between the two versions */
1455 static void r300GenerateSimpleVertexShader(r300ContextPtr r300
)
1460 /* Allocate parameters */
1461 r300
->state
.vap_param
.transform_offset
=0x0; /* transform matrix */
1462 r300
->state
.vertex_shader
.param_offset
=0x0;
1463 r300
->state
.vertex_shader
.param_count
=0x4; /* 4 vector values - 4x4 matrix */
1465 r300
->state
.vertex_shader
.program_start
=0x0;
1466 r300
->state
.vertex_shader
.unknown_ptr1
=0x4; /* magic value ? */
1467 r300
->state
.vertex_shader
.program_end
=0x0;
1469 r300
->state
.vertex_shader
.unknown_ptr2
=0x0; /* magic value */
1470 r300
->state
.vertex_shader
.unknown_ptr3
=0x4; /* magic value */
1472 /* Initialize matrix and vector parameters.. these should really be restructured */
1473 /* TODO: fix vertex_shader structure */
1474 r300
->state
.vertex_shader
.matrix
[0].length
=16;
1475 r300
->state
.vertex_shader
.matrix
[1].length
=0;
1476 r300
->state
.vertex_shader
.matrix
[2].length
=0;
1477 r300
->state
.vertex_shader
.vector
[0].length
=0;
1478 r300
->state
.vertex_shader
.vector
[1].length
=0;
1479 r300
->state
.vertex_shader
.unknown1
.length
=0;
1480 r300
->state
.vertex_shader
.unknown2
.length
=0;
1482 #define WRITE_OP(oper,source1,source2,source3) {\
1483 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].op=(oper); \
1484 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src1=(source1); \
1485 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src2=(source2); \
1486 r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src3=(source3); \
1487 r300->state.vertex_shader.program_end++; \
1490 /* Multiply vertex coordinates with transform matrix */
1493 EASY_VSF_OP(MUL
, 0, ALL
, TMP
),
1496 EASY_VSF_SOURCE(0, W
, W
, W
, W
, NONE
, NONE
)
1500 EASY_VSF_OP(MUL
, 1, ALL
, RESULT
),
1507 EASY_VSF_OP(MAD
, 0, ALL
, TMP
),
1514 EASY_VSF_OP(MAD
, 0, ALL
, TMP
),
1521 EASY_VSF_OP(MAD
, 0, ALL
, RESULT
),
1528 if (RENDERINPUTS_TEST( r300
->state
.render_inputs_bitset
, _TNL_ATTRIB_COLOR1
)) {
1530 EASY_VSF_OP(MUL
, o_reg
++, ALL
, RESULT
),
1531 VSF_REG(r300
->state
.vap_reg
.i_color
[1]),
1532 VSF_ATTR_UNITY(r300
->state
.vap_reg
.i_color
[1]),
1533 VSF_UNITY(r300
->state
.vap_reg
.i_color
[1])
1537 /* Pass through texture coordinates, if any */
1538 for(i
=0;i
< r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;i
++)
1539 if (RENDERINPUTS_TEST( r300
->state
.render_inputs_bitset
, _TNL_ATTRIB_TEX(i
) )){
1540 // fprintf(stderr, "i_tex[%d]=%d\n", i, r300->state.vap_reg.i_tex[i]);
1542 EASY_VSF_OP(MUL
, o_reg
++ /* 2+i */, ALL
, RESULT
),
1543 VSF_REG(r300
->state
.vap_reg
.i_tex
[i
]),
1544 VSF_ATTR_UNITY(r300
->state
.vap_reg
.i_tex
[i
]),
1545 VSF_UNITY(r300
->state
.vap_reg
.i_tex
[i
])
1549 r300
->state
.vertex_shader
.program_end
--; /* r300 wants program length to be one more - no idea why */
1550 r300
->state
.vertex_shader
.program
.length
=(r300
->state
.vertex_shader
.program_end
+1)*4;
1552 r300
->state
.vertex_shader
.unknown_ptr1
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1553 r300
->state
.vertex_shader
.unknown_ptr2
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1554 r300
->state
.vertex_shader
.unknown_ptr3
=r300
->state
.vertex_shader
.program_end
; /* magic value ? */
1559 void r300SetupVertexShader(r300ContextPtr rmesa
)
1561 GLcontext
* ctx
= rmesa
->radeon
.glCtx
;
1563 /* Reset state, in case we don't use something */
1564 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1565 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1566 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1568 /* Not sure why this doesnt work...
1569 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
1570 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. */
1571 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
1572 if(hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
){
1573 r300SetupVertexProgram(rmesa
);
1577 /* This needs to be replaced by vertex shader generation code */
1581 /* textures enabled ? */
1582 if(rmesa
->state
.texture
.tc_count
>0){
1583 rmesa
->state
.vertex_shader
=SINGLE_TEXTURE_VERTEX_SHADER
;
1585 rmesa
->state
.vertex_shader
=FLAT_COLOR_VERTEX_SHADER
;
1589 r300GenerateSimpleVertexShader(rmesa
);
1591 rmesa
->state
.vertex_shader
.matrix
[0].length
=16;
1592 memcpy(rmesa
->state
.vertex_shader
.matrix
[0].body
.f
, ctx
->_ModelProjectMatrix
.m
, 16*4);
1594 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(rmesa
->state
.vertex_shader
.program
));
1596 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX0
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1598 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX1
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1599 setup_vertex_shader_fragment(rmesa
, VSF_DEST_MATRIX2
, &(rmesa
->state
.vertex_shader
.matrix
[0]));
1601 setup_vertex_shader_fragment(rmesa
, VSF_DEST_VECTOR0
, &(rmesa
->state
.vertex_shader
.vector
[0]));
1602 setup_vertex_shader_fragment(rmesa
, VSF_DEST_VECTOR1
, &(rmesa
->state
.vertex_shader
.vector
[1]));
1606 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
, &(rmesa
->state
.vertex_shader
.unknown1
));
1607 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
, &(rmesa
->state
.vertex_shader
.unknown2
));
1610 R300_STATECHANGE(rmesa
, pvs
);
1611 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
]=(rmesa
->state
.vertex_shader
.program_start
<< R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1612 | (rmesa
->state
.vertex_shader
.unknown_ptr1
<< R300_PVS_CNTL_1_POS_END_SHIFT
)
1613 | (rmesa
->state
.vertex_shader
.program_end
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1614 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
]=(rmesa
->state
.vertex_shader
.param_offset
<< R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1615 | (rmesa
->state
.vertex_shader
.param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1616 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
]=(rmesa
->state
.vertex_shader
.unknown_ptr2
<< R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1617 | (rmesa
->state
.vertex_shader
.unknown_ptr3
<< 0);
1619 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1620 so I leave it as a reminder */
1622 reg_start(R300_VAP_PVS_WAITIDLE
,0);
1627 void r300SetupVertexProgram(r300ContextPtr rmesa
)
1629 GLcontext
* ctx
= rmesa
->radeon
.glCtx
;
1632 struct r300_vertex_program
*prog
=(struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1635 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1636 R300_STATECHANGE(rmesa
, vpp
);
1637 param_count
= r300VertexProgUpdateParams(ctx
, prog
, (float *)&rmesa
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
]);
1638 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
1641 /* Reset state, in case we don't use something */
1642 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1643 ((drm_r300_cmd_header_t
*)rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1645 setup_vertex_shader_fragment(rmesa
, VSF_DEST_PROGRAM
, &(prog
->program
));
1648 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN1
, &(rmesa
->state
.vertex_shader
.unknown1
));
1649 setup_vertex_shader_fragment(rmesa
, VSF_DEST_UNKNOWN2
, &(rmesa
->state
.vertex_shader
.unknown2
));
1652 inst_count
=prog
->program
.length
/4 - 1;
1654 R300_STATECHANGE(rmesa
, pvs
);
1655 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
]=(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
)
1656 | (inst_count
/*pos_end*/ << R300_PVS_CNTL_1_POS_END_SHIFT
)
1657 | (inst_count
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1658 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
]=(0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
)
1659 | (param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1660 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
]=(0/*rmesa->state.vertex_shader.unknown_ptr2*/ << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
)
1661 | (inst_count
/*rmesa->state.vertex_shader.unknown_ptr3*/ << 0);
1663 /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
1664 so I leave it as a reminder */
1666 reg_start(R300_VAP_PVS_WAITIDLE
,0);
1671 extern void _tnl_UpdateFixedFunctionProgram( GLcontext
*ctx
);
1673 extern int future_hw_tcl_on
;
1674 void r300UpdateShaders(r300ContextPtr rmesa
)
1677 struct r300_vertex_program
*vp
;
1679 ctx
= rmesa
->radeon
.glCtx
;
1681 /* Disable tnl programs when doing software vertex programs.
1682 I can only hope this actually disables it at the right time. */
1683 ctx
->_MaintainTnlProgram
= hw_tcl_on
;
1685 if (rmesa
->NewGLState
&& hw_tcl_on
) {
1686 rmesa
->NewGLState
= 0;
1688 _tnl_UpdateFixedFunctionProgram(ctx
);
1690 vp
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1691 if (vp
->translated
== GL_FALSE
)
1692 r300_translate_vertex_shader(vp
);
1693 if (vp
->translated
== GL_FALSE
) {
1694 fprintf(stderr
, "Failing back to sw-tcl\n");
1695 hw_tcl_on
= future_hw_tcl_on
= 0;
1696 r300ResetHwState(rmesa
);
1704 void r300UpdateShaderStates(r300ContextPtr rmesa
)
1707 ctx
= rmesa
->radeon
.glCtx
;
1710 r300UpdateTextureState(ctx
);
1713 r300SetupPixelShader(rmesa
);
1714 r300_setup_textures(ctx
);
1716 r300SetupVertexShader(rmesa
);
1717 r300_setup_rs_unit(ctx
);
1720 /* This is probably wrong for some values, I need to test this
1721 * some more. Range checking would be a good idea also..
1723 * But it works for most things. I'll fix it later if someone
1724 * else with a better clue doesn't
1726 static unsigned int r300PackFloat24(float f
)
1730 unsigned int float24
= 0;
1732 if (f
== 0.0) return 0;
1734 mantissa
= frexpf(f
, &exponent
);
1739 mantissa
= mantissa
* -1.0;
1741 /* Handle exponent, bias of 63 */
1743 float24
|= (exponent
<< 16);
1744 /* Kill 7 LSB of mantissa */
1745 float24
|= (r300PackFloat32(mantissa
) & 0x7FFFFF) >> 7;
1750 void r300SetupPixelShader(r300ContextPtr rmesa
)
1752 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1753 struct r300_fragment_program
*rp
=
1754 (struct r300_fragment_program
*)
1755 (char *)ctx
->FragmentProgram
._Current
;
1758 if (!rp
) /* should only happenen once, just after context is created */
1761 r300_translate_fragment_shader(rp
);
1762 if (!rp
->translated
) {
1763 fprintf(stderr
, "%s: No valid fragment shader, exiting\n", __func__
);
1767 #define OUTPUT_FIELD(st, reg, field) \
1768 R300_STATECHANGE(rmesa, st); \
1769 for(i=0;i<=rp->alu_end;i++) \
1770 rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=rp->alu.inst[i].field;\
1771 rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmdpacket0(reg, rp->alu_end+1);
1773 OUTPUT_FIELD(fpi
[0], R300_PFS_INSTR0_0
, inst0
);
1774 OUTPUT_FIELD(fpi
[1], R300_PFS_INSTR1_0
, inst1
);
1775 OUTPUT_FIELD(fpi
[2], R300_PFS_INSTR2_0
, inst2
);
1776 OUTPUT_FIELD(fpi
[3], R300_PFS_INSTR3_0
, inst3
);
1779 R300_STATECHANGE(rmesa
, fp
);
1780 /* I just want to say, the way these nodes are stored.. weird.. */
1781 for (i
=0,k
=(4-(rp
->cur_node
+1));i
<4;i
++,k
++) {
1782 if (i
<(rp
->cur_node
+1)) {
1783 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+k
]=
1784 (rp
->node
[i
].alu_offset
<< R300_PFS_NODE_ALU_OFFSET_SHIFT
)
1785 | (rp
->node
[i
].alu_end
<< R300_PFS_NODE_ALU_END_SHIFT
)
1786 | (rp
->node
[i
].tex_offset
<< R300_PFS_NODE_TEX_OFFSET_SHIFT
)
1787 | (rp
->node
[i
].tex_end
<< R300_PFS_NODE_TEX_END_SHIFT
)
1788 | rp
->node
[i
].flags
; /* ( (k==3) ? R300_PFS_NODE_LAST_NODE : 0); */
1790 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+(3-i
)] = 0;
1795 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
]=
1797 | (rp
->first_node_has_tex
<<3);
1799 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
]=rp
->max_temp_idx
;
1801 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
]=
1802 (rp
->alu_offset
<< R300_PFS_CNTL_ALU_OFFSET_SHIFT
)
1803 | (rp
->alu_end
<< R300_PFS_CNTL_ALU_END_SHIFT
)
1804 | (rp
->tex_offset
<< R300_PFS_CNTL_TEX_OFFSET_SHIFT
)
1805 | (rp
->tex_end
<< R300_PFS_CNTL_TEX_END_SHIFT
);
1807 R300_STATECHANGE(rmesa
, fpp
);
1808 for(i
=0;i
<rp
->const_nr
;i
++){
1809 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+0]=r300PackFloat24(rp
->constant
[i
][0]);
1810 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+1]=r300PackFloat24(rp
->constant
[i
][1]);
1811 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+2]=r300PackFloat24(rp
->constant
[i
][2]);
1812 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+4*i
+3]=r300PackFloat24(rp
->constant
[i
][3]);
1814 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
]=cmdpacket0(R300_PFS_PARAM_0_X
, rp
->const_nr
*4);
1818 * Called by Mesa after an internal state update.
1820 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
1822 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1824 _swrast_InvalidateState(ctx
, new_state
);
1825 _swsetup_InvalidateState(ctx
, new_state
);
1826 _ac_InvalidateState(ctx
, new_state
);
1827 _tnl_InvalidateState(ctx
, new_state
);
1828 _ae_invalidate_state(ctx
, new_state
);
1830 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
1831 r300UpdateDrawBuffer(ctx
);
1834 /* Go inefficiency! */
1835 r300ResetHwState(r300
);
1838 if(new_state
& _NEW_ARRAY
)
1839 r300
->state
.VB
.lock_uptodate
= GL_FALSE
;
1841 r300
->NewGLState
|= new_state
;
1845 * Completely recalculates hardware state based on the Mesa state.
1847 void r300ResetHwState(r300ContextPtr r300
)
1849 GLcontext
* ctx
= r300
->radeon
.glCtx
;
1851 if (RADEON_DEBUG
& DEBUG_STATE
)
1852 fprintf(stderr
, "%s\n", __FUNCTION__
);
1854 /* This is a place to initialize registers which
1855 have bitfields accessed by different functions
1856 and not all bits are used */
1858 /* initialize similiar to r200 */
1859 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] = 0;
1860 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] =
1861 (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
1862 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
) |
1863 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
) |
1864 (R300_ZS_KEEP
<< R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
) |
1865 (R300_ZS_ALWAYS
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
) |
1866 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
) |
1867 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
) |
1868 (R300_ZS_KEEP
<< R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
);
1869 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] = 0x00ffff00;
1872 /* go and compute register values from GL state */
1874 r300UpdateWindow(ctx
);
1877 ctx
->Color
.ColorMask
[RCOMP
],
1878 ctx
->Color
.ColorMask
[GCOMP
],
1879 ctx
->Color
.ColorMask
[BCOMP
],
1880 ctx
->Color
.ColorMask
[ACOMP
]);
1882 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
1883 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
1884 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
1887 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
1888 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
1889 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0], ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
1890 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0], ctx
->Stencil
.ZFailFunc
[0], ctx
->Stencil
.ZPassFunc
[0]);
1892 r300UpdateCulling(ctx
);
1894 r300UpdateTextureState(ctx
);
1896 // r300_setup_routing(ctx, GL_TRUE);
1898 #if 0 /* Done in prior to rendering */
1899 if(hw_tcl_on
== GL_FALSE
){
1900 r300EmitArrays(ctx
, GL_TRUE
); /* Just do the routing */
1901 r300_setup_textures(ctx
);
1902 r300_setup_rs_unit(ctx
);
1904 r300SetupVertexShader(r300
);
1905 r300SetupPixelShader(r300
);
1909 r300_set_blend_state(ctx
);
1911 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
1912 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
1914 /* Initialize magic registers
1915 TODO : learn what they really do, or get rid of
1916 those we don't have to touch */
1917 r300
->hw
.unk2080
.cmd
[1] = 0x0030045A; //0x0030065a /* Dangerous */
1919 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
1920 | R300_VPORT_X_OFFSET_ENA
1921 | R300_VPORT_Y_SCALE_ENA
1922 | R300_VPORT_Y_OFFSET_ENA
1923 | R300_VPORT_Z_SCALE_ENA
1924 | R300_VPORT_Z_OFFSET_ENA
1926 r300
->hw
.vte
.cmd
[2] = 0x00000008;
1928 r300
->hw
.unk2134
.cmd
[1] = 0x00FFFFFF;
1929 r300
->hw
.unk2134
.cmd
[2] = 0x00000000;
1930 #ifdef MESA_BIG_ENDIAN
1931 r300
->hw
.unk2140
.cmd
[1] = 0x00000002;
1933 r300
->hw
.unk2140
.cmd
[1] = 0x00000000;
1936 #if 0 /* Done in setup routing */
1937 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[0].cmd
)->packet0
.count
= 1;
1938 r300
->hw
.vir
[0].cmd
[1] = 0x21030003;
1940 ((drm_r300_cmd_header_t
*)r300
->hw
.vir
[1].cmd
)->packet0
.count
= 1;
1941 r300
->hw
.vir
[1].cmd
[1] = 0xF688F688;
1943 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_0
] = 0x00000001;
1944 r300
->hw
.vic
.cmd
[R300_VIR_CNTL_1
] = 0x00000405;
1947 r300
->hw
.unk21DC
.cmd
[1] = 0xAAAAAAAA;
1949 r300
->hw
.unk221C
.cmd
[1] = R300_221C_NORMAL
;
1951 r300
->hw
.unk2220
.cmd
[1] = r300PackFloat32(1.0);
1952 r300
->hw
.unk2220
.cmd
[2] = r300PackFloat32(1.0);
1953 r300
->hw
.unk2220
.cmd
[3] = r300PackFloat32(1.0);
1954 r300
->hw
.unk2220
.cmd
[4] = r300PackFloat32(1.0);
1956 /* what about other chips than r300 or rv350??? */
1957 if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
)
1958 r300
->hw
.unk2288
.cmd
[1] = R300_2288_R300
;
1960 r300
->hw
.unk2288
.cmd
[1] = R300_2288_RV350
;
1963 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_0
] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
1964 | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT
;
1965 r300
->hw
.vof
.cmd
[R300_VOF_CNTL_1
] = 0; /* no textures */
1968 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] = 0;
1969 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] = 0;
1970 r300
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] = 0;
1973 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
1974 | R300_GB_LINE_STUFF_ENABLE
1975 | R300_GB_TRIANGLE_STUFF_ENABLE
/*| R300_GB_UNK31*/;
1977 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
1978 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
1979 if ((r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R300
) ||
1980 (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R350
))
1981 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
1982 | R300_GB_TILE_PIPE_COUNT_R300
1983 | R300_GB_TILE_SIZE_16
;
1984 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
)
1985 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
1986 | R300_GB_TILE_PIPE_COUNT_RV410
1987 | R300_GB_TILE_SIZE_16
;
1988 else if (r300
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
)
1989 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
1990 | R300_GB_TILE_PIPE_COUNT_R420
1991 | R300_GB_TILE_SIZE_16
;
1993 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] = R300_GB_TILE_ENABLE
1994 | R300_GB_TILE_PIPE_COUNT_RV300
1995 | R300_GB_TILE_SIZE_16
;
1996 /* set to 0 when fog is disabled? */
1997 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
1998 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = 0x00000000; /* No antialiasing */
2000 //r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
2002 r300
->hw
.unk4200
.cmd
[1] = r300PackFloat32(0.0);
2003 r300
->hw
.unk4200
.cmd
[2] = r300PackFloat32(0.0);
2004 r300
->hw
.unk4200
.cmd
[3] = r300PackFloat32(1.0);
2005 r300
->hw
.unk4200
.cmd
[4] = r300PackFloat32(1.0);
2007 r300
->hw
.unk4214
.cmd
[1] = 0x00050005;
2009 r300PointSize(ctx
, 0.0);
2011 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] = (6 << R300_POINTSIZE_X_SHIFT
) |
2012 (6 << R300_POINTSIZE_Y_SHIFT
);
2015 r300
->hw
.unk4230
.cmd
[1] = 0x18000006;
2016 r300
->hw
.unk4230
.cmd
[2] = 0x00020006;
2017 r300
->hw
.unk4230
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2019 r300LineWidth(ctx
, 0.0);
2021 r300
->hw
.unk4260
.cmd
[1] = 0;
2022 r300
->hw
.unk4260
.cmd
[2] = r300PackFloat32(0.0);
2023 r300
->hw
.unk4260
.cmd
[3] = r300PackFloat32(1.0);
2025 r300
->hw
.unk4274
.cmd
[1] = 0x00000002;
2026 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2027 r300
->hw
.unk4274
.cmd
[3] = 0x00000000;
2028 r300
->hw
.unk4274
.cmd
[4] = 0x00000000;
2030 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2031 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2032 r300
->hw
.unk4288
.cmd
[2] = 0x00000001;
2033 r300
->hw
.unk4288
.cmd
[3] = 0x00000000;
2034 r300
->hw
.unk42A0
.cmd
[1] = 0x00000000;
2036 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
, ctx
->Polygon
.OffsetUnits
);
2037 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2039 r300
->hw
.unk42C0
.cmd
[1] = 0x4B7FFFFF;
2040 r300
->hw
.unk42C0
.cmd
[2] = 0x00000000;
2043 r300
->hw
.unk43A4
.cmd
[1] = 0x0000001C;
2044 r300
->hw
.unk43A4
.cmd
[2] = 0x2DA49525;
2046 r300
->hw
.unk43E8
.cmd
[1] = 0x00FFFFFF;
2049 r300
->hw
.fp
.cmd
[R300_FP_CNTL0
] = 0;
2050 r300
->hw
.fp
.cmd
[R300_FP_CNTL1
] = 0;
2051 r300
->hw
.fp
.cmd
[R300_FP_CNTL2
] = 0;
2052 r300
->hw
.fp
.cmd
[R300_FP_NODE0
] = 0;
2053 r300
->hw
.fp
.cmd
[R300_FP_NODE1
] = 0;
2054 r300
->hw
.fp
.cmd
[R300_FP_NODE2
] = 0;
2055 r300
->hw
.fp
.cmd
[R300_FP_NODE3
] = 0;
2058 r300
->hw
.unk46A4
.cmd
[1] = 0x00001B01;
2059 r300
->hw
.unk46A4
.cmd
[2] = 0x00001B0F;
2060 r300
->hw
.unk46A4
.cmd
[3] = 0x00001B0F;
2061 r300
->hw
.unk46A4
.cmd
[4] = 0x00001B0F;
2062 r300
->hw
.unk46A4
.cmd
[5] = 0x00000001;
2065 for(i
= 1; i
<= 64; ++i
) {
2066 /* create NOP instructions */
2067 r300
->hw
.fpi
[0].cmd
[i
] = FP_INSTRC(MAD
, FP_ARGC(SRC0C_XYZ
), FP_ARGC(ONE
), FP_ARGC(ZERO
));
2068 r300
->hw
.fpi
[1].cmd
[i
] = FP_SELC(0,XYZ
,NO
,FP_TMP(0),0,0);
2069 r300
->hw
.fpi
[2].cmd
[i
] = FP_INSTRA(MAD
, FP_ARGA(SRC0A
), FP_ARGA(ONE
), FP_ARGA(ZERO
));
2070 r300
->hw
.fpi
[3].cmd
[i
] = FP_SELA(0,W
,NO
,FP_TMP(0),0,0);
2073 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2074 ctx
->Driver
.Fogfv( ctx
, GL_FOG_MODE
, NULL
);
2075 ctx
->Driver
.Fogfv( ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2076 ctx
->Driver
.Fogfv( ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2077 ctx
->Driver
.Fogfv( ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2078 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2079 ctx
->Driver
.Fogfv( ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2081 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
2082 r300
->hw
.unk4BD8
.cmd
[1] = 0;
2084 r300
->hw
.unk4E00
.cmd
[1] = 0;
2087 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = 0;
2088 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = 0;
2091 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2092 r300
->hw
.unk4E10
.cmd
[2] = 0;
2093 r300
->hw
.unk4E10
.cmd
[3] = 0;
2095 /* Again, r300ClearBuffer uses this */
2096 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = r300
->radeon
.state
.color
.drawOffset
+
2097 r300
->radeon
.radeonScreen
->fbLocation
;
2098 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.state
.color
.drawPitch
;
2100 if (r300
->radeon
.radeonScreen
->cpp
== 4)
2101 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
2103 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
2105 if (r300
->radeon
.sarea
->tiling_enabled
)
2106 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
2108 r300
->hw
.unk4E50
.cmd
[1] = 0;
2109 r300
->hw
.unk4E50
.cmd
[2] = 0;
2110 r300
->hw
.unk4E50
.cmd
[3] = 0;
2111 r300
->hw
.unk4E50
.cmd
[4] = 0;
2112 r300
->hw
.unk4E50
.cmd
[5] = 0;
2113 r300
->hw
.unk4E50
.cmd
[6] = 0;
2114 r300
->hw
.unk4E50
.cmd
[7] = 0;
2115 r300
->hw
.unk4E50
.cmd
[8] = 0;
2116 r300
->hw
.unk4E50
.cmd
[9] = 0;
2118 r300
->hw
.unk4E88
.cmd
[1] = 0;
2120 r300
->hw
.unk4EA0
.cmd
[1] = 0x00000000;
2121 r300
->hw
.unk4EA0
.cmd
[2] = 0xffffffff;
2123 switch (ctx
->Visual
.depthBits
) {
2125 r300
->hw
.unk4F10
.cmd
[1] = R300_DEPTH_FORMAT_16BIT_INT_Z
;
2128 r300
->hw
.unk4F10
.cmd
[1] = R300_DEPTH_FORMAT_24BIT_INT_Z
;
2131 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2132 ctx
->Visual
.depthBits
);
2137 //r300->hw.unk4F10.cmd[1] |= R300_DEPTH_FORMAT_UNK32;
2139 r300
->hw
.unk4F10
.cmd
[3] = 0x00000003;
2140 r300
->hw
.unk4F10
.cmd
[4] = 0x00000000;
2142 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
2143 r300
->radeon
.radeonScreen
->depthOffset
+
2144 r300
->radeon
.radeonScreen
->fbLocation
;
2145 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
2147 if (r300
->radeon
.sarea
->tiling_enabled
) {
2148 /* Turn off when clearing buffers ? */
2149 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_TILE_ENABLE
;
2151 if (ctx
->Visual
.depthBits
== 24)
2152 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_MICROTILE_ENABLE
;
2155 r300
->hw
.unk4F28
.cmd
[1] = 0;
2157 r300
->hw
.unk4F30
.cmd
[1] = 0;
2158 r300
->hw
.unk4F30
.cmd
[2] = 0;
2160 r300
->hw
.unk4F44
.cmd
[1] = 0;
2162 r300
->hw
.unk4F54
.cmd
[1] = 0;
2165 ((drm_r300_cmd_header_t
*)r300
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2166 for(i
= 1; i
< R300_VPI_CMDSIZE
; i
+= 4) {
2168 r300
->hw
.vpi
.cmd
[i
+0] = VP_OUT(ADD
,TMP
,0,XYZW
);
2169 r300
->hw
.vpi
.cmd
[i
+1] = VP_IN(TMP
,0);
2170 r300
->hw
.vpi
.cmd
[i
+2] = VP_ZERO();
2171 r300
->hw
.vpi
.cmd
[i
+3] = VP_ZERO();
2174 ((drm_r300_cmd_header_t
*)r300
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2175 for(i
= 1; i
< R300_VPP_CMDSIZE
; ++i
)
2176 r300
->hw
.vpp
.cmd
[i
] = 0;
2179 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2180 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2181 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2182 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2185 r300
->hw
.all_dirty
= GL_TRUE
;
2191 * Calculate initial hardware state and register state functions.
2192 * Assumes that the command buffer and state atoms have been
2193 * initialized already.
2195 void r300InitState(r300ContextPtr r300
)
2197 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2200 radeonInitState(&r300
->radeon
);
2202 switch (ctx
->Visual
.depthBits
) {
2204 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2205 depth_fmt
= R200_DEPTH_FORMAT_16BIT_INT_Z
;
2206 r300
->state
.stencil
.clear
= 0x00000000;
2209 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2210 depth_fmt
= R200_DEPTH_FORMAT_24BIT_INT_Z
;
2211 r300
->state
.stencil
.clear
= 0x00ff0000;
2214 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2215 ctx
->Visual
.depthBits
);
2219 /* Only have hw stencil when depth buffer is 24 bits deep */
2220 r300
->state
.stencil
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2221 ctx
->Visual
.depthBits
== 24);
2223 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2225 r300ResetHwState(r300
);
2228 static void r300RenderMode( GLcontext
*ctx
, GLenum mode
)
2230 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2236 * Initialize driver's state callback functions
2238 void r300InitStateFuncs(struct dd_function_table
* functions
)
2240 radeonInitStateFuncs(functions
);
2242 functions
->UpdateState
= r300InvalidateState
;
2243 functions
->AlphaFunc
= r300AlphaFunc
;
2244 functions
->BlendColor
= r300BlendColor
;
2245 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2246 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2247 functions
->Enable
= r300Enable
;
2248 functions
->ColorMask
= r300ColorMask
;
2249 functions
->DepthFunc
= r300DepthFunc
;
2250 functions
->DepthMask
= r300DepthMask
;
2251 functions
->CullFace
= r300CullFace
;
2252 functions
->Fogfv
= r300Fogfv
;
2253 functions
->FrontFace
= r300FrontFace
;
2254 functions
->ShadeModel
= r300ShadeModel
;
2256 /* Stencil related */
2257 functions
->ClearStencil
= r300ClearStencil
;
2258 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2259 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2260 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2262 /* Viewport related */
2263 functions
->Viewport
= r300Viewport
;
2264 functions
->DepthRange
= r300DepthRange
;
2265 functions
->PointSize
= r300PointSize
;
2266 functions
->LineWidth
= r300LineWidth
;
2268 functions
->PolygonOffset
= r300PolygonOffset
;
2269 functions
->PolygonMode
= r300PolygonMode
;
2271 functions
->RenderMode
= r300RenderMode
;