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 "nv_object.xml.h"
33 #include "nv10_3d.xml.h"
34 #include "nv04_driver.h"
35 #include "nv10_driver.h"
37 static const struct dri_extension nv10_extensions
[] = {
38 { "GL_ARB_texture_env_crossbar", NULL
},
39 { "GL_EXT_texture_rectangle", NULL
},
40 { "GL_ARB_texture_env_combine", NULL
},
41 { "GL_ARB_texture_env_dot3", NULL
},
46 use_fast_zclear(struct gl_context
*ctx
, GLbitfield buffers
)
48 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
49 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
51 if (buffers
& BUFFER_BIT_STENCIL
) {
53 * The stencil test is bypassed when fast Z clears are
56 nctx
->hierz
.clear_blocked
= GL_TRUE
;
57 context_dirty(ctx
, ZCLEAR
);
61 return !nctx
->hierz
.clear_blocked
&&
62 fb
->_Xmax
== fb
->Width
&& fb
->_Xmin
== 0 &&
63 fb
->_Ymax
== fb
->Height
&& fb
->_Ymin
== 0;
67 nv10_use_viewport_zclear(struct gl_context
*ctx
)
69 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
70 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
72 return context_chipset(ctx
) < 0x17 &&
73 !nctx
->hierz
.clear_blocked
&& fb
->_DepthBuffer
&&
74 (_mesa_get_format_bits(fb
->_DepthBuffer
->Format
,
75 GL_DEPTH_BITS
) >= 24);
79 nv10_transform_depth(struct gl_context
*ctx
, float z
)
81 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
83 if (nv10_use_viewport_zclear(ctx
))
84 return 2097152.0 * (z
+ (nctx
->hierz
.clear_seq
& 7));
86 return ctx
->DrawBuffer
->_DepthMaxF
* z
;
90 nv10_zclear(struct gl_context
*ctx
, GLbitfield
*buffers
)
93 * Pre-nv17 cards don't have native support for fast Z clears,
94 * but in some cases we can still "clear" the Z buffer without
95 * actually blitting to it if we're willing to sacrifice a few
96 * bits of depth precision.
98 * Each time a clear is requested we modify the viewport
99 * transform in such a way that the old contents of the depth
100 * buffer are clamped to the requested clear value when
101 * they're read by the GPU.
103 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
104 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
105 struct nouveau_framebuffer
*nfb
= to_nouveau_framebuffer(fb
);
106 struct nouveau_surface
*s
= &to_nouveau_renderbuffer(
107 fb
->_DepthBuffer
->Wrapped
)->surface
;
109 if (nv10_use_viewport_zclear(ctx
)) {
111 float z
= ctx
->Depth
.Clear
;
112 uint32_t value
= pack_zs_f(s
->format
, z
, 0);
114 get_scissors(fb
, &x
, &y
, &w
, &h
);
115 *buffers
&= ~BUFFER_BIT_DEPTH
;
117 if (use_fast_zclear(ctx
, *buffers
)) {
118 if (nfb
->hierz
.clear_value
!= value
) {
119 /* Don't fast clear if we're changing
120 * the depth value. */
121 nfb
->hierz
.clear_value
= value
;
123 } else if (z
== 0.0) {
124 nctx
->hierz
.clear_seq
++;
125 context_dirty(ctx
, ZCLEAR
);
127 if ((nctx
->hierz
.clear_seq
& 7) != 0 &&
128 nctx
->hierz
.clear_seq
!= 1)
129 /* We didn't wrap around -- no need to
130 * clear the depth buffer for real. */
133 } else if (z
== 1.0) {
134 nctx
->hierz
.clear_seq
--;
135 context_dirty(ctx
, ZCLEAR
);
137 if ((nctx
->hierz
.clear_seq
& 7) != 7)
143 value
= pack_zs_f(s
->format
,
144 (z
+ (nctx
->hierz
.clear_seq
& 7)) / 8, 0);
145 context_drv(ctx
)->surface_fill(ctx
, s
, ~0, value
, x
, y
, w
, h
);
150 nv17_zclear(struct gl_context
*ctx
, GLbitfield
*buffers
)
152 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
153 struct nouveau_channel
*chan
= context_chan(ctx
);
154 struct nouveau_grobj
*celsius
= context_eng3d(ctx
);
155 struct nouveau_framebuffer
*nfb
= to_nouveau_framebuffer(
157 struct nouveau_surface
*s
= &to_nouveau_renderbuffer(
158 nfb
->base
._DepthBuffer
->Wrapped
)->surface
;
160 /* Clear the hierarchical depth buffer */
161 BEGIN_RING(chan
, celsius
, NV17_3D_HIERZ_FILL_VALUE
, 1);
162 OUT_RING(chan
, pack_zs_f(s
->format
, ctx
->Depth
.Clear
, 0));
163 BEGIN_RING(chan
, celsius
, NV17_3D_HIERZ_BUFFER_CLEAR
, 1);
166 /* Mark the depth buffer as cleared */
167 if (use_fast_zclear(ctx
, *buffers
)) {
168 if (nctx
->hierz
.clear_seq
)
169 *buffers
&= ~BUFFER_BIT_DEPTH
;
171 nfb
->hierz
.clear_value
=
172 pack_zs_f(s
->format
, ctx
->Depth
.Clear
, 0);
173 nctx
->hierz
.clear_seq
++;
175 context_dirty(ctx
, ZCLEAR
);
180 nv10_clear(struct gl_context
*ctx
, GLbitfield buffers
)
182 nouveau_validate_framebuffer(ctx
);
184 if ((buffers
& BUFFER_BIT_DEPTH
) && ctx
->Depth
.Mask
) {
185 if (context_chipset(ctx
) >= 0x17)
186 nv17_zclear(ctx
, &buffers
);
188 nv10_zclear(ctx
, &buffers
);
190 /* Emit the zclear state if it's dirty */
191 _mesa_update_state(ctx
);
194 nouveau_clear(ctx
, buffers
);
198 nv10_hwctx_init(struct gl_context
*ctx
)
200 struct nouveau_channel
*chan
= context_chan(ctx
);
201 struct nouveau_grobj
*celsius
= context_eng3d(ctx
);
202 struct nouveau_hw_state
*hw
= &to_nouveau_context(ctx
)->hw
;
205 BEGIN_RING(chan
, celsius
, NV10_3D_DMA_NOTIFY
, 1);
206 OUT_RING(chan
, hw
->ntfy
->handle
);
208 BEGIN_RING(chan
, celsius
, NV10_3D_DMA_TEXTURE0
, 3);
209 OUT_RING(chan
, chan
->vram
->handle
);
210 OUT_RING(chan
, chan
->gart
->handle
);
211 OUT_RING(chan
, chan
->gart
->handle
);
212 BEGIN_RING(chan
, celsius
, NV10_3D_DMA_COLOR
, 2);
213 OUT_RING(chan
, chan
->vram
->handle
);
214 OUT_RING(chan
, chan
->vram
->handle
);
216 BEGIN_RING(chan
, celsius
, NV04_GRAPH_NOP
, 1);
219 BEGIN_RING(chan
, celsius
, NV10_3D_RT_HORIZ
, 2);
223 BEGIN_RING(chan
, celsius
, NV10_3D_VIEWPORT_CLIP_HORIZ(0), 1);
224 OUT_RING(chan
, 0x7ff << 16 | 0x800);
225 BEGIN_RING(chan
, celsius
, NV10_3D_VIEWPORT_CLIP_VERT(0), 1);
226 OUT_RING(chan
, 0x7ff << 16 | 0x800);
228 for (i
= 1; i
< 8; i
++) {
229 BEGIN_RING(chan
, celsius
, NV10_3D_VIEWPORT_CLIP_HORIZ(i
), 1);
231 BEGIN_RING(chan
, celsius
, NV10_3D_VIEWPORT_CLIP_VERT(i
), 1);
235 BEGIN_RING(chan
, celsius
, 0x290, 1);
236 OUT_RING(chan
, 0x10 << 16 | 1);
237 BEGIN_RING(chan
, celsius
, 0x3f4, 1);
240 BEGIN_RING(chan
, celsius
, NV04_GRAPH_NOP
, 1);
243 if (context_chipset(ctx
) >= 0x17) {
244 BEGIN_RING(chan
, celsius
, NV17_3D_UNK01AC
, 2);
245 OUT_RING(chan
, chan
->vram
->handle
);
246 OUT_RING(chan
, chan
->vram
->handle
);
248 BEGIN_RING(chan
, celsius
, 0xd84, 1);
251 BEGIN_RING(chan
, celsius
, NV17_3D_COLOR_MASK_ENABLE
, 1);
255 if (context_chipset(ctx
) >= 0x11) {
256 BEGIN_RING(chan
, celsius
, 0x120, 3);
261 BEGIN_RING(chan
, celsius
, NV04_GRAPH_NOP
, 1);
265 BEGIN_RING(chan
, celsius
, NV04_GRAPH_NOP
, 1);
269 BEGIN_RING(chan
, celsius
, NV10_3D_FOG_ENABLE
, 1);
271 BEGIN_RING(chan
, celsius
, NV10_3D_ALPHA_FUNC_ENABLE
, 1);
273 BEGIN_RING(chan
, celsius
, NV10_3D_ALPHA_FUNC_FUNC
, 2);
274 OUT_RING(chan
, 0x207);
276 BEGIN_RING(chan
, celsius
, NV10_3D_TEX_ENABLE(0), 2);
280 BEGIN_RING(chan
, celsius
, NV10_3D_BLEND_FUNC_ENABLE
, 1);
282 BEGIN_RING(chan
, celsius
, NV10_3D_DITHER_ENABLE
, 2);
285 BEGIN_RING(chan
, celsius
, NV10_3D_LINE_SMOOTH_ENABLE
, 1);
287 BEGIN_RING(chan
, celsius
, NV10_3D_VERTEX_WEIGHT_ENABLE
, 2);
290 BEGIN_RING(chan
, celsius
, NV10_3D_BLEND_FUNC_SRC
, 4);
294 OUT_RING(chan
, 0x8006);
295 BEGIN_RING(chan
, celsius
, NV10_3D_STENCIL_MASK
, 8);
296 OUT_RING(chan
, 0xff);
297 OUT_RING(chan
, 0x207);
299 OUT_RING(chan
, 0xff);
300 OUT_RING(chan
, 0x1e00);
301 OUT_RING(chan
, 0x1e00);
302 OUT_RING(chan
, 0x1e00);
303 OUT_RING(chan
, 0x1d01);
304 BEGIN_RING(chan
, celsius
, NV10_3D_NORMALIZE_ENABLE
, 1);
306 BEGIN_RING(chan
, celsius
, NV10_3D_FOG_ENABLE
, 2);
309 BEGIN_RING(chan
, celsius
, NV10_3D_LIGHT_MODEL
, 1);
311 BEGIN_RING(chan
, celsius
, NV10_3D_SEPARATE_SPECULAR_ENABLE
, 1);
313 BEGIN_RING(chan
, celsius
, NV10_3D_ENABLED_LIGHTS
, 1);
315 BEGIN_RING(chan
, celsius
, NV10_3D_POLYGON_OFFSET_POINT_ENABLE
, 3);
319 BEGIN_RING(chan
, celsius
, NV10_3D_DEPTH_FUNC
, 1);
320 OUT_RING(chan
, 0x201);
321 BEGIN_RING(chan
, celsius
, NV10_3D_DEPTH_WRITE_ENABLE
, 1);
323 BEGIN_RING(chan
, celsius
, NV10_3D_DEPTH_TEST_ENABLE
, 1);
325 BEGIN_RING(chan
, celsius
, NV10_3D_POLYGON_OFFSET_FACTOR
, 2);
328 BEGIN_RING(chan
, celsius
, NV10_3D_POINT_SIZE
, 1);
330 BEGIN_RING(chan
, celsius
, NV10_3D_POINT_PARAMETERS_ENABLE
, 2);
333 BEGIN_RING(chan
, celsius
, NV10_3D_LINE_WIDTH
, 1);
335 BEGIN_RING(chan
, celsius
, NV10_3D_LINE_SMOOTH_ENABLE
, 1);
337 BEGIN_RING(chan
, celsius
, NV10_3D_POLYGON_MODE_FRONT
, 2);
338 OUT_RING(chan
, 0x1b02);
339 OUT_RING(chan
, 0x1b02);
340 BEGIN_RING(chan
, celsius
, NV10_3D_CULL_FACE
, 2);
341 OUT_RING(chan
, 0x405);
342 OUT_RING(chan
, 0x901);
343 BEGIN_RING(chan
, celsius
, NV10_3D_POLYGON_SMOOTH_ENABLE
, 1);
345 BEGIN_RING(chan
, celsius
, NV10_3D_CULL_FACE_ENABLE
, 1);
347 BEGIN_RING(chan
, celsius
, NV10_3D_TEX_GEN_MODE(0, 0), 8);
348 for (i
= 0; i
< 8; i
++)
351 BEGIN_RING(chan
, celsius
, NV10_3D_TEX_MATRIX_ENABLE(0), 2);
354 BEGIN_RING(chan
, celsius
, NV10_3D_FOG_COEFF(0), 3);
355 OUT_RING(chan
, 0x3fc00000); /* -1.50 */
356 OUT_RING(chan
, 0xbdb8aa0a); /* -0.09 */
357 OUT_RING(chan
, 0); /* 0.00 */
359 BEGIN_RING(chan
, celsius
, NV04_GRAPH_NOP
, 1);
362 BEGIN_RING(chan
, celsius
, NV10_3D_FOG_MODE
, 2);
363 OUT_RING(chan
, 0x802);
365 /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when
366 * using texturing, except when using the texture matrix
368 BEGIN_RING(chan
, celsius
, NV10_3D_VIEW_MATRIX_ENABLE
, 1);
370 BEGIN_RING(chan
, celsius
, NV10_3D_COLOR_MASK
, 1);
371 OUT_RING(chan
, 0x01010101);
373 /* Set vertex component */
374 BEGIN_RING(chan
, celsius
, NV10_3D_VERTEX_COL_4F_R
, 4);
375 OUT_RINGf(chan
, 1.0);
376 OUT_RINGf(chan
, 0.0);
377 OUT_RINGf(chan
, 0.0);
378 OUT_RINGf(chan
, 1.0);
379 BEGIN_RING(chan
, celsius
, NV10_3D_VERTEX_COL2_3F_R
, 3);
383 BEGIN_RING(chan
, celsius
, NV10_3D_VERTEX_NOR_3F_X
, 3);
386 OUT_RINGf(chan
, 1.0);
387 BEGIN_RING(chan
, celsius
, NV10_3D_VERTEX_TX0_4F_S
, 4);
388 OUT_RINGf(chan
, 0.0);
389 OUT_RINGf(chan
, 0.0);
390 OUT_RINGf(chan
, 0.0);
391 OUT_RINGf(chan
, 1.0);
392 BEGIN_RING(chan
, celsius
, NV10_3D_VERTEX_TX1_4F_S
, 4);
393 OUT_RINGf(chan
, 0.0);
394 OUT_RINGf(chan
, 0.0);
395 OUT_RINGf(chan
, 0.0);
396 OUT_RINGf(chan
, 1.0);
397 BEGIN_RING(chan
, celsius
, NV10_3D_VERTEX_FOG_1F
, 1);
398 OUT_RINGf(chan
, 0.0);
399 BEGIN_RING(chan
, celsius
, NV10_3D_EDGEFLAG_ENABLE
, 1);
402 BEGIN_RING(chan
, celsius
, NV10_3D_DEPTH_RANGE_NEAR
, 2);
403 OUT_RINGf(chan
, 0.0);
404 OUT_RINGf(chan
, 16777216.0);
410 nv10_context_destroy(struct gl_context
*ctx
)
412 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
414 nv04_surface_takedown(ctx
);
415 nv10_swtnl_destroy(ctx
);
416 nv10_vbo_destroy(ctx
);
418 nouveau_grobj_free(&nctx
->hw
.eng3d
);
420 nouveau_context_deinit(ctx
);
424 static struct gl_context
*
425 nv10_context_create(struct nouveau_screen
*screen
, const struct gl_config
*visual
,
426 struct gl_context
*share_ctx
)
428 struct nouveau_context
*nctx
;
429 struct gl_context
*ctx
;
430 unsigned celsius_class
;
433 nctx
= CALLOC_STRUCT(nouveau_context
);
439 if (!nouveau_context_init(ctx
, screen
, visual
, share_ctx
))
442 driInitExtensions(ctx
, nv10_extensions
, GL_FALSE
);
445 ctx
->Const
.MaxTextureLevels
= 12;
446 ctx
->Const
.MaxTextureCoordUnits
= NV10_TEXTURE_UNITS
;
447 ctx
->Const
.MaxTextureImageUnits
= NV10_TEXTURE_UNITS
;
448 ctx
->Const
.MaxTextureUnits
= NV10_TEXTURE_UNITS
;
449 ctx
->Const
.MaxTextureMaxAnisotropy
= 2;
450 ctx
->Const
.MaxTextureLodBias
= 15;
451 ctx
->Driver
.Clear
= nv10_clear
;
454 ret
= nv04_surface_init(ctx
);
459 if (context_chipset(ctx
) >= 0x17)
460 celsius_class
= NV17_3D
;
461 else if (context_chipset(ctx
) >= 0x11)
462 celsius_class
= NV11_3D
;
464 celsius_class
= NV10_3D
;
466 ret
= nouveau_grobj_alloc(context_chan(ctx
), 0xbeef0001, celsius_class
,
471 nv10_hwctx_init(ctx
);
473 nv10_swtnl_init(ctx
);
478 nv10_context_destroy(ctx
);
482 const struct nouveau_driver nv10_driver
= {
483 .context_create
= nv10_context_create
,
484 .context_destroy
= nv10_context_destroy
,
485 .surface_copy
= nv04_surface_copy
,
486 .surface_fill
= nv04_surface_fill
,
487 .emit
= (nouveau_state_func
[]) {
488 nv10_emit_alpha_func
,
489 nv10_emit_blend_color
,
490 nv10_emit_blend_equation
,
491 nv10_emit_blend_func
,
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_clip_plane
,
498 nv10_emit_color_mask
,
499 nv10_emit_color_material
,
501 nv10_emit_front_face
,
505 nv10_emit_framebuffer
,
507 nv10_emit_light_enable
,
508 nv10_emit_light_model
,
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_light_source
,
517 nv10_emit_line_stipple
,
519 nv10_emit_logic_opcode
,
520 nv10_emit_material_ambient
,
521 nouveau_emit_nothing
,
522 nv10_emit_material_diffuse
,
523 nouveau_emit_nothing
,
524 nv10_emit_material_specular
,
525 nouveau_emit_nothing
,
526 nv10_emit_material_shininess
,
527 nouveau_emit_nothing
,
529 nv10_emit_point_mode
,
530 nv10_emit_point_parameter
,
531 nv10_emit_polygon_mode
,
532 nv10_emit_polygon_offset
,
533 nv10_emit_polygon_stipple
,
534 nv10_emit_projection
,
535 nv10_emit_render_mode
,
537 nv10_emit_shade_model
,
538 nv10_emit_stencil_func
,
539 nv10_emit_stencil_mask
,
540 nv10_emit_stencil_op
,
543 nouveau_emit_nothing
,
544 nouveau_emit_nothing
,
547 nouveau_emit_nothing
,
548 nouveau_emit_nothing
,
551 nouveau_emit_nothing
,
552 nouveau_emit_nothing
,
555 nouveau_emit_nothing
,
556 nouveau_emit_nothing
,
560 .num_emit
= NUM_NV10_STATE
,