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_fbo.h"
30 #include "nouveau_util.h"
31 #include "nouveau_class.h"
32 #include "nv04_driver.h"
33 #include "nv10_driver.h"
35 static const struct dri_extension nv10_extensions
[] = {
36 { "GL_ARB_texture_env_crossbar", NULL
},
37 { "GL_EXT_texture_rectangle", NULL
},
38 { "GL_ARB_texture_env_combine", NULL
},
39 { "GL_ARB_texture_env_dot3", NULL
},
44 use_fast_zclear(GLcontext
*ctx
, GLbitfield buffers
)
46 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
47 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
49 if (buffers
& BUFFER_BIT_STENCIL
) {
51 * The stencil test is bypassed when fast Z clears are
54 nctx
->hierz
.clear_blocked
= GL_TRUE
;
55 context_dirty(ctx
, ZCLEAR
);
59 return !nctx
->hierz
.clear_blocked
&&
60 fb
->_Xmax
== fb
->Width
&& fb
->_Xmin
== 0 &&
61 fb
->_Ymax
== fb
->Height
&& fb
->_Ymin
== 0;
65 nv10_clear(GLcontext
*ctx
, GLbitfield buffers
)
67 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
68 struct nouveau_channel
*chan
= context_chan(ctx
);
69 struct nouveau_grobj
*celsius
= context_eng3d(ctx
);
70 struct nouveau_framebuffer
*nfb
= to_nouveau_framebuffer(
73 nouveau_validate_framebuffer(ctx
);
75 if ((buffers
& BUFFER_BIT_DEPTH
) &&
76 ctx
->Depth
.Mask
&& nfb
->hierz
.bo
) {
77 struct nouveau_surface
*s
= &to_nouveau_renderbuffer(
78 nfb
->base
._DepthBuffer
->Wrapped
)->surface
;
80 /* Clear the hierarchical depth buffer */
81 BEGIN_RING(chan
, celsius
, NV17TCL_LMA_DEPTH_FILL_VALUE
, 1);
82 OUT_RING(chan
, pack_zs_f(s
->format
, ctx
->Depth
.Clear
, 0));
83 BEGIN_RING(chan
, celsius
, NV17TCL_LMA_DEPTH_BUFFER_CLEAR
, 1);
86 /* Mark the depth buffer as cleared */
87 if (use_fast_zclear(ctx
, buffers
)) {
88 if (nctx
->hierz
.clear_seq
)
89 buffers
&= ~BUFFER_BIT_DEPTH
;
91 nfb
->hierz
.clear_value
=
92 pack_zs_f(s
->format
, ctx
->Depth
.Clear
, 0);
93 nctx
->hierz
.clear_seq
++;
95 context_dirty(ctx
, ZCLEAR
);
99 nouveau_clear(ctx
, buffers
);
103 nv10_hwctx_init(GLcontext
*ctx
)
105 struct nouveau_channel
*chan
= context_chan(ctx
);
106 struct nouveau_grobj
*celsius
= context_eng3d(ctx
);
107 struct nouveau_hw_state
*hw
= &to_nouveau_context(ctx
)->hw
;
110 BEGIN_RING(chan
, celsius
, NV10TCL_DMA_NOTIFY
, 1);
111 OUT_RING(chan
, hw
->ntfy
->handle
);
113 BEGIN_RING(chan
, celsius
, NV10TCL_DMA_IN_MEMORY0
, 3);
114 OUT_RING(chan
, chan
->vram
->handle
);
115 OUT_RING(chan
, chan
->gart
->handle
);
116 OUT_RING(chan
, chan
->gart
->handle
);
117 BEGIN_RING(chan
, celsius
, NV10TCL_DMA_IN_MEMORY2
, 2);
118 OUT_RING(chan
, chan
->vram
->handle
);
119 OUT_RING(chan
, chan
->vram
->handle
);
121 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
124 BEGIN_RING(chan
, celsius
, NV10TCL_RT_HORIZ
, 2);
128 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1);
129 OUT_RING(chan
, 0x7ff << 16 | 0x800);
130 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_VERT(0), 1);
131 OUT_RING(chan
, 0x7ff << 16 | 0x800);
133 for (i
= 1; i
< 8; i
++) {
134 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_HORIZ(i
), 1);
136 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_VERT(i
), 1);
140 BEGIN_RING(chan
, celsius
, 0x290, 1);
141 OUT_RING(chan
, 0x10 << 16 | 1);
142 BEGIN_RING(chan
, celsius
, 0x3f4, 1);
145 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
148 if (context_chipset(ctx
) >= 0x17) {
149 BEGIN_RING(chan
, celsius
, NV17TCL_DMA_IN_MEMORY4
, 2);
150 OUT_RING(chan
, chan
->vram
->handle
);
151 OUT_RING(chan
, chan
->vram
->handle
);
153 BEGIN_RING(chan
, celsius
, 0xd84, 1);
156 BEGIN_RING(chan
, celsius
, NV17TCL_COLOR_MASK_ENABLE
, 1);
160 if (context_chipset(ctx
) >= 0x11) {
161 BEGIN_RING(chan
, celsius
, 0x120, 3);
166 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
170 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
174 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_ENABLE
, 1);
176 BEGIN_RING(chan
, celsius
, NV10TCL_ALPHA_FUNC_ENABLE
, 1);
178 BEGIN_RING(chan
, celsius
, NV10TCL_ALPHA_FUNC_FUNC
, 2);
179 OUT_RING(chan
, 0x207);
181 BEGIN_RING(chan
, celsius
, NV10TCL_TX_ENABLE(0), 2);
185 BEGIN_RING(chan
, celsius
, NV10TCL_BLEND_FUNC_ENABLE
, 1);
187 BEGIN_RING(chan
, celsius
, NV10TCL_DITHER_ENABLE
, 2);
190 BEGIN_RING(chan
, celsius
, NV10TCL_LINE_SMOOTH_ENABLE
, 1);
192 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_WEIGHT_ENABLE
, 2);
195 BEGIN_RING(chan
, celsius
, NV10TCL_BLEND_FUNC_SRC
, 4);
199 OUT_RING(chan
, 0x8006);
200 BEGIN_RING(chan
, celsius
, NV10TCL_STENCIL_MASK
, 8);
201 OUT_RING(chan
, 0xff);
202 OUT_RING(chan
, 0x207);
204 OUT_RING(chan
, 0xff);
205 OUT_RING(chan
, 0x1e00);
206 OUT_RING(chan
, 0x1e00);
207 OUT_RING(chan
, 0x1e00);
208 OUT_RING(chan
, 0x1d01);
209 BEGIN_RING(chan
, celsius
, NV10TCL_NORMALIZE_ENABLE
, 1);
211 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_ENABLE
, 2);
214 BEGIN_RING(chan
, celsius
, NV10TCL_LIGHT_MODEL
, 1);
216 BEGIN_RING(chan
, celsius
, NV10TCL_SEPARATE_SPECULAR_ENABLE
, 1);
218 BEGIN_RING(chan
, celsius
, NV10TCL_ENABLED_LIGHTS
, 1);
220 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_OFFSET_POINT_ENABLE
, 3);
224 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_FUNC
, 1);
225 OUT_RING(chan
, 0x201);
226 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_WRITE_ENABLE
, 1);
228 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_TEST_ENABLE
, 1);
230 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_OFFSET_FACTOR
, 2);
233 BEGIN_RING(chan
, celsius
, NV10TCL_POINT_SIZE
, 1);
235 BEGIN_RING(chan
, celsius
, NV10TCL_POINT_PARAMETERS_ENABLE
, 2);
238 BEGIN_RING(chan
, celsius
, NV10TCL_LINE_WIDTH
, 1);
240 BEGIN_RING(chan
, celsius
, NV10TCL_LINE_SMOOTH_ENABLE
, 1);
242 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_MODE_FRONT
, 2);
243 OUT_RING(chan
, 0x1b02);
244 OUT_RING(chan
, 0x1b02);
245 BEGIN_RING(chan
, celsius
, NV10TCL_CULL_FACE
, 2);
246 OUT_RING(chan
, 0x405);
247 OUT_RING(chan
, 0x901);
248 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_SMOOTH_ENABLE
, 1);
250 BEGIN_RING(chan
, celsius
, NV10TCL_CULL_FACE_ENABLE
, 1);
252 BEGIN_RING(chan
, celsius
, NV10TCL_TX_GEN_MODE_S(0), 8);
253 for (i
= 0; i
< 8; i
++)
256 BEGIN_RING(chan
, celsius
, NV10TCL_TX_MATRIX_ENABLE(0), 2);
259 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_EQUATION_CONSTANT
, 3);
260 OUT_RING(chan
, 0x3fc00000); /* -1.50 */
261 OUT_RING(chan
, 0xbdb8aa0a); /* -0.09 */
262 OUT_RING(chan
, 0); /* 0.00 */
264 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
267 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_MODE
, 2);
268 OUT_RING(chan
, 0x802);
270 /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when
271 * using texturing, except when using the texture matrix
273 BEGIN_RING(chan
, celsius
, NV10TCL_VIEW_MATRIX_ENABLE
, 1);
275 BEGIN_RING(chan
, celsius
, NV10TCL_COLOR_MASK
, 1);
276 OUT_RING(chan
, 0x01010101);
278 /* Set vertex component */
279 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_COL_4F_R
, 4);
280 OUT_RINGf(chan
, 1.0);
281 OUT_RINGf(chan
, 0.0);
282 OUT_RINGf(chan
, 0.0);
283 OUT_RINGf(chan
, 1.0);
284 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_COL2_3F_R
, 3);
288 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_NOR_3F_X
, 3);
291 OUT_RINGf(chan
, 1.0);
292 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_TX0_4F_S
, 4);
293 OUT_RINGf(chan
, 0.0);
294 OUT_RINGf(chan
, 0.0);
295 OUT_RINGf(chan
, 0.0);
296 OUT_RINGf(chan
, 1.0);
297 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_TX1_4F_S
, 4);
298 OUT_RINGf(chan
, 0.0);
299 OUT_RINGf(chan
, 0.0);
300 OUT_RINGf(chan
, 0.0);
301 OUT_RINGf(chan
, 1.0);
302 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_FOG_1F
, 1);
303 OUT_RINGf(chan
, 0.0);
304 BEGIN_RING(chan
, celsius
, NV10TCL_EDGEFLAG_ENABLE
, 1);
307 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_RANGE_NEAR
, 2);
309 OUT_RINGf(chan
, 16777216.0);
315 nv10_context_destroy(GLcontext
*ctx
)
317 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
319 nv04_surface_takedown(ctx
);
320 nv10_render_destroy(ctx
);
322 nouveau_grobj_free(&nctx
->hw
.eng3d
);
324 nouveau_context_deinit(ctx
);
329 nv10_context_create(struct nouveau_screen
*screen
, const GLvisual
*visual
,
330 GLcontext
*share_ctx
)
332 struct nouveau_context
*nctx
;
334 unsigned celsius_class
;
337 nctx
= CALLOC_STRUCT(nouveau_context
);
343 if (!nouveau_context_init(ctx
, screen
, visual
, share_ctx
))
346 driInitExtensions(ctx
, nv10_extensions
, GL_FALSE
);
349 ctx
->Const
.MaxTextureLevels
= 12;
350 ctx
->Const
.MaxTextureCoordUnits
= NV10_TEXTURE_UNITS
;
351 ctx
->Const
.MaxTextureImageUnits
= NV10_TEXTURE_UNITS
;
352 ctx
->Const
.MaxTextureUnits
= NV10_TEXTURE_UNITS
;
353 ctx
->Const
.MaxTextureMaxAnisotropy
= 2;
354 ctx
->Const
.MaxTextureLodBias
= 15;
355 ctx
->Driver
.Clear
= nv10_clear
;
358 ret
= nv04_surface_init(ctx
);
363 if (context_chipset(ctx
) >= 0x17)
364 celsius_class
= NV17TCL
;
365 else if (context_chipset(ctx
) >= 0x11)
366 celsius_class
= NV11TCL
;
368 celsius_class
= NV10TCL
;
370 ret
= nouveau_grobj_alloc(context_chan(ctx
), 0xbeef0001, celsius_class
,
375 nv10_hwctx_init(ctx
);
376 nv10_render_init(ctx
);
381 nv10_context_destroy(ctx
);
385 const struct nouveau_driver nv10_driver
= {
386 .context_create
= nv10_context_create
,
387 .context_destroy
= nv10_context_destroy
,
388 .surface_copy
= nv04_surface_copy
,
389 .surface_fill
= nv04_surface_fill
,
390 .emit
= (nouveau_state_func
[]) {
391 nv10_emit_alpha_func
,
392 nv10_emit_blend_color
,
393 nv10_emit_blend_equation
,
394 nv10_emit_blend_func
,
395 nv10_emit_clip_plane
,
396 nv10_emit_clip_plane
,
397 nv10_emit_clip_plane
,
398 nv10_emit_clip_plane
,
399 nv10_emit_clip_plane
,
400 nv10_emit_clip_plane
,
401 nv10_emit_color_mask
,
402 nv10_emit_color_material
,
404 nv10_emit_front_face
,
408 nv10_emit_framebuffer
,
410 nv10_emit_light_enable
,
411 nv10_emit_light_model
,
412 nv10_emit_light_source
,
413 nv10_emit_light_source
,
414 nv10_emit_light_source
,
415 nv10_emit_light_source
,
416 nv10_emit_light_source
,
417 nv10_emit_light_source
,
418 nv10_emit_light_source
,
419 nv10_emit_light_source
,
420 nv10_emit_line_stipple
,
422 nv10_emit_logic_opcode
,
423 nv10_emit_material_ambient
,
424 nouveau_emit_nothing
,
425 nv10_emit_material_diffuse
,
426 nouveau_emit_nothing
,
427 nv10_emit_material_specular
,
428 nouveau_emit_nothing
,
429 nv10_emit_material_shininess
,
430 nouveau_emit_nothing
,
432 nv10_emit_point_mode
,
433 nv10_emit_point_parameter
,
434 nv10_emit_polygon_mode
,
435 nv10_emit_polygon_offset
,
436 nv10_emit_polygon_stipple
,
437 nv10_emit_projection
,
438 nv10_emit_render_mode
,
440 nv10_emit_shade_model
,
441 nv10_emit_stencil_func
,
442 nv10_emit_stencil_mask
,
443 nv10_emit_stencil_op
,
446 nouveau_emit_nothing
,
447 nouveau_emit_nothing
,
450 nouveau_emit_nothing
,
451 nouveau_emit_nothing
,
454 nouveau_emit_nothing
,
455 nouveau_emit_nothing
,
458 nouveau_emit_nothing
,
459 nouveau_emit_nothing
,
463 .num_emit
= NUM_NV10_STATE
,