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_A_UNORM8
||
41 ti
->TexFormat
== MESA_FORMAT_L_UNORM8
||
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 BEGIN_NV04(push
, NV01_SUBC(3D
, OBJECT
), 1);
70 PUSH_DATA (push
, fahrenheit
->handle
);
71 nctx
->eng3d
= fahrenheit
;
78 nv04_hwctx_init(struct gl_context
*ctx
)
80 struct nouveau_hw_state
*hw
= &to_nouveau_context(ctx
)->hw
;
81 struct nouveau_pushbuf
*push
= context_push(ctx
);
82 struct nv04_fifo
*fifo
= hw
->chan
->data
;
84 BEGIN_NV04(push
, NV01_SUBC(SURF
, OBJECT
), 1);
85 PUSH_DATA (push
, hw
->surf3d
->handle
);
86 BEGIN_NV04(push
, NV04_SF3D(DMA_NOTIFY
), 3);
87 PUSH_DATA (push
, hw
->ntfy
->handle
);
88 PUSH_DATA (push
, fifo
->vram
);
89 PUSH_DATA (push
, fifo
->vram
);
91 BEGIN_NV04(push
, NV01_SUBC(3D
, OBJECT
), 1);
92 PUSH_DATA (push
, hw
->eng3d
->handle
);
93 BEGIN_NV04(push
, NV04_TTRI(DMA_NOTIFY
), 4);
94 PUSH_DATA (push
, hw
->ntfy
->handle
);
95 PUSH_DATA (push
, fifo
->vram
);
96 PUSH_DATA (push
, fifo
->gart
);
97 PUSH_DATA (push
, hw
->surf3d
->handle
);
99 BEGIN_NV04(push
, NV01_SUBC(3D
, OBJECT
), 1);
100 PUSH_DATA (push
, hw
->eng3dm
->handle
);
101 BEGIN_NV04(push
, NV04_MTRI(DMA_NOTIFY
), 4);
102 PUSH_DATA (push
, hw
->ntfy
->handle
);
103 PUSH_DATA (push
, fifo
->vram
);
104 PUSH_DATA (push
, fifo
->gart
);
105 PUSH_DATA (push
, hw
->surf3d
->handle
);
111 init_dummy_texture(struct gl_context
*ctx
)
113 struct nouveau_surface
*s
= &to_nv04_context(ctx
)->dummy_texture
;
115 nouveau_surface_alloc(ctx
, s
, SWIZZLED
,
116 NOUVEAU_BO_MAP
| NOUVEAU_BO_VRAM
,
117 MESA_FORMAT_B8G8R8A8_UNORM
, 1, 1);
119 nouveau_bo_map(s
->bo
, NOUVEAU_BO_WR
, context_client(ctx
));
120 *(uint32_t *)s
->bo
->map
= 0xffffffff;
124 nv04_context_destroy(struct gl_context
*ctx
)
126 struct nouveau_context
*nctx
= to_nouveau_context(ctx
);
128 nv04_surface_takedown(ctx
);
129 nv04_render_destroy(ctx
);
130 nouveau_surface_ref(NULL
, &to_nv04_context(ctx
)->dummy_texture
);
132 nouveau_object_del(&nctx
->hw
.eng3d
);
133 nouveau_object_del(&nctx
->hw
.eng3dm
);
134 nouveau_object_del(&nctx
->hw
.surf3d
);
136 nouveau_context_deinit(ctx
);
140 static struct gl_context
*
141 nv04_context_create(struct nouveau_screen
*screen
, gl_api api
,
142 const struct gl_config
*visual
,
143 struct gl_context
*share_ctx
)
145 struct nv04_context
*nctx
;
146 struct nouveau_hw_state
*hw
;
147 struct gl_context
*ctx
;
150 nctx
= CALLOC_STRUCT(nv04_context
);
154 ctx
= &nctx
->base
.base
;
157 if (!nouveau_context_init(ctx
, api
, screen
, visual
, share_ctx
))
161 ctx
->Const
.MaxTextureLevels
= 11;
162 ctx
->Const
.MaxTextureCoordUnits
= NV04_TEXTURE_UNITS
;
163 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
= NV04_TEXTURE_UNITS
;
164 ctx
->Const
.MaxTextureUnits
= NV04_TEXTURE_UNITS
;
165 ctx
->Const
.MaxTextureMaxAnisotropy
= 2;
166 ctx
->Const
.MaxTextureLodBias
= 15;
169 ret
= nv04_surface_init(ctx
);
174 ret
= nouveau_object_new(context_chan(ctx
), 0xbeef0001,
175 NV04_TEXTURED_TRIANGLE_CLASS
, NULL
, 0,
180 ret
= nouveau_object_new(context_chan(ctx
), 0xbeef0002,
181 NV04_MULTITEX_TRIANGLE_CLASS
, NULL
, 0,
186 ret
= nouveau_object_new(context_chan(ctx
), 0xbeef0003,
187 NV04_SURFACE_3D_CLASS
, NULL
, 0,
192 init_dummy_texture(ctx
);
193 nv04_hwctx_init(ctx
);
194 nv04_render_init(ctx
);
199 nv04_context_destroy(ctx
);
203 const struct nouveau_driver nv04_driver
= {
204 .context_create
= nv04_context_create
,
205 .context_destroy
= nv04_context_destroy
,
206 .surface_copy
= nv04_surface_copy
,
207 .surface_fill
= nv04_surface_fill
,
208 .emit
= (nouveau_state_func
[]) {
210 nouveau_emit_nothing
,
213 nouveau_emit_nothing
,
214 nouveau_emit_nothing
,
215 nouveau_emit_nothing
,
216 nouveau_emit_nothing
,
217 nouveau_emit_nothing
,
218 nouveau_emit_nothing
,
220 nouveau_emit_nothing
,
222 nouveau_emit_nothing
,
225 nouveau_emit_nothing
,
226 nv04_emit_framebuffer
,
228 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
,
235 nouveau_emit_nothing
,
236 nouveau_emit_nothing
,
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
,
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
,
276 nouveau_emit_nothing
,
277 nouveau_emit_nothing
,
278 nouveau_emit_nothing
,
282 .num_emit
= NUM_NV04_STATE
,