• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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