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 "nv04_3d.xml.h"
32 #include "nv04_driver.h"
35 texunit_needs_combiners(struct gl_texture_unit
*u
)
37 struct gl_texture_object
*t
= u
->_Current
;
38 struct gl_texture_image
*ti
= t
->Image
[0][t
->BaseLevel
];
40 return ti
->TexFormat
== MESA_FORMAT_A8
||
41 ti
->TexFormat
== MESA_FORMAT_L8
||
42 u
->EnvMode
== GL_COMBINE
||
43 u
->EnvMode
== GL_COMBINE4_NV
||
44 u
->EnvMode
== GL_BLEND
||
48 struct nouveau_object
*
49 nv04_context_engine(struct gl_context
*ctx
)
51 struct nv04_context
*nctx
= to_nv04_context(ctx
);
52 struct nouveau_hw_state
*hw
= &to_nouveau_context(ctx
)->hw
;
53 struct nouveau_pushbuf
*push
= context_push(ctx
);
54 struct nouveau_object
*fahrenheit
;
56 if ((ctx
->Texture
.Unit
[0]._ReallyEnabled
&&
57 texunit_needs_combiners(&ctx
->Texture
.Unit
[0])) ||
58 ctx
->Texture
.Unit
[1]._ReallyEnabled
||
59 ctx
->Stencil
.Enabled
||
60 !(ctx
->Color
.ColorMask
[0][RCOMP
] &&
61 ctx
->Color
.ColorMask
[0][GCOMP
] &&
62 ctx
->Color
.ColorMask
[0][BCOMP
] &&
63 ctx
->Color
.ColorMask
[0][ACOMP
]))
64 fahrenheit
= hw
->eng3dm
;
66 fahrenheit
= hw
->eng3d
;
68 if (fahrenheit
!= nctx
->eng3d
) {
69 nctx
->eng3d
= fahrenheit
;
71 BEGIN_NV04(push
, NV01_SUBC(3D
, OBJECT
), 1);
72 PUSH_DATA (push
, fahrenheit
->handle
);
74 if (nv04_mtex_engine(fahrenheit
)) {
75 context_dirty_i(ctx
, TEX_ENV
, 0);
76 context_dirty_i(ctx
, TEX_ENV
, 1);
77 context_dirty_i(ctx
, TEX_OBJ
, 0);
78 context_dirty_i(ctx
, TEX_OBJ
, 1);
79 context_dirty(ctx
, CONTROL
);
80 context_dirty(ctx
, BLEND
);
82 nouveau_bufctx_reset(to_nouveau_context(ctx
)->hw
.
83 bufctx
, BUFCTX_TEX(1));
84 context_dirty_i(ctx
, TEX_ENV
, 0);
85 context_dirty_i(ctx
, TEX_OBJ
, 0);
86 context_dirty(ctx
, CONTROL
);
87 context_dirty(ctx
, BLEND
);
95 nv04_hwctx_init(struct gl_context
*ctx
)
97 struct nouveau_hw_state
*hw
= &to_nouveau_context(ctx
)->hw
;
98 struct nouveau_pushbuf
*push
= context_push(ctx
);
99 struct nv04_fifo
*fifo
= hw
->chan
->data
;
101 BEGIN_NV04(push
, NV01_SUBC(SURF
, OBJECT
), 1);
102 PUSH_DATA (push
, hw
->surf3d
->handle
);
103 BEGIN_NV04(push
, NV04_SF3D(DMA_NOTIFY
), 3);
104 PUSH_DATA (push
, hw
->ntfy
->handle
);
105 PUSH_DATA (push
, fifo
->vram
);
106 PUSH_DATA (push
, fifo
->vram
);
108 BEGIN_NV04(push
, NV01_SUBC(3D
, OBJECT
), 1);
109 PUSH_DATA (push
, hw
->eng3d
->handle
);
110 BEGIN_NV04(push
, NV04_TTRI(DMA_NOTIFY
), 4);
111 PUSH_DATA (push
, hw
->ntfy
->handle
);
112 PUSH_DATA (push
, fifo
->vram
);
113 PUSH_DATA (push
, fifo
->gart
);
114 PUSH_DATA (push
, hw
->surf3d
->handle
);
116 BEGIN_NV04(push
, NV01_SUBC(3D
, OBJECT
), 1);
117 PUSH_DATA (push
, hw
->eng3dm
->handle
);
118 BEGIN_NV04(push
, NV04_MTRI(DMA_NOTIFY
), 4);
119 PUSH_DATA (push
, hw
->ntfy
->handle
);
120 PUSH_DATA (push
, fifo
->vram
);
121 PUSH_DATA (push
, fifo
->gart
);
122 PUSH_DATA (push
, hw
->surf3d
->handle
);
128 init_dummy_texture(struct gl_context
*ctx
)
130 struct nouveau_surface
*s
= &to_nv04_context(ctx
)->dummy_texture
;
132 nouveau_surface_alloc(ctx
, s
, SWIZZLED
,
133 NOUVEAU_BO_MAP
| NOUVEAU_BO_VRAM
,
134 MESA_FORMAT_ARGB8888
, 1, 1);
136 nouveau_bo_map(s
->bo
, NOUVEAU_BO_WR
, context_client(ctx
));
137 *(uint32_t *)s
->bo
->map
= 0xffffffff;
141 nv04_context_destroy(struct gl_context
*ctx
)
143 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
145 nv04_surface_takedown(ctx
);
146 nv04_render_destroy(ctx
);
147 nouveau_surface_ref(NULL
, &to_nv04_context(ctx
)->dummy_texture
);
149 nouveau_object_del(&nctx
->hw
.eng3d
);
150 nouveau_object_del(&nctx
->hw
.eng3dm
);
151 nouveau_object_del(&nctx
->hw
.surf3d
);
153 nouveau_context_deinit(ctx
);
157 static struct gl_context
*
158 nv04_context_create(struct nouveau_screen
*screen
, const struct gl_config
*visual
,
159 struct gl_context
*share_ctx
)
161 struct nv04_context
*nctx
;
162 struct nouveau_hw_state
*hw
;
163 struct gl_context
*ctx
;
166 nctx
= CALLOC_STRUCT(nv04_context
);
170 ctx
= &nctx
->base
.base
;
173 if (!nouveau_context_init(ctx
, screen
, visual
, share_ctx
))
177 ctx
->Const
.MaxTextureLevels
= 11;
178 ctx
->Const
.MaxTextureCoordUnits
= NV04_TEXTURE_UNITS
;
179 ctx
->Const
.MaxTextureImageUnits
= NV04_TEXTURE_UNITS
;
180 ctx
->Const
.MaxTextureUnits
= NV04_TEXTURE_UNITS
;
181 ctx
->Const
.MaxTextureMaxAnisotropy
= 2;
182 ctx
->Const
.MaxTextureLodBias
= 15;
185 ret
= nv04_surface_init(ctx
);
190 ret
= nouveau_object_new(context_chan(ctx
), 0xbeef0001,
191 NV04_TEXTURED_TRIANGLE_CLASS
, NULL
, 0,
196 ret
= nouveau_object_new(context_chan(ctx
), 0xbeef0002,
197 NV04_MULTITEX_TRIANGLE_CLASS
, NULL
, 0,
202 ret
= nouveau_object_new(context_chan(ctx
), 0xbeef0003,
203 NV04_SURFACE_3D_CLASS
, NULL
, 0,
208 init_dummy_texture(ctx
);
209 nv04_hwctx_init(ctx
);
210 nv04_render_init(ctx
);
215 nv04_context_destroy(ctx
);
219 const struct nouveau_driver nv04_driver
= {
220 .context_create
= nv04_context_create
,
221 .context_destroy
= nv04_context_destroy
,
222 .surface_copy
= nv04_surface_copy
,
223 .surface_fill
= nv04_surface_fill
,
224 .emit
= (nouveau_state_func
[]) {
226 nouveau_emit_nothing
,
229 nouveau_emit_nothing
,
230 nouveau_emit_nothing
,
231 nouveau_emit_nothing
,
232 nouveau_emit_nothing
,
233 nouveau_emit_nothing
,
234 nouveau_emit_nothing
,
236 nouveau_emit_nothing
,
238 nouveau_emit_nothing
,
241 nouveau_emit_nothing
,
242 nv04_emit_framebuffer
,
244 nouveau_emit_nothing
,
245 nouveau_emit_nothing
,
246 nouveau_emit_nothing
,
247 nouveau_emit_nothing
,
248 nouveau_emit_nothing
,
249 nouveau_emit_nothing
,
250 nouveau_emit_nothing
,
251 nouveau_emit_nothing
,
252 nouveau_emit_nothing
,
253 nouveau_emit_nothing
,
254 nouveau_emit_nothing
,
255 nouveau_emit_nothing
,
256 nouveau_emit_nothing
,
257 nouveau_emit_nothing
,
258 nouveau_emit_nothing
,
259 nouveau_emit_nothing
,
260 nouveau_emit_nothing
,
261 nouveau_emit_nothing
,
262 nouveau_emit_nothing
,
263 nouveau_emit_nothing
,
264 nouveau_emit_nothing
,
265 nouveau_emit_nothing
,
266 nouveau_emit_nothing
,
267 nouveau_emit_nothing
,
268 nouveau_emit_nothing
,
269 nouveau_emit_nothing
,
270 nouveau_emit_nothing
,
271 nouveau_emit_nothing
,
272 nouveau_emit_nothing
,
280 nouveau_emit_nothing
,
281 nouveau_emit_nothing
,
282 nouveau_emit_nothing
,
283 nouveau_emit_nothing
,
284 nouveau_emit_nothing
,
285 nouveau_emit_nothing
,
286 nouveau_emit_nothing
,
287 nouveau_emit_nothing
,
288 nouveau_emit_nothing
,
289 nouveau_emit_nothing
,
292 nouveau_emit_nothing
,
293 nouveau_emit_nothing
,
294 nouveau_emit_nothing
,
298 .num_emit
= NUM_NV04_STATE
,