xref: /aosp_15_r20/external/mesa3d/src/gallium/auxiliary/util/u_screen.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2018 Broadcom
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 (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include <sys/stat.h>
25 
26 #include "pipe/p_screen.h"
27 #include "util/u_screen.h"
28 #include "util/u_debug.h"
29 #include "util/os_file.h"
30 #include "util/os_time.h"
31 #include "util/simple_mtx.h"
32 #include "util/u_hash_table.h"
33 #include "util/u_pointer.h"
34 #include "util/macros.h"
35 
36 #ifdef HAVE_LIBDRM
37 #include <xf86drm.h>
38 #endif
39 
40 /**
41  * Helper to use from a pipe_screen->get_param() implementation to return
42  * default values for unsupported PIPE_CAPs.
43  *
44  * Call this function from your pipe_screen->get_param() implementation's
45  * default case, so that implementors of new pipe caps don't need to
46  */
47 int
u_pipe_screen_get_param_defaults(struct pipe_screen * pscreen,enum pipe_cap param)48 u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen,
49                                  enum pipe_cap param)
50 {
51    UNUSED uint64_t cap;
52    UNUSED int fd;
53 
54    assert(param < PIPE_CAP_LAST);
55 
56    /* Let's keep these sorted by position in p_defines.h. */
57    switch (param) {
58    case PIPE_CAP_NPOT_TEXTURES:
59    case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
60    case PIPE_CAP_ANISOTROPIC_FILTER:
61       return 0;
62 
63    case PIPE_CAP_GRAPHICS:
64    case PIPE_CAP_GL_CLAMP:
65    case PIPE_CAP_MAX_RENDER_TARGETS:
66    case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
67    case PIPE_CAP_DITHERING:
68       return 1;
69 
70    case PIPE_CAP_OCCLUSION_QUERY:
71    case PIPE_CAP_QUERY_TIME_ELAPSED:
72    case PIPE_CAP_TEXTURE_SWIZZLE:
73       return 0;
74 
75    case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
76    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
77       unreachable("driver must implement these.");
78 
79    case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
80    case PIPE_CAP_BLEND_EQUATION_SEPARATE:
81    case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
82    case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
83    case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: /* enables EXT_transform_feedback */
84    case PIPE_CAP_PRIMITIVE_RESTART:
85    case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
86    case PIPE_CAP_INDEP_BLEND_ENABLE:
87    case PIPE_CAP_INDEP_BLEND_FUNC:
88    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
89    case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: /* Enables GL_EXT_texture_array */
90    case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT:
91    case PIPE_CAP_FS_COORD_ORIGIN_LOWER_LEFT:
92    case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
93    case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER:
94    case PIPE_CAP_DEPTH_CLIP_DISABLE:
95    case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
96    case PIPE_CAP_DEPTH_CLAMP_ENABLE:
97    case PIPE_CAP_SHADER_STENCIL_EXPORT:
98    case PIPE_CAP_VS_INSTANCEID:
99    case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
100    case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
101    case PIPE_CAP_SEAMLESS_CUBE_MAP:
102    case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
103    case PIPE_CAP_MULTIVIEW:
104       return 0;
105 
106    case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART:
107    case PIPE_CAP_SUPPORTED_PRIM_MODES:
108       return BITFIELD_MASK(MESA_PRIM_COUNT);
109 
110    case PIPE_CAP_MIN_TEXEL_OFFSET:
111       /* GL 3.x minimum value. */
112       return -8;
113    case PIPE_CAP_MAX_TEXEL_OFFSET:
114       return 7;
115 
116    case PIPE_CAP_CONDITIONAL_RENDER:
117    case PIPE_CAP_TEXTURE_BARRIER:
118       return 0;
119 
120    case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
121       /* GL_EXT_transform_feedback minimum value. */
122       return 4;
123    case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
124       return 64;
125 
126    case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
127    case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
128    case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
129    case PIPE_CAP_VERTEX_COLOR_CLAMPED:
130       return 0;
131 
132    case PIPE_CAP_GLSL_FEATURE_LEVEL:
133    case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
134       /* Minimum GLSL level implemented by gallium drivers. */
135       return 120;
136 
137    case PIPE_CAP_ESSL_FEATURE_LEVEL:
138       /* Tell gallium frontend to fallback to PIPE_CAP_GLSL_FEATURE_LEVEL */
139       return 0;
140 
141    case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
142    case PIPE_CAP_USER_VERTEX_BUFFERS:
143    case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
144    case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
145    case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
146    case PIPE_CAP_VERTEX_ATTRIB_ELEMENT_ALIGNED_ONLY:
147    case PIPE_CAP_COMPUTE:
148       return 0;
149 
150    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
151       /* GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT default value. */
152       return 1;
153 
154    case PIPE_CAP_START_INSTANCE:
155    case PIPE_CAP_QUERY_TIMESTAMP:
156    case PIPE_CAP_TIMER_RESOLUTION:
157    case PIPE_CAP_TEXTURE_MULTISAMPLE:
158       return 0;
159 
160    case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
161       /* GL_ARB_map_buffer_alignment minimum value. All drivers expose the
162        * extension.
163        */
164       return 64;
165 
166    case PIPE_CAP_CUBE_MAP_ARRAY:
167    case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
168       return 0;
169 
170    case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
171       /* GL_EXT_texture_buffer minimum value. */
172       return 256;
173 
174    case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
175    case PIPE_CAP_TGSI_TEXCOORD:
176       return 0;
177 
178    case PIPE_CAP_TEXTURE_TRANSFER_MODES:
179       return PIPE_TEXTURE_TRANSFER_BLIT;
180 
181    case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
182    case PIPE_CAP_QUERY_PIPELINE_STATISTICS_SINGLE:
183    case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
184       return 0;
185 
186    case PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT:
187       /* GL_EXT_texture_buffer minimum value. */
188       return 65536;
189 
190    case PIPE_CAP_LINEAR_IMAGE_PITCH_ALIGNMENT:
191       return 0;
192 
193    case PIPE_CAP_LINEAR_IMAGE_BASE_ADDRESS_ALIGNMENT:
194       return 0;
195 
196    case PIPE_CAP_MAX_VIEWPORTS:
197       return 1;
198 
199    case PIPE_CAP_ENDIANNESS:
200       return PIPE_ENDIAN_LITTLE;
201 
202    case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
203    case PIPE_CAP_VS_LAYER_VIEWPORT:
204    case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
205    case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
206    case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: /* Enables ARB_texture_gather */
207    case PIPE_CAP_TEXTURE_GATHER_SM5:
208       return 0;
209 
210    /* All new drivers should support persistent/coherent mappings. This CAP
211     * should only be unset by layered drivers whose host drivers cannot support
212     * coherent mappings.
213     */
214    case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
215       return 1;
216 
217    case PIPE_CAP_FAKE_SW_MSAA:
218    case PIPE_CAP_TEXTURE_QUERY_LOD:
219       return 0;
220 
221    case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
222       return -8;
223    case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
224       return 7;
225 
226    case PIPE_CAP_SAMPLE_SHADING:
227    case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
228    case PIPE_CAP_VS_WINDOW_SPACE_POSITION:
229    case PIPE_CAP_MAX_VERTEX_STREAMS:
230    case PIPE_CAP_DRAW_INDIRECT:
231    case PIPE_CAP_FS_FINE_DERIVATIVE:
232       return 0;
233 
234    case PIPE_CAP_VENDOR_ID:
235    case PIPE_CAP_DEVICE_ID:
236       return 0xffffffff;
237 
238    case PIPE_CAP_ACCELERATED:
239    case PIPE_CAP_VIDEO_MEMORY:
240    case PIPE_CAP_UMA:
241       unreachable("driver must implement these.");
242 
243    case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
244       return 0;
245 
246    case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
247       /* GL minimum value */
248       return 2048;
249 
250    case PIPE_CAP_SAMPLER_VIEW_TARGET:
251    case PIPE_CAP_CLIP_HALFZ:
252    case PIPE_CAP_POLYGON_OFFSET_CLAMP:
253    case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
254    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
255    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY_COMPUTE_ONLY:
256    case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
257    case PIPE_CAP_DEVICE_PROTECTED_SURFACE:
258    case PIPE_CAP_DEVICE_PROTECTED_CONTEXT:
259    case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
260    case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
261    case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
262    case PIPE_CAP_DEPTH_BOUNDS_TEST:
263    case PIPE_CAP_TEXTURE_QUERY_SAMPLES:
264    case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
265       return 0;
266 
267    /* All drivers should expose this cap, as it is required for applications to
268     * be able to efficiently compile GL shaders from multiple threads during
269     * load.
270     */
271    case PIPE_CAP_SHAREABLE_SHADERS:
272       return 1;
273 
274    case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
275    case PIPE_CAP_CLEAR_SCISSORED:
276    case PIPE_CAP_DRAW_PARAMETERS:
277    case PIPE_CAP_SHADER_PACK_HALF_FLOAT:
278    case PIPE_CAP_MULTI_DRAW_INDIRECT:
279    case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
280    case PIPE_CAP_FS_POSITION_IS_SYSVAL:
281    case PIPE_CAP_FS_POINT_IS_SYSVAL:
282    case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL:
283       return 0;
284    case PIPE_CAP_MULTI_DRAW_INDIRECT_PARTIAL_STRIDE:
285       return 1;
286 
287    case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
288       /* Enables GL_ARB_shader_storage_buffer_object */
289       return 0;
290 
291    case PIPE_CAP_INVALIDATE_BUFFER:
292    case PIPE_CAP_GENERATE_MIPMAP:
293    case PIPE_CAP_STRING_MARKER:
294    case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
295    case PIPE_CAP_QUERY_BUFFER_OBJECT:
296    case PIPE_CAP_QUERY_MEMORY_INFO: /* Enables GL_ATI_meminfo */
297       return 0;
298 
299    case PIPE_CAP_PCI_GROUP:
300    case PIPE_CAP_PCI_BUS:
301    case PIPE_CAP_PCI_DEVICE:
302    case PIPE_CAP_PCI_FUNCTION:
303       unreachable("driver must implement these.");
304 
305    case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
306    case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
307    case PIPE_CAP_CULL_DISTANCE:
308    case PIPE_CAP_CULL_DISTANCE_NOCOMBINE:
309    case PIPE_CAP_SHADER_GROUP_VOTE:
310    case PIPE_CAP_MAX_WINDOW_RECTANGLES: /* Enables EXT_window_rectangles */
311    case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
312    case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
313    case PIPE_CAP_VIEWPORT_SWIZZLE:
314    case PIPE_CAP_VIEWPORT_MASK:
315    case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
316    case PIPE_CAP_SHADER_ARRAY_COMPONENTS:
317    case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
318    case PIPE_CAP_NATIVE_FENCE_FD:
319       return 0;
320 
321    case PIPE_CAP_RASTERIZER_SUBPIXEL_BITS:
322       return 4; /* GLES 2.0 minimum value */
323 
324    case PIPE_CAP_PREFER_BACK_BUFFER_REUSE:
325       return 1;
326 
327    case PIPE_CAP_GLSL_TESS_LEVELS_AS_INPUTS:
328       return 0;
329 
330    case PIPE_CAP_FBFETCH:
331    case PIPE_CAP_FBFETCH_COHERENT:
332    case PIPE_CAP_FBFETCH_ZS:
333    case PIPE_CAP_BLEND_EQUATION_ADVANCED:
334    case PIPE_CAP_LEGACY_MATH_RULES:
335    case PIPE_CAP_FP16:
336    case PIPE_CAP_DOUBLES:
337    case PIPE_CAP_INT64:
338    case PIPE_CAP_TGSI_TEX_TXF_LZ:
339    case PIPE_CAP_SHADER_CLOCK:
340    case PIPE_CAP_POLYGON_MODE_FILL_RECTANGLE:
341    case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE:
342    case PIPE_CAP_SHADER_BALLOT:
343    case PIPE_CAP_TES_LAYER_VIEWPORT:
344    case PIPE_CAP_CAN_BIND_CONST_BUFFER_AS_VERTEX:
345    case PIPE_CAP_TGSI_DIV:
346    case PIPE_CAP_NIR_ATOMICS_AS_DEREF:
347       return 0;
348 
349    case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
350       /* Drivers generally support this, and it reduces GL overhead just to
351        * throw an error when buffers are mapped.
352        */
353       return 1;
354 
355    case PIPE_CAP_PREFER_IMM_ARRAYS_AS_CONSTBUF:
356       /* Don't unset this unless your driver can do better, like using nir_opt_large_constants() */
357       return 1;
358 
359    case PIPE_CAP_POST_DEPTH_COVERAGE:
360    case PIPE_CAP_BINDLESS_TEXTURE:
361    case PIPE_CAP_NIR_SAMPLERS_AS_DEREF:
362    case PIPE_CAP_QUERY_SO_OVERFLOW:
363    case PIPE_CAP_MEMOBJ:
364    case PIPE_CAP_LOAD_CONSTBUF:
365    case PIPE_CAP_TILE_RASTER_ORDER:
366       return 0;
367 
368    case PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
369       /* nonzero overrides defaults */
370       return 0;
371 
372    case PIPE_CAP_FRAMEBUFFER_MSAA_CONSTRAINTS:
373    case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET:
374    case PIPE_CAP_CONTEXT_PRIORITY_MASK:
375    case PIPE_CAP_FENCE_SIGNAL:
376    case PIPE_CAP_CONSTBUF0_FLAGS:
377    case PIPE_CAP_PACKED_UNIFORMS:
378    case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_TRIANGLES:
379    case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_POINTS_LINES:
380    case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_TRIANGLES:
381    case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES:
382    case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS:
383    case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE:
384    case PIPE_CAP_CONSERVATIVE_RASTER_INNER_COVERAGE:
385    case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
386    case PIPE_CAP_MAX_COMBINED_SHADER_BUFFERS:
387    case PIPE_CAP_MAX_COMBINED_HW_ATOMIC_COUNTERS:
388    case PIPE_CAP_MAX_COMBINED_HW_ATOMIC_COUNTER_BUFFERS:
389    case PIPE_CAP_IMAGE_ATOMIC_FLOAT_ADD:
390    case PIPE_CAP_IMAGE_LOAD_FORMATTED:
391    case PIPE_CAP_IMAGE_STORE_FORMATTED:
392    case PIPE_CAP_PREFER_COMPUTE_FOR_MULTIMEDIA:
393    case PIPE_CAP_FRAGMENT_SHADER_INTERLOCK:
394    case PIPE_CAP_ATOMIC_FLOAT_MINMAX:
395    case PIPE_CAP_SHADER_SAMPLES_IDENTICAL:
396    case PIPE_CAP_IMAGE_ATOMIC_INC_WRAP:
397    case PIPE_CAP_TGSI_TG4_COMPONENT_IN_SWIZZLE:
398    case PIPE_CAP_GLSL_ZERO_INIT:
399    case PIPE_CAP_ALLOW_DRAW_OUT_OF_ORDER:
400       return 0;
401 
402    case PIPE_CAP_MAX_GS_INVOCATIONS:
403       return 32;
404 
405    case PIPE_CAP_MAX_SHADER_BUFFER_SIZE_UINT:
406       return 1 << 27;
407 
408    case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:
409    case PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET:
410       return 0;
411 
412    case PIPE_CAP_MAX_VERTEX_ELEMENT_SRC_OFFSET:
413       return 2047;
414 
415    case PIPE_CAP_SURFACE_SAMPLE_COUNT:
416       return 0;
417    case PIPE_CAP_DEST_SURFACE_SRGB_CONTROL:
418       return 1;
419 
420    case PIPE_CAP_MAX_VARYINGS:
421       return 8;
422 
423    case PIPE_CAP_COMPUTE_GRID_INFO_LAST_BLOCK:
424       return 0;
425 
426    case PIPE_CAP_COMPUTE_SHADER_DERIVATIVES:
427       return 0;
428 
429    case PIPE_CAP_THROTTLE:
430       return 1;
431 
432    case PIPE_CAP_TEXTURE_SHADOW_LOD:
433       return 0;
434 
435    case PIPE_CAP_GL_SPIRV:
436    case PIPE_CAP_GL_SPIRV_VARIABLE_POINTERS:
437       return 0;
438 
439    case PIPE_CAP_DEMOTE_TO_HELPER_INVOCATION:
440       return 0;
441 
442    case PIPE_CAP_DMABUF:
443 #if defined(HAVE_LIBDRM) && (DETECT_OS_LINUX || DETECT_OS_BSD || DETECT_OS_MANAGARM)
444       fd = pscreen->get_screen_fd(pscreen);
445       if (fd != -1 && (drmGetCap(fd, DRM_CAP_PRIME, &cap) == 0))
446          return cap;
447       else
448          return 0;
449 #else
450       return 0;
451 #endif
452 
453    case PIPE_CAP_CL_GL_SHARING:
454       return 0;
455 
456    case PIPE_CAP_TEXTURE_SHADOW_MAP: /* Enables ARB_shadow */
457       return 1;
458 
459    case PIPE_CAP_FLATSHADE:
460    case PIPE_CAP_ALPHA_TEST:
461    case PIPE_CAP_POINT_SIZE_FIXED:
462    case PIPE_CAP_TWO_SIDED_COLOR:
463    case PIPE_CAP_CLIP_PLANES:
464       return 1;
465 
466    case PIPE_CAP_MAX_VERTEX_BUFFERS:
467       return 16;
468 
469    case PIPE_CAP_OPENCL_INTEGER_FUNCTIONS:
470    case PIPE_CAP_INTEGER_MULTIPLY_32X16:
471       return 0;
472    case PIPE_CAP_NIR_IMAGES_AS_DEREF:
473       return 1;
474 
475    case PIPE_CAP_FRONTEND_NOOP:
476       /* Enables INTEL_blackhole_render */
477       return 0;
478 
479    case PIPE_CAP_PACKED_STREAM_OUTPUT:
480       return 1;
481 
482    case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED:
483    case PIPE_CAP_PSIZ_CLAMPED:
484    case PIPE_CAP_MAP_UNSYNCHRONIZED_THREAD_SAFE:
485       return 0;
486 
487    case PIPE_CAP_GL_BEGIN_END_BUFFER_SIZE:
488       return 512 * 1024;
489 
490    case PIPE_CAP_SYSTEM_SVM:
491    case PIPE_CAP_ALPHA_TO_COVERAGE_DITHER_CONTROL:
492    case PIPE_CAP_NO_CLIP_ON_COPY_TEX:
493    case PIPE_CAP_MAX_TEXTURE_MB:
494    case PIPE_CAP_PREFER_REAL_BUFFER_IN_CONSTBUF0:
495       return 0;
496 
497    case PIPE_CAP_TEXRECT:
498       return 1;
499 
500    case PIPE_CAP_SHADER_ATOMIC_INT64:
501       return 0;
502 
503    case PIPE_CAP_SAMPLER_REDUCTION_MINMAX:
504    case PIPE_CAP_SAMPLER_REDUCTION_MINMAX_ARB:
505       return 0;
506 
507    case PIPE_CAP_ALLOW_DYNAMIC_VAO_FASTPATH:
508       return 1;
509 
510    case PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART:
511    case PIPE_CAP_DRAW_VERTEX_STATE:
512       return 0;
513 
514    case PIPE_CAP_PREFER_POT_ALIGNED_VARYINGS:
515       return 0;
516 
517    case PIPE_CAP_MAX_SPARSE_TEXTURE_SIZE:
518    case PIPE_CAP_MAX_SPARSE_3D_TEXTURE_SIZE:
519    case PIPE_CAP_MAX_SPARSE_ARRAY_TEXTURE_LAYERS:
520    case PIPE_CAP_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS:
521    case PIPE_CAP_QUERY_SPARSE_TEXTURE_RESIDENCY:
522    case PIPE_CAP_CLAMP_SPARSE_TEXTURE_LOD:
523    case PIPE_CAP_TIMELINE_SEMAPHORE_IMPORT:
524    case PIPE_CAP_ALLOW_GLTHREAD_BUFFER_SUBDATA_OPT:
525       return 0;
526 
527    case PIPE_CAP_MAX_CONSTANT_BUFFER_SIZE_UINT:
528       return pscreen->get_shader_param(pscreen, PIPE_SHADER_FRAGMENT,
529                                        PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE);
530 
531    case PIPE_CAP_HARDWARE_GL_SELECT: {
532       /* =0: on CPU, always disabled
533        * >0: on GPU, enable by default, user can disable it manually
534        * <0: unknown, disable by default, user can enable it manually
535        */
536       int accel = pscreen->get_param(pscreen, PIPE_CAP_ACCELERATED);
537 
538       return !!accel && debug_get_bool_option("MESA_HW_ACCEL_SELECT", accel > 0) &&
539          /* internal geometry shader need indirect array access */
540          pscreen->get_shader_param(pscreen, PIPE_SHADER_GEOMETRY,
541                                    PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR) &&
542          /* internal geometry shader need SSBO support */
543          pscreen->get_shader_param(pscreen, PIPE_SHADER_GEOMETRY,
544                                    PIPE_SHADER_CAP_MAX_SHADER_BUFFERS);
545    }
546 
547    case PIPE_CAP_QUERY_TIMESTAMP_BITS:
548       return 64;
549 
550    case PIPE_CAP_VALIDATE_ALL_DIRTY_STATES:
551    case PIPE_CAP_NULL_TEXTURES:
552    case PIPE_CAP_ASTC_VOID_EXTENTS_NEED_DENORM_FLUSH:
553    case PIPE_CAP_ASTC_DECODE_MODE:
554    case PIPE_CAP_HAS_CONST_BW:
555       return 0;
556 
557    case PIPE_CAP_TEXTURE_SAMPLER_INDEPENDENT:
558       /* this is expected of gallium drivers, but some just don't support it */
559       return 1;
560 
561    case PIPE_CAP_PERFORMANCE_MONITOR:
562       return pscreen->get_driver_query_info && pscreen->get_driver_query_group_info &&
563              pscreen->get_driver_query_group_info(pscreen, 0, NULL) != 0;
564 
565    case PIPE_CAP_SHADER_SUBGROUP_SIZE:
566    case PIPE_CAP_SHADER_SUBGROUP_SUPPORTED_STAGES:
567    case PIPE_CAP_SHADER_SUBGROUP_SUPPORTED_FEATURES:
568    case PIPE_CAP_SHADER_SUBGROUP_QUAD_ALL_STAGES:
569       return 0;
570 
571    default:
572       unreachable("bad PIPE_CAP_*");
573    }
574 }
575 
u_default_get_timestamp(UNUSED struct pipe_screen * screen)576 uint64_t u_default_get_timestamp(UNUSED struct pipe_screen *screen)
577 {
578    return os_time_get_nano();
579 }
580 
581 static uint32_t
hash_file_description(const void * key)582 hash_file_description(const void *key)
583 {
584    int fd = pointer_to_intptr(key);
585    struct stat stat;
586 
587    // File descriptions can't be hashed, but it should be safe to assume
588    // that the same file description will always refer to he same file
589    if (fstat(fd, &stat) == -1)
590       return ~0; // Make sure fstat failing won't result in a random hash
591 
592    return stat.st_dev ^ stat.st_ino ^ stat.st_rdev;
593 }
594 
595 
596 static bool
equal_file_description(const void * key1,const void * key2)597 equal_file_description(const void *key1, const void *key2)
598 {
599    int ret;
600    int fd1 = pointer_to_intptr(key1);
601    int fd2 = pointer_to_intptr(key2);
602    struct stat stat1, stat2;
603 
604    // If the file descriptors are the same, the file description will be too
605    // This will also catch sentinels, such as -1
606    if (fd1 == fd2)
607       return true;
608 
609    ret = os_same_file_description(fd1, fd2);
610    if (ret >= 0)
611       return (ret == 0);
612 
613    {
614       static bool has_warned;
615       if (!has_warned)
616          fprintf(stderr, "os_same_file_description couldn't determine if "
617                  "two DRM fds reference the same file description. (%s)\n"
618                  "Let's just assume that file descriptors for the same file probably"
619                  "share the file description instead. This may cause problems when"
620                  "that isn't the case.\n", strerror(errno));
621       has_warned = true;
622    }
623 
624    // Let's at least check that it's the same file, different files can't
625    // have the same file descriptions
626    fstat(fd1, &stat1);
627    fstat(fd2, &stat2);
628 
629    return stat1.st_dev == stat2.st_dev &&
630           stat1.st_ino == stat2.st_ino &&
631           stat1.st_rdev == stat2.st_rdev;
632 }
633 
634 
635 static struct hash_table *
hash_table_create_file_description_keys(void)636 hash_table_create_file_description_keys(void)
637 {
638    return _mesa_hash_table_create(NULL, hash_file_description, equal_file_description);
639 }
640 
641 static struct hash_table *fd_tab = NULL;
642 
643 static simple_mtx_t screen_mutex = SIMPLE_MTX_INITIALIZER;
644 
645 static void
drm_screen_destroy(struct pipe_screen * pscreen)646 drm_screen_destroy(struct pipe_screen *pscreen)
647 {
648    bool destroy;
649 
650    simple_mtx_lock(&screen_mutex);
651    destroy = --pscreen->refcnt == 0;
652    if (destroy) {
653       int fd = pscreen->get_screen_fd(pscreen);
654       _mesa_hash_table_remove_key(fd_tab, intptr_to_pointer(fd));
655 
656       if (!fd_tab->entries) {
657          _mesa_hash_table_destroy(fd_tab, NULL);
658          fd_tab = NULL;
659       }
660    }
661    simple_mtx_unlock(&screen_mutex);
662 
663    if (destroy) {
664       pscreen->destroy = pscreen->winsys_priv;
665       pscreen->destroy(pscreen);
666    }
667 }
668 
669 struct pipe_screen *
u_pipe_screen_lookup_or_create(int gpu_fd,const struct pipe_screen_config * config,struct renderonly * ro,pipe_screen_create_function screen_create)670 u_pipe_screen_lookup_or_create(int gpu_fd,
671                                const struct pipe_screen_config *config,
672                                struct renderonly *ro,
673                                pipe_screen_create_function screen_create)
674 {
675    struct pipe_screen *pscreen = NULL;
676 
677    simple_mtx_lock(&screen_mutex);
678    if (!fd_tab) {
679       fd_tab = hash_table_create_file_description_keys();
680       if (!fd_tab)
681          goto unlock;
682    }
683 
684    pscreen = util_hash_table_get(fd_tab, intptr_to_pointer(gpu_fd));
685    if (pscreen) {
686       pscreen->refcnt++;
687    } else {
688       pscreen = screen_create(gpu_fd, config, ro);
689       if (pscreen) {
690          pscreen->refcnt = 1;
691          _mesa_hash_table_insert(fd_tab, intptr_to_pointer(gpu_fd), pscreen);
692 
693          /* Bit of a hack, to avoid circular linkage dependency,
694           * ie. pipe driver having to call in to winsys, we
695           * override the pipe drivers screen->destroy() */
696          pscreen->winsys_priv = pscreen->destroy;
697          pscreen->destroy = drm_screen_destroy;
698       }
699    }
700 
701 unlock:
702    simple_mtx_unlock(&screen_mutex);
703    return pscreen;
704 }
705