2 Copyright (C) The Weather Channel, Inc. 2002.
3 Copyright (C) 2004 Nicolai Haehnle.
6 The Weather Channel (TM) funded Tungsten Graphics to develop the
7 initial release of the Radeon 8500 driver under the XFree86 license.
8 This notice must be preserved.
10 Permission is hereby granted, free of charge, to any person obtaining
11 a copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sublicense, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial
20 portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
35 * \author Nicolai Haehnle <prefect_@gmx.net>
38 #include "main/glheader.h"
39 #include "main/state.h"
40 #include "main/imports.h"
41 #include "main/enums.h"
42 #include "main/macros.h"
43 #include "main/context.h"
45 #include "main/simple_list.h"
46 #include "main/api_arrayelt.h"
47 #include "main/texformat.h"
49 #include "swrast/swrast.h"
50 #include "swrast_setup/swrast_setup.h"
51 #include "shader/prog_parameter.h"
52 #include "shader/prog_statevars.h"
56 #include "r300_context.h"
57 #include "r300_ioctl.h"
58 #include "r300_state.h"
60 #include "r300_emit.h"
61 #include "r300_fragprog.h"
64 #include "drirenderbuffer.h"
66 extern int future_hw_tcl_on
;
67 extern void _tnl_UpdateFixedFunctionProgram(GLcontext
* ctx
);
69 static void r300BlendColor(GLcontext
* ctx
, const GLfloat cf
[4])
71 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
73 R300_STATECHANGE(rmesa
, blend_color
);
75 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
) {
76 GLuint r
= IROUND(cf
[0]*1023.0f
);
77 GLuint g
= IROUND(cf
[1]*1023.0f
);
78 GLuint b
= IROUND(cf
[2]*1023.0f
);
79 GLuint a
= IROUND(cf
[3]*1023.0f
);
81 rmesa
->hw
.blend_color
.cmd
[1] = r
| (a
<< 16);
82 rmesa
->hw
.blend_color
.cmd
[2] = b
| (g
<< 16);
85 CLAMPED_FLOAT_TO_UBYTE(color
[0], cf
[0]);
86 CLAMPED_FLOAT_TO_UBYTE(color
[1], cf
[1]);
87 CLAMPED_FLOAT_TO_UBYTE(color
[2], cf
[2]);
88 CLAMPED_FLOAT_TO_UBYTE(color
[3], cf
[3]);
90 rmesa
->hw
.blend_color
.cmd
[1] = PACK_COLOR_8888(color
[3], color
[0],
96 * Calculate the hardware blend factor setting. This same function is used
97 * for source and destination of both alpha and RGB.
100 * The hardware register value for the specified blend factor. This value
101 * will need to be shifted into the correct position for either source or
102 * destination factor.
105 * Since the two cases where source and destination are handled differently
106 * are essentially error cases, they should never happen. Determine if these
107 * cases can be removed.
109 static int blend_factor(GLenum factor
, GLboolean is_src
)
113 return R300_BLEND_GL_ZERO
;
116 return R300_BLEND_GL_ONE
;
119 return R300_BLEND_GL_DST_COLOR
;
121 case GL_ONE_MINUS_DST_COLOR
:
122 return R300_BLEND_GL_ONE_MINUS_DST_COLOR
;
125 return R300_BLEND_GL_SRC_COLOR
;
127 case GL_ONE_MINUS_SRC_COLOR
:
128 return R300_BLEND_GL_ONE_MINUS_SRC_COLOR
;
131 return R300_BLEND_GL_SRC_ALPHA
;
133 case GL_ONE_MINUS_SRC_ALPHA
:
134 return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
137 return R300_BLEND_GL_DST_ALPHA
;
139 case GL_ONE_MINUS_DST_ALPHA
:
140 return R300_BLEND_GL_ONE_MINUS_DST_ALPHA
;
142 case GL_SRC_ALPHA_SATURATE
:
143 return (is_src
) ? R300_BLEND_GL_SRC_ALPHA_SATURATE
:
146 case GL_CONSTANT_COLOR
:
147 return R300_BLEND_GL_CONST_COLOR
;
149 case GL_ONE_MINUS_CONSTANT_COLOR
:
150 return R300_BLEND_GL_ONE_MINUS_CONST_COLOR
;
152 case GL_CONSTANT_ALPHA
:
153 return R300_BLEND_GL_CONST_ALPHA
;
155 case GL_ONE_MINUS_CONSTANT_ALPHA
:
156 return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
159 fprintf(stderr
, "unknown blend factor %x\n", factor
);
160 return (is_src
) ? R300_BLEND_GL_ONE
: R300_BLEND_GL_ZERO
;
166 * Sets both the blend equation and the blend function.
167 * This is done in a single
168 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
169 * change the interpretation of the blend function.
170 * Also, make sure that blend function and blend equation are set to their
171 * default value if color blending is not enabled, since at least blend
172 * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results
173 * otherwise for unknown reasons.
176 /* helper function */
177 static void r300SetBlendCntl(r300ContextPtr r300
, int func
, int eqn
,
178 int cbits
, int funcA
, int eqnA
)
180 GLuint new_ablend
, new_cblend
;
184 "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n",
185 eqnA
, funcA
, eqn
, func
, cbits
);
187 new_ablend
= eqnA
| funcA
;
188 new_cblend
= eqn
| func
;
190 /* Some blend factor combinations don't seem to work when the
191 * BLEND_NO_SEPARATE bit is set.
193 * Especially problematic candidates are the ONE_MINUS_* flags,
194 * but I can't see a real pattern.
197 if (new_ablend
== new_cblend
) {
198 new_cblend
|= R300_DISCARD_SRC_PIXELS_SRC_ALPHA_0
;
203 if ((new_ablend
!= r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]) ||
204 (new_cblend
!= r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
])) {
205 R300_STATECHANGE(r300
, bld
);
206 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = new_ablend
;
207 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = new_cblend
;
211 static void r300SetBlendState(GLcontext
* ctx
)
213 r300ContextPtr r300
= R300_CONTEXT(ctx
);
214 int func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
215 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
216 int eqn
= R300_COMB_FCN_ADD_CLAMP
;
217 int funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
218 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
219 int eqnA
= R300_COMB_FCN_ADD_CLAMP
;
221 if (RGBA_LOGICOP_ENABLED(ctx
) || !ctx
->Color
.BlendEnabled
) {
222 r300SetBlendCntl(r300
, func
, eqn
, 0, func
, eqn
);
227 (blend_factor(ctx
->Color
.BlendSrcRGB
, GL_TRUE
) <<
228 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstRGB
,
230 R300_DST_BLEND_SHIFT
);
232 switch (ctx
->Color
.BlendEquationRGB
) {
234 eqn
= R300_COMB_FCN_ADD_CLAMP
;
237 case GL_FUNC_SUBTRACT
:
238 eqn
= R300_COMB_FCN_SUB_CLAMP
;
241 case GL_FUNC_REVERSE_SUBTRACT
:
242 eqn
= R300_COMB_FCN_RSUB_CLAMP
;
246 eqn
= R300_COMB_FCN_MIN
;
247 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
248 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
252 eqn
= R300_COMB_FCN_MAX
;
253 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
254 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
259 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
260 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
265 (blend_factor(ctx
->Color
.BlendSrcA
, GL_TRUE
) <<
266 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstA
,
268 R300_DST_BLEND_SHIFT
);
270 switch (ctx
->Color
.BlendEquationA
) {
272 eqnA
= R300_COMB_FCN_ADD_CLAMP
;
275 case GL_FUNC_SUBTRACT
:
276 eqnA
= R300_COMB_FCN_SUB_CLAMP
;
279 case GL_FUNC_REVERSE_SUBTRACT
:
280 eqnA
= R300_COMB_FCN_RSUB_CLAMP
;
284 eqnA
= R300_COMB_FCN_MIN
;
285 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
286 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
290 eqnA
= R300_COMB_FCN_MAX
;
291 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
292 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
297 "[%s:%u] Invalid A blend equation (0x%04x).\n",
298 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationA
);
302 r300SetBlendCntl(r300
,
304 (R300_SEPARATE_ALPHA_ENABLE
|
306 R300_ALPHA_BLEND_ENABLE
), funcA
, eqnA
);
309 static void r300BlendEquationSeparate(GLcontext
* ctx
,
310 GLenum modeRGB
, GLenum modeA
)
312 r300SetBlendState(ctx
);
315 static void r300BlendFuncSeparate(GLcontext
* ctx
,
316 GLenum sfactorRGB
, GLenum dfactorRGB
,
317 GLenum sfactorA
, GLenum dfactorA
)
319 r300SetBlendState(ctx
);
323 * Translate LogicOp enums into hardware representation.
324 * Both use a very logical bit-wise layout, but unfortunately the order
325 * of bits is reversed.
327 static GLuint
translate_logicop(GLenum logicop
)
329 GLuint bits
= logicop
- GL_CLEAR
;
330 bits
= ((bits
& 1) << 3) | ((bits
& 2) << 1) | ((bits
& 4) >> 1) | ((bits
& 8) >> 3);
331 return bits
<< R300_RB3D_ROPCNTL_ROP_SHIFT
;
335 * Used internally to update the r300->hw hardware state to match the
336 * current OpenGL state.
338 static void r300SetLogicOpState(GLcontext
*ctx
)
340 r300ContextPtr r300
= R300_CONTEXT(ctx
);
341 R300_STATECHANGE(r300
, rop
);
342 if (RGBA_LOGICOP_ENABLED(ctx
)) {
343 r300
->hw
.rop
.cmd
[1] = R300_RB3D_ROPCNTL_ROP_ENABLE
|
344 translate_logicop(ctx
->Color
.LogicOp
);
346 r300
->hw
.rop
.cmd
[1] = 0;
351 * Called by Mesa when an application program changes the LogicOp state
354 static void r300LogicOpcode(GLcontext
*ctx
, GLenum logicop
)
356 if (RGBA_LOGICOP_ENABLED(ctx
))
357 r300SetLogicOpState(ctx
);
360 static void r300ClipPlane( GLcontext
*ctx
, GLenum plane
, const GLfloat
*eq
)
362 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
366 /* no VAP UCP on non-TCL chipsets */
367 if (!(rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
370 p
= (GLint
) plane
- (GLint
) GL_CLIP_PLANE0
;
371 ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
373 R300_STATECHANGE( rmesa
, vpucp
[p
] );
374 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_X
] = ip
[0];
375 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Y
] = ip
[1];
376 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Z
] = ip
[2];
377 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_W
] = ip
[3];
380 static void r300SetClipPlaneState(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
382 r300ContextPtr r300
= R300_CONTEXT(ctx
);
385 /* no VAP UCP on non-TCL chipsets */
386 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
389 p
= cap
- GL_CLIP_PLANE0
;
390 R300_STATECHANGE(r300
, vap_clip_cntl
);
392 r300
->hw
.vap_clip_cntl
.cmd
[1] |= (R300_VAP_UCP_ENABLE_0
<< p
);
393 r300ClipPlane(ctx
, cap
, NULL
);
395 r300
->hw
.vap_clip_cntl
.cmd
[1] &= ~(R300_VAP_UCP_ENABLE_0
<< p
);
400 * Update our tracked culling state based on Mesa's state.
402 static void r300UpdateCulling(GLcontext
* ctx
)
404 r300ContextPtr r300
= R300_CONTEXT(ctx
);
407 if (ctx
->Polygon
.CullFlag
) {
408 switch (ctx
->Polygon
.CullFaceMode
) {
410 val
= R300_CULL_FRONT
;
413 val
= R300_CULL_BACK
;
415 case GL_FRONT_AND_BACK
:
416 val
= R300_CULL_FRONT
| R300_CULL_BACK
;
423 switch (ctx
->Polygon
.FrontFace
) {
425 val
|= R300_FRONT_FACE_CW
;
428 val
|= R300_FRONT_FACE_CCW
;
434 R300_STATECHANGE(r300
, cul
);
435 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
438 static void r300SetPolygonOffsetState(GLcontext
* ctx
, GLboolean state
)
440 r300ContextPtr r300
= R300_CONTEXT(ctx
);
442 R300_STATECHANGE(r300
, occlusion_cntl
);
444 r300
->hw
.occlusion_cntl
.cmd
[1] |= (3 << 0);
446 r300
->hw
.occlusion_cntl
.cmd
[1] &= ~(3 << 0);
450 static GLboolean
current_fragment_program_writes_depth(GLcontext
* ctx
)
452 r300ContextPtr r300
= R300_CONTEXT(ctx
);
454 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
455 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
456 (char *)ctx
->FragmentProgram
._Current
;
457 return (fp
&& fp
->WritesDepth
);
459 struct r500_fragment_program
* fp
=
460 (struct r500_fragment_program
*)(char*)
461 ctx
->FragmentProgram
._Current
;
462 return (fp
&& fp
->writes_depth
);
466 static void r300SetEarlyZState(GLcontext
* ctx
)
468 r300ContextPtr r300
= R300_CONTEXT(ctx
);
469 GLuint topZ
= R300_ZTOP_ENABLE
;
471 if (ctx
->Color
.AlphaEnabled
&& ctx
->Color
.AlphaFunc
!= GL_ALWAYS
)
472 topZ
= R300_ZTOP_DISABLE
;
473 if (current_fragment_program_writes_depth(ctx
))
474 topZ
= R300_ZTOP_DISABLE
;
476 if (topZ
!= r300
->hw
.zstencil_format
.cmd
[2]) {
477 /* Note: This completely reemits the stencil format.
478 * I have not tested whether this is strictly necessary,
479 * or if emitting a write to ZB_ZTOP is enough.
481 R300_STATECHANGE(r300
, zstencil_format
);
482 r300
->hw
.zstencil_format
.cmd
[2] = topZ
;
486 static void r300SetAlphaState(GLcontext
* ctx
)
488 r300ContextPtr r300
= R300_CONTEXT(ctx
);
490 uint32_t pp_misc
= 0x0;
491 GLboolean really_enabled
= ctx
->Color
.AlphaEnabled
;
493 CLAMPED_FLOAT_TO_UBYTE(refByte
, ctx
->Color
.AlphaRef
);
495 switch (ctx
->Color
.AlphaFunc
) {
497 pp_misc
|= R300_FG_ALPHA_FUNC_NEVER
;
500 pp_misc
|= R300_FG_ALPHA_FUNC_LESS
;
503 pp_misc
|= R300_FG_ALPHA_FUNC_EQUAL
;
506 pp_misc
|= R300_FG_ALPHA_FUNC_LE
;
509 pp_misc
|= R300_FG_ALPHA_FUNC_GREATER
;
512 pp_misc
|= R300_FG_ALPHA_FUNC_NOTEQUAL
;
515 pp_misc
|= R300_FG_ALPHA_FUNC_GE
;
518 /*pp_misc |= FG_ALPHA_FUNC_ALWAYS; */
519 really_enabled
= GL_FALSE
;
523 if (really_enabled
) {
524 pp_misc
|= R300_FG_ALPHA_FUNC_ENABLE
;
525 pp_misc
|= R500_FG_ALPHA_FUNC_8BIT
;
526 pp_misc
|= (refByte
& R300_FG_ALPHA_FUNC_VAL_MASK
);
531 R300_STATECHANGE(r300
, at
);
532 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
533 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
535 r300SetEarlyZState(ctx
);
538 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
542 r300SetAlphaState(ctx
);
545 static int translate_func(int func
)
549 return R300_ZS_NEVER
;
553 return R300_ZS_EQUAL
;
555 return R300_ZS_LEQUAL
;
557 return R300_ZS_GREATER
;
559 return R300_ZS_NOTEQUAL
;
561 return R300_ZS_GEQUAL
;
563 return R300_ZS_ALWAYS
;
568 static void r300SetDepthState(GLcontext
* ctx
)
570 r300ContextPtr r300
= R300_CONTEXT(ctx
);
572 R300_STATECHANGE(r300
, zs
);
573 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_STENCIL_ENABLE
|R300_STENCIL_FRONT_BACK
;
574 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~(R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
);
576 if (ctx
->Depth
.Test
) {
577 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_Z_ENABLE
;
579 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_Z_WRITE_ENABLE
;
580 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
581 translate_func(ctx
->Depth
.Func
) << R300_Z_FUNC_SHIFT
;
584 r300SetEarlyZState(ctx
);
587 static void r300SetStencilState(GLcontext
* ctx
, GLboolean state
)
589 r300ContextPtr r300
= R300_CONTEXT(ctx
);
591 if (r300
->radeon
.state
.stencil
.hwBuffer
) {
592 R300_STATECHANGE(r300
, zs
);
594 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
597 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
598 ~R300_STENCIL_ENABLE
;
602 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
607 static void r300UpdatePolygonMode(GLcontext
* ctx
)
609 r300ContextPtr r300
= R300_CONTEXT(ctx
);
610 uint32_t hw_mode
= R300_GA_POLY_MODE_DISABLE
;
612 /* Only do something if a polygon mode is wanted, default is GL_FILL */
613 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
614 ctx
->Polygon
.BackMode
!= GL_FILL
) {
617 /* Handle GL_CW (clock wise and GL_CCW (counter clock wise)
618 * correctly by selecting the correct front and back face
620 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
621 f
= ctx
->Polygon
.FrontMode
;
622 b
= ctx
->Polygon
.BackMode
;
624 f
= ctx
->Polygon
.BackMode
;
625 b
= ctx
->Polygon
.FrontMode
;
628 /* Enable polygon mode */
629 hw_mode
|= R300_GA_POLY_MODE_DUAL
;
633 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_LINE
;
636 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_POINT
;
639 hw_mode
|= R300_GA_POLY_MODE_FRONT_PTYPE_TRI
;
645 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_LINE
;
648 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_POINT
;
651 hw_mode
|= R300_GA_POLY_MODE_BACK_PTYPE_TRI
;
656 if (r300
->hw
.polygon_mode
.cmd
[1] != hw_mode
) {
657 R300_STATECHANGE(r300
, polygon_mode
);
658 r300
->hw
.polygon_mode
.cmd
[1] = hw_mode
;
661 r300
->hw
.polygon_mode
.cmd
[2] = 0x00000001;
662 r300
->hw
.polygon_mode
.cmd
[3] = 0x00000000;
666 * Change the culling mode.
668 * \note Mesa already filters redundant calls to this function.
670 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
674 r300UpdateCulling(ctx
);
678 * Change the polygon orientation.
680 * \note Mesa already filters redundant calls to this function.
682 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
686 r300UpdateCulling(ctx
);
687 r300UpdatePolygonMode(ctx
);
691 * Change the depth testing function.
693 * \note Mesa already filters redundant calls to this function.
695 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
698 r300SetDepthState(ctx
);
702 * Enable/Disable depth writing.
704 * \note Mesa already filters redundant calls to this function.
706 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
709 r300SetDepthState(ctx
);
713 * Handle glColorMask()
715 static void r300ColorMask(GLcontext
* ctx
,
716 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
718 r300ContextPtr r300
= R300_CONTEXT(ctx
);
719 int mask
= (r
? RB3D_COLOR_CHANNEL_MASK_RED_MASK0
: 0) |
720 (g
? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0
: 0) |
721 (b
? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0
: 0) |
722 (a
? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0
: 0);
724 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
725 R300_STATECHANGE(r300
, cmk
);
726 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
730 /* =============================================================
733 static void r300Fogfv(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
735 r300ContextPtr r300
= R300_CONTEXT(ctx
);
739 } fogScale
, fogStart
;
743 fogScale
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
];
744 fogStart
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_START
];
748 switch (ctx
->Fog
.Mode
) {
750 R300_STATECHANGE(r300
, fogs
);
751 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
753 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
754 R300_FG_FOG_BLEND_FN_LINEAR
;
756 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
761 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
763 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
768 R300_STATECHANGE(r300
, fogs
);
769 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
771 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
772 R300_FG_FOG_BLEND_FN_EXP
;
773 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
777 R300_STATECHANGE(r300
, fogs
);
778 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
780 cmd
[R300_FOGS_STATE
] & ~R300_FG_FOG_BLEND_FN_MASK
) |
781 R300_FG_FOG_BLEND_FN_EXP2
;
782 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
790 switch (ctx
->Fog
.Mode
) {
792 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
796 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
804 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
805 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
810 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
812 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
818 R300_STATECHANGE(r300
, fogc
);
819 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] =
820 (GLuint
) (ctx
->Fog
.Color
[0] * 1023.0F
) & 0x3FF;
821 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] =
822 (GLuint
) (ctx
->Fog
.Color
[1] * 1023.0F
) & 0x3FF;
823 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] =
824 (GLuint
) (ctx
->Fog
.Color
[2] * 1023.0F
) & 0x3FF;
826 case GL_FOG_COORD_SRC
:
832 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
833 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
834 R300_STATECHANGE(r300
, fogp
);
835 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
836 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
840 static void r300SetFogState(GLcontext
* ctx
, GLboolean state
)
842 r300ContextPtr r300
= R300_CONTEXT(ctx
);
844 R300_STATECHANGE(r300
, fogs
);
846 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] |= R300_FG_FOG_BLEND_ENABLE
;
848 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
849 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
850 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
851 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
852 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
854 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] &= ~R300_FG_FOG_BLEND_ENABLE
;
858 /* =============================================================
861 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
863 r300ContextPtr r300
= R300_CONTEXT(ctx
);
864 /* same size limits for AA, non-AA points */
865 size
= CLAMP(size
, ctx
->Const
.MinPointSize
, ctx
->Const
.MaxPointSize
);
867 R300_STATECHANGE(r300
, ps
);
868 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
869 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
870 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
873 static void r300PointParameter(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
875 r300ContextPtr r300
= R300_CONTEXT(ctx
);
878 case GL_POINT_SIZE_MIN
:
879 R300_STATECHANGE(r300
, ga_point_minmax
);
880 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MIN_MASK
;
881 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MinSize
* 6.0);
883 case GL_POINT_SIZE_MAX
:
884 R300_STATECHANGE(r300
, ga_point_minmax
);
885 r300
->hw
.ga_point_minmax
.cmd
[1] &= ~R300_GA_POINT_MINMAX_MAX_MASK
;
886 r300
->hw
.ga_point_minmax
.cmd
[1] |= (GLuint
)(ctx
->Point
.MaxSize
* 6.0)
887 << R300_GA_POINT_MINMAX_MAX_SHIFT
;
889 case GL_POINT_DISTANCE_ATTENUATION
:
891 case GL_POINT_FADE_THRESHOLD_SIZE
:
898 /* =============================================================
901 static void r300LineWidth(GLcontext
* ctx
, GLfloat widthf
)
903 r300ContextPtr r300
= R300_CONTEXT(ctx
);
905 widthf
= CLAMP(widthf
,
906 ctx
->Const
.MinPointSize
,
907 ctx
->Const
.MaxPointSize
);
908 R300_STATECHANGE(r300
, lcntl
);
909 r300
->hw
.lcntl
.cmd
[1] =
910 R300_LINE_CNT_HO
| R300_LINE_CNT_VE
| (int)(widthf
* 6.0);
913 static void r300PolygonMode(GLcontext
* ctx
, GLenum face
, GLenum mode
)
918 r300UpdatePolygonMode(ctx
);
921 /* =============================================================
925 static int translate_stencil_op(int op
)
933 return R300_ZS_REPLACE
;
938 case GL_INCR_WRAP_EXT
:
939 return R300_ZS_INCR_WRAP
;
940 case GL_DECR_WRAP_EXT
:
941 return R300_ZS_DECR_WRAP
;
943 return R300_ZS_INVERT
;
945 WARN_ONCE("Do not know how to translate stencil op");
951 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
953 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
955 R300_STATECHANGE(rmesa
, shade
);
956 rmesa
->hw
.shade
.cmd
[1] = 0x00000002;
959 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
962 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
967 rmesa
->hw
.shade
.cmd
[3] = 0x00000000;
968 rmesa
->hw
.shade
.cmd
[4] = 0x00000000;
971 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
972 GLenum func
, GLint ref
, GLuint mask
)
974 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
976 ((ctx
->Stencil
.Ref
[0] & 0xff) << R300_STENCILREF_SHIFT
)
977 | ((ctx
->Stencil
.ValueMask
[0] & 0xff) << R300_STENCILMASK_SHIFT
);
978 const unsigned back
= ctx
->Stencil
._BackFace
;
981 R300_STATECHANGE(rmesa
, zs
);
982 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_STENCIL_FRONT_BACK
;
983 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~((R300_ZS_MASK
<<
984 R300_S_FRONT_FUNC_SHIFT
)
986 R300_S_BACK_FUNC_SHIFT
));
988 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
989 ~((R300_STENCILREF_MASK
<< R300_STENCILREF_SHIFT
) |
990 (R300_STENCILREF_MASK
<< R300_STENCILMASK_SHIFT
));
992 flag
= translate_func(ctx
->Stencil
.Function
[0]);
993 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
994 (flag
<< R300_S_FRONT_FUNC_SHIFT
);
996 flag
= translate_func(ctx
->Stencil
.Function
[back
]);
998 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
999 (flag
<< R300_S_BACK_FUNC_SHIFT
);
1000 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
1003 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
1005 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1007 R300_STATECHANGE(rmesa
, zs
);
1008 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
1009 ~(R300_STENCILREF_MASK
<<
1010 R300_STENCILWRITEMASK_SHIFT
);
1011 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |=
1013 WriteMask
[0] & R300_STENCILREF_MASK
) <<
1014 R300_STENCILWRITEMASK_SHIFT
;
1017 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
,
1018 GLenum fail
, GLenum zfail
, GLenum zpass
)
1020 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1021 const unsigned back
= ctx
->Stencil
._BackFace
;
1023 R300_STATECHANGE(rmesa
, zs
);
1024 /* It is easier to mask what's left.. */
1025 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
1026 (R300_ZS_MASK
<< R300_Z_FUNC_SHIFT
) |
1027 (R300_ZS_MASK
<< R300_S_FRONT_FUNC_SHIFT
) |
1028 (R300_ZS_MASK
<< R300_S_BACK_FUNC_SHIFT
);
1030 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1031 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
1032 R300_S_FRONT_SFAIL_OP_SHIFT
)
1033 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
1034 R300_S_FRONT_ZFAIL_OP_SHIFT
)
1035 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
1036 R300_S_FRONT_ZPASS_OP_SHIFT
);
1038 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
1039 (translate_stencil_op(ctx
->Stencil
.FailFunc
[back
]) <<
1040 R300_S_BACK_SFAIL_OP_SHIFT
)
1041 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[back
]) <<
1042 R300_S_BACK_ZFAIL_OP_SHIFT
)
1043 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[back
]) <<
1044 R300_S_BACK_ZPASS_OP_SHIFT
);
1047 /* =============================================================
1048 * Window position and viewport transformation
1052 * To correctly position primitives:
1054 #define SUBPIXEL_X 0.125
1055 #define SUBPIXEL_Y 0.125
1057 static void r300UpdateWindow(GLcontext
* ctx
)
1059 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1060 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
1061 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
1062 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
1063 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1065 GLfloat sx
= v
[MAT_SX
];
1066 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1067 GLfloat sy
= -v
[MAT_SY
];
1068 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1069 GLfloat sz
= v
[MAT_SZ
] * rmesa
->radeon
.state
.depth
.scale
;
1070 GLfloat tz
= v
[MAT_TZ
] * rmesa
->radeon
.state
.depth
.scale
;
1072 radeon_firevertices(&rmesa
->radeon
);
1073 R300_STATECHANGE(rmesa
, vpt
);
1075 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
1076 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1077 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
1078 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1079 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
1080 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
1083 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
1084 GLsizei width
, GLsizei height
)
1086 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1087 __DRIcontext
*driContext
= rmesa
->radeon
.dri
.context
;
1088 /* Don't pipeline viewport changes, conflict with window offset
1089 * setting below. Could apply deltas to rescue pipelined viewport
1090 * values, or keep the originals hanging around.
1092 if (rmesa
->radeon
.radeonScreen
->driScreen
->dri2
.enabled
) {
1093 radeon_update_renderbuffers(driContext
, driContext
->driDrawablePriv
);
1094 if (driContext
->driDrawablePriv
!= driContext
->driReadablePriv
) {
1095 radeon_update_renderbuffers(driContext
,
1096 driContext
->driReadablePriv
);
1099 r300UpdateWindow(ctx
);
1102 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
1104 r300UpdateWindow(ctx
);
1107 void r300UpdateViewportOffset(GLcontext
* ctx
)
1109 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1110 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
) rmesa
)->dri
.drawable
;
1111 GLfloat xoffset
= (GLfloat
) dPriv
->x
;
1112 GLfloat yoffset
= (GLfloat
) dPriv
->y
+ dPriv
->h
;
1113 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1115 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
1116 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
1118 if (rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
1119 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
)) {
1120 /* Note: this should also modify whatever data the context reset
1123 R300_STATECHANGE(rmesa
, vpt
);
1124 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
1125 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
1129 radeonUpdateScissor(ctx
);
1133 * Tell the card where to render (offset, pitch).
1134 * Effected by glDrawBuffer, etc
1136 void r300UpdateDrawBuffer(GLcontext
* ctx
)
1138 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1139 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
1140 struct radeon_renderbuffer
*rrb
;
1142 if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_FRONT_LEFT
) {
1145 (void *) fb
->Attachment
[BUFFER_FRONT_LEFT
].Renderbuffer
;
1146 } else if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_BACK_LEFT
) {
1148 rrb
= (void *) fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
;
1150 /* drawing to multiple buffers, or none */
1157 R300_STATECHANGE(rmesa
, cb
);
1161 r300FetchStateParameter(GLcontext
* ctx
,
1162 const gl_state_index state
[STATE_LENGTH
],
1165 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1168 case STATE_INTERNAL
:
1170 case STATE_R300_WINDOW_DIMENSION
:
1171 value
[0] = r300
->radeon
.dri
.drawable
->w
* 0.5f
; /* width*0.5 */
1172 value
[1] = r300
->radeon
.dri
.drawable
->h
* 0.5f
; /* height*0.5 */
1173 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1174 value
[3] = 1.0F
; /* not used */
1177 case STATE_R300_TEXRECT_FACTOR
:{
1178 struct gl_texture_object
*t
=
1179 ctx
->Texture
.Unit
[state
[2]].CurrentRect
;
1181 if (t
&& t
->Image
[0][t
->BaseLevel
]) {
1182 struct gl_texture_image
*image
=
1183 t
->Image
[0][t
->BaseLevel
];
1184 value
[0] = 1.0 / image
->Width2
;
1185 value
[1] = 1.0 / image
->Height2
;
1206 * Update R300's own internal state parameters.
1207 * For now just STATE_R300_WINDOW_DIMENSION
1209 void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1211 struct r300_fragment_program
*fp
;
1212 struct gl_program_parameter_list
*paramList
;
1215 if (!(new_state
& (_NEW_BUFFERS
| _NEW_PROGRAM
)))
1218 fp
= (struct r300_fragment_program
*)ctx
->FragmentProgram
._Current
;
1222 paramList
= fp
->mesa_program
.Base
.Parameters
;
1227 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1228 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
) {
1229 r300FetchStateParameter(ctx
,
1230 paramList
->Parameters
[i
].
1232 paramList
->ParameterValues
[i
]);
1237 /* =============================================================
1240 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1242 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1243 GLfloat constant
= units
;
1245 switch (ctx
->Visual
.depthBits
) {
1256 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1258 R300_STATECHANGE(rmesa
, zbs
);
1259 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1260 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1261 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1262 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1265 /* Routing and texture-related */
1267 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1268 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1269 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1270 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1271 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1272 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1273 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1274 * combinations where only one of them is nearest.
1276 static unsigned long gen_fixed_filter(unsigned long f
)
1278 unsigned long mag
, min
, needs_fixing
= 0;
1281 /* We ignore MIRROR bit so we dont have to do everything twice */
1282 if ((f
& ((7 - 1) << R300_TX_WRAP_S_SHIFT
)) ==
1283 (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)) {
1286 if ((f
& ((7 - 1) << R300_TX_WRAP_T_SHIFT
)) ==
1287 (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)) {
1290 if ((f
& ((7 - 1) << R300_TX_WRAP_R_SHIFT
)) ==
1291 (R300_TX_CLAMP
<< R300_TX_WRAP_R_SHIFT
)) {
1298 mag
= f
& R300_TX_MAG_FILTER_MASK
;
1299 min
= f
& (R300_TX_MIN_FILTER_MASK
|R300_TX_MIN_FILTER_MIP_MASK
);
1301 /* TODO: Check for anisto filters too */
1302 if ((mag
!= R300_TX_MAG_FILTER_NEAREST
)
1303 && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1306 /* r300 cant handle these modes hence we force nearest to linear */
1307 if ((mag
== R300_TX_MAG_FILTER_NEAREST
)
1308 && (min
!= R300_TX_MIN_FILTER_NEAREST
)) {
1309 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1310 f
|= R300_TX_MAG_FILTER_LINEAR
;
1314 if ((min
== R300_TX_MIN_FILTER_NEAREST
)
1315 && (mag
!= R300_TX_MAG_FILTER_NEAREST
)) {
1316 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1317 f
|= R300_TX_MIN_FILTER_LINEAR
;
1321 /* Both are nearest */
1322 if (needs_fixing
& 1) {
1323 f
&= ~((7 - 1) << R300_TX_WRAP_S_SHIFT
);
1324 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1326 if (needs_fixing
& 2) {
1327 f
&= ~((7 - 1) << R300_TX_WRAP_T_SHIFT
);
1328 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1330 if (needs_fixing
& 4) {
1331 f
&= ~((7 - 1) << R300_TX_WRAP_R_SHIFT
);
1332 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_R_SHIFT
;
1337 static void r300SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1339 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1341 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1342 (char *)ctx
->FragmentProgram
._Current
;
1343 struct r300_fragment_program_code
*code
= &fp
->code
;
1345 R300_STATECHANGE(r300
, fpt
);
1347 for (i
= 0; i
< code
->tex
.length
; i
++) {
1352 unit
= code
->tex
.inst
[i
] >> R300_TEX_ID_SHIFT
;
1355 val
= code
->tex
.inst
[i
];
1356 val
&= ~R300_TEX_ID_MASK
;
1359 (val
& R300_TEX_INST_MASK
) >> R300_TEX_INST_SHIFT
;
1360 if (opcode
== R300_TEX_OP_KIL
) {
1361 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1363 if (tmu_mappings
[unit
] >= 0) {
1365 tmu_mappings
[unit
] <<
1367 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1369 // We get here when the corresponding texture image is incomplete
1370 // (e.g. incomplete mipmaps etc.)
1371 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1376 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] =
1377 cmdpacket0(r300
->radeon
.radeonScreen
,
1378 R300_US_TEX_INST_0
, code
->tex
.length
);
1381 static void r500SetupFragmentShaderTextures(GLcontext
*ctx
, int *tmu_mappings
)
1384 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
1385 (char *)ctx
->FragmentProgram
._Current
;
1386 struct r500_fragment_program_code
*code
= &fp
->code
;
1388 /* find all the texture instructions and relocate the texture units */
1389 for (i
= 0; i
< code
->inst_end
+ 1; i
++) {
1390 if ((code
->inst
[i
].inst0
& 0x3) == R500_INST_TYPE_TEX
) {
1392 int unit
, opcode
, new_unit
;
1394 val
= code
->inst
[i
].inst1
;
1396 unit
= (val
>> 16) & 0xf;
1398 val
&= ~(0xf << 16);
1400 opcode
= val
& (0x7 << 22);
1401 if (opcode
== R500_TEX_INST_TEXKILL
) {
1404 if (tmu_mappings
[unit
] >= 0) {
1405 new_unit
= tmu_mappings
[unit
];
1410 val
|= R500_TEX_ID(new_unit
);
1411 code
->inst
[i
].inst1
= val
;
1416 static GLuint
translate_lod_bias(GLfloat bias
)
1418 GLint b
= (int)(bias
*32);
1421 else if (b
< -(1 << 9))
1423 return (((GLuint
)b
) << R300_LOD_BIAS_SHIFT
) & R300_LOD_BIAS_MASK
;
1426 static void r300SetupTextures(GLcontext
* ctx
)
1429 struct radeon_tex_obj
*t
;
1430 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1432 int last_hw_tmu
= -1; /* -1 translates into no setup costs for fields */
1433 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1, };
1434 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1435 (char *)ctx
->FragmentProgram
._Current
;
1437 R300_STATECHANGE(r300
, txe
);
1438 R300_STATECHANGE(r300
, tex
.filter
);
1439 R300_STATECHANGE(r300
, tex
.filter_1
);
1440 R300_STATECHANGE(r300
, tex
.size
);
1441 R300_STATECHANGE(r300
, tex
.format
);
1442 R300_STATECHANGE(r300
, tex
.pitch
);
1443 R300_STATECHANGE(r300
, tex
.offset
);
1444 R300_STATECHANGE(r300
, tex
.chroma_key
);
1445 R300_STATECHANGE(r300
, tex
.border_color
);
1447 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] = 0x0;
1449 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1450 if (RADEON_DEBUG
& DEBUG_STATE
)
1451 fprintf(stderr
, "mtu=%d\n", mtu
);
1453 if (mtu
> R300_MAX_TEXTURE_UNITS
) {
1455 "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1456 mtu
, R300_MAX_TEXTURE_UNITS
);
1460 /* We cannot let disabled tmu offsets pass DRM */
1461 for (i
= 0; i
< mtu
; i
++) {
1462 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
1463 tmu_mappings
[i
] = hw_tmu
;
1465 t
= radeon_tex_obj(ctx
->Texture
.Unit
[i
]._Current
);
1469 if ((t
->pp_txformat
& 0xffffff00) == 0xffffff00) {
1471 ("unknown texture format (entry %x) encountered. Help me !\n",
1472 t
->pp_txformat
& 0xff);
1475 if (RADEON_DEBUG
& DEBUG_STATE
)
1477 "Activating texture unit %d\n", i
);
1479 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1481 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+
1483 gen_fixed_filter(t
->pp_txfilter
) | (hw_tmu
<< 28);
1484 /* Note: There is a LOD bias per texture unit and a LOD bias
1485 * per texture object. We add them here to get the correct behaviour.
1486 * (The per-texture object LOD bias was introduced in OpenGL 1.4
1487 * and is not present in the EXT_texture_object extension).
1489 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1491 translate_lod_bias(ctx
->Texture
.Unit
[i
].LodBias
+ t
->base
.LodBias
);
1492 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1494 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+
1495 hw_tmu
] = t
->pp_txformat
;
1496 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1498 r300
->hw
.textures
[hw_tmu
] = t
;
1500 if (t
->tile_bits
& R300_TXO_MACRO_TILE
) {
1501 WARN_ONCE("macro tiling enabled!\n");
1504 if (t
->tile_bits
& R300_TXO_MICRO_TILE
) {
1505 WARN_ONCE("micro tiling enabled!\n");
1508 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_VALUE_0
+
1510 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+
1514 last_hw_tmu
= hw_tmu
;
1520 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1521 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FILTER0_0
, last_hw_tmu
+ 1);
1522 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] =
1523 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1524 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] =
1525 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1526 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] =
1527 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1528 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] =
1529 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FORMAT2_0
, last_hw_tmu
+ 1);
1530 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] =
1531 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1532 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] =
1533 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1534 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] =
1535 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1537 if (!fp
) /* should only happenen once, just after context is created */
1540 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
1541 if (fp
->mesa_program
.UsesKill
&& last_hw_tmu
< 0) {
1542 // The KILL operation requires the first texture unit
1544 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= 1;
1545 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
] = 0;
1546 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1547 cmdpacket0(r300
->radeon
.radeonScreen
, R300_TX_FILTER0_0
, 1);
1549 r300SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1551 r500SetupFragmentShaderTextures(ctx
, tmu_mappings
);
1553 if (RADEON_DEBUG
& DEBUG_STATE
)
1554 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n",
1555 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1558 union r300_outputs_written
{
1559 GLuint vp_outputs
; /* hw_tcl_on */
1560 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1563 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1564 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1565 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1567 static void r300SetupRSUnit(GLcontext
* ctx
)
1569 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1570 /* I'm still unsure if these are needed */
1571 GLuint interp_col
[8];
1572 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1573 struct vertex_buffer
*VB
= &tnl
->vb
;
1574 union r300_outputs_written OutputsWritten
;
1576 int fp_reg
, high_rr
;
1578 int rs_tex_count
= 0, rs_col_count
= 0;
1581 memset(interp_col
, 0, sizeof(interp_col
));
1584 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1586 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1588 if (ctx
->FragmentProgram
._Current
)
1589 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1591 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1592 return; /* This should only ever happen once.. */
1595 R300_STATECHANGE(r300
, ri
);
1596 R300_STATECHANGE(r300
, rc
);
1597 R300_STATECHANGE(r300
, rr
);
1599 fp_reg
= col_interp_nr
= high_rr
= 0;
1601 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1603 if (InputsRead
& FRAG_BIT_WPOS
) {
1604 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1605 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1608 if (i
== ctx
->Const
.MaxTextureUnits
) {
1609 fprintf(stderr
, "\tno free texcoord found...\n");
1613 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1614 InputsRead
&= ~FRAG_BIT_WPOS
;
1617 if (InputsRead
& FRAG_BIT_COL0
) {
1618 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1619 interp_col
[0] |= R300_RS_COL_PTR(rs_col_count
);
1621 interp_col
[0] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1622 rs_col_count
+= count
;
1625 interp_col
[0] = R300_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1627 if (InputsRead
& FRAG_BIT_COL1
) {
1628 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1630 interp_col
[1] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1631 interp_col
[1] |= R300_RS_COL_PTR(1);
1632 rs_col_count
+= count
;
1635 if (InputsRead
& FRAG_BIT_FOGC
) {
1637 * Just turn off the bit for now.
1638 * Need to do something similar to the color/texcoord inputs.
1640 InputsRead
&= ~FRAG_BIT_FOGC
;
1643 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1646 /* with TCL we always seem to route 4 components */
1650 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1652 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | rs_tex_count
;
1654 case 4: swiz
= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3); break;
1655 case 3: swiz
= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(R300_RS_SEL_K1
); break;
1658 case 2: swiz
= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(R300_RS_SEL_K0
) | R300_RS_SEL_Q(R300_RS_SEL_K1
); break;
1661 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] |= swiz
;
1663 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1664 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1666 rs_tex_count
+= count
;
1668 //assert(r300->state.texture.tc_count != 0);
1669 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R300_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1670 | (fp_reg
<< R300_RS_INST_TEX_ADDR_SHIFT
);
1673 /* Passing invalid data here can lock the GPU. */
1674 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1675 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1678 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1683 if (InputsRead
& FRAG_BIT_COL0
) {
1684 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1685 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R300_RS_INST_COL_ADDR_SHIFT
);
1686 InputsRead
&= ~FRAG_BIT_COL0
;
1689 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1693 if (InputsRead
& FRAG_BIT_COL1
) {
1694 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1695 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] |= R300_RS_INST_COL_ID(1) | R300_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R300_RS_INST_COL_ADDR_SHIFT
);
1696 InputsRead
&= ~FRAG_BIT_COL1
;
1701 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1705 /* Need at least one. This might still lock as the values are undefined... */
1706 if (rs_tex_count
== 0 && col_interp_nr
== 0) {
1707 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R300_RS_INST_COL_ADDR_SHIFT
);
1711 r300
->hw
.rc
.cmd
[1] = 0 | (rs_tex_count
<< R300_IT_COUNT_SHIFT
)
1712 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1715 assert(high_rr
>= 0);
1716 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(r300
->radeon
.radeonScreen
, R300_RS_INST_0
, high_rr
+ 1);
1717 r300
->hw
.rc
.cmd
[2] = high_rr
;
1720 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1723 static void r500SetupRSUnit(GLcontext
* ctx
)
1725 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1726 /* I'm still unsure if these are needed */
1727 GLuint interp_col
[8];
1728 union r300_outputs_written OutputsWritten
;
1729 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1730 struct vertex_buffer
*VB
= &tnl
->vb
;
1732 int fp_reg
, high_rr
;
1733 int rs_col_count
= 0;
1734 int in_texcoords
, col_interp_nr
;
1737 memset(interp_col
, 0, sizeof(interp_col
));
1739 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1741 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1743 if (ctx
->FragmentProgram
._Current
)
1744 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1746 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1747 return; /* This should only ever happen once.. */
1750 R300_STATECHANGE(r300
, ri
);
1751 R300_STATECHANGE(r300
, rc
);
1752 R300_STATECHANGE(r300
, rr
);
1754 fp_reg
= col_interp_nr
= high_rr
= in_texcoords
= 0;
1756 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] = 0;
1758 if (InputsRead
& FRAG_BIT_WPOS
) {
1759 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1760 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1763 if (i
== ctx
->Const
.MaxTextureUnits
) {
1764 fprintf(stderr
, "\tno free texcoord found...\n");
1768 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1769 InputsRead
&= ~FRAG_BIT_WPOS
;
1772 if (InputsRead
& FRAG_BIT_COL0
) {
1773 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
1774 interp_col
[0] |= R500_RS_COL_PTR(rs_col_count
);
1776 interp_col
[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB1
);
1777 rs_col_count
+= count
;
1780 interp_col
[0] = R500_RS_COL_FMT(R300_RS_COL_FMT_0001
);
1782 if (InputsRead
& FRAG_BIT_COL1
) {
1783 count
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->size
;
1784 interp_col
[1] |= R500_RS_COL_PTR(1);
1786 interp_col
[1] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB0
);
1787 rs_col_count
+= count
;
1790 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1793 /* with TCL we always seem to route 4 components */
1794 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1799 count
= VB
->AttribPtr
[_TNL_ATTRIB_TEX(i
)]->size
;
1801 /* always have on texcoord */
1802 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_S_SHIFT
;
1804 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_T_SHIFT
;
1806 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
;
1809 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_R_SHIFT
;
1811 swiz
|= R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
;
1814 swiz
|= in_texcoords
++ << R500_RS_IP_TEX_PTR_Q_SHIFT
;
1816 swiz
|= R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
;
1819 swiz
= (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_S_SHIFT
) |
1820 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_T_SHIFT
) |
1821 (R500_RS_IP_PTR_K0
<< R500_RS_IP_TEX_PTR_R_SHIFT
) |
1822 (R500_RS_IP_PTR_K1
<< R500_RS_IP_TEX_PTR_Q_SHIFT
);
1824 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = interp_col
[i
] | swiz
;
1826 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] = 0;
1827 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1828 //assert(r300->state.texture.tc_count != 0);
1829 r300
->hw
.rr
.cmd
[R300_RR_INST_0
+ fp_reg
] |= R500_RS_INST_TEX_CN_WRITE
| i
/* source INTERP */
1830 | (fp_reg
<< R500_RS_INST_TEX_ADDR_SHIFT
);
1833 /* Passing invalid data here can lock the GPU. */
1834 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1835 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1838 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1843 if (InputsRead
& FRAG_BIT_COL0
) {
1844 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1845 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1846 InputsRead
&= ~FRAG_BIT_COL0
;
1849 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1853 if (InputsRead
& FRAG_BIT_COL1
) {
1854 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1855 r300
->hw
.rr
.cmd
[R300_RR_INST_1
] |= (1 << 12) | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1856 InputsRead
&= ~FRAG_BIT_COL1
;
1861 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1865 /* Need at least one. This might still lock as the values are undefined... */
1866 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1867 r300
->hw
.rr
.cmd
[R300_RR_INST_0
] |= 0 | R500_RS_INST_COL_CN_WRITE
| (fp_reg
++ << R500_RS_INST_COL_ADDR_SHIFT
);
1871 r300
->hw
.rc
.cmd
[1] = 0 | (in_texcoords
<< R300_IT_COUNT_SHIFT
)
1872 | (col_interp_nr
<< R300_IC_COUNT_SHIFT
)
1875 assert(high_rr
>= 0);
1876 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(r300
->radeon
.radeonScreen
, R500_RS_INST_0
, high_rr
+ 1);
1877 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1880 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1886 #define bump_vpu_count(ptr, new_count) do{\
1887 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1888 int _nc=(new_count)/4; \
1889 assert(_nc < 256); \
1890 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1893 static INLINE
void r300SetupVertexProgramFragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1897 if (vsf
->length
== 0)
1900 if (vsf
->length
& 0x3) {
1901 fprintf(stderr
, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1905 switch ((dest
>> 8) & 0xf) {
1907 R300_STATECHANGE(r300
, vpi
);
1908 for (i
= 0; i
< vsf
->length
; i
++)
1909 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1910 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1914 R300_STATECHANGE(r300
, vpp
);
1915 for (i
= 0; i
< vsf
->length
; i
++)
1916 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1917 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1920 R300_STATECHANGE(r300
, vps
);
1921 for (i
= 0; i
< vsf
->length
; i
++)
1922 r300
->hw
.vps
.cmd
[1 + i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1923 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1926 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1931 #define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c))
1934 static void r300VapCntl(r300ContextPtr rmesa
, GLuint input_count
,
1935 GLuint output_count
, GLuint temp_count
)
1941 /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS.
1942 * See r500 docs 6.5.2 - done in emit */
1944 /* avoid division by zero */
1945 if (input_count
== 0) input_count
= 1;
1946 if (output_count
== 0) output_count
= 1;
1947 if (temp_count
== 0) temp_count
= 1;
1949 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1954 pvs_num_slots
= MIN3(10, vtx_mem_size
/input_count
, vtx_mem_size
/output_count
);
1955 pvs_num_cntrls
= MIN2(6, vtx_mem_size
/temp_count
);
1957 R300_STATECHANGE(rmesa
, vap_cntl
);
1958 if (rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
) {
1959 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] =
1960 (pvs_num_slots
<< R300_PVS_NUM_SLOTS_SHIFT
) |
1961 (pvs_num_cntrls
<< R300_PVS_NUM_CNTLRS_SHIFT
) |
1962 (12 << R300_VF_MAX_VTX_NUM_SHIFT
);
1963 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
1964 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= R500_TCL_STATE_OPTIMIZATION
;
1966 /* not sure about non-tcl */
1967 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] = ((10 << R300_PVS_NUM_SLOTS_SHIFT
) |
1968 (5 << R300_PVS_NUM_CNTLRS_SHIFT
) |
1969 (5 << R300_VF_MAX_VTX_NUM_SHIFT
));
1971 if (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV515
)
1972 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (2 << R300_PVS_NUM_FPUS_SHIFT
);
1973 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV530
) ||
1974 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV560
) ||
1975 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV570
))
1976 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (5 << R300_PVS_NUM_FPUS_SHIFT
);
1977 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_RV410
) ||
1978 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R420
))
1979 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (6 << R300_PVS_NUM_FPUS_SHIFT
);
1980 else if ((rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R520
) ||
1981 (rmesa
->radeon
.radeonScreen
->chip_family
== CHIP_FAMILY_R580
))
1982 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (8 << R300_PVS_NUM_FPUS_SHIFT
);
1984 rmesa
->hw
.vap_cntl
.cmd
[R300_VAP_CNTL_INSTR
] |= (4 << R300_PVS_NUM_FPUS_SHIFT
);
1988 static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa
)
1990 struct r300_vertex_shader_state
*prog
= &(rmesa
->state
.vertex_shader
);
1995 int param_count
= 0;
1996 int program_end
= 0;
1998 for (i
= VERT_ATTRIB_POS
; i
< VERT_ATTRIB_MAX
; i
++) {
1999 if (rmesa
->state
.sw_tcl_inputs
[i
] != -1) {
2000 prog
->program
.body
.i
[program_end
+ 0] = PVS_OP_DST_OPERAND(VE_MULTIPLY
, GL_FALSE
, GL_FALSE
, o_reg
++, VSF_FLAG_ALL
, PVS_DST_REG_OUT
);
2001 prog
->program
.body
.i
[program_end
+ 1] = PVS_SRC_OPERAND(rmesa
->state
.sw_tcl_inputs
[i
], PVS_SRC_SELECT_X
, PVS_SRC_SELECT_Y
, PVS_SRC_SELECT_Z
, PVS_SRC_SELECT_W
, PVS_SRC_REG_INPUT
, VSF_FLAG_NONE
);
2002 prog
->program
.body
.i
[program_end
+ 2] = PVS_SRC_OPERAND(rmesa
->state
.sw_tcl_inputs
[i
], PVS_SRC_SELECT_FORCE_1
, PVS_SRC_SELECT_FORCE_1
, PVS_SRC_SELECT_FORCE_1
, PVS_SRC_SELECT_FORCE_1
, PVS_SRC_REG_INPUT
, VSF_FLAG_NONE
);
2003 prog
->program
.body
.i
[program_end
+ 3] = PVS_SRC_OPERAND(rmesa
->state
.sw_tcl_inputs
[i
], PVS_SRC_SELECT_FORCE_1
, PVS_SRC_SELECT_FORCE_1
, PVS_SRC_SELECT_FORCE_1
, PVS_SRC_SELECT_FORCE_1
, PVS_SRC_REG_INPUT
, VSF_FLAG_NONE
);
2009 prog
->program
.length
= program_end
;
2011 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
,
2013 inst_count
= (prog
->program
.length
/ 4) - 1;
2015 r300VapCntl(rmesa
, i_reg
, o_reg
, 0);
2017 R300_STATECHANGE(rmesa
, pvs
);
2018 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2019 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2020 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2021 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2022 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2023 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2024 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2025 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2026 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2029 static int bit_count (int x
)
2031 x
= ((x
& 0xaaaaaaaaU
) >> 1) + (x
& 0x55555555U
);
2032 x
= ((x
& 0xccccccccU
) >> 2) + (x
& 0x33333333U
);
2033 x
= (x
>> 16) + (x
& 0xffff);
2034 x
= ((x
& 0xf0f0) >> 4) + (x
& 0x0f0f);
2035 return (x
>> 8) + (x
& 0x00ff);
2038 static void r300SetupRealVertexProgram(r300ContextPtr rmesa
)
2040 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2041 struct r300_vertex_program
*prog
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
2043 int param_count
= 0;
2045 /* FIXME: r300SetupVertexProgramFragment */
2046 R300_STATECHANGE(rmesa
, vpp
);
2048 r300VertexProgUpdateParams(ctx
,
2049 (struct r300_vertex_program_cont
*)
2050 ctx
->VertexProgram
._Current
,
2051 (float *)&rmesa
->hw
.vpp
.
2052 cmd
[R300_VPP_PARAM_0
]);
2053 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
2056 r300SetupVertexProgramFragment(rmesa
, R300_PVS_CODE_START
, &(prog
->program
));
2057 inst_count
= (prog
->program
.length
/ 4) - 1;
2059 r300VapCntl(rmesa
, bit_count(prog
->key
.InputsRead
),
2060 bit_count(prog
->key
.OutputsWritten
), prog
->num_temporaries
);
2062 R300_STATECHANGE(rmesa
, pvs
);
2063 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
2064 (0 << R300_PVS_FIRST_INST_SHIFT
) |
2065 (inst_count
<< R300_PVS_XYZW_VALID_INST_SHIFT
) |
2066 (inst_count
<< R300_PVS_LAST_INST_SHIFT
);
2067 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
2068 (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT
) |
2069 (param_count
<< R300_PVS_MAX_CONST_ADDR_SHIFT
);
2070 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
2071 (inst_count
<< R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
2075 static void r300SetupVertexProgram(r300ContextPtr rmesa
)
2077 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2079 /* Reset state, in case we don't use something */
2080 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
2081 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
2082 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
2084 /* Not sure why this doesnt work...
2085 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
2086 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. */
2087 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
2088 if (hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
) {
2089 r300SetupRealVertexProgram(rmesa
);
2091 /* FIXME: This needs to be replaced by vertex shader generation code. */
2092 r300SetupDefaultVertexProgram(rmesa
);
2098 * Enable/Disable states.
2100 * \note Mesa already filters redundant calls to this function.
2102 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
2104 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2105 if (RADEON_DEBUG
& DEBUG_STATE
)
2106 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
2107 _mesa_lookup_enum_by_nr(cap
),
2108 state
? "GL_TRUE" : "GL_FALSE");
2117 r300SetFogState(ctx
, state
);
2120 r300SetAlphaState(ctx
);
2122 case GL_COLOR_LOGIC_OP
:
2123 r300SetLogicOpState(ctx
);
2124 /* fall-through, because logic op overrides blending */
2126 r300SetBlendState(ctx
);
2128 case GL_CLIP_PLANE0
:
2129 case GL_CLIP_PLANE1
:
2130 case GL_CLIP_PLANE2
:
2131 case GL_CLIP_PLANE3
:
2132 case GL_CLIP_PLANE4
:
2133 case GL_CLIP_PLANE5
:
2134 r300SetClipPlaneState(ctx
, cap
, state
);
2137 r300SetDepthState(ctx
);
2139 case GL_STENCIL_TEST
:
2140 r300SetStencilState(ctx
, state
);
2143 r300UpdateCulling(ctx
);
2145 case GL_POLYGON_OFFSET_POINT
:
2146 case GL_POLYGON_OFFSET_LINE
:
2147 case GL_POLYGON_OFFSET_FILL
:
2148 r300SetPolygonOffsetState(ctx
, state
);
2150 case GL_SCISSOR_TEST
:
2151 radeon_firevertices(&rmesa
->radeon
);
2152 rmesa
->radeon
.state
.scissor
.enabled
= state
;
2153 radeonUpdateScissor( ctx
);
2161 * Completely recalculates hardware state based on the Mesa state.
2163 static void r300ResetHwState(r300ContextPtr r300
)
2165 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2166 struct radeon_renderbuffer
*rrb
;
2169 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2172 if (RADEON_DEBUG
& DEBUG_STATE
)
2173 fprintf(stderr
, "%s\n", __FUNCTION__
);
2175 r300UpdateWindow(ctx
);
2178 ctx
->Color
.ColorMask
[RCOMP
],
2179 ctx
->Color
.ColorMask
[GCOMP
],
2180 ctx
->Color
.ColorMask
[BCOMP
], ctx
->Color
.ColorMask
[ACOMP
]);
2182 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
2183 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
2184 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
2187 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
2188 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
2189 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0],
2190 ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
2191 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0],
2192 ctx
->Stencil
.ZFailFunc
[0],
2193 ctx
->Stencil
.ZPassFunc
[0]);
2195 r300UpdateCulling(ctx
);
2197 r300SetBlendState(ctx
);
2198 r300SetLogicOpState(ctx
);
2200 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
2201 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
2203 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
2204 | R300_VPORT_X_OFFSET_ENA
2205 | R300_VPORT_Y_SCALE_ENA
2206 | R300_VPORT_Y_OFFSET_ENA
2207 | R300_VPORT_Z_SCALE_ENA
2208 | R300_VPORT_Z_OFFSET_ENA
| R300_VTX_W0_FMT
;
2209 r300
->hw
.vte
.cmd
[2] = 0x00000008;
2211 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[1] = 0x00FFFFFF;
2212 r300
->hw
.vap_vf_max_vtx_indx
.cmd
[2] = 0x00000000;
2214 #ifdef MESA_LITTLE_ENDIAN
2215 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_NO_SWAP
;
2217 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_32BIT_SWAP
;
2220 /* disable VAP/TCL on non-TCL capable chips */
2222 r300
->hw
.vap_cntl_status
.cmd
[1] |= R300_VAP_TCL_BYPASS
;
2224 r300
->hw
.vap_psc_sgn_norm_cntl
.cmd
[1] = 0xAAAAAAAA;
2226 /* XXX: Other families? */
2228 r300
->hw
.vap_clip_cntl
.cmd
[1] = R300_PS_UCP_MODE_DIST_COP
;
2230 r300
->hw
.vap_clip
.cmd
[1] = r300PackFloat32(1.0); /* X */
2231 r300
->hw
.vap_clip
.cmd
[2] = r300PackFloat32(1.0); /* X */
2232 r300
->hw
.vap_clip
.cmd
[3] = r300PackFloat32(1.0); /* Y */
2233 r300
->hw
.vap_clip
.cmd
[4] = r300PackFloat32(1.0); /* Y */
2235 switch (r300
->radeon
.radeonScreen
->chip_family
) {
2236 case CHIP_FAMILY_R300
:
2237 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_R300
;
2240 r300
->hw
.vap_pvs_vtx_timeout_reg
.cmd
[1] = R300_2288_RV350
;
2245 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
2246 | R300_GB_LINE_STUFF_ENABLE
2247 | R300_GB_TRIANGLE_STUFF_ENABLE
;
2249 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
2250 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
2252 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
2253 R300_GB_TILE_ENABLE
| R300_GB_TILE_SIZE_16
/*| R300_GB_SUBPIXEL_1_16*/;
2254 switch (r300
->radeon
.radeonScreen
->num_gb_pipes
) {
2257 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2258 R300_GB_TILE_PIPE_COUNT_RV300
;
2261 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2262 R300_GB_TILE_PIPE_COUNT_R300
;
2265 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2266 R300_GB_TILE_PIPE_COUNT_R420_3P
;
2269 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
2270 R300_GB_TILE_PIPE_COUNT_R420
;
2274 /* XXX: set to 0 when fog is disabled? */
2275 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
2277 /* XXX: Enable anti-aliasing? */
2278 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = GB_AA_CONFIG_AA_DISABLE
;
2280 r300
->hw
.ga_point_s0
.cmd
[1] = r300PackFloat32(0.0);
2281 r300
->hw
.ga_point_s0
.cmd
[2] = r300PackFloat32(0.0);
2282 r300
->hw
.ga_point_s0
.cmd
[3] = r300PackFloat32(1.0);
2283 r300
->hw
.ga_point_s0
.cmd
[4] = r300PackFloat32(1.0);
2285 r300
->hw
.ga_triangle_stipple
.cmd
[1] = 0x00050005;
2287 r300PointSize(ctx
, 1.0);
2289 r300
->hw
.ga_point_minmax
.cmd
[1] = 0x18000006;
2290 r300
->hw
.ga_point_minmax
.cmd
[2] = 0x00020006;
2291 r300
->hw
.ga_point_minmax
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
2293 r300LineWidth(ctx
, 1.0);
2295 r300
->hw
.ga_line_stipple
.cmd
[1] = 0;
2296 r300
->hw
.ga_line_stipple
.cmd
[2] = r300PackFloat32(0.0);
2297 r300
->hw
.ga_line_stipple
.cmd
[3] = r300PackFloat32(1.0);
2299 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
2301 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
2302 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
2303 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
2305 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
,
2306 ctx
->Polygon
.OffsetUnits
);
2307 r300Enable(ctx
, GL_POLYGON_OFFSET_POINT
, ctx
->Polygon
.OffsetPoint
);
2308 r300Enable(ctx
, GL_POLYGON_OFFSET_LINE
, ctx
->Polygon
.OffsetLine
);
2309 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
2311 r300
->hw
.su_depth_scale
.cmd
[1] = 0x4B7FFFFF;
2312 r300
->hw
.su_depth_scale
.cmd
[2] = 0x00000000;
2314 r300
->hw
.sc_hyperz
.cmd
[1] = 0x0000001C;
2315 r300
->hw
.sc_hyperz
.cmd
[2] = 0x2DA49525;
2317 r300
->hw
.sc_screendoor
.cmd
[1] = 0x00FFFFFF;
2319 r300
->hw
.us_out_fmt
.cmd
[1] = R500_OUT_FMT_C4_8
|
2320 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2321 r300
->hw
.us_out_fmt
.cmd
[2] = R500_OUT_FMT_UNUSED
|
2322 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2323 r300
->hw
.us_out_fmt
.cmd
[3] = R500_OUT_FMT_UNUSED
|
2324 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2325 r300
->hw
.us_out_fmt
.cmd
[4] = R500_OUT_FMT_UNUSED
|
2326 R500_C0_SEL_B
| R500_C1_SEL_G
| R500_C2_SEL_R
| R500_C3_SEL_A
;
2327 r300
->hw
.us_out_fmt
.cmd
[5] = R300_W_FMT_W24
;
2329 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
2330 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2331 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
2332 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
2333 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
2334 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
2335 r300Fogfv(ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
2337 r300
->hw
.fg_depth_src
.cmd
[1] = 0;
2339 r300
->hw
.rb3d_cctl
.cmd
[1] = 0;
2341 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
2343 r300
->hw
.rb3d_dither_ctl
.cmd
[1] = 0;
2344 r300
->hw
.rb3d_dither_ctl
.cmd
[2] = 0;
2345 r300
->hw
.rb3d_dither_ctl
.cmd
[3] = 0;
2346 r300
->hw
.rb3d_dither_ctl
.cmd
[4] = 0;
2347 r300
->hw
.rb3d_dither_ctl
.cmd
[5] = 0;
2348 r300
->hw
.rb3d_dither_ctl
.cmd
[6] = 0;
2349 r300
->hw
.rb3d_dither_ctl
.cmd
[7] = 0;
2350 r300
->hw
.rb3d_dither_ctl
.cmd
[8] = 0;
2351 r300
->hw
.rb3d_dither_ctl
.cmd
[9] = 0;
2353 r300
->hw
.rb3d_aaresolve_ctl
.cmd
[1] = 0;
2355 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[1] = 0x00000000;
2356 r300
->hw
.rb3d_discard_src_pixel_lte_threshold
.cmd
[2] = 0xffffffff;
2358 rrb
= r300
->radeon
.state
.depth
.rrb
;
2359 if (rrb
&& rrb
->bo
&& (rrb
->bo
->flags
& RADEON_BO_FLAGS_MACRO_TILE
)) {
2360 /* XXX: Turn off when clearing buffers ? */
2361 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTHMACROTILE_ENABLE
;
2363 if (ctx
->Visual
.depthBits
== 24)
2364 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |=
2365 R300_DEPTHMICROTILE_TILED
;
2368 r300
->hw
.zb_depthclearvalue
.cmd
[1] = 0;
2370 switch (ctx
->Visual
.depthBits
) {
2372 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_16BIT_INT_Z
;
2375 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2378 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n", ctx
->Visual
.depthBits
);
2382 r300
->hw
.zstencil_format
.cmd
[2] = R300_ZTOP_DISABLE
;
2383 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
2384 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
2385 r300SetEarlyZState(ctx
);
2387 r300
->hw
.unk4F30
.cmd
[1] = 0;
2388 r300
->hw
.unk4F30
.cmd
[2] = 0;
2390 r300
->hw
.zb_hiz_offset
.cmd
[1] = 0;
2392 r300
->hw
.zb_hiz_pitch
.cmd
[1] = 0;
2394 r300VapCntl(r300
, 0, 0, 0);
2396 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
2397 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
2398 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
2399 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
2402 r300
->radeon
.hw
.all_dirty
= GL_TRUE
;
2405 void r300UpdateShaders(r300ContextPtr rmesa
)
2408 struct r300_vertex_program
*vp
;
2411 ctx
= rmesa
->radeon
.glCtx
;
2413 if (rmesa
->radeon
.NewGLState
&& hw_tcl_on
) {
2414 rmesa
->radeon
.NewGLState
= 0;
2416 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2417 rmesa
->temp_attrib
[i
] =
2418 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
2419 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2420 &rmesa
->dummy_attrib
[i
];
2423 _tnl_UpdateFixedFunctionProgram(ctx
);
2425 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2426 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2427 rmesa
->temp_attrib
[i
];
2430 r300SelectVertexShader(rmesa
);
2431 vp
= (struct r300_vertex_program
*)
2432 CURRENT_VERTEX_SHADER(ctx
);
2433 /*if (vp->translated == GL_FALSE)
2434 r300TranslateVertexShader(vp); */
2435 if (vp
->translated
== GL_FALSE
) {
2436 fprintf(stderr
, "Failing back to sw-tcl\n");
2437 hw_tcl_on
= future_hw_tcl_on
= 0;
2438 r300ResetHwState(rmesa
);
2440 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2444 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2447 static const GLfloat
*get_fragmentprogram_constant(GLcontext
*ctx
,
2448 struct gl_program
*program
, struct prog_src_register srcreg
)
2450 static const GLfloat dummy
[4] = { 0, 0, 0, 0 };
2452 switch(srcreg
.File
) {
2453 case PROGRAM_LOCAL_PARAM
:
2454 return program
->LocalParams
[srcreg
.Index
];
2455 case PROGRAM_ENV_PARAM
:
2456 return ctx
->FragmentProgram
.Parameters
[srcreg
.Index
];
2457 case PROGRAM_STATE_VAR
:
2458 case PROGRAM_NAMED_PARAM
:
2459 case PROGRAM_CONSTANT
:
2460 return program
->Parameters
->ParameterValues
[srcreg
.Index
];
2462 _mesa_problem(ctx
, "get_fragmentprogram_constant: Unknown\n");
2468 static void r300SetupPixelShader(r300ContextPtr rmesa
)
2470 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2471 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
2472 (char *)ctx
->FragmentProgram
._Current
;
2473 struct r300_fragment_program_code
*code
;
2476 if (!fp
) /* should only happenen once, just after context is created */
2479 r300TranslateFragmentShader(rmesa
, fp
);
2480 if (!fp
->translated
) {
2481 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2487 r300SetupTextures(ctx
);
2489 R300_STATECHANGE(rmesa
, fpi
[0]);
2490 R300_STATECHANGE(rmesa
, fpi
[1]);
2491 R300_STATECHANGE(rmesa
, fpi
[2]);
2492 R300_STATECHANGE(rmesa
, fpi
[3]);
2493 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_RGB_INST_0
, code
->alu
.length
);
2494 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_RGB_ADDR_0
, code
->alu
.length
);
2495 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_ALPHA_INST_0
, code
->alu
.length
);
2496 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_US_ALU_ALPHA_ADDR_0
, code
->alu
.length
);
2497 for (i
= 0; i
< code
->alu
.length
; i
++) {
2498 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst0
;
2499 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst1
;
2500 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst2
;
2501 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_INSTR_0
+ i
] = code
->alu
.inst
[i
].inst3
;
2504 R300_STATECHANGE(rmesa
, fp
);
2505 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
] = code
->cur_node
| (code
->first_node_has_tex
<< 3);
2506 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
] = code
->max_temp_idx
;
2507 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
] =
2508 (0 << R300_PFS_CNTL_ALU_OFFSET_SHIFT
) |
2509 ((code
->alu
.length
-1) << R300_PFS_CNTL_ALU_END_SHIFT
) |
2510 (0 << R300_PFS_CNTL_TEX_OFFSET_SHIFT
) |
2511 ((code
->tex
.length
? code
->tex
.length
-1 : 0) << R300_PFS_CNTL_TEX_END_SHIFT
);
2512 /* I just want to say, the way these nodes are stored.. weird.. */
2513 for (i
= 0, k
= (4 - (code
->cur_node
+ 1)); i
< 4; i
++, k
++) {
2514 if (i
< (code
->cur_node
+ 1)) {
2515 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ k
] =
2516 (code
->node
[i
].alu_offset
<< R300_ALU_START_SHIFT
) |
2517 (code
->node
[i
].alu_end
<< R300_ALU_SIZE_SHIFT
) |
2518 (code
->node
[i
].tex_offset
<< R300_TEX_START_SHIFT
) |
2519 (code
->node
[i
].tex_end
<< R300_TEX_SIZE_SHIFT
) |
2520 code
->node
[i
].flags
;
2522 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ (3 - i
)] = 0;
2526 R300_STATECHANGE(rmesa
, fpp
);
2527 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
] = cmdpacket0(rmesa
->radeon
.radeonScreen
, R300_PFS_PARAM_0_X
, code
->const_nr
* 4);
2528 for (i
= 0; i
< code
->const_nr
; i
++) {
2529 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2530 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2531 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat24(constant
[0]);
2532 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat24(constant
[1]);
2533 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat24(constant
[2]);
2534 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat24(constant
[3]);
2538 #define bump_r500fp_count(ptr, new_count) do{\
2539 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2540 int _nc=(new_count)/6; \
2541 assert(_nc < 256); \
2542 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2545 #define bump_r500fp_const_count(ptr, new_count) do{\
2546 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
2547 int _nc=(new_count)/4; \
2548 assert(_nc < 256); \
2549 if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\
2552 static void r500SetupPixelShader(r300ContextPtr rmesa
)
2554 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2555 struct r500_fragment_program
*fp
= (struct r500_fragment_program
*)
2556 (char *)ctx
->FragmentProgram
._Current
;
2558 struct r500_fragment_program_code
*code
;
2560 if (!fp
) /* should only happenen once, just after context is created */
2563 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp
.cmd
)->r500fp
.count
= 0;
2564 ((drm_r300_cmd_header_t
*) rmesa
->hw
.r500fp_const
.cmd
)->r500fp
.count
= 0;
2566 r500TranslateFragmentShader(rmesa
, fp
);
2567 if (!fp
->translated
) {
2568 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2574 if (fp
->mesa_program
.FogOption
!= GL_NONE
) {
2575 /* Enable HW fog. Try not to squish GL context.
2576 * (Anybody sane remembered to set glFog() opts first!) */
2577 r300SetFogState(ctx
, GL_TRUE
);
2578 ctx
->Fog
.Mode
= fp
->mesa_program
.FogOption
;
2579 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
2581 /* Make sure HW is matching GL context. */
2582 r300SetFogState(ctx
, ctx
->Fog
.Enabled
);
2584 r300SetupTextures(ctx
);
2586 R300_STATECHANGE(rmesa
, fp
);
2587 rmesa
->hw
.fp
.cmd
[R500_FP_PIXSIZE
] = code
->max_temp_idx
;
2589 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_ADDR
] =
2590 R500_US_CODE_START_ADDR(code
->inst_offset
) |
2591 R500_US_CODE_END_ADDR(code
->inst_end
);
2592 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_RANGE
] =
2593 R500_US_CODE_RANGE_ADDR(code
->inst_offset
) |
2594 R500_US_CODE_RANGE_SIZE(code
->inst_end
);
2595 rmesa
->hw
.fp
.cmd
[R500_FP_CODE_OFFSET
] =
2596 R500_US_CODE_OFFSET_ADDR(0); /* FIXME when we add flow control */
2598 R300_STATECHANGE(rmesa
, r500fp
);
2599 /* Emit our shader... */
2600 for (i
= 0; i
< code
->inst_end
+1; i
++) {
2601 rmesa
->hw
.r500fp
.cmd
[i
*6+1] = code
->inst
[i
].inst0
;
2602 rmesa
->hw
.r500fp
.cmd
[i
*6+2] = code
->inst
[i
].inst1
;
2603 rmesa
->hw
.r500fp
.cmd
[i
*6+3] = code
->inst
[i
].inst2
;
2604 rmesa
->hw
.r500fp
.cmd
[i
*6+4] = code
->inst
[i
].inst3
;
2605 rmesa
->hw
.r500fp
.cmd
[i
*6+5] = code
->inst
[i
].inst4
;
2606 rmesa
->hw
.r500fp
.cmd
[i
*6+6] = code
->inst
[i
].inst5
;
2609 bump_r500fp_count(rmesa
->hw
.r500fp
.cmd
, (code
->inst_end
+ 1) * 6);
2611 R300_STATECHANGE(rmesa
, r500fp_const
);
2612 for (i
= 0; i
< code
->const_nr
; i
++) {
2613 const GLfloat
*constant
= get_fragmentprogram_constant(ctx
,
2614 &fp
->mesa_program
.Base
, code
->constant
[i
]);
2615 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat32(constant
[0]);
2616 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat32(constant
[1]);
2617 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat32(constant
[2]);
2618 rmesa
->hw
.r500fp_const
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat32(constant
[3]);
2620 bump_r500fp_const_count(rmesa
->hw
.r500fp_const
.cmd
, code
->const_nr
* 4);
2624 void r300UpdateShaderStates(r300ContextPtr rmesa
)
2627 ctx
= rmesa
->radeon
.glCtx
;
2629 r300SetEarlyZState(ctx
);
2631 GLuint fgdepthsrc
= R300_FG_DEPTH_SRC_SCAN
;
2632 if (current_fragment_program_writes_depth(ctx
))
2633 fgdepthsrc
= R300_FG_DEPTH_SRC_SHADER
;
2634 if (fgdepthsrc
!= rmesa
->hw
.fg_depth_src
.cmd
[1]) {
2635 R300_STATECHANGE(rmesa
, fg_depth_src
);
2636 rmesa
->hw
.fg_depth_src
.cmd
[1] = fgdepthsrc
;
2639 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2640 r500SetupPixelShader(rmesa
);
2642 r300SetupPixelShader(rmesa
);
2644 if (rmesa
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
)
2645 r500SetupRSUnit(ctx
);
2647 r300SetupRSUnit(ctx
);
2649 if ((rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2650 r300SetupVertexProgram(rmesa
);
2655 * Called by Mesa after an internal state update.
2657 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
2659 r300ContextPtr r300
= R300_CONTEXT(ctx
);
2661 _swrast_InvalidateState(ctx
, new_state
);
2662 _swsetup_InvalidateState(ctx
, new_state
);
2663 _vbo_InvalidateState(ctx
, new_state
);
2664 _tnl_InvalidateState(ctx
, new_state
);
2665 _ae_invalidate_state(ctx
, new_state
);
2667 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2668 r300UpdateDrawBuffer(ctx
);
2671 r300UpdateStateParameters(ctx
, new_state
);
2673 r300
->radeon
.NewGLState
|= new_state
;
2677 * Calculate initial hardware state and register state functions.
2678 * Assumes that the command buffer and state atoms have been
2679 * initialized already.
2681 void r300InitState(r300ContextPtr r300
)
2683 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2686 switch (ctx
->Visual
.depthBits
) {
2688 r300
->radeon
.state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2689 depth_fmt
= R300_DEPTHFORMAT_16BIT_INT_Z
;
2692 r300
->radeon
.state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2693 depth_fmt
= R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL
;
2696 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2697 ctx
->Visual
.depthBits
);
2701 /* Only have hw stencil when depth buffer is 24 bits deep */
2702 r300
->radeon
.state
.stencil
.hwBuffer
= (ctx
->Visual
.stencilBits
> 0 &&
2703 ctx
->Visual
.depthBits
== 24);
2705 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2707 r300ResetHwState(r300
);
2710 static void r300RenderMode(GLcontext
* ctx
, GLenum mode
)
2712 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2717 void r300UpdateClipPlanes( GLcontext
*ctx
)
2719 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2722 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
2723 if (ctx
->Transform
.ClipPlanesEnabled
& (1 << p
)) {
2724 GLint
*ip
= (GLint
*)ctx
->Transform
._ClipUserPlane
[p
];
2726 R300_STATECHANGE( rmesa
, vpucp
[p
] );
2727 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_X
] = ip
[0];
2728 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Y
] = ip
[1];
2729 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_Z
] = ip
[2];
2730 rmesa
->hw
.vpucp
[p
].cmd
[R300_VPUCP_W
] = ip
[3];
2735 static void r300DrawBuffer( GLcontext
*ctx
, GLenum mode
)
2737 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2738 if (RADEON_DEBUG
& DEBUG_DRI
)
2739 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
2740 _mesa_lookup_enum_by_nr( mode
));
2742 radeon_firevertices(&rmesa
->radeon
); /* don't pipeline cliprect changes */
2744 radeonSetCliprects( &rmesa
->radeon
);
2745 radeonUpdatePageFlipping(&rmesa
->radeon
);
2748 static void r300ReadBuffer( GLcontext
*ctx
, GLenum mode
)
2750 if (RADEON_DEBUG
& DEBUG_DRI
)
2751 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
2752 _mesa_lookup_enum_by_nr( mode
));
2757 * Initialize driver's state callback functions
2759 void r300InitStateFuncs(struct dd_function_table
*functions
)
2762 functions
->UpdateState
= r300InvalidateState
;
2763 functions
->AlphaFunc
= r300AlphaFunc
;
2764 functions
->BlendColor
= r300BlendColor
;
2765 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2766 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2767 functions
->Enable
= r300Enable
;
2768 functions
->ColorMask
= r300ColorMask
;
2769 functions
->DepthFunc
= r300DepthFunc
;
2770 functions
->DepthMask
= r300DepthMask
;
2771 functions
->CullFace
= r300CullFace
;
2772 functions
->Fogfv
= r300Fogfv
;
2773 functions
->FrontFace
= r300FrontFace
;
2774 functions
->ShadeModel
= r300ShadeModel
;
2775 functions
->LogicOpcode
= r300LogicOpcode
;
2777 /* ARB_point_parameters */
2778 functions
->PointParameterfv
= r300PointParameter
;
2780 /* Stencil related */
2781 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2782 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2783 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2785 /* Viewport related */
2786 functions
->Viewport
= r300Viewport
;
2787 functions
->DepthRange
= r300DepthRange
;
2788 functions
->PointSize
= r300PointSize
;
2789 functions
->LineWidth
= r300LineWidth
;
2791 functions
->PolygonOffset
= r300PolygonOffset
;
2792 functions
->PolygonMode
= r300PolygonMode
;
2794 functions
->RenderMode
= r300RenderMode
;
2796 functions
->ClipPlane
= r300ClipPlane
;
2797 functions
->Scissor
= radeonScissor
;
2799 functions
->DrawBuffer
= r300DrawBuffer
;
2800 functions
->ReadBuffer
= r300ReadBuffer
;