OSDN Git Service

gallium: add PIPE_CAP_MAX_GS_INVOCATIONS
[android-x86/external-mesa.git] / src / gallium / drivers / vc4 / vc4_screen.c
1 /*
2  * Copyright © 2014 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 "os/os_misc.h"
26 #include "pipe/p_defines.h"
27 #include "pipe/p_screen.h"
28 #include "pipe/p_state.h"
29
30 #include "util/u_cpu_detect.h"
31 #include "util/u_debug.h"
32 #include "util/u_memory.h"
33 #include "util/u_format.h"
34 #include "util/u_hash_table.h"
35 #include "util/ralloc.h"
36
37 #include <xf86drm.h>
38 #include "drm_fourcc.h"
39 #include "vc4_drm.h"
40 #include "vc4_screen.h"
41 #include "vc4_context.h"
42 #include "vc4_resource.h"
43
44 static const struct debug_named_value debug_options[] = {
45         { "cl",       VC4_DEBUG_CL,
46           "Dump command list during creation" },
47         { "surf",       VC4_DEBUG_SURFACE,
48           "Dump surface layouts" },
49         { "qpu",      VC4_DEBUG_QPU,
50           "Dump generated QPU instructions" },
51         { "qir",      VC4_DEBUG_QIR,
52           "Dump QPU IR during program compile" },
53         { "nir",      VC4_DEBUG_NIR,
54           "Dump NIR during program compile" },
55         { "tgsi",     VC4_DEBUG_TGSI,
56           "Dump TGSI during program compile" },
57         { "shaderdb", VC4_DEBUG_SHADERDB,
58           "Dump program compile information for shader-db analysis" },
59         { "perf",     VC4_DEBUG_PERF,
60           "Print during performance-related events" },
61         { "norast",   VC4_DEBUG_NORAST,
62           "Skip actual hardware execution of commands" },
63         { "always_flush", VC4_DEBUG_ALWAYS_FLUSH,
64           "Flush after each draw call" },
65         { "always_sync", VC4_DEBUG_ALWAYS_SYNC,
66           "Wait for finish after each flush" },
67 #ifdef USE_VC4_SIMULATOR
68         { "dump", VC4_DEBUG_DUMP,
69           "Write a GPU command stream trace file" },
70 #endif
71         { NULL }
72 };
73
74 DEBUG_GET_ONCE_FLAGS_OPTION(vc4_debug, "VC4_DEBUG", debug_options, 0)
75 uint32_t vc4_debug;
76
77 static const char *
78 vc4_screen_get_name(struct pipe_screen *pscreen)
79 {
80         struct vc4_screen *screen = vc4_screen(pscreen);
81
82         if (!screen->name) {
83                 screen->name = ralloc_asprintf(screen,
84                                                "VC4 V3D %d.%d",
85                                                screen->v3d_ver / 10,
86                                                screen->v3d_ver % 10);
87         }
88
89         return screen->name;
90 }
91
92 static const char *
93 vc4_screen_get_vendor(struct pipe_screen *pscreen)
94 {
95         return "Broadcom";
96 }
97
98 static void
99 vc4_screen_destroy(struct pipe_screen *pscreen)
100 {
101         struct vc4_screen *screen = vc4_screen(pscreen);
102
103         util_hash_table_destroy(screen->bo_handles);
104         vc4_bufmgr_destroy(pscreen);
105         slab_destroy_parent(&screen->transfer_pool);
106         free(screen->ro);
107
108 #ifdef USE_VC4_SIMULATOR
109         vc4_simulator_destroy(screen);
110 #endif
111
112         close(screen->fd);
113         ralloc_free(pscreen);
114 }
115
116 static bool
117 vc4_has_feature(struct vc4_screen *screen, uint32_t feature)
118 {
119         struct drm_vc4_get_param p = {
120                 .param = feature,
121         };
122         int ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &p);
123
124         if (ret != 0)
125                 return false;
126
127         return p.value;
128 }
129
130 static int
131 vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
132 {
133         struct vc4_screen *screen = vc4_screen(pscreen);
134
135         switch (param) {
136                 /* Supported features (boolean caps). */
137         case PIPE_CAP_VERTEX_COLOR_CLAMPED:
138         case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
139         case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
140         case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
141         case PIPE_CAP_NPOT_TEXTURES:
142         case PIPE_CAP_SHAREABLE_SHADERS:
143         case PIPE_CAP_BLEND_EQUATION_SEPARATE:
144         case PIPE_CAP_TEXTURE_MULTISAMPLE:
145         case PIPE_CAP_TEXTURE_SWIZZLE:
146         case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
147         case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
148         case PIPE_CAP_TEXTURE_BARRIER:
149                 return 1;
150
151         case PIPE_CAP_NATIVE_FENCE_FD:
152                 return screen->has_syncobj;
153
154         case PIPE_CAP_TILE_RASTER_ORDER:
155                 return vc4_has_feature(screen,
156                                        DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER);
157
158                 /* lying for GL 2.0 */
159         case PIPE_CAP_OCCLUSION_QUERY:
160         case PIPE_CAP_POINT_SPRITE:
161                 return 1;
162
163         case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
164                 return 256;
165
166         case PIPE_CAP_GLSL_FEATURE_LEVEL:
167         case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
168                 return 120;
169
170         case PIPE_CAP_MAX_VIEWPORTS:
171                 return 1;
172
173         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
174         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
175                 return 1;
176
177         case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
178         case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
179                 return 1;
180
181                 /* Unsupported features. */
182         case PIPE_CAP_ANISOTROPIC_FILTER:
183         case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
184         case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
185         case PIPE_CAP_CUBE_MAP_ARRAY:
186         case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
187         case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
188         case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
189         case PIPE_CAP_SEAMLESS_CUBE_MAP:
190         case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
191         case PIPE_CAP_TGSI_INSTANCEID:
192         case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
193         case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
194         case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
195         case PIPE_CAP_COMPUTE:
196         case PIPE_CAP_START_INSTANCE:
197         case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
198         case PIPE_CAP_SHADER_STENCIL_EXPORT:
199         case PIPE_CAP_TGSI_TEXCOORD:
200         case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
201         case PIPE_CAP_CONDITIONAL_RENDER:
202         case PIPE_CAP_PRIMITIVE_RESTART:
203         case PIPE_CAP_SM3:
204         case PIPE_CAP_INDEP_BLEND_ENABLE:
205         case PIPE_CAP_INDEP_BLEND_FUNC:
206         case PIPE_CAP_DEPTH_CLIP_DISABLE:
207         case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
208         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
209         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
210         case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
211         case PIPE_CAP_USER_VERTEX_BUFFERS:
212         case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
213         case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
214         case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
215         case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
216         case PIPE_CAP_TEXTURE_GATHER_SM5:
217         case PIPE_CAP_FAKE_SW_MSAA:
218         case PIPE_CAP_TEXTURE_QUERY_LOD:
219         case PIPE_CAP_SAMPLE_SHADING:
220         case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
221         case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
222         case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
223         case PIPE_CAP_MAX_TEXEL_OFFSET:
224         case PIPE_CAP_MAX_VERTEX_STREAMS:
225         case PIPE_CAP_DRAW_INDIRECT:
226         case PIPE_CAP_MULTI_DRAW_INDIRECT:
227         case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
228         case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
229         case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
230         case PIPE_CAP_SAMPLER_VIEW_TARGET:
231         case PIPE_CAP_CLIP_HALFZ:
232         case PIPE_CAP_VERTEXID_NOBASE:
233         case PIPE_CAP_POLYGON_OFFSET_CLAMP:
234         case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
235         case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
236         case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
237         case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
238         case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
239         case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
240         case PIPE_CAP_DEPTH_BOUNDS_TEST:
241         case PIPE_CAP_TGSI_TXQS:
242         case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
243         case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
244         case PIPE_CAP_CLEAR_TEXTURE:
245         case PIPE_CAP_DRAW_PARAMETERS:
246         case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
247         case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
248         case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
249         case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
250         case PIPE_CAP_INVALIDATE_BUFFER:
251         case PIPE_CAP_GENERATE_MIPMAP:
252         case PIPE_CAP_STRING_MARKER:
253         case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
254         case PIPE_CAP_QUERY_BUFFER_OBJECT:
255         case PIPE_CAP_QUERY_MEMORY_INFO:
256         case PIPE_CAP_PCI_GROUP:
257         case PIPE_CAP_PCI_BUS:
258         case PIPE_CAP_PCI_DEVICE:
259         case PIPE_CAP_PCI_FUNCTION:
260         case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
261         case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
262         case PIPE_CAP_CULL_DISTANCE:
263         case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
264         case PIPE_CAP_TGSI_VOTE:
265         case PIPE_CAP_MAX_WINDOW_RECTANGLES:
266         case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
267         case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
268         case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
269         case PIPE_CAP_TGSI_CAN_READ_OUTPUTS:
270         case PIPE_CAP_TGSI_FS_FBFETCH:
271         case PIPE_CAP_TGSI_MUL_ZERO_WINS:
272         case PIPE_CAP_DOUBLES:
273         case PIPE_CAP_INT64:
274         case PIPE_CAP_INT64_DIVMOD:
275         case PIPE_CAP_TGSI_TEX_TXF_LZ:
276         case PIPE_CAP_TGSI_CLOCK:
277         case PIPE_CAP_POLYGON_MODE_FILL_RECTANGLE:
278         case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE:
279         case PIPE_CAP_TGSI_BALLOT:
280         case PIPE_CAP_TGSI_TES_LAYER_VIEWPORT:
281         case PIPE_CAP_CAN_BIND_CONST_BUFFER_AS_VERTEX:
282         case PIPE_CAP_POST_DEPTH_COVERAGE:
283         case PIPE_CAP_BINDLESS_TEXTURE:
284         case PIPE_CAP_NIR_SAMPLERS_AS_DEREF:
285         case PIPE_CAP_QUERY_SO_OVERFLOW:
286         case PIPE_CAP_MEMOBJ:
287         case PIPE_CAP_LOAD_CONSTBUF:
288         case PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS:
289         case PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
290         case PIPE_CAP_FRAMEBUFFER_MSAA_CONSTRAINTS:
291         case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET:
292         case PIPE_CAP_CONTEXT_PRIORITY_MASK:
293         case PIPE_CAP_FENCE_SIGNAL:
294         case PIPE_CAP_CONSTBUF0_FLAGS:
295         case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_TRIANGLES:
296         case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_POINTS_LINES:
297         case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_TRIANGLES:
298         case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES:
299         case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE:
300         case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS:
301         case PIPE_CAP_PACKED_UNIFORMS:
302         case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
303                 return 0;
304
305                 /* Stream output. */
306         case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
307         case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
308         case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
309         case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
310         case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
311                 return 0;
312
313                 /* Geometry shader output, unsupported. */
314         case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
315         case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
316         case PIPE_CAP_MAX_GS_INVOCATIONS:
317                 return 0;
318
319                 /* Texturing. */
320         case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
321         case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
322                 return VC4_MAX_MIP_LEVELS;
323         case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
324                 /* Note: Not supported in hardware, just faking it. */
325                 return 5;
326         case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
327                 return 0;
328
329                 /* Render targets. */
330         case PIPE_CAP_MAX_RENDER_TARGETS:
331                 return 1;
332
333                 /* Queries. */
334         case PIPE_CAP_QUERY_TIME_ELAPSED:
335         case PIPE_CAP_QUERY_TIMESTAMP:
336                 return 0;
337
338         case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
339         case PIPE_CAP_MIN_TEXEL_OFFSET:
340                 return 0;
341
342         case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
343                 return 2048;
344
345         case PIPE_CAP_ENDIANNESS:
346                 return PIPE_ENDIAN_LITTLE;
347
348         case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
349                 return 64;
350
351         case PIPE_CAP_VENDOR_ID:
352                 return 0x14E4;
353         case PIPE_CAP_DEVICE_ID:
354                 return 0xFFFFFFFF;
355         case PIPE_CAP_ACCELERATED:
356                 return 1;
357         case PIPE_CAP_VIDEO_MEMORY: {
358                 uint64_t system_memory;
359
360                 if (!os_get_total_physical_memory(&system_memory))
361                         return 0;
362
363                 return (int)(system_memory >> 20);
364         }
365         case PIPE_CAP_UMA:
366                 return 1;
367
368         default:
369                 fprintf(stderr, "unknown param %d\n", param);
370                 return 0;
371         }
372 }
373
374 static float
375 vc4_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
376 {
377         switch (param) {
378         case PIPE_CAPF_MAX_LINE_WIDTH:
379         case PIPE_CAPF_MAX_LINE_WIDTH_AA:
380                 return 32;
381
382         case PIPE_CAPF_MAX_POINT_WIDTH:
383         case PIPE_CAPF_MAX_POINT_WIDTH_AA:
384                 return 512.0f;
385
386         case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
387                 return 0.0f;
388         case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
389                 return 0.0f;
390
391         case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
392         case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
393         case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
394                 return 0.0f;
395         default:
396                 fprintf(stderr, "unknown paramf %d\n", param);
397                 return 0;
398         }
399 }
400
401 static int
402 vc4_screen_get_shader_param(struct pipe_screen *pscreen,
403                             enum pipe_shader_type shader,
404                             enum pipe_shader_cap param)
405 {
406         if (shader != PIPE_SHADER_VERTEX &&
407             shader != PIPE_SHADER_FRAGMENT) {
408                 return 0;
409         }
410
411         /* this is probably not totally correct.. but it's a start: */
412         switch (param) {
413         case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
414         case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
415         case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
416         case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
417                 return 16384;
418
419         case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
420                 return vc4_screen(pscreen)->has_control_flow;
421
422         case PIPE_SHADER_CAP_MAX_INPUTS:
423                 return 8;
424         case PIPE_SHADER_CAP_MAX_OUTPUTS:
425                 return shader == PIPE_SHADER_FRAGMENT ? 1 : 8;
426         case PIPE_SHADER_CAP_MAX_TEMPS:
427                 return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
428         case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
429                 return 16 * 1024 * sizeof(float);
430         case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
431                 return 1;
432         case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
433                 return 0;
434         case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
435         case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
436         case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
437                 return 0;
438         case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
439                 return 1;
440         case PIPE_SHADER_CAP_SUBROUTINES:
441                 return 0;
442         case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
443                 return 0;
444         case PIPE_SHADER_CAP_INTEGERS:
445                 return 1;
446         case PIPE_SHADER_CAP_INT64_ATOMICS:
447         case PIPE_SHADER_CAP_FP16:
448         case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
449         case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
450         case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
451         case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
452         case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
453                 return 0;
454         case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
455         case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
456                 return VC4_MAX_TEXTURE_SAMPLERS;
457         case PIPE_SHADER_CAP_PREFERRED_IR:
458                 return PIPE_SHADER_IR_NIR;
459         case PIPE_SHADER_CAP_SUPPORTED_IRS:
460                 return 0;
461         case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
462                 return 32;
463         case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
464         case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
465         case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
466         case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
467         case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
468         case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
469                 return 0;
470         case PIPE_SHADER_CAP_SCALAR_ISA:
471                 return 1;
472         default:
473                 fprintf(stderr, "unknown shader param %d\n", param);
474                 return 0;
475         }
476         return 0;
477 }
478
479 static boolean
480 vc4_screen_is_format_supported(struct pipe_screen *pscreen,
481                                enum pipe_format format,
482                                enum pipe_texture_target target,
483                                unsigned sample_count,
484                                unsigned storage_sample_count,
485                                unsigned usage)
486 {
487         struct vc4_screen *screen = vc4_screen(pscreen);
488
489         if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
490                 return false;
491
492         if (sample_count > 1 && sample_count != VC4_MAX_SAMPLES)
493                 return FALSE;
494
495         if (target >= PIPE_MAX_TEXTURE_TYPES) {
496                 return FALSE;
497         }
498
499         if (usage & PIPE_BIND_VERTEX_BUFFER) {
500                 switch (format) {
501                 case PIPE_FORMAT_R32G32B32A32_FLOAT:
502                 case PIPE_FORMAT_R32G32B32_FLOAT:
503                 case PIPE_FORMAT_R32G32_FLOAT:
504                 case PIPE_FORMAT_R32_FLOAT:
505                 case PIPE_FORMAT_R32G32B32A32_SNORM:
506                 case PIPE_FORMAT_R32G32B32_SNORM:
507                 case PIPE_FORMAT_R32G32_SNORM:
508                 case PIPE_FORMAT_R32_SNORM:
509                 case PIPE_FORMAT_R32G32B32A32_SSCALED:
510                 case PIPE_FORMAT_R32G32B32_SSCALED:
511                 case PIPE_FORMAT_R32G32_SSCALED:
512                 case PIPE_FORMAT_R32_SSCALED:
513                 case PIPE_FORMAT_R16G16B16A16_UNORM:
514                 case PIPE_FORMAT_R16G16B16_UNORM:
515                 case PIPE_FORMAT_R16G16_UNORM:
516                 case PIPE_FORMAT_R16_UNORM:
517                 case PIPE_FORMAT_R16G16B16A16_SNORM:
518                 case PIPE_FORMAT_R16G16B16_SNORM:
519                 case PIPE_FORMAT_R16G16_SNORM:
520                 case PIPE_FORMAT_R16_SNORM:
521                 case PIPE_FORMAT_R16G16B16A16_USCALED:
522                 case PIPE_FORMAT_R16G16B16_USCALED:
523                 case PIPE_FORMAT_R16G16_USCALED:
524                 case PIPE_FORMAT_R16_USCALED:
525                 case PIPE_FORMAT_R16G16B16A16_SSCALED:
526                 case PIPE_FORMAT_R16G16B16_SSCALED:
527                 case PIPE_FORMAT_R16G16_SSCALED:
528                 case PIPE_FORMAT_R16_SSCALED:
529                 case PIPE_FORMAT_R8G8B8A8_UNORM:
530                 case PIPE_FORMAT_R8G8B8_UNORM:
531                 case PIPE_FORMAT_R8G8_UNORM:
532                 case PIPE_FORMAT_R8_UNORM:
533                 case PIPE_FORMAT_R8G8B8A8_SNORM:
534                 case PIPE_FORMAT_R8G8B8_SNORM:
535                 case PIPE_FORMAT_R8G8_SNORM:
536                 case PIPE_FORMAT_R8_SNORM:
537                 case PIPE_FORMAT_R8G8B8A8_USCALED:
538                 case PIPE_FORMAT_R8G8B8_USCALED:
539                 case PIPE_FORMAT_R8G8_USCALED:
540                 case PIPE_FORMAT_R8_USCALED:
541                 case PIPE_FORMAT_R8G8B8A8_SSCALED:
542                 case PIPE_FORMAT_R8G8B8_SSCALED:
543                 case PIPE_FORMAT_R8G8_SSCALED:
544                 case PIPE_FORMAT_R8_SSCALED:
545                         break;
546                 default:
547                         return FALSE;
548                 }
549         }
550
551         if ((usage & PIPE_BIND_RENDER_TARGET) &&
552             !vc4_rt_format_supported(format)) {
553                 return FALSE;
554         }
555
556         if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
557             (!vc4_tex_format_supported(format) ||
558              (format == PIPE_FORMAT_ETC1_RGB8 && !screen->has_etc1))) {
559                 return FALSE;
560         }
561
562         if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
563             format != PIPE_FORMAT_S8_UINT_Z24_UNORM &&
564             format != PIPE_FORMAT_X8Z24_UNORM) {
565                 return FALSE;
566         }
567
568         if ((usage & PIPE_BIND_INDEX_BUFFER) &&
569             format != PIPE_FORMAT_I8_UINT &&
570             format != PIPE_FORMAT_I16_UINT) {
571                 return FALSE;
572         }
573
574         return TRUE;
575 }
576
577 static void
578 vc4_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
579                                   enum pipe_format format, int max,
580                                   uint64_t *modifiers,
581                                   unsigned int *external_only,
582                                   int *count)
583 {
584         int m, i;
585         uint64_t available_modifiers[] = {
586                 DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED,
587                 DRM_FORMAT_MOD_LINEAR,
588         };
589         struct vc4_screen *screen = vc4_screen(pscreen);
590         int num_modifiers = screen->has_tiling_ioctl ? 2 : 1;
591
592         if (!modifiers) {
593                 *count = num_modifiers;
594                 return;
595         }
596
597         *count = MIN2(max, num_modifiers);
598         m = screen->has_tiling_ioctl ? 0 : 1;
599         /* We support both modifiers (tiled and linear) for all sampler
600          * formats, but if we don't have the DRM_VC4_GET_TILING ioctl
601          * we shouldn't advertise the tiled formats.
602          */
603         for (i = 0; i < *count; i++) {
604                 modifiers[i] = available_modifiers[m++];
605                 if (external_only)
606                         external_only[i] = false;
607        }
608 }
609
610 #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
611
612 static unsigned handle_hash(void *key)
613 {
614     return PTR_TO_UINT(key);
615 }
616
617 static int handle_compare(void *key1, void *key2)
618 {
619     return PTR_TO_UINT(key1) != PTR_TO_UINT(key2);
620 }
621
622 static bool
623 vc4_get_chip_info(struct vc4_screen *screen)
624 {
625         struct drm_vc4_get_param ident0 = {
626                 .param = DRM_VC4_PARAM_V3D_IDENT0,
627         };
628         struct drm_vc4_get_param ident1 = {
629                 .param = DRM_VC4_PARAM_V3D_IDENT1,
630         };
631         int ret;
632
633         ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident0);
634         if (ret != 0) {
635                 if (errno == EINVAL) {
636                         /* Backwards compatibility with 2835 kernels which
637                          * only do V3D 2.1.
638                          */
639                         screen->v3d_ver = 21;
640                         return true;
641                 } else {
642                         fprintf(stderr, "Couldn't get V3D IDENT0: %s\n",
643                                 strerror(errno));
644                         return false;
645                 }
646         }
647         ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident1);
648         if (ret != 0) {
649                 fprintf(stderr, "Couldn't get V3D IDENT1: %s\n",
650                         strerror(errno));
651                 return false;
652         }
653
654         uint32_t major = (ident0.value >> 24) & 0xff;
655         uint32_t minor = (ident1.value >> 0) & 0xf;
656         screen->v3d_ver = major * 10 + minor;
657
658         if (screen->v3d_ver != 21 && screen->v3d_ver != 26) {
659                 fprintf(stderr,
660                         "V3D %d.%d not supported by this version of Mesa.\n",
661                         screen->v3d_ver / 10,
662                         screen->v3d_ver % 10);
663                 return false;
664         }
665
666         return true;
667 }
668
669 struct pipe_screen *
670 vc4_screen_create(int fd, struct renderonly *ro)
671 {
672         struct vc4_screen *screen = rzalloc(NULL, struct vc4_screen);
673         uint64_t syncobj_cap = 0;
674         struct pipe_screen *pscreen;
675         int err;
676
677         pscreen = &screen->base;
678
679         pscreen->destroy = vc4_screen_destroy;
680         pscreen->get_param = vc4_screen_get_param;
681         pscreen->get_paramf = vc4_screen_get_paramf;
682         pscreen->get_shader_param = vc4_screen_get_shader_param;
683         pscreen->context_create = vc4_context_create;
684         pscreen->is_format_supported = vc4_screen_is_format_supported;
685
686         screen->fd = fd;
687         if (ro) {
688                 screen->ro = renderonly_dup(ro);
689                 if (!screen->ro) {
690                         fprintf(stderr, "Failed to dup renderonly object\n");
691                         ralloc_free(screen);
692                         return NULL;
693                 }
694         }
695
696         list_inithead(&screen->bo_cache.time_list);
697         (void) mtx_init(&screen->bo_handles_mutex, mtx_plain);
698         screen->bo_handles = util_hash_table_create(handle_hash, handle_compare);
699
700         screen->has_control_flow =
701                 vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_BRANCHES);
702         screen->has_etc1 =
703                 vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_ETC1);
704         screen->has_threaded_fs =
705                 vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_THREADED_FS);
706         screen->has_madvise =
707                 vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_MADVISE);
708         screen->has_perfmon_ioctl =
709                 vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_PERFMON);
710
711         err = drmGetCap(fd, DRM_CAP_SYNCOBJ, &syncobj_cap);
712         if (err == 0 && syncobj_cap)
713                 screen->has_syncobj = true;
714
715         if (!vc4_get_chip_info(screen))
716                 goto fail;
717
718         util_cpu_detect();
719
720         slab_create_parent(&screen->transfer_pool, sizeof(struct vc4_transfer), 16);
721
722         vc4_fence_screen_init(screen);
723
724         vc4_debug = debug_get_option_vc4_debug();
725         if (vc4_debug & VC4_DEBUG_SHADERDB)
726                 vc4_debug |= VC4_DEBUG_NORAST;
727
728 #ifdef USE_VC4_SIMULATOR
729         vc4_simulator_init(screen);
730 #endif
731
732         vc4_resource_screen_init(pscreen);
733
734         pscreen->get_name = vc4_screen_get_name;
735         pscreen->get_vendor = vc4_screen_get_vendor;
736         pscreen->get_device_vendor = vc4_screen_get_vendor;
737         pscreen->get_compiler_options = vc4_screen_get_compiler_options;
738         pscreen->query_dmabuf_modifiers = vc4_screen_query_dmabuf_modifiers;
739
740         if (screen->has_perfmon_ioctl) {
741                 pscreen->get_driver_query_group_info = vc4_get_driver_query_group_info;
742                 pscreen->get_driver_query_info = vc4_get_driver_query_info;
743         }
744
745         return pscreen;
746
747 fail:
748         close(fd);
749         ralloc_free(pscreen);
750         return NULL;
751 }