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"
34 struct nouveau_grobj
*
35 nv04_context_engine(GLcontext
*ctx
)
37 struct nv04_context
*nctx
= to_nv04_context(ctx
);
38 struct nouveau_hw_state
*hw
= &to_nouveau_context(ctx
)->hw
;
39 struct nouveau_grobj
*fahrenheit
;
41 if (ctx
->Texture
.Unit
[0].EnvMode
== GL_COMBINE
||
42 ctx
->Texture
.Unit
[0].EnvMode
== GL_BLEND
||
43 ctx
->Texture
.Unit
[0].EnvMode
== GL_ADD
||
44 ctx
->Texture
.Unit
[1]._ReallyEnabled
||
46 fahrenheit
= hw
->eng3dm
;
48 fahrenheit
= hw
->eng3d
;
50 if (fahrenheit
!= nctx
->eng3d
) {
51 nctx
->eng3d
= fahrenheit
;
53 if (nv04_mtex_engine(fahrenheit
)) {
54 context_dirty_i(ctx
, TEX_ENV
, 0);
55 context_dirty_i(ctx
, TEX_ENV
, 1);
56 context_dirty_i(ctx
, TEX_OBJ
, 0);
57 context_dirty_i(ctx
, TEX_OBJ
, 1);
58 context_dirty(ctx
, CONTROL
);
59 context_dirty(ctx
, BLEND
);
61 context_bctx_i(ctx
, TEXTURE
, 1);
62 context_dirty_i(ctx
, TEX_ENV
, 0);
63 context_dirty_i(ctx
, TEX_OBJ
, 0);
64 context_dirty(ctx
, CONTROL
);
65 context_dirty(ctx
, BLEND
);
73 nv04_channel_flush_notify(struct nouveau_channel
*chan
)
75 struct nouveau_context
*nctx
= chan
->user_private
;
76 GLcontext
*ctx
= &nctx
->base
;
78 if (nctx
->fallback
< SWRAST
&& ctx
->DrawBuffer
) {
79 GLcontext
*ctx
= &nctx
->base
;
81 /* Flushing seems to clobber the engine context. */
82 context_dirty_i(ctx
, TEX_OBJ
, 0);
83 context_dirty_i(ctx
, TEX_OBJ
, 1);
84 context_dirty_i(ctx
, TEX_ENV
, 0);
85 context_dirty_i(ctx
, TEX_ENV
, 1);
86 context_dirty(ctx
, CONTROL
);
87 context_dirty(ctx
, BLEND
);
89 nouveau_state_emit(ctx
);
94 nv04_hwctx_init(GLcontext
*ctx
)
96 struct nouveau_channel
*chan
= context_chan(ctx
);
97 struct nouveau_hw_state
*hw
= &to_nouveau_context(ctx
)->hw
;
98 struct nouveau_grobj
*surf3d
= hw
->surf3d
;
99 struct nouveau_grobj
*eng3d
= hw
->eng3d
;
100 struct nouveau_grobj
*eng3dm
= hw
->eng3dm
;
102 BIND_RING(chan
, surf3d
, 7);
103 BEGIN_RING(chan
, surf3d
, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY
, 3);
104 OUT_RING(chan
, hw
->ntfy
->handle
);
105 OUT_RING(chan
, chan
->vram
->handle
);
106 OUT_RING(chan
, chan
->vram
->handle
);
108 BEGIN_RING(chan
, eng3d
, NV04_TEXTURED_TRIANGLE_DMA_NOTIFY
, 4);
109 OUT_RING(chan
, hw
->ntfy
->handle
);
110 OUT_RING(chan
, chan
->vram
->handle
);
111 OUT_RING(chan
, chan
->gart
->handle
);
112 OUT_RING(chan
, surf3d
->handle
);
114 BEGIN_RING(chan
, eng3dm
, NV04_MULTITEX_TRIANGLE_DMA_NOTIFY
, 4);
115 OUT_RING(chan
, hw
->ntfy
->handle
);
116 OUT_RING(chan
, chan
->vram
->handle
);
117 OUT_RING(chan
, chan
->gart
->handle
);
118 OUT_RING(chan
, surf3d
->handle
);
124 init_dummy_texture(GLcontext
*ctx
)
126 struct nouveau_surface
*s
= &to_nv04_context(ctx
)->dummy_texture
;
128 nouveau_surface_alloc(ctx
, s
, SWIZZLED
,
129 NOUVEAU_BO_MAP
| NOUVEAU_BO_VRAM
,
130 MESA_FORMAT_ARGB8888
, 1, 1);
132 nouveau_bo_map(s
->bo
, NOUVEAU_BO_WR
);
133 *(uint32_t *)s
->bo
->map
= 0xffffffff;
134 nouveau_bo_unmap(s
->bo
);
138 nv04_context_destroy(GLcontext
*ctx
)
140 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
142 nv04_surface_takedown(ctx
);
143 nv04_render_destroy(ctx
);
144 nouveau_surface_ref(NULL
, &to_nv04_context(ctx
)->dummy_texture
);
146 nouveau_grobj_free(&nctx
->hw
.eng3d
);
147 nouveau_grobj_free(&nctx
->hw
.eng3dm
);
148 nouveau_grobj_free(&nctx
->hw
.surf3d
);
150 nouveau_context_deinit(ctx
);
155 nv04_context_create(struct nouveau_screen
*screen
, const GLvisual
*visual
,
156 GLcontext
*share_ctx
)
158 struct nv04_context
*nctx
;
159 struct nouveau_hw_state
*hw
;
163 nctx
= CALLOC_STRUCT(nv04_context
);
167 ctx
= &nctx
->base
.base
;
170 if (!nouveau_context_init(ctx
, screen
, visual
, share_ctx
))
173 hw
->chan
->flush_notify
= nv04_channel_flush_notify
;
176 ctx
->Const
.MaxTextureCoordUnits
= NV04_TEXTURE_UNITS
;
177 ctx
->Const
.MaxTextureImageUnits
= NV04_TEXTURE_UNITS
;
178 ctx
->Const
.MaxTextureUnits
= NV04_TEXTURE_UNITS
;
179 ctx
->Const
.MaxTextureMaxAnisotropy
= 2;
180 ctx
->Const
.MaxTextureLodBias
= 15;
183 ret
= nv04_surface_init(ctx
);
188 ret
= nouveau_grobj_alloc(context_chan(ctx
), 0xbeef0001,
189 NV04_TEXTURED_TRIANGLE
, &hw
->eng3d
);
193 ret
= nouveau_grobj_alloc(context_chan(ctx
), 0xbeef0002,
194 NV04_MULTITEX_TRIANGLE
, &hw
->eng3dm
);
198 ret
= nouveau_grobj_alloc(context_chan(ctx
), 0xbeef0003,
199 NV04_CONTEXT_SURFACES_3D
, &hw
->surf3d
);
203 nv04_hwctx_init(ctx
);
204 nv04_render_init(ctx
);
205 init_dummy_texture(ctx
);
210 nv04_context_destroy(ctx
);
214 const struct nouveau_driver nv04_driver
= {
215 .context_create
= nv04_context_create
,
216 .context_destroy
= nv04_context_destroy
,
217 .surface_copy
= nv04_surface_copy
,
218 .surface_fill
= nv04_surface_fill
,
219 .emit
= (nouveau_state_func
[]) {
221 nouveau_emit_nothing
,
224 nouveau_emit_nothing
,
225 nouveau_emit_nothing
,
226 nouveau_emit_nothing
,
227 nouveau_emit_nothing
,
228 nouveau_emit_nothing
,
229 nouveau_emit_nothing
,
231 nouveau_emit_nothing
,
233 nouveau_emit_nothing
,
236 nouveau_emit_nothing
,
237 nv04_emit_framebuffer
,
239 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
,
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
,
275 nouveau_emit_nothing
,
276 nouveau_emit_nothing
,
277 nouveau_emit_nothing
,
278 nouveau_emit_nothing
,
279 nouveau_emit_nothing
,
280 nouveau_emit_nothing
,
283 nouveau_emit_nothing
,
284 nouveau_emit_nothing
,
285 nouveau_emit_nothing
,
289 .num_emit
= NUM_NV04_STATE
,