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"
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_grobj
*
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_grobj
*fahrenheit
;
55 if ((ctx
->Texture
.Unit
[0]._ReallyEnabled
&&
56 texunit_needs_combiners(&ctx
->Texture
.Unit
[0])) ||
57 ctx
->Texture
.Unit
[1]._ReallyEnabled
||
58 ctx
->Stencil
.Enabled
||
59 !(ctx
->Color
.ColorMask
[0][RCOMP
] &&
60 ctx
->Color
.ColorMask
[0][GCOMP
] &&
61 ctx
->Color
.ColorMask
[0][BCOMP
] &&
62 ctx
->Color
.ColorMask
[0][ACOMP
]))
63 fahrenheit
= hw
->eng3dm
;
65 fahrenheit
= hw
->eng3d
;
67 if (fahrenheit
!= nctx
->eng3d
) {
68 nctx
->eng3d
= fahrenheit
;
70 if (nv04_mtex_engine(fahrenheit
)) {
71 context_dirty_i(ctx
, TEX_ENV
, 0);
72 context_dirty_i(ctx
, TEX_ENV
, 1);
73 context_dirty_i(ctx
, TEX_OBJ
, 0);
74 context_dirty_i(ctx
, TEX_OBJ
, 1);
75 context_dirty(ctx
, CONTROL
);
76 context_dirty(ctx
, BLEND
);
78 context_bctx_i(ctx
, TEXTURE
, 1);
79 context_dirty_i(ctx
, TEX_ENV
, 0);
80 context_dirty_i(ctx
, TEX_OBJ
, 0);
81 context_dirty(ctx
, CONTROL
);
82 context_dirty(ctx
, BLEND
);
90 nv04_channel_flush_notify(struct nouveau_channel
*chan
)
92 struct nouveau_context
*nctx
= chan
->user_private
;
93 struct gl_context
*ctx
= &nctx
->base
;
95 if (nctx
->fallback
< SWRAST
) {
96 nouveau_bo_state_emit(ctx
);
98 /* Reemit the engine state. */
99 context_emit(ctx
, TEX_OBJ0
);
100 context_emit(ctx
, TEX_OBJ1
);
101 context_emit(ctx
, TEX_ENV0
);
102 context_emit(ctx
, TEX_ENV1
);
103 context_emit(ctx
, CONTROL
);
104 context_emit(ctx
, BLEND
);
109 nv04_hwctx_init(struct gl_context
*ctx
)
111 struct nouveau_channel
*chan
= context_chan(ctx
);
112 struct nouveau_hw_state
*hw
= &to_nouveau_context(ctx
)->hw
;
113 struct nouveau_grobj
*surf3d
= hw
->surf3d
;
114 struct nouveau_grobj
*eng3d
= hw
->eng3d
;
115 struct nouveau_grobj
*eng3dm
= hw
->eng3dm
;
117 BIND_RING(chan
, surf3d
, 7);
118 BEGIN_RING(chan
, surf3d
, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY
, 3);
119 OUT_RING(chan
, hw
->ntfy
->handle
);
120 OUT_RING(chan
, chan
->vram
->handle
);
121 OUT_RING(chan
, chan
->vram
->handle
);
123 BEGIN_RING(chan
, eng3d
, NV04_TEXTURED_TRIANGLE_DMA_NOTIFY
, 4);
124 OUT_RING(chan
, hw
->ntfy
->handle
);
125 OUT_RING(chan
, chan
->vram
->handle
);
126 OUT_RING(chan
, chan
->gart
->handle
);
127 OUT_RING(chan
, surf3d
->handle
);
129 BEGIN_RING(chan
, eng3dm
, NV04_MULTITEX_TRIANGLE_DMA_NOTIFY
, 4);
130 OUT_RING(chan
, hw
->ntfy
->handle
);
131 OUT_RING(chan
, chan
->vram
->handle
);
132 OUT_RING(chan
, chan
->gart
->handle
);
133 OUT_RING(chan
, surf3d
->handle
);
139 init_dummy_texture(struct gl_context
*ctx
)
141 struct nouveau_surface
*s
= &to_nv04_context(ctx
)->dummy_texture
;
143 nouveau_surface_alloc(ctx
, s
, SWIZZLED
,
144 NOUVEAU_BO_MAP
| NOUVEAU_BO_VRAM
,
145 MESA_FORMAT_ARGB8888
, 1, 1);
147 nouveau_bo_map(s
->bo
, NOUVEAU_BO_WR
);
148 *(uint32_t *)s
->bo
->map
= 0xffffffff;
149 nouveau_bo_unmap(s
->bo
);
153 nv04_context_destroy(struct gl_context
*ctx
)
155 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
157 nv04_surface_takedown(ctx
);
158 nv04_render_destroy(ctx
);
159 nouveau_surface_ref(NULL
, &to_nv04_context(ctx
)->dummy_texture
);
161 nouveau_grobj_free(&nctx
->hw
.eng3d
);
162 nouveau_grobj_free(&nctx
->hw
.eng3dm
);
163 nouveau_grobj_free(&nctx
->hw
.surf3d
);
165 nouveau_context_deinit(ctx
);
169 static struct gl_context
*
170 nv04_context_create(struct nouveau_screen
*screen
, const struct gl_config
*visual
,
171 struct gl_context
*share_ctx
)
173 struct nv04_context
*nctx
;
174 struct nouveau_hw_state
*hw
;
175 struct gl_context
*ctx
;
178 nctx
= CALLOC_STRUCT(nv04_context
);
182 ctx
= &nctx
->base
.base
;
185 if (!nouveau_context_init(ctx
, screen
, visual
, share_ctx
))
188 hw
->chan
->flush_notify
= nv04_channel_flush_notify
;
191 ctx
->Const
.MaxTextureLevels
= 11;
192 ctx
->Const
.MaxTextureCoordUnits
= NV04_TEXTURE_UNITS
;
193 ctx
->Const
.MaxTextureImageUnits
= NV04_TEXTURE_UNITS
;
194 ctx
->Const
.MaxTextureUnits
= NV04_TEXTURE_UNITS
;
195 ctx
->Const
.MaxTextureMaxAnisotropy
= 2;
196 ctx
->Const
.MaxTextureLodBias
= 15;
199 ret
= nv04_surface_init(ctx
);
204 ret
= nouveau_grobj_alloc(context_chan(ctx
), 0xbeef0001,
205 NV04_TEXTURED_TRIANGLE
, &hw
->eng3d
);
209 ret
= nouveau_grobj_alloc(context_chan(ctx
), 0xbeef0002,
210 NV04_MULTITEX_TRIANGLE
, &hw
->eng3dm
);
214 ret
= nouveau_grobj_alloc(context_chan(ctx
), 0xbeef0003,
215 NV04_CONTEXT_SURFACES_3D
, &hw
->surf3d
);
219 init_dummy_texture(ctx
);
220 nv04_hwctx_init(ctx
);
221 nv04_render_init(ctx
);
226 nv04_context_destroy(ctx
);
230 const struct nouveau_driver nv04_driver
= {
231 .context_create
= nv04_context_create
,
232 .context_destroy
= nv04_context_destroy
,
233 .surface_copy
= nv04_surface_copy
,
234 .surface_fill
= nv04_surface_fill
,
235 .emit
= (nouveau_state_func
[]) {
237 nouveau_emit_nothing
,
240 nouveau_emit_nothing
,
241 nouveau_emit_nothing
,
242 nouveau_emit_nothing
,
243 nouveau_emit_nothing
,
244 nouveau_emit_nothing
,
245 nouveau_emit_nothing
,
247 nouveau_emit_nothing
,
249 nouveau_emit_nothing
,
252 nouveau_emit_nothing
,
253 nv04_emit_framebuffer
,
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
,
273 nouveau_emit_nothing
,
274 nouveau_emit_nothing
,
275 nouveau_emit_nothing
,
276 nouveau_emit_nothing
,
277 nouveau_emit_nothing
,
278 nouveau_emit_nothing
,
279 nouveau_emit_nothing
,
280 nouveau_emit_nothing
,
281 nouveau_emit_nothing
,
282 nouveau_emit_nothing
,
283 nouveau_emit_nothing
,
291 nouveau_emit_nothing
,
292 nouveau_emit_nothing
,
293 nouveau_emit_nothing
,
294 nouveau_emit_nothing
,
295 nouveau_emit_nothing
,
296 nouveau_emit_nothing
,
297 nouveau_emit_nothing
,
298 nouveau_emit_nothing
,
299 nouveau_emit_nothing
,
300 nouveau_emit_nothing
,
303 nouveau_emit_nothing
,
304 nouveau_emit_nothing
,
305 nouveau_emit_nothing
,
309 .num_emit
= NUM_NV04_STATE
,