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 <xf86drm.h>
27 #include "drm-uapi/nouveau_drm.h"
28 #include "util/format/u_format.h"
29 #include "util/format/u_format_s3tc.h"
30 #include "util/u_screen.h"
31
32 #include "nv_object.xml.h"
33 #include "nv_m2mf.xml.h"
34 #include "nv30/nv30-40_3d.xml.h"
35 #include "nv30/nv01_2d.xml.h"
36
37 #include "nouveau_fence.h"
38 #include "nv30/nv30_screen.h"
39 #include "nv30/nv30_context.h"
40 #include "nv30/nv30_resource.h"
41 #include "nv30/nv30_format.h"
42 #include "nv30/nv30_winsys.h"
43
44 #define RANKINE_0397_CHIPSET 0x00000003
45 #define RANKINE_0497_CHIPSET 0x000001e0
46 #define RANKINE_0697_CHIPSET 0x00000010
47 #define CURIE_4097_CHIPSET 0x00000baf
48 #define CURIE_4497_CHIPSET 0x00005450
49 #define CURIE_4497_CHIPSET6X 0x00000088
50
51 static int
nv30_screen_get_shader_param(struct pipe_screen * pscreen,enum pipe_shader_type shader,enum pipe_shader_cap param)52 nv30_screen_get_shader_param(struct pipe_screen *pscreen,
53 enum pipe_shader_type shader,
54 enum pipe_shader_cap param)
55 {
56 struct nv30_screen *screen = nv30_screen(pscreen);
57 struct nouveau_object *eng3d = screen->eng3d;
58
59 switch (shader) {
60 case PIPE_SHADER_VERTEX:
61 switch (param) {
62 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
63 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
64 return (eng3d->oclass >= NV40_3D_CLASS) ? 512 : 256;
65 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
66 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
67 return (eng3d->oclass >= NV40_3D_CLASS) ? 512 : 0;
68 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
69 return 0;
70 case PIPE_SHADER_CAP_MAX_INPUTS:
71 case PIPE_SHADER_CAP_MAX_OUTPUTS:
72 return 16;
73 case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE:
74 return ((eng3d->oclass >= NV40_3D_CLASS) ? (468 - 6): (256 - 6)) * sizeof(float[4]);
75 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
76 return 1;
77 case PIPE_SHADER_CAP_MAX_TEMPS:
78 return (eng3d->oclass >= NV40_3D_CLASS) ? 32 : 13;
79 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
80 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
81 return 0;
82 case PIPE_SHADER_CAP_CONT_SUPPORTED:
83 case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
84 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
85 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
86 case PIPE_SHADER_CAP_SUBROUTINES:
87 case PIPE_SHADER_CAP_INTEGERS:
88 case PIPE_SHADER_CAP_INT64_ATOMICS:
89 case PIPE_SHADER_CAP_FP16:
90 case PIPE_SHADER_CAP_FP16_DERIVATIVES:
91 case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
92 case PIPE_SHADER_CAP_INT16:
93 case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
94 case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
95 case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
96 case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
97 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
98 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
99 return 0;
100 case PIPE_SHADER_CAP_SUPPORTED_IRS:
101 return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI);
102 default:
103 debug_printf("unknown vertex shader param %d\n", param);
104 return 0;
105 }
106 break;
107 case PIPE_SHADER_FRAGMENT:
108 switch (param) {
109 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
110 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
111 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
112 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
113 return 4096;
114 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
115 return 0;
116 case PIPE_SHADER_CAP_MAX_INPUTS:
117 return 8; /* should be possible to do 10 with nv4x */
118 case PIPE_SHADER_CAP_MAX_OUTPUTS:
119 return 4;
120 case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE:
121 return ((eng3d->oclass >= NV40_3D_CLASS) ? 224 : 32) * sizeof(float[4]);
122 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
123 return 1;
124 case PIPE_SHADER_CAP_MAX_TEMPS:
125 return 32;
126 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
127 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
128 return 16;
129 case PIPE_SHADER_CAP_CONT_SUPPORTED:
130 case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
131 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
132 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
133 case PIPE_SHADER_CAP_SUBROUTINES:
134 case PIPE_SHADER_CAP_INTEGERS:
135 case PIPE_SHADER_CAP_FP16:
136 case PIPE_SHADER_CAP_FP16_DERIVATIVES:
137 case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
138 case PIPE_SHADER_CAP_INT16:
139 case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
140 case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
141 case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
142 case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
143 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
144 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
145 return 0;
146 case PIPE_SHADER_CAP_SUPPORTED_IRS:
147 return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI);
148 default:
149 debug_printf("unknown fragment shader param %d\n", param);
150 return 0;
151 }
152 break;
153 default:
154 return 0;
155 }
156 }
157
158 static void
nv30_init_screen_caps(struct nv30_screen * screen)159 nv30_init_screen_caps(struct nv30_screen *screen)
160 {
161 struct pipe_caps *caps = (struct pipe_caps *)&screen->base.base.caps;
162
163 u_init_pipe_screen_caps(&screen->base.base, 1);
164
165 struct nouveau_object *eng3d = screen->eng3d;
166 struct nouveau_device *dev = screen->base.device;
167
168 /* non-boolean capabilities */
169 caps->max_render_targets = (eng3d->oclass >= NV40_3D_CLASS) ? 4 : 1;
170 caps->max_texture_2d_size = 4096;
171 caps->max_texture_3d_levels = 10;
172 caps->max_texture_cube_levels = 13;
173 caps->glsl_feature_level =
174 caps->glsl_feature_level_compatibility = 120;
175 caps->endianness = PIPE_ENDIAN_LITTLE;
176 caps->constant_buffer_offset_alignment = 16;
177 caps->min_map_buffer_alignment = NOUVEAU_MIN_BUFFER_MAP_ALIGN;
178 caps->max_viewports = 1;
179 caps->max_vertex_attrib_stride = 2048;
180 caps->max_texture_upload_memory_budget = 8 * 1024 * 1024;
181 caps->max_varyings = 8;
182
183 /* supported capabilities */
184 caps->anisotropic_filter = true;
185 caps->occlusion_query = true;
186 caps->query_time_elapsed = true;
187 caps->query_timestamp = true;
188 caps->texture_swizzle = true;
189 caps->depth_clip_disable = true;
190 caps->fs_coord_origin_upper_left = true;
191 caps->fs_coord_origin_lower_left = true;
192 caps->fs_coord_pixel_center_half_integer = true;
193 caps->fs_coord_pixel_center_integer = true;
194 caps->tgsi_texcoord = true;
195 caps->buffer_map_persistent_coherent = true;
196 caps->clear_scissored = true;
197 caps->allow_mapped_buffers_during_execution = true;
198 caps->query_memory_info = true;
199 caps->vertex_input_alignment = PIPE_VERTEX_INPUT_ALIGNMENT_4BYTE;
200 caps->texture_transfer_modes = PIPE_TEXTURE_TRANSFER_BLIT;
201 /* nv35 capabilities */
202 caps->depth_bounds_test =
203 eng3d->oclass == NV35_3D_CLASS || eng3d->oclass >= NV40_3D_CLASS;
204 caps->supported_prim_modes_with_restart =
205 caps->supported_prim_modes = BITFIELD_MASK(MESA_PRIM_COUNT);
206 /* nv4x capabilities */
207 caps->blend_equation_separate =
208 caps->npot_textures =
209 caps->conditional_render =
210 caps->texture_mirror_clamp =
211 caps->texture_mirror_clamp_to_edge =
212 caps->primitive_restart =
213 caps->primitive_restart_fixed_index = eng3d->oclass >= NV40_3D_CLASS;
214 /* unsupported */
215 caps->emulate_nonfixed_primitive_restart = false;
216 caps->depth_clip_disable_separate = false;
217 caps->max_dual_source_render_targets = 0;
218 caps->fragment_shader_texture_lod = false;
219 caps->fragment_shader_derivatives = false;
220 caps->indep_blend_enable = false;
221 caps->indep_blend_func = false;
222 caps->max_texture_array_layers = 0;
223 caps->shader_stencil_export = false;
224 caps->vs_instanceid = false;
225 caps->vertex_element_instance_divisor = false; /* xxx = yes? */
226 caps->max_stream_output_buffers = 0;
227 caps->stream_output_pause_resume = false;
228 caps->stream_output_interleave_buffers = false;
229 caps->min_texel_offset = 0;
230 caps->max_texel_offset = 0;
231 caps->min_texture_gather_offset = 0;
232 caps->max_texture_gather_offset = 0;
233 caps->max_stream_output_separate_components = 0;
234 caps->max_stream_output_interleaved_components = 0;
235 caps->max_geometry_output_vertices = 0;
236 caps->max_geometry_total_output_components = 0;
237 caps->max_vertex_streams = 0;
238 caps->tgsi_can_compact_constants = false;
239 caps->texture_barrier = false;
240 caps->seamless_cube_map = false;
241 caps->seamless_cube_map_per_texture = false;
242 caps->cube_map_array = false;
243 caps->vertex_color_unclamped = false;
244 caps->fragment_color_clamped = false;
245 caps->vertex_color_clamped = false;
246 caps->quads_follow_provoking_vertex_convention = false;
247 caps->mixed_colorbuffer_formats = false;
248 caps->start_instance = false;
249 caps->texture_multisample = false;
250 caps->texture_buffer_objects = false;
251 caps->texture_buffer_offset_alignment = 0;
252 caps->query_pipeline_statistics = false;
253 caps->texture_border_color_quirk = false;
254 caps->max_texel_buffer_elements = 0;
255 caps->mixed_framebuffer_sizes = false;
256 caps->vs_layer_viewport = false;
257 caps->max_texture_gather_components = 0;
258 caps->texture_gather_sm5 = false;
259 caps->fake_sw_msaa = false;
260 caps->texture_query_lod = false;
261 caps->sample_shading = false;
262 caps->texture_gather_offsets = false;
263 caps->vs_window_space_position = false;
264 caps->user_vertex_buffers = false;
265 caps->compute = false;
266 caps->draw_indirect = false;
267 caps->multi_draw_indirect = false;
268 caps->multi_draw_indirect_params = false;
269 caps->fs_fine_derivative = false;
270 caps->conditional_render_inverted = false;
271 caps->sampler_view_target = false;
272 caps->clip_halfz = false;
273 caps->polygon_offset_clamp = false;
274 caps->multisample_z_resolve = false;
275 caps->resource_from_user_memory = false;
276 caps->device_reset_status_query = false;
277 caps->max_shader_patch_varyings = 0;
278 caps->texture_float_linear = false;
279 caps->texture_half_float_linear = false;
280 caps->texture_query_samples = false;
281 caps->force_persample_interp = false;
282 caps->copy_between_compressed_and_plain_formats = false;
283 caps->shareable_shaders = false;
284 caps->draw_parameters = false;
285 caps->shader_pack_half_float = false;
286 caps->fs_position_is_sysval = false;
287 caps->fs_face_is_integer_sysval = false;
288 caps->shader_buffer_offset_alignment = 0;
289 caps->invalidate_buffer = false;
290 caps->generate_mipmap = false;
291 caps->string_marker = false;
292 caps->buffer_sampler_view_rgba_only = false;
293 caps->surface_reinterpret_blocks = false;
294 caps->query_buffer_object = false;
295 caps->framebuffer_no_attachment = false;
296 caps->robust_buffer_access_behavior = false;
297 caps->cull_distance = false;
298 caps->shader_group_vote = false;
299 caps->max_window_rectangles = 0;
300 caps->polygon_offset_units_unscaled = false;
301 caps->viewport_subpixel_bits = 0;
302 caps->mixed_color_depth_bits = 0;
303 caps->shader_array_components = false;
304 caps->native_fence_fd = false;
305 caps->fbfetch = 0;
306 caps->legacy_math_rules = false;
307 caps->doubles = false;
308 caps->int64 = false;
309 caps->tgsi_tex_txf_lz = false;
310 caps->shader_clock = false;
311 caps->polygon_mode_fill_rectangle = false;
312 caps->sparse_buffer_page_size = 0;
313 caps->shader_ballot = false;
314 caps->tes_layer_viewport = false;
315 caps->can_bind_const_buffer_as_vertex = false;
316 caps->post_depth_coverage = false;
317 caps->bindless_texture = false;
318 caps->nir_samplers_as_deref = false;
319 caps->query_so_overflow = false;
320 caps->memobj = false;
321 caps->load_constbuf = false;
322 caps->tile_raster_order = false;
323 caps->max_combined_shader_output_resources = 0;
324 caps->framebuffer_msaa_constraints = false;
325 caps->signed_vertex_buffer_offset = false;
326 caps->context_priority_mask = 0;
327 caps->fence_signal = false;
328 caps->constbuf0_flags = 0;
329 caps->packed_uniforms = false;
330 caps->conservative_raster_post_snap_triangles = false;
331 caps->conservative_raster_post_snap_points_lines = false;
332 caps->conservative_raster_pre_snap_triangles = false;
333 caps->conservative_raster_pre_snap_points_lines = false;
334 caps->conservative_raster_post_depth_coverage = false;
335 caps->max_conservative_raster_subpixel_precision_bias = false;
336 caps->programmable_sample_locations = false;
337 caps->image_load_formatted = false;
338 caps->tgsi_div = false;
339 caps->image_atomic_inc_wrap = false;
340 caps->image_store_formatted = false;
341
342 caps->pci_group = dev->info.pci.domain;
343 caps->pci_bus = dev->info.pci.bus;
344 caps->pci_device = dev->info.pci.dev;
345 caps->pci_function = dev->info.pci.func;
346
347 caps->max_gs_invocations = 32;
348 caps->max_shader_buffer_size = 1 << 27;
349 caps->vendor_id = 0x10de;
350 caps->device_id = dev->info.device_id;
351 caps->video_memory = dev->vram_size >> 20;
352 caps->uma = false;
353
354 caps->min_line_width =
355 caps->min_line_width_aa =
356 caps->min_point_size =
357 caps->min_point_size_aa = 1;
358
359 caps->point_size_granularity =
360 caps->line_width_granularity = 0.1;
361
362 caps->max_line_width =
363 caps->max_line_width_aa = 10.0;
364
365 caps->max_point_size =
366 caps->max_point_size_aa = 64.0;
367
368 caps->max_texture_anisotropy = (eng3d->oclass >= NV40_3D_CLASS) ? 16.0 : 8.0;
369 caps->max_texture_lod_bias = 15.0;
370 }
371
372 static bool
nv30_screen_is_format_supported(struct pipe_screen * pscreen,enum pipe_format format,enum pipe_texture_target target,unsigned sample_count,unsigned storage_sample_count,unsigned bindings)373 nv30_screen_is_format_supported(struct pipe_screen *pscreen,
374 enum pipe_format format,
375 enum pipe_texture_target target,
376 unsigned sample_count,
377 unsigned storage_sample_count,
378 unsigned bindings)
379 {
380 if (sample_count > nv30_screen(pscreen)->max_sample_count)
381 return false;
382
383 if (!(0x00000017 & (1 << sample_count)))
384 return false;
385
386 if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
387 return false;
388
389 /* No way to render to a swizzled 3d texture. We don't necessarily know if
390 * it's swizzled or not here, but we have to assume anyways.
391 */
392 if (target == PIPE_TEXTURE_3D && (bindings & PIPE_BIND_RENDER_TARGET))
393 return false;
394
395 /* shared is always supported */
396 bindings &= ~PIPE_BIND_SHARED;
397
398 if (bindings & PIPE_BIND_INDEX_BUFFER) {
399 if (format != PIPE_FORMAT_R8_UINT &&
400 format != PIPE_FORMAT_R16_UINT &&
401 format != PIPE_FORMAT_R32_UINT)
402 return false;
403 bindings &= ~PIPE_BIND_INDEX_BUFFER;
404 }
405
406 return (nv30_format_info(pscreen, format)->bindings & bindings) == bindings;
407 }
408
409 static const nir_shader_compiler_options nv30_base_compiler_options = {
410 .fuse_ffma32 = true,
411 .fuse_ffma64 = true,
412 .lower_bitops = true,
413 .lower_extract_byte = true,
414 .lower_extract_word = true,
415 .lower_fdiv = true,
416 .lower_fsat = true,
417 .lower_insert_byte = true,
418 .lower_insert_word = true,
419 .lower_fdph = true,
420 .lower_flrp32 = true,
421 .lower_flrp64 = true,
422 .lower_fmod = true,
423 .lower_fpow = true, /* In hardware as of nv40 FS */
424 .lower_uniforms_to_ubo = true,
425 .lower_vector_cmp = true,
426 .force_indirect_unrolling = nir_var_all,
427 .force_indirect_unrolling_sampler = true,
428 .max_unroll_iterations = 32,
429 .no_integers = true,
430 };
431
432 static const void *
nv30_screen_get_compiler_options(struct pipe_screen * pscreen,enum pipe_shader_ir ir,enum pipe_shader_type shader)433 nv30_screen_get_compiler_options(struct pipe_screen *pscreen,
434 enum pipe_shader_ir ir,
435 enum pipe_shader_type shader)
436 {
437 struct nv30_screen *screen = nv30_screen(pscreen);
438 assert(ir == PIPE_SHADER_IR_NIR);
439
440 /* The FS compiler options are different between nv30 and nv40, and are set
441 * up at screen creation time.
442 */
443 if (shader == PIPE_SHADER_FRAGMENT)
444 return &screen->fs_compiler_options;
445
446 return &nv30_base_compiler_options;
447 }
448
449 static void
nv30_screen_fence_emit(struct pipe_context * pcontext,uint32_t * sequence,struct nouveau_bo * wait)450 nv30_screen_fence_emit(struct pipe_context *pcontext, uint32_t *sequence,
451 struct nouveau_bo *wait)
452 {
453 struct nv30_context *nv30 = nv30_context(pcontext);
454 struct nv30_screen *screen = nv30->screen;
455 struct nouveau_pushbuf *push = nv30->base.pushbuf;
456 struct nouveau_pushbuf_refn ref = { wait, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR };
457
458 *sequence = ++screen->base.fence.sequence;
459
460 assert(PUSH_AVAIL(push) + push->rsvd_kick >= 3);
461 PUSH_DATA (push, NV30_3D_FENCE_OFFSET |
462 (2 /* size */ << 18) | (7 /* subchan */ << 13));
463 PUSH_DATA (push, 0);
464 PUSH_DATA (push, *sequence);
465
466 nouveau_pushbuf_refn(push, &ref, 1);
467 }
468
469 static uint32_t
nv30_screen_fence_update(struct pipe_screen * pscreen)470 nv30_screen_fence_update(struct pipe_screen *pscreen)
471 {
472 struct nv30_screen *screen = nv30_screen(pscreen);
473 struct nv04_notify *fence = screen->fence->data;
474 return *(uint32_t *)((char *)screen->notify->map + fence->offset);
475 }
476
477 static void
nv30_screen_destroy(struct pipe_screen * pscreen)478 nv30_screen_destroy(struct pipe_screen *pscreen)
479 {
480 struct nv30_screen *screen = nv30_screen(pscreen);
481
482 if (!screen->base.initialized)
483 return;
484
485 nouveau_bo_ref(NULL, &screen->notify);
486
487 nouveau_heap_destroy(&screen->query_heap);
488 nouveau_heap_destroy(&screen->vp_exec_heap);
489 nouveau_heap_destroy(&screen->vp_data_heap);
490
491 nouveau_object_del(&screen->query);
492 nouveau_object_del(&screen->fence);
493 nouveau_object_del(&screen->ntfy);
494
495 nouveau_object_del(&screen->sifm);
496 nouveau_object_del(&screen->swzsurf);
497 nouveau_object_del(&screen->surf2d);
498 nouveau_object_del(&screen->m2mf);
499 nouveau_object_del(&screen->eng3d);
500 nouveau_object_del(&screen->null);
501
502 nouveau_screen_fini(&screen->base);
503 FREE(screen);
504 }
505
506 #define FAIL_SCREEN_INIT(str, err) \
507 do { \
508 NOUVEAU_ERR(str, err); \
509 screen->base.base.context_create = NULL; \
510 return &screen->base; \
511 } while(0)
512
513 struct nouveau_screen *
nv30_screen_create(struct nouveau_device * dev)514 nv30_screen_create(struct nouveau_device *dev)
515 {
516 struct nv30_screen *screen;
517 struct pipe_screen *pscreen;
518 struct nouveau_pushbuf *push;
519 struct nv04_fifo *fifo;
520 unsigned oclass = 0;
521 int ret, i;
522
523 switch (dev->chipset & 0xf0) {
524 case 0x30:
525 if (RANKINE_0397_CHIPSET & (1 << (dev->chipset & 0x0f)))
526 oclass = NV30_3D_CLASS;
527 else
528 if (RANKINE_0697_CHIPSET & (1 << (dev->chipset & 0x0f)))
529 oclass = NV34_3D_CLASS;
530 else
531 if (RANKINE_0497_CHIPSET & (1 << (dev->chipset & 0x0f)))
532 oclass = NV35_3D_CLASS;
533 break;
534 case 0x40:
535 if (CURIE_4097_CHIPSET & (1 << (dev->chipset & 0x0f)))
536 oclass = NV40_3D_CLASS;
537 else
538 if (CURIE_4497_CHIPSET & (1 << (dev->chipset & 0x0f)))
539 oclass = NV44_3D_CLASS;
540 break;
541 case 0x60:
542 if (CURIE_4497_CHIPSET6X & (1 << (dev->chipset & 0x0f)))
543 oclass = NV44_3D_CLASS;
544 break;
545 default:
546 break;
547 }
548
549 if (!oclass) {
550 NOUVEAU_ERR("unknown 3d class for 0x%02x\n", dev->chipset);
551 return NULL;
552 }
553
554 screen = CALLOC_STRUCT(nv30_screen);
555 if (!screen)
556 return NULL;
557
558 pscreen = &screen->base.base;
559 pscreen->destroy = nv30_screen_destroy;
560
561 /*
562 * Some modern apps try to use msaa without keeping in mind the
563 * restrictions on videomem of older cards. Resulting in dmesg saying:
564 * [ 1197.850642] nouveau E[soffice.bin[3785]] fail ttm_validate
565 * [ 1197.850648] nouveau E[soffice.bin[3785]] validating bo list
566 * [ 1197.850654] nouveau E[soffice.bin[3785]] validate: -12
567 *
568 * Because we are running out of video memory, after which the program
569 * using the msaa visual freezes, and eventually the entire system freezes.
570 *
571 * To work around this we do not allow msaa visauls by default and allow
572 * the user to override this via NV30_MAX_MSAA.
573 */
574 screen->max_sample_count = debug_get_num_option("NV30_MAX_MSAA", 0);
575 if (screen->max_sample_count > 4)
576 screen->max_sample_count = 4;
577
578 pscreen->get_shader_param = nv30_screen_get_shader_param;
579 pscreen->context_create = nv30_context_create;
580 pscreen->is_format_supported = nv30_screen_is_format_supported;
581 pscreen->get_compiler_options = nv30_screen_get_compiler_options;
582
583 nv30_resource_screen_init(pscreen);
584 nouveau_screen_init_vdec(&screen->base);
585
586 screen->base.fence.emit = nv30_screen_fence_emit;
587 screen->base.fence.update = nv30_screen_fence_update;
588
589 ret = nouveau_screen_init(&screen->base, dev);
590 if (ret)
591 FAIL_SCREEN_INIT("nv30_screen_init failed: %d\n", ret);
592
593 screen->base.vidmem_bindings |= PIPE_BIND_VERTEX_BUFFER;
594 screen->base.sysmem_bindings |= PIPE_BIND_VERTEX_BUFFER;
595 if (oclass == NV40_3D_CLASS) {
596 screen->base.vidmem_bindings |= PIPE_BIND_INDEX_BUFFER;
597 screen->base.sysmem_bindings |= PIPE_BIND_INDEX_BUFFER;
598 }
599
600 screen->fs_compiler_options = nv30_base_compiler_options;
601 screen->fs_compiler_options.lower_fsat = false;
602 if (oclass >= NV40_3D_CLASS)
603 screen->fs_compiler_options.lower_fpow = false;
604
605 fifo = screen->base.channel->data;
606 push = screen->base.pushbuf;
607 push->rsvd_kick = 16;
608
609 ret = nouveau_object_new(screen->base.channel, 0x00000000, NV01_NULL_CLASS,
610 NULL, 0, &screen->null);
611 if (ret)
612 FAIL_SCREEN_INIT("error allocating null object: %d\n", ret);
613
614 /* DMA_FENCE refuses to accept DMA objects with "adjust" filled in,
615 * this means that the address pointed at by the DMA object must
616 * be 4KiB aligned, which means this object needs to be the first
617 * one allocated on the channel.
618 */
619 ret = nouveau_object_new(screen->base.channel, 0xbeef1e00,
620 NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {
621 .length = 32 }, sizeof(struct nv04_notify),
622 &screen->fence);
623 if (ret)
624 FAIL_SCREEN_INIT("error allocating fence notifier: %d\n", ret);
625
626 /* DMA_NOTIFY object, we don't actually use this but M2MF fails without */
627 ret = nouveau_object_new(screen->base.channel, 0xbeef0301,
628 NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {
629 .length = 32 }, sizeof(struct nv04_notify),
630 &screen->ntfy);
631 if (ret)
632 FAIL_SCREEN_INIT("error allocating sync notifier: %d\n", ret);
633
634 /* DMA_QUERY, used to implement occlusion queries, we attempt to allocate
635 * the remainder of the "notifier block" assigned by the kernel for
636 * use as query objects
637 */
638 ret = nouveau_object_new(screen->base.channel, 0xbeef0351,
639 NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {
640 .length = 4096 - 128 }, sizeof(struct nv04_notify),
641 &screen->query);
642 if (ret)
643 FAIL_SCREEN_INIT("error allocating query notifier: %d\n", ret);
644
645 ret = nouveau_heap_init(&screen->query_heap, 0, 4096 - 128);
646 if (ret)
647 FAIL_SCREEN_INIT("error creating query heap: %d\n", ret);
648
649 list_inithead(&screen->queries);
650
651 /* Vertex program resources (code/data), currently 6 of the constant
652 * slots are reserved to implement user clipping planes
653 */
654 if (oclass < NV40_3D_CLASS) {
655 nouveau_heap_init(&screen->vp_exec_heap, 0, 256);
656 nouveau_heap_init(&screen->vp_data_heap, 6, 256 - 6);
657 } else {
658 nouveau_heap_init(&screen->vp_exec_heap, 0, 512);
659 nouveau_heap_init(&screen->vp_data_heap, 6, 468 - 6);
660 }
661
662 ret = nouveau_bo_wrap(screen->base.device, fifo->base.notify, &screen->notify);
663 if (ret == 0)
664 ret = BO_MAP(&screen->base, screen->notify, 0, screen->base.client);
665 if (ret)
666 FAIL_SCREEN_INIT("error mapping notifier memory: %d\n", ret);
667
668 ret = nouveau_object_new(screen->base.channel, 0xbeef3097, oclass,
669 NULL, 0, &screen->eng3d);
670 if (ret)
671 FAIL_SCREEN_INIT("error allocating 3d object: %d\n", ret);
672
673 nv30_init_screen_caps(screen);
674
675 BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
676 PUSH_DATA (push, screen->eng3d->handle);
677 BEGIN_NV04(push, NV30_3D(DMA_NOTIFY), 13);
678 PUSH_DATA (push, screen->ntfy->handle);
679 PUSH_DATA (push, fifo->vram); /* TEXTURE0 */
680 PUSH_DATA (push, fifo->gart); /* TEXTURE1 */
681 PUSH_DATA (push, fifo->vram); /* COLOR1 */
682 PUSH_DATA (push, screen->null->handle); /* UNK190 */
683 PUSH_DATA (push, fifo->vram); /* COLOR0 */
684 PUSH_DATA (push, fifo->vram); /* ZETA */
685 PUSH_DATA (push, fifo->vram); /* VTXBUF0 */
686 PUSH_DATA (push, fifo->gart); /* VTXBUF1 */
687 PUSH_DATA (push, screen->fence->handle); /* FENCE */
688 PUSH_DATA (push, screen->query->handle); /* QUERY - intr 0x80 if nullobj */
689 PUSH_DATA (push, screen->null->handle); /* UNK1AC */
690 PUSH_DATA (push, screen->null->handle); /* UNK1B0 */
691 if (screen->eng3d->oclass < NV40_3D_CLASS) {
692 BEGIN_NV04(push, SUBC_3D(0x03b0), 1);
693 PUSH_DATA (push, 0x00100000);
694 BEGIN_NV04(push, SUBC_3D(0x1d80), 1);
695 PUSH_DATA (push, 3);
696
697 BEGIN_NV04(push, SUBC_3D(0x1e98), 1);
698 PUSH_DATA (push, 0);
699 BEGIN_NV04(push, SUBC_3D(0x17e0), 3);
700 PUSH_DATA (push, fui(0.0));
701 PUSH_DATA (push, fui(0.0));
702 PUSH_DATA (push, fui(1.0));
703 BEGIN_NV04(push, SUBC_3D(0x1f80), 16);
704 for (i = 0; i < 16; i++)
705 PUSH_DATA (push, (i == 8) ? 0x0000ffff : 0);
706
707 BEGIN_NV04(push, NV30_3D(RC_ENABLE), 1);
708 PUSH_DATA (push, 0);
709 } else {
710 BEGIN_NV04(push, NV40_3D(DMA_COLOR2), 2);
711 PUSH_DATA (push, fifo->vram);
712 PUSH_DATA (push, fifo->vram); /* COLOR3 */
713
714 BEGIN_NV04(push, SUBC_3D(0x1450), 1);
715 PUSH_DATA (push, 0x00000004);
716
717 BEGIN_NV04(push, SUBC_3D(0x1ea4), 3); /* ZCULL */
718 PUSH_DATA (push, 0x00000010);
719 PUSH_DATA (push, 0x01000100);
720 PUSH_DATA (push, 0xff800006);
721
722 /* vtxprog output routing */
723 BEGIN_NV04(push, SUBC_3D(0x1fc4), 1);
724 PUSH_DATA (push, 0x06144321);
725 BEGIN_NV04(push, SUBC_3D(0x1fc8), 2);
726 PUSH_DATA (push, 0xedcba987);
727 PUSH_DATA (push, 0x0000006f);
728 BEGIN_NV04(push, SUBC_3D(0x1fd0), 1);
729 PUSH_DATA (push, 0x00171615);
730 BEGIN_NV04(push, SUBC_3D(0x1fd4), 1);
731 PUSH_DATA (push, 0x001b1a19);
732
733 BEGIN_NV04(push, SUBC_3D(0x1ef8), 1);
734 PUSH_DATA (push, 0x0020ffff);
735 BEGIN_NV04(push, SUBC_3D(0x1d64), 1);
736 PUSH_DATA (push, 0x01d300d4);
737
738 BEGIN_NV04(push, NV40_3D(MIPMAP_ROUNDING), 1);
739 PUSH_DATA (push, NV40_3D_MIPMAP_ROUNDING_MODE_DOWN);
740 }
741
742 ret = nouveau_object_new(screen->base.channel, 0xbeef3901, NV03_M2MF_CLASS,
743 NULL, 0, &screen->m2mf);
744 if (ret)
745 FAIL_SCREEN_INIT("error allocating m2mf object: %d\n", ret);
746
747 BEGIN_NV04(push, NV01_SUBC(M2MF, OBJECT), 1);
748 PUSH_DATA (push, screen->m2mf->handle);
749 BEGIN_NV04(push, NV03_M2MF(DMA_NOTIFY), 1);
750 PUSH_DATA (push, screen->ntfy->handle);
751
752 ret = nouveau_object_new(screen->base.channel, 0xbeef6201,
753 NV10_SURFACE_2D_CLASS, NULL, 0, &screen->surf2d);
754 if (ret)
755 FAIL_SCREEN_INIT("error allocating surf2d object: %d\n", ret);
756
757 BEGIN_NV04(push, NV01_SUBC(SF2D, OBJECT), 1);
758 PUSH_DATA (push, screen->surf2d->handle);
759 BEGIN_NV04(push, NV04_SF2D(DMA_NOTIFY), 1);
760 PUSH_DATA (push, screen->ntfy->handle);
761
762 if (dev->chipset < 0x40)
763 oclass = NV30_SURFACE_SWZ_CLASS;
764 else
765 oclass = NV40_SURFACE_SWZ_CLASS;
766
767 ret = nouveau_object_new(screen->base.channel, 0xbeef5201, oclass,
768 NULL, 0, &screen->swzsurf);
769 if (ret)
770 FAIL_SCREEN_INIT("error allocating swizzled surface object: %d\n", ret);
771
772 BEGIN_NV04(push, NV01_SUBC(SSWZ, OBJECT), 1);
773 PUSH_DATA (push, screen->swzsurf->handle);
774 BEGIN_NV04(push, NV04_SSWZ(DMA_NOTIFY), 1);
775 PUSH_DATA (push, screen->ntfy->handle);
776
777 if (dev->chipset < 0x40)
778 oclass = NV30_SIFM_CLASS;
779 else
780 oclass = NV40_SIFM_CLASS;
781
782 ret = nouveau_object_new(screen->base.channel, 0xbeef7701, oclass,
783 NULL, 0, &screen->sifm);
784 if (ret)
785 FAIL_SCREEN_INIT("error allocating scaled image object: %d\n", ret);
786
787 BEGIN_NV04(push, NV01_SUBC(SIFM, OBJECT), 1);
788 PUSH_DATA (push, screen->sifm->handle);
789 BEGIN_NV04(push, NV03_SIFM(DMA_NOTIFY), 1);
790 PUSH_DATA (push, screen->ntfy->handle);
791 BEGIN_NV04(push, NV05_SIFM(COLOR_CONVERSION), 1);
792 PUSH_DATA (push, NV05_SIFM_COLOR_CONVERSION_TRUNCATE);
793 PUSH_KICK (push);
794
795 return &screen->base;
796 }
797