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
);
131 if (NOUVEAU_CARD_USING_SHADERS
)
134 plane
-= GL_CLIP_PLANE0
;
135 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane
), 4);
136 OUT_RING_CACHEf(equation
[0]);
137 OUT_RING_CACHEf(equation
[1]);
138 OUT_RING_CACHEf(equation
[2]);
139 OUT_RING_CACHEf(equation
[3]);
142 static void nv30ColorMask(GLcontext
*ctx
, GLboolean rmask
, GLboolean gmask
,
143 GLboolean bmask
, GLboolean amask
)
145 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
146 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_COLOR_MASK
, 1);
147 OUT_RING_CACHE(((amask
&& 0x01) << 24) | ((rmask
&& 0x01) << 16) | ((gmask
&& 0x01)<< 8) | ((bmask
&& 0x01) << 0));
150 static void nv30ColorMaterial(GLcontext
*ctx
, GLenum face
, GLenum mode
)
155 static void nv30CullFace(GLcontext
*ctx
, GLenum mode
)
157 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
158 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_CULL_FACE
, 1);
159 OUT_RING_CACHE(mode
);
162 static void nv30FrontFace(GLcontext
*ctx
, GLenum mode
)
164 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
165 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_FRONT_FACE
, 1);
166 OUT_RING_CACHE(mode
);
169 static void nv30DepthFunc(GLcontext
*ctx
, GLenum func
)
171 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
172 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_DEPTH_FUNC
, 1);
173 OUT_RING_CACHE(func
);
176 static void nv30DepthMask(GLcontext
*ctx
, GLboolean flag
)
178 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
179 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE
, 1);
180 OUT_RING_CACHE(flag
);
183 static void nv30DepthRange(GLcontext
*ctx
, GLclampd nearval
, GLclampd farval
)
185 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
186 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR
, 2);
187 OUT_RING_CACHEf(nearval
);
188 OUT_RING_CACHEf(farval
);
191 /** Specify the current buffer for writing */
192 //void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
193 /** Specify the buffers for writing for fragment programs*/
194 //void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
196 static void nv30Enable(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
198 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
202 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE
, 1);
203 OUT_RING_CACHE(state
);
205 // case GL_AUTO_NORMAL:
207 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE
, 1);
208 OUT_RING_CACHE(state
);
216 if (NOUVEAU_CARD_USING_SHADERS
) {
217 nouveauShader
*nvs
= (nouveauShader
*)ctx
->VertexProgram
._Current
;
219 nvs
->translated
= GL_FALSE
;
221 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap
-GL_CLIP_PLANE0
), 1);
222 OUT_RING_CACHE(state
);
225 case GL_COLOR_LOGIC_OP
:
226 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE
, 1);
227 OUT_RING_CACHE(state
);
229 // case GL_COLOR_MATERIAL:
230 // case GL_COLOR_SUM_EXT:
231 // case GL_COLOR_TABLE:
232 // case GL_CONVOLUTION_1D:
233 // case GL_CONVOLUTION_2D:
235 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE
, 1);
236 OUT_RING_CACHE(state
);
239 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE
, 1);
240 OUT_RING_CACHE(state
);
243 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE
, 1);
244 OUT_RING_CACHE(state
);
247 if (NOUVEAU_CARD_USING_SHADERS
)
249 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE
, 1);
250 OUT_RING_CACHE(state
);
252 // case GL_HISTOGRAM:
253 // case GL_INDEX_LOGIC_OP:
263 uint32_t mask
=0x11<<(2*(cap
-GL_LIGHT0
));
265 if (NOUVEAU_CARD_USING_SHADERS
)
268 nmesa
->enabled_lights
=((nmesa
->enabled_lights
&mask
)|(mask
*state
));
269 if (nmesa
->lighting_enabled
)
271 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS
, 1);
272 OUT_RING_CACHE(nmesa
->enabled_lights
);
277 if (NOUVEAU_CARD_USING_SHADERS
)
280 nmesa
->lighting_enabled
=state
;
281 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS
, 1);
282 if (nmesa
->lighting_enabled
)
283 OUT_RING_CACHE(nmesa
->enabled_lights
);
287 // case GL_LINE_SMOOTH:
288 // case GL_LINE_STIPPLE:
289 // case GL_MAP1_COLOR_4:
290 // case GL_MAP1_INDEX:
291 // case GL_MAP1_NORMAL:
292 // case GL_MAP1_TEXTURE_COORD_1:
293 // case GL_MAP1_TEXTURE_COORD_2:
294 // case GL_MAP1_TEXTURE_COORD_3:
295 // case GL_MAP1_TEXTURE_COORD_4:
296 // case GL_MAP1_VERTEX_3:
297 // case GL_MAP1_VERTEX_4:
298 // case GL_MAP2_COLOR_4:
299 // case GL_MAP2_INDEX:
300 // case GL_MAP2_NORMAL:
301 // case GL_MAP2_TEXTURE_COORD_1:
302 // case GL_MAP2_TEXTURE_COORD_2:
303 // case GL_MAP2_TEXTURE_COORD_3:
304 // case GL_MAP2_TEXTURE_COORD_4:
305 // case GL_MAP2_VERTEX_3:
306 // case GL_MAP2_VERTEX_4:
309 if (nmesa
->screen
->card
->type
!= NV_44
) {
310 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE
, 1);
311 OUT_RING_CACHE(state
);
314 // case GL_POINT_SMOOTH:
315 case GL_POLYGON_OFFSET_POINT
:
316 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE
, 1);
317 OUT_RING_CACHE(state
);
319 case GL_POLYGON_OFFSET_LINE
:
320 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE
, 1);
321 OUT_RING_CACHE(state
);
323 case GL_POLYGON_OFFSET_FILL
:
324 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE
, 1);
325 OUT_RING_CACHE(state
);
327 case GL_POLYGON_SMOOTH
:
328 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE
, 1);
329 OUT_RING_CACHE(state
);
331 case GL_POLYGON_STIPPLE
:
332 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE
, 1);
333 OUT_RING_CACHE(state
);
335 // case GL_POST_COLOR_MATRIX_COLOR_TABLE:
336 // case GL_POST_CONVOLUTION_COLOR_TABLE:
337 // case GL_RESCALE_NORMAL:
338 case GL_SCISSOR_TEST
:
339 /* No enable bit, nv30Scissor will adjust to max range */
340 ctx
->Driver
.Scissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
341 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
343 // case GL_SEPARABLE_2D:
344 case GL_STENCIL_TEST
:
345 // TODO BACK and FRONT ?
346 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE
, 1);
347 OUT_RING_CACHE(state
);
348 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE
, 1);
349 OUT_RING_CACHE(state
);
351 // case GL_TEXTURE_GEN_Q:
352 // case GL_TEXTURE_GEN_R:
353 // case GL_TEXTURE_GEN_S:
354 // case GL_TEXTURE_GEN_T:
355 // case GL_TEXTURE_1D:
356 // case GL_TEXTURE_2D:
357 // case GL_TEXTURE_3D:
361 static void nv30Fogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*params
)
363 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
365 if (NOUVEAU_CARD_USING_SHADERS
)
373 /* The modes are different in GL and the card. */
374 switch(ctx
->Fog
.Mode
)
386 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_FOG_MODE
, 1);
387 OUT_RING_CACHE (mode
);
393 UNCLAMPED_FLOAT_TO_RGBA_CHAN(c
,params
);
394 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_FOG_COLOR
, 1);
395 /* nvidia ignores the alpha channel */
396 OUT_RING_CACHE(PACK_COLOR_8888_REV(c
[0],c
[1],c
[2],c
[3]));
404 switch(ctx
->Fog
.Mode
)
407 f
= -1.0/(ctx
->Fog
.End
- ctx
->Fog
.Start
);
408 c
= ctx
->Fog
.Start
/(ctx
->Fog
.End
- ctx
->Fog
.Start
) + 2.001953;
411 f
= -0.090168*ctx
->Fog
.Density
;
414 f
= -0.212330*ctx
->Fog
.Density
;
417 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR
, 1);
419 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT
, 1);
421 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC
, 1);
422 OUT_RING_CACHE(0); /* Is this always the same? */
425 // case GL_FOG_COORD_SRC:
431 static void nv30Hint(GLcontext
*ctx
, GLenum target
, GLenum mode
)
433 // TODO I need love (fog and line_smooth hints)
436 // void (*IndexMask)(GLcontext *ctx, GLuint mask);
440 SPOTLIGHT_UPDATE_EXPONENT
,
441 SPOTLIGHT_UPDATE_DIRECTION
,
445 static void nv30Lightfv(GLcontext
*ctx
, GLenum light
, GLenum pname
, const GLfloat
*params
)
447 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
448 GLint p
= light
- GL_LIGHT0
;
449 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
450 int spotlight_update
= SPOTLIGHT_NO_UPDATE
;
452 if (NOUVEAU_CARD_USING_SHADERS
)
455 /* not sure where the fourth param value goes...*/
459 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p
), 3);
460 OUT_RING_CACHEf(params
[0]);
461 OUT_RING_CACHEf(params
[1]);
462 OUT_RING_CACHEf(params
[2]);
465 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p
), 3);
466 OUT_RING_CACHEf(params
[0]);
467 OUT_RING_CACHEf(params
[1]);
468 OUT_RING_CACHEf(params
[2]);
471 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p
), 3);
472 OUT_RING_CACHEf(params
[0]);
473 OUT_RING_CACHEf(params
[1]);
474 OUT_RING_CACHEf(params
[2]);
477 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p
), 3);
478 OUT_RING_CACHEf(params
[0]);
479 OUT_RING_CACHEf(params
[1]);
480 OUT_RING_CACHEf(params
[2]);
482 case GL_SPOT_DIRECTION
:
483 spotlight_update
= SPOTLIGHT_UPDATE_DIRECTION
;
485 case GL_SPOT_EXPONENT
:
486 spotlight_update
= SPOTLIGHT_UPDATE_EXPONENT
;
489 spotlight_update
= SPOTLIGHT_UPDATE_ALL
;
491 case GL_CONSTANT_ATTENUATION
:
492 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p
), 1);
493 OUT_RING_CACHEf(*params
);
495 case GL_LINEAR_ATTENUATION
:
496 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p
), 1);
497 OUT_RING_CACHEf(*params
);
499 case GL_QUADRATIC_ATTENUATION
:
500 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p
), 1);
501 OUT_RING_CACHEf(*params
);
507 switch(spotlight_update
) {
508 case SPOTLIGHT_UPDATE_DIRECTION
:
511 GLfloat spot_light_coef_a
= 1.0 / (l
->_CosCutoff
- 1.0);
512 x
= spot_light_coef_a
* l
->_NormDirection
[0];
513 y
= spot_light_coef_a
* l
->_NormDirection
[1];
514 z
= spot_light_coef_a
* l
->_NormDirection
[2];
515 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p
), 3);
521 case SPOTLIGHT_UPDATE_EXPONENT
:
524 cc
= 1.0; /* FIXME: These need to be correctly computed */
527 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p
), 3);
533 case SPOTLIGHT_UPDATE_ALL
:
535 GLfloat cc
,lc
,qc
, x
,y
,z
, c
;
536 GLfloat spot_light_coef_a
= 1.0 / (l
->_CosCutoff
- 1.0);
537 cc
= 1.0; /* FIXME: These need to be correctly computed */
540 x
= spot_light_coef_a
* l
->_NormDirection
[0];
541 y
= spot_light_coef_a
* l
->_NormDirection
[1];
542 z
= spot_light_coef_a
* l
->_NormDirection
[2];
543 c
= spot_light_coef_a
+ 1.0;
544 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p
), 7);
559 /** Set the lighting model parameters */
560 void (*LightModelfv
)(GLcontext
*ctx
, GLenum pname
, const GLfloat
*params
);
563 static void nv30LineStipple(GLcontext
*ctx
, GLint factor
, GLushort pattern
)
565 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
566 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN
, 1);
567 OUT_RING_CACHE((pattern
<< 16) | factor
);
570 static void nv30LineWidth(GLcontext
*ctx
, GLfloat width
)
572 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
575 ubWidth
= (GLubyte
)(width
* 8.0) & 0xFF;
577 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH
, 1);
578 OUT_RING_CACHE(ubWidth
);
581 static void nv30LogicOpcode(GLcontext
*ctx
, GLenum opcode
)
583 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
584 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP
, 1);
585 OUT_RING_CACHE(opcode
);
588 static void nv30PointParameterfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*params
)
590 /*TODO: not sure what goes here. */
591 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
595 /** Specify the diameter of rasterized points */
596 static void nv30PointSize(GLcontext
*ctx
, GLfloat size
)
598 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
599 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POINT_SIZE
, 1);
600 OUT_RING_CACHEf(size
);
603 /** Select a polygon rasterization mode */
604 static void nv30PolygonMode(GLcontext
*ctx
, GLenum face
, GLenum mode
)
606 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
608 if (face
== GL_FRONT
|| face
== GL_FRONT_AND_BACK
) {
609 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT
, 1);
610 OUT_RING_CACHE(mode
);
612 if (face
== GL_BACK
|| face
== GL_FRONT_AND_BACK
) {
613 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK
, 1);
614 OUT_RING_CACHE(mode
);
618 /** Set the scale and units used to calculate depth values */
619 static void nv30PolygonOffset(GLcontext
*ctx
, GLfloat factor
, GLfloat units
)
621 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
622 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR
, 2);
623 OUT_RING_CACHEf(factor
);
625 /* Looks like we always multiply units by 2.0... according to the dumps.*/
626 OUT_RING_CACHEf(units
* 2.0);
629 /** Set the polygon stippling pattern */
630 static void nv30PolygonStipple(GLcontext
*ctx
, const GLubyte
*mask
)
632 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
633 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32);
634 OUT_RING_CACHEp(mask
, 32);
637 /* Specifies the current buffer for reading */
638 void (*ReadBuffer
)( GLcontext
*ctx
, GLenum buffer
);
639 /** Set rasterization mode */
640 void (*RenderMode
)(GLcontext
*ctx
, GLenum mode
);
642 /* Translate GL coords to window coords, clamping w/h to the
643 * dimensions of the window.
645 static void nv30WindowCoords(nouveauContextPtr nmesa
,
646 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
647 GLuint
*wX
, GLuint
*wY
, GLuint
*wW
, GLuint
*wH
)
649 if ((x
+w
) > nmesa
->drawW
)
650 w
= nmesa
->drawW
- x
;
651 (*wX
) = x
+ nmesa
->drawX
;
654 if ((y
+h
) > nmesa
->drawH
)
655 h
= nmesa
->drawH
- y
;
656 (*wY
) = (nmesa
->drawH
- y
) - h
+ nmesa
->drawY
;
660 /** Define the scissor box */
661 static void nv30Scissor(GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
663 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
664 GLuint wX
, wY
, wW
, wH
;
666 /* There's no scissor enable bit, so adjust the scissor to cover the
667 * maximum draw buffer bounds
669 if (!ctx
->Scissor
.Enabled
) {
675 nv30WindowCoords(nmesa
, x
, y
, w
, h
, &wX
, &wY
, &wW
, &wH
);
678 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS
, 2);
679 OUT_RING_CACHE ((wW
<< 16) | wX
);
680 OUT_RING_CACHE ((wH
<< 16) | wY
);
683 /** Select flat or smooth shading */
684 static void nv30ShadeModel(GLcontext
*ctx
, GLenum mode
)
686 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
688 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SHADE_MODEL
, 1);
689 OUT_RING_CACHE(mode
);
692 /** OpenGL 2.0 two-sided StencilFunc */
693 static void nv30StencilFuncSeparate(GLcontext
*ctx
, GLenum face
, GLenum func
,
694 GLint ref
, GLuint mask
)
696 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
698 if (face
== GL_FRONT
|| face
== GL_FRONT_AND_BACK
) {
699 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC
, 3);
700 OUT_RING_CACHE(func
);
702 OUT_RING_CACHE(mask
);
704 if (face
== GL_BACK
|| face
== GL_FRONT_AND_BACK
) {
705 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC
, 3);
706 OUT_RING_CACHE(func
);
708 OUT_RING_CACHE(mask
);
712 /** OpenGL 2.0 two-sided StencilMask */
713 static void nv30StencilMaskSeparate(GLcontext
*ctx
, GLenum face
, GLuint mask
)
715 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
717 if (face
== GL_FRONT
|| face
== GL_FRONT_AND_BACK
) {
718 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK
, 1);
719 OUT_RING_CACHE(mask
);
721 if (face
== GL_BACK
|| face
== GL_FRONT_AND_BACK
) {
722 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK
, 1);
723 OUT_RING_CACHE(mask
);
727 /** OpenGL 2.0 two-sided StencilOp */
728 static void nv30StencilOpSeparate(GLcontext
*ctx
, GLenum face
, GLenum fail
,
729 GLenum zfail
, GLenum zpass
)
731 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
733 if (face
== GL_FRONT
|| face
== GL_FRONT_AND_BACK
) {
734 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL
, 3);
735 OUT_RING_CACHE(fail
);
736 OUT_RING_CACHE(zfail
);
737 OUT_RING_CACHE(zpass
);
739 if (face
== GL_BACK
|| face
== GL_FRONT_AND_BACK
) {
740 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL
, 3);
741 OUT_RING_CACHE(fail
);
742 OUT_RING_CACHE(zfail
);
743 OUT_RING_CACHE(zpass
);
747 /** Control the generation of texture coordinates */
748 void (*TexGen
)(GLcontext
*ctx
, GLenum coord
, GLenum pname
,
749 const GLfloat
*params
);
750 /** Set texture environment parameters */
751 void (*TexEnv
)(GLcontext
*ctx
, GLenum target
, GLenum pname
,
752 const GLfloat
*param
);
753 /** Set texture parameters */
754 void (*TexParameter
)(GLcontext
*ctx
, GLenum target
,
755 struct gl_texture_object
*texObj
,
756 GLenum pname
, const GLfloat
*params
);
758 static void nv30TextureMatrix(GLcontext
*ctx
, GLuint unit
, const GLmatrix
*mat
)
760 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
762 if (!NOUVEAU_CARD_USING_SHADERS
) {
763 BEGIN_RING_CACHE(NvSub3D
,
764 NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit
, 0), 16);
765 /*XXX: This SHOULD work.*/
766 OUT_RING_CACHEp(mat
->m
, 16);
770 static void nv30WindowMoved(nouveauContextPtr nmesa
)
772 GLcontext
*ctx
= nmesa
->glCtx
;
773 GLfloat
*v
= nmesa
->viewport
.m
;
774 GLuint wX
, wY
, wW
, wH
;
776 nv30WindowCoords(nmesa
, ctx
->Viewport
.X
, ctx
->Viewport
.Y
,
777 ctx
->Viewport
.Width
, ctx
->Viewport
.Height
,
779 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0
, 2);
780 OUT_RING_CACHE ((wW
<< 16) | wX
);
781 OUT_RING_CACHE ((wH
<< 16) | wY
);
783 /* something to do with clears, possibly doesn't belong here */
784 BEGIN_RING_CACHE(NvSub3D
,
785 NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0
, 2);
786 OUT_RING_CACHE(((nmesa
->drawX
+ nmesa
->drawW
) << 16) | nmesa
->drawX
);
787 OUT_RING_CACHE(((nmesa
->drawY
+ nmesa
->drawH
) << 16) | nmesa
->drawY
);
789 /* viewport transform */
790 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX
, 8);
791 OUT_RING_CACHEf (v
[MAT_TX
]);
792 OUT_RING_CACHEf (v
[MAT_TY
]);
793 OUT_RING_CACHEf (v
[MAT_TZ
]);
794 OUT_RING_CACHEf (0.0);
795 OUT_RING_CACHEf (v
[MAT_SX
]);
796 OUT_RING_CACHEf (v
[MAT_SY
]);
797 OUT_RING_CACHEf (v
[MAT_SZ
]);
798 OUT_RING_CACHEf (0.0);
800 ctx
->Driver
.Scissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
801 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
804 static GLboolean
nv30InitCard(nouveauContextPtr nmesa
)
807 nouveauObjectOnSubchannel(nmesa
, NvSub3D
, Nv3D
);
809 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1
, 3);
813 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8
, 1);
815 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4
, 2);
818 BEGIN_RING_SIZE(NvSub3D
, 0x1b0, 1); /* SET_OBJECT8B*/
821 for(i
= 0x2c8; i
<= 0x2fc; i
+= 4)
823 BEGIN_RING_SIZE(NvSub3D
, i
, 1);
827 BEGIN_RING_SIZE(NvSub3D
, 0x0220, 1);
830 BEGIN_RING_SIZE(NvSub3D
, 0x03b0, 1);
831 OUT_RING(0x00100000);
832 BEGIN_RING_SIZE(NvSub3D
, 0x1454, 1);
834 BEGIN_RING_SIZE(NvSub3D
, 0x1d80, 1);
838 BEGIN_RING_SIZE(NvSub3D
, 0x1e98, 1);
840 BEGIN_RING_SIZE(NvSub3D
, 0x17e0, 3);
843 OUT_RING(0x3f800000);
844 BEGIN_RING_SIZE(NvSub3D
, 0x1f80, 16);
845 OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
846 OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
847 OUT_RING(0x0000ffff);
848 OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0);
849 OUT_RING(0); OUT_RING(0); OUT_RING(0);
851 BEGIN_RING_SIZE(NvSub3D, 0x100, 2);
855 BEGIN_RING_SIZE(NvSub3D
, 0x120, 3);
860 BEGIN_RING_SIZE(NvSub3D
, 0x1d88, 1);
861 OUT_RING(0x00001200);
863 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_RC_ENABLE
, 1);
869 static GLboolean
nv40InitCard(nouveauContextPtr nmesa
)
871 nouveauObjectOnSubchannel(nmesa
, NvSub3D
, Nv3D
);
873 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1
, 2);
876 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8
, 1);
878 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4
, 2);
881 BEGIN_RING_SIZE(NvSub3D
, 0x0220, 1);
884 BEGIN_RING_SIZE(NvSub3D
, 0x1ea4, 3);
885 OUT_RING(0x00000010);
886 OUT_RING(0x01000100);
887 OUT_RING(0xff800006);
888 BEGIN_RING_SIZE(NvSub3D
, 0x1fc4, 1);
889 OUT_RING(0x06144321);
890 BEGIN_RING_SIZE(NvSub3D
, 0x1fc8, 2);
891 OUT_RING(0xedcba987);
892 OUT_RING(0x00000021);
893 BEGIN_RING_SIZE(NvSub3D
, 0x1fd0, 1);
894 OUT_RING(0x00171615);
895 BEGIN_RING_SIZE(NvSub3D
, 0x1fd4, 1);
896 OUT_RING(0x001b1a19);
898 BEGIN_RING_SIZE(NvSub3D
, 0x1ef8, 1);
899 OUT_RING(0x0020ffff);
900 BEGIN_RING_SIZE(NvSub3D
, 0x1d64, 1);
901 OUT_RING(0x00d30000);
902 BEGIN_RING_SIZE(NvSub3D
, 0x1e94, 1);
903 OUT_RING(0x00000001);
909 nv30BindBuffers(nouveauContextPtr nmesa
, int num_color
,
910 nouveau_renderbuffer_t
**color
, nouveau_renderbuffer_t
*depth
)
914 w
= color
[0]->mesa
.Width
;
915 h
= color
[0]->mesa
.Height
;
921 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0
, 5);
922 OUT_RING (((w
+x
)<<16)|x
);
923 OUT_RING (((h
+y
)<<16)|y
);
924 if (color
[0]->mesa
._ActualFormat
== GL_RGBA8
)
928 if (nmesa
->screen
->card
->type
>= NV_40
)
929 OUT_RING (color
[0]->pitch
);
931 OUT_RING (color
[0]->pitch
| (depth
? (depth
->pitch
<< 16): 0));
932 OUT_RING (color
[0]->offset
);
935 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET
, 1);
936 OUT_RING (depth
->offset
);
937 if (nmesa
->screen
->card
->type
>= NV_40
) {
938 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH
, 1);
939 OUT_RING (depth
->pitch
);
946 void nv30InitStateFuncs(GLcontext
*ctx
, struct dd_function_table
*func
)
948 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
950 func
->AlphaFunc
= nv30AlphaFunc
;
951 func
->BlendColor
= nv30BlendColor
;
952 func
->BlendEquationSeparate
= nv30BlendEquationSeparate
;
953 func
->BlendFuncSeparate
= nv30BlendFuncSeparate
;
954 func
->Clear
= nv30Clear
;
955 func
->ClearColor
= nv30ClearColor
;
956 func
->ClearDepth
= nv30ClearDepth
;
957 func
->ClearStencil
= nv30ClearStencil
;
958 func
->ClipPlane
= nv30ClipPlane
;
959 func
->ColorMask
= nv30ColorMask
;
960 func
->ColorMaterial
= nv30ColorMaterial
;
961 func
->CullFace
= nv30CullFace
;
962 func
->FrontFace
= nv30FrontFace
;
963 func
->DepthFunc
= nv30DepthFunc
;
964 func
->DepthMask
= nv30DepthMask
;
965 func
->DepthRange
= nv30DepthRange
;
966 func
->Enable
= nv30Enable
;
967 func
->Fogfv
= nv30Fogfv
;
968 func
->Hint
= nv30Hint
;
969 func
->Lightfv
= nv30Lightfv
;
970 /* func->LightModelfv = nv30LightModelfv; */
971 func
->LineStipple
= nv30LineStipple
;
972 func
->LineWidth
= nv30LineWidth
;
973 func
->LogicOpcode
= nv30LogicOpcode
;
974 func
->PointParameterfv
= nv30PointParameterfv
;
975 func
->PointSize
= nv30PointSize
;
976 func
->PolygonMode
= nv30PolygonMode
;
977 func
->PolygonOffset
= nv30PolygonOffset
;
978 func
->PolygonStipple
= nv30PolygonStipple
;
980 func
->ReadBuffer
= nv30ReadBuffer
;
981 func
->RenderMode
= nv30RenderMode
;
983 func
->Scissor
= nv30Scissor
;
984 func
->ShadeModel
= nv30ShadeModel
;
985 func
->StencilFuncSeparate
= nv30StencilFuncSeparate
;
986 func
->StencilMaskSeparate
= nv30StencilMaskSeparate
;
987 func
->StencilOpSeparate
= nv30StencilOpSeparate
;
989 func
->TexGen
= nv30TexGen
;
990 func
->TexParameter
= nv30TexParameter
;
992 func
->TextureMatrix
= nv30TextureMatrix
;
995 if (nmesa
->screen
->card
->type
>= NV_40
)
996 nmesa
->hw_func
.InitCard
= nv40InitCard
;
998 nmesa
->hw_func
.InitCard
= nv30InitCard
;
999 nmesa
->hw_func
.BindBuffers
= nv30BindBuffers
;
1000 nmesa
->hw_func
.WindowMoved
= nv30WindowMoved
;