Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /* |
2 | * Copyright 2012 Red Hat Inc. |
||
3 | * |
||
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
5 | * copy of this software and associated documentation files (the "Software"), |
||
6 | * to deal in the Software without restriction, including without limitation |
||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
8 | * and/or sell copies of the Software, and to permit persons to whom the |
||
9 | * Software is furnished to do so, subject to the following conditions: |
||
10 | * |
||
11 | * The above copyright notice and this permission notice shall be included in |
||
12 | * all copies or substantial portions of the Software. |
||
13 | * |
||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||
20 | * OTHER DEALINGS IN THE SOFTWARE. |
||
21 | * |
||
22 | * Authors: Ben Skeggs |
||
23 | * |
||
24 | */ |
||
25 | |||
26 | #include "util/u_format.h" |
||
27 | #include "util/u_format_s3tc.h" |
||
28 | |||
29 | #include "nouveau/nv_object.xml.h" |
||
30 | #include "nouveau/nv_m2mf.xml.h" |
||
31 | #include "nv30-40_3d.xml.h" |
||
32 | #include "nv01_2d.xml.h" |
||
33 | |||
34 | #include "nouveau/nouveau_fence.h" |
||
35 | #include "nv30_screen.h" |
||
36 | #include "nv30_context.h" |
||
37 | #include "nv30_resource.h" |
||
38 | #include "nv30_format.h" |
||
39 | |||
40 | #define RANKINE_0397_CHIPSET 0x00000003 |
||
41 | #define RANKINE_0497_CHIPSET 0x000001e0 |
||
42 | #define RANKINE_0697_CHIPSET 0x00000010 |
||
43 | #define CURIE_4097_CHIPSET 0x00000baf |
||
44 | #define CURIE_4497_CHIPSET 0x00005450 |
||
45 | #define CURIE_4497_CHIPSET6X 0x00000088 |
||
46 | |||
47 | static int |
||
48 | nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) |
||
49 | { |
||
50 | struct nv30_screen *screen = nv30_screen(pscreen); |
||
51 | struct nouveau_object *eng3d = screen->eng3d; |
||
52 | |||
53 | switch (param) { |
||
54 | /* non-boolean capabilities */ |
||
55 | case PIPE_CAP_MAX_RENDER_TARGETS: |
||
56 | return (eng3d->oclass >= NV40_3D_CLASS) ? 4 : 1; |
||
57 | case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: |
||
58 | return 13; |
||
59 | case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: |
||
60 | return 10; |
||
61 | case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: |
||
62 | return 13; |
||
63 | case PIPE_CAP_MAX_COMBINED_SAMPLERS: |
||
64 | return 16; |
||
65 | case PIPE_CAP_GLSL_FEATURE_LEVEL: |
||
66 | return 120; |
||
67 | /* supported capabilities */ |
||
68 | case PIPE_CAP_TWO_SIDED_STENCIL: |
||
69 | case PIPE_CAP_ANISOTROPIC_FILTER: |
||
70 | case PIPE_CAP_POINT_SPRITE: |
||
71 | case PIPE_CAP_SCALED_RESOLVE: |
||
72 | case PIPE_CAP_OCCLUSION_QUERY: |
||
73 | case PIPE_CAP_QUERY_TIME_ELAPSED: |
||
74 | case PIPE_CAP_QUERY_TIMESTAMP: |
||
75 | case PIPE_CAP_TEXTURE_SHADOW_MAP: |
||
76 | case PIPE_CAP_TEXTURE_SWIZZLE: |
||
77 | case PIPE_CAP_DEPTH_CLIP_DISABLE: |
||
78 | case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: |
||
79 | case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: |
||
80 | case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: |
||
81 | case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: |
||
82 | case PIPE_CAP_TGSI_TEXCOORD: |
||
83 | case PIPE_CAP_USER_CONSTANT_BUFFERS: |
||
84 | case PIPE_CAP_USER_INDEX_BUFFERS: |
||
85 | return 1; |
||
86 | case PIPE_CAP_USER_VERTEX_BUFFERS: |
||
87 | return 0; |
||
88 | case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: |
||
89 | return 16; |
||
90 | /* nv4x capabilities */ |
||
91 | case PIPE_CAP_BLEND_EQUATION_SEPARATE: |
||
92 | case PIPE_CAP_NPOT_TEXTURES: |
||
93 | case PIPE_CAP_CONDITIONAL_RENDER: |
||
94 | case PIPE_CAP_TEXTURE_MIRROR_CLAMP: |
||
95 | case PIPE_CAP_PRIMITIVE_RESTART: |
||
96 | return (eng3d->oclass >= NV40_3D_CLASS) ? 1 : 0; |
||
97 | /* unsupported */ |
||
98 | case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: |
||
99 | case PIPE_CAP_SM3: |
||
100 | case PIPE_CAP_INDEP_BLEND_ENABLE: |
||
101 | case PIPE_CAP_INDEP_BLEND_FUNC: |
||
102 | case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: |
||
103 | case PIPE_CAP_SHADER_STENCIL_EXPORT: |
||
104 | case PIPE_CAP_TGSI_INSTANCEID: |
||
105 | case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: /* XXX: yes? */ |
||
106 | case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: |
||
107 | case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: |
||
108 | case PIPE_CAP_MIN_TEXEL_OFFSET: |
||
109 | case PIPE_CAP_MAX_TEXEL_OFFSET: |
||
110 | case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: |
||
111 | case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: |
||
112 | case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: |
||
113 | case PIPE_CAP_TEXTURE_BARRIER: |
||
114 | case PIPE_CAP_SEAMLESS_CUBE_MAP: |
||
115 | case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: |
||
116 | case PIPE_CAP_CUBE_MAP_ARRAY: |
||
117 | case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: |
||
118 | case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: |
||
119 | case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: |
||
120 | case PIPE_CAP_START_INSTANCE: |
||
121 | case PIPE_CAP_TEXTURE_MULTISAMPLE: |
||
122 | case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: |
||
123 | case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: |
||
124 | case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: |
||
125 | case PIPE_CAP_QUERY_PIPELINE_STATISTICS: |
||
126 | case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: |
||
127 | case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE: |
||
128 | return 0; |
||
129 | case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: |
||
130 | case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: |
||
131 | case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: |
||
132 | case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: |
||
133 | return 1; |
||
134 | case PIPE_CAP_ENDIANNESS: |
||
135 | return PIPE_ENDIAN_LITTLE; |
||
136 | default: |
||
137 | debug_printf("unknown param %d\n", param); |
||
138 | return 0; |
||
139 | } |
||
140 | } |
||
141 | |||
142 | static float |
||
143 | nv30_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) |
||
144 | { |
||
145 | struct nv30_screen *screen = nv30_screen(pscreen); |
||
146 | struct nouveau_object *eng3d = screen->eng3d; |
||
147 | |||
148 | switch (param) { |
||
149 | case PIPE_CAPF_MAX_LINE_WIDTH: |
||
150 | case PIPE_CAPF_MAX_LINE_WIDTH_AA: |
||
151 | return 10.0; |
||
152 | case PIPE_CAPF_MAX_POINT_WIDTH: |
||
153 | case PIPE_CAPF_MAX_POINT_WIDTH_AA: |
||
154 | return 64.0; |
||
155 | case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: |
||
156 | return (eng3d->oclass >= NV40_3D_CLASS) ? 16.0 : 8.0; |
||
157 | case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: |
||
158 | return 15.0; |
||
159 | default: |
||
160 | debug_printf("unknown paramf %d\n", param); |
||
161 | return 0; |
||
162 | } |
||
163 | } |
||
164 | |||
165 | static int |
||
166 | nv30_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, |
||
167 | enum pipe_shader_cap param) |
||
168 | { |
||
169 | struct nv30_screen *screen = nv30_screen(pscreen); |
||
170 | struct nouveau_object *eng3d = screen->eng3d; |
||
171 | |||
172 | switch (shader) { |
||
173 | case PIPE_SHADER_VERTEX: |
||
174 | switch (param) { |
||
175 | case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: |
||
176 | case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: |
||
177 | return (eng3d->oclass >= NV40_3D_CLASS) ? 512 : 256; |
||
178 | case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: |
||
179 | case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: |
||
180 | return (eng3d->oclass >= NV40_3D_CLASS) ? 512 : 0; |
||
181 | case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: |
||
182 | return 0; |
||
183 | case PIPE_SHADER_CAP_MAX_INPUTS: |
||
184 | return 16; |
||
185 | case PIPE_SHADER_CAP_MAX_CONSTS: |
||
186 | return (eng3d->oclass >= NV40_3D_CLASS) ? (468 - 6): (256 - 6); |
||
187 | case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: |
||
188 | return 1; |
||
189 | case PIPE_SHADER_CAP_MAX_TEMPS: |
||
190 | return (eng3d->oclass >= NV40_3D_CLASS) ? 32 : 13; |
||
191 | case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: |
||
192 | return 0; |
||
193 | case PIPE_SHADER_CAP_MAX_ADDRS: |
||
194 | return 2; |
||
195 | case PIPE_SHADER_CAP_MAX_PREDS: |
||
196 | case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: |
||
197 | case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: |
||
198 | case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: |
||
199 | case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: |
||
200 | case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: |
||
201 | case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: |
||
202 | case PIPE_SHADER_CAP_SUBROUTINES: |
||
203 | case PIPE_SHADER_CAP_INTEGERS: |
||
204 | return 0; |
||
205 | default: |
||
206 | debug_printf("unknown vertex shader param %d\n", param); |
||
207 | return 0; |
||
208 | } |
||
209 | break; |
||
210 | case PIPE_SHADER_FRAGMENT: |
||
211 | switch (param) { |
||
212 | case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: |
||
213 | case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: |
||
214 | case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: |
||
215 | case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: |
||
216 | return 4096; |
||
217 | case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: |
||
218 | return 0; |
||
219 | case PIPE_SHADER_CAP_MAX_INPUTS: |
||
220 | return (eng3d->oclass >= NV40_3D_CLASS) ? 12 : 10; |
||
221 | case PIPE_SHADER_CAP_MAX_CONSTS: |
||
222 | return (eng3d->oclass >= NV40_3D_CLASS) ? 224 : 32; |
||
223 | case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: |
||
224 | return 1; |
||
225 | case PIPE_SHADER_CAP_MAX_TEMPS: |
||
226 | return 32; |
||
227 | case PIPE_SHADER_CAP_MAX_ADDRS: |
||
228 | return (eng3d->oclass >= NV40_3D_CLASS) ? 1 : 0; |
||
229 | case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: |
||
230 | return 16; |
||
231 | case PIPE_SHADER_CAP_MAX_PREDS: |
||
232 | case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: |
||
233 | case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: |
||
234 | case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: |
||
235 | case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: |
||
236 | case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: |
||
237 | case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: |
||
238 | case PIPE_SHADER_CAP_SUBROUTINES: |
||
239 | return 0; |
||
240 | default: |
||
241 | debug_printf("unknown fragment shader param %d\n", param); |
||
242 | return 0; |
||
243 | } |
||
244 | break; |
||
245 | default: |
||
246 | return 0; |
||
247 | } |
||
248 | } |
||
249 | |||
250 | static boolean |
||
251 | nv30_screen_is_format_supported(struct pipe_screen *pscreen, |
||
252 | enum pipe_format format, |
||
253 | enum pipe_texture_target target, |
||
254 | unsigned sample_count, |
||
255 | unsigned bindings) |
||
256 | { |
||
257 | if (sample_count > 4) |
||
258 | return FALSE; |
||
259 | if (!(0x00000017 & (1 << sample_count))) |
||
260 | return FALSE; |
||
261 | |||
262 | if (!util_format_is_supported(format, bindings)) { |
||
263 | return FALSE; |
||
264 | } |
||
265 | |||
266 | /* transfers & shared are always supported */ |
||
267 | bindings &= ~(PIPE_BIND_TRANSFER_READ | |
||
268 | PIPE_BIND_TRANSFER_WRITE | |
||
269 | PIPE_BIND_SHARED); |
||
270 | |||
271 | return (nv30_format_info(pscreen, format)->bindings & bindings) == bindings; |
||
272 | } |
||
273 | |||
274 | static void |
||
275 | nv30_screen_fence_emit(struct pipe_screen *pscreen, uint32_t *sequence) |
||
276 | { |
||
277 | struct nv30_screen *screen = nv30_screen(pscreen); |
||
278 | struct nouveau_pushbuf *push = screen->base.pushbuf; |
||
279 | |||
280 | *sequence = ++screen->base.fence.sequence; |
||
281 | |||
282 | BEGIN_NV04(push, NV30_3D(FENCE_OFFSET), 2); |
||
283 | PUSH_DATA (push, 0); |
||
284 | PUSH_DATA (push, *sequence); |
||
285 | } |
||
286 | |||
287 | static uint32_t |
||
288 | nv30_screen_fence_update(struct pipe_screen *pscreen) |
||
289 | { |
||
290 | struct nv30_screen *screen = nv30_screen(pscreen); |
||
291 | struct nv04_notify *fence = screen->fence->data; |
||
292 | return *(uint32_t *)((char *)screen->notify->map + fence->offset); |
||
293 | } |
||
294 | |||
295 | static void |
||
296 | nv30_screen_destroy(struct pipe_screen *pscreen) |
||
297 | { |
||
298 | struct nv30_screen *screen = nv30_screen(pscreen); |
||
299 | |||
300 | if (screen->base.fence.current && |
||
301 | screen->base.fence.current->state >= NOUVEAU_FENCE_STATE_EMITTED) { |
||
302 | nouveau_fence_wait(screen->base.fence.current); |
||
303 | nouveau_fence_ref (NULL, &screen->base.fence.current); |
||
304 | } |
||
305 | |||
306 | nouveau_object_del(&screen->query); |
||
307 | nouveau_object_del(&screen->fence); |
||
308 | nouveau_object_del(&screen->ntfy); |
||
309 | |||
310 | nouveau_object_del(&screen->sifm); |
||
311 | nouveau_object_del(&screen->swzsurf); |
||
312 | nouveau_object_del(&screen->surf2d); |
||
313 | nouveau_object_del(&screen->m2mf); |
||
314 | nouveau_object_del(&screen->eng3d); |
||
315 | nouveau_object_del(&screen->null); |
||
316 | |||
317 | nouveau_screen_fini(&screen->base); |
||
318 | FREE(screen); |
||
319 | } |
||
320 | |||
321 | #define FAIL_SCREEN_INIT(str, err) \ |
||
322 | do { \ |
||
323 | NOUVEAU_ERR(str, err); \ |
||
324 | nv30_screen_destroy(pscreen); \ |
||
325 | return NULL; \ |
||
326 | } while(0) |
||
327 | |||
328 | struct pipe_screen * |
||
329 | nv30_screen_create(struct nouveau_device *dev) |
||
330 | { |
||
331 | struct nv30_screen *screen = CALLOC_STRUCT(nv30_screen); |
||
332 | struct pipe_screen *pscreen; |
||
333 | struct nouveau_pushbuf *push; |
||
334 | struct nv04_fifo *fifo; |
||
335 | unsigned oclass = 0; |
||
336 | int ret, i; |
||
337 | |||
338 | if (!screen) |
||
339 | return NULL; |
||
340 | |||
341 | switch (dev->chipset & 0xf0) { |
||
342 | case 0x30: |
||
343 | if (RANKINE_0397_CHIPSET & (1 << (dev->chipset & 0x0f))) |
||
344 | oclass = NV30_3D_CLASS; |
||
345 | else |
||
346 | if (RANKINE_0697_CHIPSET & (1 << (dev->chipset & 0x0f))) |
||
347 | oclass = NV34_3D_CLASS; |
||
348 | else |
||
349 | if (RANKINE_0497_CHIPSET & (1 << (dev->chipset & 0x0f))) |
||
350 | oclass = NV35_3D_CLASS; |
||
351 | break; |
||
352 | case 0x40: |
||
353 | if (CURIE_4097_CHIPSET & (1 << (dev->chipset & 0x0f))) |
||
354 | oclass = NV40_3D_CLASS; |
||
355 | else |
||
356 | if (CURIE_4497_CHIPSET & (1 << (dev->chipset & 0x0f))) |
||
357 | oclass = NV44_3D_CLASS; |
||
358 | break; |
||
359 | case 0x60: |
||
360 | if (CURIE_4497_CHIPSET6X & (1 << (dev->chipset & 0x0f))) |
||
361 | oclass = NV44_3D_CLASS; |
||
362 | break; |
||
363 | default: |
||
364 | break; |
||
365 | } |
||
366 | |||
367 | if (!oclass) { |
||
368 | NOUVEAU_ERR("unknown 3d class for 0x%02x\n", dev->chipset); |
||
369 | FREE(screen); |
||
370 | return NULL; |
||
371 | } |
||
372 | |||
373 | pscreen = &screen->base.base; |
||
374 | pscreen->destroy = nv30_screen_destroy; |
||
375 | pscreen->get_param = nv30_screen_get_param; |
||
376 | pscreen->get_paramf = nv30_screen_get_paramf; |
||
377 | pscreen->get_shader_param = nv30_screen_get_shader_param; |
||
378 | pscreen->context_create = nv30_context_create; |
||
379 | pscreen->is_format_supported = nv30_screen_is_format_supported; |
||
380 | nv30_resource_screen_init(pscreen); |
||
381 | |||
382 | screen->base.fence.emit = nv30_screen_fence_emit; |
||
383 | screen->base.fence.update = nv30_screen_fence_update; |
||
384 | |||
385 | ret = nouveau_screen_init(&screen->base, dev); |
||
386 | if (ret) |
||
387 | FAIL_SCREEN_INIT("nv30_screen_init failed: %d\n", ret); |
||
388 | |||
389 | screen->base.vidmem_bindings |= PIPE_BIND_VERTEX_BUFFER; |
||
390 | screen->base.sysmem_bindings |= PIPE_BIND_VERTEX_BUFFER; |
||
391 | if (oclass == NV40_3D_CLASS) { |
||
392 | screen->base.vidmem_bindings |= PIPE_BIND_INDEX_BUFFER; |
||
393 | screen->base.sysmem_bindings |= PIPE_BIND_INDEX_BUFFER; |
||
394 | } |
||
395 | |||
396 | fifo = screen->base.channel->data; |
||
397 | push = screen->base.pushbuf; |
||
398 | push->rsvd_kick = 16; |
||
399 | |||
400 | ret = nouveau_object_new(screen->base.channel, 0x00000000, NV01_NULL_CLASS, |
||
401 | NULL, 0, &screen->null); |
||
402 | if (ret) |
||
403 | FAIL_SCREEN_INIT("error allocating null object: %d\n", ret); |
||
404 | |||
405 | /* DMA_FENCE refuses to accept DMA objects with "adjust" filled in, |
||
406 | * this means that the address pointed at by the DMA object must |
||
407 | * be 4KiB aligned, which means this object needs to be the first |
||
408 | * one allocated on the channel. |
||
409 | */ |
||
410 | ret = nouveau_object_new(screen->base.channel, 0xbeef1e00, |
||
411 | NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) { |
||
412 | .length = 32 }, sizeof(struct nv04_notify), |
||
413 | &screen->fence); |
||
414 | if (ret) |
||
415 | FAIL_SCREEN_INIT("error allocating fence notifier: %d\n", ret); |
||
416 | |||
417 | /* DMA_NOTIFY object, we don't actually use this but M2MF fails without */ |
||
418 | ret = nouveau_object_new(screen->base.channel, 0xbeef0301, |
||
419 | NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) { |
||
420 | .length = 32 }, sizeof(struct nv04_notify), |
||
421 | &screen->ntfy); |
||
422 | if (ret) |
||
423 | FAIL_SCREEN_INIT("error allocating sync notifier: %d\n", ret); |
||
424 | |||
425 | /* DMA_QUERY, used to implement occlusion queries, we attempt to allocate |
||
426 | * the remainder of the "notifier block" assigned by the kernel for |
||
427 | * use as query objects |
||
428 | */ |
||
429 | ret = nouveau_object_new(screen->base.channel, 0xbeef0351, |
||
430 | NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) { |
||
431 | .length = 4096 - 128 }, sizeof(struct nv04_notify), |
||
432 | &screen->query); |
||
433 | if (ret) |
||
434 | FAIL_SCREEN_INIT("error allocating query notifier: %d\n", ret); |
||
435 | |||
436 | ret = nouveau_heap_init(&screen->query_heap, 0, 4096 - 128); |
||
437 | if (ret) |
||
438 | FAIL_SCREEN_INIT("error creating query heap: %d\n", ret); |
||
439 | |||
440 | LIST_INITHEAD(&screen->queries); |
||
441 | |||
442 | /* Vertex program resources (code/data), currently 6 of the constant |
||
443 | * slots are reserved to implement user clipping planes |
||
444 | */ |
||
445 | if (oclass < NV40_3D_CLASS) { |
||
446 | nouveau_heap_init(&screen->vp_exec_heap, 0, 256); |
||
447 | nouveau_heap_init(&screen->vp_data_heap, 6, 256 - 6); |
||
448 | } else { |
||
449 | nouveau_heap_init(&screen->vp_exec_heap, 0, 512); |
||
450 | nouveau_heap_init(&screen->vp_data_heap, 6, 468 - 6); |
||
451 | } |
||
452 | |||
453 | ret = nouveau_bo_wrap(screen->base.device, fifo->notify, &screen->notify); |
||
454 | if (ret == 0) |
||
455 | nouveau_bo_map(screen->notify, 0, screen->base.client); |
||
456 | if (ret) |
||
457 | FAIL_SCREEN_INIT("error mapping notifier memory: %d\n", ret); |
||
458 | |||
459 | ret = nouveau_object_new(screen->base.channel, 0xbeef3097, oclass, |
||
460 | NULL, 0, &screen->eng3d); |
||
461 | if (ret) |
||
462 | FAIL_SCREEN_INIT("error allocating 3d object: %d\n", ret); |
||
463 | |||
464 | BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1); |
||
465 | PUSH_DATA (push, screen->eng3d->handle); |
||
466 | BEGIN_NV04(push, NV30_3D(DMA_NOTIFY), 13); |
||
467 | PUSH_DATA (push, screen->ntfy->handle); |
||
468 | PUSH_DATA (push, fifo->vram); /* TEXTURE0 */ |
||
469 | PUSH_DATA (push, fifo->gart); /* TEXTURE1 */ |
||
470 | PUSH_DATA (push, fifo->vram); /* COLOR1 */ |
||
471 | PUSH_DATA (push, screen->null->handle); /* UNK190 */ |
||
472 | PUSH_DATA (push, fifo->vram); /* COLOR0 */ |
||
473 | PUSH_DATA (push, fifo->vram); /* ZETA */ |
||
474 | PUSH_DATA (push, fifo->vram); /* VTXBUF0 */ |
||
475 | PUSH_DATA (push, fifo->gart); /* VTXBUF1 */ |
||
476 | PUSH_DATA (push, screen->fence->handle); /* FENCE */ |
||
477 | PUSH_DATA (push, screen->query->handle); /* QUERY - intr 0x80 if nullobj */ |
||
478 | PUSH_DATA (push, screen->null->handle); /* UNK1AC */ |
||
479 | PUSH_DATA (push, screen->null->handle); /* UNK1B0 */ |
||
480 | if (screen->eng3d->oclass < NV40_3D_CLASS) { |
||
481 | BEGIN_NV04(push, SUBC_3D(0x03b0), 1); |
||
482 | PUSH_DATA (push, 0x00100000); |
||
483 | BEGIN_NV04(push, SUBC_3D(0x1d80), 1); |
||
484 | PUSH_DATA (push, 3); |
||
485 | |||
486 | BEGIN_NV04(push, SUBC_3D(0x1e98), 1); |
||
487 | PUSH_DATA (push, 0); |
||
488 | BEGIN_NV04(push, SUBC_3D(0x17e0), 3); |
||
489 | PUSH_DATA (push, fui(0.0)); |
||
490 | PUSH_DATA (push, fui(0.0)); |
||
491 | PUSH_DATA (push, fui(1.0)); |
||
492 | BEGIN_NV04(push, SUBC_3D(0x1f80), 16); |
||
493 | for (i = 0; i < 16; i++) |
||
494 | PUSH_DATA (push, (i == 8) ? 0x0000ffff : 0); |
||
495 | |||
496 | BEGIN_NV04(push, NV30_3D(RC_ENABLE), 1); |
||
497 | PUSH_DATA (push, 0); |
||
498 | } else { |
||
499 | BEGIN_NV04(push, NV40_3D(DMA_COLOR2), 2); |
||
500 | PUSH_DATA (push, fifo->vram); |
||
501 | PUSH_DATA (push, fifo->vram); /* COLOR3 */ |
||
502 | |||
503 | BEGIN_NV04(push, SUBC_3D(0x1450), 1); |
||
504 | PUSH_DATA (push, 0x00000004); |
||
505 | |||
506 | BEGIN_NV04(push, SUBC_3D(0x1ea4), 3); /* ZCULL */ |
||
507 | PUSH_DATA (push, 0x00000010); |
||
508 | PUSH_DATA (push, 0x01000100); |
||
509 | PUSH_DATA (push, 0xff800006); |
||
510 | |||
511 | /* vtxprog output routing */ |
||
512 | BEGIN_NV04(push, SUBC_3D(0x1fc4), 1); |
||
513 | PUSH_DATA (push, 0x06144321); |
||
514 | BEGIN_NV04(push, SUBC_3D(0x1fc8), 2); |
||
515 | PUSH_DATA (push, 0xedcba987); |
||
516 | PUSH_DATA (push, 0x0000006f); |
||
517 | BEGIN_NV04(push, SUBC_3D(0x1fd0), 1); |
||
518 | PUSH_DATA (push, 0x00171615); |
||
519 | BEGIN_NV04(push, SUBC_3D(0x1fd4), 1); |
||
520 | PUSH_DATA (push, 0x001b1a19); |
||
521 | |||
522 | BEGIN_NV04(push, SUBC_3D(0x1ef8), 1); |
||
523 | PUSH_DATA (push, 0x0020ffff); |
||
524 | BEGIN_NV04(push, SUBC_3D(0x1d64), 1); |
||
525 | PUSH_DATA (push, 0x01d300d4); |
||
526 | |||
527 | BEGIN_NV04(push, NV40_3D(MIPMAP_ROUNDING), 1); |
||
528 | PUSH_DATA (push, NV40_3D_MIPMAP_ROUNDING_MODE_DOWN); |
||
529 | } |
||
530 | |||
531 | ret = nouveau_object_new(screen->base.channel, 0xbeef3901, NV03_M2MF_CLASS, |
||
532 | NULL, 0, &screen->m2mf); |
||
533 | if (ret) |
||
534 | FAIL_SCREEN_INIT("error allocating m2mf object: %d\n", ret); |
||
535 | |||
536 | BEGIN_NV04(push, NV01_SUBC(M2MF, OBJECT), 1); |
||
537 | PUSH_DATA (push, screen->m2mf->handle); |
||
538 | BEGIN_NV04(push, NV03_M2MF(DMA_NOTIFY), 1); |
||
539 | PUSH_DATA (push, screen->ntfy->handle); |
||
540 | |||
541 | ret = nouveau_object_new(screen->base.channel, 0xbeef6201, |
||
542 | NV10_SURFACE_2D_CLASS, NULL, 0, &screen->surf2d); |
||
543 | if (ret) |
||
544 | FAIL_SCREEN_INIT("error allocating surf2d object: %d\n", ret); |
||
545 | |||
546 | BEGIN_NV04(push, NV01_SUBC(SF2D, OBJECT), 1); |
||
547 | PUSH_DATA (push, screen->surf2d->handle); |
||
548 | BEGIN_NV04(push, NV04_SF2D(DMA_NOTIFY), 1); |
||
549 | PUSH_DATA (push, screen->ntfy->handle); |
||
550 | |||
551 | if (dev->chipset < 0x40) |
||
552 | oclass = NV30_SURFACE_SWZ_CLASS; |
||
553 | else |
||
554 | oclass = NV40_SURFACE_SWZ_CLASS; |
||
555 | |||
556 | ret = nouveau_object_new(screen->base.channel, 0xbeef5201, oclass, |
||
557 | NULL, 0, &screen->swzsurf); |
||
558 | if (ret) |
||
559 | FAIL_SCREEN_INIT("error allocating swizzled surface object: %d\n", ret); |
||
560 | |||
561 | BEGIN_NV04(push, NV01_SUBC(SSWZ, OBJECT), 1); |
||
562 | PUSH_DATA (push, screen->swzsurf->handle); |
||
563 | BEGIN_NV04(push, NV04_SSWZ(DMA_NOTIFY), 1); |
||
564 | PUSH_DATA (push, screen->ntfy->handle); |
||
565 | |||
566 | if (dev->chipset < 0x40) |
||
567 | oclass = NV30_SIFM_CLASS; |
||
568 | else |
||
569 | oclass = NV40_SIFM_CLASS; |
||
570 | |||
571 | ret = nouveau_object_new(screen->base.channel, 0xbeef7701, oclass, |
||
572 | NULL, 0, &screen->sifm); |
||
573 | if (ret) |
||
574 | FAIL_SCREEN_INIT("error allocating scaled image object: %d\n", ret); |
||
575 | |||
576 | BEGIN_NV04(push, NV01_SUBC(SIFM, OBJECT), 1); |
||
577 | PUSH_DATA (push, screen->sifm->handle); |
||
578 | BEGIN_NV04(push, NV03_SIFM(DMA_NOTIFY), 1); |
||
579 | PUSH_DATA (push, screen->ntfy->handle); |
||
580 | BEGIN_NV04(push, NV05_SIFM(COLOR_CONVERSION), 1); |
||
581 | PUSH_DATA (push, NV05_SIFM_COLOR_CONVERSION_TRUNCATE); |
||
582 | |||
583 | nouveau_pushbuf_kick(push, push->channel); |
||
584 | |||
585 | nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE); |
||
586 | return pscreen; |
||
587 | }>>>>>><>><>><>><>><>><>><> |