2 Copyright (C) The Weather Channel, Inc. 2002.
3 Copyright (C) 2004 Nicolai Haehnle.
6 The Weather Channel (TM) funded Tungsten Graphics to develop the
7 initial release of the Radeon 8500 driver under the XFree86 license.
8 This notice must be preserved.
10 Permission is hereby granted, free of charge, to any person obtaining
11 a copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sublicense, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial
20 portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
35 * \author Nicolai Haehnle <prefect_@gmx.net>
45 #include "simple_list.h"
47 #include "api_arrayelt.h"
48 #include "swrast/swrast.h"
49 #include "swrast_setup/swrast_setup.h"
50 #include "shader/prog_parameter.h"
51 #include "shader/prog_statevars.h"
54 #include "texformat.h"
56 #include "radeon_ioctl.h"
57 #include "radeon_state.h"
58 #include "r300_context.h"
59 #include "r300_ioctl.h"
60 #include "r300_state.h"
62 #include "r300_emit.h"
63 #include "r300_fragprog.h"
66 #include "drirenderbuffer.h"
68 extern int future_hw_tcl_on
;
69 extern void _tnl_UpdateFixedFunctionProgram(GLcontext
* ctx
);
71 static void r300BlendColor(GLcontext
* ctx
, const GLfloat cf
[4])
74 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
76 R300_STATECHANGE(rmesa
, blend_color
);
78 CLAMPED_FLOAT_TO_UBYTE(color
[0], cf
[0]);
79 CLAMPED_FLOAT_TO_UBYTE(color
[1], cf
[1]);
80 CLAMPED_FLOAT_TO_UBYTE(color
[2], cf
[2]);
81 CLAMPED_FLOAT_TO_UBYTE(color
[3], cf
[3]);
83 rmesa
->hw
.blend_color
.cmd
[1] = PACK_COLOR_8888(color
[3], color
[0],
88 * Calculate the hardware blend factor setting. This same function is used
89 * for source and destination of both alpha and RGB.
92 * The hardware register value for the specified blend factor. This value
93 * will need to be shifted into the correct position for either source or
97 * Since the two cases where source and destination are handled differently
98 * are essentially error cases, they should never happen. Determine if these
99 * cases can be removed.
101 static int blend_factor(GLenum factor
, GLboolean is_src
)
105 return R300_BLEND_GL_ZERO
;
108 return R300_BLEND_GL_ONE
;
111 return R300_BLEND_GL_DST_COLOR
;
113 case GL_ONE_MINUS_DST_COLOR
:
114 return R300_BLEND_GL_ONE_MINUS_DST_COLOR
;
117 return R300_BLEND_GL_SRC_COLOR
;
119 case GL_ONE_MINUS_SRC_COLOR
:
120 return R300_BLEND_GL_ONE_MINUS_SRC_COLOR
;
123 return R300_BLEND_GL_SRC_ALPHA
;
125 case GL_ONE_MINUS_SRC_ALPHA
:
126 return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA
;
129 return R300_BLEND_GL_DST_ALPHA
;
131 case GL_ONE_MINUS_DST_ALPHA
:
132 return R300_BLEND_GL_ONE_MINUS_DST_ALPHA
;
134 case GL_SRC_ALPHA_SATURATE
:
135 return (is_src
) ? R300_BLEND_GL_SRC_ALPHA_SATURATE
:
138 case GL_CONSTANT_COLOR
:
139 return R300_BLEND_GL_CONST_COLOR
;
141 case GL_ONE_MINUS_CONSTANT_COLOR
:
142 return R300_BLEND_GL_ONE_MINUS_CONST_COLOR
;
144 case GL_CONSTANT_ALPHA
:
145 return R300_BLEND_GL_CONST_ALPHA
;
147 case GL_ONE_MINUS_CONSTANT_ALPHA
:
148 return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA
;
151 fprintf(stderr
, "unknown blend factor %x\n", factor
);
152 return (is_src
) ? R300_BLEND_GL_ONE
: R300_BLEND_GL_ZERO
;
158 * Sets both the blend equation and the blend function.
159 * This is done in a single
160 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
161 * change the interpretation of the blend function.
162 * Also, make sure that blend function and blend equation are set to their
163 * default value if color blending is not enabled, since at least blend
164 * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results
165 * otherwise for unknown reasons.
168 /* helper function */
169 static void r300SetBlendCntl(r300ContextPtr r300
, int func
, int eqn
,
170 int cbits
, int funcA
, int eqnA
)
172 GLuint new_ablend
, new_cblend
;
176 "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n",
177 eqnA
, funcA
, eqn
, func
, cbits
);
179 new_ablend
= eqnA
| funcA
;
180 new_cblend
= eqn
| func
;
182 /* Some blend factor combinations don't seem to work when the
183 * BLEND_NO_SEPARATE bit is set.
185 * Especially problematic candidates are the ONE_MINUS_* flags,
186 * but I can't see a real pattern.
189 if (new_ablend
== new_cblend
) {
190 new_cblend
|= R300_BLEND_NO_SEPARATE
;
195 if ((new_ablend
!= r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
]) ||
196 (new_cblend
!= r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
])) {
197 R300_STATECHANGE(r300
, bld
);
198 r300
->hw
.bld
.cmd
[R300_BLD_ABLEND
] = new_ablend
;
199 r300
->hw
.bld
.cmd
[R300_BLD_CBLEND
] = new_cblend
;
203 static void r300SetBlendState(GLcontext
* ctx
)
205 r300ContextPtr r300
= R300_CONTEXT(ctx
);
206 int func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
207 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
208 int eqn
= R300_COMB_FCN_ADD_CLAMP
;
209 int funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
210 (R300_BLEND_GL_ZERO
<< R300_DST_BLEND_SHIFT
);
211 int eqnA
= R300_COMB_FCN_ADD_CLAMP
;
213 if (RGBA_LOGICOP_ENABLED(ctx
) || !ctx
->Color
.BlendEnabled
) {
214 r300SetBlendCntl(r300
, func
, eqn
, 0, func
, eqn
);
219 (blend_factor(ctx
->Color
.BlendSrcRGB
, GL_TRUE
) <<
220 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstRGB
,
222 R300_DST_BLEND_SHIFT
);
224 switch (ctx
->Color
.BlendEquationRGB
) {
226 eqn
= R300_COMB_FCN_ADD_CLAMP
;
229 case GL_FUNC_SUBTRACT
:
230 eqn
= R300_COMB_FCN_SUB_CLAMP
;
233 case GL_FUNC_REVERSE_SUBTRACT
:
234 eqn
= R300_COMB_FCN_RSUB_CLAMP
;
238 eqn
= R300_COMB_FCN_MIN
;
239 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
240 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
244 eqn
= R300_COMB_FCN_MAX
;
245 func
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
246 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
251 "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
252 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
257 (blend_factor(ctx
->Color
.BlendSrcA
, GL_TRUE
) <<
258 R300_SRC_BLEND_SHIFT
) | (blend_factor(ctx
->Color
.BlendDstA
,
260 R300_DST_BLEND_SHIFT
);
262 switch (ctx
->Color
.BlendEquationA
) {
264 eqnA
= R300_COMB_FCN_ADD_CLAMP
;
267 case GL_FUNC_SUBTRACT
:
268 eqnA
= R300_COMB_FCN_SUB_CLAMP
;
271 case GL_FUNC_REVERSE_SUBTRACT
:
272 eqnA
= R300_COMB_FCN_RSUB_CLAMP
;
276 eqnA
= R300_COMB_FCN_MIN
;
277 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
278 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
282 eqnA
= R300_COMB_FCN_MAX
;
283 funcA
= (R300_BLEND_GL_ONE
<< R300_SRC_BLEND_SHIFT
) |
284 (R300_BLEND_GL_ONE
<< R300_DST_BLEND_SHIFT
);
289 "[%s:%u] Invalid A blend equation (0x%04x).\n",
290 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationA
);
294 r300SetBlendCntl(r300
,
296 R300_BLEND_UNKNOWN
| R300_BLEND_ENABLE
, funcA
, eqnA
);
299 static void r300BlendEquationSeparate(GLcontext
* ctx
,
300 GLenum modeRGB
, GLenum modeA
)
302 r300SetBlendState(ctx
);
305 static void r300BlendFuncSeparate(GLcontext
* ctx
,
306 GLenum sfactorRGB
, GLenum dfactorRGB
,
307 GLenum sfactorA
, GLenum dfactorA
)
309 r300SetBlendState(ctx
);
313 * Update our tracked culling state based on Mesa's state.
315 static void r300UpdateCulling(GLcontext
* ctx
)
317 r300ContextPtr r300
= R300_CONTEXT(ctx
);
320 R300_STATECHANGE(r300
, cul
);
321 if (ctx
->Polygon
.CullFlag
) {
322 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
)
323 val
= R300_CULL_FRONT
| R300_CULL_BACK
;
324 else if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
325 val
= R300_CULL_FRONT
;
327 val
= R300_CULL_BACK
;
329 if (ctx
->Polygon
.FrontFace
== GL_CW
)
330 val
|= R300_FRONT_FACE_CW
;
332 val
|= R300_FRONT_FACE_CCW
;
334 r300
->hw
.cul
.cmd
[R300_CUL_CULL
] = val
;
337 static void r300SetEarlyZState(GLcontext
* ctx
)
339 /* updates register R300_RB3D_EARLY_Z (0x4F14)
340 if depth test is not enabled it should be R300_EARLY_Z_DISABLE
341 if depth is enabled and alpha not it should be R300_EARLY_Z_ENABLE
342 if depth and alpha is enabled it should be R300_EARLY_Z_DISABLE
344 r300ContextPtr r300
= R300_CONTEXT(ctx
);
346 R300_STATECHANGE(r300
, zstencil_format
);
347 if (ctx
->Color
.AlphaEnabled
&& ctx
->Color
.AlphaFunc
!= GL_ALWAYS
)
348 /* disable early Z */
349 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_DISABLE
;
351 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
)
353 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_ENABLE
;
355 /* disable early Z */
356 r300
->hw
.zstencil_format
.cmd
[2] = R300_EARLY_Z_DISABLE
;
360 static void r300SetAlphaState(GLcontext
* ctx
)
362 r300ContextPtr r300
= R300_CONTEXT(ctx
);
364 uint32_t pp_misc
= 0x0;
365 GLboolean really_enabled
= ctx
->Color
.AlphaEnabled
;
367 CLAMPED_FLOAT_TO_UBYTE(refByte
, ctx
->Color
.AlphaRef
);
369 switch (ctx
->Color
.AlphaFunc
) {
371 pp_misc
|= R300_ALPHA_TEST_FAIL
;
374 pp_misc
|= R300_ALPHA_TEST_LESS
;
377 pp_misc
|= R300_ALPHA_TEST_EQUAL
;
380 pp_misc
|= R300_ALPHA_TEST_LEQUAL
;
383 pp_misc
|= R300_ALPHA_TEST_GREATER
;
386 pp_misc
|= R300_ALPHA_TEST_NEQUAL
;
389 pp_misc
|= R300_ALPHA_TEST_GEQUAL
;
392 /*pp_misc |= R300_ALPHA_TEST_PASS; */
393 really_enabled
= GL_FALSE
;
397 if (really_enabled
) {
398 pp_misc
|= R300_ALPHA_TEST_ENABLE
;
399 pp_misc
|= (refByte
& R300_REF_ALPHA_MASK
);
404 R300_STATECHANGE(r300
, at
);
405 r300
->hw
.at
.cmd
[R300_AT_ALPHA_TEST
] = pp_misc
;
407 r300SetEarlyZState(ctx
);
410 static void r300AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
414 r300SetAlphaState(ctx
);
417 static int translate_func(int func
)
421 return R300_ZS_NEVER
;
425 return R300_ZS_EQUAL
;
427 return R300_ZS_LEQUAL
;
429 return R300_ZS_GREATER
;
431 return R300_ZS_NOTEQUAL
;
433 return R300_ZS_GEQUAL
;
435 return R300_ZS_ALWAYS
;
440 static void r300SetDepthState(GLcontext
* ctx
)
442 r300ContextPtr r300
= R300_CONTEXT(ctx
);
444 R300_STATECHANGE(r300
, zs
);
445 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &= R300_RB3D_STENCIL_ENABLE
;
446 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
447 ~(R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
);
449 if (ctx
->Depth
.Test
&& ctx
->Depth
.Func
!= GL_NEVER
) {
451 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
452 R300_RB3D_Z_TEST_AND_WRITE
;
454 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_TEST
;
456 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
457 translate_func(ctx
->Depth
.
458 Func
) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
460 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |= R300_RB3D_Z_DISABLED_1
;
461 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
462 translate_func(GL_NEVER
) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
;
465 r300SetEarlyZState(ctx
);
468 static void r300UpdatePolygonMode(GLcontext
* ctx
)
470 r300ContextPtr r300
= R300_CONTEXT(ctx
);
471 uint32_t hw_mode
= 0;
473 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
474 ctx
->Polygon
.BackMode
!= GL_FILL
) {
477 if (ctx
->Polygon
.FrontFace
== GL_CCW
) {
478 f
= ctx
->Polygon
.FrontMode
;
479 b
= ctx
->Polygon
.BackMode
;
481 f
= ctx
->Polygon
.BackMode
;
482 b
= ctx
->Polygon
.FrontMode
;
485 hw_mode
|= R300_PM_ENABLED
;
489 hw_mode
|= R300_PM_FRONT_LINE
;
491 case GL_POINT
: /* noop */
492 hw_mode
|= R300_PM_FRONT_POINT
;
495 hw_mode
|= R300_PM_FRONT_FILL
;
501 hw_mode
|= R300_PM_BACK_LINE
;
503 case GL_POINT
: /* noop */
504 hw_mode
|= R300_PM_BACK_POINT
;
507 hw_mode
|= R300_PM_BACK_FILL
;
512 if (r300
->hw
.polygon_mode
.cmd
[1] != hw_mode
) {
513 R300_STATECHANGE(r300
, polygon_mode
);
514 r300
->hw
.polygon_mode
.cmd
[1] = hw_mode
;
519 * Change the culling mode.
521 * \note Mesa already filters redundant calls to this function.
523 static void r300CullFace(GLcontext
* ctx
, GLenum mode
)
527 r300UpdateCulling(ctx
);
531 * Change the polygon orientation.
533 * \note Mesa already filters redundant calls to this function.
535 static void r300FrontFace(GLcontext
* ctx
, GLenum mode
)
539 r300UpdateCulling(ctx
);
540 r300UpdatePolygonMode(ctx
);
544 * Change the depth testing function.
546 * \note Mesa already filters redundant calls to this function.
548 static void r300DepthFunc(GLcontext
* ctx
, GLenum func
)
551 r300SetDepthState(ctx
);
555 * Enable/Disable depth writing.
557 * \note Mesa already filters redundant calls to this function.
559 static void r300DepthMask(GLcontext
* ctx
, GLboolean mask
)
562 r300SetDepthState(ctx
);
566 * Handle glColorMask()
568 static void r300ColorMask(GLcontext
* ctx
,
569 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
571 r300ContextPtr r300
= R300_CONTEXT(ctx
);
572 int mask
= (r
? R300_COLORMASK0_R
: 0) |
573 (g
? R300_COLORMASK0_G
: 0) |
574 (b
? R300_COLORMASK0_B
: 0) | (a
? R300_COLORMASK0_A
: 0);
576 if (mask
!= r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
]) {
577 R300_STATECHANGE(r300
, cmk
);
578 r300
->hw
.cmk
.cmd
[R300_CMK_COLORMASK
] = mask
;
582 /* =============================================================
585 static void r300Fogfv(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
587 r300ContextPtr r300
= R300_CONTEXT(ctx
);
591 } fogScale
, fogStart
;
595 fogScale
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
];
596 fogStart
.i
= r300
->hw
.fogp
.cmd
[R300_FOGP_START
];
600 if (!ctx
->Fog
.Enabled
)
602 switch (ctx
->Fog
.Mode
) {
604 R300_STATECHANGE(r300
, fogs
);
605 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
607 cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) |
608 R300_FOG_MODE_LINEAR
;
610 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
615 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
617 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
622 R300_STATECHANGE(r300
, fogs
);
623 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
625 cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) |
627 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
631 R300_STATECHANGE(r300
, fogs
);
632 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] =
634 cmd
[R300_FOGS_STATE
] & ~R300_FOG_MODE_MASK
) |
636 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
643 switch (ctx
->Fog
.Mode
) {
645 fogScale
.f
= 0.0933 * ctx
->Fog
.Density
;
649 fogScale
.f
= 0.3 * ctx
->Fog
.Density
;
657 if (ctx
->Fog
.Mode
== GL_LINEAR
) {
658 if (ctx
->Fog
.Start
== ctx
->Fog
.End
) {
663 1.0 / (ctx
->Fog
.End
- ctx
->Fog
.Start
);
665 -ctx
->Fog
.Start
/ (ctx
->Fog
.End
-
671 R300_STATECHANGE(r300
, fogc
);
672 r300
->hw
.fogc
.cmd
[R300_FOGC_R
] =
673 (GLuint
) (ctx
->Fog
.Color
[0] * 1023.0F
) & 0x3FF;
674 r300
->hw
.fogc
.cmd
[R300_FOGC_G
] =
675 (GLuint
) (ctx
->Fog
.Color
[1] * 1023.0F
) & 0x3FF;
676 r300
->hw
.fogc
.cmd
[R300_FOGC_B
] =
677 (GLuint
) (ctx
->Fog
.Color
[2] * 1023.0F
) & 0x3FF;
679 case GL_FOG_COORD_SRC
:
685 if (fogScale
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] ||
686 fogStart
.i
!= r300
->hw
.fogp
.cmd
[R300_FOGP_START
]) {
687 R300_STATECHANGE(r300
, fogp
);
688 r300
->hw
.fogp
.cmd
[R300_FOGP_SCALE
] = fogScale
.i
;
689 r300
->hw
.fogp
.cmd
[R300_FOGP_START
] = fogStart
.i
;
693 /* =============================================================
696 static void r300PointSize(GLcontext
* ctx
, GLfloat size
)
698 r300ContextPtr r300
= R300_CONTEXT(ctx
);
700 size
= ctx
->Point
._Size
;
702 R300_STATECHANGE(r300
, ps
);
703 r300
->hw
.ps
.cmd
[R300_PS_POINTSIZE
] =
704 ((int)(size
* 6) << R300_POINTSIZE_X_SHIFT
) |
705 ((int)(size
* 6) << R300_POINTSIZE_Y_SHIFT
);
708 /* =============================================================
711 static void r300LineWidth(GLcontext
* ctx
, GLfloat widthf
)
713 r300ContextPtr r300
= R300_CONTEXT(ctx
);
715 widthf
= ctx
->Line
._Width
;
717 R300_STATECHANGE(r300
, lcntl
);
718 r300
->hw
.lcntl
.cmd
[1] =
719 R300_LINE_CNT_HO
| R300_LINE_CNT_VE
| (int)(widthf
* 6.0);
722 static void r300PolygonMode(GLcontext
* ctx
, GLenum face
, GLenum mode
)
727 r300UpdatePolygonMode(ctx
);
730 /* =============================================================
734 static int translate_stencil_op(int op
)
742 return R300_ZS_REPLACE
;
747 case GL_INCR_WRAP_EXT
:
748 return R300_ZS_INCR_WRAP
;
749 case GL_DECR_WRAP_EXT
:
750 return R300_ZS_DECR_WRAP
;
752 return R300_ZS_INVERT
;
754 WARN_ONCE("Do not know how to translate stencil op");
760 static void r300ShadeModel(GLcontext
* ctx
, GLenum mode
)
762 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
764 R300_STATECHANGE(rmesa
, shade
);
767 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_FLAT
;
770 rmesa
->hw
.shade
.cmd
[2] = R300_RE_SHADE_MODEL_SMOOTH
;
777 static void r300StencilFuncSeparate(GLcontext
* ctx
, GLenum face
,
778 GLenum func
, GLint ref
, GLuint mask
)
780 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
783 Ref
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_REF_SHIFT
) | ((ctx
->
789 R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
793 R300_STATECHANGE(rmesa
, zs
);
795 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &= ~((R300_ZS_MASK
<<
796 R300_RB3D_ZS1_FRONT_FUNC_SHIFT
)
798 R300_RB3D_ZS1_BACK_FUNC_SHIFT
));
800 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
801 ~((R300_RB3D_ZS2_STENCIL_MASK
<<
802 R300_RB3D_ZS2_STENCIL_REF_SHIFT
) |
803 (R300_RB3D_ZS2_STENCIL_MASK
<< R300_RB3D_ZS2_STENCIL_MASK_SHIFT
));
805 flag
= translate_func(ctx
->Stencil
.Function
[0]);
806 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
807 (flag
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
);
809 if (ctx
->Stencil
._TestTwoSide
)
810 flag
= translate_func(ctx
->Stencil
.Function
[1]);
812 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
813 (flag
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
814 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |= refmask
;
817 static void r300StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
819 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
821 R300_STATECHANGE(rmesa
, zs
);
822 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] &=
823 ~(R300_RB3D_ZS2_STENCIL_MASK
<<
824 R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
);
825 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_2
] |=
827 WriteMask
[0] & 0xff) << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
;
830 static void r300StencilOpSeparate(GLcontext
* ctx
, GLenum face
,
831 GLenum fail
, GLenum zfail
, GLenum zpass
)
833 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
835 R300_STATECHANGE(rmesa
, zs
);
836 /* It is easier to mask what's left.. */
837 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] &=
838 (R300_ZS_MASK
<< R300_RB3D_ZS1_DEPTH_FUNC_SHIFT
) |
839 (R300_ZS_MASK
<< R300_RB3D_ZS1_FRONT_FUNC_SHIFT
) |
840 (R300_ZS_MASK
<< R300_RB3D_ZS1_BACK_FUNC_SHIFT
);
842 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
843 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
844 R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT
)
845 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
846 R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT
)
847 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
848 R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT
);
850 if (ctx
->Stencil
._TestTwoSide
) {
851 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
852 (translate_stencil_op(ctx
->Stencil
.FailFunc
[1]) <<
853 R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
854 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[1]) <<
855 R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
856 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[1]) <<
857 R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
859 rmesa
->hw
.zs
.cmd
[R300_ZS_CNTL_1
] |=
860 (translate_stencil_op(ctx
->Stencil
.FailFunc
[0]) <<
861 R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT
)
862 | (translate_stencil_op(ctx
->Stencil
.ZFailFunc
[0]) <<
863 R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT
)
864 | (translate_stencil_op(ctx
->Stencil
.ZPassFunc
[0]) <<
865 R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT
);
869 static void r300ClearStencil(GLcontext
* ctx
, GLint s
)
871 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
873 rmesa
->state
.stencil
.clear
=
874 ((GLuint
) (ctx
->Stencil
.Clear
& 0xff) |
875 (R300_RB3D_ZS2_STENCIL_MASK
<<
876 R300_RB3D_ZS2_STENCIL_MASK_SHIFT
) | ((ctx
->Stencil
.
877 WriteMask
[0] & 0xff) <<
878 R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT
));
881 /* =============================================================
882 * Window position and viewport transformation
886 * To correctly position primitives:
888 #define SUBPIXEL_X 0.125
889 #define SUBPIXEL_Y 0.125
891 static void r300UpdateWindow(GLcontext
* ctx
)
893 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
894 __DRIdrawablePrivate
*dPriv
= rmesa
->radeon
.dri
.drawable
;
895 GLfloat xoffset
= dPriv
? (GLfloat
) dPriv
->x
: 0;
896 GLfloat yoffset
= dPriv
? (GLfloat
) dPriv
->y
+ dPriv
->h
: 0;
897 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
899 GLfloat sx
= v
[MAT_SX
];
900 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
901 GLfloat sy
= -v
[MAT_SY
];
902 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
903 GLfloat sz
= v
[MAT_SZ
] * rmesa
->state
.depth
.scale
;
904 GLfloat tz
= v
[MAT_TZ
] * rmesa
->state
.depth
.scale
;
906 R300_FIREVERTICES(rmesa
);
907 R300_STATECHANGE(rmesa
, vpt
);
909 rmesa
->hw
.vpt
.cmd
[R300_VPT_XSCALE
] = r300PackFloat32(sx
);
910 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
911 rmesa
->hw
.vpt
.cmd
[R300_VPT_YSCALE
] = r300PackFloat32(sy
);
912 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
913 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZSCALE
] = r300PackFloat32(sz
);
914 rmesa
->hw
.vpt
.cmd
[R300_VPT_ZOFFSET
] = r300PackFloat32(tz
);
917 static void r300Viewport(GLcontext
* ctx
, GLint x
, GLint y
,
918 GLsizei width
, GLsizei height
)
920 /* Don't pipeline viewport changes, conflict with window offset
921 * setting below. Could apply deltas to rescue pipelined viewport
922 * values, or keep the originals hanging around.
924 r300UpdateWindow(ctx
);
927 static void r300DepthRange(GLcontext
* ctx
, GLclampd nearval
, GLclampd farval
)
929 r300UpdateWindow(ctx
);
932 void r300UpdateViewportOffset(GLcontext
* ctx
)
934 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
935 __DRIdrawablePrivate
*dPriv
= ((radeonContextPtr
) rmesa
)->dri
.drawable
;
936 GLfloat xoffset
= (GLfloat
) dPriv
->x
;
937 GLfloat yoffset
= (GLfloat
) dPriv
->y
+ dPriv
->h
;
938 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
940 GLfloat tx
= v
[MAT_TX
] + xoffset
+ SUBPIXEL_X
;
941 GLfloat ty
= (-v
[MAT_TY
]) + yoffset
+ SUBPIXEL_Y
;
943 if (rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] != r300PackFloat32(tx
) ||
944 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] != r300PackFloat32(ty
)) {
945 /* Note: this should also modify whatever data the context reset
948 R300_STATECHANGE(rmesa
, vpt
);
949 rmesa
->hw
.vpt
.cmd
[R300_VPT_XOFFSET
] = r300PackFloat32(tx
);
950 rmesa
->hw
.vpt
.cmd
[R300_VPT_YOFFSET
] = r300PackFloat32(ty
);
954 radeonUpdateScissor(ctx
);
958 * Tell the card where to render (offset, pitch).
959 * Effected by glDrawBuffer, etc
961 void r300UpdateDrawBuffer(GLcontext
* ctx
)
963 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
964 r300ContextPtr r300
= rmesa
;
965 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
966 driRenderbuffer
*drb
;
968 if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
) {
971 (driRenderbuffer
*) fb
->Attachment
[BUFFER_FRONT_LEFT
].
973 } else if (fb
->_ColorDrawBufferMask
[0] == BUFFER_BIT_BACK_LEFT
) {
976 (driRenderbuffer
*) fb
->Attachment
[BUFFER_BACK_LEFT
].
979 /* drawing to multiple buffers, or none */
984 assert(drb
->flippedPitch
);
986 R300_STATECHANGE(rmesa
, cb
);
988 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] = drb
->flippedOffset
+ //r300->radeon.state.color.drawOffset +
989 r300
->radeon
.radeonScreen
->fbLocation
;
990 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = drb
->flippedPitch
; //r300->radeon.state.color.drawPitch;
992 if (r300
->radeon
.radeonScreen
->cpp
== 4)
993 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
995 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
997 if (r300
->radeon
.sarea
->tiling_enabled
)
998 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
1000 R200_STATECHANGE(rmesa
, ctx
);
1002 /* Note: we used the (possibly) page-flipped values */
1003 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLOROFFSET
]
1004 = ((drb
->flippedOffset
+ rmesa
->r200Screen
->fbLocation
)
1005 & R200_COLOROFFSET_MASK
);
1006 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] = drb
->flippedPitch
;
1008 if (rmesa
->sarea
->tiling_enabled
) {
1009 rmesa
->hw
.ctx
.cmd
[CTX_RB3D_COLORPITCH
] |=
1010 R200_COLOR_TILE_ENABLE
;
1016 r300FetchStateParameter(GLcontext
* ctx
,
1017 const gl_state_index state
[STATE_LENGTH
],
1020 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1023 case STATE_INTERNAL
:
1025 case STATE_R300_WINDOW_DIMENSION
:
1026 value
[0] = r300
->radeon
.dri
.drawable
->w
* 0.5f
; /* width*0.5 */
1027 value
[1] = r300
->radeon
.dri
.drawable
->h
* 0.5f
; /* height*0.5 */
1028 value
[2] = 0.5F
; /* for moving range [-1 1] -> [0 1] */
1029 value
[3] = 1.0F
; /* not used */
1032 case STATE_R300_TEXRECT_FACTOR
:{
1033 struct gl_texture_object
*t
=
1034 ctx
->Texture
.Unit
[state
[2]].CurrentRect
;
1036 if (t
&& t
->Image
[0][t
->BaseLevel
]) {
1037 struct gl_texture_image
*image
=
1038 t
->Image
[0][t
->BaseLevel
];
1039 value
[0] = 1.0 / image
->Width2
;
1040 value
[1] = 1.0 / image
->Height2
;
1061 * Update R300's own internal state parameters.
1062 * For now just STATE_R300_WINDOW_DIMENSION
1064 void r300UpdateStateParameters(GLcontext
* ctx
, GLuint new_state
)
1066 struct r300_fragment_program
*fp
;
1067 struct gl_program_parameter_list
*paramList
;
1070 if (!(new_state
& (_NEW_BUFFERS
| _NEW_PROGRAM
)))
1073 fp
= (struct r300_fragment_program
*)ctx
->FragmentProgram
._Current
;
1077 paramList
= fp
->mesa_program
.Base
.Parameters
;
1082 for (i
= 0; i
< paramList
->NumParameters
; i
++) {
1083 if (paramList
->Parameters
[i
].Type
== PROGRAM_STATE_VAR
) {
1084 r300FetchStateParameter(ctx
,
1085 paramList
->Parameters
[i
].
1087 paramList
->ParameterValues
[i
]);
1092 /* =============================================================
1095 static void r300PolygonOffset(GLcontext
* ctx
, GLfloat factor
, GLfloat units
)
1097 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
1098 GLfloat constant
= units
;
1100 switch (ctx
->Visual
.depthBits
) {
1111 /* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
1113 R300_STATECHANGE(rmesa
, zbs
);
1114 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_FACTOR
] = r300PackFloat32(factor
);
1115 rmesa
->hw
.zbs
.cmd
[R300_ZBS_T_CONSTANT
] = r300PackFloat32(constant
);
1116 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_FACTOR
] = r300PackFloat32(factor
);
1117 rmesa
->hw
.zbs
.cmd
[R300_ZBS_W_CONSTANT
] = r300PackFloat32(constant
);
1120 /* Routing and texture-related */
1122 /* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST.
1123 * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead.
1124 * We need to recalculate wrap modes whenever filter mode is changed because someone might do:
1125 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1126 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1127 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1128 * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle
1129 * combinations where only one of them is nearest.
1131 static unsigned long gen_fixed_filter(unsigned long f
)
1133 unsigned long mag
, min
, needs_fixing
= 0;
1136 /* We ignore MIRROR bit so we dont have to do everything twice */
1137 if ((f
& ((7 - 1) << R300_TX_WRAP_S_SHIFT
)) ==
1138 (R300_TX_CLAMP
<< R300_TX_WRAP_S_SHIFT
)) {
1141 if ((f
& ((7 - 1) << R300_TX_WRAP_T_SHIFT
)) ==
1142 (R300_TX_CLAMP
<< R300_TX_WRAP_T_SHIFT
)) {
1145 if ((f
& ((7 - 1) << R300_TX_WRAP_Q_SHIFT
)) ==
1146 (R300_TX_CLAMP
<< R300_TX_WRAP_Q_SHIFT
)) {
1153 mag
= f
& R300_TX_MAG_FILTER_MASK
;
1154 min
= f
& R300_TX_MIN_FILTER_MASK
;
1156 /* TODO: Check for anisto filters too */
1157 if ((mag
!= R300_TX_MAG_FILTER_NEAREST
)
1158 && (min
!= R300_TX_MIN_FILTER_NEAREST
))
1161 /* r300 cant handle these modes hence we force nearest to linear */
1162 if ((mag
== R300_TX_MAG_FILTER_NEAREST
)
1163 && (min
!= R300_TX_MIN_FILTER_NEAREST
)) {
1164 f
&= ~R300_TX_MAG_FILTER_NEAREST
;
1165 f
|= R300_TX_MAG_FILTER_LINEAR
;
1169 if ((min
== R300_TX_MIN_FILTER_NEAREST
)
1170 && (mag
!= R300_TX_MAG_FILTER_NEAREST
)) {
1171 f
&= ~R300_TX_MIN_FILTER_NEAREST
;
1172 f
|= R300_TX_MIN_FILTER_LINEAR
;
1176 /* Both are nearest */
1177 if (needs_fixing
& 1) {
1178 f
&= ~((7 - 1) << R300_TX_WRAP_S_SHIFT
);
1179 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
;
1181 if (needs_fixing
& 2) {
1182 f
&= ~((7 - 1) << R300_TX_WRAP_T_SHIFT
);
1183 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
;
1185 if (needs_fixing
& 4) {
1186 f
&= ~((7 - 1) << R300_TX_WRAP_Q_SHIFT
);
1187 f
|= R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_Q_SHIFT
;
1192 static void r300SetupTextures(GLcontext
* ctx
)
1195 struct r300_tex_obj
*t
;
1196 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1198 int last_hw_tmu
= -1; /* -1 translates into no setup costs for fields */
1199 int tmu_mappings
[R300_MAX_TEXTURE_UNITS
] = { -1, };
1200 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
1201 (char *)ctx
->FragmentProgram
._Current
;
1203 R300_STATECHANGE(r300
, txe
);
1204 R300_STATECHANGE(r300
, tex
.filter
);
1205 R300_STATECHANGE(r300
, tex
.filter_1
);
1206 R300_STATECHANGE(r300
, tex
.size
);
1207 R300_STATECHANGE(r300
, tex
.format
);
1208 R300_STATECHANGE(r300
, tex
.pitch
);
1209 R300_STATECHANGE(r300
, tex
.offset
);
1210 R300_STATECHANGE(r300
, tex
.chroma_key
);
1211 R300_STATECHANGE(r300
, tex
.border_color
);
1213 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] = 0x0;
1215 mtu
= r300
->radeon
.glCtx
->Const
.MaxTextureUnits
;
1216 if (RADEON_DEBUG
& DEBUG_STATE
)
1217 fprintf(stderr
, "mtu=%d\n", mtu
);
1219 if (mtu
> R300_MAX_TEXTURE_UNITS
) {
1221 "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
1222 mtu
, R300_MAX_TEXTURE_UNITS
);
1226 /* We cannot let disabled tmu offsets pass DRM */
1227 for (i
= 0; i
< mtu
; i
++) {
1228 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
1230 #if 0 /* Enables old behaviour */
1233 tmu_mappings
[i
] = hw_tmu
;
1235 t
= r300
->state
.texture
.unit
[i
].texobj
;
1236 /* XXX questionable fix for bug 9170: */
1240 if ((t
->format
& 0xffffff00) == 0xffffff00) {
1242 ("unknown texture format (entry %x) encountered. Help me !\n",
1246 if (RADEON_DEBUG
& DEBUG_STATE
)
1248 "Activating texture unit %d\n", i
);
1250 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
] |= (1 << hw_tmu
);
1252 r300
->hw
.tex
.filter
.cmd
[R300_TEX_VALUE_0
+
1254 gen_fixed_filter(t
->filter
) | (hw_tmu
<< 28);
1255 /* Currently disabled! */
1256 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] = 0x0; //0x20501f80;
1257 r300
->hw
.tex
.size
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1259 r300
->hw
.tex
.format
.cmd
[R300_TEX_VALUE_0
+
1260 hw_tmu
] = t
->format
;
1261 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_VALUE_0
+ hw_tmu
] =
1263 r300
->hw
.tex
.offset
.cmd
[R300_TEX_VALUE_0
+
1264 hw_tmu
] = t
->offset
;
1266 if (t
->offset
& R300_TXO_MACRO_TILE
) {
1267 WARN_ONCE("macro tiling enabled!\n");
1270 if (t
->offset
& R300_TXO_MICRO_TILE
) {
1271 WARN_ONCE("micro tiling enabled!\n");
1274 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_VALUE_0
+
1276 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_VALUE_0
+
1280 last_hw_tmu
= hw_tmu
;
1286 r300
->hw
.tex
.filter
.cmd
[R300_TEX_CMD_0
] =
1287 cmdpacket0(R300_TX_FILTER_0
, last_hw_tmu
+ 1);
1288 r300
->hw
.tex
.filter_1
.cmd
[R300_TEX_CMD_0
] =
1289 cmdpacket0(R300_TX_FILTER1_0
, last_hw_tmu
+ 1);
1290 r300
->hw
.tex
.size
.cmd
[R300_TEX_CMD_0
] =
1291 cmdpacket0(R300_TX_SIZE_0
, last_hw_tmu
+ 1);
1292 r300
->hw
.tex
.format
.cmd
[R300_TEX_CMD_0
] =
1293 cmdpacket0(R300_TX_FORMAT_0
, last_hw_tmu
+ 1);
1294 r300
->hw
.tex
.pitch
.cmd
[R300_TEX_CMD_0
] =
1295 cmdpacket0(R300_TX_PITCH_0
, last_hw_tmu
+ 1);
1296 r300
->hw
.tex
.offset
.cmd
[R300_TEX_CMD_0
] =
1297 cmdpacket0(R300_TX_OFFSET_0
, last_hw_tmu
+ 1);
1298 r300
->hw
.tex
.chroma_key
.cmd
[R300_TEX_CMD_0
] =
1299 cmdpacket0(R300_TX_CHROMA_KEY_0
, last_hw_tmu
+ 1);
1300 r300
->hw
.tex
.border_color
.cmd
[R300_TEX_CMD_0
] =
1301 cmdpacket0(R300_TX_BORDER_COLOR_0
, last_hw_tmu
+ 1);
1303 if (!fp
) /* should only happenen once, just after context is created */
1306 R300_STATECHANGE(r300
, fpt
);
1308 for (i
= 0; i
< fp
->tex
.length
; i
++) {
1313 unit
= fp
->tex
.inst
[i
] >> R300_FPITX_IMAGE_SHIFT
;
1316 val
= fp
->tex
.inst
[i
];
1317 val
&= ~R300_FPITX_IMAGE_MASK
;
1320 (val
& R300_FPITX_OPCODE_MASK
) >> R300_FPITX_OPCODE_SHIFT
;
1321 if (opcode
== R300_FPITX_OP_KIL
) {
1322 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1324 if (tmu_mappings
[unit
] >= 0) {
1326 tmu_mappings
[unit
] <<
1327 R300_FPITX_IMAGE_SHIFT
;
1328 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1330 // We get here when the corresponding texture image is incomplete
1331 // (e.g. incomplete mipmaps etc.)
1332 r300
->hw
.fpt
.cmd
[R300_FPT_INSTR_0
+ i
] = val
;
1337 r300
->hw
.fpt
.cmd
[R300_FPT_CMD_0
] =
1338 cmdpacket0(R300_PFS_TEXI_0
, fp
->tex
.length
);
1340 if (RADEON_DEBUG
& DEBUG_STATE
)
1341 fprintf(stderr
, "TX_ENABLE: %08x last_hw_tmu=%d\n",
1342 r300
->hw
.txe
.cmd
[R300_TXE_ENABLE
], last_hw_tmu
);
1345 union r300_outputs_written
{
1346 GLuint vp_outputs
; /* hw_tcl_on */
1347 DECLARE_RENDERINPUTS(index_bitset
); /* !hw_tcl_on */
1350 #define R300_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \
1351 ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \
1352 RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) ))
1354 static void r300SetupRSUnit(GLcontext
* ctx
)
1356 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1357 /* I'm still unsure if these are needed */
1358 GLuint interp_magic
[8] = {
1360 R300_RS_INTERP_1_UNKNOWN
,
1361 R300_RS_INTERP_2_UNKNOWN
,
1362 R300_RS_INTERP_3_UNKNOWN
,
1368 union r300_outputs_written OutputsWritten
;
1370 int fp_reg
, high_rr
;
1371 int in_texcoords
, col_interp_nr
;
1375 OutputsWritten
.vp_outputs
= CURRENT_VERTEX_SHADER(ctx
)->key
.OutputsWritten
;
1377 RENDERINPUTS_COPY(OutputsWritten
.index_bitset
, r300
->state
.render_inputs_bitset
);
1379 if (ctx
->FragmentProgram
._Current
)
1380 InputsRead
= ctx
->FragmentProgram
._Current
->Base
.InputsRead
;
1382 fprintf(stderr
, "No ctx->FragmentProgram._Current!!\n");
1383 return; /* This should only ever happen once.. */
1386 R300_STATECHANGE(r300
, ri
);
1387 R300_STATECHANGE(r300
, rc
);
1388 R300_STATECHANGE(r300
, rr
);
1390 fp_reg
= in_texcoords
= col_interp_nr
= high_rr
= 0;
1392 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] = 0;
1394 if (InputsRead
& FRAG_BIT_WPOS
) {
1395 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
1396 if (!(InputsRead
& (FRAG_BIT_TEX0
<< i
)))
1399 if (i
== ctx
->Const
.MaxTextureUnits
) {
1400 fprintf(stderr
, "\tno free texcoord found...\n");
1404 InputsRead
|= (FRAG_BIT_TEX0
<< i
);
1405 InputsRead
&= ~FRAG_BIT_WPOS
;
1408 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
1409 r300
->hw
.ri
.cmd
[R300_RI_INTERP_0
+ i
] = 0 | R300_RS_INTERP_USED
| (in_texcoords
<< R300_RS_INTERP_SRC_SHIFT
)
1412 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] = 0;
1413 if (InputsRead
& (FRAG_BIT_TEX0
<< i
)) {
1414 //assert(r300->state.texture.tc_count != 0);
1415 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
+ fp_reg
] |= R300_RS_ROUTE_ENABLE
| i
/* source INTERP */
1416 | (fp_reg
<< R300_RS_ROUTE_DEST_SHIFT
);
1419 /* Passing invalid data here can lock the GPU. */
1420 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1421 InputsRead
&= ~(FRAG_BIT_TEX0
<< i
);
1424 WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i
);
1427 /* Need to count all coords enabled at vof */
1428 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_TEX0
+ i
, _TNL_ATTRIB_TEX(i
))) {
1433 if (InputsRead
& FRAG_BIT_COL0
) {
1434 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL0
, _TNL_ATTRIB_COLOR0
)) {
1435 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0 | R300_RS_ROUTE_0_COLOR
| (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1436 InputsRead
&= ~FRAG_BIT_COL0
;
1439 WARN_ONCE("fragprog wants col0, vp doesn't provide it\n");
1443 if (InputsRead
& FRAG_BIT_COL1
) {
1444 if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten
, VERT_RESULT_COL1
, _TNL_ATTRIB_COLOR1
)) {
1445 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_1
] |= R300_RS_ROUTE_1_UNKNOWN11
| R300_RS_ROUTE_1_COLOR1
| (fp_reg
++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT
);
1446 InputsRead
&= ~FRAG_BIT_COL1
;
1451 WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
1455 /* Need at least one. This might still lock as the values are undefined... */
1456 if (in_texcoords
== 0 && col_interp_nr
== 0) {
1457 r300
->hw
.rr
.cmd
[R300_RR_ROUTE_0
] |= 0 | R300_RS_ROUTE_0_COLOR
| (fp_reg
++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT
);
1461 r300
->hw
.rc
.cmd
[1] = 0 | (in_texcoords
<< R300_RS_CNTL_TC_CNT_SHIFT
)
1462 | (col_interp_nr
<< R300_RS_CNTL_CI_CNT_SHIFT
)
1463 | R300_RS_CNTL_0_UNKNOWN_18
;
1465 assert(high_rr
>= 0);
1466 r300
->hw
.rr
.cmd
[R300_RR_CMD_0
] = cmdpacket0(R300_RS_ROUTE_0
, high_rr
+ 1);
1467 r300
->hw
.rc
.cmd
[2] = 0xC0 | high_rr
;
1470 WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead
);
1473 #define bump_vpu_count(ptr, new_count) do{\
1474 drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
1475 int _nc=(new_count)/4; \
1476 assert(_nc < 256); \
1477 if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
1480 static inline void r300SetupVertexProgramFragment(r300ContextPtr r300
, int dest
, struct r300_vertex_shader_fragment
*vsf
)
1484 if (vsf
->length
== 0)
1487 if (vsf
->length
& 0x3) {
1488 fprintf(stderr
, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
1492 switch ((dest
>> 8) & 0xf) {
1494 R300_STATECHANGE(r300
, vpi
);
1495 for (i
= 0; i
< vsf
->length
; i
++)
1496 r300
->hw
.vpi
.cmd
[R300_VPI_INSTR_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1497 bump_vpu_count(r300
->hw
.vpi
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1501 R300_STATECHANGE(r300
, vpp
);
1502 for (i
= 0; i
< vsf
->length
; i
++)
1503 r300
->hw
.vpp
.cmd
[R300_VPP_PARAM_0
+ i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1504 bump_vpu_count(r300
->hw
.vpp
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1507 R300_STATECHANGE(r300
, vps
);
1508 for (i
= 0; i
< vsf
->length
; i
++)
1509 r300
->hw
.vps
.cmd
[1 + i
+ 4 * (dest
& 0xff)] = (vsf
->body
.d
[i
]);
1510 bump_vpu_count(r300
->hw
.vps
.cmd
, vsf
->length
+ 4 * (dest
& 0xff));
1513 fprintf(stderr
, "%s:%s don't know how to handle dest %04x\n", __FILE__
, __FUNCTION__
, dest
);
1518 static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa
)
1520 struct r300_vertex_shader_state
*prog
= &(rmesa
->state
.vertex_shader
);
1524 int param_count
= 0;
1525 int program_end
= 0;
1527 for (i
= VERT_ATTRIB_POS
; i
< VERT_ATTRIB_MAX
; i
++) {
1528 if (rmesa
->state
.sw_tcl_inputs
[i
] != -1) {
1529 prog
->program
.body
.i
[program_end
].op
= EASY_VSF_OP(MUL
, o_reg
++, ALL
, RESULT
);
1530 prog
->program
.body
.i
[program_end
].src
[0] = VSF_REG(rmesa
->state
.sw_tcl_inputs
[i
]);
1531 prog
->program
.body
.i
[program_end
].src
[1] = VSF_ATTR_UNITY(rmesa
->state
.sw_tcl_inputs
[i
]);
1532 prog
->program
.body
.i
[program_end
].src
[2] = VSF_UNITY(rmesa
->state
.sw_tcl_inputs
[i
]);
1537 prog
->program
.length
= program_end
* 4;
1539 r300SetupVertexProgramFragment(rmesa
, VSF_DEST_PROGRAM
, &(prog
->program
));
1540 inst_count
= (prog
->program
.length
/ 4) - 1;
1542 R300_STATECHANGE(rmesa
, pvs
);
1543 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
1544 (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
) |
1545 (inst_count
<< R300_PVS_CNTL_1_POS_END_SHIFT
) |
1546 (inst_count
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1547 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
1548 (0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
) |
1549 (param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1550 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
1551 (inst_count
<< R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
) |
1552 (inst_count
<< R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT
);
1555 static void r300SetupRealVertexProgram(r300ContextPtr rmesa
)
1557 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1558 struct r300_vertex_program
*prog
= (struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
);
1560 int param_count
= 0;
1562 /* FIXME: r300SetupVertexProgramFragment */
1563 R300_STATECHANGE(rmesa
, vpp
);
1565 r300VertexProgUpdateParams(ctx
,
1566 (struct r300_vertex_program_cont
*)
1567 ctx
->VertexProgram
._Current
,
1568 (float *)&rmesa
->hw
.vpp
.
1569 cmd
[R300_VPP_PARAM_0
]);
1570 bump_vpu_count(rmesa
->hw
.vpp
.cmd
, param_count
);
1573 r300SetupVertexProgramFragment(rmesa
, VSF_DEST_PROGRAM
, &(prog
->program
));
1574 inst_count
= (prog
->program
.length
/ 4) - 1;
1576 R300_STATECHANGE(rmesa
, pvs
);
1577 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_1
] =
1578 (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT
) |
1579 (inst_count
<< R300_PVS_CNTL_1_POS_END_SHIFT
) |
1580 (inst_count
<< R300_PVS_CNTL_1_PROGRAM_END_SHIFT
);
1581 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_2
] =
1582 (0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT
) |
1583 (param_count
<< R300_PVS_CNTL_2_PARAM_COUNT_SHIFT
);
1584 rmesa
->hw
.pvs
.cmd
[R300_PVS_CNTL_3
] =
1585 (inst_count
<< R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT
) |
1586 (inst_count
<< R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT
);
1589 static void r300SetupVertexProgram(r300ContextPtr rmesa
)
1591 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
1593 /* Reset state, in case we don't use something */
1594 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpp
.cmd
)->vpu
.count
= 0;
1595 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vpi
.cmd
)->vpu
.count
= 0;
1596 ((drm_r300_cmd_header_t
*) rmesa
->hw
.vps
.cmd
)->vpu
.count
= 0;
1598 /* Not sure why this doesnt work...
1599 0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
1600 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. */
1601 //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
1602 if (hw_tcl_on
&& ((struct r300_vertex_program
*)CURRENT_VERTEX_SHADER(ctx
))->translated
) {
1603 r300SetupRealVertexProgram(rmesa
);
1605 /* FIXME: This needs to be replaced by vertex shader generation code. */
1606 r300SetupDefaultVertexProgram(rmesa
);
1610 /* FIXME: This is done for vertex shader fragments, but also needs to be
1611 * done for vap_pvs, so I leave it as a reminder. */
1613 reg_start(R300_VAP_PVS_WAITIDLE
, 0);
1619 * Enable/Disable states.
1621 * \note Mesa already filters redundant calls to this function.
1623 static void r300Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
1625 r300ContextPtr r300
= R300_CONTEXT(ctx
);
1627 if (RADEON_DEBUG
& DEBUG_STATE
)
1628 fprintf(stderr
, "%s( %s = %s )\n", __FUNCTION__
,
1629 _mesa_lookup_enum_by_nr(cap
),
1630 state
? "GL_TRUE" : "GL_FALSE");
1633 /* Fast track this one...
1641 R300_STATECHANGE(r300
, fogs
);
1643 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] |= R300_FOG_ENABLE
;
1645 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
1646 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
1647 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
1648 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
1649 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
1651 r300
->hw
.fogs
.cmd
[R300_FOGS_STATE
] &= ~R300_FOG_ENABLE
;
1657 r300SetAlphaState(ctx
);
1661 case GL_COLOR_LOGIC_OP
:
1662 r300SetBlendState(ctx
);
1666 r300SetDepthState(ctx
);
1669 case GL_STENCIL_TEST
:
1670 if (r300
->state
.stencil
.hw_stencil
) {
1671 R300_STATECHANGE(r300
, zs
);
1673 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] |=
1674 R300_RB3D_STENCIL_ENABLE
;
1676 r300
->hw
.zs
.cmd
[R300_ZS_CNTL_0
] &=
1677 ~R300_RB3D_STENCIL_ENABLE
;
1681 FALLBACK(&r300
->radeon
, RADEON_FALLBACK_STENCIL
, state
);
1687 r300UpdateCulling(ctx
);
1690 case GL_POLYGON_OFFSET_POINT
:
1691 case GL_POLYGON_OFFSET_LINE
:
1692 case GL_POLYGON_OFFSET_FILL
:
1693 R300_STATECHANGE(r300
, occlusion_cntl
);
1695 r300
->hw
.occlusion_cntl
.cmd
[1] |= (3 << 0);
1697 r300
->hw
.occlusion_cntl
.cmd
[1] &= ~(3 << 0);
1701 radeonEnable(ctx
, cap
, state
);
1707 * Completely recalculates hardware state based on the Mesa state.
1709 static void r300ResetHwState(r300ContextPtr r300
)
1711 GLcontext
*ctx
= r300
->radeon
.glCtx
;
1714 if (!(r300
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
1717 if (RADEON_DEBUG
& DEBUG_STATE
)
1718 fprintf(stderr
, "%s\n", __FUNCTION__
);
1720 r300UpdateWindow(ctx
);
1723 ctx
->Color
.ColorMask
[RCOMP
],
1724 ctx
->Color
.ColorMask
[GCOMP
],
1725 ctx
->Color
.ColorMask
[BCOMP
], ctx
->Color
.ColorMask
[ACOMP
]);
1727 r300Enable(ctx
, GL_DEPTH_TEST
, ctx
->Depth
.Test
);
1728 r300DepthMask(ctx
, ctx
->Depth
.Mask
);
1729 r300DepthFunc(ctx
, ctx
->Depth
.Func
);
1732 r300Enable(ctx
, GL_STENCIL_TEST
, ctx
->Stencil
.Enabled
);
1733 r300StencilMaskSeparate(ctx
, 0, ctx
->Stencil
.WriteMask
[0]);
1734 r300StencilFuncSeparate(ctx
, 0, ctx
->Stencil
.Function
[0],
1735 ctx
->Stencil
.Ref
[0], ctx
->Stencil
.ValueMask
[0]);
1736 r300StencilOpSeparate(ctx
, 0, ctx
->Stencil
.FailFunc
[0],
1737 ctx
->Stencil
.ZFailFunc
[0],
1738 ctx
->Stencil
.ZPassFunc
[0]);
1740 r300UpdateCulling(ctx
);
1742 r300UpdateTextureState(ctx
);
1744 r300SetBlendState(ctx
);
1746 r300AlphaFunc(ctx
, ctx
->Color
.AlphaFunc
, ctx
->Color
.AlphaRef
);
1747 r300Enable(ctx
, GL_ALPHA_TEST
, ctx
->Color
.AlphaEnabled
);
1750 r300
->hw
.vap_cntl
.cmd
[1] = 0x0014045a;
1752 r300
->hw
.vap_cntl
.cmd
[1] = 0x0030045A; //0x0030065a /* Dangerous */
1754 r300
->hw
.vte
.cmd
[1] = R300_VPORT_X_SCALE_ENA
1755 | R300_VPORT_X_OFFSET_ENA
1756 | R300_VPORT_Y_SCALE_ENA
1757 | R300_VPORT_Y_OFFSET_ENA
1758 | R300_VPORT_Z_SCALE_ENA
1759 | R300_VPORT_Z_OFFSET_ENA
| R300_VTX_W0_FMT
;
1760 r300
->hw
.vte
.cmd
[2] = 0x00000008;
1762 r300
->hw
.unk2134
.cmd
[1] = 0x00FFFFFF;
1763 r300
->hw
.unk2134
.cmd
[2] = 0x00000000;
1765 #ifdef MESA_LITTLE_ENDIAN
1766 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_NO_SWAP
;
1768 r300
->hw
.vap_cntl_status
.cmd
[1] = R300_VC_32BIT_SWAP
;
1771 /* disable VAP/TCL on non-TCL capable chips */
1773 r300
->hw
.vap_cntl_status
.cmd
[1] |= R300_VAP_TCL_BYPASS
;
1775 r300
->hw
.unk21DC
.cmd
[1] = 0xAAAAAAAA;
1777 r300
->hw
.unk221C
.cmd
[1] = R300_221C_NORMAL
;
1779 r300
->hw
.vap_clip
.cmd
[1] = r300PackFloat32(1.0); /* X */
1780 r300
->hw
.vap_clip
.cmd
[2] = r300PackFloat32(1.0); /* X */
1781 r300
->hw
.vap_clip
.cmd
[3] = r300PackFloat32(1.0); /* Y */
1782 r300
->hw
.vap_clip
.cmd
[4] = r300PackFloat32(1.0); /* Y */
1784 /* XXX: Other families? */
1786 switch (r300
->radeon
.radeonScreen
->chip_family
) {
1787 case CHIP_FAMILY_R300
:
1788 r300
->hw
.unk2288
.cmd
[1] = R300_2288_R300
;
1791 r300
->hw
.unk2288
.cmd
[1] = R300_2288_RV350
;
1796 r300
->hw
.gb_enable
.cmd
[1] = R300_GB_POINT_STUFF_ENABLE
1797 | R300_GB_LINE_STUFF_ENABLE
1798 | R300_GB_TRIANGLE_STUFF_ENABLE
/*| R300_GB_UNK31 */ ;
1800 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_0
] = 0x66666666;
1801 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_MSPOS_1
] = 0x06666666;
1803 /* XXX: Other families? */
1804 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] =
1805 R300_GB_TILE_ENABLE
| R300_GB_TILE_SIZE_16
;
1806 switch (r300
->radeon
.radeonScreen
->chip_family
) {
1807 case CHIP_FAMILY_R300
:
1808 case CHIP_FAMILY_R350
:
1809 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
1810 R300_GB_TILE_PIPE_COUNT_R300
;
1812 case CHIP_FAMILY_RV410
:
1813 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
1814 R300_GB_TILE_PIPE_COUNT_RV410
;
1816 case CHIP_FAMILY_R420
:
1817 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
1818 R300_GB_TILE_PIPE_COUNT_R420
;
1821 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_TILE_CONFIG
] |=
1822 R300_GB_TILE_PIPE_COUNT_RV300
;
1826 /* XXX: set to 0 when fog is disabled? */
1827 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_SELECT
] = R300_GB_FOG_SELECT_1_1_W
;
1829 /* XXX: Enable anti-aliasing? */
1830 r300
->hw
.gb_misc
.cmd
[R300_GB_MISC_AA_CONFIG
] = R300_AA_DISABLE
;
1832 r300
->hw
.unk4200
.cmd
[1] = r300PackFloat32(0.0);
1833 r300
->hw
.unk4200
.cmd
[2] = r300PackFloat32(0.0);
1834 r300
->hw
.unk4200
.cmd
[3] = r300PackFloat32(1.0);
1835 r300
->hw
.unk4200
.cmd
[4] = r300PackFloat32(1.0);
1837 r300
->hw
.unk4214
.cmd
[1] = 0x00050005;
1839 r300PointSize(ctx
, 1.0);
1841 r300
->hw
.unk4230
.cmd
[1] = 0x18000006;
1842 r300
->hw
.unk4230
.cmd
[2] = 0x00020006;
1843 r300
->hw
.unk4230
.cmd
[3] = r300PackFloat32(1.0 / 192.0);
1845 r300LineWidth(ctx
, 1.0);
1847 r300
->hw
.unk4260
.cmd
[1] = 0;
1848 r300
->hw
.unk4260
.cmd
[2] = r300PackFloat32(0.0);
1849 r300
->hw
.unk4260
.cmd
[3] = r300PackFloat32(1.0);
1851 r300
->hw
.shade
.cmd
[1] = 0x00000002;
1852 r300ShadeModel(ctx
, ctx
->Light
.ShadeModel
);
1853 r300
->hw
.shade
.cmd
[3] = 0x00000000;
1854 r300
->hw
.shade
.cmd
[4] = 0x00000000;
1856 r300PolygonMode(ctx
, GL_FRONT
, ctx
->Polygon
.FrontMode
);
1857 r300PolygonMode(ctx
, GL_BACK
, ctx
->Polygon
.BackMode
);
1858 r300
->hw
.polygon_mode
.cmd
[2] = 0x00000001;
1859 r300
->hw
.polygon_mode
.cmd
[3] = 0x00000000;
1860 r300
->hw
.zbias_cntl
.cmd
[1] = 0x00000000;
1862 r300PolygonOffset(ctx
, ctx
->Polygon
.OffsetFactor
,
1863 ctx
->Polygon
.OffsetUnits
);
1864 r300Enable(ctx
, GL_POLYGON_OFFSET_POINT
, ctx
->Polygon
.OffsetPoint
);
1865 r300Enable(ctx
, GL_POLYGON_OFFSET_LINE
, ctx
->Polygon
.OffsetLine
);
1866 r300Enable(ctx
, GL_POLYGON_OFFSET_FILL
, ctx
->Polygon
.OffsetFill
);
1868 r300
->hw
.unk42C0
.cmd
[1] = 0x4B7FFFFF;
1869 r300
->hw
.unk42C0
.cmd
[2] = 0x00000000;
1871 r300
->hw
.unk43A4
.cmd
[1] = 0x0000001C;
1872 r300
->hw
.unk43A4
.cmd
[2] = 0x2DA49525;
1874 r300
->hw
.unk43E8
.cmd
[1] = 0x00FFFFFF;
1876 r300
->hw
.unk46A4
.cmd
[1] = 0x00001B01;
1877 r300
->hw
.unk46A4
.cmd
[2] = 0x00001B0F;
1878 r300
->hw
.unk46A4
.cmd
[3] = 0x00001B0F;
1879 r300
->hw
.unk46A4
.cmd
[4] = 0x00001B0F;
1880 r300
->hw
.unk46A4
.cmd
[5] = 0x00000001;
1882 r300Enable(ctx
, GL_FOG
, ctx
->Fog
.Enabled
);
1883 r300Fogfv(ctx
, GL_FOG_MODE
, NULL
);
1884 r300Fogfv(ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
1885 r300Fogfv(ctx
, GL_FOG_START
, &ctx
->Fog
.Start
);
1886 r300Fogfv(ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
1887 r300Fogfv(ctx
, GL_FOG_COLOR
, ctx
->Fog
.Color
);
1888 r300Fogfv(ctx
, GL_FOG_COORDINATE_SOURCE_EXT
, NULL
);
1890 r300
->hw
.at
.cmd
[R300_AT_UNKNOWN
] = 0;
1891 r300
->hw
.unk4BD8
.cmd
[1] = 0;
1893 r300
->hw
.unk4E00
.cmd
[1] = 0;
1895 r300BlendColor(ctx
, ctx
->Color
.BlendColor
);
1896 r300
->hw
.blend_color
.cmd
[2] = 0;
1897 r300
->hw
.blend_color
.cmd
[3] = 0;
1899 /* Again, r300ClearBuffer uses this */
1900 r300
->hw
.cb
.cmd
[R300_CB_OFFSET
] =
1901 r300
->radeon
.state
.color
.drawOffset
+
1902 r300
->radeon
.radeonScreen
->fbLocation
;
1903 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] = r300
->radeon
.state
.color
.drawPitch
;
1905 if (r300
->radeon
.radeonScreen
->cpp
== 4)
1906 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_ARGB8888
;
1908 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_FORMAT_RGB565
;
1910 if (r300
->radeon
.sarea
->tiling_enabled
)
1911 r300
->hw
.cb
.cmd
[R300_CB_PITCH
] |= R300_COLOR_TILE_ENABLE
;
1913 r300
->hw
.unk4E50
.cmd
[1] = 0;
1914 r300
->hw
.unk4E50
.cmd
[2] = 0;
1915 r300
->hw
.unk4E50
.cmd
[3] = 0;
1916 r300
->hw
.unk4E50
.cmd
[4] = 0;
1917 r300
->hw
.unk4E50
.cmd
[5] = 0;
1918 r300
->hw
.unk4E50
.cmd
[6] = 0;
1919 r300
->hw
.unk4E50
.cmd
[7] = 0;
1920 r300
->hw
.unk4E50
.cmd
[8] = 0;
1921 r300
->hw
.unk4E50
.cmd
[9] = 0;
1923 r300
->hw
.unk4E88
.cmd
[1] = 0;
1925 r300
->hw
.unk4EA0
.cmd
[1] = 0x00000000;
1926 r300
->hw
.unk4EA0
.cmd
[2] = 0xffffffff;
1928 switch (ctx
->Visual
.depthBits
) {
1930 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTH_FORMAT_16BIT_INT_Z
;
1933 r300
->hw
.zstencil_format
.cmd
[1] = R300_DEPTH_FORMAT_24BIT_INT_Z
;
1936 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
1937 ctx
->Visual
.depthBits
);
1942 //r300->hw.zstencil_format.cmd[1] |= R300_DEPTH_FORMAT_UNK32;
1944 r300
->hw
.zstencil_format
.cmd
[3] = 0x00000003;
1945 r300
->hw
.zstencil_format
.cmd
[4] = 0x00000000;
1947 r300
->hw
.zb
.cmd
[R300_ZB_OFFSET
] =
1948 r300
->radeon
.radeonScreen
->depthOffset
+
1949 r300
->radeon
.radeonScreen
->fbLocation
;
1950 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] = r300
->radeon
.radeonScreen
->depthPitch
;
1952 if (r300
->radeon
.sarea
->tiling_enabled
) {
1953 /* XXX: Turn off when clearing buffers ? */
1954 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |= R300_DEPTH_TILE_ENABLE
;
1956 if (ctx
->Visual
.depthBits
== 24)
1957 r300
->hw
.zb
.cmd
[R300_ZB_PITCH
] |=
1958 R300_DEPTH_MICROTILE_ENABLE
;
1961 r300
->hw
.unk4F28
.cmd
[1] = 0;
1963 r300
->hw
.unk4F30
.cmd
[1] = 0;
1964 r300
->hw
.unk4F30
.cmd
[2] = 0;
1966 r300
->hw
.unk4F44
.cmd
[1] = 0;
1968 r300
->hw
.unk4F54
.cmd
[1] = 0;
1971 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_0
] = 0;
1972 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_1
] = 0;
1973 r300
->hw
.vps
.cmd
[R300_VPS_POINTSIZE
] = r300PackFloat32(1.0);
1974 r300
->hw
.vps
.cmd
[R300_VPS_ZERO_3
] = 0;
1977 r300
->hw
.all_dirty
= GL_TRUE
;
1980 void r300UpdateShaders(r300ContextPtr rmesa
)
1983 struct r300_vertex_program
*vp
;
1986 ctx
= rmesa
->radeon
.glCtx
;
1988 if (rmesa
->NewGLState
&& hw_tcl_on
) {
1989 rmesa
->NewGLState
= 0;
1991 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
1992 rmesa
->temp_attrib
[i
] =
1993 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
];
1994 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
1995 &rmesa
->dummy_attrib
[i
];
1998 _tnl_UpdateFixedFunctionProgram(ctx
);
2000 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
2001 TNL_CONTEXT(ctx
)->vb
.AttribPtr
[i
] =
2002 rmesa
->temp_attrib
[i
];
2005 r300SelectVertexShader(rmesa
);
2006 vp
= (struct r300_vertex_program
*)
2007 CURRENT_VERTEX_SHADER(ctx
);
2008 /*if (vp->translated == GL_FALSE)
2009 r300TranslateVertexShader(vp); */
2010 if (vp
->translated
== GL_FALSE
) {
2011 fprintf(stderr
, "Failing back to sw-tcl\n");
2012 hw_tcl_on
= future_hw_tcl_on
= 0;
2013 r300ResetHwState(rmesa
);
2017 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
2021 static void r300SetupPixelShader(r300ContextPtr rmesa
)
2023 GLcontext
*ctx
= rmesa
->radeon
.glCtx
;
2024 struct r300_fragment_program
*fp
= (struct r300_fragment_program
*)
2025 (char *)ctx
->FragmentProgram
._Current
;
2028 if (!fp
) /* should only happenen once, just after context is created */
2031 r300TranslateFragmentShader(rmesa
, fp
);
2032 if (!fp
->translated
) {
2033 fprintf(stderr
, "%s: No valid fragment shader, exiting\n",
2038 R300_STATECHANGE(rmesa
, fpi
[0]);
2039 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_PFS_INSTR0_0
, fp
->alu_end
+ 1);
2040 for (i
= 0; i
<= fp
->alu_end
; i
++) {
2041 rmesa
->hw
.fpi
[0].cmd
[R300_FPI_INSTR_0
+ i
] = fp
->alu
.inst
[i
].inst0
;
2044 R300_STATECHANGE(rmesa
, fpi
[1]);
2045 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_PFS_INSTR1_0
, fp
->alu_end
+ 1);
2046 for (i
= 0; i
<= fp
->alu_end
; i
++) {
2047 rmesa
->hw
.fpi
[1].cmd
[R300_FPI_INSTR_0
+ i
] = fp
->alu
.inst
[i
].inst1
;
2050 R300_STATECHANGE(rmesa
, fpi
[2]);
2051 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_PFS_INSTR2_0
, fp
->alu_end
+ 1);
2052 for (i
= 0; i
<= fp
->alu_end
; i
++) {
2053 rmesa
->hw
.fpi
[2].cmd
[R300_FPI_INSTR_0
+ i
] = fp
->alu
.inst
[i
].inst2
;
2056 R300_STATECHANGE(rmesa
, fpi
[3]);
2057 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_CMD_0
] = cmdpacket0(R300_PFS_INSTR3_0
, fp
->alu_end
+ 1);
2058 for (i
= 0; i
<= fp
->alu_end
; i
++) {
2059 rmesa
->hw
.fpi
[3].cmd
[R300_FPI_INSTR_0
+ i
] = fp
->alu
.inst
[i
].inst3
;
2062 R300_STATECHANGE(rmesa
, fp
);
2063 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL0
] = fp
->cur_node
| (fp
->first_node_has_tex
<< 3);
2064 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL1
] = fp
->max_temp_idx
;
2065 rmesa
->hw
.fp
.cmd
[R300_FP_CNTL2
] =
2066 (fp
->alu_offset
<< R300_PFS_CNTL_ALU_OFFSET_SHIFT
) |
2067 (fp
->alu_end
<< R300_PFS_CNTL_ALU_END_SHIFT
) |
2068 (fp
->tex_offset
<< R300_PFS_CNTL_TEX_OFFSET_SHIFT
) |
2069 (fp
->tex_end
<< R300_PFS_CNTL_TEX_END_SHIFT
);
2070 /* I just want to say, the way these nodes are stored.. weird.. */
2071 for (i
= 0, k
= (4 - (fp
->cur_node
+ 1)); i
< 4; i
++, k
++) {
2072 if (i
< (fp
->cur_node
+ 1)) {
2073 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ k
] =
2074 (fp
->node
[i
].alu_offset
<< R300_PFS_NODE_ALU_OFFSET_SHIFT
) |
2075 (fp
->node
[i
].alu_end
<< R300_PFS_NODE_ALU_END_SHIFT
) |
2076 (fp
->node
[i
].tex_offset
<< R300_PFS_NODE_TEX_OFFSET_SHIFT
) |
2077 (fp
->node
[i
].tex_end
<< R300_PFS_NODE_TEX_END_SHIFT
) |
2080 rmesa
->hw
.fp
.cmd
[R300_FP_NODE0
+ (3 - i
)] = 0;
2084 R300_STATECHANGE(rmesa
, fpp
);
2085 rmesa
->hw
.fpp
.cmd
[R300_FPP_CMD_0
] = cmdpacket0(R300_PFS_PARAM_0_X
, fp
->const_nr
* 4);
2086 for (i
= 0; i
< fp
->const_nr
; i
++) {
2087 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 0] = r300PackFloat24(fp
->constant
[i
][0]);
2088 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 1] = r300PackFloat24(fp
->constant
[i
][1]);
2089 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 2] = r300PackFloat24(fp
->constant
[i
][2]);
2090 rmesa
->hw
.fpp
.cmd
[R300_FPP_PARAM_0
+ 4 * i
+ 3] = r300PackFloat24(fp
->constant
[i
][3]);
2094 void r300UpdateShaderStates(r300ContextPtr rmesa
)
2097 ctx
= rmesa
->radeon
.glCtx
;
2099 r300UpdateTextureState(ctx
);
2101 r300SetupPixelShader(rmesa
);
2102 r300SetupTextures(ctx
);
2104 if ((rmesa
->radeon
.radeonScreen
->chip_flags
& RADEON_CHIPSET_TCL
))
2105 r300SetupVertexProgram(rmesa
);
2106 r300SetupRSUnit(ctx
);
2110 * Called by Mesa after an internal state update.
2112 static void r300InvalidateState(GLcontext
* ctx
, GLuint new_state
)
2114 r300ContextPtr r300
= R300_CONTEXT(ctx
);
2116 _swrast_InvalidateState(ctx
, new_state
);
2117 _swsetup_InvalidateState(ctx
, new_state
);
2118 _vbo_InvalidateState(ctx
, new_state
);
2119 _tnl_InvalidateState(ctx
, new_state
);
2120 _ae_invalidate_state(ctx
, new_state
);
2122 if (new_state
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
2123 r300UpdateDrawBuffer(ctx
);
2126 r300UpdateStateParameters(ctx
, new_state
);
2128 r300
->NewGLState
|= new_state
;
2132 * Calculate initial hardware state and register state functions.
2133 * Assumes that the command buffer and state atoms have been
2134 * initialized already.
2136 void r300InitState(r300ContextPtr r300
)
2138 GLcontext
*ctx
= r300
->radeon
.glCtx
;
2141 radeonInitState(&r300
->radeon
);
2143 switch (ctx
->Visual
.depthBits
) {
2145 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffff;
2146 depth_fmt
= R300_DEPTH_FORMAT_16BIT_INT_Z
;
2147 r300
->state
.stencil
.clear
= 0x00000000;
2150 r300
->state
.depth
.scale
= 1.0 / (GLfloat
) 0xffffff;
2151 depth_fmt
= R300_DEPTH_FORMAT_24BIT_INT_Z
;
2152 r300
->state
.stencil
.clear
= 0x00ff0000;
2155 fprintf(stderr
, "Error: Unsupported depth %d... exiting\n",
2156 ctx
->Visual
.depthBits
);
2160 /* Only have hw stencil when depth buffer is 24 bits deep */
2161 r300
->state
.stencil
.hw_stencil
= (ctx
->Visual
.stencilBits
> 0 &&
2162 ctx
->Visual
.depthBits
== 24);
2164 memset(&(r300
->state
.texture
), 0, sizeof(r300
->state
.texture
));
2166 r300ResetHwState(r300
);
2169 static void r300RenderMode(GLcontext
* ctx
, GLenum mode
)
2171 r300ContextPtr rmesa
= R300_CONTEXT(ctx
);
2177 * Initialize driver's state callback functions
2179 void r300InitStateFuncs(struct dd_function_table
*functions
)
2181 radeonInitStateFuncs(functions
);
2183 functions
->UpdateState
= r300InvalidateState
;
2184 functions
->AlphaFunc
= r300AlphaFunc
;
2185 functions
->BlendColor
= r300BlendColor
;
2186 functions
->BlendEquationSeparate
= r300BlendEquationSeparate
;
2187 functions
->BlendFuncSeparate
= r300BlendFuncSeparate
;
2188 functions
->Enable
= r300Enable
;
2189 functions
->ColorMask
= r300ColorMask
;
2190 functions
->DepthFunc
= r300DepthFunc
;
2191 functions
->DepthMask
= r300DepthMask
;
2192 functions
->CullFace
= r300CullFace
;
2193 functions
->Fogfv
= r300Fogfv
;
2194 functions
->FrontFace
= r300FrontFace
;
2195 functions
->ShadeModel
= r300ShadeModel
;
2197 /* Stencil related */
2198 functions
->ClearStencil
= r300ClearStencil
;
2199 functions
->StencilFuncSeparate
= r300StencilFuncSeparate
;
2200 functions
->StencilMaskSeparate
= r300StencilMaskSeparate
;
2201 functions
->StencilOpSeparate
= r300StencilOpSeparate
;
2203 /* Viewport related */
2204 functions
->Viewport
= r300Viewport
;
2205 functions
->DepthRange
= r300DepthRange
;
2206 functions
->PointSize
= r300PointSize
;
2207 functions
->LineWidth
= r300LineWidth
;
2209 functions
->PolygonOffset
= r300PolygonOffset
;
2210 functions
->PolygonMode
= r300PolygonMode
;
2212 functions
->RenderMode
= r300RenderMode
;