2 * Copyright (C) 2009-2010 Francisco Jerez.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 #include "nouveau_driver.h"
28 #include "nouveau_context.h"
29 #include "nouveau_class.h"
30 #include "nv04_driver.h"
31 #include "nv10_driver.h"
32 #include "nv20_driver.h"
34 static const struct dri_extension nv20_extensions
[] = {
35 { "GL_ARB_texture_env_crossbar", NULL
},
36 { "GL_EXT_texture_rectangle", NULL
},
37 { "GL_ARB_texture_env_combine", NULL
},
38 { "GL_ARB_texture_env_dot3", NULL
},
43 nv20_hwctx_init(GLcontext
*ctx
)
45 struct nouveau_channel
*chan
= context_chan(ctx
);
46 struct nouveau_grobj
*kelvin
= context_eng3d(ctx
);
47 struct nouveau_hw_state
*hw
= &to_nouveau_context(ctx
)->hw
;
50 BEGIN_RING(chan
, kelvin
, NV20TCL_DMA_NOTIFY
, 1);
51 OUT_RING (chan
, hw
->ntfy
->handle
);
52 BEGIN_RING(chan
, kelvin
, NV20TCL_DMA_TEXTURE0
, 2);
53 OUT_RING (chan
, chan
->vram
->handle
);
54 OUT_RING (chan
, chan
->gart
->handle
);
55 BEGIN_RING(chan
, kelvin
, NV20TCL_DMA_COLOR
, 2);
56 OUT_RING (chan
, chan
->vram
->handle
);
57 OUT_RING (chan
, chan
->vram
->handle
);
58 BEGIN_RING(chan
, kelvin
, NV20TCL_DMA_VTXBUF0
, 2);
59 OUT_RING(chan
, chan
->vram
->handle
);
60 OUT_RING(chan
, chan
->gart
->handle
);
62 BEGIN_RING(chan
, kelvin
, NV20TCL_DMA_QUERY
, 1);
65 BEGIN_RING(chan
, kelvin
, NV20TCL_RT_HORIZ
, 2);
69 BEGIN_RING(chan
, kelvin
, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 1);
70 OUT_RING (chan
, 0xfff << 16 | 0x0);
71 BEGIN_RING(chan
, kelvin
, NV20TCL_VIEWPORT_CLIP_VERT(0), 1);
72 OUT_RING (chan
, 0xfff << 16 | 0x0);
74 for (i
= 1; i
< NV20TCL_VIEWPORT_CLIP_HORIZ__SIZE
; i
++) {
75 BEGIN_RING(chan
, kelvin
, NV20TCL_VIEWPORT_CLIP_HORIZ(i
), 1);
77 BEGIN_RING(chan
, kelvin
, NV20TCL_VIEWPORT_CLIP_VERT(i
), 1);
81 BEGIN_RING(chan
, kelvin
, NV20TCL_VIEWPORT_CLIP_MODE
, 1);
84 BEGIN_RING(chan
, kelvin
, 0x17e0, 3);
85 OUT_RINGf (chan
, 0.0);
86 OUT_RINGf (chan
, 0.0);
87 OUT_RINGf (chan
, 1.0);
89 if (context_chipset(ctx
) >= 0x25) {
90 BEGIN_RING(chan
, kelvin
, NV20TCL_TX_RCOMP
, 1);
91 OUT_RING (chan
, NV20TCL_TX_RCOMP_LEQUAL
| 0xdb0);
93 BEGIN_RING(chan
, kelvin
, 0x1e68, 1);
94 OUT_RING (chan
, 0x4b800000); /* 16777216.000000 */
95 BEGIN_RING(chan
, kelvin
, NV20TCL_TX_RCOMP
, 1);
96 OUT_RING (chan
, NV20TCL_TX_RCOMP_LEQUAL
);
99 BEGIN_RING(chan
, kelvin
, 0x290, 1);
100 OUT_RING (chan
, 0x10 << 16 | 1);
101 BEGIN_RING(chan
, kelvin
, 0x9fc, 1);
103 BEGIN_RING(chan
, kelvin
, 0x1d80, 1);
105 BEGIN_RING(chan
, kelvin
, 0x9f8, 1);
107 BEGIN_RING(chan
, kelvin
, 0x17ec, 3);
108 OUT_RINGf (chan
, 0.0);
109 OUT_RINGf (chan
, 1.0);
110 OUT_RINGf (chan
, 0.0);
112 if (context_chipset(ctx
) >= 0x25) {
113 BEGIN_RING(chan
, kelvin
, 0x1d88, 1);
116 BEGIN_RING(chan
, kelvin
, NV25TCL_DMA_IN_MEMORY9
, 1);
117 OUT_RING (chan
, chan
->vram
->handle
);
118 BEGIN_RING(chan
, kelvin
, NV25TCL_DMA_IN_MEMORY8
, 1);
119 OUT_RING (chan
, chan
->vram
->handle
);
122 BEGIN_RING(chan
, kelvin
, NV20TCL_DMA_FENCE
, 1);
125 BEGIN_RING(chan
, kelvin
, 0x1e98, 1);
128 BEGIN_RING(chan
, kelvin
, NV20TCL_NOTIFY
, 1);
131 BEGIN_RING(chan
, kelvin
, 0x120, 3);
136 if (context_chipset(ctx
) >= 0x25) {
137 BEGIN_RING(chan
, kelvin
, 0x022c, 2);
138 OUT_RING (chan
, 0x280);
139 OUT_RING (chan
, 0x07d28000);
141 BEGIN_RING(chan
, kelvin
, 0x1da4, 1);
145 BEGIN_RING(chan
, kelvin
, NV20TCL_RT_HORIZ
, 2);
146 OUT_RING (chan
, 0 << 16 | 0);
147 OUT_RING (chan
, 0 << 16 | 0);
149 BEGIN_RING(chan
, kelvin
, NV20TCL_ALPHA_FUNC_ENABLE
, 1);
151 BEGIN_RING(chan
, kelvin
, NV20TCL_ALPHA_FUNC_FUNC
, 2);
152 OUT_RING (chan
, NV20TCL_ALPHA_FUNC_FUNC_ALWAYS
);
155 for (i
= 0; i
< NV20TCL_TX_ENABLE__SIZE
; i
++) {
156 BEGIN_RING(chan
, kelvin
, NV20TCL_TX_ENABLE(i
), 1);
160 BEGIN_RING(chan
, kelvin
, NV20TCL_TX_SHADER_OP
, 1);
162 BEGIN_RING(chan
, kelvin
, NV20TCL_TX_SHADER_CULL_MODE
, 1);
165 BEGIN_RING(chan
, kelvin
, NV20TCL_RC_IN_ALPHA(0), 4);
166 OUT_RING (chan
, 0x30d410d0);
170 BEGIN_RING(chan
, kelvin
, NV20TCL_RC_OUT_RGB(0), 4);
171 OUT_RING (chan
, 0x00000c00);
175 BEGIN_RING(chan
, kelvin
, NV20TCL_RC_ENABLE
, 1);
176 OUT_RING (chan
, 0x00011101);
177 BEGIN_RING(chan
, kelvin
, NV20TCL_RC_FINAL0
, 2);
178 OUT_RING (chan
, 0x130e0300);
179 OUT_RING (chan
, 0x0c091c80);
180 BEGIN_RING(chan
, kelvin
, NV20TCL_RC_OUT_ALPHA(0), 4);
181 OUT_RING (chan
, 0x00000c00);
185 BEGIN_RING(chan
, kelvin
, NV20TCL_RC_IN_RGB(0), 4);
186 OUT_RING (chan
, 0x20c400c0);
190 BEGIN_RING(chan
, kelvin
, NV20TCL_RC_COLOR0
, 2);
193 BEGIN_RING(chan
, kelvin
, NV20TCL_RC_CONSTANT_COLOR0(0), 4);
194 OUT_RING (chan
, 0x035125a0);
196 OUT_RING (chan
, 0x40002000);
199 BEGIN_RING(chan
, kelvin
, NV20TCL_MULTISAMPLE_CONTROL
, 1);
200 OUT_RING (chan
, 0xffff0000);
201 BEGIN_RING(chan
, kelvin
, NV20TCL_BLEND_FUNC_ENABLE
, 1);
203 BEGIN_RING(chan
, kelvin
, NV20TCL_DITHER_ENABLE
, 1);
205 BEGIN_RING(chan
, kelvin
, NV20TCL_STENCIL_ENABLE
, 1);
207 BEGIN_RING(chan
, kelvin
, NV20TCL_BLEND_FUNC_SRC
, 4);
208 OUT_RING (chan
, NV20TCL_BLEND_FUNC_SRC_ONE
);
209 OUT_RING (chan
, NV20TCL_BLEND_FUNC_DST_ZERO
);
211 OUT_RING (chan
, NV20TCL_BLEND_EQUATION_FUNC_ADD
);
212 BEGIN_RING(chan
, kelvin
, NV20TCL_STENCIL_MASK
, 7);
213 OUT_RING (chan
, 0xff);
214 OUT_RING (chan
, NV20TCL_STENCIL_FUNC_FUNC_ALWAYS
);
216 OUT_RING (chan
, 0xff);
217 OUT_RING (chan
, NV20TCL_STENCIL_OP_FAIL_KEEP
);
218 OUT_RING (chan
, NV20TCL_STENCIL_OP_ZFAIL_KEEP
);
219 OUT_RING (chan
, NV20TCL_STENCIL_OP_ZPASS_KEEP
);
221 BEGIN_RING(chan
, kelvin
, NV20TCL_COLOR_LOGIC_OP_ENABLE
, 2);
223 OUT_RING (chan
, NV20TCL_COLOR_LOGIC_OP_OP_COPY
);
224 BEGIN_RING(chan
, kelvin
, 0x17cc, 1);
226 if (context_chipset(ctx
) >= 0x25) {
227 BEGIN_RING(chan
, kelvin
, 0x1d84, 1);
230 BEGIN_RING(chan
, kelvin
, NV20TCL_LIGHTING_ENABLE
, 1);
232 BEGIN_RING(chan
, kelvin
, NV20TCL_LIGHT_MODEL
, 1);
233 OUT_RING (chan
, NV20TCL_LIGHT_MODEL_VIEWER_NONLOCAL
);
234 BEGIN_RING(chan
, kelvin
, NV20TCL_SEPARATE_SPECULAR_ENABLE
, 1);
236 BEGIN_RING(chan
, kelvin
, NV20TCL_LIGHT_MODEL_TWO_SIDE_ENABLE
, 1);
238 BEGIN_RING(chan
, kelvin
, NV20TCL_ENABLED_LIGHTS
, 1);
240 BEGIN_RING(chan
, kelvin
, NV20TCL_NORMALIZE_ENABLE
, 1);
242 BEGIN_RING(chan
, kelvin
, NV20TCL_POLYGON_STIPPLE_PATTERN(0),
243 NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE
);
244 for (i
= 0; i
< NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE
; i
++) {
245 OUT_RING(chan
, 0xffffffff);
248 BEGIN_RING(chan
, kelvin
, NV20TCL_POLYGON_OFFSET_POINT_ENABLE
, 3);
252 BEGIN_RING(chan
, kelvin
, NV20TCL_DEPTH_FUNC
, 1);
253 OUT_RING (chan
, NV20TCL_DEPTH_FUNC_LESS
);
254 BEGIN_RING(chan
, kelvin
, NV20TCL_DEPTH_WRITE_ENABLE
, 1);
256 BEGIN_RING(chan
, kelvin
, NV20TCL_DEPTH_TEST_ENABLE
, 1);
258 BEGIN_RING(chan
, kelvin
, NV20TCL_POLYGON_OFFSET_FACTOR
, 2);
259 OUT_RINGf (chan
, 0.0);
260 OUT_RINGf (chan
, 0.0);
261 BEGIN_RING(chan
, kelvin
, NV20TCL_DEPTH_UNK17D8
, 1);
263 if (context_chipset(ctx
) < 0x25) {
264 BEGIN_RING(chan
, kelvin
, 0x1d84, 1);
267 BEGIN_RING(chan
, kelvin
, NV20TCL_POINT_SIZE
, 1);
268 if (context_chipset(ctx
) >= 0x25)
269 OUT_RINGf (chan
, 1.0);
273 if (context_chipset(ctx
) >= 0x25) {
274 BEGIN_RING(chan
, kelvin
, NV20TCL_POINT_PARAMETERS_ENABLE
, 1);
276 BEGIN_RING(chan
, kelvin
, 0x0a1c, 1);
277 OUT_RING (chan
, 0x800);
279 BEGIN_RING(chan
, kelvin
, NV20TCL_POINT_PARAMETERS_ENABLE
, 2);
284 BEGIN_RING(chan
, kelvin
, NV20TCL_LINE_WIDTH
, 1);
286 BEGIN_RING(chan
, kelvin
, NV20TCL_LINE_SMOOTH_ENABLE
, 1);
288 BEGIN_RING(chan
, kelvin
, NV20TCL_POLYGON_MODE_FRONT
, 2);
289 OUT_RING (chan
, NV20TCL_POLYGON_MODE_FRONT_FILL
);
290 OUT_RING (chan
, NV20TCL_POLYGON_MODE_BACK_FILL
);
291 BEGIN_RING(chan
, kelvin
, NV20TCL_CULL_FACE
, 2);
292 OUT_RING (chan
, NV20TCL_CULL_FACE_BACK
);
293 OUT_RING (chan
, NV20TCL_FRONT_FACE_CCW
);
294 BEGIN_RING(chan
, kelvin
, NV20TCL_POLYGON_SMOOTH_ENABLE
, 1);
296 BEGIN_RING(chan
, kelvin
, NV20TCL_CULL_FACE_ENABLE
, 1);
298 BEGIN_RING(chan
, kelvin
, NV20TCL_SHADE_MODEL
, 1);
299 OUT_RING (chan
, NV20TCL_SHADE_MODEL_SMOOTH
);
300 BEGIN_RING(chan
, kelvin
, NV20TCL_POLYGON_STIPPLE_ENABLE
, 1);
303 BEGIN_RING(chan
, kelvin
, NV20TCL_TX_GEN_MODE_S(0),
304 4 * NV20TCL_TX_GEN_MODE_S__SIZE
);
305 for (i
=0; i
< 4 * NV20TCL_TX_GEN_MODE_S__SIZE
; i
++)
308 BEGIN_RING(chan
, kelvin
, NV20TCL_FOG_EQUATION_CONSTANT
, 3);
309 OUT_RINGf (chan
, 1.5);
310 OUT_RINGf (chan
, -0.090168);
311 OUT_RINGf (chan
, 0.0);
312 BEGIN_RING(chan
, kelvin
, NV20TCL_FOG_MODE
, 2);
313 OUT_RING (chan
, NV20TCL_FOG_MODE_EXP_SIGNED
);
314 OUT_RING (chan
, NV20TCL_FOG_COORD_FOG
);
315 BEGIN_RING(chan
, kelvin
, NV20TCL_FOG_ENABLE
, 2);
319 BEGIN_RING(chan
, kelvin
, NV20TCL_ENGINE
, 1);
320 OUT_RING (chan
, NV20TCL_ENGINE_FIXED
);
322 for (i
= 0; i
< NV20TCL_TX_MATRIX_ENABLE__SIZE
; i
++) {
323 BEGIN_RING(chan
, kelvin
, NV20TCL_TX_MATRIX_ENABLE(i
), 1);
327 BEGIN_RING(chan
, kelvin
, NV20TCL_VTX_ATTR_4F_X(1), 4 * 15);
328 OUT_RINGf(chan
, 1.0);
329 OUT_RINGf(chan
, 0.0);
330 OUT_RINGf(chan
, 0.0);
331 OUT_RINGf(chan
, 1.0);
332 OUT_RINGf(chan
, 0.0);
333 OUT_RINGf(chan
, 0.0);
334 OUT_RINGf(chan
, 1.0);
335 OUT_RINGf(chan
, 1.0);
336 OUT_RINGf(chan
, 1.0);
337 OUT_RINGf(chan
, 1.0);
338 OUT_RINGf(chan
, 1.0);
339 OUT_RINGf(chan
, 1.0);
340 for (i
= 0; i
< 12; i
++) {
341 OUT_RINGf(chan
, 0.0);
342 OUT_RINGf(chan
, 0.0);
343 OUT_RINGf(chan
, 0.0);
344 OUT_RINGf(chan
, 1.0);
347 BEGIN_RING(chan
, kelvin
, NV20TCL_EDGEFLAG_ENABLE
, 1);
349 BEGIN_RING(chan
, kelvin
, NV20TCL_COLOR_MASK
, 1);
350 OUT_RING (chan
, 0x00010101);
351 BEGIN_RING(chan
, kelvin
, NV20TCL_CLEAR_VALUE
, 1);
354 BEGIN_RING(chan
, kelvin
, NV20TCL_DEPTH_RANGE_NEAR
, 2);
355 OUT_RINGf (chan
, 0.0);
356 OUT_RINGf (chan
, 16777216.0);
358 BEGIN_RING(chan
, kelvin
, NV20TCL_VIEWPORT_TRANSLATE_X
, 4);
359 OUT_RINGf (chan
, 0.0);
360 OUT_RINGf (chan
, 0.0);
361 OUT_RINGf (chan
, 0.0);
362 OUT_RINGf (chan
, 16777215.0);
364 BEGIN_RING(chan
, kelvin
, NV20TCL_VIEWPORT_SCALE_X
, 4);
365 OUT_RINGf (chan
, 0.0);
366 OUT_RINGf (chan
, 0.0);
367 OUT_RINGf (chan
, 16777215.0 * 0.5);
368 OUT_RINGf (chan
, 65535.0);
374 nv20_context_destroy(GLcontext
*ctx
)
376 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
378 nv04_surface_takedown(ctx
);
379 nv20_render_destroy(ctx
);
381 nouveau_grobj_free(&nctx
->hw
.eng3d
);
383 nouveau_context_deinit(ctx
);
388 nv20_context_create(struct nouveau_screen
*screen
, const GLvisual
*visual
,
389 GLcontext
*share_ctx
)
391 struct nouveau_context
*nctx
;
393 unsigned kelvin_class
;
396 nctx
= CALLOC_STRUCT(nouveau_context
);
402 if (!nouveau_context_init(ctx
, screen
, visual
, share_ctx
))
405 driInitExtensions(ctx
, nv20_extensions
, GL_FALSE
);
408 ctx
->Const
.MaxTextureCoordUnits
= NV20_TEXTURE_UNITS
;
409 ctx
->Const
.MaxTextureImageUnits
= NV20_TEXTURE_UNITS
;
410 ctx
->Const
.MaxTextureUnits
= NV20_TEXTURE_UNITS
;
411 ctx
->Const
.MaxTextureMaxAnisotropy
= 8;
412 ctx
->Const
.MaxTextureLodBias
= 15;
415 ret
= nv04_surface_init(ctx
);
420 if (context_chipset(ctx
) >= 0x25)
421 kelvin_class
= NV25TCL
;
423 kelvin_class
= NV20TCL
;
425 ret
= nouveau_grobj_alloc(context_chan(ctx
), 0xbeef0001, kelvin_class
,
430 nv20_hwctx_init(ctx
);
431 nv20_render_init(ctx
);
436 nv20_context_destroy(ctx
);
440 const struct nouveau_driver nv20_driver
= {
441 .context_create
= nv20_context_create
,
442 .context_destroy
= nv20_context_destroy
,
443 .surface_copy
= nv04_surface_copy
,
444 .surface_fill
= nv04_surface_fill
,
445 .emit
= (nouveau_state_func
[]) {
446 nv10_emit_alpha_func
,
447 nv10_emit_blend_color
,
448 nv10_emit_blend_equation
,
449 nv10_emit_blend_func
,
450 nv20_emit_clip_plane
,
451 nv20_emit_clip_plane
,
452 nv20_emit_clip_plane
,
453 nv20_emit_clip_plane
,
454 nv20_emit_clip_plane
,
455 nv20_emit_clip_plane
,
456 nv10_emit_color_mask
,
457 nv20_emit_color_material
,
459 nv10_emit_front_face
,
463 nv20_emit_framebuffer
,
465 nv10_emit_light_enable
,
466 nv20_emit_light_model
,
467 nv20_emit_light_source
,
468 nv20_emit_light_source
,
469 nv20_emit_light_source
,
470 nv20_emit_light_source
,
471 nv20_emit_light_source
,
472 nv20_emit_light_source
,
473 nv20_emit_light_source
,
474 nv20_emit_light_source
,
475 nv10_emit_line_stipple
,
477 nv20_emit_logic_opcode
,
478 nv20_emit_material_ambient
,
479 nv20_emit_material_ambient
,
480 nv20_emit_material_diffuse
,
481 nv20_emit_material_diffuse
,
482 nv20_emit_material_specular
,
483 nv20_emit_material_specular
,
484 nv20_emit_material_shininess
,
485 nv20_emit_material_shininess
,
487 nv20_emit_point_mode
,
488 nv10_emit_point_parameter
,
489 nv10_emit_polygon_mode
,
490 nv10_emit_polygon_offset
,
491 nv10_emit_polygon_stipple
,
492 nv20_emit_projection
,
493 nv10_emit_render_mode
,
495 nv10_emit_shade_model
,
496 nv10_emit_stencil_func
,
497 nv10_emit_stencil_mask
,
498 nv10_emit_stencil_op
,
518 .num_emit
= NUM_NV20_STATE
,