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_use_viewport_zclear(GLcontext
*ctx
)
67 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
68 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
70 return context_chipset(ctx
) < 0x17 &&
71 !nctx
->hierz
.clear_blocked
&& fb
->_DepthBuffer
&&
72 (_mesa_get_format_bits(fb
->_DepthBuffer
->Format
,
73 GL_DEPTH_BITS
) >= 24);
77 nv10_transform_depth(GLcontext
*ctx
, float z
)
79 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
81 if (nv10_use_viewport_zclear(ctx
))
82 return 2097152.0 * (z
+ (nctx
->hierz
.clear_seq
& 7));
84 return ctx
->DrawBuffer
->_DepthMaxF
* z
;
88 nv10_zclear(GLcontext
*ctx
, GLbitfield
*buffers
)
91 * Pre-nv17 cards don't have native support for fast Z clears,
92 * but in some cases we can still "clear" the Z buffer without
93 * actually blitting to it if we're willing to sacrifice a few
94 * bits of depth precision.
96 * Each time a clear is requested we modify the viewport
97 * transform in such a way that the old contents of the depth
98 * buffer are clamped to the requested clear value when
99 * they're read by the GPU.
101 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
102 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
103 struct nouveau_framebuffer
*nfb
= to_nouveau_framebuffer(fb
);
104 struct nouveau_surface
*s
= &to_nouveau_renderbuffer(
105 fb
->_DepthBuffer
->Wrapped
)->surface
;
107 if (nv10_use_viewport_zclear(ctx
)) {
109 float z
= ctx
->Depth
.Clear
;
110 uint32_t value
= pack_zs_f(s
->format
, z
, 0);
112 get_scissors(fb
, &x
, &y
, &w
, &h
);
113 *buffers
&= ~BUFFER_BIT_DEPTH
;
115 if (use_fast_zclear(ctx
, *buffers
)) {
116 if (nfb
->hierz
.clear_value
!= value
) {
117 /* Don't fast clear if we're changing
118 * the depth value. */
119 nfb
->hierz
.clear_value
= value
;
121 } else if (z
== 0.0) {
122 nctx
->hierz
.clear_seq
++;
123 context_dirty(ctx
, ZCLEAR
);
125 if ((nctx
->hierz
.clear_seq
& 7) != 0 &&
126 nctx
->hierz
.clear_seq
!= 1)
127 /* We didn't wrap around -- no need to
128 * clear the depth buffer for real. */
131 } else if (z
== 1.0) {
132 nctx
->hierz
.clear_seq
--;
133 context_dirty(ctx
, ZCLEAR
);
135 if ((nctx
->hierz
.clear_seq
& 7) != 7)
141 value
= pack_zs_f(s
->format
,
142 (z
+ (nctx
->hierz
.clear_seq
& 7)) / 8, 0);
143 context_drv(ctx
)->surface_fill(ctx
, s
, ~0, value
, x
, y
, w
, h
);
148 nv17_zclear(GLcontext
*ctx
, GLbitfield
*buffers
)
150 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
151 struct nouveau_channel
*chan
= context_chan(ctx
);
152 struct nouveau_grobj
*celsius
= context_eng3d(ctx
);
153 struct nouveau_framebuffer
*nfb
= to_nouveau_framebuffer(
155 struct nouveau_surface
*s
= &to_nouveau_renderbuffer(
156 nfb
->base
._DepthBuffer
->Wrapped
)->surface
;
158 /* Clear the hierarchical depth buffer */
159 BEGIN_RING(chan
, celsius
, NV17TCL_LMA_DEPTH_FILL_VALUE
, 1);
160 OUT_RING(chan
, pack_zs_f(s
->format
, ctx
->Depth
.Clear
, 0));
161 BEGIN_RING(chan
, celsius
, NV17TCL_LMA_DEPTH_BUFFER_CLEAR
, 1);
164 /* Mark the depth buffer as cleared */
165 if (use_fast_zclear(ctx
, *buffers
)) {
166 if (nctx
->hierz
.clear_seq
)
167 *buffers
&= ~BUFFER_BIT_DEPTH
;
169 nfb
->hierz
.clear_value
=
170 pack_zs_f(s
->format
, ctx
->Depth
.Clear
, 0);
171 nctx
->hierz
.clear_seq
++;
173 context_dirty(ctx
, ZCLEAR
);
178 nv10_clear(GLcontext
*ctx
, GLbitfield buffers
)
180 nouveau_validate_framebuffer(ctx
);
182 if ((buffers
& BUFFER_BIT_DEPTH
) && ctx
->Depth
.Mask
) {
183 if (context_chipset(ctx
) >= 0x17)
184 nv17_zclear(ctx
, &buffers
);
186 nv10_zclear(ctx
, &buffers
);
189 nouveau_clear(ctx
, buffers
);
193 nv10_hwctx_init(GLcontext
*ctx
)
195 struct nouveau_channel
*chan
= context_chan(ctx
);
196 struct nouveau_grobj
*celsius
= context_eng3d(ctx
);
197 struct nouveau_hw_state
*hw
= &to_nouveau_context(ctx
)->hw
;
200 BEGIN_RING(chan
, celsius
, NV10TCL_DMA_NOTIFY
, 1);
201 OUT_RING(chan
, hw
->ntfy
->handle
);
203 BEGIN_RING(chan
, celsius
, NV10TCL_DMA_IN_MEMORY0
, 3);
204 OUT_RING(chan
, chan
->vram
->handle
);
205 OUT_RING(chan
, chan
->gart
->handle
);
206 OUT_RING(chan
, chan
->gart
->handle
);
207 BEGIN_RING(chan
, celsius
, NV10TCL_DMA_IN_MEMORY2
, 2);
208 OUT_RING(chan
, chan
->vram
->handle
);
209 OUT_RING(chan
, chan
->vram
->handle
);
211 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
214 BEGIN_RING(chan
, celsius
, NV10TCL_RT_HORIZ
, 2);
218 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1);
219 OUT_RING(chan
, 0x7ff << 16 | 0x800);
220 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_VERT(0), 1);
221 OUT_RING(chan
, 0x7ff << 16 | 0x800);
223 for (i
= 1; i
< 8; i
++) {
224 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_HORIZ(i
), 1);
226 BEGIN_RING(chan
, celsius
, NV10TCL_VIEWPORT_CLIP_VERT(i
), 1);
230 BEGIN_RING(chan
, celsius
, 0x290, 1);
231 OUT_RING(chan
, 0x10 << 16 | 1);
232 BEGIN_RING(chan
, celsius
, 0x3f4, 1);
235 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
238 if (context_chipset(ctx
) >= 0x17) {
239 BEGIN_RING(chan
, celsius
, NV17TCL_DMA_IN_MEMORY4
, 2);
240 OUT_RING(chan
, chan
->vram
->handle
);
241 OUT_RING(chan
, chan
->vram
->handle
);
243 BEGIN_RING(chan
, celsius
, 0xd84, 1);
246 BEGIN_RING(chan
, celsius
, NV17TCL_COLOR_MASK_ENABLE
, 1);
250 if (context_chipset(ctx
) >= 0x11) {
251 BEGIN_RING(chan
, celsius
, 0x120, 3);
256 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
260 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
264 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_ENABLE
, 1);
266 BEGIN_RING(chan
, celsius
, NV10TCL_ALPHA_FUNC_ENABLE
, 1);
268 BEGIN_RING(chan
, celsius
, NV10TCL_ALPHA_FUNC_FUNC
, 2);
269 OUT_RING(chan
, 0x207);
271 BEGIN_RING(chan
, celsius
, NV10TCL_TX_ENABLE(0), 2);
275 BEGIN_RING(chan
, celsius
, NV10TCL_BLEND_FUNC_ENABLE
, 1);
277 BEGIN_RING(chan
, celsius
, NV10TCL_DITHER_ENABLE
, 2);
280 BEGIN_RING(chan
, celsius
, NV10TCL_LINE_SMOOTH_ENABLE
, 1);
282 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_WEIGHT_ENABLE
, 2);
285 BEGIN_RING(chan
, celsius
, NV10TCL_BLEND_FUNC_SRC
, 4);
289 OUT_RING(chan
, 0x8006);
290 BEGIN_RING(chan
, celsius
, NV10TCL_STENCIL_MASK
, 8);
291 OUT_RING(chan
, 0xff);
292 OUT_RING(chan
, 0x207);
294 OUT_RING(chan
, 0xff);
295 OUT_RING(chan
, 0x1e00);
296 OUT_RING(chan
, 0x1e00);
297 OUT_RING(chan
, 0x1e00);
298 OUT_RING(chan
, 0x1d01);
299 BEGIN_RING(chan
, celsius
, NV10TCL_NORMALIZE_ENABLE
, 1);
301 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_ENABLE
, 2);
304 BEGIN_RING(chan
, celsius
, NV10TCL_LIGHT_MODEL
, 1);
306 BEGIN_RING(chan
, celsius
, NV10TCL_SEPARATE_SPECULAR_ENABLE
, 1);
308 BEGIN_RING(chan
, celsius
, NV10TCL_ENABLED_LIGHTS
, 1);
310 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_OFFSET_POINT_ENABLE
, 3);
314 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_FUNC
, 1);
315 OUT_RING(chan
, 0x201);
316 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_WRITE_ENABLE
, 1);
318 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_TEST_ENABLE
, 1);
320 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_OFFSET_FACTOR
, 2);
323 BEGIN_RING(chan
, celsius
, NV10TCL_POINT_SIZE
, 1);
325 BEGIN_RING(chan
, celsius
, NV10TCL_POINT_PARAMETERS_ENABLE
, 2);
328 BEGIN_RING(chan
, celsius
, NV10TCL_LINE_WIDTH
, 1);
330 BEGIN_RING(chan
, celsius
, NV10TCL_LINE_SMOOTH_ENABLE
, 1);
332 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_MODE_FRONT
, 2);
333 OUT_RING(chan
, 0x1b02);
334 OUT_RING(chan
, 0x1b02);
335 BEGIN_RING(chan
, celsius
, NV10TCL_CULL_FACE
, 2);
336 OUT_RING(chan
, 0x405);
337 OUT_RING(chan
, 0x901);
338 BEGIN_RING(chan
, celsius
, NV10TCL_POLYGON_SMOOTH_ENABLE
, 1);
340 BEGIN_RING(chan
, celsius
, NV10TCL_CULL_FACE_ENABLE
, 1);
342 BEGIN_RING(chan
, celsius
, NV10TCL_TX_GEN_MODE_S(0), 8);
343 for (i
= 0; i
< 8; i
++)
346 BEGIN_RING(chan
, celsius
, NV10TCL_TX_MATRIX_ENABLE(0), 2);
349 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_EQUATION_CONSTANT
, 3);
350 OUT_RING(chan
, 0x3fc00000); /* -1.50 */
351 OUT_RING(chan
, 0xbdb8aa0a); /* -0.09 */
352 OUT_RING(chan
, 0); /* 0.00 */
354 BEGIN_RING(chan
, celsius
, NV10TCL_NOP
, 1);
357 BEGIN_RING(chan
, celsius
, NV10TCL_FOG_MODE
, 2);
358 OUT_RING(chan
, 0x802);
360 /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when
361 * using texturing, except when using the texture matrix
363 BEGIN_RING(chan
, celsius
, NV10TCL_VIEW_MATRIX_ENABLE
, 1);
365 BEGIN_RING(chan
, celsius
, NV10TCL_COLOR_MASK
, 1);
366 OUT_RING(chan
, 0x01010101);
368 /* Set vertex component */
369 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_COL_4F_R
, 4);
370 OUT_RINGf(chan
, 1.0);
371 OUT_RINGf(chan
, 0.0);
372 OUT_RINGf(chan
, 0.0);
373 OUT_RINGf(chan
, 1.0);
374 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_COL2_3F_R
, 3);
378 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_NOR_3F_X
, 3);
381 OUT_RINGf(chan
, 1.0);
382 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_TX0_4F_S
, 4);
383 OUT_RINGf(chan
, 0.0);
384 OUT_RINGf(chan
, 0.0);
385 OUT_RINGf(chan
, 0.0);
386 OUT_RINGf(chan
, 1.0);
387 BEGIN_RING(chan
, celsius
, NV10TCL_VERTEX_TX1_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
, NV10TCL_VERTEX_FOG_1F
, 1);
393 OUT_RINGf(chan
, 0.0);
394 BEGIN_RING(chan
, celsius
, NV10TCL_EDGEFLAG_ENABLE
, 1);
397 BEGIN_RING(chan
, celsius
, NV10TCL_DEPTH_RANGE_NEAR
, 2);
398 OUT_RINGf(chan
, 0.0);
399 OUT_RINGf(chan
, 16777216.0);
405 nv10_context_destroy(GLcontext
*ctx
)
407 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
409 nv04_surface_takedown(ctx
);
410 nv10_render_destroy(ctx
);
412 nouveau_grobj_free(&nctx
->hw
.eng3d
);
414 nouveau_context_deinit(ctx
);
419 nv10_context_create(struct nouveau_screen
*screen
, const GLvisual
*visual
,
420 GLcontext
*share_ctx
)
422 struct nouveau_context
*nctx
;
424 unsigned celsius_class
;
427 nctx
= CALLOC_STRUCT(nouveau_context
);
433 if (!nouveau_context_init(ctx
, screen
, visual
, share_ctx
))
436 driInitExtensions(ctx
, nv10_extensions
, GL_FALSE
);
439 ctx
->Const
.MaxTextureLevels
= 12;
440 ctx
->Const
.MaxTextureCoordUnits
= NV10_TEXTURE_UNITS
;
441 ctx
->Const
.MaxTextureImageUnits
= NV10_TEXTURE_UNITS
;
442 ctx
->Const
.MaxTextureUnits
= NV10_TEXTURE_UNITS
;
443 ctx
->Const
.MaxTextureMaxAnisotropy
= 2;
444 ctx
->Const
.MaxTextureLodBias
= 15;
445 ctx
->Driver
.Clear
= nv10_clear
;
448 ret
= nv04_surface_init(ctx
);
453 if (context_chipset(ctx
) >= 0x17)
454 celsius_class
= NV17TCL
;
455 else if (context_chipset(ctx
) >= 0x11)
456 celsius_class
= NV11TCL
;
458 celsius_class
= NV10TCL
;
460 ret
= nouveau_grobj_alloc(context_chan(ctx
), 0xbeef0001, celsius_class
,
465 nv10_hwctx_init(ctx
);
466 nv10_render_init(ctx
);
471 nv10_context_destroy(ctx
);
475 const struct nouveau_driver nv10_driver
= {
476 .context_create
= nv10_context_create
,
477 .context_destroy
= nv10_context_destroy
,
478 .surface_copy
= nv04_surface_copy
,
479 .surface_fill
= nv04_surface_fill
,
480 .emit
= (nouveau_state_func
[]) {
481 nv10_emit_alpha_func
,
482 nv10_emit_blend_color
,
483 nv10_emit_blend_equation
,
484 nv10_emit_blend_func
,
485 nv10_emit_clip_plane
,
486 nv10_emit_clip_plane
,
487 nv10_emit_clip_plane
,
488 nv10_emit_clip_plane
,
489 nv10_emit_clip_plane
,
490 nv10_emit_clip_plane
,
491 nv10_emit_color_mask
,
492 nv10_emit_color_material
,
494 nv10_emit_front_face
,
498 nv10_emit_framebuffer
,
500 nv10_emit_light_enable
,
501 nv10_emit_light_model
,
502 nv10_emit_light_source
,
503 nv10_emit_light_source
,
504 nv10_emit_light_source
,
505 nv10_emit_light_source
,
506 nv10_emit_light_source
,
507 nv10_emit_light_source
,
508 nv10_emit_light_source
,
509 nv10_emit_light_source
,
510 nv10_emit_line_stipple
,
512 nv10_emit_logic_opcode
,
513 nv10_emit_material_ambient
,
514 nouveau_emit_nothing
,
515 nv10_emit_material_diffuse
,
516 nouveau_emit_nothing
,
517 nv10_emit_material_specular
,
518 nouveau_emit_nothing
,
519 nv10_emit_material_shininess
,
520 nouveau_emit_nothing
,
522 nv10_emit_point_mode
,
523 nv10_emit_point_parameter
,
524 nv10_emit_polygon_mode
,
525 nv10_emit_polygon_offset
,
526 nv10_emit_polygon_stipple
,
527 nv10_emit_projection
,
528 nv10_emit_render_mode
,
530 nv10_emit_shade_model
,
531 nv10_emit_stencil_func
,
532 nv10_emit_stencil_mask
,
533 nv10_emit_stencil_op
,
536 nouveau_emit_nothing
,
537 nouveau_emit_nothing
,
540 nouveau_emit_nothing
,
541 nouveau_emit_nothing
,
544 nouveau_emit_nothing
,
545 nouveau_emit_nothing
,
548 nouveau_emit_nothing
,
549 nouveau_emit_nothing
,
553 .num_emit
= NUM_NV10_STATE
,