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 "main/state.h"
28 #include "nouveau_driver.h"
29 #include "nouveau_context.h"
30 #include "nouveau_fbo.h"
31 #include "nouveau_util.h"
32 #include "nouveau_class.h"
33 #include "nv04_driver.h"
34 #include "nv10_driver.h"
36 static const struct dri_extension nv10_extensions
[] = {
37 { "GL_ARB_texture_env_crossbar", NULL
},
38 { "GL_EXT_texture_rectangle", NULL
},
39 { "GL_ARB_texture_env_combine", NULL
},
40 { "GL_ARB_texture_env_dot3", NULL
},
45 use_fast_zclear(struct gl_context
*ctx
, GLbitfield buffers
)
47 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
48 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
50 if (buffers
& BUFFER_BIT_STENCIL
) {
52 * The stencil test is bypassed when fast Z clears are
55 nctx
->hierz
.clear_blocked
= GL_TRUE
;
56 context_dirty(ctx
, ZCLEAR
);
60 return !nctx
->hierz
.clear_blocked
&&
61 fb
->_Xmax
== fb
->Width
&& fb
->_Xmin
== 0 &&
62 fb
->_Ymax
== fb
->Height
&& fb
->_Ymin
== 0;
66 nv10_use_viewport_zclear(struct gl_context
*ctx
)
68 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
69 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
71 return context_chipset(ctx
) < 0x17 &&
72 !nctx
->hierz
.clear_blocked
&& fb
->_DepthBuffer
&&
73 (_mesa_get_format_bits(fb
->_DepthBuffer
->Format
,
74 GL_DEPTH_BITS
) >= 24);
78 nv10_transform_depth(struct gl_context
*ctx
, float z
)
80 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
82 if (nv10_use_viewport_zclear(ctx
))
83 return 2097152.0 * (z
+ (nctx
->hierz
.clear_seq
& 7));
85 return ctx
->DrawBuffer
->_DepthMaxF
* z
;
89 nv10_zclear(struct gl_context
*ctx
, GLbitfield
*buffers
)
92 * Pre-nv17 cards don't have native support for fast Z clears,
93 * but in some cases we can still "clear" the Z buffer without
94 * actually blitting to it if we're willing to sacrifice a few
95 * bits of depth precision.
97 * Each time a clear is requested we modify the viewport
98 * transform in such a way that the old contents of the depth
99 * buffer are clamped to the requested clear value when
100 * they're read by the GPU.
102 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
103 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
104 struct nouveau_framebuffer
*nfb
= to_nouveau_framebuffer(fb
);
105 struct nouveau_surface
*s
= &to_nouveau_renderbuffer(
106 fb
->_DepthBuffer
->Wrapped
)->surface
;
108 if (nv10_use_viewport_zclear(ctx
)) {
110 float z
= ctx
->Depth
.Clear
;
111 uint32_t value
= pack_zs_f(s
->format
, z
, 0);
113 get_scissors(fb
, &x
, &y
, &w
, &h
);
114 *buffers
&= ~BUFFER_BIT_DEPTH
;
116 if (use_fast_zclear(ctx
, *buffers
)) {
117 if (nfb
->hierz
.clear_value
!= value
) {
118 /* Don't fast clear if we're changing
119 * the depth value. */
120 nfb
->hierz
.clear_value
= value
;
122 } else if (z
== 0.0) {
123 nctx
->hierz
.clear_seq
++;
124 context_dirty(ctx
, ZCLEAR
);
126 if ((nctx
->hierz
.clear_seq
& 7) != 0 &&
127 nctx
->hierz
.clear_seq
!= 1)
128 /* We didn't wrap around -- no need to
129 * clear the depth buffer for real. */
132 } else if (z
== 1.0) {
133 nctx
->hierz
.clear_seq
--;
134 context_dirty(ctx
, ZCLEAR
);
136 if ((nctx
->hierz
.clear_seq
& 7) != 7)
142 value
= pack_zs_f(s
->format
,
143 (z
+ (nctx
->hierz
.clear_seq
& 7)) / 8, 0);
144 context_drv(ctx
)->surface_fill(ctx
, s
, ~0, value
, x
, y
, w
, h
);
149 nv17_zclear(struct gl_context
*ctx
, GLbitfield
*buffers
)
151 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
152 struct nouveau_channel
*chan
= context_chan(ctx
);
153 struct nouveau_grobj
*celsius
= context_eng3d(ctx
);
154 struct nouveau_framebuffer
*nfb
= to_nouveau_framebuffer(
156 struct nouveau_surface
*s
= &to_nouveau_renderbuffer(
157 nfb
->base
._DepthBuffer
->Wrapped
)->surface
;
159 /* Clear the hierarchical depth buffer */
160 BEGIN_RING(chan
, celsius
, NV17TCL_LMA_DEPTH_FILL_VALUE
, 1);
161 OUT_RING(chan
, pack_zs_f(s
->format
, ctx
->Depth
.Clear
, 0));
162 BEGIN_RING(chan
, celsius
, NV17TCL_LMA_DEPTH_BUFFER_CLEAR
, 1);
165 /* Mark the depth buffer as cleared */
166 if (use_fast_zclear(ctx
, *buffers
)) {
167 if (nctx
->hierz
.clear_seq
)
168 *buffers
&= ~BUFFER_BIT_DEPTH
;
170 nfb
->hierz
.clear_value
=
171 pack_zs_f(s
->format
, ctx
->Depth
.Clear
, 0);
172 nctx
->hierz
.clear_seq
++;
174 context_dirty(ctx
, ZCLEAR
);
179 nv10_clear(struct gl_context
*ctx
, GLbitfield buffers
)
181 nouveau_validate_framebuffer(ctx
);
183 if ((buffers
& BUFFER_BIT_DEPTH
) && ctx
->Depth
.Mask
) {
184 if (context_chipset(ctx
) >= 0x17)
185 nv17_zclear(ctx
, &buffers
);
187 nv10_zclear(ctx
, &buffers
);
189 /* Emit the zclear state if it's dirty */
190 _mesa_update_state(ctx
);
193 nouveau_clear(ctx
, buffers
);
197 nv10_hwctx_init(struct gl_context
*ctx
)
199 struct nouveau_channel
*chan
= context_chan(ctx
);
200 struct nouveau_grobj
*celsius
= context_eng3d(ctx
);
201 struct nouveau_hw_state
*hw
= &to_nouveau_context(ctx
)->hw
;
204 BEGIN_RING(chan
, celsius
, NV10TCL_DMA_NOTIFY
, 1);
205 OUT_RING(chan
, hw
->ntfy
->handle
);
207 BEGIN_RING(chan
, celsius
, NV10TCL_DMA_IN_MEMORY0
, 3);
208 OUT_RING(chan
, chan
->vram
->handle
);
209 OUT_RING(chan
, chan
->gart
->handle
);
210 OUT_RING(chan
, chan
->gart
->handle
);
211 BEGIN_RING(chan
, celsius
, NV10TCL_DMA_IN_MEMORY2
, 2);
212 OUT_RING(chan
, chan
->vram
->handle
);
213 OUT_RING(chan
, chan
->vram
->handle
);
215 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
218 BEGIN_RING(chan
, celsius
, NV10TCL_RT_HORIZ
, 2);
222 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1);
223 OUT_RING(chan
, 0x7ff << 16 | 0x800);
224 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_VERT(0), 1);
225 OUT_RING(chan
, 0x7ff << 16 | 0x800);
227 for (i
= 1; i
< 8; i
++) {
228 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_HORIZ(i
), 1);
230 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_VERT(i
), 1);
234 BEGIN_RING(chan
, celsius
, 0x290, 1);
235 OUT_RING(chan
, 0x10 << 16 | 1);
236 BEGIN_RING(chan
, celsius
, 0x3f4, 1);
239 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
242 if (context_chipset(ctx
) >= 0x17) {
243 BEGIN_RING(chan
, celsius
, NV17TCL_DMA_IN_MEMORY4
, 2);
244 OUT_RING(chan
, chan
->vram
->handle
);
245 OUT_RING(chan
, chan
->vram
->handle
);
247 BEGIN_RING(chan
, celsius
, 0xd84, 1);
250 BEGIN_RING(chan
, celsius
, NV17TCL_COLOR_MASK_ENABLE
, 1);
254 if (context_chipset(ctx
) >= 0x11) {
255 BEGIN_RING(chan
, celsius
, 0x120, 3);
260 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
264 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
268 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_ENABLE
, 1);
270 BEGIN_RING(chan
, celsius
, NV10TCL_ALPHA_FUNC_ENABLE
, 1);
272 BEGIN_RING(chan
, celsius
, NV10TCL_ALPHA_FUNC_FUNC
, 2);
273 OUT_RING(chan
, 0x207);
275 BEGIN_RING(chan
, celsius
, NV10TCL_TX_ENABLE(0), 2);
279 BEGIN_RING(chan
, celsius
, NV10TCL_BLEND_FUNC_ENABLE
, 1);
281 BEGIN_RING(chan
, celsius
, NV10TCL_DITHER_ENABLE
, 2);
284 BEGIN_RING(chan
, celsius
, NV10TCL_LINE_SMOOTH_ENABLE
, 1);
286 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_WEIGHT_ENABLE
, 2);
289 BEGIN_RING(chan
, celsius
, NV10TCL_BLEND_FUNC_SRC
, 4);
293 OUT_RING(chan
, 0x8006);
294 BEGIN_RING(chan
, celsius
, NV10TCL_STENCIL_MASK
, 8);
295 OUT_RING(chan
, 0xff);
296 OUT_RING(chan
, 0x207);
298 OUT_RING(chan
, 0xff);
299 OUT_RING(chan
, 0x1e00);
300 OUT_RING(chan
, 0x1e00);
301 OUT_RING(chan
, 0x1e00);
302 OUT_RING(chan
, 0x1d01);
303 BEGIN_RING(chan
, celsius
, NV10TCL_NORMALIZE_ENABLE
, 1);
305 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_ENABLE
, 2);
308 BEGIN_RING(chan
, celsius
, NV10TCL_LIGHT_MODEL
, 1);
310 BEGIN_RING(chan
, celsius
, NV10TCL_SEPARATE_SPECULAR_ENABLE
, 1);
312 BEGIN_RING(chan
, celsius
, NV10TCL_ENABLED_LIGHTS
, 1);
314 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_OFFSET_POINT_ENABLE
, 3);
318 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_FUNC
, 1);
319 OUT_RING(chan
, 0x201);
320 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_WRITE_ENABLE
, 1);
322 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_TEST_ENABLE
, 1);
324 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_OFFSET_FACTOR
, 2);
327 BEGIN_RING(chan
, celsius
, NV10TCL_POINT_SIZE
, 1);
329 BEGIN_RING(chan
, celsius
, NV10TCL_POINT_PARAMETERS_ENABLE
, 2);
332 BEGIN_RING(chan
, celsius
, NV10TCL_LINE_WIDTH
, 1);
334 BEGIN_RING(chan
, celsius
, NV10TCL_LINE_SMOOTH_ENABLE
, 1);
336 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_MODE_FRONT
, 2);
337 OUT_RING(chan
, 0x1b02);
338 OUT_RING(chan
, 0x1b02);
339 BEGIN_RING(chan
, celsius
, NV10TCL_CULL_FACE
, 2);
340 OUT_RING(chan
, 0x405);
341 OUT_RING(chan
, 0x901);
342 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_SMOOTH_ENABLE
, 1);
344 BEGIN_RING(chan
, celsius
, NV10TCL_CULL_FACE_ENABLE
, 1);
346 BEGIN_RING(chan
, celsius
, NV10TCL_TX_GEN_MODE_S(0), 8);
347 for (i
= 0; i
< 8; i
++)
350 BEGIN_RING(chan
, celsius
, NV10TCL_TX_MATRIX_ENABLE(0), 2);
353 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_EQUATION_CONSTANT
, 3);
354 OUT_RING(chan
, 0x3fc00000); /* -1.50 */
355 OUT_RING(chan
, 0xbdb8aa0a); /* -0.09 */
356 OUT_RING(chan
, 0); /* 0.00 */
358 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
361 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_MODE
, 2);
362 OUT_RING(chan
, 0x802);
364 /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when
365 * using texturing, except when using the texture matrix
367 BEGIN_RING(chan
, celsius
, NV10TCL_VIEW_MATRIX_ENABLE
, 1);
369 BEGIN_RING(chan
, celsius
, NV10TCL_COLOR_MASK
, 1);
370 OUT_RING(chan
, 0x01010101);
372 /* Set vertex component */
373 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_COL_4F_R
, 4);
374 OUT_RINGf(chan
, 1.0);
375 OUT_RINGf(chan
, 0.0);
376 OUT_RINGf(chan
, 0.0);
377 OUT_RINGf(chan
, 1.0);
378 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_COL2_3F_R
, 3);
382 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_NOR_3F_X
, 3);
385 OUT_RINGf(chan
, 1.0);
386 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_TX0_4F_S
, 4);
387 OUT_RINGf(chan
, 0.0);
388 OUT_RINGf(chan
, 0.0);
389 OUT_RINGf(chan
, 0.0);
390 OUT_RINGf(chan
, 1.0);
391 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_TX1_4F_S
, 4);
392 OUT_RINGf(chan
, 0.0);
393 OUT_RINGf(chan
, 0.0);
394 OUT_RINGf(chan
, 0.0);
395 OUT_RINGf(chan
, 1.0);
396 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_FOG_1F
, 1);
397 OUT_RINGf(chan
, 0.0);
398 BEGIN_RING(chan
, celsius
, NV10TCL_EDGEFLAG_ENABLE
, 1);
401 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_RANGE_NEAR
, 2);
402 OUT_RINGf(chan
, 0.0);
403 OUT_RINGf(chan
, 16777216.0);
409 nv10_context_destroy(struct gl_context
*ctx
)
411 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
413 nv04_surface_takedown(ctx
);
414 nv10_swtnl_destroy(ctx
);
415 nv10_vbo_destroy(ctx
);
417 nouveau_grobj_free(&nctx
->hw
.eng3d
);
419 nouveau_context_deinit(ctx
);
423 static struct gl_context
*
424 nv10_context_create(struct nouveau_screen
*screen
, const struct gl_config
*visual
,
425 struct gl_context
*share_ctx
)
427 struct nouveau_context
*nctx
;
428 struct gl_context
*ctx
;
429 unsigned celsius_class
;
432 nctx
= CALLOC_STRUCT(nouveau_context
);
438 if (!nouveau_context_init(ctx
, screen
, visual
, share_ctx
))
441 driInitExtensions(ctx
, nv10_extensions
, GL_FALSE
);
444 ctx
->Const
.MaxTextureLevels
= 12;
445 ctx
->Const
.MaxTextureCoordUnits
= NV10_TEXTURE_UNITS
;
446 ctx
->Const
.MaxTextureImageUnits
= NV10_TEXTURE_UNITS
;
447 ctx
->Const
.MaxTextureUnits
= NV10_TEXTURE_UNITS
;
448 ctx
->Const
.MaxTextureMaxAnisotropy
= 2;
449 ctx
->Const
.MaxTextureLodBias
= 15;
450 ctx
->Driver
.Clear
= nv10_clear
;
453 ret
= nv04_surface_init(ctx
);
458 if (context_chipset(ctx
) >= 0x17)
459 celsius_class
= NV17TCL
;
460 else if (context_chipset(ctx
) >= 0x11)
461 celsius_class
= NV11TCL
;
463 celsius_class
= NV10TCL
;
465 ret
= nouveau_grobj_alloc(context_chan(ctx
), 0xbeef0001, celsius_class
,
470 nv10_hwctx_init(ctx
);
472 nv10_swtnl_init(ctx
);
477 nv10_context_destroy(ctx
);
481 const struct nouveau_driver nv10_driver
= {
482 .context_create
= nv10_context_create
,
483 .context_destroy
= nv10_context_destroy
,
484 .surface_copy
= nv04_surface_copy
,
485 .surface_fill
= nv04_surface_fill
,
486 .emit
= (nouveau_state_func
[]) {
487 nv10_emit_alpha_func
,
488 nv10_emit_blend_color
,
489 nv10_emit_blend_equation
,
490 nv10_emit_blend_func
,
491 nv10_emit_clip_plane
,
492 nv10_emit_clip_plane
,
493 nv10_emit_clip_plane
,
494 nv10_emit_clip_plane
,
495 nv10_emit_clip_plane
,
496 nv10_emit_clip_plane
,
497 nv10_emit_color_mask
,
498 nv10_emit_color_material
,
500 nv10_emit_front_face
,
504 nv10_emit_framebuffer
,
506 nv10_emit_light_enable
,
507 nv10_emit_light_model
,
508 nv10_emit_light_source
,
509 nv10_emit_light_source
,
510 nv10_emit_light_source
,
511 nv10_emit_light_source
,
512 nv10_emit_light_source
,
513 nv10_emit_light_source
,
514 nv10_emit_light_source
,
515 nv10_emit_light_source
,
516 nv10_emit_line_stipple
,
518 nv10_emit_logic_opcode
,
519 nv10_emit_material_ambient
,
520 nouveau_emit_nothing
,
521 nv10_emit_material_diffuse
,
522 nouveau_emit_nothing
,
523 nv10_emit_material_specular
,
524 nouveau_emit_nothing
,
525 nv10_emit_material_shininess
,
526 nouveau_emit_nothing
,
528 nv10_emit_point_mode
,
529 nv10_emit_point_parameter
,
530 nv10_emit_polygon_mode
,
531 nv10_emit_polygon_offset
,
532 nv10_emit_polygon_stipple
,
533 nv10_emit_projection
,
534 nv10_emit_render_mode
,
536 nv10_emit_shade_model
,
537 nv10_emit_stencil_func
,
538 nv10_emit_stencil_mask
,
539 nv10_emit_stencil_op
,
542 nouveau_emit_nothing
,
543 nouveau_emit_nothing
,
546 nouveau_emit_nothing
,
547 nouveau_emit_nothing
,
550 nouveau_emit_nothing
,
551 nouveau_emit_nothing
,
554 nouveau_emit_nothing
,
555 nouveau_emit_nothing
,
559 .num_emit
= NUM_NV10_STATE
,