1 /*
2 * Copyright © 2014-2017 Broadcom
3 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25 #include <sys/sysinfo.h>
26
27 #include "common/v3d_device_info.h"
28 #include "common/v3d_limits.h"
29 #include "util/os_misc.h"
30 #include "pipe/p_defines.h"
31 #include "pipe/p_screen.h"
32 #include "pipe/p_state.h"
33 #include "util/perf/cpu_trace.h"
34
35 #include "util/u_debug.h"
36 #include "util/u_memory.h"
37 #include "util/format/u_format.h"
38 #include "util/u_hash_table.h"
39 #include "util/u_screen.h"
40 #include "util/u_transfer_helper.h"
41 #include "util/ralloc.h"
42 #include "util/xmlconfig.h"
43
44 #include <xf86drm.h>
45 #include "v3d_screen.h"
46 #include "v3d_context.h"
47 #include "v3d_resource.h"
48 #include "compiler/v3d_compiler.h"
49 #include "drm-uapi/drm_fourcc.h"
50
51 const char *
v3d_screen_get_name(struct pipe_screen * pscreen)52 v3d_screen_get_name(struct pipe_screen *pscreen)
53 {
54 struct v3d_screen *screen = v3d_screen(pscreen);
55
56 if (!screen->name) {
57 screen->name = ralloc_asprintf(screen,
58 "V3D %d.%d.%d.%d",
59 screen->devinfo.ver / 10,
60 screen->devinfo.ver % 10,
61 screen->devinfo.rev,
62 screen->devinfo.compat_rev);
63 }
64
65 return screen->name;
66 }
67
68 static const char *
v3d_screen_get_vendor(struct pipe_screen * pscreen)69 v3d_screen_get_vendor(struct pipe_screen *pscreen)
70 {
71 return "Broadcom";
72 }
73
74 static void
v3d_screen_destroy(struct pipe_screen * pscreen)75 v3d_screen_destroy(struct pipe_screen *pscreen)
76 {
77 struct v3d_screen *screen = v3d_screen(pscreen);
78
79 v3d_perfcntrs_fini(screen->perfcnt);
80 screen->perfcnt = NULL;
81
82 _mesa_hash_table_destroy(screen->bo_handles, NULL);
83 v3d_bufmgr_destroy(pscreen);
84 slab_destroy_parent(&screen->transfer_pool);
85 if (screen->ro)
86 screen->ro->destroy(screen->ro);
87
88 #if USE_V3D_SIMULATOR
89 v3d_simulator_destroy(screen->sim_file);
90 #endif
91
92 v3d_compiler_free(screen->compiler);
93
94 #ifdef ENABLE_SHADER_CACHE
95 if (screen->disk_cache)
96 disk_cache_destroy(screen->disk_cache);
97 #endif
98
99 u_transfer_helper_destroy(pscreen->transfer_helper);
100
101 close(screen->fd);
102 ralloc_free(pscreen);
103 }
104
105 static bool
v3d_has_feature(struct v3d_screen * screen,enum drm_v3d_param feature)106 v3d_has_feature(struct v3d_screen *screen, enum drm_v3d_param feature)
107 {
108 struct drm_v3d_get_param p = {
109 .param = feature,
110 };
111 int ret = v3d_ioctl(screen->fd, DRM_IOCTL_V3D_GET_PARAM, &p);
112
113 if (ret != 0)
114 return false;
115
116 return p.value;
117 }
118
119 static int
v3d_screen_get_shader_param(struct pipe_screen * pscreen,enum pipe_shader_type shader,enum pipe_shader_cap param)120 v3d_screen_get_shader_param(struct pipe_screen *pscreen, enum pipe_shader_type shader,
121 enum pipe_shader_cap param)
122 {
123 struct v3d_screen *screen = v3d_screen(pscreen);
124
125 switch (shader) {
126 case PIPE_SHADER_VERTEX:
127 case PIPE_SHADER_FRAGMENT:
128 case PIPE_SHADER_GEOMETRY:
129 break;
130 case PIPE_SHADER_COMPUTE:
131 if (!screen->has_csd)
132 return 0;
133 break;
134 default:
135 return 0;
136 }
137
138 /* this is probably not totally correct.. but it's a start: */
139 switch (param) {
140 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
141 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
142 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
143 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
144 return 16384;
145
146 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
147 return UINT_MAX;
148
149 case PIPE_SHADER_CAP_MAX_INPUTS:
150 switch (shader) {
151 case PIPE_SHADER_VERTEX:
152 return V3D_MAX_VS_INPUTS / 4;
153 case PIPE_SHADER_GEOMETRY:
154 return V3D_MAX_GS_INPUTS / 4;
155 case PIPE_SHADER_FRAGMENT:
156 return V3D_MAX_FS_INPUTS / 4;
157 default:
158 return 0;
159 };
160 case PIPE_SHADER_CAP_MAX_OUTPUTS:
161 if (shader == PIPE_SHADER_FRAGMENT)
162 return 4;
163 else
164 return V3D_MAX_FS_INPUTS / 4;
165 case PIPE_SHADER_CAP_MAX_TEMPS:
166 return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
167 case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE:
168 /* Note: Limited by the offset size in
169 * v3d_unit_data_create().
170 */
171 return 16 * 1024 * sizeof(float);
172 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
173 return 16;
174 case PIPE_SHADER_CAP_CONT_SUPPORTED:
175 return 0;
176 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
177 return 1;
178 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
179 return 1;
180 case PIPE_SHADER_CAP_SUBROUTINES:
181 return 0;
182 case PIPE_SHADER_CAP_INTEGERS:
183 return 1;
184 case PIPE_SHADER_CAP_FP16:
185 case PIPE_SHADER_CAP_FP16_DERIVATIVES:
186 case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
187 case PIPE_SHADER_CAP_INT16:
188 case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
189 case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
190 case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
191 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
192 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
193 return 0;
194 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
195 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
196 return V3D_MAX_TEXTURE_SAMPLERS;
197
198 case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
199 if (screen->has_cache_flush) {
200 if (shader == PIPE_SHADER_VERTEX ||
201 shader == PIPE_SHADER_GEOMETRY) {
202 return 0;
203 }
204 return PIPE_MAX_SHADER_BUFFERS;
205 } else {
206 return 0;
207 }
208
209 case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
210 return screen->has_cache_flush ? PIPE_MAX_SHADER_IMAGES : 0;
211
212 case PIPE_SHADER_CAP_SUPPORTED_IRS:
213 return 1 << PIPE_SHADER_IR_NIR;
214 default:
215 fprintf(stderr, "unknown shader param %d\n", param);
216 return 0;
217 }
218 return 0;
219 }
220
221 static int
v3d_get_compute_param(struct pipe_screen * pscreen,enum pipe_shader_ir ir_type,enum pipe_compute_cap param,void * ret)222 v3d_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type,
223 enum pipe_compute_cap param, void *ret)
224 {
225 struct v3d_screen *screen = v3d_screen(pscreen);
226 const char *const ir = "v3d";
227
228 if (!screen->has_csd)
229 return 0;
230
231 #define RET(x) do { \
232 if (ret) \
233 memcpy(ret, x, sizeof(x)); \
234 return sizeof(x); \
235 } while (0)
236
237 switch (param) {
238 case PIPE_COMPUTE_CAP_ADDRESS_BITS:
239 RET((uint32_t []) { 32 });
240 break;
241
242 case PIPE_COMPUTE_CAP_IR_TARGET:
243 if (ret)
244 sprintf(ret, "%s", ir);
245 return strlen(ir) * sizeof(char);
246
247 case PIPE_COMPUTE_CAP_GRID_DIMENSION:
248 RET((uint64_t []) { 3 });
249
250 case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
251 /* GL_MAX_COMPUTE_SHADER_WORK_GROUP_COUNT: The CSD has a
252 * 16-bit field for the number of workgroups in each
253 * dimension.
254 */
255 RET(((uint64_t []) { 65535, 65535, 65535 }));
256
257 case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
258 /* GL_MAX_COMPUTE_WORK_GROUP_SIZE */
259 RET(((uint64_t []) { 256, 256, 256 }));
260
261 case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
262 case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:
263 /* GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: This is
264 * limited by WG_SIZE in the CSD.
265 */
266 RET((uint64_t []) { 256 });
267
268 case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
269 /* GL_MAX_COMPUTE_SHARED_MEMORY_SIZE */
270 RET((uint64_t []) { 32768 });
271
272 case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE:
273 case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:
274 RET((uint64_t []) { 4096 });
275
276 case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE: {
277 struct sysinfo si;
278 sysinfo(&si);
279 RET((uint64_t []) { si.totalram });
280 }
281
282 case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE: {
283 struct sysinfo si;
284 sysinfo(&si);
285 RET((uint64_t []) { MIN2(V3D_MAX_BUFFER_RANGE, si.totalram) });
286 }
287
288 case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:
289 /* OpenCL only */
290 RET((uint32_t []) { 0 });
291
292 case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:
293 RET((uint32_t []) { 1 });
294
295 case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED:
296 RET((uint32_t []) { 1 });
297
298 case PIPE_COMPUTE_CAP_SUBGROUP_SIZES:
299 RET((uint32_t []) { 16 });
300
301 case PIPE_COMPUTE_CAP_MAX_SUBGROUPS:
302 RET((uint32_t []) { 0 });
303
304 }
305
306 return 0;
307 }
308
309 static void
v3d_init_screen_caps(struct v3d_screen * screen)310 v3d_init_screen_caps(struct v3d_screen *screen)
311 {
312 struct pipe_caps *caps = (struct pipe_caps *)&screen->base.caps;
313
314 u_init_pipe_screen_caps(&screen->base, 1);
315
316 /* Supported features (boolean caps). */
317 caps->vertex_color_unclamped = true;
318 caps->npot_textures = true;
319 caps->blend_equation_separate = true;
320 caps->texture_multisample = true;
321 caps->texture_swizzle = true;
322 caps->vertex_element_instance_divisor = true;
323 caps->start_instance = true;
324 caps->vs_instanceid = true;
325 caps->fragment_shader_texture_lod = true;
326 caps->fragment_shader_derivatives = true;
327 caps->primitive_restart_fixed_index = true;
328 caps->emulate_nonfixed_primitive_restart = true;
329 caps->primitive_restart = true;
330 caps->occlusion_query = true;
331 caps->stream_output_pause_resume = true;
332 caps->draw_indirect = true;
333 caps->multi_draw_indirect = true;
334 caps->quads_follow_provoking_vertex_convention = true;
335 caps->signed_vertex_buffer_offset = true;
336 caps->shader_pack_half_float = true;
337 caps->texture_half_float_linear = true;
338 caps->framebuffer_no_attachment = true;
339 caps->fs_face_is_integer_sysval = true;
340 caps->tgsi_texcoord = true;
341 caps->texture_mirror_clamp_to_edge = true;
342 caps->sampler_view_target = true;
343 caps->anisotropic_filter = true;
344 caps->copy_between_compressed_and_plain_formats = true;
345 caps->indep_blend_func = true;
346 caps->conditional_render = true;
347 caps->conditional_render_inverted = true;
348 caps->cube_map_array = true;
349 caps->texture_barrier = true;
350 caps->polygon_offset_clamp = true;
351 caps->texture_query_lod = true;
352
353 caps->query_timestamp =
354 caps->query_time_elapsed = screen->has_cpu_queue && screen->has_multisync;
355 caps->texture_sampler_independent = false;
356
357 /* We can't enable this flag, because it results in load_ubo
358 * intrinsics across a 16b boundary, but v3d's TMU general
359 * memory accesses wrap on 16b boundaries.
360 */
361 caps->packed_uniforms = false;
362
363 caps->nir_images_as_deref = false;
364
365 /* XXX perf: we don't want to emit these extra blits for
366 * glReadPixels(), since we still have to do an uncached read
367 * from the GPU of the result after waiting for the TFU blit
368 * to happen. However, disabling this introduces instability
369 * in
370 * dEQP-GLES31.functional.image_load_store.early_fragment_tests.*
371 * and corruption in chromium's rendering.
372 */
373 caps->texture_transfer_modes = PIPE_TEXTURE_TRANSFER_BLIT;
374
375 caps->compute = screen->has_csd;
376
377 caps->generate_mipmap = v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_TFU);
378
379 caps->indep_blend_enable = true;
380
381 caps->constant_buffer_offset_alignment = V3D_NON_COHERENT_ATOM_SIZE;
382
383 caps->max_texture_gather_components = 4;
384
385 /* Disables shader storage when 0. */
386 caps->shader_buffer_offset_alignment = screen->has_cache_flush ? 4 : 0;
387
388 caps->glsl_feature_level = 330;
389
390 caps->essl_feature_level = 310;
391
392 caps->glsl_feature_level_compatibility = 140;
393
394 caps->fs_coord_origin_upper_left = true;
395 caps->fs_coord_origin_lower_left = false;
396 caps->fs_coord_pixel_center_integer = false;
397 caps->fs_coord_pixel_center_half_integer = true;
398
399 caps->mixed_framebuffer_sizes = true;
400 caps->mixed_color_depth_bits = true;
401
402 caps->max_stream_output_buffers = 4;
403
404 caps->max_varyings = V3D_MAX_FS_INPUTS / 4;
405
406 /* Texturing. */
407 caps->max_texture_2d_size =
408 screen->nonmsaa_texture_size_limit ? 7680 : V3D_MAX_IMAGE_DIMENSION;
409 caps->max_texture_cube_levels =
410 caps->max_texture_3d_levels = V3D_MAX_MIP_LEVELS;
411 caps->max_texture_array_layers = V3D_MAX_ARRAY_LAYERS;
412
413 caps->max_render_targets = V3D_MAX_RENDER_TARGETS(screen->devinfo.ver);
414
415 caps->vendor_id = 0x14E4;
416
417 uint64_t system_memory;
418 caps->video_memory = os_get_total_physical_memory(&system_memory) ?
419 system_memory >> 20 : 0;
420
421 caps->uma = true;
422
423 caps->alpha_test = false;
424 caps->flatshade = false;
425 caps->two_sided_color = false;
426 caps->vertex_color_clamped = false;
427 caps->fragment_color_clamped = false;
428 caps->gl_clamp = false;
429
430 /* Geometry shaders */
431 /* Minimum required by GLES 3.2 */
432 caps->max_geometry_total_output_components = 1024;
433 /* MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS / 4 */
434 caps->max_geometry_output_vertices = 256;
435 caps->max_gs_invocations = 32;
436
437 caps->supported_prim_modes =
438 caps->supported_prim_modes_with_restart = screen->prim_types;
439
440 caps->texture_buffer_objects = true;
441
442 caps->texture_buffer_offset_alignment = V3D_TMU_TEXEL_ALIGN;
443
444 caps->image_store_formatted = false;
445
446 caps->native_fence_fd = true;
447
448 caps->depth_clip_disable = screen->devinfo.ver >= 71;
449
450 caps->min_line_width =
451 caps->min_line_width_aa =
452 caps->min_point_size =
453 caps->min_point_size_aa = 1;
454
455 caps->point_size_granularity =
456 caps->line_width_granularity = 0.1;
457
458 caps->max_line_width =
459 caps->max_line_width_aa = V3D_MAX_LINE_WIDTH;
460
461 caps->max_point_size =
462 caps->max_point_size_aa = V3D_MAX_POINT_SIZE;
463
464 caps->max_texture_anisotropy = 16.0f;
465 caps->max_texture_lod_bias = 16.0f;
466 }
467
468 static bool
v3d_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 usage)469 v3d_screen_is_format_supported(struct pipe_screen *pscreen,
470 enum pipe_format format,
471 enum pipe_texture_target target,
472 unsigned sample_count,
473 unsigned storage_sample_count,
474 unsigned usage)
475 {
476 struct v3d_screen *screen = v3d_screen(pscreen);
477
478 if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
479 return false;
480
481 if (sample_count > 1 && sample_count != V3D_MAX_SAMPLES)
482 return false;
483
484 if (target >= PIPE_MAX_TEXTURE_TYPES) {
485 return false;
486 }
487
488 if (usage & PIPE_BIND_VERTEX_BUFFER) {
489 switch (format) {
490 case PIPE_FORMAT_R32G32B32A32_FLOAT:
491 case PIPE_FORMAT_R32G32B32_FLOAT:
492 case PIPE_FORMAT_R32G32_FLOAT:
493 case PIPE_FORMAT_R32_FLOAT:
494 case PIPE_FORMAT_R32G32B32A32_SNORM:
495 case PIPE_FORMAT_R32G32B32_SNORM:
496 case PIPE_FORMAT_R32G32_SNORM:
497 case PIPE_FORMAT_R32_SNORM:
498 case PIPE_FORMAT_R32G32B32A32_SSCALED:
499 case PIPE_FORMAT_R32G32B32_SSCALED:
500 case PIPE_FORMAT_R32G32_SSCALED:
501 case PIPE_FORMAT_R32_SSCALED:
502 case PIPE_FORMAT_R16G16B16A16_UNORM:
503 case PIPE_FORMAT_R16G16B16A16_FLOAT:
504 case PIPE_FORMAT_R16G16B16_UNORM:
505 case PIPE_FORMAT_R16G16_UNORM:
506 case PIPE_FORMAT_R16_UNORM:
507 case PIPE_FORMAT_R16_FLOAT:
508 case PIPE_FORMAT_R16G16B16A16_SNORM:
509 case PIPE_FORMAT_R16G16B16_SNORM:
510 case PIPE_FORMAT_R16G16_SNORM:
511 case PIPE_FORMAT_R16G16_FLOAT:
512 case PIPE_FORMAT_R16_SNORM:
513 case PIPE_FORMAT_R16G16B16A16_USCALED:
514 case PIPE_FORMAT_R16G16B16_USCALED:
515 case PIPE_FORMAT_R16G16_USCALED:
516 case PIPE_FORMAT_R16_USCALED:
517 case PIPE_FORMAT_R16G16B16A16_SSCALED:
518 case PIPE_FORMAT_R16G16B16_SSCALED:
519 case PIPE_FORMAT_R16G16_SSCALED:
520 case PIPE_FORMAT_R16_SSCALED:
521 case PIPE_FORMAT_B8G8R8A8_UNORM:
522 case PIPE_FORMAT_R8G8B8A8_UNORM:
523 case PIPE_FORMAT_R8G8B8_UNORM:
524 case PIPE_FORMAT_R8G8_UNORM:
525 case PIPE_FORMAT_R8_UNORM:
526 case PIPE_FORMAT_R8G8B8A8_SNORM:
527 case PIPE_FORMAT_R8G8B8_SNORM:
528 case PIPE_FORMAT_R8G8_SNORM:
529 case PIPE_FORMAT_R8_SNORM:
530 case PIPE_FORMAT_R8G8B8A8_USCALED:
531 case PIPE_FORMAT_R8G8B8_USCALED:
532 case PIPE_FORMAT_R8G8_USCALED:
533 case PIPE_FORMAT_R8_USCALED:
534 case PIPE_FORMAT_R8G8B8A8_SSCALED:
535 case PIPE_FORMAT_R8G8B8_SSCALED:
536 case PIPE_FORMAT_R8G8_SSCALED:
537 case PIPE_FORMAT_R8_SSCALED:
538 case PIPE_FORMAT_R10G10B10A2_UNORM:
539 case PIPE_FORMAT_B10G10R10A2_UNORM:
540 case PIPE_FORMAT_R10G10B10A2_SNORM:
541 case PIPE_FORMAT_B10G10R10A2_SNORM:
542 case PIPE_FORMAT_R10G10B10A2_USCALED:
543 case PIPE_FORMAT_B10G10R10A2_USCALED:
544 case PIPE_FORMAT_R10G10B10A2_SSCALED:
545 case PIPE_FORMAT_B10G10R10A2_SSCALED:
546 break;
547 default:
548 return false;
549 }
550 }
551
552 /* FORMAT_NONE gets allowed for ARB_framebuffer_no_attachments's probe
553 * of FRAMEBUFFER_MAX_SAMPLES
554 */
555 if ((usage & PIPE_BIND_RENDER_TARGET) &&
556 format != PIPE_FORMAT_NONE &&
557 !v3d_rt_format_supported(&screen->devinfo, format)) {
558 return false;
559 }
560
561 /* We do not support EXT_float_blend (blending with 32F formats)*/
562 if ((usage & PIPE_BIND_BLENDABLE) &&
563 (format == PIPE_FORMAT_R32G32B32A32_FLOAT ||
564 format == PIPE_FORMAT_R32G32_FLOAT ||
565 format == PIPE_FORMAT_R32_FLOAT)) {
566 return false;
567 }
568
569 if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
570 !v3d_tex_format_supported(&screen->devinfo, format)) {
571 return false;
572 }
573
574 if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
575 !(format == PIPE_FORMAT_S8_UINT_Z24_UNORM ||
576 format == PIPE_FORMAT_X8Z24_UNORM ||
577 format == PIPE_FORMAT_Z16_UNORM ||
578 format == PIPE_FORMAT_Z32_FLOAT ||
579 format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)) {
580 return false;
581 }
582
583 if ((usage & PIPE_BIND_INDEX_BUFFER) &&
584 !(format == PIPE_FORMAT_R8_UINT ||
585 format == PIPE_FORMAT_R16_UINT ||
586 format == PIPE_FORMAT_R32_UINT)) {
587 return false;
588 }
589
590 if (usage & PIPE_BIND_SHADER_IMAGE) {
591 switch (format) {
592 /* FIXME: maybe we can implement a swizzle-on-writes to add
593 * support for BGRA-alike formats.
594 */
595 case PIPE_FORMAT_A4B4G4R4_UNORM:
596 case PIPE_FORMAT_A1B5G5R5_UNORM:
597 case PIPE_FORMAT_B5G6R5_UNORM:
598 case PIPE_FORMAT_B8G8R8A8_UNORM:
599 case PIPE_FORMAT_X8Z24_UNORM:
600 case PIPE_FORMAT_Z16_UNORM:
601 return false;
602 default:
603 return true;
604 }
605 }
606
607 return true;
608 }
609
610 static const void *
v3d_screen_get_compiler_options(struct pipe_screen * pscreen,enum pipe_shader_ir ir,enum pipe_shader_type shader)611 v3d_screen_get_compiler_options(struct pipe_screen *pscreen,
612 enum pipe_shader_ir ir,
613 enum pipe_shader_type shader)
614 {
615 struct v3d_screen *screen = v3d_screen(pscreen);
616 const struct v3d_device_info *devinfo = &screen->devinfo;
617
618 static bool initialized = false;
619 static nir_shader_compiler_options options = {
620 .compact_arrays = true,
621 .lower_uadd_sat = true,
622 .lower_usub_sat = true,
623 .lower_iadd_sat = true,
624 .lower_all_io_to_temps = true,
625 .lower_extract_byte = true,
626 .lower_extract_word = true,
627 .lower_insert_byte = true,
628 .lower_insert_word = true,
629 .lower_bitfield_insert = true,
630 .lower_bitfield_extract = true,
631 .lower_bitfield_reverse = true,
632 .lower_bit_count = true,
633 .lower_cs_local_id_to_index = true,
634 .lower_ffract = true,
635 .lower_fmod = true,
636 .lower_pack_unorm_2x16 = true,
637 .lower_pack_snorm_2x16 = true,
638 .lower_pack_unorm_4x8 = true,
639 .lower_pack_snorm_4x8 = true,
640 .lower_unpack_unorm_4x8 = true,
641 .lower_unpack_snorm_4x8 = true,
642 .lower_pack_half_2x16 = true,
643 .lower_unpack_half_2x16 = true,
644 .lower_pack_32_2x16 = true,
645 .lower_pack_32_2x16_split = true,
646 .lower_unpack_32_2x16_split = true,
647 .lower_fdiv = true,
648 .lower_find_lsb = true,
649 .lower_ffma16 = true,
650 .lower_ffma32 = true,
651 .lower_ffma64 = true,
652 .lower_flrp32 = true,
653 .lower_fpow = true,
654 .lower_fsqrt = true,
655 .lower_ifind_msb = true,
656 .lower_isign = true,
657 .lower_ldexp = true,
658 .lower_hadd = true,
659 .lower_fisnormal = true,
660 .lower_mul_high = true,
661 .lower_wpos_pntc = true,
662 .lower_to_scalar = true,
663 .lower_int64_options =
664 nir_lower_bcsel64 |
665 nir_lower_conv64 |
666 nir_lower_iadd64 |
667 nir_lower_icmp64 |
668 nir_lower_imul_2x32_64 |
669 nir_lower_imul64 |
670 nir_lower_ineg64 |
671 nir_lower_logic64 |
672 nir_lower_shift64 |
673 nir_lower_ufind_msb64,
674 .lower_fquantize2f16 = true,
675 .lower_ufind_msb = true,
676 .has_fsub = true,
677 .has_isub = true,
678 .has_uclz = true,
679 .divergence_analysis_options =
680 nir_divergence_multiple_workgroup_per_compute_subgroup,
681 /* We don't currently support this in the backend, but that is
682 * okay because our NIR compiler sets the option
683 * lower_all_io_to_temps, which will eliminate indirect
684 * indexing on all input/output variables by translating it to
685 * indirect indexing on temporary variables instead, which we
686 * will then lower to scratch. We prefer this over setting this
687 * to 0, which would cause if-ladder injection to eliminate
688 * indirect indexing on inputs.
689 */
690 .support_indirect_inputs = (uint8_t)BITFIELD_MASK(PIPE_SHADER_TYPES),
691 .support_indirect_outputs = (uint8_t)BITFIELD_MASK(PIPE_SHADER_TYPES),
692 /* This will enable loop unrolling in the state tracker so we won't
693 * be able to selectively disable it in backend if it leads to
694 * lower thread counts or TMU spills. Choose a conservative maximum to
695 * limit register pressure impact.
696 */
697 .max_unroll_iterations = 16,
698 .force_indirect_unrolling_sampler = true,
699 .scalarize_ddx = true,
700 .max_varying_expression_cost = 4,
701 };
702
703 if (!initialized) {
704 options.lower_fsat = devinfo->ver < 71;
705 initialized = true;
706 }
707
708 return &options;
709 }
710
711 static const uint64_t v3d_available_modifiers[] = {
712 DRM_FORMAT_MOD_BROADCOM_UIF,
713 DRM_FORMAT_MOD_LINEAR,
714 DRM_FORMAT_MOD_BROADCOM_SAND128,
715 };
716
717 static void
v3d_screen_query_dmabuf_modifiers(struct pipe_screen * pscreen,enum pipe_format format,int max,uint64_t * modifiers,unsigned int * external_only,int * count)718 v3d_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
719 enum pipe_format format, int max,
720 uint64_t *modifiers,
721 unsigned int *external_only,
722 int *count)
723 {
724 int i;
725 int num_modifiers = ARRAY_SIZE(v3d_available_modifiers);
726
727 switch (format) {
728 case PIPE_FORMAT_P030:
729 /* Expose SAND128, but not LINEAR or UIF */
730 *count = 1;
731 if (modifiers && max > 0) {
732 modifiers[0] = DRM_FORMAT_MOD_BROADCOM_SAND128;
733 if (external_only)
734 external_only[0] = true;
735 }
736 return;
737
738 case PIPE_FORMAT_NV12:
739 /* Expose UIF, LINEAR and SAND128 */
740 break;
741
742 case PIPE_FORMAT_R8_UNORM:
743 case PIPE_FORMAT_R8G8_UNORM:
744 case PIPE_FORMAT_R16_UNORM:
745 case PIPE_FORMAT_R16G16_UNORM:
746 /* Expose UIF, LINEAR and SAND128 */
747 if (!modifiers) break;
748 *count = MIN2(max, num_modifiers);
749 for (i = 0; i < *count; i++) {
750 modifiers[i] = v3d_available_modifiers[i];
751 if (external_only)
752 external_only[i] = modifiers[i] == DRM_FORMAT_MOD_BROADCOM_SAND128;
753 }
754 return;
755
756 default:
757 /* Expose UIF and LINEAR, but not SAND128 */
758 num_modifiers--;
759 }
760
761 if (!modifiers) {
762 *count = num_modifiers;
763 return;
764 }
765
766 *count = MIN2(max, num_modifiers);
767 for (i = 0; i < *count; i++) {
768 modifiers[i] = v3d_available_modifiers[i];
769 if (external_only)
770 external_only[i] = util_format_is_yuv(format);
771 }
772 }
773
774 static bool
v3d_screen_is_dmabuf_modifier_supported(struct pipe_screen * pscreen,uint64_t modifier,enum pipe_format format,bool * external_only)775 v3d_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,
776 uint64_t modifier,
777 enum pipe_format format,
778 bool *external_only)
779 {
780 int i;
781 if (fourcc_mod_broadcom_mod(modifier) == DRM_FORMAT_MOD_BROADCOM_SAND128) {
782 switch(format) {
783 case PIPE_FORMAT_NV12:
784 case PIPE_FORMAT_P030:
785 case PIPE_FORMAT_R8_UNORM:
786 case PIPE_FORMAT_R8G8_UNORM:
787 case PIPE_FORMAT_R16_UNORM:
788 case PIPE_FORMAT_R16G16_UNORM:
789 if (external_only)
790 *external_only = true;
791 return true;
792 default:
793 return false;
794 }
795 } else if (format == PIPE_FORMAT_P030) {
796 /* For PIPE_FORMAT_P030 we don't expose LINEAR or UIF. */
797 return false;
798 }
799
800 /* We don't want to generally allow DRM_FORMAT_MOD_BROADCOM_SAND128
801 * modifier, that is the last v3d_available_modifiers. We only accept
802 * it in the case of having a PIPE_FORMAT_NV12 or PIPE_FORMAT_P030.
803 */
804 assert(v3d_available_modifiers[ARRAY_SIZE(v3d_available_modifiers) - 1] ==
805 DRM_FORMAT_MOD_BROADCOM_SAND128);
806 for (i = 0; i < ARRAY_SIZE(v3d_available_modifiers) - 1; i++) {
807 if (v3d_available_modifiers[i] == modifier) {
808 if (external_only)
809 *external_only = util_format_is_yuv(format);
810
811 return true;
812 }
813 }
814
815 return false;
816 }
817
818 static enum pipe_format
v3d_screen_get_compatible_tlb_format(struct pipe_screen * screen,enum pipe_format format)819 v3d_screen_get_compatible_tlb_format(struct pipe_screen *screen,
820 enum pipe_format format)
821 {
822 switch (format) {
823 case PIPE_FORMAT_R16G16_UNORM:
824 return PIPE_FORMAT_R16G16_UINT;
825 default:
826 return format;
827 }
828 }
829
830 static struct disk_cache *
v3d_screen_get_disk_shader_cache(struct pipe_screen * pscreen)831 v3d_screen_get_disk_shader_cache(struct pipe_screen *pscreen)
832 {
833 struct v3d_screen *screen = v3d_screen(pscreen);
834
835 return screen->disk_cache;
836 }
837
838 static int
v3d_screen_get_fd(struct pipe_screen * pscreen)839 v3d_screen_get_fd(struct pipe_screen *pscreen)
840 {
841 struct v3d_screen *screen = v3d_screen(pscreen);
842
843 return screen->fd;
844 }
845
846 struct pipe_screen *
v3d_screen_create(int fd,const struct pipe_screen_config * config,struct renderonly * ro)847 v3d_screen_create(int fd, const struct pipe_screen_config *config,
848 struct renderonly *ro)
849 {
850 struct v3d_screen *screen = rzalloc(NULL, struct v3d_screen);
851 struct pipe_screen *pscreen;
852
853 util_cpu_trace_init();
854
855 pscreen = &screen->base;
856
857 pscreen->destroy = v3d_screen_destroy;
858 pscreen->get_screen_fd = v3d_screen_get_fd;
859 pscreen->get_shader_param = v3d_screen_get_shader_param;
860 pscreen->get_compute_param = v3d_get_compute_param;
861 pscreen->context_create = v3d_context_create;
862 pscreen->is_format_supported = v3d_screen_is_format_supported;
863 pscreen->get_canonical_format = v3d_screen_get_compatible_tlb_format;
864
865 screen->fd = fd;
866 screen->ro = ro;
867
868 list_inithead(&screen->bo_cache.time_list);
869 (void)mtx_init(&screen->bo_handles_mutex, mtx_plain);
870 screen->bo_handles = util_hash_table_create_ptr_keys();
871
872 #if USE_V3D_SIMULATOR
873 screen->sim_file = v3d_simulator_init(screen->fd);
874 #endif
875
876 if (!v3d_get_device_info(screen->fd, &screen->devinfo, &v3d_ioctl))
877 goto fail;
878
879 screen->perfcnt = v3d_perfcntrs_init(&screen->devinfo, screen->fd);
880 if (!screen->perfcnt)
881 goto fail;
882
883 driParseConfigFiles(config->options, config->options_info, 0, "v3d",
884 NULL, NULL, NULL, 0, NULL, 0);
885
886 /* We have to driCheckOption for the simulator mode to not assertion
887 * fail on not having our XML config.
888 */
889 const char *nonmsaa_name = "v3d_nonmsaa_texture_size_limit";
890 screen->nonmsaa_texture_size_limit =
891 driCheckOption(config->options, nonmsaa_name, DRI_BOOL) &&
892 driQueryOptionb(config->options, nonmsaa_name);
893
894 slab_create_parent(&screen->transfer_pool, sizeof(struct v3d_transfer), 16);
895
896 screen->has_csd = v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_CSD);
897 screen->has_cache_flush =
898 v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_CACHE_FLUSH);
899 screen->has_perfmon = v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_PERFMON);
900 screen->has_cpu_queue = v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_CPU_QUEUE);
901 screen->has_multisync = v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_MULTISYNC_EXT);
902
903 v3d_fence_screen_init(screen);
904
905 v3d_process_debug_variable();
906
907 v3d_resource_screen_init(pscreen);
908
909 screen->compiler = v3d_compiler_init(&screen->devinfo, 0);
910
911 #ifdef ENABLE_SHADER_CACHE
912 v3d_disk_cache_init(screen);
913 #endif
914
915 pscreen->get_name = v3d_screen_get_name;
916 pscreen->get_vendor = v3d_screen_get_vendor;
917 pscreen->get_device_vendor = v3d_screen_get_vendor;
918 pscreen->get_compiler_options = v3d_screen_get_compiler_options;
919 pscreen->get_disk_shader_cache = v3d_screen_get_disk_shader_cache;
920 pscreen->query_dmabuf_modifiers = v3d_screen_query_dmabuf_modifiers;
921 pscreen->is_dmabuf_modifier_supported =
922 v3d_screen_is_dmabuf_modifier_supported;
923
924 if (screen->has_perfmon) {
925 pscreen->get_driver_query_group_info = v3d_get_driver_query_group_info;
926 pscreen->get_driver_query_info = v3d_get_driver_query_info;
927 }
928
929 /* Generate the bitmask of supported draw primitives. */
930 screen->prim_types = BITFIELD_BIT(MESA_PRIM_POINTS) |
931 BITFIELD_BIT(MESA_PRIM_LINES) |
932 BITFIELD_BIT(MESA_PRIM_LINE_LOOP) |
933 BITFIELD_BIT(MESA_PRIM_LINE_STRIP) |
934 BITFIELD_BIT(MESA_PRIM_TRIANGLES) |
935 BITFIELD_BIT(MESA_PRIM_TRIANGLE_STRIP) |
936 BITFIELD_BIT(MESA_PRIM_TRIANGLE_FAN) |
937 BITFIELD_BIT(MESA_PRIM_LINES_ADJACENCY) |
938 BITFIELD_BIT(MESA_PRIM_LINE_STRIP_ADJACENCY) |
939 BITFIELD_BIT(MESA_PRIM_TRIANGLES_ADJACENCY) |
940 BITFIELD_BIT(MESA_PRIM_TRIANGLE_STRIP_ADJACENCY);
941
942 v3d_init_screen_caps(screen);
943
944 return pscreen;
945
946 fail:
947 close(fd);
948 ralloc_free(pscreen);
949 return NULL;
950 }
951