• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_3D_LEVELS:
77    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
78       unreachable("driver must implement these.");
79 
80    case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
81    case PIPE_CAP_BLEND_EQUATION_SEPARATE:
82    case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
83    case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
84    case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: /* enables EXT_transform_feedback */
85    case PIPE_CAP_PRIMITIVE_RESTART:
86    case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
87    case PIPE_CAP_INDEP_BLEND_ENABLE:
88    case PIPE_CAP_INDEP_BLEND_FUNC:
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       return 0;
104 
105    case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART:
106    case PIPE_CAP_SUPPORTED_PRIM_MODES:
107       return BITFIELD_MASK(MESA_PRIM_COUNT);
108 
109    case PIPE_CAP_MIN_TEXEL_OFFSET:
110       /* GL 3.x minimum value. */
111       return -8;
112    case PIPE_CAP_MAX_TEXEL_OFFSET:
113       return 7;
114 
115    case PIPE_CAP_CONDITIONAL_RENDER:
116    case PIPE_CAP_TEXTURE_BARRIER:
117       return 0;
118 
119    case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
120       /* GL_EXT_transform_feedback minimum value. */
121       return 4;
122    case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
123       return 64;
124 
125    case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
126    case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
127    case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
128    case PIPE_CAP_VERTEX_COLOR_CLAMPED:
129       return 0;
130 
131    case PIPE_CAP_GLSL_FEATURE_LEVEL:
132    case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
133       /* Minimum GLSL level implemented by gallium drivers. */
134       return 120;
135 
136    case PIPE_CAP_ESSL_FEATURE_LEVEL:
137       /* Tell gallium frontend to fallback to PIPE_CAP_GLSL_FEATURE_LEVEL */
138       return 0;
139 
140    case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
141    case PIPE_CAP_USER_VERTEX_BUFFERS:
142    case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
143    case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
144    case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
145    case PIPE_CAP_VERTEX_ATTRIB_ELEMENT_ALIGNED_ONLY:
146    case PIPE_CAP_COMPUTE:
147       return 0;
148 
149    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
150       /* GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT default value. */
151       return 1;
152 
153    case PIPE_CAP_START_INSTANCE:
154    case PIPE_CAP_QUERY_TIMESTAMP:
155    case PIPE_CAP_TIMER_RESOLUTION:
156    case PIPE_CAP_TEXTURE_MULTISAMPLE:
157       return 0;
158 
159    case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
160       /* GL_ARB_map_buffer_alignment minimum value. All drivers expose the
161        * extension.
162        */
163       return 64;
164 
165    case PIPE_CAP_CUBE_MAP_ARRAY:
166    case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
167       return 0;
168 
169    case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
170       /* GL_EXT_texture_buffer minimum value. */
171       return 256;
172 
173    case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
174    case PIPE_CAP_TGSI_TEXCOORD:
175       return 0;
176 
177    case PIPE_CAP_TEXTURE_TRANSFER_MODES:
178       return PIPE_TEXTURE_TRANSFER_BLIT;
179 
180    case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
181    case PIPE_CAP_QUERY_PIPELINE_STATISTICS_SINGLE:
182    case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
183       return 0;
184 
185    case PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT:
186       /* GL_EXT_texture_buffer minimum value. */
187       return 65536;
188 
189    case PIPE_CAP_LINEAR_IMAGE_PITCH_ALIGNMENT:
190       return 0;
191 
192    case PIPE_CAP_LINEAR_IMAGE_BASE_ADDRESS_ALIGNMENT:
193       return 0;
194 
195    case PIPE_CAP_MAX_VIEWPORTS:
196       return 1;
197 
198    case PIPE_CAP_ENDIANNESS:
199       return PIPE_ENDIAN_LITTLE;
200 
201    case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
202    case PIPE_CAP_VS_LAYER_VIEWPORT:
203    case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
204    case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
205    case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: /* Enables ARB_texture_gather */
206    case PIPE_CAP_TEXTURE_GATHER_SM5:
207       return 0;
208 
209    /* All new drivers should support persistent/coherent mappings. This CAP
210     * should only be unset by layered drivers whose host drivers cannot support
211     * coherent mappings.
212     */
213    case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
214       return 1;
215 
216    case PIPE_CAP_FAKE_SW_MSAA:
217    case PIPE_CAP_TEXTURE_QUERY_LOD:
218       return 0;
219 
220    case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
221       return -8;
222    case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
223       return 7;
224 
225    case PIPE_CAP_SAMPLE_SHADING:
226    case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
227    case PIPE_CAP_VS_WINDOW_SPACE_POSITION:
228    case PIPE_CAP_MAX_VERTEX_STREAMS:
229    case PIPE_CAP_DRAW_INDIRECT:
230    case PIPE_CAP_FS_FINE_DERIVATIVE:
231       return 0;
232 
233    case PIPE_CAP_VENDOR_ID:
234    case PIPE_CAP_DEVICE_ID:
235       return 0xffffffff;
236 
237    case PIPE_CAP_ACCELERATED:
238    case PIPE_CAP_VIDEO_MEMORY:
239    case PIPE_CAP_UMA:
240       unreachable("driver must implement these.");
241 
242    case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
243       return 0;
244 
245    case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
246       /* GL minimum value */
247       return 2048;
248 
249    case PIPE_CAP_SAMPLER_VIEW_TARGET:
250    case PIPE_CAP_CLIP_HALFZ:
251    case PIPE_CAP_POLYGON_OFFSET_CLAMP:
252    case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
253    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
254    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY_COMPUTE_ONLY:
255    case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
256    case PIPE_CAP_DEVICE_PROTECTED_SURFACE:
257    case PIPE_CAP_DEVICE_PROTECTED_CONTEXT:
258    case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
259    case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
260    case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
261    case PIPE_CAP_DEPTH_BOUNDS_TEST:
262    case PIPE_CAP_TEXTURE_QUERY_SAMPLES:
263    case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
264       return 0;
265 
266    /* All drivers should expose this cap, as it is required for applications to
267     * be able to efficiently compile GL shaders from multiple threads during
268     * load.
269     */
270    case PIPE_CAP_SHAREABLE_SHADERS:
271       return 1;
272 
273    case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
274    case PIPE_CAP_CLEAR_SCISSORED:
275    case PIPE_CAP_DRAW_PARAMETERS:
276    case PIPE_CAP_SHADER_PACK_HALF_FLOAT:
277    case PIPE_CAP_MULTI_DRAW_INDIRECT:
278    case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
279    case PIPE_CAP_FS_POSITION_IS_SYSVAL:
280    case PIPE_CAP_FS_POINT_IS_SYSVAL:
281    case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL:
282       return 0;
283    case PIPE_CAP_MULTI_DRAW_INDIRECT_PARTIAL_STRIDE:
284       return 1;
285 
286    case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
287       /* Enables GL_ARB_shader_storage_buffer_object */
288       return 0;
289 
290    case PIPE_CAP_INVALIDATE_BUFFER:
291    case PIPE_CAP_GENERATE_MIPMAP:
292    case PIPE_CAP_STRING_MARKER:
293    case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
294    case PIPE_CAP_QUERY_BUFFER_OBJECT:
295    case PIPE_CAP_QUERY_MEMORY_INFO: /* Enables GL_ATI_meminfo */
296       return 0;
297 
298    case PIPE_CAP_PCI_GROUP:
299    case PIPE_CAP_PCI_BUS:
300    case PIPE_CAP_PCI_DEVICE:
301    case PIPE_CAP_PCI_FUNCTION:
302       unreachable("driver must implement these.");
303 
304    case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
305    case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
306    case PIPE_CAP_CULL_DISTANCE:
307    case PIPE_CAP_CULL_DISTANCE_NOCOMBINE:
308    case PIPE_CAP_SHADER_GROUP_VOTE:
309    case PIPE_CAP_MAX_WINDOW_RECTANGLES: /* Enables EXT_window_rectangles */
310    case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
311    case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
312    case PIPE_CAP_VIEWPORT_SWIZZLE:
313    case PIPE_CAP_VIEWPORT_MASK:
314    case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
315    case PIPE_CAP_SHADER_ARRAY_COMPONENTS:
316    case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
317    case PIPE_CAP_SHADER_CAN_READ_OUTPUTS:
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_NIR_COMPACT_ARRAYS:
363    case PIPE_CAP_QUERY_SO_OVERFLOW:
364    case PIPE_CAP_MEMOBJ:
365    case PIPE_CAP_LOAD_CONSTBUF:
366    case PIPE_CAP_TILE_RASTER_ORDER:
367       return 0;
368 
369    case PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
370       /* nonzero overrides defaults */
371       return 0;
372 
373    case PIPE_CAP_FRAMEBUFFER_MSAA_CONSTRAINTS:
374    case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET:
375    case PIPE_CAP_CONTEXT_PRIORITY_MASK:
376    case PIPE_CAP_FENCE_SIGNAL:
377    case PIPE_CAP_CONSTBUF0_FLAGS:
378    case PIPE_CAP_PACKED_UNIFORMS:
379    case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_TRIANGLES:
380    case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_POINTS_LINES:
381    case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_TRIANGLES:
382    case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES:
383    case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS:
384    case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE:
385    case PIPE_CAP_CONSERVATIVE_RASTER_INNER_COVERAGE:
386    case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
387    case PIPE_CAP_MAX_COMBINED_SHADER_BUFFERS:
388    case PIPE_CAP_MAX_COMBINED_HW_ATOMIC_COUNTERS:
389    case PIPE_CAP_MAX_COMBINED_HW_ATOMIC_COUNTER_BUFFERS:
390    case PIPE_CAP_IMAGE_ATOMIC_FLOAT_ADD:
391    case PIPE_CAP_IMAGE_LOAD_FORMATTED:
392    case PIPE_CAP_IMAGE_STORE_FORMATTED:
393    case PIPE_CAP_PREFER_COMPUTE_FOR_MULTIMEDIA:
394    case PIPE_CAP_FRAGMENT_SHADER_INTERLOCK:
395    case PIPE_CAP_ATOMIC_FLOAT_MINMAX:
396    case PIPE_CAP_SHADER_SAMPLES_IDENTICAL:
397    case PIPE_CAP_IMAGE_ATOMIC_INC_WRAP:
398    case PIPE_CAP_TGSI_TG4_COMPONENT_IN_SWIZZLE:
399    case PIPE_CAP_GLSL_ZERO_INIT:
400    case PIPE_CAP_ALLOW_DRAW_OUT_OF_ORDER:
401       return 0;
402 
403    case PIPE_CAP_MAX_GS_INVOCATIONS:
404       return 32;
405 
406    case PIPE_CAP_MAX_SHADER_BUFFER_SIZE_UINT:
407       return 1 << 27;
408 
409    case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:
410    case PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET:
411       return 0;
412 
413    case PIPE_CAP_MAX_VERTEX_ELEMENT_SRC_OFFSET:
414       return 2047;
415 
416    case PIPE_CAP_SURFACE_SAMPLE_COUNT:
417       return 0;
418    case PIPE_CAP_DEST_SURFACE_SRGB_CONTROL:
419       return 1;
420 
421    case PIPE_CAP_MAX_VARYINGS:
422       return 8;
423 
424    case PIPE_CAP_COMPUTE_GRID_INFO_LAST_BLOCK:
425       return 0;
426 
427    case PIPE_CAP_COMPUTE_SHADER_DERIVATIVES:
428       return 0;
429 
430    case PIPE_CAP_THROTTLE:
431       return 1;
432 
433    case PIPE_CAP_TEXTURE_SHADOW_LOD:
434       return 0;
435 
436    case PIPE_CAP_GL_SPIRV:
437    case PIPE_CAP_GL_SPIRV_VARIABLE_POINTERS:
438       return 0;
439 
440    case PIPE_CAP_DEMOTE_TO_HELPER_INVOCATION:
441       return 0;
442 
443    case PIPE_CAP_DMABUF:
444 #if defined(HAVE_LIBDRM) && (DETECT_OS_LINUX || DETECT_OS_BSD || DETECT_OS_MANAGARM)
445       fd = pscreen->get_screen_fd(pscreen);
446       if (fd != -1 && (drmGetCap(fd, DRM_CAP_PRIME, &cap) == 0))
447          return cap;
448       else
449          return 0;
450 #else
451       return 0;
452 #endif
453 
454    case PIPE_CAP_CL_GL_SHARING:
455       return 0;
456 
457    case PIPE_CAP_TEXTURE_SHADOW_MAP: /* Enables ARB_shadow */
458       return 1;
459 
460    case PIPE_CAP_FLATSHADE:
461    case PIPE_CAP_ALPHA_TEST:
462    case PIPE_CAP_POINT_SIZE_FIXED:
463    case PIPE_CAP_TWO_SIDED_COLOR:
464    case PIPE_CAP_CLIP_PLANES:
465       return 1;
466 
467    case PIPE_CAP_MAX_VERTEX_BUFFERS:
468       return 16;
469 
470    case PIPE_CAP_OPENCL_INTEGER_FUNCTIONS:
471    case PIPE_CAP_INTEGER_MULTIPLY_32X16:
472       return 0;
473    case PIPE_CAP_NIR_IMAGES_AS_DEREF:
474       return 1;
475 
476    case PIPE_CAP_FRONTEND_NOOP:
477       /* Enables INTEL_blackhole_render */
478       return 0;
479 
480    case PIPE_CAP_PACKED_STREAM_OUTPUT:
481       return 1;
482 
483    case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED:
484    case PIPE_CAP_PSIZ_CLAMPED:
485    case PIPE_CAP_MAP_UNSYNCHRONIZED_THREAD_SAFE:
486       return 0;
487 
488    case PIPE_CAP_GL_BEGIN_END_BUFFER_SIZE:
489       return 512 * 1024;
490 
491    case PIPE_CAP_SYSTEM_SVM:
492    case PIPE_CAP_ALPHA_TO_COVERAGE_DITHER_CONTROL:
493    case PIPE_CAP_NO_CLIP_ON_COPY_TEX:
494    case PIPE_CAP_MAX_TEXTURE_MB:
495    case PIPE_CAP_PREFER_REAL_BUFFER_IN_CONSTBUF0:
496       return 0;
497 
498    case PIPE_CAP_TEXRECT:
499       return 1;
500 
501    case PIPE_CAP_SHADER_ATOMIC_INT64:
502       return 0;
503 
504    case PIPE_CAP_SAMPLER_REDUCTION_MINMAX:
505    case PIPE_CAP_SAMPLER_REDUCTION_MINMAX_ARB:
506       return 0;
507 
508    case PIPE_CAP_ALLOW_DYNAMIC_VAO_FASTPATH:
509       return 1;
510 
511    case PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART:
512    case PIPE_CAP_DRAW_VERTEX_STATE:
513       return 0;
514 
515    case PIPE_CAP_PREFER_POT_ALIGNED_VARYINGS:
516       return 0;
517 
518    case PIPE_CAP_MAX_SPARSE_TEXTURE_SIZE:
519    case PIPE_CAP_MAX_SPARSE_3D_TEXTURE_SIZE:
520    case PIPE_CAP_MAX_SPARSE_ARRAY_TEXTURE_LAYERS:
521    case PIPE_CAP_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS:
522    case PIPE_CAP_QUERY_SPARSE_TEXTURE_RESIDENCY:
523    case PIPE_CAP_CLAMP_SPARSE_TEXTURE_LOD:
524    case PIPE_CAP_TIMELINE_SEMAPHORE_IMPORT:
525    case PIPE_CAP_ALLOW_GLTHREAD_BUFFER_SUBDATA_OPT:
526       return 0;
527 
528    case PIPE_CAP_MAX_CONSTANT_BUFFER_SIZE_UINT:
529       return pscreen->get_shader_param(pscreen, PIPE_SHADER_FRAGMENT,
530                                        PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE);
531 
532    case PIPE_CAP_HARDWARE_GL_SELECT: {
533       /* =0: on CPU, always disabled
534        * >0: on GPU, enable by default, user can disable it manually
535        * <0: unknown, disable by default, user can enable it manually
536        */
537       int accel = pscreen->get_param(pscreen, PIPE_CAP_ACCELERATED);
538 
539       return !!accel && debug_get_bool_option("MESA_HW_ACCEL_SELECT", accel > 0) &&
540          /* internal geometry shader need indirect array access */
541          pscreen->get_shader_param(pscreen, PIPE_SHADER_GEOMETRY,
542                                    PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR) &&
543          /* internal geometry shader need SSBO support */
544          pscreen->get_shader_param(pscreen, PIPE_SHADER_GEOMETRY,
545                                    PIPE_SHADER_CAP_MAX_SHADER_BUFFERS);
546    }
547 
548    case PIPE_CAP_QUERY_TIMESTAMP_BITS:
549       return 64;
550 
551    case PIPE_CAP_VALIDATE_ALL_DIRTY_STATES:
552    case PIPE_CAP_NULL_TEXTURES:
553    case PIPE_CAP_ASTC_VOID_EXTENTS_NEED_DENORM_FLUSH:
554    case PIPE_CAP_HAS_CONST_BW:
555       return 0;
556 
557    case PIPE_CAP_PERFORMANCE_MONITOR:
558       return pscreen->get_driver_query_info && pscreen->get_driver_query_group_info &&
559              pscreen->get_driver_query_group_info(pscreen, 0, NULL) != 0;
560 
561    default:
562       unreachable("bad PIPE_CAP_*");
563    }
564 }
565 
u_default_get_timestamp(UNUSED struct pipe_screen * screen)566 uint64_t u_default_get_timestamp(UNUSED struct pipe_screen *screen)
567 {
568    return os_time_get_nano();
569 }
570 
571 static uint32_t
hash_file_description(const void * key)572 hash_file_description(const void *key)
573 {
574    int fd = pointer_to_intptr(key);
575    struct stat stat;
576 
577    // File descriptions can't be hashed, but it should be safe to assume
578    // that the same file description will always refer to he same file
579    if (fstat(fd, &stat) == -1)
580       return ~0; // Make sure fstat failing won't result in a random hash
581 
582    return stat.st_dev ^ stat.st_ino ^ stat.st_rdev;
583 }
584 
585 
586 static bool
equal_file_description(const void * key1,const void * key2)587 equal_file_description(const void *key1, const void *key2)
588 {
589    int ret;
590    int fd1 = pointer_to_intptr(key1);
591    int fd2 = pointer_to_intptr(key2);
592    struct stat stat1, stat2;
593 
594    // If the file descriptors are the same, the file description will be too
595    // This will also catch sentinels, such as -1
596    if (fd1 == fd2)
597       return true;
598 
599    ret = os_same_file_description(fd1, fd2);
600    if (ret >= 0)
601       return (ret == 0);
602 
603    {
604       static bool has_warned;
605       if (!has_warned)
606          fprintf(stderr, "os_same_file_description couldn't determine if "
607                  "two DRM fds reference the same file description. (%s)\n"
608                  "Let's just assume that file descriptors for the same file probably"
609                  "share the file description instead. This may cause problems when"
610                  "that isn't the case.\n", strerror(errno));
611       has_warned = true;
612    }
613 
614    // Let's at least check that it's the same file, different files can't
615    // have the same file descriptions
616    fstat(fd1, &stat1);
617    fstat(fd2, &stat2);
618 
619    return stat1.st_dev == stat2.st_dev &&
620           stat1.st_ino == stat2.st_ino &&
621           stat1.st_rdev == stat2.st_rdev;
622 }
623 
624 
625 static struct hash_table *
hash_table_create_file_description_keys(void)626 hash_table_create_file_description_keys(void)
627 {
628    return _mesa_hash_table_create(NULL, hash_file_description, equal_file_description);
629 }
630 
631 static struct hash_table *fd_tab = NULL;
632 
633 static simple_mtx_t screen_mutex = SIMPLE_MTX_INITIALIZER;
634 
635 static void
drm_screen_destroy(struct pipe_screen * pscreen)636 drm_screen_destroy(struct pipe_screen *pscreen)
637 {
638    bool destroy;
639 
640    simple_mtx_lock(&screen_mutex);
641    destroy = --pscreen->refcnt == 0;
642    if (destroy) {
643       int fd = pscreen->get_screen_fd(pscreen);
644       _mesa_hash_table_remove_key(fd_tab, intptr_to_pointer(fd));
645 
646       if (!fd_tab->entries) {
647          _mesa_hash_table_destroy(fd_tab, NULL);
648          fd_tab = NULL;
649       }
650    }
651    simple_mtx_unlock(&screen_mutex);
652 
653    if (destroy) {
654       pscreen->destroy = pscreen->winsys_priv;
655       pscreen->destroy(pscreen);
656    }
657 }
658 
659 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)660 u_pipe_screen_lookup_or_create(int gpu_fd,
661                                const struct pipe_screen_config *config,
662                                struct renderonly *ro,
663                                pipe_screen_create_function screen_create)
664 {
665    struct pipe_screen *pscreen = NULL;
666 
667    simple_mtx_lock(&screen_mutex);
668    if (!fd_tab) {
669       fd_tab = hash_table_create_file_description_keys();
670       if (!fd_tab)
671          goto unlock;
672    }
673 
674    pscreen = util_hash_table_get(fd_tab, intptr_to_pointer(gpu_fd));
675    if (pscreen) {
676       pscreen->refcnt++;
677    } else {
678       pscreen = screen_create(gpu_fd, config, ro);
679       if (pscreen) {
680          pscreen->refcnt = 1;
681          _mesa_hash_table_insert(fd_tab, intptr_to_pointer(gpu_fd), pscreen);
682 
683          /* Bit of a hack, to avoid circular linkage dependency,
684           * ie. pipe driver having to call in to winsys, we
685           * override the pipe drivers screen->destroy() */
686          pscreen->winsys_priv = pscreen->destroy;
687          pscreen->destroy = drm_screen_destroy;
688       }
689    }
690 
691 unlock:
692    simple_mtx_unlock(&screen_mutex);
693    return pscreen;
694 }
695