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"
32 #include "tnl/t_pipeline.h"
37 static void nv20AlphaFunc(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
39 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
41 CLAMPED_FLOAT_TO_UBYTE(ubRef
, ref
);
43 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC
, 2);
45 OUT_RING_CACHE(ubRef
);
48 static void nv20BlendColor(GLcontext
*ctx
, const GLfloat color
[4])
50 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
53 CLAMPED_FLOAT_TO_UBYTE(cf
[0], color
[0]);
54 CLAMPED_FLOAT_TO_UBYTE(cf
[1], color
[1]);
55 CLAMPED_FLOAT_TO_UBYTE(cf
[2], color
[2]);
56 CLAMPED_FLOAT_TO_UBYTE(cf
[3], color
[3]);
58 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_BLEND_COLOR
, 1);
59 OUT_RING_CACHE(PACK_COLOR_8888(cf
[3], cf
[1], cf
[2], cf
[0]));
62 static void nv20BlendEquationSeparate(GLcontext
*ctx
, GLenum modeRGB
, GLenum modeA
)
64 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
65 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_BLEND_EQUATION
, 1);
66 OUT_RING_CACHE((modeA
<<16) | modeRGB
);
70 static void nv20BlendFuncSeparate(GLcontext
*ctx
, GLenum sfactorRGB
, GLenum dfactorRGB
,
71 GLenum sfactorA
, GLenum dfactorA
)
73 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
74 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC
, 2);
75 OUT_RING_CACHE((sfactorA
<<16) | sfactorRGB
);
76 OUT_RING_CACHE((dfactorA
<<16) | dfactorRGB
);
79 static void nv20Clear(GLcontext
*ctx
, GLbitfield mask
)
84 static void nv20ClearColor(GLcontext
*ctx
, const GLfloat color
[4])
86 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
88 UNCLAMPED_FLOAT_TO_RGBA_CHAN(c
,color
);
89 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB
, 1);
90 OUT_RING_CACHE(PACK_COLOR_8888(c
[3],c
[0],c
[1],c
[2]));
93 static void nv20ClearDepth(GLcontext
*ctx
, GLclampd d
)
95 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
96 nmesa
->clear_value
=((nmesa
->clear_value
&0x000000FF)|(((uint32_t)(d
*0xFFFFFF))<<8));
97 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH
, 1);
98 OUT_RING_CACHE(nmesa
->clear_value
);
101 /* we're don't support indexed buffers
102 void (*ClearIndex)(GLcontext *ctx, GLuint index)
105 static void nv20ClearStencil(GLcontext
*ctx
, GLint s
)
107 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
108 nmesa
->clear_value
=((nmesa
->clear_value
&0xFFFFFF00)|(s
&0x000000FF));
109 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH
, 1);
110 OUT_RING_CACHE(nmesa
->clear_value
);
113 static void nv20ClipPlane(GLcontext
*ctx
, GLenum plane
, const GLfloat
*equation
)
115 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
116 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane
), 4);
117 OUT_RING_CACHEf(equation
[0]);
118 OUT_RING_CACHEf(equation
[1]);
119 OUT_RING_CACHEf(equation
[2]);
120 OUT_RING_CACHEf(equation
[3]);
123 static void nv20ColorMask(GLcontext
*ctx
, GLboolean rmask
, GLboolean gmask
,
124 GLboolean bmask
, GLboolean amask
)
126 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
127 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_COLOR_MASK
, 1);
128 OUT_RING_CACHE(((amask
&& 0x01) << 24) | ((rmask
&& 0x01) << 16) | ((gmask
&& 0x01)<< 8) | ((bmask
&& 0x01) << 0));
131 static void nv20ColorMaterial(GLcontext
*ctx
, GLenum face
, GLenum mode
)
136 static void nv20CullFace(GLcontext
*ctx
, GLenum mode
)
138 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
139 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_CULL_FACE
, 1);
140 OUT_RING_CACHE(mode
);
143 static void nv20FrontFace(GLcontext
*ctx
, GLenum mode
)
145 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
146 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_FRONT_FACE
, 1);
147 OUT_RING_CACHE(mode
);
150 static void nv20DepthFunc(GLcontext
*ctx
, GLenum func
)
152 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
153 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_DEPTH_FUNC
, 1);
154 OUT_RING_CACHE(func
);
157 static void nv20DepthMask(GLcontext
*ctx
, GLboolean flag
)
159 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
160 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE
, 1);
161 OUT_RING_CACHE(flag
);
164 static void nv20DepthRange(GLcontext
*ctx
, GLclampd nearval
, GLclampd farval
)
166 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
167 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR
, 2);
168 OUT_RING_CACHEf(nearval
);
169 OUT_RING_CACHEf(farval
);
172 /** Specify the current buffer for writing */
173 //void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
174 /** Specify the buffers for writing for fragment programs*/
175 //void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
177 static void nv20Enable(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
179 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
183 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE
, 1);
184 OUT_RING_CACHE(state
);
186 // case GL_AUTO_NORMAL:
188 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE
, 1);
189 OUT_RING_CACHE(state
);
197 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap
-GL_CLIP_PLANE0
), 1);
198 OUT_RING_CACHE(state
);
200 case GL_COLOR_LOGIC_OP
:
201 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE
, 1);
202 OUT_RING_CACHE(state
);
204 // case GL_COLOR_MATERIAL:
205 // case GL_COLOR_SUM_EXT:
206 // case GL_COLOR_TABLE:
207 // case GL_CONVOLUTION_1D:
208 // case GL_CONVOLUTION_2D:
210 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE
, 1);
211 OUT_RING_CACHE(state
);
214 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE
, 1);
215 OUT_RING_CACHE(state
);
218 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_DITHER_ENABLE
, 1);
219 OUT_RING_CACHE(state
);
222 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_FOG_ENABLE
, 1);
223 OUT_RING_CACHE(state
);
225 // case GL_HISTOGRAM:
226 // case GL_INDEX_LOGIC_OP:
236 uint32_t mask
=0x11<<(2*(cap
-GL_LIGHT0
));
237 nmesa
->enabled_lights
=((nmesa
->enabled_lights
&mask
)|(mask
*state
));
238 if (nmesa
->lighting_enabled
)
240 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS
, 1);
241 OUT_RING_CACHE(nmesa
->enabled_lights
);
246 nmesa
->lighting_enabled
=state
;
247 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS
, 1);
248 if (nmesa
->lighting_enabled
)
249 OUT_RING_CACHE(nmesa
->enabled_lights
);
254 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE
, 1);
255 OUT_RING_CACHE(state
);
257 // case GL_LINE_STIPPLE:
258 // case GL_MAP1_COLOR_4:
259 // case GL_MAP1_INDEX:
260 // case GL_MAP1_NORMAL:
261 // case GL_MAP1_TEXTURE_COORD_1:
262 // case GL_MAP1_TEXTURE_COORD_2:
263 // case GL_MAP1_TEXTURE_COORD_3:
264 // case GL_MAP1_TEXTURE_COORD_4:
265 // case GL_MAP1_VERTEX_3:
266 // case GL_MAP1_VERTEX_4:
267 // case GL_MAP2_COLOR_4:
268 // case GL_MAP2_INDEX:
269 // case GL_MAP2_NORMAL:
270 // case GL_MAP2_TEXTURE_COORD_1:
271 // case GL_MAP2_TEXTURE_COORD_2:
272 // case GL_MAP2_TEXTURE_COORD_3:
273 // case GL_MAP2_TEXTURE_COORD_4:
274 // case GL_MAP2_VERTEX_3:
275 // case GL_MAP2_VERTEX_4:
278 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE
, 1);
279 OUT_RING_CACHE(state
);
281 // case GL_POINT_SMOOTH:
282 case GL_POLYGON_OFFSET_POINT
:
283 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE
, 1);
284 OUT_RING_CACHE(state
);
286 case GL_POLYGON_OFFSET_LINE
:
287 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE
, 1);
288 OUT_RING_CACHE(state
);
290 case GL_POLYGON_OFFSET_FILL
:
291 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE
, 1);
292 OUT_RING_CACHE(state
);
294 case GL_POLYGON_SMOOTH
:
295 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE
, 1);
296 OUT_RING_CACHE(state
);
298 case GL_POLYGON_STIPPLE
:
299 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE
, 1);
300 OUT_RING_CACHE(state
);
302 // case GL_POST_COLOR_MATRIX_COLOR_TABLE:
303 // case GL_POST_CONVOLUTION_COLOR_TABLE:
304 // case GL_RESCALE_NORMAL:
305 case GL_SCISSOR_TEST
:
306 /* No enable bit, nv20Scissor will adjust to max range */
307 ctx
->Driver
.Scissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
308 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
310 // case GL_SEPARABLE_2D:
311 case GL_STENCIL_TEST
:
312 // TODO BACK and FRONT ?
313 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_STENCIL_ENABLE
, 1);
314 OUT_RING_CACHE(state
);
316 // case GL_TEXTURE_GEN_Q:
317 // case GL_TEXTURE_GEN_R:
318 // case GL_TEXTURE_GEN_S:
319 // case GL_TEXTURE_GEN_T:
320 // case GL_TEXTURE_1D:
321 // case GL_TEXTURE_2D:
322 // case GL_TEXTURE_3D:
326 static void nv20Fogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*params
)
328 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
332 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_FOG_MODE
, 1);
333 //OUT_RING_CACHE (params);
335 /* TODO: unsure about the rest.*/
342 static void nv20Hint(GLcontext
*ctx
, GLenum target
, GLenum mode
)
344 // TODO I need love (fog and line_smooth hints)
347 // void (*IndexMask)(GLcontext *ctx, GLuint mask);
351 SPOTLIGHT_UPDATE_EXPONENT
,
352 SPOTLIGHT_UPDATE_DIRECTION
,
356 static void nv20Lightfv(GLcontext
*ctx
, GLenum light
, GLenum pname
, const GLfloat
*params
)
358 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
359 GLint p
= light
- GL_LIGHT0
;
360 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
361 int spotlight_update
= SPOTLIGHT_NO_UPDATE
;
363 /* not sure where the fourth param value goes...*/
367 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p
), 3);
368 OUT_RING_CACHEf(params
[0]);
369 OUT_RING_CACHEf(params
[1]);
370 OUT_RING_CACHEf(params
[2]);
373 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p
), 3);
374 OUT_RING_CACHEf(params
[0]);
375 OUT_RING_CACHEf(params
[1]);
376 OUT_RING_CACHEf(params
[2]);
379 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p
), 3);
380 OUT_RING_CACHEf(params
[0]);
381 OUT_RING_CACHEf(params
[1]);
382 OUT_RING_CACHEf(params
[2]);
385 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p
), 3);
386 OUT_RING_CACHEf(params
[0]);
387 OUT_RING_CACHEf(params
[1]);
388 OUT_RING_CACHEf(params
[2]);
390 case GL_SPOT_DIRECTION
:
391 spotlight_update
= SPOTLIGHT_UPDATE_DIRECTION
;
393 case GL_SPOT_EXPONENT
:
394 spotlight_update
= SPOTLIGHT_UPDATE_EXPONENT
;
397 spotlight_update
= SPOTLIGHT_UPDATE_ALL
;
399 case GL_CONSTANT_ATTENUATION
:
400 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p
), 1);
401 OUT_RING_CACHEf(*params
);
403 case GL_LINEAR_ATTENUATION
:
404 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p
), 1);
405 OUT_RING_CACHEf(*params
);
407 case GL_QUADRATIC_ATTENUATION
:
408 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p
), 1);
409 OUT_RING_CACHEf(*params
);
415 switch(spotlight_update
) {
416 case SPOTLIGHT_UPDATE_DIRECTION
:
419 GLfloat spot_light_coef_a
= 1.0 / (l
->_CosCutoff
- 1.0);
420 x
= spot_light_coef_a
* l
->_NormDirection
[0];
421 y
= spot_light_coef_a
* l
->_NormDirection
[1];
422 z
= spot_light_coef_a
* l
->_NormDirection
[2];
423 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p
), 3);
429 case SPOTLIGHT_UPDATE_EXPONENT
:
432 cc
= 1.0; /* FIXME: These need to be correctly computed */
435 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p
), 3);
441 case SPOTLIGHT_UPDATE_ALL
:
443 GLfloat cc
,lc
,qc
, x
,y
,z
, c
;
444 GLfloat spot_light_coef_a
= 1.0 / (l
->_CosCutoff
- 1.0);
445 cc
= 1.0; /* FIXME: These need to be correctly computed */
448 x
= spot_light_coef_a
* l
->_NormDirection
[0];
449 y
= spot_light_coef_a
* l
->_NormDirection
[1];
450 z
= spot_light_coef_a
* l
->_NormDirection
[2];
451 c
= spot_light_coef_a
+ 1.0;
452 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p
), 7);
467 /** Set the lighting model parameters */
468 static void (*LightModelfv
)(GLcontext
*ctx
, GLenum pname
, const GLfloat
*params
);
471 static void nv20LineStipple(GLcontext
*ctx
, GLint factor
, GLushort pattern
)
473 /* nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
474 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1);
475 OUT_RING_CACHE((pattern << 16) | factor);*/
478 static void nv20LineWidth(GLcontext
*ctx
, GLfloat width
)
480 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
481 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LINE_WIDTH
, 1);
482 OUT_RING_CACHEf(width
);
485 static void nv20LogicOpcode(GLcontext
*ctx
, GLenum opcode
)
487 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
488 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP
, 1);
489 OUT_RING_CACHE(opcode
);
492 static void nv20PointParameterfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*params
)
494 /*TODO: not sure what goes here. */
495 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
499 /** Specify the diameter of rasterized points */
500 static void nv20PointSize(GLcontext
*ctx
, GLfloat size
)
502 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
503 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POINT_SIZE
, 1);
504 OUT_RING_CACHEf(size
);
507 /** Select a polygon rasterization mode */
508 static void nv20PolygonMode(GLcontext
*ctx
, GLenum face
, GLenum mode
)
510 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
512 if (face
== GL_FRONT
|| face
== GL_FRONT_AND_BACK
) {
513 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT
, 1);
514 OUT_RING_CACHE(mode
);
516 if (face
== GL_BACK
|| face
== GL_FRONT_AND_BACK
) {
517 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK
, 1);
518 OUT_RING_CACHE(mode
);
522 /** Set the scale and units used to calculate depth values */
523 static void nv20PolygonOffset(GLcontext
*ctx
, GLfloat factor
, GLfloat units
)
525 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
526 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR
, 2);
527 OUT_RING_CACHEf(factor
);
528 OUT_RING_CACHEf(units
);
531 /** Set the polygon stippling pattern */
532 static void nv20PolygonStipple(GLcontext
*ctx
, const GLubyte
*mask
)
534 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
535 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32);
536 OUT_RING_CACHEp(mask
, 32);
539 /* Specifies the current buffer for reading */
540 void (*ReadBuffer
)( GLcontext
*ctx
, GLenum buffer
);
541 /** Set rasterization mode */
542 void (*RenderMode
)(GLcontext
*ctx
, GLenum mode
);
544 /** Define the scissor box */
545 static void nv20Scissor(GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
547 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
549 /* There's no scissor enable bit, so adjust the scissor to cover the
550 * maximum draw buffer bounds
552 if (!ctx
->Scissor
.Enabled
) {
560 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1
, 2);
561 OUT_RING_CACHE(((x
+w
-1) << 16) | x
);
562 OUT_RING_CACHE(((y
+h
-1) << 16) | y
);
565 /** Select flat or smooth shading */
566 static void nv20ShadeModel(GLcontext
*ctx
, GLenum mode
)
568 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
570 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_SHADE_MODEL
, 1);
571 OUT_RING_CACHE(mode
);
574 /** OpenGL 2.0 two-sided StencilFunc */
575 static void nv20StencilFuncSeparate(GLcontext
*ctx
, GLenum face
, GLenum func
,
576 GLint ref
, GLuint mask
)
578 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
580 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC
, 3);
581 OUT_RING_CACHE(func
);
583 OUT_RING_CACHE(mask
);
586 /** OpenGL 2.0 two-sided StencilMask */
587 static void nv20StencilMaskSeparate(GLcontext
*ctx
, GLenum face
, GLuint mask
)
589 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
591 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_STENCIL_MASK
, 1);
592 OUT_RING_CACHE(mask
);
595 /** OpenGL 2.0 two-sided StencilOp */
596 static void nv20StencilOpSeparate(GLcontext
*ctx
, GLenum face
, GLenum fail
,
597 GLenum zfail
, GLenum zpass
)
599 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
601 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL
, 1);
602 OUT_RING_CACHE(fail
);
603 OUT_RING_CACHE(zfail
);
604 OUT_RING_CACHE(zpass
);
607 /** Control the generation of texture coordinates */
608 void (*TexGen
)(GLcontext
*ctx
, GLenum coord
, GLenum pname
,
609 const GLfloat
*params
);
610 /** Set texture environment parameters */
611 void (*TexEnv
)(GLcontext
*ctx
, GLenum target
, GLenum pname
,
612 const GLfloat
*param
);
613 /** Set texture parameters */
614 void (*TexParameter
)(GLcontext
*ctx
, GLenum target
,
615 struct gl_texture_object
*texObj
,
616 GLenum pname
, const GLfloat
*params
);
618 static void nv20TextureMatrix(GLcontext
*ctx
, GLuint unit
, const GLmatrix
*mat
)
620 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
621 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_TX_MATRIX(unit
, 0), 16);
622 /*XXX: This SHOULD work.*/
623 OUT_RING_CACHEp(mat
->m
, 16);
626 /* Update anything that depends on the window position/size */
627 static void nv20WindowMoved(nouveauContextPtr nmesa
)
629 GLcontext
*ctx
= nmesa
->glCtx
;
630 GLfloat
*v
= nmesa
->viewport
.m
;
631 GLuint w
= ctx
->Viewport
.Width
;
632 GLuint h
= ctx
->Viewport
.Height
;
633 GLuint x
= ctx
->Viewport
.X
+ nmesa
->drawX
;
634 GLuint y
= ctx
->Viewport
.Y
+ nmesa
->drawY
;
637 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ
, 2);
638 OUT_RING_CACHE((w
<< 16) | x
);
639 OUT_RING_CACHE((h
<< 16) | y
);
641 BEGIN_RING_SIZE(NvSub3D
, 0x02b4, 1);
644 BEGIN_RING_CACHE(NvSub3D
,
645 NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2);
646 OUT_RING_CACHE((4095 << 16) | 0);
647 OUT_RING_CACHE((4095 << 16) | 0);
648 for (i
=1; i
<8; i
++) {
649 BEGIN_RING_CACHE(NvSub3D
,
650 NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i
), 1);
652 BEGIN_RING_CACHE(NvSub3D
,
653 NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i
), 1);
657 ctx
->Driver
.Scissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
658 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
660 /* TODO: recalc viewport scale coefs */
663 /* Initialise any card-specific non-GL related state */
664 static GLboolean
nv20InitCard(nouveauContextPtr nmesa
)
666 nouveauObjectOnSubchannel(nmesa
, NvSub3D
, Nv3D
);
668 BEGIN_RING_SIZE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_SET_OBJECT1
, 2);
669 OUT_RING(NvDmaFB
); /* 184 dma_object1 */
670 OUT_RING(NvDmaFB
); /* 188 dma_object2 */
671 BEGIN_RING_SIZE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_SET_OBJECT3
, 2);
672 OUT_RING(NvDmaFB
); /* 194 dma_object3 */
673 OUT_RING(NvDmaFB
); /* 198 dma_object4 */
674 BEGIN_RING_SIZE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8
, 1);
675 OUT_RING(NvDmaFB
); /* 1a8 dma_object8 */
677 BEGIN_RING_SIZE(NvSub3D
, 0x17e0, 3);
682 BEGIN_RING_SIZE(NvSub3D
, 0x1e6c, 1);
684 BEGIN_RING_SIZE(NvSub3D
, 0x0290, 1);
685 OUT_RING(0x00100001);
686 BEGIN_RING_SIZE(NvSub3D
, 0x09fc, 1);
688 BEGIN_RING_SIZE(NvSub3D
, 0x1d80, 1);
690 BEGIN_RING_SIZE(NvSub3D
, 0x09f8, 1);
693 BEGIN_RING_SIZE(NvSub3D
, 0x17ec, 3);
698 BEGIN_RING_SIZE(NvSub3D
, 0x1d88, 1);
701 /* FIXME: More dma objects to setup ? */
703 BEGIN_RING_SIZE(NvSub3D
, 0x1e98, 1);
706 BEGIN_RING_SIZE(NvSub3D
, 0x120, 3);
714 /* Update buffer offset/pitch/format */
715 static GLboolean
nv20BindBuffers(nouveauContextPtr nmesa
, int num_color
,
716 nouveau_renderbuffer
**color
,
717 nouveau_renderbuffer
*depth
)
720 GLuint pitch
, format
, depth_pitch
;
722 w
= color
[0]->mesa
.Width
;
723 h
= color
[0]->mesa
.Height
;
730 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ
, 6);
731 OUT_RING_CACHE((w
<< 16) | x
);
732 OUT_RING_CACHE((h
<< 16) | y
);
733 depth_pitch
= (depth
? depth
->pitch
: color
[0]->pitch
);
734 pitch
= (depth_pitch
<<16) | color
[0]->pitch
;
736 if (color
[0]->mesa
._ActualFormat
!= GL_RGBA8
) {
737 format
= 0x123; /* R5G6B5 color buffer */
739 OUT_RING_CACHE(format
);
740 OUT_RING_CACHE(pitch
);
741 OUT_RING_CACHE(color
[0]->offset
);
742 OUT_RING_CACHE(depth
? depth
->offset
: color
[0]->offset
);
745 BEGIN_RING_SIZE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH
, 2);
746 /* TODO: use a different buffer */
747 OUT_RING(depth
->pitch
);
748 OUT_RING(depth
->offset
);
751 /* Always set to bottom left of buffer */
752 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X
, 4);
753 OUT_RING_CACHEf (0.0);
754 OUT_RING_CACHEf ((GLfloat
) h
);
755 OUT_RING_CACHEf (0.0);
756 OUT_RING_CACHEf (0.0);
761 void nv20InitStateFuncs(GLcontext
*ctx
, struct dd_function_table
*func
)
763 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
765 func
->AlphaFunc
= nv20AlphaFunc
;
766 func
->BlendColor
= nv20BlendColor
;
767 func
->BlendEquationSeparate
= nv20BlendEquationSeparate
;
768 func
->BlendFuncSeparate
= nv20BlendFuncSeparate
;
769 func
->Clear
= nv20Clear
;
770 func
->ClearColor
= nv20ClearColor
;
771 func
->ClearDepth
= nv20ClearDepth
;
772 func
->ClearStencil
= nv20ClearStencil
;
773 func
->ClipPlane
= nv20ClipPlane
;
774 func
->ColorMask
= nv20ColorMask
;
775 func
->ColorMaterial
= nv20ColorMaterial
;
776 func
->CullFace
= nv20CullFace
;
777 func
->FrontFace
= nv20FrontFace
;
778 func
->DepthFunc
= nv20DepthFunc
;
779 func
->DepthMask
= nv20DepthMask
;
780 func
->DepthRange
= nv20DepthRange
;
781 func
->Enable
= nv20Enable
;
782 func
->Fogfv
= nv20Fogfv
;
783 func
->Hint
= nv20Hint
;
784 func
->Lightfv
= nv20Lightfv
;
785 /* func->LightModelfv = nv20LightModelfv; */
786 func
->LineStipple
= nv20LineStipple
;
787 func
->LineWidth
= nv20LineWidth
;
788 func
->LogicOpcode
= nv20LogicOpcode
;
789 func
->PointParameterfv
= nv20PointParameterfv
;
790 func
->PointSize
= nv20PointSize
;
791 func
->PolygonMode
= nv20PolygonMode
;
792 func
->PolygonOffset
= nv20PolygonOffset
;
793 func
->PolygonStipple
= nv20PolygonStipple
;
794 /* func->ReadBuffer = nv20ReadBuffer;*/
795 /* func->RenderMode = nv20RenderMode;*/
796 func
->Scissor
= nv20Scissor
;
797 func
->ShadeModel
= nv20ShadeModel
;
798 func
->StencilFuncSeparate
= nv20StencilFuncSeparate
;
799 func
->StencilMaskSeparate
= nv20StencilMaskSeparate
;
800 func
->StencilOpSeparate
= nv20StencilOpSeparate
;
801 /* func->TexGen = nv20TexGen;*/
802 /* func->TexParameter = nv20TexParameter;*/
803 func
->TextureMatrix
= nv20TextureMatrix
;
805 nmesa
->hw_func
.InitCard
= nv20InitCard
;
806 nmesa
->hw_func
.BindBuffers
= nv20BindBuffers
;
807 nmesa
->hw_func
.WindowMoved
= nv20WindowMoved
;