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
) {
79 /* Flushing seems to clobber the engine context. */
80 context_emit(ctx
, TEX_OBJ0
);
81 context_emit(ctx
, TEX_OBJ1
);
82 context_emit(ctx
, TEX_ENV0
);
83 context_emit(ctx
, TEX_ENV1
);
84 context_emit(ctx
, CONTROL
);
85 context_emit(ctx
, BLEND
);
87 nouveau_bo_state_emit(ctx
);
92 nv04_hwctx_init(GLcontext
*ctx
)
94 struct nouveau_channel
*chan
= context_chan(ctx
);
95 struct nouveau_hw_state
*hw
= &to_nouveau_context(ctx
)->hw
;
96 struct nouveau_grobj
*surf3d
= hw
->surf3d
;
97 struct nouveau_grobj
*eng3d
= hw
->eng3d
;
98 struct nouveau_grobj
*eng3dm
= hw
->eng3dm
;
100 BIND_RING(chan
, surf3d
, 7);
101 BEGIN_RING(chan
, surf3d
, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY
, 3);
102 OUT_RING(chan
, hw
->ntfy
->handle
);
103 OUT_RING(chan
, chan
->vram
->handle
);
104 OUT_RING(chan
, chan
->vram
->handle
);
106 BEGIN_RING(chan
, eng3d
, NV04_TEXTURED_TRIANGLE_DMA_NOTIFY
, 4);
107 OUT_RING(chan
, hw
->ntfy
->handle
);
108 OUT_RING(chan
, chan
->vram
->handle
);
109 OUT_RING(chan
, chan
->gart
->handle
);
110 OUT_RING(chan
, surf3d
->handle
);
112 BEGIN_RING(chan
, eng3dm
, NV04_MULTITEX_TRIANGLE_DMA_NOTIFY
, 4);
113 OUT_RING(chan
, hw
->ntfy
->handle
);
114 OUT_RING(chan
, chan
->vram
->handle
);
115 OUT_RING(chan
, chan
->gart
->handle
);
116 OUT_RING(chan
, surf3d
->handle
);
122 init_dummy_texture(GLcontext
*ctx
)
124 struct nouveau_surface
*s
= &to_nv04_context(ctx
)->dummy_texture
;
126 nouveau_surface_alloc(ctx
, s
, SWIZZLED
,
127 NOUVEAU_BO_MAP
| NOUVEAU_BO_VRAM
,
128 MESA_FORMAT_ARGB8888
, 1, 1);
130 nouveau_bo_map(s
->bo
, NOUVEAU_BO_WR
);
131 *(uint32_t *)s
->bo
->map
= 0xffffffff;
132 nouveau_bo_unmap(s
->bo
);
136 nv04_context_destroy(GLcontext
*ctx
)
138 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
140 nv04_surface_takedown(ctx
);
141 nv04_render_destroy(ctx
);
142 nouveau_surface_ref(NULL
, &to_nv04_context(ctx
)->dummy_texture
);
144 nouveau_grobj_free(&nctx
->hw
.eng3d
);
145 nouveau_grobj_free(&nctx
->hw
.eng3dm
);
146 nouveau_grobj_free(&nctx
->hw
.surf3d
);
148 nouveau_context_deinit(ctx
);
153 nv04_context_create(struct nouveau_screen
*screen
, const GLvisual
*visual
,
154 GLcontext
*share_ctx
)
156 struct nv04_context
*nctx
;
157 struct nouveau_hw_state
*hw
;
161 nctx
= CALLOC_STRUCT(nv04_context
);
165 ctx
= &nctx
->base
.base
;
168 if (!nouveau_context_init(ctx
, screen
, visual
, share_ctx
))
171 hw
->chan
->flush_notify
= nv04_channel_flush_notify
;
174 ctx
->Const
.MaxTextureCoordUnits
= NV04_TEXTURE_UNITS
;
175 ctx
->Const
.MaxTextureImageUnits
= NV04_TEXTURE_UNITS
;
176 ctx
->Const
.MaxTextureUnits
= NV04_TEXTURE_UNITS
;
177 ctx
->Const
.MaxTextureMaxAnisotropy
= 2;
178 ctx
->Const
.MaxTextureLodBias
= 15;
181 ret
= nv04_surface_init(ctx
);
186 ret
= nouveau_grobj_alloc(context_chan(ctx
), 0xbeef0001,
187 NV04_TEXTURED_TRIANGLE
, &hw
->eng3d
);
191 ret
= nouveau_grobj_alloc(context_chan(ctx
), 0xbeef0002,
192 NV04_MULTITEX_TRIANGLE
, &hw
->eng3dm
);
196 ret
= nouveau_grobj_alloc(context_chan(ctx
), 0xbeef0003,
197 NV04_CONTEXT_SURFACES_3D
, &hw
->surf3d
);
201 init_dummy_texture(ctx
);
202 nv04_hwctx_init(ctx
);
203 nv04_render_init(ctx
);
208 nv04_context_destroy(ctx
);
212 const struct nouveau_driver nv04_driver
= {
213 .context_create
= nv04_context_create
,
214 .context_destroy
= nv04_context_destroy
,
215 .surface_copy
= nv04_surface_copy
,
216 .surface_fill
= nv04_surface_fill
,
217 .emit
= (nouveau_state_func
[]) {
219 nouveau_emit_nothing
,
222 nouveau_emit_nothing
,
223 nouveau_emit_nothing
,
224 nouveau_emit_nothing
,
225 nouveau_emit_nothing
,
226 nouveau_emit_nothing
,
227 nouveau_emit_nothing
,
229 nouveau_emit_nothing
,
231 nouveau_emit_nothing
,
234 nouveau_emit_nothing
,
235 nv04_emit_framebuffer
,
237 nouveau_emit_nothing
,
238 nouveau_emit_nothing
,
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
,
273 nouveau_emit_nothing
,
274 nouveau_emit_nothing
,
275 nouveau_emit_nothing
,
276 nouveau_emit_nothing
,
277 nouveau_emit_nothing
,
278 nouveau_emit_nothing
,
281 nouveau_emit_nothing
,
282 nouveau_emit_nothing
,
283 nouveau_emit_nothing
,
287 .num_emit
= NUM_NV04_STATE
,