1 /**************************************************************************
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 on the rights to use, copy, modify, merge, publish, distribute, sub
10 license, and/or sell copies of the Software, and to permit persons to whom
11 the Software is furnished to do so, subject to the following conditions:
13 The above copyright notice and this permission notice (including the next
14 paragraph) shall be included in all copies or substantial portions of the
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
21 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 USE OR OTHER DEALINGS IN THE SOFTWARE.
25 **************************************************************************/
27 #include "nouveau_context.h"
28 #include "nouveau_object.h"
29 #include "nouveau_fifo.h"
30 #include "nouveau_reg.h"
31 #include "nouveau_state.h"
33 #include "tnl/t_pipeline.h"
38 #define NOUVEAU_CARD_USING_SHADERS (nmesa->screen->card->type >= NV_40)
40 static void nv30AlphaFunc(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
42 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
44 CLAMPED_FLOAT_TO_UBYTE(ubRef
, ref
);
46 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC
, 2);
47 OUT_RING_CACHE(func
); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */
48 OUT_RING_CACHE(ubRef
); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */
51 static void nv30BlendColor(GLcontext
*ctx
, const GLfloat color
[4])
53 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
56 CLAMPED_FLOAT_TO_UBYTE(cf
[0], color
[0]);
57 CLAMPED_FLOAT_TO_UBYTE(cf
[1], color
[1]);
58 CLAMPED_FLOAT_TO_UBYTE(cf
[2], color
[2]);
59 CLAMPED_FLOAT_TO_UBYTE(cf
[3], color
[3]);
61 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_BLEND_COLOR
, 1);
62 OUT_RING_CACHE(PACK_COLOR_8888(cf
[3], cf
[1], cf
[2], cf
[0]));
65 static void nv30BlendEquationSeparate(GLcontext
*ctx
, GLenum modeRGB
, GLenum modeA
)
67 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
68 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_BLEND_EQUATION
, 1);
69 OUT_RING_CACHE((modeA
<<16) | modeRGB
);
73 static void nv30BlendFuncSeparate(GLcontext
*ctx
, GLenum sfactorRGB
, GLenum dfactorRGB
,
74 GLenum sfactorA
, GLenum dfactorA
)
76 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
77 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC
, 2);
78 OUT_RING_CACHE((sfactorA
<<16) | sfactorRGB
);
79 OUT_RING_CACHE((dfactorA
<<16) | dfactorRGB
);
82 static void nv30Clear(GLcontext
*ctx
, GLbitfield mask
)
84 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
87 if (mask
& (BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
))
89 if (mask
& (BUFFER_BIT_DEPTH
))
93 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS
, 1);
98 static void nv30ClearColor(GLcontext
*ctx
, const GLfloat color
[4])
100 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
102 UNCLAMPED_FLOAT_TO_RGBA_CHAN(c
,color
);
103 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB
, 1);
104 OUT_RING_CACHE(PACK_COLOR_8888(c
[3],c
[0],c
[1],c
[2]));
107 static void nv30ClearDepth(GLcontext
*ctx
, GLclampd d
)
109 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
110 nmesa
->clear_value
=((nmesa
->clear_value
&0x000000FF)|(((uint32_t)(d
*0xFFFFFF))<<8));
111 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH
, 1);
112 OUT_RING_CACHE(nmesa
->clear_value
);
115 /* we're don't support indexed buffers
116 void (*ClearIndex)(GLcontext *ctx, GLuint index)
119 static void nv30ClearStencil(GLcontext
*ctx
, GLint s
)
121 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
122 nmesa
->clear_value
=((nmesa
->clear_value
&0xFFFFFF00)|(s
&0x000000FF));
123 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH
, 1);
124 OUT_RING_CACHE(nmesa
->clear_value
);
127 static void nv30ClipPlane(GLcontext
*ctx
, GLenum plane
, const GLfloat
*equation
)
129 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
130 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane
), 4);
131 OUT_RING_CACHEf(equation
[0]);
132 OUT_RING_CACHEf(equation
[1]);
133 OUT_RING_CACHEf(equation
[2]);
134 OUT_RING_CACHEf(equation
[3]);
137 static void nv30ColorMask(GLcontext
*ctx
, GLboolean rmask
, GLboolean gmask
,
138 GLboolean bmask
, GLboolean amask
)
140 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
141 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_COLOR_MASK
, 1);
142 OUT_RING_CACHE(((amask
&& 0x01) << 24) | ((rmask
&& 0x01) << 16) | ((gmask
&& 0x01)<< 8) | ((bmask
&& 0x01) << 0));
145 static void nv30ColorMaterial(GLcontext
*ctx
, GLenum face
, GLenum mode
)
150 static void nv30CullFace(GLcontext
*ctx
, GLenum mode
)
152 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
153 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_CULL_FACE
, 1);
154 OUT_RING_CACHE(mode
);
157 static void nv30FrontFace(GLcontext
*ctx
, GLenum mode
)
159 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
160 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_FRONT_FACE
, 1);
161 OUT_RING_CACHE(mode
);
164 static void nv30DepthFunc(GLcontext
*ctx
, GLenum func
)
166 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
167 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_DEPTH_FUNC
, 1);
168 OUT_RING_CACHE(func
);
171 static void nv30DepthMask(GLcontext
*ctx
, GLboolean flag
)
173 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
174 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE
, 1);
175 OUT_RING_CACHE(flag
);
178 static void nv30DepthRange(GLcontext
*ctx
, GLclampd nearval
, GLclampd farval
)
180 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
181 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR
, 2);
182 OUT_RING_CACHEf(nearval
);
183 OUT_RING_CACHEf(farval
);
186 /** Specify the current buffer for writing */
187 //void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
188 /** Specify the buffers for writing for fragment programs*/
189 //void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
191 static void nv30Enable(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
193 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
197 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE
, 1);
198 OUT_RING_CACHE(state
);
200 // case GL_AUTO_NORMAL:
202 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE
, 1);
203 OUT_RING_CACHE(state
);
211 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap
-GL_CLIP_PLANE0
), 1);
212 OUT_RING_CACHE(state
);
214 case GL_COLOR_LOGIC_OP
:
215 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE
, 1);
216 OUT_RING_CACHE(state
);
218 // case GL_COLOR_MATERIAL:
219 // case GL_COLOR_SUM_EXT:
220 // case GL_COLOR_TABLE:
221 // case GL_CONVOLUTION_1D:
222 // case GL_CONVOLUTION_2D:
224 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE
, 1);
225 OUT_RING_CACHE(state
);
228 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE
, 1);
229 OUT_RING_CACHE(state
);
232 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE
, 1);
233 OUT_RING_CACHE(state
);
236 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE
, 1);
237 OUT_RING_CACHE(state
);
239 // case GL_HISTOGRAM:
240 // case GL_INDEX_LOGIC_OP:
250 uint32_t mask
=0x11<<(2*(cap
-GL_LIGHT0
));
252 if (NOUVEAU_CARD_USING_SHADERS
)
255 nmesa
->enabled_lights
=((nmesa
->enabled_lights
&mask
)|(mask
*state
));
256 if (nmesa
->lighting_enabled
)
258 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS
, 1);
259 OUT_RING_CACHE(nmesa
->enabled_lights
);
264 if (NOUVEAU_CARD_USING_SHADERS
)
267 nmesa
->lighting_enabled
=state
;
268 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS
, 1);
269 if (nmesa
->lighting_enabled
)
270 OUT_RING_CACHE(nmesa
->enabled_lights
);
274 // case GL_LINE_SMOOTH:
275 // case GL_LINE_STIPPLE:
276 // case GL_MAP1_COLOR_4:
277 // case GL_MAP1_INDEX:
278 // case GL_MAP1_NORMAL:
279 // case GL_MAP1_TEXTURE_COORD_1:
280 // case GL_MAP1_TEXTURE_COORD_2:
281 // case GL_MAP1_TEXTURE_COORD_3:
282 // case GL_MAP1_TEXTURE_COORD_4:
283 // case GL_MAP1_VERTEX_3:
284 // case GL_MAP1_VERTEX_4:
285 // case GL_MAP2_COLOR_4:
286 // case GL_MAP2_INDEX:
287 // case GL_MAP2_NORMAL:
288 // case GL_MAP2_TEXTURE_COORD_1:
289 // case GL_MAP2_TEXTURE_COORD_2:
290 // case GL_MAP2_TEXTURE_COORD_3:
291 // case GL_MAP2_TEXTURE_COORD_4:
292 // case GL_MAP2_VERTEX_3:
293 // case GL_MAP2_VERTEX_4:
296 if (nmesa
->screen
->card
->type
!= NV_44
) {
297 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE
, 1);
298 OUT_RING_CACHE(state
);
301 // case GL_POINT_SMOOTH:
302 case GL_POLYGON_OFFSET_POINT
:
303 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE
, 1);
304 OUT_RING_CACHE(state
);
306 case GL_POLYGON_OFFSET_LINE
:
307 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE
, 1);
308 OUT_RING_CACHE(state
);
310 case GL_POLYGON_OFFSET_FILL
:
311 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE
, 1);
312 OUT_RING_CACHE(state
);
314 case GL_POLYGON_SMOOTH
:
315 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE
, 1);
316 OUT_RING_CACHE(state
);
318 case GL_POLYGON_STIPPLE
:
319 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE
, 1);
320 OUT_RING_CACHE(state
);
322 // case GL_POST_COLOR_MATRIX_COLOR_TABLE:
323 // case GL_POST_CONVOLUTION_COLOR_TABLE:
324 // case GL_RESCALE_NORMAL:
325 case GL_SCISSOR_TEST
:
326 /* No enable bit, nv30Scissor will adjust to max range */
327 ctx
->Driver
.Scissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
328 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
330 // case GL_SEPARABLE_2D:
331 case GL_STENCIL_TEST
:
332 // TODO BACK and FRONT ?
333 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE
, 1);
334 OUT_RING_CACHE(state
);
335 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE
, 1);
336 OUT_RING_CACHE(state
);
338 // case GL_TEXTURE_GEN_Q:
339 // case GL_TEXTURE_GEN_R:
340 // case GL_TEXTURE_GEN_S:
341 // case GL_TEXTURE_GEN_T:
342 // case GL_TEXTURE_1D:
343 // case GL_TEXTURE_2D:
344 // case GL_TEXTURE_3D:
348 static void nv30Fogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*params
)
350 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
352 if (NOUVEAU_CARD_USING_SHADERS
)
360 /* The modes are different in GL and the card. */
361 switch(ctx
->Fog
.Mode
)
373 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_FOG_MODE
, 1);
374 OUT_RING_CACHE (mode
);
380 UNCLAMPED_FLOAT_TO_RGBA_CHAN(c
,params
);
381 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_FOG_COLOR
, 1);
382 /* nvidia ignores the alpha channel */
383 OUT_RING_CACHE(PACK_COLOR_8888_REV(c
[0],c
[1],c
[2],c
[3]));
391 switch(ctx
->Fog
.Mode
)
394 f
= -1.0/(ctx
->Fog
.End
- ctx
->Fog
.Start
);
395 c
= ctx
->Fog
.Start
/(ctx
->Fog
.End
- ctx
->Fog
.Start
) + 2.001953;
398 f
= -0.090168*ctx
->Fog
.Density
;
401 f
= -0.212330*ctx
->Fog
.Density
;
404 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR
, 1);
406 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT
, 1);
408 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC
, 1);
409 OUT_RING_CACHE(0); /* Is this always the same? */
412 // case GL_FOG_COORD_SRC:
418 static void nv30Hint(GLcontext
*ctx
, GLenum target
, GLenum mode
)
420 // TODO I need love (fog and line_smooth hints)
423 // void (*IndexMask)(GLcontext *ctx, GLuint mask);
427 SPOTLIGHT_UPDATE_EXPONENT
,
428 SPOTLIGHT_UPDATE_DIRECTION
,
432 static void nv30Lightfv(GLcontext
*ctx
, GLenum light
, GLenum pname
, const GLfloat
*params
)
434 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
435 GLint p
= light
- GL_LIGHT0
;
436 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
437 int spotlight_update
= SPOTLIGHT_NO_UPDATE
;
439 if (NOUVEAU_CARD_USING_SHADERS
)
442 /* not sure where the fourth param value goes...*/
446 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p
), 3);
447 OUT_RING_CACHEf(params
[0]);
448 OUT_RING_CACHEf(params
[1]);
449 OUT_RING_CACHEf(params
[2]);
452 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p
), 3);
453 OUT_RING_CACHEf(params
[0]);
454 OUT_RING_CACHEf(params
[1]);
455 OUT_RING_CACHEf(params
[2]);
458 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p
), 3);
459 OUT_RING_CACHEf(params
[0]);
460 OUT_RING_CACHEf(params
[1]);
461 OUT_RING_CACHEf(params
[2]);
464 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p
), 3);
465 OUT_RING_CACHEf(params
[0]);
466 OUT_RING_CACHEf(params
[1]);
467 OUT_RING_CACHEf(params
[2]);
469 case GL_SPOT_DIRECTION
:
470 spotlight_update
= SPOTLIGHT_UPDATE_DIRECTION
;
472 case GL_SPOT_EXPONENT
:
473 spotlight_update
= SPOTLIGHT_UPDATE_EXPONENT
;
476 spotlight_update
= SPOTLIGHT_UPDATE_ALL
;
478 case GL_CONSTANT_ATTENUATION
:
479 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p
), 1);
480 OUT_RING_CACHEf(*params
);
482 case GL_LINEAR_ATTENUATION
:
483 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p
), 1);
484 OUT_RING_CACHEf(*params
);
486 case GL_QUADRATIC_ATTENUATION
:
487 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p
), 1);
488 OUT_RING_CACHEf(*params
);
494 switch(spotlight_update
) {
495 case SPOTLIGHT_UPDATE_DIRECTION
:
498 GLfloat spot_light_coef_a
= 1.0 / (l
->_CosCutoff
- 1.0);
499 x
= spot_light_coef_a
* l
->_NormDirection
[0];
500 y
= spot_light_coef_a
* l
->_NormDirection
[1];
501 z
= spot_light_coef_a
* l
->_NormDirection
[2];
502 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p
), 3);
508 case SPOTLIGHT_UPDATE_EXPONENT
:
511 cc
= 1.0; /* FIXME: These need to be correctly computed */
514 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p
), 3);
520 case SPOTLIGHT_UPDATE_ALL
:
522 GLfloat cc
,lc
,qc
, x
,y
,z
, c
;
523 GLfloat spot_light_coef_a
= 1.0 / (l
->_CosCutoff
- 1.0);
524 cc
= 1.0; /* FIXME: These need to be correctly computed */
527 x
= spot_light_coef_a
* l
->_NormDirection
[0];
528 y
= spot_light_coef_a
* l
->_NormDirection
[1];
529 z
= spot_light_coef_a
* l
->_NormDirection
[2];
530 c
= spot_light_coef_a
+ 1.0;
531 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p
), 7);
546 /** Set the lighting model parameters */
547 void (*LightModelfv
)(GLcontext
*ctx
, GLenum pname
, const GLfloat
*params
);
550 static void nv30LineStipple(GLcontext
*ctx
, GLint factor
, GLushort pattern
)
552 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
553 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN
, 1);
554 OUT_RING_CACHE((pattern
<< 16) | factor
);
557 static void nv30LineWidth(GLcontext
*ctx
, GLfloat width
)
559 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
562 CLAMPED_FLOAT_TO_UBYTE(ubWidth
, width
);
564 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH
, 1);
565 OUT_RING_CACHE(ubWidth
);
568 static void nv30LogicOpcode(GLcontext
*ctx
, GLenum opcode
)
570 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
571 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP
, 1);
572 OUT_RING_CACHE(opcode
);
575 static void nv30PointParameterfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*params
)
577 /*TODO: not sure what goes here. */
578 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
582 /** Specify the diameter of rasterized points */
583 static void nv30PointSize(GLcontext
*ctx
, GLfloat size
)
585 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
586 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POINT_SIZE
, 1);
587 OUT_RING_CACHEf(size
);
590 /** Select a polygon rasterization mode */
591 static void nv30PolygonMode(GLcontext
*ctx
, GLenum face
, GLenum mode
)
593 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
595 if (face
== GL_FRONT
|| face
== GL_FRONT_AND_BACK
) {
596 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT
, 1);
597 OUT_RING_CACHE(mode
);
599 if (face
== GL_BACK
|| face
== GL_FRONT_AND_BACK
) {
600 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK
, 1);
601 OUT_RING_CACHE(mode
);
605 /** Set the scale and units used to calculate depth values */
606 static void nv30PolygonOffset(GLcontext
*ctx
, GLfloat factor
, GLfloat units
)
608 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
609 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR
, 2);
610 OUT_RING_CACHEf(factor
);
612 /* Looks like we always multiply units by 2.0... according to the dumps.*/
613 OUT_RING_CACHEf(units
* 2.0);
616 /** Set the polygon stippling pattern */
617 static void nv30PolygonStipple(GLcontext
*ctx
, const GLubyte
*mask
)
619 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
620 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32);
621 OUT_RING_CACHEp(mask
, 32);
624 /* Specifies the current buffer for reading */
625 void (*ReadBuffer
)( GLcontext
*ctx
, GLenum buffer
);
626 /** Set rasterization mode */
627 void (*RenderMode
)(GLcontext
*ctx
, GLenum mode
);
629 /** Define the scissor box */
630 static void nv30Scissor(GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
632 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
634 /* There's no scissor enable bit, so adjust the scissor to cover the
635 * maximum draw buffer bounds
637 if (!ctx
->Scissor
.Enabled
) {
645 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS
, 2);
646 OUT_RING_CACHE(((w
) << 16) | x
);
647 OUT_RING_CACHE(((h
) << 16) | y
);
650 /** Select flat or smooth shading */
651 static void nv30ShadeModel(GLcontext
*ctx
, GLenum mode
)
653 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
655 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SHADE_MODEL
, 1);
656 OUT_RING_CACHE(mode
);
659 /** OpenGL 2.0 two-sided StencilFunc */
660 static void nv30StencilFuncSeparate(GLcontext
*ctx
, GLenum face
, GLenum func
,
661 GLint ref
, GLuint mask
)
663 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
665 if (face
== GL_FRONT
|| face
== GL_FRONT_AND_BACK
) {
666 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC
, 3);
667 OUT_RING_CACHE(func
);
669 OUT_RING_CACHE(mask
);
671 if (face
== GL_BACK
|| face
== GL_FRONT_AND_BACK
) {
672 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC
, 3);
673 OUT_RING_CACHE(func
);
675 OUT_RING_CACHE(mask
);
679 /** OpenGL 2.0 two-sided StencilMask */
680 static void nv30StencilMaskSeparate(GLcontext
*ctx
, GLenum face
, GLuint mask
)
682 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
684 if (face
== GL_FRONT
|| face
== GL_FRONT_AND_BACK
) {
685 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK
, 1);
686 OUT_RING_CACHE(mask
);
688 if (face
== GL_BACK
|| face
== GL_FRONT_AND_BACK
) {
689 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK
, 1);
690 OUT_RING_CACHE(mask
);
694 /** OpenGL 2.0 two-sided StencilOp */
695 static void nv30StencilOpSeparate(GLcontext
*ctx
, GLenum face
, GLenum fail
,
696 GLenum zfail
, GLenum zpass
)
698 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
700 if (face
== GL_FRONT
|| face
== GL_FRONT_AND_BACK
) {
701 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL
, 3);
702 OUT_RING_CACHE(fail
);
703 OUT_RING_CACHE(zfail
);
704 OUT_RING_CACHE(zpass
);
706 if (face
== GL_BACK
|| face
== GL_FRONT_AND_BACK
) {
707 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL
, 3);
708 OUT_RING_CACHE(fail
);
709 OUT_RING_CACHE(zfail
);
710 OUT_RING_CACHE(zpass
);
714 /** Control the generation of texture coordinates */
715 void (*TexGen
)(GLcontext
*ctx
, GLenum coord
, GLenum pname
,
716 const GLfloat
*params
);
717 /** Set texture environment parameters */
718 void (*TexEnv
)(GLcontext
*ctx
, GLenum target
, GLenum pname
,
719 const GLfloat
*param
);
720 /** Set texture parameters */
721 void (*TexParameter
)(GLcontext
*ctx
, GLenum target
,
722 struct gl_texture_object
*texObj
,
723 GLenum pname
, const GLfloat
*params
);
725 static void nv30TextureMatrix(GLcontext
*ctx
, GLuint unit
, const GLmatrix
*mat
)
727 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
728 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit
, 0), 16);
729 /*XXX: This SHOULD work.*/
730 OUT_RING_CACHEp(mat
->m
, 16);
733 static void nv30WindowMoved(nouveauContextPtr nmesa
)
735 GLcontext
*ctx
= nmesa
->glCtx
;
736 GLfloat
*v
= nmesa
->viewport
.m
;
737 GLuint w
= ctx
->Viewport
.Width
;
738 GLuint h
= ctx
->Viewport
.Height
;
739 GLuint x
= ctx
->Viewport
.X
+ nmesa
->drawX
;
740 GLuint y
= ctx
->Viewport
.Y
+ nmesa
->drawY
;
742 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0
, 2);
743 OUT_RING_CACHE((w
<< 16) | x
);
744 OUT_RING_CACHE((h
<< 16) | y
);
745 /* something to do with clears, possibly doesn't belong here */
746 BEGIN_RING_CACHE(NvSub3D
,
747 NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0
, 2);
748 OUT_RING_CACHE(((w
+x
) << 16) | x
);
749 OUT_RING_CACHE(((h
+y
) << 16) | y
);
750 /* viewport transform */
751 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX
, 8);
752 OUT_RING_CACHEf (v
[MAT_TX
]);
753 OUT_RING_CACHEf (v
[MAT_TY
]);
754 OUT_RING_CACHEf (v
[MAT_TZ
]);
755 OUT_RING_CACHEf (0.0);
756 OUT_RING_CACHEf (v
[MAT_SX
]);
757 OUT_RING_CACHEf (v
[MAT_SY
]);
758 OUT_RING_CACHEf (v
[MAT_SZ
]);
759 OUT_RING_CACHEf (0.0);
761 ctx
->Driver
.Scissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
762 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
765 static GLboolean
nv30InitCard(nouveauContextPtr nmesa
)
768 nouveauObjectOnSubchannel(nmesa
, NvSub3D
, Nv3D
);
770 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1
, 3);
774 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8
, 1);
776 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4
, 2);
779 BEGIN_RING_SIZE(NvSub3D
, 0x1b0, 1); /* SET_OBJECT8B*/
782 for(i
= 0x2c8; i
<= 0x2fc; i
+= 4)
784 BEGIN_RING_SIZE(NvSub3D
, i
, 1);
788 BEGIN_RING_SIZE(NvSub3D
, 0x0220, 1);
791 BEGIN_RING_SIZE(NvSub3D
, 0x03b0, 1);
792 OUT_RING(0x00100000);
793 BEGIN_RING_SIZE(NvSub3D
, 0x1454, 1);
795 BEGIN_RING_SIZE(NvSub3D
, 0x1d80, 1);
797 BEGIN_RING_SIZE(NvSub3D
, 0x1450, 1);
798 OUT_RING(0x00030004);
801 BEGIN_RING_SIZE(NvSub3D
, 0x1e98, 1);
803 BEGIN_RING_SIZE(NvSub3D
, 0x17e0, 3);
806 OUT_RING(0x3f800000);
807 BEGIN_RING_SIZE(NvSub3D
, 0x1f80, 16);
808 OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
809 OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
810 OUT_RING(0x0000ffff);
811 OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
812 OUT_RING(0); OUT_RING(0); OUT_RING(0);
814 BEGIN_RING_SIZE(NvSub3D, 0x100, 2);
818 BEGIN_RING_SIZE(NvSub3D
, 0x120, 3);
823 BEGIN_RING_SIZE(NvSub3D
, 0x1d88, 1);
824 OUT_RING(0x00001200);
829 static GLboolean
nv40InitCard(nouveauContextPtr nmesa
)
831 nouveauObjectOnSubchannel(nmesa
, NvSub3D
, Nv3D
);
833 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1
, 2);
836 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8
, 1);
838 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4
, 2);
841 BEGIN_RING_SIZE(NvSub3D
, 0x0220, 1);
844 BEGIN_RING_SIZE(NvSub3D
, 0x1ea4, 3);
845 OUT_RING(0x00000010);
846 OUT_RING(0x01000100);
847 OUT_RING(0xff800006);
848 BEGIN_RING_SIZE(NvSub3D
, 0x1fc4, 1);
849 OUT_RING(0x06144321);
850 BEGIN_RING_SIZE(NvSub3D
, 0x1fc8, 2);
851 OUT_RING(0xedcba987);
852 OUT_RING(0x00000021);
853 BEGIN_RING_SIZE(NvSub3D
, 0x1fd0, 1);
854 OUT_RING(0x00171615);
855 BEGIN_RING_SIZE(NvSub3D
, 0x1fd4, 1);
856 OUT_RING(0x001b1a19);
858 BEGIN_RING_SIZE(NvSub3D
, 0x1ef8, 1);
859 OUT_RING(0x0020ffff);
860 BEGIN_RING_SIZE(NvSub3D
, 0x1d64, 1);
861 OUT_RING(0x00d30000);
862 BEGIN_RING_SIZE(NvSub3D
, 0x1e94, 1);
863 OUT_RING(0x00000001);
865 BEGIN_RING_SIZE(NvSub3D
, 0x1d60, 1);
866 OUT_RING(0x03008000);
871 static GLboolean
nv30BindBuffers(nouveauContextPtr nmesa
, int num_color
,
872 nouveau_renderbuffer
**color
,
873 nouveau_renderbuffer
*depth
)
877 w
= color
[0]->mesa
.Width
;
878 h
= color
[0]->mesa
.Height
;
884 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0
, 5);
885 OUT_RING (((w
+x
)<<16)|x
);
886 OUT_RING (((h
+y
)<<16)|y
);
887 if (color
[0]->mesa
._ActualFormat
== GL_RGBA8
)
891 if (nmesa
->screen
->card
->type
>= NV_40
)
892 OUT_RING (color
[0]->pitch
);
894 OUT_RING (color
[0]->pitch
| (depth
? (depth
->pitch
<< 16): 0));
895 OUT_RING (color
[0]->offset
);
898 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET
, 1);
899 OUT_RING (depth
->offset
);
900 if (nmesa
->screen
->card
->type
>= NV_40
) {
901 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH
, 1);
902 OUT_RING (depth
->pitch
>> 2);
909 void nv30InitStateFuncs(GLcontext
*ctx
, struct dd_function_table
*func
)
911 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
913 func
->AlphaFunc
= nv30AlphaFunc
;
914 func
->BlendColor
= nv30BlendColor
;
915 func
->BlendEquationSeparate
= nv30BlendEquationSeparate
;
916 func
->BlendFuncSeparate
= nv30BlendFuncSeparate
;
917 func
->Clear
= nv30Clear
;
918 func
->ClearColor
= nv30ClearColor
;
919 func
->ClearDepth
= nv30ClearDepth
;
920 func
->ClearStencil
= nv30ClearStencil
;
921 func
->ClipPlane
= nv30ClipPlane
;
922 func
->ColorMask
= nv30ColorMask
;
923 func
->ColorMaterial
= nv30ColorMaterial
;
924 func
->CullFace
= nv30CullFace
;
925 func
->FrontFace
= nv30FrontFace
;
926 func
->DepthFunc
= nv30DepthFunc
;
927 func
->DepthMask
= nv30DepthMask
;
928 func
->DepthRange
= nv30DepthRange
;
929 func
->Enable
= nv30Enable
;
930 func
->Fogfv
= nv30Fogfv
;
931 func
->Hint
= nv30Hint
;
932 func
->Lightfv
= nv30Lightfv
;
933 /* func->LightModelfv = nv30LightModelfv; */
934 func
->LineStipple
= nv30LineStipple
;
935 func
->LineWidth
= nv30LineWidth
;
936 func
->LogicOpcode
= nv30LogicOpcode
;
937 func
->PointParameterfv
= nv30PointParameterfv
;
938 func
->PointSize
= nv30PointSize
;
939 func
->PolygonMode
= nv30PolygonMode
;
940 func
->PolygonOffset
= nv30PolygonOffset
;
941 func
->PolygonStipple
= nv30PolygonStipple
;
943 func
->ReadBuffer
= nv30ReadBuffer
;
944 func
->RenderMode
= nv30RenderMode
;
946 func
->Scissor
= nv30Scissor
;
947 func
->ShadeModel
= nv30ShadeModel
;
948 func
->StencilFuncSeparate
= nv30StencilFuncSeparate
;
949 func
->StencilMaskSeparate
= nv30StencilMaskSeparate
;
950 func
->StencilOpSeparate
= nv30StencilOpSeparate
;
952 func
->TexGen
= nv30TexGen
;
953 func
->TexParameter
= nv30TexParameter
;
955 func
->TextureMatrix
= nv30TextureMatrix
;
958 if (nmesa
->screen
->card
->type
>= NV_40
)
959 nmesa
->hw_func
.InitCard
= nv40InitCard
;
961 nmesa
->hw_func
.InitCard
= nv30InitCard
;
962 nmesa
->hw_func
.BindBuffers
= nv30BindBuffers
;
963 nmesa
->hw_func
.WindowMoved
= nv30WindowMoved
;