1 /*
2 * Copyright 2010 Christoph Bumiller
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
23 #include <xf86drm.h>
24 #include "drm-uapi/nouveau_drm.h"
25 #include <nvif/class.h>
26 #include "util/format/u_format.h"
27 #include "util/format/u_format_s3tc.h"
28 #include "util/u_screen.h"
29 #include "pipe/p_screen.h"
30
31 #include "nouveau_vp3_video.h"
32
33 #include "nv50_ir_driver.h"
34
35 #include "nvc0/nvc0_context.h"
36 #include "nvc0/nvc0_screen.h"
37
38 #include "nvc0/mme/com9097.mme.h"
39 #include "nvc0/mme/com90c0.mme.h"
40 #include "nvc0/mme/comc597.mme.h"
41
42 #include "nv50/g80_texture.xml.h"
43
44 static bool
nvc0_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)45 nvc0_screen_is_format_supported(struct pipe_screen *pscreen,
46 enum pipe_format format,
47 enum pipe_texture_target target,
48 unsigned sample_count,
49 unsigned storage_sample_count,
50 unsigned bindings)
51 {
52 const struct util_format_description *desc = util_format_description(format);
53
54 if (sample_count > 8)
55 return false;
56 if (!(0x117 & (1 << sample_count))) /* 0, 1, 2, 4 or 8 */
57 return false;
58
59 if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
60 return false;
61
62 /* Short-circuit the rest of the logic -- this is used by the gallium frontend
63 * to determine valid MS levels in a no-attachments scenario.
64 */
65 if (format == PIPE_FORMAT_NONE && bindings & PIPE_BIND_RENDER_TARGET)
66 return true;
67
68 if ((bindings & PIPE_BIND_SAMPLER_VIEW) && (target != PIPE_BUFFER))
69 if (util_format_get_blocksizebits(format) == 3 * 32)
70 return false;
71
72 if (bindings & PIPE_BIND_LINEAR)
73 if (util_format_is_depth_or_stencil(format) ||
74 (target != PIPE_TEXTURE_1D &&
75 target != PIPE_TEXTURE_2D &&
76 target != PIPE_TEXTURE_RECT) ||
77 sample_count > 1)
78 return false;
79
80 /* Restrict ETC2 and ASTC formats here. These are only supported on GK20A
81 * and GM20B.
82 */
83 if ((desc->layout == UTIL_FORMAT_LAYOUT_ETC ||
84 desc->layout == UTIL_FORMAT_LAYOUT_ASTC) &&
85 nouveau_screen(pscreen)->device->chipset != 0x12b &&
86 nouveau_screen(pscreen)->class_3d != NVEA_3D_CLASS)
87 return false;
88
89 /* shared is always supported */
90 bindings &= ~(PIPE_BIND_LINEAR |
91 PIPE_BIND_SHARED);
92
93 if (bindings & PIPE_BIND_SHADER_IMAGE) {
94 if (format == PIPE_FORMAT_B8G8R8A8_UNORM &&
95 nouveau_screen(pscreen)->class_3d < NVE4_3D_CLASS) {
96 /* This should work on Fermi, but for currently unknown reasons it
97 * does not and results in breaking reads from pbos. */
98 return false;
99 }
100 }
101
102 if (bindings & PIPE_BIND_INDEX_BUFFER) {
103 if (format != PIPE_FORMAT_R8_UINT &&
104 format != PIPE_FORMAT_R16_UINT &&
105 format != PIPE_FORMAT_R32_UINT)
106 return false;
107 bindings &= ~PIPE_BIND_INDEX_BUFFER;
108 }
109
110 return (( nvc0_format_table[format].usage |
111 nvc0_vertex_format[format].usage) & bindings) == bindings;
112 }
113
114 static int
nvc0_screen_get_shader_param(struct pipe_screen * pscreen,enum pipe_shader_type shader,enum pipe_shader_cap param)115 nvc0_screen_get_shader_param(struct pipe_screen *pscreen,
116 enum pipe_shader_type shader,
117 enum pipe_shader_cap param)
118 {
119 const struct nouveau_screen *screen = nouveau_screen(pscreen);
120 const uint16_t class_3d = screen->class_3d;
121
122 switch (shader) {
123 case PIPE_SHADER_VERTEX:
124 case PIPE_SHADER_GEOMETRY:
125 case PIPE_SHADER_FRAGMENT:
126 case PIPE_SHADER_COMPUTE:
127 case PIPE_SHADER_TESS_CTRL:
128 case PIPE_SHADER_TESS_EVAL:
129 break;
130 default:
131 return 0;
132 }
133
134 switch (param) {
135 case PIPE_SHADER_CAP_SUPPORTED_IRS:
136 return 1 << PIPE_SHADER_IR_NIR;
137 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
138 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
139 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
140 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
141 return 16384;
142 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
143 return 16;
144 case PIPE_SHADER_CAP_MAX_INPUTS:
145 return 0x200 / 16;
146 case PIPE_SHADER_CAP_MAX_OUTPUTS:
147 return 32;
148 case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE:
149 return NVC0_MAX_CONSTBUF_SIZE;
150 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
151 return NVC0_MAX_PIPE_CONSTBUFS;
152 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
153 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
154 return 1;
155 case PIPE_SHADER_CAP_MAX_TEMPS:
156 return NVC0_CAP_MAX_PROGRAM_TEMPS;
157 case PIPE_SHADER_CAP_CONT_SUPPORTED:
158 return 1;
159 case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
160 return 1;
161 case PIPE_SHADER_CAP_SUBROUTINES:
162 return 1;
163 case PIPE_SHADER_CAP_INTEGERS:
164 return 1;
165 case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
166 case PIPE_SHADER_CAP_INT64_ATOMICS:
167 case PIPE_SHADER_CAP_FP16:
168 case PIPE_SHADER_CAP_FP16_DERIVATIVES:
169 case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
170 case PIPE_SHADER_CAP_INT16:
171 case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
172 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
173 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
174 return 0;
175 case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
176 return NVC0_MAX_BUFFERS;
177 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
178 return (class_3d >= NVE4_3D_CLASS) ? 32 : 16;
179 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
180 return (class_3d >= NVE4_3D_CLASS) ? 32 : 16;
181 case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
182 if (class_3d >= NVE4_3D_CLASS)
183 return NVC0_MAX_IMAGES;
184 if (shader == PIPE_SHADER_FRAGMENT || shader == PIPE_SHADER_COMPUTE)
185 return NVC0_MAX_IMAGES;
186 return 0;
187 default:
188 NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param);
189 return 0;
190 }
191 }
192
193 static int
nvc0_screen_get_compute_param(struct pipe_screen * pscreen,enum pipe_shader_ir ir_type,enum pipe_compute_cap param,void * data)194 nvc0_screen_get_compute_param(struct pipe_screen *pscreen,
195 enum pipe_shader_ir ir_type,
196 enum pipe_compute_cap param, void *data)
197 {
198 struct nvc0_screen *screen = nvc0_screen(pscreen);
199 struct nouveau_device *dev = screen->base.device;
200 const uint16_t obj_class = screen->compute->oclass;
201
202 #define RET(x) do { \
203 if (data) \
204 memcpy(data, x, sizeof(x)); \
205 return sizeof(x); \
206 } while (0)
207
208 switch (param) {
209 case PIPE_COMPUTE_CAP_GRID_DIMENSION:
210 RET((uint64_t []) { 3 });
211 case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
212 if (obj_class >= NVE4_COMPUTE_CLASS) {
213 RET(((uint64_t []) { 0x7fffffff, 65535, 65535 }));
214 } else {
215 RET(((uint64_t []) { 65535, 65535, 65535 }));
216 }
217 case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
218 RET(((uint64_t []) { 1024, 1024, 64 }));
219 case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
220 RET((uint64_t []) { 1024 });
221 case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:
222 if (obj_class >= NVE4_COMPUTE_CLASS) {
223 RET((uint64_t []) { 1024 });
224 } else {
225 RET((uint64_t []) { 512 });
226 }
227 case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE: /* g[] */
228 RET((uint64_t []) { nouveau_device_get_global_mem_size(dev) });
229 case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE: /* s[] */
230 switch (obj_class) {
231 case GM200_COMPUTE_CLASS:
232 RET((uint64_t []) { 96 << 10 });
233 case GM107_COMPUTE_CLASS:
234 RET((uint64_t []) { 64 << 10 });
235 default:
236 RET((uint64_t []) { 48 << 10 });
237 }
238 case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE: /* l[] */
239 RET((uint64_t []) { 512 << 10 });
240 case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE: /* c[], arbitrary limit */
241 RET((uint64_t []) { 4096 });
242 case PIPE_COMPUTE_CAP_SUBGROUP_SIZES:
243 RET((uint32_t []) { 32 });
244 case PIPE_COMPUTE_CAP_MAX_SUBGROUPS:
245 RET((uint32_t []) { 0 });
246 case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE:
247 RET((uint64_t []) { nouveau_device_get_global_mem_size(dev) });
248 case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED:
249 RET((uint32_t []) { NVC0_MAX_IMAGES });
250 case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:
251 RET((uint32_t []) { screen->mp_count_compute });
252 case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:
253 RET((uint32_t []) { 512 }); /* FIXME: arbitrary limit */
254 case PIPE_COMPUTE_CAP_ADDRESS_BITS:
255 RET((uint32_t []) { 64 });
256 default:
257 return 0;
258 }
259
260 #undef RET
261 }
262
263 static void
nvc0_init_screen_caps(struct nvc0_screen * screen)264 nvc0_init_screen_caps(struct nvc0_screen *screen)
265 {
266 struct pipe_caps *caps = (struct pipe_caps *)&screen->base.base.caps;
267
268 u_init_pipe_screen_caps(&screen->base.base, 1);
269
270 const uint16_t class_3d = screen->base.class_3d;
271 struct nouveau_device *dev = screen->base.device;
272
273 /* non-boolean caps */
274 caps->max_texture_2d_size = 16384;
275 caps->max_texture_cube_levels = 15;
276 caps->max_texture_3d_levels = 12;
277 caps->max_texture_array_layers = 2048;
278 caps->min_texel_offset = -8;
279 caps->max_texel_offset = 7;
280 caps->min_texture_gather_offset = -32;
281 caps->max_texture_gather_offset = 31;
282 caps->max_texel_buffer_elements = 128 * 1024 * 1024;
283 caps->glsl_feature_level = 430;
284 caps->glsl_feature_level_compatibility = 430;
285 caps->max_render_targets = 8;
286 caps->max_dual_source_render_targets = 1;
287 caps->viewport_subpixel_bits =
288 caps->rasterizer_subpixel_bits = 8;
289 caps->max_stream_output_buffers = 4;
290 caps->max_stream_output_separate_components =
291 caps->max_stream_output_interleaved_components = 128;
292 caps->max_geometry_output_vertices =
293 caps->max_geometry_total_output_components = 1024;
294 caps->max_vertex_streams = 4;
295 caps->max_gs_invocations = 32;
296 caps->max_shader_buffer_size = 1 << 27;
297 caps->max_vertex_attrib_stride = 2048;
298 caps->max_vertex_element_src_offset = 2047;
299 caps->constant_buffer_offset_alignment = 256;
300 caps->texture_buffer_offset_alignment = class_3d < GM107_3D_CLASS ?
301 256 /* IMAGE bindings require alignment to 256 */ : 16;
302 caps->shader_buffer_offset_alignment = 16;
303 caps->min_map_buffer_alignment = NOUVEAU_MIN_BUFFER_MAP_ALIGN;
304 caps->max_viewports = NVC0_MAX_VIEWPORTS;
305 caps->max_texture_gather_components = 4;
306 caps->texture_border_color_quirk = PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50;
307 caps->endianness = PIPE_ENDIAN_LITTLE;
308 caps->max_shader_patch_varyings = 30;
309 caps->max_window_rectangles = NVC0_MAX_WINDOW_RECTANGLES;
310 caps->max_conservative_raster_subpixel_precision_bias = class_3d >= GM200_3D_CLASS ? 8 : 0;
311 caps->max_texture_upload_memory_budget = 64 * 1024 * 1024;
312 /* NOTE: These only count our slots for GENERIC varyings.
313 * The address space may be larger, but the actual hard limit seems to be
314 * less than what the address space layout permits, so don't add TEXCOORD,
315 * COLOR, etc. here.
316 */
317 caps->max_varyings = 0x1f0 / 16;
318 caps->max_vertex_buffers = 16;
319 caps->gl_begin_end_buffer_size = 512 * 1024; /* TODO: Investigate tuning this */
320 caps->max_texture_mb = 0; /* TODO: use 1/2 of VRAM for this? */
321
322 caps->timer_resolution = 1000;
323
324 caps->supported_prim_modes_with_restart =
325 caps->supported_prim_modes = BITFIELD_MASK(MESA_PRIM_COUNT);
326
327 /* supported caps */
328 caps->texture_mirror_clamp = true;
329 caps->texture_mirror_clamp_to_edge = true;
330 caps->texture_swizzle = true;
331 caps->npot_textures = true;
332 caps->mixed_framebuffer_sizes = true;
333 caps->mixed_color_depth_bits = true;
334 caps->anisotropic_filter = true;
335 caps->seamless_cube_map = true;
336 caps->cube_map_array = true;
337 caps->texture_buffer_objects = true;
338 caps->texture_multisample = true;
339 caps->depth_clip_disable = true;
340 caps->tgsi_texcoord = true;
341 caps->fragment_shader_texture_lod = true;
342 caps->fragment_shader_derivatives = true;
343 caps->fragment_color_clamped = true;
344 caps->vertex_color_unclamped = true;
345 caps->vertex_color_clamped = true;
346 caps->query_timestamp = true;
347 caps->query_time_elapsed = true;
348 caps->occlusion_query = true;
349 caps->stream_output_pause_resume = true;
350 caps->stream_output_interleave_buffers = true;
351 caps->query_pipeline_statistics = true;
352 caps->blend_equation_separate = true;
353 caps->indep_blend_enable = true;
354 caps->indep_blend_func = true;
355 caps->fs_coord_origin_upper_left = true;
356 caps->fs_coord_pixel_center_half_integer = true;
357 caps->primitive_restart = true;
358 caps->primitive_restart_fixed_index = true;
359 caps->vs_instanceid = true;
360 caps->vertex_element_instance_divisor = true;
361 caps->conditional_render = true;
362 caps->texture_barrier = true;
363 caps->quads_follow_provoking_vertex_convention = true;
364 caps->start_instance = true;
365 caps->draw_indirect = true;
366 caps->user_vertex_buffers = true;
367 caps->texture_query_lod = true;
368 caps->sample_shading = true;
369 caps->texture_gather_offsets = true;
370 caps->texture_gather_sm5 = true;
371 caps->fs_fine_derivative = true;
372 caps->conditional_render_inverted = true;
373 caps->sampler_view_target = true;
374 caps->clip_halfz = true;
375 caps->polygon_offset_clamp = true;
376 caps->multisample_z_resolve = true;
377 caps->texture_float_linear = true;
378 caps->texture_half_float_linear = true;
379 caps->depth_bounds_test = true;
380 caps->texture_query_samples = true;
381 caps->copy_between_compressed_and_plain_formats = true;
382 caps->force_persample_interp = true;
383 caps->draw_parameters = true;
384 caps->shader_pack_half_float = true;
385 caps->multi_draw_indirect = true;
386 caps->memobj = true;
387 caps->multi_draw_indirect_params = true;
388 caps->fs_face_is_integer_sysval = true;
389 caps->query_buffer_object = true;
390 caps->invalidate_buffer = true;
391 caps->string_marker = true;
392 caps->framebuffer_no_attachment = true;
393 caps->cull_distance = true;
394 caps->robust_buffer_access_behavior = true;
395 caps->shader_group_vote = true;
396 caps->polygon_offset_units_unscaled = true;
397 caps->shader_array_components = true;
398 caps->legacy_math_rules = true;
399 caps->doubles = true;
400 caps->int64 = true;
401 caps->tgsi_tex_txf_lz = true;
402 caps->shader_clock = true;
403 caps->compute = true;
404 caps->can_bind_const_buffer_as_vertex = true;
405 caps->query_so_overflow = true;
406 caps->tgsi_div = true;
407 caps->image_atomic_inc_wrap = true;
408 caps->demote_to_helper_invocation = true;
409 caps->device_reset_status_query = true;
410 caps->texture_shadow_lod = true;
411 caps->clear_scissored = true;
412 caps->image_store_formatted = true;
413 caps->query_memory_info = true;
414 caps->texture_transfer_modes =
415 screen->base.vram_domain & NOUVEAU_BO_VRAM ? PIPE_TEXTURE_TRANSFER_BLIT : 0;
416 caps->fbfetch = class_3d >= NVE4_3D_CLASS ? 1 : 0; /* needs testing on fermi */
417 caps->seamless_cube_map_per_texture =
418 caps->shader_ballot = class_3d >= NVE4_3D_CLASS;
419 caps->bindless_texture = class_3d >= NVE4_3D_CLASS;
420 caps->image_atomic_float_add = class_3d < GM107_3D_CLASS; /* needs additional lowering */
421 caps->polygon_mode_fill_rectangle =
422 caps->vs_layer_viewport =
423 caps->tes_layer_viewport =
424 caps->post_depth_coverage =
425 caps->conservative_raster_post_snap_triangles =
426 caps->conservative_raster_post_snap_points_lines =
427 caps->conservative_raster_post_depth_coverage =
428 caps->programmable_sample_locations =
429 caps->viewport_swizzle =
430 caps->viewport_mask =
431 caps->sampler_reduction_minmax = class_3d >= GM200_3D_CLASS;
432 caps->conservative_raster_pre_snap_triangles = class_3d >= GP100_3D_CLASS;
433 caps->resource_from_user_memory_compute_only =
434 caps->system_svm = screen->base.has_svm;
435
436 caps->gl_spirv = true;
437 caps->gl_spirv_variable_pointers = true;
438
439 /* nir related caps */
440 caps->nir_images_as_deref = false;
441
442 caps->pci_group = dev->info.pci.domain;
443 caps->pci_bus = dev->info.pci.bus;
444 caps->pci_device = dev->info.pci.dev;
445 caps->pci_function = dev->info.pci.func;
446
447 caps->opencl_integer_functions = false; /* could be done */
448 caps->integer_multiply_32x16 = false; /* could be done */
449 caps->map_unsynchronized_thread_safe = false; /* when we fix MT stuff */
450 caps->alpha_to_coverage_dither_control = false; /* TODO */
451 caps->shader_atomic_int64 = false; /* TODO */
452 caps->hardware_gl_select = false;
453
454 caps->vendor_id = 0x10de;
455 caps->device_id = dev->info.device_id;
456 caps->video_memory = dev->vram_size >> 20;
457 caps->uma = screen->base.is_uma;
458
459 caps->min_line_width =
460 caps->min_line_width_aa =
461 caps->min_point_size =
462 caps->min_point_size_aa = 1;
463 caps->point_size_granularity =
464 caps->line_width_granularity = 0.1;
465 caps->max_line_width =
466 caps->max_line_width_aa = 10.0f;
467 caps->max_point_size = 63.0f;
468 caps->max_point_size_aa = 63.375f;
469 caps->max_texture_anisotropy = 16.0f;
470 caps->max_texture_lod_bias = 15.0f;
471 caps->min_conservative_raster_dilate = 0.0f;
472 caps->max_conservative_raster_dilate = class_3d >= GM200_3D_CLASS ? 0.75f : 0.0f;
473 caps->conservative_raster_dilate_granularity = class_3d >= GM200_3D_CLASS ? 0.25f : 0.0f;
474 }
475
476 static void
nvc0_screen_get_sample_pixel_grid(struct pipe_screen * pscreen,unsigned sample_count,unsigned * width,unsigned * height)477 nvc0_screen_get_sample_pixel_grid(struct pipe_screen *pscreen,
478 unsigned sample_count,
479 unsigned *width, unsigned *height)
480 {
481 switch (sample_count) {
482 case 0:
483 case 1:
484 /* this could be 4x4, but the GL state tracker makes it difficult to
485 * create a 1x MSAA texture and smaller grids save CB space */
486 *width = 2;
487 *height = 4;
488 break;
489 case 2:
490 *width = 2;
491 *height = 4;
492 break;
493 case 4:
494 *width = 2;
495 *height = 2;
496 break;
497 case 8:
498 *width = 1;
499 *height = 2;
500 break;
501 default:
502 assert(0);
503 }
504 }
505
506 static void
nvc0_screen_destroy(struct pipe_screen * pscreen)507 nvc0_screen_destroy(struct pipe_screen *pscreen)
508 {
509 struct nvc0_screen *screen = nvc0_screen(pscreen);
510
511 if (!screen->base.initialized)
512 return;
513
514 if (screen->blitter)
515 nvc0_blitter_destroy(screen);
516 if (screen->pm.prog) {
517 screen->pm.prog->code = NULL; /* hardcoded, don't FREE */
518 nvc0_program_destroy(NULL, screen->pm.prog);
519 FREE(screen->pm.prog);
520 }
521
522 nouveau_bo_ref(NULL, &screen->text);
523 nouveau_bo_ref(NULL, &screen->uniform_bo);
524 nouveau_bo_ref(NULL, &screen->tls);
525 nouveau_bo_ref(NULL, &screen->txc);
526 nouveau_bo_ref(NULL, &screen->fence.bo);
527 nouveau_bo_ref(NULL, &screen->poly_cache);
528
529 nouveau_heap_free(&screen->lib_code);
530 nouveau_heap_destroy(&screen->text_heap);
531
532 FREE(screen->tic.entries);
533
534 nouveau_object_del(&screen->eng3d);
535 nouveau_object_del(&screen->eng2d);
536 nouveau_object_del(&screen->m2mf);
537 nouveau_object_del(&screen->copy);
538 nouveau_object_del(&screen->compute);
539 nouveau_object_del(&screen->nvsw);
540
541 nouveau_screen_fini(&screen->base);
542 simple_mtx_destroy(&screen->state_lock);
543
544 FREE(screen);
545 }
546
547 static int
nvc0_graph_set_macro(struct nvc0_screen * screen,uint32_t m,unsigned pos,unsigned size,const uint32_t * data)548 nvc0_graph_set_macro(struct nvc0_screen *screen, uint32_t m, unsigned pos,
549 unsigned size, const uint32_t *data)
550 {
551 struct nouveau_pushbuf *push = screen->base.pushbuf;
552
553 size /= 4;
554
555 assert((pos + size) <= 0x800);
556
557 BEGIN_NVC0(push, SUBC_3D(NVC0_GRAPH_MACRO_ID), 2);
558 PUSH_DATA (push, (m - 0x3800) / 8);
559 PUSH_DATA (push, pos);
560 BEGIN_1IC0(push, SUBC_3D(NVC0_GRAPH_MACRO_UPLOAD_POS), size + 1);
561 PUSH_DATA (push, pos);
562 PUSH_DATAp(push, data, size);
563
564 return pos + size;
565 }
566
567 static int
tu102_graph_set_macro(struct nvc0_screen * screen,uint32_t m,unsigned pos,unsigned size,const uint32_t * data)568 tu102_graph_set_macro(struct nvc0_screen *screen, uint32_t m, unsigned pos,
569 unsigned size, const uint32_t *data)
570 {
571 struct nouveau_pushbuf *push = screen->base.pushbuf;
572
573 size /= 4;
574
575 assert((pos + size) <= 0x800);
576
577 BEGIN_NVC0(push, SUBC_3D(NVC0_GRAPH_MACRO_ID), 2);
578 PUSH_DATA (push, (m - 0x3800) / 8);
579 PUSH_DATA (push, pos);
580 BEGIN_1IC0(push, SUBC_3D(NVC0_GRAPH_MACRO_UPLOAD_POS), size + 1);
581 PUSH_DATA (push, pos);
582 PUSH_DATAp(push, data, size);
583
584 return pos + (size / 3);
585 }
586
587 static void
nvc0_magic_3d_init(struct nouveau_pushbuf * push,uint16_t obj_class)588 nvc0_magic_3d_init(struct nouveau_pushbuf *push, uint16_t obj_class)
589 {
590 BEGIN_NVC0(push, SUBC_3D(0x10cc), 1);
591 PUSH_DATA (push, 0xff);
592 BEGIN_NVC0(push, SUBC_3D(0x10e0), 2);
593 PUSH_DATA (push, 0xff);
594 PUSH_DATA (push, 0xff);
595 BEGIN_NVC0(push, SUBC_3D(0x10ec), 2);
596 PUSH_DATA (push, 0xff);
597 PUSH_DATA (push, 0xff);
598 if (obj_class < GV100_3D_CLASS) {
599 BEGIN_NVC0(push, SUBC_3D(0x074c), 1);
600 PUSH_DATA (push, 0x3f);
601 }
602
603 BEGIN_NVC0(push, SUBC_3D(0x16a8), 1);
604 PUSH_DATA (push, (3 << 16) | 3);
605 BEGIN_NVC0(push, SUBC_3D(0x1794), 1);
606 PUSH_DATA (push, (2 << 16) | 2);
607
608 if (obj_class < GM107_3D_CLASS) {
609 BEGIN_NVC0(push, SUBC_3D(0x12ac), 1);
610 PUSH_DATA (push, 0);
611 }
612 BEGIN_NVC0(push, SUBC_3D(0x0218), 1);
613 PUSH_DATA (push, 0x10);
614 BEGIN_NVC0(push, SUBC_3D(0x10fc), 1);
615 PUSH_DATA (push, 0x10);
616 BEGIN_NVC0(push, SUBC_3D(0x1290), 1);
617 PUSH_DATA (push, 0x10);
618 BEGIN_NVC0(push, SUBC_3D(0x12d8), 2);
619 PUSH_DATA (push, 0x10);
620 PUSH_DATA (push, 0x10);
621 BEGIN_NVC0(push, SUBC_3D(0x1140), 1);
622 PUSH_DATA (push, 0x10);
623 BEGIN_NVC0(push, SUBC_3D(0x1610), 1);
624 PUSH_DATA (push, 0xe);
625
626 BEGIN_NVC0(push, NVC0_3D(VERTEX_ID_GEN_MODE), 1);
627 PUSH_DATA (push, NVC0_3D_VERTEX_ID_GEN_MODE_DRAW_ARRAYS_ADD_START);
628 BEGIN_NVC0(push, SUBC_3D(0x030c), 1);
629 PUSH_DATA (push, 0);
630 BEGIN_NVC0(push, SUBC_3D(0x0300), 1);
631 PUSH_DATA (push, 3);
632
633 if (obj_class < GV100_3D_CLASS) {
634 BEGIN_NVC0(push, SUBC_3D(0x02d0), 1);
635 PUSH_DATA (push, 0x3fffff);
636 }
637 BEGIN_NVC0(push, SUBC_3D(0x0fdc), 1);
638 PUSH_DATA (push, 1);
639 BEGIN_NVC0(push, SUBC_3D(0x19c0), 1);
640 PUSH_DATA (push, 1);
641
642 if (obj_class < GM107_3D_CLASS) {
643 BEGIN_NVC0(push, SUBC_3D(0x075c), 1);
644 PUSH_DATA (push, 3);
645
646 if (obj_class >= NVE4_3D_CLASS) {
647 BEGIN_NVC0(push, SUBC_3D(0x07fc), 1);
648 PUSH_DATA (push, 1);
649 }
650 }
651
652 /* TODO: find out what software methods 0x1528, 0x1280 and (on nve4) 0x02dc
653 * are supposed to do */
654 }
655
656 static void
nvc0_screen_fence_emit(struct pipe_context * pcontext,u32 * sequence,struct nouveau_bo * wait)657 nvc0_screen_fence_emit(struct pipe_context *pcontext, u32 *sequence,
658 struct nouveau_bo *wait)
659 {
660 struct nvc0_context *nvc0 = nvc0_context(pcontext);
661 struct nvc0_screen *screen = nvc0->screen;
662 struct nouveau_pushbuf *push = nvc0->base.pushbuf;
663 struct nouveau_pushbuf_refn ref = { wait, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR };
664
665 /* we need to do it after possible flush in MARK_RING */
666 *sequence = ++screen->base.fence.sequence;
667
668 assert(PUSH_AVAIL(push) + push->rsvd_kick >= 5);
669 PUSH_DATA (push, NVC0_FIFO_PKHDR_SQ(NVC0_3D(QUERY_ADDRESS_HIGH), 4));
670 PUSH_DATAh(push, screen->fence.bo->offset);
671 PUSH_DATA (push, screen->fence.bo->offset);
672 PUSH_DATA (push, *sequence);
673 PUSH_DATA (push, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT |
674 (0xf << NVC0_3D_QUERY_GET_UNIT__SHIFT));
675
676 nouveau_pushbuf_refn(push, &ref, 1);
677 }
678
679 static u32
nvc0_screen_fence_update(struct pipe_screen * pscreen)680 nvc0_screen_fence_update(struct pipe_screen *pscreen)
681 {
682 struct nvc0_screen *screen = nvc0_screen(pscreen);
683 return screen->fence.map[0];
684 }
685
686 static int
nvc0_screen_init_compute(struct nvc0_screen * screen)687 nvc0_screen_init_compute(struct nvc0_screen *screen)
688 {
689 const struct nouveau_mclass computes[] = {
690 { AD102_COMPUTE_CLASS, -1 },
691 { GA102_COMPUTE_CLASS, -1 },
692 { TU102_COMPUTE_CLASS, -1 },
693 { GV100_COMPUTE_CLASS, -1 },
694 { GP104_COMPUTE_CLASS, -1 },
695 { GP100_COMPUTE_CLASS, -1 },
696 { GM200_COMPUTE_CLASS, -1 },
697 { GM107_COMPUTE_CLASS, -1 },
698 { NVF0_COMPUTE_CLASS, -1 },
699 { NVE4_COMPUTE_CLASS, -1 },
700 /* In theory, GF110+ should also support NVC8_COMPUTE_CLASS but,
701 * in practice, a ILLEGAL_CLASS dmesg fail appears when using it. */
702 // { NVC8_COMPUTE_CLASS, -1 },
703 { NVC0_COMPUTE_CLASS, -1 },
704 {}
705 };
706 struct nouveau_object *chan = screen->base.channel;
707 int ret;
708
709 screen->base.base.get_compute_param = nvc0_screen_get_compute_param;
710
711 ret = nouveau_object_mclass(chan, computes);
712 if (ret < 0) {
713 NOUVEAU_ERR("No supported compute class: %d\n", ret);
714 return ret;
715 }
716
717 ret = nouveau_object_new(chan, 0xbeef00c0, computes[ret].oclass, NULL, 0, &screen->compute);
718 if (ret) {
719 NOUVEAU_ERR("Failed to allocate compute class: %d\n", ret);
720 return ret;
721 }
722
723 if (screen->compute->oclass < NVE4_COMPUTE_CLASS)
724 return nvc0_screen_compute_setup(screen, screen->base.pushbuf);
725
726 return nve4_screen_compute_setup(screen, screen->base.pushbuf);
727 }
728
729 static int
nvc0_screen_resize_tls_area(struct nvc0_screen * screen,uint32_t lpos,uint32_t lneg,uint32_t cstack)730 nvc0_screen_resize_tls_area(struct nvc0_screen *screen,
731 uint32_t lpos, uint32_t lneg, uint32_t cstack)
732 {
733 struct nouveau_bo *bo = NULL;
734 int ret;
735 uint64_t size = (lpos + lneg) * 32 + cstack;
736
737 if (size >= (1 << 20)) {
738 NOUVEAU_ERR("requested TLS size too large: 0x%"PRIx64"\n", size);
739 return -1;
740 }
741
742 size *= (screen->base.device->chipset >= 0xe0) ? 64 : 48; /* max warps */
743 size = align(size, 0x8000);
744 size *= screen->mp_count;
745
746 size = align(size, 1 << 17);
747
748 ret = nouveau_bo_new(screen->base.device, NV_VRAM_DOMAIN(&screen->base), 1 << 17, size,
749 NULL, &bo);
750 if (ret)
751 return ret;
752
753 /* Make sure that the pushbuf has acquired a reference to the old tls
754 * segment, as it may have commands that will reference it.
755 */
756 if (screen->tls)
757 PUSH_REF1(screen->base.pushbuf, screen->tls,
758 NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RDWR);
759 nouveau_bo_ref(NULL, &screen->tls);
760 screen->tls = bo;
761 return 0;
762 }
763
764 int
nvc0_screen_resize_text_area(struct nvc0_screen * screen,struct nouveau_pushbuf * push,uint64_t size)765 nvc0_screen_resize_text_area(struct nvc0_screen *screen, struct nouveau_pushbuf *push,
766 uint64_t size)
767 {
768 struct nouveau_bo *bo;
769 int ret;
770
771 ret = nouveau_bo_new(screen->base.device, NV_VRAM_DOMAIN(&screen->base),
772 1 << 17, size, NULL, &bo);
773 if (ret)
774 return ret;
775
776 /* Make sure that the pushbuf has acquired a reference to the old text
777 * segment, as it may have commands that will reference it.
778 */
779 if (screen->text)
780 PUSH_REF1(screen->base.pushbuf, screen->text,
781 NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD);
782 nouveau_bo_ref(NULL, &screen->text);
783 screen->text = bo;
784
785 nouveau_heap_free(&screen->lib_code);
786 nouveau_heap_destroy(&screen->text_heap);
787
788 /*
789 * Shader storage needs a 2K (from NVIDIA) overallocations at the end
790 * to avoid prefetch bugs.
791 */
792 nouveau_heap_init(&screen->text_heap, 0, size - 0x800);
793
794 /* update the code segment setup */
795 if (screen->eng3d->oclass < GV100_3D_CLASS) {
796 BEGIN_NVC0(push, NVC0_3D(CODE_ADDRESS_HIGH), 2);
797 PUSH_DATAh(push, screen->text->offset);
798 PUSH_DATA (push, screen->text->offset);
799 if (screen->compute) {
800 BEGIN_NVC0(push, NVC0_CP(CODE_ADDRESS_HIGH), 2);
801 PUSH_DATAh(push, screen->text->offset);
802 PUSH_DATA (push, screen->text->offset);
803 }
804 }
805
806 return 0;
807 }
808
809 void
nvc0_screen_bind_cb_3d(struct nvc0_screen * screen,struct nouveau_pushbuf * push,bool * can_serialize,int stage,int index,int size,uint64_t addr)810 nvc0_screen_bind_cb_3d(struct nvc0_screen *screen, struct nouveau_pushbuf *push,
811 bool *can_serialize, int stage, int index, int size, uint64_t addr)
812 {
813 assert(stage != 5);
814
815 if (screen->base.class_3d >= GM107_3D_CLASS) {
816 struct nvc0_cb_binding *binding = &screen->cb_bindings[stage][index];
817
818 // TODO: Better figure out the conditions in which this is needed
819 bool serialize = binding->addr == addr && binding->size != size;
820 if (can_serialize)
821 serialize = serialize && *can_serialize;
822 if (serialize) {
823 IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
824 if (can_serialize)
825 *can_serialize = false;
826 }
827
828 binding->addr = addr;
829 binding->size = size;
830 }
831
832 if (size >= 0) {
833 BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
834 PUSH_DATA (push, size);
835 PUSH_DATAh(push, addr);
836 PUSH_DATA (push, addr);
837 }
838 IMMED_NVC0(push, NVC0_3D(CB_BIND(stage)), (index << 4) | (size >= 0));
839 }
840
841 static const void *
nvc0_screen_get_compiler_options(struct pipe_screen * pscreen,enum pipe_shader_ir ir,enum pipe_shader_type shader)842 nvc0_screen_get_compiler_options(struct pipe_screen *pscreen,
843 enum pipe_shader_ir ir,
844 enum pipe_shader_type shader)
845 {
846 struct nvc0_screen *screen = nvc0_screen(pscreen);
847 if (ir == PIPE_SHADER_IR_NIR)
848 return nv50_ir_nir_shader_compiler_options(screen->base.device->chipset, shader);
849 return NULL;
850 }
851
852 #define FAIL_SCREEN_INIT(str, err) \
853 do { \
854 NOUVEAU_ERR(str, err); \
855 goto fail; \
856 } while(0)
857
858 struct nouveau_screen *
nvc0_screen_create(struct nouveau_device * dev)859 nvc0_screen_create(struct nouveau_device *dev)
860 {
861 struct nvc0_screen *screen;
862 struct pipe_screen *pscreen;
863 struct nouveau_object *chan;
864
865 struct nouveau_pushbuf *push;
866 uint64_t value;
867 uint32_t flags;
868 int ret;
869 unsigned i;
870
871 switch (dev->chipset & ~0xf) {
872 case 0xc0:
873 case 0xd0:
874 case 0xe0:
875 case 0xf0:
876 case 0x100:
877 case 0x110:
878 case 0x120:
879 case 0x130:
880 case 0x140:
881 case 0x160:
882 case 0x170:
883 case 0x190:
884 break;
885 default:
886 return NULL;
887 }
888
889 screen = CALLOC_STRUCT(nvc0_screen);
890 if (!screen)
891 return NULL;
892 pscreen = &screen->base.base;
893 pscreen->destroy = nvc0_screen_destroy;
894
895 simple_mtx_init(&screen->state_lock, mtx_plain);
896
897 ret = nouveau_screen_init(&screen->base, dev);
898 if (ret)
899 FAIL_SCREEN_INIT("Base screen init failed: %d\n", ret);
900 chan = screen->base.channel;
901 push = screen->base.pushbuf;
902 push->rsvd_kick = 5;
903
904 /* TODO: could this be higher on Kepler+? how does reclocking vs no
905 * reclocking affect performance?
906 * TODO: could this be higher on Fermi?
907 */
908 if (dev->chipset >= 0xe0)
909 screen->base.transfer_pushbuf_threshold = 1024;
910
911 screen->base.vidmem_bindings |= PIPE_BIND_CONSTANT_BUFFER |
912 PIPE_BIND_SHADER_BUFFER |
913 PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER |
914 PIPE_BIND_COMMAND_ARGS_BUFFER | PIPE_BIND_QUERY_BUFFER;
915 screen->base.sysmem_bindings |=
916 PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER;
917
918 if (screen->base.vram_domain & NOUVEAU_BO_GART) {
919 screen->base.sysmem_bindings |= screen->base.vidmem_bindings;
920 screen->base.vidmem_bindings = 0;
921 }
922
923 pscreen->context_create = nvc0_create;
924 pscreen->is_format_supported = nvc0_screen_is_format_supported;
925 pscreen->get_shader_param = nvc0_screen_get_shader_param;
926 pscreen->get_sample_pixel_grid = nvc0_screen_get_sample_pixel_grid;
927 pscreen->get_driver_query_info = nvc0_screen_get_driver_query_info;
928 pscreen->get_driver_query_group_info = nvc0_screen_get_driver_query_group_info;
929 /* nir stuff */
930 pscreen->get_compiler_options = nvc0_screen_get_compiler_options;
931
932 nvc0_screen_init_resource_functions(pscreen);
933
934 screen->base.base.get_video_param = nouveau_vp3_screen_get_video_param;
935 screen->base.base.is_video_format_supported = nouveau_vp3_screen_video_supported;
936
937 flags = NOUVEAU_BO_GART | NOUVEAU_BO_MAP;
938 if (screen->base.drm->version >= 0x01000202)
939 flags |= NOUVEAU_BO_COHERENT;
940
941 ret = nouveau_bo_new(dev, flags, 0, 4096, NULL, &screen->fence.bo);
942 if (ret)
943 FAIL_SCREEN_INIT("Error allocating fence BO: %d\n", ret);
944 BO_MAP(&screen->base, screen->fence.bo, 0, NULL);
945 screen->fence.map = screen->fence.bo->map;
946 screen->base.fence.emit = nvc0_screen_fence_emit;
947 screen->base.fence.update = nvc0_screen_fence_update;
948
949 if (dev->chipset < 0x140) {
950 ret = nouveau_object_new(chan, (dev->chipset < 0xe0) ? 0x1f906e : 0x906e,
951 NVIF_CLASS_SW_GF100, NULL, 0, &screen->nvsw);
952 if (ret)
953 FAIL_SCREEN_INIT("Error creating SW object: %d\n", ret);
954
955 BEGIN_NVC0(push, SUBC_SW(NV01_SUBCHAN_OBJECT), 1);
956 PUSH_DATA (push, screen->nvsw->handle);
957 }
958
959 const struct nouveau_mclass m2mfs[] = {
960 { NVF0_P2MF_CLASS, -1 },
961 { NVE4_P2MF_CLASS, -1 },
962 { NVC0_M2MF_CLASS, -1 },
963 {}
964 };
965
966 ret = nouveau_object_mclass(chan, m2mfs);
967 if (ret < 0)
968 FAIL_SCREEN_INIT("No supported m2mf class: %d\n", ret);
969
970 ret = nouveau_object_new(chan, 0xbeef323f, m2mfs[ret].oclass, NULL, 0,
971 &screen->m2mf);
972 if (ret)
973 FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret);
974
975 BEGIN_NVC0(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1);
976 PUSH_DATA (push, screen->m2mf->oclass);
977
978 if (screen->m2mf->oclass >= NVE4_P2MF_CLASS) {
979 const struct nouveau_mclass copys[] = {
980 { AMPERE_DMA_COPY_B, -1 },
981 { AMPERE_DMA_COPY_A, -1 },
982 { TURING_DMA_COPY_A, -1 },
983 { VOLTA_DMA_COPY_A, -1 },
984 { PASCAL_DMA_COPY_B, -1 },
985 { PASCAL_DMA_COPY_A, -1 },
986 { MAXWELL_DMA_COPY_A, -1 },
987 { KEPLER_DMA_COPY_A, -1 },
988 {}
989 };
990
991 ret = nouveau_object_mclass(chan, copys);
992 if (ret < 0)
993 FAIL_SCREEN_INIT("No supported copy engine class: %d\n", ret);
994
995 ret = nouveau_object_new(chan, 0, copys[ret].oclass, NULL, 0, &screen->copy);
996 if (ret)
997 FAIL_SCREEN_INIT("Error allocating copy engine class: %d\n", ret);
998
999 BEGIN_NVC0(push, SUBC_COPY(NV01_SUBCHAN_OBJECT), 1);
1000 PUSH_DATA (push, screen->copy->oclass);
1001 }
1002
1003 ret = nouveau_object_new(chan, 0xbeef902d, NVC0_2D_CLASS, NULL, 0,
1004 &screen->eng2d);
1005 if (ret)
1006 FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret);
1007
1008 BEGIN_NVC0(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1);
1009 PUSH_DATA (push, screen->eng2d->oclass);
1010 BEGIN_NVC0(push, SUBC_2D(NVC0_2D_SINGLE_GPC), 1);
1011 PUSH_DATA (push, 0);
1012 BEGIN_NVC0(push, NVC0_2D(OPERATION), 1);
1013 PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY);
1014 BEGIN_NVC0(push, NVC0_2D(CLIP_ENABLE), 1);
1015 PUSH_DATA (push, 0);
1016 BEGIN_NVC0(push, NVC0_2D(COLOR_KEY_ENABLE), 1);
1017 PUSH_DATA (push, 0);
1018 BEGIN_NVC0(push, NVC0_2D(SET_PIXELS_FROM_MEMORY_CORRAL_SIZE), 1);
1019 PUSH_DATA (push, 0x3f);
1020 BEGIN_NVC0(push, NVC0_2D(SET_PIXELS_FROM_MEMORY_SAFE_OVERLAP), 1);
1021 PUSH_DATA (push, 1);
1022 BEGIN_NVC0(push, NVC0_2D(COND_MODE), 1);
1023 PUSH_DATA (push, NV50_2D_COND_MODE_ALWAYS);
1024
1025 BEGIN_NVC0(push, SUBC_2D(NVC0_GRAPH_NOTIFY_ADDRESS_HIGH), 2);
1026 PUSH_DATAh(push, screen->fence.bo->offset + 16);
1027 PUSH_DATA (push, screen->fence.bo->offset + 16);
1028
1029 const struct nouveau_mclass threeds[] = {
1030 { AD102_3D_CLASS, -1 },
1031 { GA102_3D_CLASS, -1 },
1032 { TU102_3D_CLASS, -1 },
1033 { GV100_3D_CLASS, -1 },
1034 { GP102_3D_CLASS, -1 },
1035 { GP100_3D_CLASS, -1 },
1036 { GM200_3D_CLASS, -1 },
1037 { GM107_3D_CLASS, -1 },
1038 { NVF0_3D_CLASS, -1 },
1039 { NVEA_3D_CLASS, -1 },
1040 { NVE4_3D_CLASS, -1 },
1041 { NVC8_3D_CLASS, -1 },
1042 { NVC1_3D_CLASS, -1 },
1043 { NVC0_3D_CLASS, -1 },
1044 {}
1045 };
1046
1047 ret = nouveau_object_mclass(chan, threeds);
1048 if (ret < 0)
1049 FAIL_SCREEN_INIT("No supported 3d class: %d\n", ret);
1050
1051 ret = nouveau_object_new(chan, 0xbeef003d, threeds[ret].oclass, NULL, 0,
1052 &screen->eng3d);
1053 if (ret)
1054 FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret);
1055 screen->base.class_3d = screen->eng3d->oclass;
1056
1057 nvc0_init_screen_caps(screen);
1058
1059 BEGIN_NVC0(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1);
1060 PUSH_DATA (push, screen->eng3d->oclass);
1061
1062 BEGIN_NVC0(push, NVC0_3D(COND_MODE), 1);
1063 PUSH_DATA (push, NVC0_3D_COND_MODE_ALWAYS);
1064
1065 if (debug_get_bool_option("NOUVEAU_SHADER_WATCHDOG", true)) {
1066 /* kill shaders after about 1 second (at 100 MHz) */
1067 BEGIN_NVC0(push, NVC0_3D(WATCHDOG_TIMER), 1);
1068 PUSH_DATA (push, 0x17);
1069 }
1070
1071 IMMED_NVC0(push, NVC0_3D(ZETA_COMP_ENABLE),
1072 screen->base.drm->version >= 0x01000101);
1073 BEGIN_NVC0(push, NVC0_3D(RT_COMP_ENABLE(0)), 8);
1074 for (i = 0; i < 8; ++i)
1075 PUSH_DATA(push, screen->base.drm->version >= 0x01000101);
1076
1077 BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1);
1078 PUSH_DATA (push, 1);
1079
1080 BEGIN_NVC0(push, NVC0_3D(CSAA_ENABLE), 1);
1081 PUSH_DATA (push, 0);
1082 BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_ENABLE), 1);
1083 PUSH_DATA (push, 0);
1084 BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 1);
1085 PUSH_DATA (push, NVC0_3D_MULTISAMPLE_MODE_MS1);
1086 BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_CTRL), 1);
1087 PUSH_DATA (push, 0);
1088 BEGIN_NVC0(push, NVC0_3D(LINE_WIDTH_SEPARATE), 1);
1089 PUSH_DATA (push, 1);
1090 BEGIN_NVC0(push, NVC0_3D(PRIM_RESTART_WITH_DRAW_ARRAYS), 1);
1091 PUSH_DATA (push, 1);
1092 BEGIN_NVC0(push, NVC0_3D(BLEND_SEPARATE_ALPHA), 1);
1093 PUSH_DATA (push, 1);
1094 BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE_COMMON), 1);
1095 PUSH_DATA (push, 0);
1096 BEGIN_NVC0(push, NVC0_3D(SHADE_MODEL), 1);
1097 PUSH_DATA (push, NVC0_3D_SHADE_MODEL_SMOOTH);
1098 if (screen->eng3d->oclass < NVE4_3D_CLASS) {
1099 IMMED_NVC0(push, NVC0_3D(TEX_MISC), 0);
1100 } else if (screen->eng3d->oclass < GA102_3D_CLASS) {
1101 BEGIN_NVC0(push, NVE4_3D(TEX_CB_INDEX), 1);
1102 PUSH_DATA (push, 15);
1103 }
1104 BEGIN_NVC0(push, NVC0_3D(CALL_LIMIT_LOG), 1);
1105 PUSH_DATA (push, 8); /* 128 */
1106 BEGIN_NVC0(push, NVC0_3D(ZCULL_STATCTRS_ENABLE), 1);
1107 PUSH_DATA (push, 1);
1108 if (screen->eng3d->oclass >= NVC1_3D_CLASS) {
1109 BEGIN_NVC0(push, NVC0_3D(CACHE_SPLIT), 1);
1110 PUSH_DATA (push, NVC0_3D_CACHE_SPLIT_48K_SHARED_16K_L1);
1111 }
1112
1113 nvc0_magic_3d_init(push, screen->eng3d->oclass);
1114
1115 ret = nvc0_screen_resize_text_area(screen, push, 1 << 19);
1116 if (ret)
1117 FAIL_SCREEN_INIT("Error allocating TEXT area: %d\n", ret);
1118
1119 /* 6 user uniform areas, 6 driver areas, and 1 for the runout */
1120 ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 1 << 12, 13 << 16, NULL,
1121 &screen->uniform_bo);
1122 if (ret)
1123 FAIL_SCREEN_INIT("Error allocating uniform BO: %d\n", ret);
1124
1125 PUSH_REF1 (push, screen->uniform_bo, NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_WR);
1126
1127 /* return { 0.0, 0.0, 0.0, 0.0 } for out-of-bounds vtxbuf access */
1128 BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
1129 PUSH_DATA (push, 256);
1130 PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_RUNOUT_INFO);
1131 PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_RUNOUT_INFO);
1132 BEGIN_1IC0(push, NVC0_3D(CB_POS), 5);
1133 PUSH_DATA (push, 0);
1134 PUSH_DATAf(push, 0.0f);
1135 PUSH_DATAf(push, 0.0f);
1136 PUSH_DATAf(push, 0.0f);
1137 PUSH_DATAf(push, 0.0f);
1138 BEGIN_NVC0(push, NVC0_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2);
1139 PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_RUNOUT_INFO);
1140 PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_RUNOUT_INFO);
1141
1142 if (screen->base.drm->version >= 0x01000101) {
1143 ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
1144 if (ret)
1145 FAIL_SCREEN_INIT("NOUVEAU_GETPARAM_GRAPH_UNITS failed: %d\n", ret);
1146 } else {
1147 if (dev->chipset >= 0xe0 && dev->chipset < 0xf0)
1148 value = (8 << 8) | 4;
1149 else
1150 value = (16 << 8) | 4;
1151 }
1152 screen->gpc_count = value & 0x000000ff;
1153 screen->mp_count = value >> 8;
1154 screen->mp_count_compute = screen->mp_count;
1155
1156 ret = nvc0_screen_resize_tls_area(screen, 128 * 16, 0, 0x200);
1157 if (ret)
1158 FAIL_SCREEN_INIT("Error allocating TLS area: %d\n", ret);
1159
1160 BEGIN_NVC0(push, NVC0_3D(TEMP_ADDRESS_HIGH), 4);
1161 PUSH_DATAh(push, screen->tls->offset);
1162 PUSH_DATA (push, screen->tls->offset);
1163 PUSH_DATA (push, screen->tls->size >> 32);
1164 PUSH_DATA (push, screen->tls->size);
1165 BEGIN_NVC0(push, NVC0_3D(WARP_TEMP_ALLOC), 1);
1166 PUSH_DATA (push, 0);
1167 /* Reduce likelihood of collision with real buffers by placing the hole at
1168 * the top of the 4G area. This will have to be dealt with for real
1169 * eventually by blocking off that area from the VM.
1170 */
1171 BEGIN_NVC0(push, NVC0_3D(LOCAL_BASE), 1);
1172 PUSH_DATA (push, 0xff << 24);
1173
1174 if (screen->eng3d->oclass < GM107_3D_CLASS) {
1175 ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 1 << 17, 1 << 20, NULL,
1176 &screen->poly_cache);
1177 if (ret)
1178 FAIL_SCREEN_INIT("Error allocating poly cache BO: %d\n", ret);
1179
1180 BEGIN_NVC0(push, NVC0_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3);
1181 PUSH_DATAh(push, screen->poly_cache->offset);
1182 PUSH_DATA (push, screen->poly_cache->offset);
1183 PUSH_DATA (push, 3);
1184 }
1185
1186 ret = nouveau_bo_new(dev, NV_VRAM_DOMAIN(&screen->base), 1 << 17, 1 << 17, NULL,
1187 &screen->txc);
1188 if (ret)
1189 FAIL_SCREEN_INIT("Error allocating txc BO: %d\n", ret);
1190
1191 BEGIN_NVC0(push, NVC0_3D(TIC_ADDRESS_HIGH), 3);
1192 PUSH_DATAh(push, screen->txc->offset);
1193 PUSH_DATA (push, screen->txc->offset);
1194 PUSH_DATA (push, NVC0_TIC_MAX_ENTRIES - 1);
1195 if (screen->eng3d->oclass >= GM107_3D_CLASS) {
1196 screen->tic.maxwell = true;
1197 if (screen->eng3d->oclass == GM107_3D_CLASS) {
1198 screen->tic.maxwell =
1199 debug_get_bool_option("NOUVEAU_MAXWELL_TIC", true);
1200 IMMED_NVC0(push, SUBC_3D(0x0f10), screen->tic.maxwell);
1201 }
1202 }
1203
1204 BEGIN_NVC0(push, NVC0_3D(TSC_ADDRESS_HIGH), 3);
1205 PUSH_DATAh(push, screen->txc->offset + 65536);
1206 PUSH_DATA (push, screen->txc->offset + 65536);
1207 PUSH_DATA (push, NVC0_TSC_MAX_ENTRIES - 1);
1208
1209 BEGIN_NVC0(push, NVC0_3D(SCREEN_Y_CONTROL), 1);
1210 PUSH_DATA (push, 0);
1211 BEGIN_NVC0(push, NVC0_3D(WINDOW_OFFSET_X), 2);
1212 PUSH_DATA (push, 0);
1213 PUSH_DATA (push, 0);
1214 BEGIN_NVC0(push, NVC0_3D(ZCULL_REGION), 1); /* deactivate ZCULL */
1215 PUSH_DATA (push, 0x3f);
1216
1217 BEGIN_NVC0(push, NVC0_3D(CLIP_RECTS_MODE), 1);
1218 PUSH_DATA (push, NVC0_3D_CLIP_RECTS_MODE_INSIDE_ANY);
1219 BEGIN_NVC0(push, NVC0_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
1220 for (i = 0; i < 8 * 2; ++i)
1221 PUSH_DATA(push, 0);
1222 BEGIN_NVC0(push, NVC0_3D(CLIP_RECTS_EN), 1);
1223 PUSH_DATA (push, 0);
1224 BEGIN_NVC0(push, NVC0_3D(CLIPID_ENABLE), 1);
1225 PUSH_DATA (push, 0);
1226
1227 /* neither scissors, viewport nor stencil mask should affect clears */
1228 BEGIN_NVC0(push, NVC0_3D(CLEAR_FLAGS), 1);
1229 PUSH_DATA (push, 0);
1230
1231 BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
1232 PUSH_DATA (push, 1);
1233 for (i = 0; i < NVC0_MAX_VIEWPORTS; i++) {
1234 BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(i)), 2);
1235 PUSH_DATAf(push, 0.0f);
1236 PUSH_DATAf(push, 1.0f);
1237 }
1238 BEGIN_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 1);
1239 PUSH_DATA (push, NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1);
1240
1241 /* We use scissors instead of exact view volume clipping,
1242 * so they're always enabled.
1243 */
1244 for (i = 0; i < NVC0_MAX_VIEWPORTS; i++) {
1245 BEGIN_NVC0(push, NVC0_3D(SCISSOR_ENABLE(i)), 3);
1246 PUSH_DATA (push, 1);
1247 PUSH_DATA (push, 16384 << 16);
1248 PUSH_DATA (push, 16384 << 16);
1249 }
1250
1251 if (screen->eng3d->oclass < TU102_3D_CLASS) {
1252 #define MK_MACRO(m, n) i = nvc0_graph_set_macro(screen, m, i, sizeof(n), n);
1253
1254 i = 0;
1255 MK_MACRO(NVC0_3D_MACRO_VERTEX_ARRAY_PER_INSTANCE, mme9097_per_instance_bf);
1256 MK_MACRO(NVC0_3D_MACRO_BLEND_ENABLES, mme9097_blend_enables);
1257 MK_MACRO(NVC0_3D_MACRO_VERTEX_ARRAY_SELECT, mme9097_vertex_array_select);
1258 MK_MACRO(NVC0_3D_MACRO_TEP_SELECT, mme9097_tep_select);
1259 MK_MACRO(NVC0_3D_MACRO_GP_SELECT, mme9097_gp_select);
1260 MK_MACRO(NVC0_3D_MACRO_POLYGON_MODE_FRONT, mme9097_poly_mode_front);
1261 MK_MACRO(NVC0_3D_MACRO_POLYGON_MODE_BACK, mme9097_poly_mode_back);
1262 MK_MACRO(NVC0_3D_MACRO_DRAW_ARRAYS_INDIRECT, mme9097_draw_arrays_indirect);
1263 MK_MACRO(NVC0_3D_MACRO_DRAW_ELEMENTS_INDIRECT, mme9097_draw_elts_indirect);
1264 MK_MACRO(NVC0_3D_MACRO_DRAW_ARRAYS_INDIRECT_COUNT, mme9097_draw_arrays_indirect_count);
1265 MK_MACRO(NVC0_3D_MACRO_DRAW_ELEMENTS_INDIRECT_COUNT, mme9097_draw_elts_indirect_count);
1266 MK_MACRO(NVC0_3D_MACRO_QUERY_BUFFER_WRITE, mme9097_query_buffer_write);
1267 MK_MACRO(NVC0_3D_MACRO_CONSERVATIVE_RASTER_STATE, mme9097_conservative_raster_state);
1268 MK_MACRO(NVC0_3D_MACRO_SET_PRIV_REG, mme9097_set_priv_reg);
1269 MK_MACRO(NVC0_3D_MACRO_COMPUTE_COUNTER, mme9097_compute_counter);
1270 MK_MACRO(NVC0_3D_MACRO_COMPUTE_COUNTER_TO_QUERY, mme9097_compute_counter_to_query);
1271 MK_MACRO(NVC0_CP_MACRO_LAUNCH_GRID_INDIRECT, mme90c0_launch_grid_indirect);
1272 } else {
1273 #undef MK_MACRO
1274 #define MK_MACRO(m, n) i = tu102_graph_set_macro(screen, m, i, sizeof(n), n);
1275
1276 i = 0;
1277 MK_MACRO(NVC0_3D_MACRO_VERTEX_ARRAY_PER_INSTANCE, mmec597_per_instance_bf);
1278 MK_MACRO(NVC0_3D_MACRO_BLEND_ENABLES, mmec597_blend_enables);
1279 MK_MACRO(NVC0_3D_MACRO_VERTEX_ARRAY_SELECT, mmec597_vertex_array_select);
1280 MK_MACRO(NVC0_3D_MACRO_TEP_SELECT, mmec597_tep_select);
1281 MK_MACRO(NVC0_3D_MACRO_GP_SELECT, mmec597_gp_select);
1282 MK_MACRO(NVC0_3D_MACRO_POLYGON_MODE_FRONT, mmec597_poly_mode_front);
1283 MK_MACRO(NVC0_3D_MACRO_POLYGON_MODE_BACK, mmec597_poly_mode_back);
1284 MK_MACRO(NVC0_3D_MACRO_DRAW_ARRAYS_INDIRECT, mmec597_draw_arrays_indirect);
1285 MK_MACRO(NVC0_3D_MACRO_DRAW_ELEMENTS_INDIRECT, mmec597_draw_elts_indirect);
1286 MK_MACRO(NVC0_3D_MACRO_DRAW_ARRAYS_INDIRECT_COUNT, mmec597_draw_arrays_indirect_count);
1287 MK_MACRO(NVC0_3D_MACRO_DRAW_ELEMENTS_INDIRECT_COUNT, mmec597_draw_elts_indirect_count);
1288 MK_MACRO(NVC0_3D_MACRO_QUERY_BUFFER_WRITE, mmec597_query_buffer_write);
1289 MK_MACRO(NVC0_3D_MACRO_CONSERVATIVE_RASTER_STATE, mmec597_conservative_raster_state);
1290 MK_MACRO(NVC0_3D_MACRO_SET_PRIV_REG, mmec597_set_priv_reg);
1291 MK_MACRO(NVC0_3D_MACRO_COMPUTE_COUNTER, mmec597_compute_counter);
1292 MK_MACRO(NVC0_3D_MACRO_COMPUTE_COUNTER_TO_QUERY, mmec597_compute_counter_to_query);
1293 }
1294
1295 BEGIN_NVC0(push, NVC0_3D(RASTERIZE_ENABLE), 1);
1296 PUSH_DATA (push, 1);
1297 BEGIN_NVC0(push, NVC0_3D(RT_SEPARATE_FRAG_DATA), 1);
1298 PUSH_DATA (push, 1);
1299 BEGIN_NVC0(push, NVC0_3D(MACRO_GP_SELECT), 1);
1300 PUSH_DATA (push, 0x40);
1301 BEGIN_NVC0(push, NVC0_3D(LAYER), 1);
1302 PUSH_DATA (push, 0);
1303 BEGIN_NVC0(push, NVC0_3D(MACRO_TEP_SELECT), 1);
1304 PUSH_DATA (push, 0x30);
1305 BEGIN_NVC0(push, NVC0_3D(PATCH_VERTICES), 1);
1306 PUSH_DATA (push, 3);
1307 BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 1);
1308 PUSH_DATA (push, 0x20);
1309 BEGIN_NVC0(push, NVC0_3D(SP_SELECT(0)), 1);
1310 PUSH_DATA (push, 0x00);
1311 screen->save_state.patch_vertices = 3;
1312
1313 BEGIN_NVC0(push, NVC0_3D(POINT_COORD_REPLACE), 1);
1314 PUSH_DATA (push, 0);
1315 BEGIN_NVC0(push, NVC0_3D(POINT_RASTER_RULES), 1);
1316 PUSH_DATA (push, NVC0_3D_POINT_RASTER_RULES_OGL);
1317
1318 IMMED_NVC0(push, NVC0_3D(EDGEFLAG), 1);
1319
1320 if (nvc0_screen_init_compute(screen))
1321 goto fail;
1322
1323 /* XXX: Compute and 3D are somehow aliased on Fermi. */
1324 for (i = 0; i < 5; ++i) {
1325 unsigned j = 0;
1326 for (j = 0; j < 16; j++)
1327 screen->cb_bindings[i][j].size = -1;
1328
1329 /* TIC and TSC entries for each unit (nve4+ only) */
1330 /* auxiliary constants (6 user clip planes, base instance id) */
1331 nvc0_screen_bind_cb_3d(screen, push, NULL, i, 15, NVC0_CB_AUX_SIZE,
1332 screen->uniform_bo->offset + NVC0_CB_AUX_INFO(i));
1333 if (screen->eng3d->oclass >= NVE4_3D_CLASS) {
1334 unsigned j;
1335 BEGIN_1IC0(push, NVC0_3D(CB_POS), 9);
1336 PUSH_DATA (push, NVC0_CB_AUX_UNK_INFO);
1337 for (j = 0; j < 8; ++j)
1338 PUSH_DATA(push, j);
1339 } else {
1340 BEGIN_NVC0(push, NVC0_3D(TEX_LIMITS(i)), 1);
1341 PUSH_DATA (push, 0x54);
1342 }
1343
1344 /* MS sample coordinate offsets: these do not work with _ALT modes ! */
1345 BEGIN_1IC0(push, NVC0_3D(CB_POS), 1 + 2 * 8);
1346 PUSH_DATA (push, NVC0_CB_AUX_MS_INFO);
1347 PUSH_DATA (push, 0); /* 0 */
1348 PUSH_DATA (push, 0);
1349 PUSH_DATA (push, 1); /* 1 */
1350 PUSH_DATA (push, 0);
1351 PUSH_DATA (push, 0); /* 2 */
1352 PUSH_DATA (push, 1);
1353 PUSH_DATA (push, 1); /* 3 */
1354 PUSH_DATA (push, 1);
1355 PUSH_DATA (push, 2); /* 4 */
1356 PUSH_DATA (push, 0);
1357 PUSH_DATA (push, 3); /* 5 */
1358 PUSH_DATA (push, 0);
1359 PUSH_DATA (push, 2); /* 6 */
1360 PUSH_DATA (push, 1);
1361 PUSH_DATA (push, 3); /* 7 */
1362 PUSH_DATA (push, 1);
1363 }
1364 BEGIN_NVC0(push, NVC0_3D(LINKED_TSC), 1);
1365 PUSH_DATA (push, 0);
1366
1367 /* requires Nvidia provided firmware */
1368 if (screen->eng3d->oclass >= GM200_3D_CLASS) {
1369 unsigned reg = screen->eng3d->oclass >= GV100_3D_CLASS ? 0x419ba4 : 0x419f78;
1370 BEGIN_1IC0(push, NVC0_3D(MACRO_SET_PRIV_REG), 3);
1371 PUSH_DATA (push, reg);
1372 PUSH_DATA (push, 0x00000000);
1373 PUSH_DATA (push, 0x00000008);
1374 }
1375
1376 PUSH_KICK (push);
1377
1378 screen->tic.entries = CALLOC(
1379 NVC0_TIC_MAX_ENTRIES + NVC0_TSC_MAX_ENTRIES + NVE4_IMG_MAX_HANDLES,
1380 sizeof(void *));
1381 screen->tsc.entries = screen->tic.entries + NVC0_TIC_MAX_ENTRIES;
1382 screen->img.entries = (void *)(screen->tsc.entries + NVC0_TSC_MAX_ENTRIES);
1383
1384 if (!nvc0_blitter_create(screen))
1385 goto fail;
1386
1387 nouveau_device_set_classes_for_debug(dev,
1388 screen->eng3d->oclass,
1389 screen->compute->oclass,
1390 screen->m2mf->oclass,
1391 screen->copy ? screen->copy->oclass : 0);
1392 return &screen->base;
1393
1394 fail:
1395 screen->base.base.context_create = NULL;
1396 return &screen->base;
1397 }
1398
1399 int
nvc0_screen_tic_alloc(struct nvc0_screen * screen,void * entry)1400 nvc0_screen_tic_alloc(struct nvc0_screen *screen, void *entry)
1401 {
1402 int i = screen->tic.next;
1403
1404 while (screen->tic.lock[i / 32] & (1 << (i % 32)))
1405 i = (i + 1) & (NVC0_TIC_MAX_ENTRIES - 1);
1406
1407 screen->tic.next = (i + 1) & (NVC0_TIC_MAX_ENTRIES - 1);
1408
1409 if (screen->tic.entries[i])
1410 nv50_tic_entry(screen->tic.entries[i])->id = -1;
1411
1412 screen->tic.entries[i] = entry;
1413 return i;
1414 }
1415
1416 int
nvc0_screen_tsc_alloc(struct nvc0_screen * screen,void * entry)1417 nvc0_screen_tsc_alloc(struct nvc0_screen *screen, void *entry)
1418 {
1419 int i = screen->tsc.next;
1420
1421 while (screen->tsc.lock[i / 32] & (1 << (i % 32)))
1422 i = (i + 1) & (NVC0_TSC_MAX_ENTRIES - 1);
1423
1424 screen->tsc.next = (i + 1) & (NVC0_TSC_MAX_ENTRIES - 1);
1425
1426 if (screen->tsc.entries[i])
1427 nv50_tsc_entry(screen->tsc.entries[i])->id = -1;
1428
1429 screen->tsc.entries[i] = entry;
1430 return i;
1431 }
1432