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
)
81 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
84 if (mask
& (BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
))
86 if (mask
& (BUFFER_BIT_DEPTH
))
90 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS
, 1);
91 OUT_RING_CACHE(hw_bufs
);
95 static void nv20ClearColor(GLcontext
*ctx
, const GLfloat color
[4])
97 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
99 UNCLAMPED_FLOAT_TO_RGBA_CHAN(c
,color
);
100 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB
, 1);
101 OUT_RING_CACHE(PACK_COLOR_8888(c
[3],c
[0],c
[1],c
[2]));
104 static void nv20ClearDepth(GLcontext
*ctx
, GLclampd d
)
106 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
107 nmesa
->clear_value
=((nmesa
->clear_value
&0x000000FF)|(((uint32_t)(d
*0xFFFFFF))<<8));
108 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH
, 1);
109 OUT_RING_CACHE(nmesa
->clear_value
);
112 /* we're don't support indexed buffers
113 void (*ClearIndex)(GLcontext *ctx, GLuint index)
116 static void nv20ClearStencil(GLcontext
*ctx
, GLint s
)
118 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
119 nmesa
->clear_value
=((nmesa
->clear_value
&0xFFFFFF00)|(s
&0x000000FF));
120 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH
, 1);
121 OUT_RING_CACHE(nmesa
->clear_value
);
124 static void nv20ClipPlane(GLcontext
*ctx
, GLenum plane
, const GLfloat
*equation
)
126 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
127 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane
), 4);
128 OUT_RING_CACHEf(equation
[0]);
129 OUT_RING_CACHEf(equation
[1]);
130 OUT_RING_CACHEf(equation
[2]);
131 OUT_RING_CACHEf(equation
[3]);
134 static void nv20ColorMask(GLcontext
*ctx
, GLboolean rmask
, GLboolean gmask
,
135 GLboolean bmask
, GLboolean amask
)
137 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
138 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_COLOR_MASK
, 1);
139 OUT_RING_CACHE(((amask
&& 0x01) << 24) | ((rmask
&& 0x01) << 16) | ((gmask
&& 0x01)<< 8) | ((bmask
&& 0x01) << 0));
142 static void nv20ColorMaterial(GLcontext
*ctx
, GLenum face
, GLenum mode
)
147 static void nv20CullFace(GLcontext
*ctx
, GLenum mode
)
149 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
150 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_CULL_FACE
, 1);
151 OUT_RING_CACHE(mode
);
154 static void nv20FrontFace(GLcontext
*ctx
, GLenum mode
)
156 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
157 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_FRONT_FACE
, 1);
158 OUT_RING_CACHE(mode
);
161 static void nv20DepthFunc(GLcontext
*ctx
, GLenum func
)
163 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
164 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_DEPTH_FUNC
, 1);
165 OUT_RING_CACHE(func
);
168 static void nv20DepthMask(GLcontext
*ctx
, GLboolean flag
)
170 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
171 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE
, 1);
172 OUT_RING_CACHE(flag
);
175 static void nv20DepthRange(GLcontext
*ctx
, GLclampd nearval
, GLclampd farval
)
177 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
178 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR
, 2);
179 OUT_RING_CACHEf(nearval
);
180 OUT_RING_CACHEf(farval
);
183 /** Specify the current buffer for writing */
184 //void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
185 /** Specify the buffers for writing for fragment programs*/
186 //void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
188 static void nv20Enable(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
190 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
194 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE
, 1);
195 OUT_RING_CACHE(state
);
197 // case GL_AUTO_NORMAL:
199 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE
, 1);
200 OUT_RING_CACHE(state
);
208 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap
-GL_CLIP_PLANE0
), 1);
209 OUT_RING_CACHE(state
);
211 case GL_COLOR_LOGIC_OP
:
212 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE
, 1);
213 OUT_RING_CACHE(state
);
215 // case GL_COLOR_MATERIAL:
216 // case GL_COLOR_SUM_EXT:
217 // case GL_COLOR_TABLE:
218 // case GL_CONVOLUTION_1D:
219 // case GL_CONVOLUTION_2D:
221 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE
, 1);
222 OUT_RING_CACHE(state
);
225 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE
, 1);
226 OUT_RING_CACHE(state
);
229 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_DITHER_ENABLE
, 1);
230 OUT_RING_CACHE(state
);
233 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_FOG_ENABLE
, 1);
234 OUT_RING_CACHE(state
);
236 // case GL_HISTOGRAM:
237 // case GL_INDEX_LOGIC_OP:
247 uint32_t mask
=0x11<<(2*(cap
-GL_LIGHT0
));
248 nmesa
->enabled_lights
=((nmesa
->enabled_lights
&mask
)|(mask
*state
));
249 if (nmesa
->lighting_enabled
)
251 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS
, 1);
252 OUT_RING_CACHE(nmesa
->enabled_lights
);
257 nmesa
->lighting_enabled
=state
;
258 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS
, 1);
259 if (nmesa
->lighting_enabled
)
260 OUT_RING_CACHE(nmesa
->enabled_lights
);
265 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE
, 1);
266 OUT_RING_CACHE(state
);
268 // case GL_LINE_STIPPLE:
269 // case GL_MAP1_COLOR_4:
270 // case GL_MAP1_INDEX:
271 // case GL_MAP1_NORMAL:
272 // case GL_MAP1_TEXTURE_COORD_1:
273 // case GL_MAP1_TEXTURE_COORD_2:
274 // case GL_MAP1_TEXTURE_COORD_3:
275 // case GL_MAP1_TEXTURE_COORD_4:
276 // case GL_MAP1_VERTEX_3:
277 // case GL_MAP1_VERTEX_4:
278 // case GL_MAP2_COLOR_4:
279 // case GL_MAP2_INDEX:
280 // case GL_MAP2_NORMAL:
281 // case GL_MAP2_TEXTURE_COORD_1:
282 // case GL_MAP2_TEXTURE_COORD_2:
283 // case GL_MAP2_TEXTURE_COORD_3:
284 // case GL_MAP2_TEXTURE_COORD_4:
285 // case GL_MAP2_VERTEX_3:
286 // case GL_MAP2_VERTEX_4:
289 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE
, 1);
290 OUT_RING_CACHE(state
);
292 // case GL_POINT_SMOOTH:
293 case GL_POLYGON_OFFSET_POINT
:
294 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE
, 1);
295 OUT_RING_CACHE(state
);
297 case GL_POLYGON_OFFSET_LINE
:
298 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE
, 1);
299 OUT_RING_CACHE(state
);
301 case GL_POLYGON_OFFSET_FILL
:
302 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE
, 1);
303 OUT_RING_CACHE(state
);
305 case GL_POLYGON_SMOOTH
:
306 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE
, 1);
307 OUT_RING_CACHE(state
);
309 case GL_POLYGON_STIPPLE
:
310 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE
, 1);
311 OUT_RING_CACHE(state
);
313 // case GL_POST_COLOR_MATRIX_COLOR_TABLE:
314 // case GL_POST_CONVOLUTION_COLOR_TABLE:
315 // case GL_RESCALE_NORMAL:
316 case GL_SCISSOR_TEST
:
317 /* No enable bit, nv20Scissor will adjust to max range */
318 ctx
->Driver
.Scissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
319 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
321 // case GL_SEPARABLE_2D:
322 case GL_STENCIL_TEST
:
323 // TODO BACK and FRONT ?
324 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_STENCIL_ENABLE
, 1);
325 OUT_RING_CACHE(state
);
327 // case GL_TEXTURE_GEN_Q:
328 // case GL_TEXTURE_GEN_R:
329 // case GL_TEXTURE_GEN_S:
330 // case GL_TEXTURE_GEN_T:
331 // case GL_TEXTURE_1D:
332 // case GL_TEXTURE_2D:
333 // case GL_TEXTURE_3D:
337 static void nv20Fogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*params
)
339 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
343 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_FOG_MODE
, 1);
344 //OUT_RING_CACHE (params);
346 /* TODO: unsure about the rest.*/
353 static void nv20Hint(GLcontext
*ctx
, GLenum target
, GLenum mode
)
355 // TODO I need love (fog and line_smooth hints)
358 // void (*IndexMask)(GLcontext *ctx, GLuint mask);
362 SPOTLIGHT_UPDATE_EXPONENT
,
363 SPOTLIGHT_UPDATE_DIRECTION
,
367 static void nv20Lightfv(GLcontext
*ctx
, GLenum light
, GLenum pname
, const GLfloat
*params
)
369 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
370 GLint p
= light
- GL_LIGHT0
;
371 struct gl_light
*l
= &ctx
->Light
.Light
[p
];
372 int spotlight_update
= SPOTLIGHT_NO_UPDATE
;
374 /* not sure where the fourth param value goes...*/
378 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p
), 3);
379 OUT_RING_CACHEf(params
[0]);
380 OUT_RING_CACHEf(params
[1]);
381 OUT_RING_CACHEf(params
[2]);
384 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p
), 3);
385 OUT_RING_CACHEf(params
[0]);
386 OUT_RING_CACHEf(params
[1]);
387 OUT_RING_CACHEf(params
[2]);
390 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p
), 3);
391 OUT_RING_CACHEf(params
[0]);
392 OUT_RING_CACHEf(params
[1]);
393 OUT_RING_CACHEf(params
[2]);
396 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p
), 3);
397 OUT_RING_CACHEf(params
[0]);
398 OUT_RING_CACHEf(params
[1]);
399 OUT_RING_CACHEf(params
[2]);
401 case GL_SPOT_DIRECTION
:
402 spotlight_update
= SPOTLIGHT_UPDATE_DIRECTION
;
404 case GL_SPOT_EXPONENT
:
405 spotlight_update
= SPOTLIGHT_UPDATE_EXPONENT
;
408 spotlight_update
= SPOTLIGHT_UPDATE_ALL
;
410 case GL_CONSTANT_ATTENUATION
:
411 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p
), 1);
412 OUT_RING_CACHEf(*params
);
414 case GL_LINEAR_ATTENUATION
:
415 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p
), 1);
416 OUT_RING_CACHEf(*params
);
418 case GL_QUADRATIC_ATTENUATION
:
419 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p
), 1);
420 OUT_RING_CACHEf(*params
);
426 switch(spotlight_update
) {
427 case SPOTLIGHT_UPDATE_DIRECTION
:
430 GLfloat spot_light_coef_a
= 1.0 / (l
->_CosCutoff
- 1.0);
431 x
= spot_light_coef_a
* l
->_NormDirection
[0];
432 y
= spot_light_coef_a
* l
->_NormDirection
[1];
433 z
= spot_light_coef_a
* l
->_NormDirection
[2];
434 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p
), 3);
440 case SPOTLIGHT_UPDATE_EXPONENT
:
443 cc
= 1.0; /* FIXME: These need to be correctly computed */
446 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p
), 3);
452 case SPOTLIGHT_UPDATE_ALL
:
454 GLfloat cc
,lc
,qc
, x
,y
,z
, c
;
455 GLfloat spot_light_coef_a
= 1.0 / (l
->_CosCutoff
- 1.0);
456 cc
= 1.0; /* FIXME: These need to be correctly computed */
459 x
= spot_light_coef_a
* l
->_NormDirection
[0];
460 y
= spot_light_coef_a
* l
->_NormDirection
[1];
461 z
= spot_light_coef_a
* l
->_NormDirection
[2];
462 c
= spot_light_coef_a
+ 1.0;
463 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p
), 7);
478 /** Set the lighting model parameters */
479 static void (*LightModelfv
)(GLcontext
*ctx
, GLenum pname
, const GLfloat
*params
);
482 static void nv20LineStipple(GLcontext
*ctx
, GLint factor
, GLushort pattern
)
484 /* nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
485 BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1);
486 OUT_RING_CACHE((pattern << 16) | factor);*/
489 static void nv20LineWidth(GLcontext
*ctx
, GLfloat width
)
491 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
492 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LINE_WIDTH
, 1);
493 OUT_RING_CACHEf(width
);
496 static void nv20LogicOpcode(GLcontext
*ctx
, GLenum opcode
)
498 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
499 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP
, 1);
500 OUT_RING_CACHE(opcode
);
503 static void nv20PointParameterfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*params
)
505 /*TODO: not sure what goes here. */
506 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
510 /** Specify the diameter of rasterized points */
511 static void nv20PointSize(GLcontext
*ctx
, GLfloat size
)
513 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
514 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POINT_SIZE
, 1);
515 OUT_RING_CACHEf(size
);
518 /** Select a polygon rasterization mode */
519 static void nv20PolygonMode(GLcontext
*ctx
, GLenum face
, GLenum mode
)
521 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
523 if (face
== GL_FRONT
|| face
== GL_FRONT_AND_BACK
) {
524 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT
, 1);
525 OUT_RING_CACHE(mode
);
527 if (face
== GL_BACK
|| face
== GL_FRONT_AND_BACK
) {
528 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK
, 1);
529 OUT_RING_CACHE(mode
);
533 /** Set the scale and units used to calculate depth values */
534 static void nv20PolygonOffset(GLcontext
*ctx
, GLfloat factor
, GLfloat units
)
536 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
537 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR
, 2);
538 OUT_RING_CACHEf(factor
);
539 OUT_RING_CACHEf(units
);
542 /** Set the polygon stippling pattern */
543 static void nv20PolygonStipple(GLcontext
*ctx
, const GLubyte
*mask
)
545 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
546 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32);
547 OUT_RING_CACHEp(mask
, 32);
550 /* Specifies the current buffer for reading */
551 void (*ReadBuffer
)( GLcontext
*ctx
, GLenum buffer
);
552 /** Set rasterization mode */
553 void (*RenderMode
)(GLcontext
*ctx
, GLenum mode
);
555 /** Define the scissor box */
556 static void nv20Scissor(GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
558 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
560 /* There's no scissor enable bit, so adjust the scissor to cover the
561 * maximum draw buffer bounds
563 if (!ctx
->Scissor
.Enabled
) {
571 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1
, 1);
572 OUT_RING_CACHE((w
<< 16) | x
);
573 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_SCISSOR_Y2_Y1
, 1);
574 OUT_RING_CACHE((h
<< 16) | y
);
578 /** Select flat or smooth shading */
579 static void nv20ShadeModel(GLcontext
*ctx
, GLenum mode
)
581 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
583 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_SHADE_MODEL
, 1);
584 OUT_RING_CACHE(mode
);
587 /** OpenGL 2.0 two-sided StencilFunc */
588 static void nv20StencilFuncSeparate(GLcontext
*ctx
, GLenum face
, GLenum func
,
589 GLint ref
, GLuint mask
)
591 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
593 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC
, 3);
594 OUT_RING_CACHE(func
);
596 OUT_RING_CACHE(mask
);
599 /** OpenGL 2.0 two-sided StencilMask */
600 static void nv20StencilMaskSeparate(GLcontext
*ctx
, GLenum face
, GLuint mask
)
602 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
604 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_STENCIL_MASK
, 1);
605 OUT_RING_CACHE(mask
);
608 /** OpenGL 2.0 two-sided StencilOp */
609 static void nv20StencilOpSeparate(GLcontext
*ctx
, GLenum face
, GLenum fail
,
610 GLenum zfail
, GLenum zpass
)
612 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
614 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL
, 1);
615 OUT_RING_CACHE(fail
);
616 OUT_RING_CACHE(zfail
);
617 OUT_RING_CACHE(zpass
);
620 /** Control the generation of texture coordinates */
621 void (*TexGen
)(GLcontext
*ctx
, GLenum coord
, GLenum pname
,
622 const GLfloat
*params
);
623 /** Set texture environment parameters */
624 void (*TexEnv
)(GLcontext
*ctx
, GLenum target
, GLenum pname
,
625 const GLfloat
*param
);
626 /** Set texture parameters */
627 void (*TexParameter
)(GLcontext
*ctx
, GLenum target
,
628 struct gl_texture_object
*texObj
,
629 GLenum pname
, const GLfloat
*params
);
631 static void nv20TextureMatrix(GLcontext
*ctx
, GLuint unit
, const GLmatrix
*mat
)
633 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
634 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_TX_MATRIX(unit
, 0), 16);
635 /*XXX: This SHOULD work.*/
636 OUT_RING_CACHEp(mat
->m
, 16);
639 /* Update anything that depends on the window position/size */
640 static void nv20WindowMoved(nouveauContextPtr nmesa
)
642 GLcontext
*ctx
= nmesa
->glCtx
;
643 GLfloat
*v
= nmesa
->viewport
.m
;
644 GLuint w
= ctx
->Viewport
.Width
;
645 GLuint h
= ctx
->Viewport
.Height
;
646 GLuint x
= ctx
->Viewport
.X
+ nmesa
->drawX
;
647 GLuint y
= ctx
->Viewport
.Y
+ nmesa
->drawY
;
650 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ
, 2);
651 OUT_RING_CACHE((w
<< 16) | x
);
652 OUT_RING_CACHE((h
<< 16) | y
);
654 BEGIN_RING_SIZE(NvSub3D
, 0x02b4, 1);
657 BEGIN_RING_CACHE(NvSub3D
,
658 NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1);
659 OUT_RING_CACHE((4095 << 16) | 0);
660 BEGIN_RING_CACHE(NvSub3D
,
661 NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1);
662 OUT_RING_CACHE((4095 << 16) | 0);
663 for (i
=1; i
<8; i
++) {
664 BEGIN_RING_CACHE(NvSub3D
,
665 NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i
), 1);
667 BEGIN_RING_CACHE(NvSub3D
,
668 NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i
), 1);
672 ctx
->Driver
.Scissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
673 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
675 /* TODO: recalc viewport scale coefs */
678 /* Initialise any card-specific non-GL related state */
679 static GLboolean
nv20InitCard(nouveauContextPtr nmesa
)
681 nouveauObjectOnSubchannel(nmesa
, NvSub3D
, Nv3D
);
683 BEGIN_RING_SIZE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_SET_OBJECT1
, 2);
684 OUT_RING(NvDmaFB
); /* 184 dma_object1 */
685 OUT_RING(NvDmaFB
); /* 188 dma_object2 */
686 BEGIN_RING_SIZE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_SET_OBJECT3
, 2);
687 OUT_RING(NvDmaFB
); /* 194 dma_object3 */
688 OUT_RING(NvDmaFB
); /* 198 dma_object4 */
689 BEGIN_RING_SIZE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8
, 1);
690 OUT_RING(NvDmaFB
); /* 1a8 dma_object8 */
692 BEGIN_RING_SIZE(NvSub3D
, 0x17e0, 3);
697 BEGIN_RING_SIZE(NvSub3D
, 0x1e6c, 1);
699 BEGIN_RING_SIZE(NvSub3D
, 0x0290, 1);
700 OUT_RING(0x00100001);
701 BEGIN_RING_SIZE(NvSub3D
, 0x09fc, 1);
703 BEGIN_RING_SIZE(NvSub3D
, 0x1d80, 1);
705 BEGIN_RING_SIZE(NvSub3D
, 0x09f8, 1);
708 BEGIN_RING_SIZE(NvSub3D
, 0x17ec, 3);
713 BEGIN_RING_SIZE(NvSub3D
, 0x1d88, 1);
716 /* FIXME: More dma objects to setup ? */
718 BEGIN_RING_SIZE(NvSub3D
, 0x1e98, 1);
721 BEGIN_RING_SIZE(NvSub3D
, 0x120, 3);
729 /* Update buffer offset/pitch/format */
730 static GLboolean
nv20BindBuffers(nouveauContextPtr nmesa
, int num_color
,
731 nouveau_renderbuffer
**color
,
732 nouveau_renderbuffer
*depth
)
735 GLuint pitch
, format
, depth_pitch
;
737 w
= color
[0]->mesa
.Width
;
738 h
= color
[0]->mesa
.Height
;
745 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ
, 6);
746 OUT_RING_CACHE((w
<< 16) | x
);
747 OUT_RING_CACHE((h
<< 16) | y
);
748 depth_pitch
= (depth
? depth
->pitch
: color
[0]->pitch
);
749 pitch
= (depth_pitch
<<16) | color
[0]->pitch
;
751 if (color
[0]->mesa
._ActualFormat
!= GL_RGBA8
) {
752 format
= 0x123; /* R5G6B5 color buffer */
754 OUT_RING_CACHE(format
);
755 OUT_RING_CACHE(pitch
);
756 OUT_RING_CACHE(color
[0]->offset
);
757 OUT_RING_CACHE(depth
? depth
->offset
: color
[0]->offset
);
760 BEGIN_RING_SIZE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH
, 2);
761 /* TODO: use a different buffer */
762 OUT_RING(depth
->pitch
);
763 OUT_RING(depth
->offset
);
766 /* Always set to bottom left of buffer */
767 BEGIN_RING_CACHE(NvSub3D
, NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X
, 4);
768 OUT_RING_CACHEf (0.0);
769 OUT_RING_CACHEf ((GLfloat
) h
);
770 OUT_RING_CACHEf (0.0);
771 OUT_RING_CACHEf (0.0);
776 void nv20InitStateFuncs(GLcontext
*ctx
, struct dd_function_table
*func
)
778 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
780 func
->AlphaFunc
= nv20AlphaFunc
;
781 func
->BlendColor
= nv20BlendColor
;
782 func
->BlendEquationSeparate
= nv20BlendEquationSeparate
;
783 func
->BlendFuncSeparate
= nv20BlendFuncSeparate
;
784 func
->Clear
= nv20Clear
;
785 func
->ClearColor
= nv20ClearColor
;
786 func
->ClearDepth
= nv20ClearDepth
;
787 func
->ClearStencil
= nv20ClearStencil
;
788 func
->ClipPlane
= nv20ClipPlane
;
789 func
->ColorMask
= nv20ColorMask
;
790 func
->ColorMaterial
= nv20ColorMaterial
;
791 func
->CullFace
= nv20CullFace
;
792 func
->FrontFace
= nv20FrontFace
;
793 func
->DepthFunc
= nv20DepthFunc
;
794 func
->DepthMask
= nv20DepthMask
;
795 func
->DepthRange
= nv20DepthRange
;
796 func
->Enable
= nv20Enable
;
797 func
->Fogfv
= nv20Fogfv
;
798 func
->Hint
= nv20Hint
;
799 func
->Lightfv
= nv20Lightfv
;
800 /* func->LightModelfv = nv20LightModelfv; */
801 func
->LineStipple
= nv20LineStipple
;
802 func
->LineWidth
= nv20LineWidth
;
803 func
->LogicOpcode
= nv20LogicOpcode
;
804 func
->PointParameterfv
= nv20PointParameterfv
;
805 func
->PointSize
= nv20PointSize
;
806 func
->PolygonMode
= nv20PolygonMode
;
807 func
->PolygonOffset
= nv20PolygonOffset
;
808 func
->PolygonStipple
= nv20PolygonStipple
;
809 /* func->ReadBuffer = nv20ReadBuffer;*/
810 /* func->RenderMode = nv20RenderMode;*/
811 func
->Scissor
= nv20Scissor
;
812 func
->ShadeModel
= nv20ShadeModel
;
813 func
->StencilFuncSeparate
= nv20StencilFuncSeparate
;
814 func
->StencilMaskSeparate
= nv20StencilMaskSeparate
;
815 func
->StencilOpSeparate
= nv20StencilOpSeparate
;
816 /* func->TexGen = nv20TexGen;*/
817 /* func->TexParameter = nv20TexParameter;*/
818 func
->TextureMatrix
= nv20TextureMatrix
;
820 nmesa
->hw_func
.InitCard
= nv20InitCard
;
821 nmesa
->hw_func
.BindBuffers
= nv20BindBuffers
;
822 nmesa
->hw_func
.WindowMoved
= nv20WindowMoved
;