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.
28 #include "main/state.h"
29 #include "nouveau_driver.h"
30 #include "nouveau_context.h"
31 #include "nouveau_fbo.h"
32 #include "nouveau_util.h"
33 #include "nv_object.xml.h"
34 #include "nv10_3d.xml.h"
35 #include "nv04_driver.h"
36 #include "nv10_driver.h"
39 use_fast_zclear(struct gl_context
*ctx
, GLbitfield buffers
)
41 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
42 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
44 if (buffers
& BUFFER_BIT_STENCIL
) {
46 * The stencil test is bypassed when fast Z clears are
49 nctx
->hierz
.clear_blocked
= GL_TRUE
;
50 context_dirty(ctx
, ZCLEAR
);
54 return !nctx
->hierz
.clear_blocked
&&
55 fb
->_Xmax
== fb
->Width
&& fb
->_Xmin
== 0 &&
56 fb
->_Ymax
== fb
->Height
&& fb
->_Ymin
== 0;
60 nv10_use_viewport_zclear(struct gl_context
*ctx
)
62 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
63 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
64 struct gl_renderbuffer
*depthRb
= fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
66 return context_eng3d(ctx
)->oclass
< NV17_3D_CLASS
&&
67 !nctx
->hierz
.clear_blocked
&& depthRb
&&
68 (_mesa_get_format_bits(depthRb
->Format
,
69 GL_DEPTH_BITS
) >= 24);
73 nv10_transform_depth(struct gl_context
*ctx
, float z
)
75 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
77 if (nv10_use_viewport_zclear(ctx
))
78 return 2097152.0 * (z
+ (nctx
->hierz
.clear_seq
& 7));
80 return ctx
->DrawBuffer
->_DepthMaxF
* z
;
84 nv10_zclear(struct gl_context
*ctx
, GLbitfield
*buffers
)
87 * Pre-nv17 cards don't have native support for fast Z clears,
88 * but in some cases we can still "clear" the Z buffer without
89 * actually blitting to it if we're willing to sacrifice a few
90 * bits of depth precision.
92 * Each time a clear is requested we modify the viewport
93 * transform in such a way that the old contents of the depth
94 * buffer are clamped to the requested clear value when
95 * they're read by the GPU.
97 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
98 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
99 struct nouveau_framebuffer
*nfb
= to_nouveau_framebuffer(fb
);
100 struct nouveau_surface
*s
= &to_nouveau_renderbuffer(
101 fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
)->surface
;
103 if (nv10_use_viewport_zclear(ctx
)) {
105 float z
= ctx
->Depth
.Clear
;
106 uint32_t value
= pack_zs_f(s
->format
, z
, 0);
108 get_scissors(fb
, &x
, &y
, &w
, &h
);
109 *buffers
&= ~BUFFER_BIT_DEPTH
;
111 if (use_fast_zclear(ctx
, *buffers
)) {
112 if (nfb
->hierz
.clear_value
!= value
) {
113 /* Don't fast clear if we're changing
114 * the depth value. */
115 nfb
->hierz
.clear_value
= value
;
117 } else if (z
== 0.0) {
118 nctx
->hierz
.clear_seq
++;
119 context_dirty(ctx
, ZCLEAR
);
121 if ((nctx
->hierz
.clear_seq
& 7) != 0 &&
122 nctx
->hierz
.clear_seq
!= 1)
123 /* We didn't wrap around -- no need to
124 * clear the depth buffer for real. */
127 } else if (z
== 1.0) {
128 nctx
->hierz
.clear_seq
--;
129 context_dirty(ctx
, ZCLEAR
);
131 if ((nctx
->hierz
.clear_seq
& 7) != 7)
137 value
= pack_zs_f(s
->format
,
138 (z
+ (nctx
->hierz
.clear_seq
& 7)) / 8, 0);
139 context_drv(ctx
)->surface_fill(ctx
, s
, ~0, value
, x
, y
, w
, h
);
144 nv17_zclear(struct gl_context
*ctx
, GLbitfield
*buffers
)
146 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
147 struct nouveau_pushbuf
*push
= context_push(ctx
);
148 struct nouveau_framebuffer
*nfb
= to_nouveau_framebuffer(
150 struct nouveau_surface
*s
= &to_nouveau_renderbuffer(
151 nfb
->base
.Attachment
[BUFFER_DEPTH
].Renderbuffer
)->surface
;
153 /* Clear the hierarchical depth buffer */
154 BEGIN_NV04(push
, NV17_3D(HIERZ_FILL_VALUE
), 1);
155 PUSH_DATA (push
, pack_zs_f(s
->format
, ctx
->Depth
.Clear
, 0));
156 BEGIN_NV04(push
, NV17_3D(HIERZ_BUFFER_CLEAR
), 1);
159 /* Mark the depth buffer as cleared */
160 if (use_fast_zclear(ctx
, *buffers
)) {
161 if (nctx
->hierz
.clear_seq
)
162 *buffers
&= ~BUFFER_BIT_DEPTH
;
164 nfb
->hierz
.clear_value
=
165 pack_zs_f(s
->format
, ctx
->Depth
.Clear
, 0);
166 nctx
->hierz
.clear_seq
++;
168 context_dirty(ctx
, ZCLEAR
);
173 nv10_clear(struct gl_context
*ctx
, GLbitfield buffers
)
175 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
176 struct nouveau_pushbuf
*push
= context_push(ctx
);
178 nouveau_validate_framebuffer(ctx
);
180 nouveau_pushbuf_bufctx(push
, nctx
->hw
.bufctx
);
181 if (nouveau_pushbuf_validate(push
)) {
182 nouveau_pushbuf_bufctx(push
, NULL
);
186 if ((buffers
& BUFFER_BIT_DEPTH
) && ctx
->Depth
.Mask
) {
187 if (context_eng3d(ctx
)->oclass
>= NV17_3D_CLASS
)
188 nv17_zclear(ctx
, &buffers
);
190 nv10_zclear(ctx
, &buffers
);
192 /* Emit the zclear state if it's dirty */
193 _mesa_update_state(ctx
);
196 nouveau_pushbuf_bufctx(push
, NULL
);
197 nouveau_clear(ctx
, buffers
);
201 nv10_hwctx_init(struct gl_context
*ctx
)
203 struct nouveau_pushbuf
*push
= context_push(ctx
);
204 struct nouveau_hw_state
*hw
= &to_nouveau_context(ctx
)->hw
;
205 struct nv04_fifo
*fifo
= hw
->chan
->data
;
208 BEGIN_NV04(push
, NV01_SUBC(3D
, OBJECT
), 1);
209 PUSH_DATA (push
, hw
->eng3d
->handle
);
210 BEGIN_NV04(push
, NV10_3D(DMA_NOTIFY
), 1);
211 PUSH_DATA (push
, hw
->ntfy
->handle
);
213 BEGIN_NV04(push
, NV10_3D(DMA_TEXTURE0
), 3);
214 PUSH_DATA (push
, fifo
->vram
);
215 PUSH_DATA (push
, fifo
->gart
);
216 PUSH_DATA (push
, fifo
->gart
);
217 BEGIN_NV04(push
, NV10_3D(DMA_COLOR
), 2);
218 PUSH_DATA (push
, fifo
->vram
);
219 PUSH_DATA (push
, fifo
->vram
);
221 BEGIN_NV04(push
, NV04_GRAPH(3D
, NOP
), 1);
224 BEGIN_NV04(push
, NV10_3D(RT_HORIZ
), 2);
228 BEGIN_NV04(push
, NV10_3D(VIEWPORT_CLIP_HORIZ(0)), 1);
229 PUSH_DATA (push
, 0x7ff << 16 | 0x800);
230 BEGIN_NV04(push
, NV10_3D(VIEWPORT_CLIP_VERT(0)), 1);
231 PUSH_DATA (push
, 0x7ff << 16 | 0x800);
233 for (i
= 1; i
< 8; i
++) {
234 BEGIN_NV04(push
, NV10_3D(VIEWPORT_CLIP_HORIZ(i
)), 1);
236 BEGIN_NV04(push
, NV10_3D(VIEWPORT_CLIP_VERT(i
)), 1);
240 BEGIN_NV04(push
, SUBC_3D(0x290), 1);
241 PUSH_DATA (push
, 0x10 << 16 | 1);
242 BEGIN_NV04(push
, SUBC_3D(0x3f4), 1);
245 BEGIN_NV04(push
, NV04_GRAPH(3D
, NOP
), 1);
248 if (context_eng3d(ctx
)->oclass
>= NV17_3D_CLASS
) {
249 BEGIN_NV04(push
, NV17_3D(UNK01AC
), 2);
250 PUSH_DATA (push
, fifo
->vram
);
251 PUSH_DATA (push
, fifo
->vram
);
253 BEGIN_NV04(push
, SUBC_3D(0xd84), 1);
254 PUSH_DATA (push
, 0x3);
256 BEGIN_NV04(push
, NV17_3D(COLOR_MASK_ENABLE
), 1);
260 if (context_eng3d(ctx
)->oclass
>= NV15_3D_CLASS
) {
261 BEGIN_NV04(push
, SUBC_3D(0x120), 3);
266 BEGIN_NV04(push
, NV04_GRAPH(3D
, NOP
), 1);
270 BEGIN_NV04(push
, NV04_GRAPH(3D
, NOP
), 1);
274 BEGIN_NV04(push
, NV10_3D(FOG_ENABLE
), 1);
276 BEGIN_NV04(push
, NV10_3D(ALPHA_FUNC_ENABLE
), 1);
278 BEGIN_NV04(push
, NV10_3D(ALPHA_FUNC_FUNC
), 2);
279 PUSH_DATA (push
, 0x207);
281 BEGIN_NV04(push
, NV10_3D(TEX_ENABLE(0)), 2);
285 BEGIN_NV04(push
, NV10_3D(BLEND_FUNC_ENABLE
), 1);
287 BEGIN_NV04(push
, NV10_3D(DITHER_ENABLE
), 2);
290 BEGIN_NV04(push
, NV10_3D(LINE_SMOOTH_ENABLE
), 1);
292 BEGIN_NV04(push
, NV10_3D(VERTEX_WEIGHT_ENABLE
), 2);
295 BEGIN_NV04(push
, NV10_3D(BLEND_FUNC_SRC
), 4);
299 PUSH_DATA (push
, 0x8006);
300 BEGIN_NV04(push
, NV10_3D(STENCIL_MASK
), 8);
301 PUSH_DATA (push
, 0xff);
302 PUSH_DATA (push
, 0x207);
304 PUSH_DATA (push
, 0xff);
305 PUSH_DATA (push
, 0x1e00);
306 PUSH_DATA (push
, 0x1e00);
307 PUSH_DATA (push
, 0x1e00);
308 PUSH_DATA (push
, 0x1d01);
309 BEGIN_NV04(push
, NV10_3D(NORMALIZE_ENABLE
), 1);
311 BEGIN_NV04(push
, NV10_3D(FOG_ENABLE
), 2);
314 BEGIN_NV04(push
, NV10_3D(LIGHT_MODEL
), 1);
316 BEGIN_NV04(push
, NV10_3D(SEPARATE_SPECULAR_ENABLE
), 1);
318 BEGIN_NV04(push
, NV10_3D(ENABLED_LIGHTS
), 1);
320 BEGIN_NV04(push
, NV10_3D(POLYGON_OFFSET_POINT_ENABLE
), 3);
324 BEGIN_NV04(push
, NV10_3D(DEPTH_FUNC
), 1);
325 PUSH_DATA (push
, 0x201);
326 BEGIN_NV04(push
, NV10_3D(DEPTH_WRITE_ENABLE
), 1);
328 BEGIN_NV04(push
, NV10_3D(DEPTH_TEST_ENABLE
), 1);
330 BEGIN_NV04(push
, NV10_3D(POLYGON_OFFSET_FACTOR
), 2);
333 BEGIN_NV04(push
, NV10_3D(POINT_SIZE
), 1);
335 BEGIN_NV04(push
, NV10_3D(POINT_PARAMETERS_ENABLE
), 2);
338 BEGIN_NV04(push
, NV10_3D(LINE_WIDTH
), 1);
340 BEGIN_NV04(push
, NV10_3D(LINE_SMOOTH_ENABLE
), 1);
342 BEGIN_NV04(push
, NV10_3D(POLYGON_MODE_FRONT
), 2);
343 PUSH_DATA (push
, 0x1b02);
344 PUSH_DATA (push
, 0x1b02);
345 BEGIN_NV04(push
, NV10_3D(CULL_FACE
), 2);
346 PUSH_DATA (push
, 0x405);
347 PUSH_DATA (push
, 0x901);
348 BEGIN_NV04(push
, NV10_3D(POLYGON_SMOOTH_ENABLE
), 1);
350 BEGIN_NV04(push
, NV10_3D(CULL_FACE_ENABLE
), 1);
352 BEGIN_NV04(push
, NV10_3D(TEX_GEN_MODE(0, 0)), 8);
353 for (i
= 0; i
< 8; i
++)
356 BEGIN_NV04(push
, NV10_3D(TEX_MATRIX_ENABLE(0)), 2);
359 BEGIN_NV04(push
, NV10_3D(FOG_COEFF(0)), 3);
360 PUSH_DATA (push
, 0x3fc00000); /* -1.50 */
361 PUSH_DATA (push
, 0xbdb8aa0a); /* -0.09 */
362 PUSH_DATA (push
, 0); /* 0.00 */
364 BEGIN_NV04(push
, NV04_GRAPH(3D
, NOP
), 1);
367 BEGIN_NV04(push
, NV10_3D(FOG_MODE
), 2);
368 PUSH_DATA (push
, 0x802);
370 /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when
371 * using texturing, except when using the texture matrix
373 BEGIN_NV04(push
, NV10_3D(VIEW_MATRIX_ENABLE
), 1);
375 BEGIN_NV04(push
, NV10_3D(COLOR_MASK
), 1);
376 PUSH_DATA (push
, 0x01010101);
378 /* Set vertex component */
379 BEGIN_NV04(push
, NV10_3D(VERTEX_COL_4F_R
), 4);
380 PUSH_DATAf(push
, 1.0);
381 PUSH_DATAf(push
, 0.0);
382 PUSH_DATAf(push
, 0.0);
383 PUSH_DATAf(push
, 1.0);
384 BEGIN_NV04(push
, NV10_3D(VERTEX_COL2_3F_R
), 3);
388 BEGIN_NV04(push
, NV10_3D(VERTEX_NOR_3F_X
), 3);
391 PUSH_DATAf(push
, 1.0);
392 BEGIN_NV04(push
, NV10_3D(VERTEX_TX0_4F_S
), 4);
393 PUSH_DATAf(push
, 0.0);
394 PUSH_DATAf(push
, 0.0);
395 PUSH_DATAf(push
, 0.0);
396 PUSH_DATAf(push
, 1.0);
397 BEGIN_NV04(push
, NV10_3D(VERTEX_TX1_4F_S
), 4);
398 PUSH_DATAf(push
, 0.0);
399 PUSH_DATAf(push
, 0.0);
400 PUSH_DATAf(push
, 0.0);
401 PUSH_DATAf(push
, 1.0);
402 BEGIN_NV04(push
, NV10_3D(VERTEX_FOG_1F
), 1);
403 PUSH_DATAf(push
, 0.0);
404 BEGIN_NV04(push
, NV10_3D(EDGEFLAG_ENABLE
), 1);
407 BEGIN_NV04(push
, NV10_3D(DEPTH_RANGE_NEAR
), 2);
408 PUSH_DATAf(push
, 0.0);
409 PUSH_DATAf(push
, 16777216.0);
415 nv10_context_destroy(struct gl_context
*ctx
)
417 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
419 nv04_surface_takedown(ctx
);
420 nv10_swtnl_destroy(ctx
);
421 nv10_vbo_destroy(ctx
);
423 nouveau_object_del(&nctx
->hw
.eng3d
);
425 nouveau_context_deinit(ctx
);
429 static struct gl_context
*
430 nv10_context_create(struct nouveau_screen
*screen
, gl_api api
,
431 const struct gl_config
*visual
,
432 struct gl_context
*share_ctx
)
434 struct nouveau_context
*nctx
;
435 struct gl_context
*ctx
;
436 unsigned celsius_class
;
439 nctx
= CALLOC_STRUCT(nouveau_context
);
445 if (!nouveau_context_init(ctx
, api
, screen
, visual
, share_ctx
))
448 ctx
->Extensions
.ARB_texture_env_crossbar
= true;
449 ctx
->Extensions
.ARB_texture_env_combine
= true;
450 ctx
->Extensions
.ARB_texture_env_dot3
= true;
451 ctx
->Extensions
.EXT_texture_env_dot3
= true;
452 ctx
->Extensions
.NV_fog_distance
= true;
453 ctx
->Extensions
.NV_texture_rectangle
= true;
454 if (ctx
->Mesa_DXTn
) {
455 ctx
->Extensions
.EXT_texture_compression_s3tc
= true;
456 ctx
->Extensions
.ANGLE_texture_compression_dxt
= true;
460 ctx
->Const
.MaxTextureLevels
= 12;
461 ctx
->Const
.MaxTextureCoordUnits
= NV10_TEXTURE_UNITS
;
462 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
= NV10_TEXTURE_UNITS
;
463 ctx
->Const
.MaxTextureUnits
= NV10_TEXTURE_UNITS
;
464 ctx
->Const
.MaxTextureMaxAnisotropy
= 2;
465 ctx
->Const
.MaxTextureLodBias
= 15;
466 ctx
->Driver
.Clear
= nv10_clear
;
469 ret
= nv04_surface_init(ctx
);
474 if (context_chipset(ctx
) >= 0x17 && context_chipset(ctx
) != 0x1a)
475 celsius_class
= NV17_3D_CLASS
;
476 else if (context_chipset(ctx
) >= 0x11)
477 celsius_class
= NV15_3D_CLASS
;
479 celsius_class
= NV10_3D_CLASS
;
481 ret
= nouveau_object_new(context_chan(ctx
), 0xbeef0001, celsius_class
,
482 NULL
, 0, &nctx
->hw
.eng3d
);
486 nv10_hwctx_init(ctx
);
488 nv10_swtnl_init(ctx
);
493 nv10_context_destroy(ctx
);
497 const struct nouveau_driver nv10_driver
= {
498 .context_create
= nv10_context_create
,
499 .context_destroy
= nv10_context_destroy
,
500 .surface_copy
= nv04_surface_copy
,
501 .surface_fill
= nv04_surface_fill
,
502 .emit
= (nouveau_state_func
[]) {
503 nv10_emit_alpha_func
,
504 nv10_emit_blend_color
,
505 nv10_emit_blend_equation
,
506 nv10_emit_blend_func
,
507 nv10_emit_clip_plane
,
508 nv10_emit_clip_plane
,
509 nv10_emit_clip_plane
,
510 nv10_emit_clip_plane
,
511 nv10_emit_clip_plane
,
512 nv10_emit_clip_plane
,
513 nv10_emit_color_mask
,
514 nv10_emit_color_material
,
516 nv10_emit_front_face
,
520 nv10_emit_framebuffer
,
522 nv10_emit_light_enable
,
523 nv10_emit_light_model
,
524 nv10_emit_light_source
,
525 nv10_emit_light_source
,
526 nv10_emit_light_source
,
527 nv10_emit_light_source
,
528 nv10_emit_light_source
,
529 nv10_emit_light_source
,
530 nv10_emit_light_source
,
531 nv10_emit_light_source
,
532 nv10_emit_line_stipple
,
534 nv10_emit_logic_opcode
,
535 nv10_emit_material_ambient
,
536 nouveau_emit_nothing
,
537 nv10_emit_material_diffuse
,
538 nouveau_emit_nothing
,
539 nv10_emit_material_specular
,
540 nouveau_emit_nothing
,
541 nv10_emit_material_shininess
,
542 nouveau_emit_nothing
,
544 nv10_emit_point_mode
,
545 nv10_emit_point_parameter
,
546 nv10_emit_polygon_mode
,
547 nv10_emit_polygon_offset
,
548 nv10_emit_polygon_stipple
,
549 nv10_emit_projection
,
550 nv10_emit_render_mode
,
552 nv10_emit_shade_model
,
553 nv10_emit_stencil_func
,
554 nv10_emit_stencil_mask
,
555 nv10_emit_stencil_op
,
558 nouveau_emit_nothing
,
559 nouveau_emit_nothing
,
562 nouveau_emit_nothing
,
563 nouveau_emit_nothing
,
566 nouveau_emit_nothing
,
567 nouveau_emit_nothing
,
570 nouveau_emit_nothing
,
571 nouveau_emit_nothing
,
575 .num_emit
= NUM_NV10_STATE
,