1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2014 Broadcom
3bf215546Sopenharmony_ci * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
4bf215546Sopenharmony_ci *
5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
11bf215546Sopenharmony_ci *
12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
14bf215546Sopenharmony_ci * Software.
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22bf215546Sopenharmony_ci * IN THE SOFTWARE.
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ci#include "util/os_misc.h"
26bf215546Sopenharmony_ci#include "pipe/p_defines.h"
27bf215546Sopenharmony_ci#include "pipe/p_screen.h"
28bf215546Sopenharmony_ci#include "pipe/p_state.h"
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci#include "util/u_debug.h"
31bf215546Sopenharmony_ci#include "util/u_memory.h"
32bf215546Sopenharmony_ci#include "util/format/u_format.h"
33bf215546Sopenharmony_ci#include "util/u_hash_table.h"
34bf215546Sopenharmony_ci#include "util/u_screen.h"
35bf215546Sopenharmony_ci#include "util/u_transfer_helper.h"
36bf215546Sopenharmony_ci#include "util/ralloc.h"
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci#include <xf86drm.h>
39bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h"
40bf215546Sopenharmony_ci#include "drm-uapi/vc4_drm.h"
41bf215546Sopenharmony_ci#include "vc4_screen.h"
42bf215546Sopenharmony_ci#include "vc4_context.h"
43bf215546Sopenharmony_ci#include "vc4_resource.h"
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_cistatic const struct debug_named_value vc4_debug_options[] = {
46bf215546Sopenharmony_ci        { "cl",       VC4_DEBUG_CL,
47bf215546Sopenharmony_ci          "Dump command list during creation" },
48bf215546Sopenharmony_ci        { "surf",       VC4_DEBUG_SURFACE,
49bf215546Sopenharmony_ci          "Dump surface layouts" },
50bf215546Sopenharmony_ci        { "qpu",      VC4_DEBUG_QPU,
51bf215546Sopenharmony_ci          "Dump generated QPU instructions" },
52bf215546Sopenharmony_ci        { "qir",      VC4_DEBUG_QIR,
53bf215546Sopenharmony_ci          "Dump QPU IR during program compile" },
54bf215546Sopenharmony_ci        { "nir",      VC4_DEBUG_NIR,
55bf215546Sopenharmony_ci          "Dump NIR during program compile" },
56bf215546Sopenharmony_ci        { "tgsi",     VC4_DEBUG_TGSI,
57bf215546Sopenharmony_ci          "Dump TGSI during program compile" },
58bf215546Sopenharmony_ci        { "shaderdb", VC4_DEBUG_SHADERDB,
59bf215546Sopenharmony_ci          "Dump program compile information for shader-db analysis" },
60bf215546Sopenharmony_ci        { "perf",     VC4_DEBUG_PERF,
61bf215546Sopenharmony_ci          "Print during performance-related events" },
62bf215546Sopenharmony_ci        { "norast",   VC4_DEBUG_NORAST,
63bf215546Sopenharmony_ci          "Skip actual hardware execution of commands" },
64bf215546Sopenharmony_ci        { "always_flush", VC4_DEBUG_ALWAYS_FLUSH,
65bf215546Sopenharmony_ci          "Flush after each draw call" },
66bf215546Sopenharmony_ci        { "always_sync", VC4_DEBUG_ALWAYS_SYNC,
67bf215546Sopenharmony_ci          "Wait for finish after each flush" },
68bf215546Sopenharmony_ci#ifdef USE_VC4_SIMULATOR
69bf215546Sopenharmony_ci        { "dump", VC4_DEBUG_DUMP,
70bf215546Sopenharmony_ci          "Write a GPU command stream trace file" },
71bf215546Sopenharmony_ci#endif
72bf215546Sopenharmony_ci        { NULL }
73bf215546Sopenharmony_ci};
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_ciDEBUG_GET_ONCE_FLAGS_OPTION(vc4_debug, "VC4_DEBUG", vc4_debug_options, 0)
76bf215546Sopenharmony_ciuint32_t vc4_debug;
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_cistatic const char *
79bf215546Sopenharmony_civc4_screen_get_name(struct pipe_screen *pscreen)
80bf215546Sopenharmony_ci{
81bf215546Sopenharmony_ci        struct vc4_screen *screen = vc4_screen(pscreen);
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci        if (!screen->name) {
84bf215546Sopenharmony_ci                screen->name = ralloc_asprintf(screen,
85bf215546Sopenharmony_ci                                               "VC4 V3D %d.%d",
86bf215546Sopenharmony_ci                                               screen->v3d_ver / 10,
87bf215546Sopenharmony_ci                                               screen->v3d_ver % 10);
88bf215546Sopenharmony_ci        }
89bf215546Sopenharmony_ci
90bf215546Sopenharmony_ci        return screen->name;
91bf215546Sopenharmony_ci}
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_cistatic const char *
94bf215546Sopenharmony_civc4_screen_get_vendor(struct pipe_screen *pscreen)
95bf215546Sopenharmony_ci{
96bf215546Sopenharmony_ci        return "Broadcom";
97bf215546Sopenharmony_ci}
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_cistatic void
100bf215546Sopenharmony_civc4_screen_destroy(struct pipe_screen *pscreen)
101bf215546Sopenharmony_ci{
102bf215546Sopenharmony_ci        struct vc4_screen *screen = vc4_screen(pscreen);
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci        _mesa_hash_table_destroy(screen->bo_handles, NULL);
105bf215546Sopenharmony_ci        vc4_bufmgr_destroy(pscreen);
106bf215546Sopenharmony_ci        slab_destroy_parent(&screen->transfer_pool);
107bf215546Sopenharmony_ci        if (screen->ro)
108bf215546Sopenharmony_ci                screen->ro->destroy(screen->ro);
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_ci#ifdef USE_VC4_SIMULATOR
111bf215546Sopenharmony_ci        vc4_simulator_destroy(screen);
112bf215546Sopenharmony_ci#endif
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ci        u_transfer_helper_destroy(pscreen->transfer_helper);
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ci        close(screen->fd);
117bf215546Sopenharmony_ci        ralloc_free(pscreen);
118bf215546Sopenharmony_ci}
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_cistatic bool
121bf215546Sopenharmony_civc4_has_feature(struct vc4_screen *screen, uint32_t feature)
122bf215546Sopenharmony_ci{
123bf215546Sopenharmony_ci        struct drm_vc4_get_param p = {
124bf215546Sopenharmony_ci                .param = feature,
125bf215546Sopenharmony_ci        };
126bf215546Sopenharmony_ci        int ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &p);
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci        if (ret != 0)
129bf215546Sopenharmony_ci                return false;
130bf215546Sopenharmony_ci
131bf215546Sopenharmony_ci        return p.value;
132bf215546Sopenharmony_ci}
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_cistatic int
135bf215546Sopenharmony_civc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
136bf215546Sopenharmony_ci{
137bf215546Sopenharmony_ci        struct vc4_screen *screen = vc4_screen(pscreen);
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci        switch (param) {
140bf215546Sopenharmony_ci                /* Supported features (boolean caps). */
141bf215546Sopenharmony_ci        case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
142bf215546Sopenharmony_ci        case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
143bf215546Sopenharmony_ci        case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
144bf215546Sopenharmony_ci        case PIPE_CAP_NPOT_TEXTURES:
145bf215546Sopenharmony_ci        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
146bf215546Sopenharmony_ci        case PIPE_CAP_TEXTURE_MULTISAMPLE:
147bf215546Sopenharmony_ci        case PIPE_CAP_TEXTURE_SWIZZLE:
148bf215546Sopenharmony_ci        case PIPE_CAP_TEXTURE_BARRIER:
149bf215546Sopenharmony_ci        case PIPE_CAP_TGSI_TEXCOORD:
150bf215546Sopenharmony_ci                return 1;
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci        case PIPE_CAP_NATIVE_FENCE_FD:
153bf215546Sopenharmony_ci                return screen->has_syncobj;
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci        case PIPE_CAP_TILE_RASTER_ORDER:
156bf215546Sopenharmony_ci                return vc4_has_feature(screen,
157bf215546Sopenharmony_ci                                       DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER);
158bf215546Sopenharmony_ci
159bf215546Sopenharmony_ci                /* lying for GL 2.0 */
160bf215546Sopenharmony_ci        case PIPE_CAP_POINT_SPRITE:
161bf215546Sopenharmony_ci                return 1;
162bf215546Sopenharmony_ci
163bf215546Sopenharmony_ci        case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT:
164bf215546Sopenharmony_ci        case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
165bf215546Sopenharmony_ci        case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL:
166bf215546Sopenharmony_ci                return 1;
167bf215546Sopenharmony_ci
168bf215546Sopenharmony_ci        case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
169bf215546Sopenharmony_ci        case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
170bf215546Sopenharmony_ci                return 1;
171bf215546Sopenharmony_ci
172bf215546Sopenharmony_ci                /* Texturing. */
173bf215546Sopenharmony_ci        case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
174bf215546Sopenharmony_ci                return 2048;
175bf215546Sopenharmony_ci        case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
176bf215546Sopenharmony_ci                return VC4_MAX_MIP_LEVELS;
177bf215546Sopenharmony_ci        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
178bf215546Sopenharmony_ci                return 0;
179bf215546Sopenharmony_ci
180bf215546Sopenharmony_ci        case PIPE_CAP_MAX_VARYINGS:
181bf215546Sopenharmony_ci                return 8;
182bf215546Sopenharmony_ci
183bf215546Sopenharmony_ci        case PIPE_CAP_VENDOR_ID:
184bf215546Sopenharmony_ci                return 0x14E4;
185bf215546Sopenharmony_ci        case PIPE_CAP_ACCELERATED:
186bf215546Sopenharmony_ci                return 1;
187bf215546Sopenharmony_ci        case PIPE_CAP_VIDEO_MEMORY: {
188bf215546Sopenharmony_ci                uint64_t system_memory;
189bf215546Sopenharmony_ci
190bf215546Sopenharmony_ci                if (!os_get_total_physical_memory(&system_memory))
191bf215546Sopenharmony_ci                        return 0;
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_ci                return (int)(system_memory >> 20);
194bf215546Sopenharmony_ci        }
195bf215546Sopenharmony_ci        case PIPE_CAP_UMA:
196bf215546Sopenharmony_ci                return 1;
197bf215546Sopenharmony_ci
198bf215546Sopenharmony_ci        case PIPE_CAP_ALPHA_TEST:
199bf215546Sopenharmony_ci        case PIPE_CAP_VERTEX_COLOR_CLAMPED:
200bf215546Sopenharmony_ci        case PIPE_CAP_TWO_SIDED_COLOR:
201bf215546Sopenharmony_ci        case PIPE_CAP_TEXRECT:
202bf215546Sopenharmony_ci        case PIPE_CAP_IMAGE_STORE_FORMATTED:
203bf215546Sopenharmony_ci                return 0;
204bf215546Sopenharmony_ci
205bf215546Sopenharmony_ci        case PIPE_CAP_SUPPORTED_PRIM_MODES:
206bf215546Sopenharmony_ci                return screen->prim_types;
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ci        default:
209bf215546Sopenharmony_ci                return u_pipe_screen_get_param_defaults(pscreen, param);
210bf215546Sopenharmony_ci        }
211bf215546Sopenharmony_ci}
212bf215546Sopenharmony_ci
213bf215546Sopenharmony_cistatic float
214bf215546Sopenharmony_civc4_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
215bf215546Sopenharmony_ci{
216bf215546Sopenharmony_ci        switch (param) {
217bf215546Sopenharmony_ci        case PIPE_CAPF_MIN_LINE_WIDTH:
218bf215546Sopenharmony_ci        case PIPE_CAPF_MIN_LINE_WIDTH_AA:
219bf215546Sopenharmony_ci        case PIPE_CAPF_MIN_POINT_SIZE:
220bf215546Sopenharmony_ci        case PIPE_CAPF_MIN_POINT_SIZE_AA:
221bf215546Sopenharmony_ci           return 1;
222bf215546Sopenharmony_ci
223bf215546Sopenharmony_ci        case PIPE_CAPF_POINT_SIZE_GRANULARITY:
224bf215546Sopenharmony_ci        case PIPE_CAPF_LINE_WIDTH_GRANULARITY:
225bf215546Sopenharmony_ci           return 0.1;
226bf215546Sopenharmony_ci
227bf215546Sopenharmony_ci        case PIPE_CAPF_MAX_LINE_WIDTH:
228bf215546Sopenharmony_ci        case PIPE_CAPF_MAX_LINE_WIDTH_AA:
229bf215546Sopenharmony_ci                return 32;
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_ci        case PIPE_CAPF_MAX_POINT_SIZE:
232bf215546Sopenharmony_ci        case PIPE_CAPF_MAX_POINT_SIZE_AA:
233bf215546Sopenharmony_ci                return 512.0f;
234bf215546Sopenharmony_ci
235bf215546Sopenharmony_ci        case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
236bf215546Sopenharmony_ci                return 0.0f;
237bf215546Sopenharmony_ci        case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
238bf215546Sopenharmony_ci                return 0.0f;
239bf215546Sopenharmony_ci
240bf215546Sopenharmony_ci        case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
241bf215546Sopenharmony_ci        case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
242bf215546Sopenharmony_ci        case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
243bf215546Sopenharmony_ci                return 0.0f;
244bf215546Sopenharmony_ci        default:
245bf215546Sopenharmony_ci                fprintf(stderr, "unknown paramf %d\n", param);
246bf215546Sopenharmony_ci                return 0;
247bf215546Sopenharmony_ci        }
248bf215546Sopenharmony_ci}
249bf215546Sopenharmony_ci
250bf215546Sopenharmony_cistatic int
251bf215546Sopenharmony_civc4_screen_get_shader_param(struct pipe_screen *pscreen,
252bf215546Sopenharmony_ci                            enum pipe_shader_type shader,
253bf215546Sopenharmony_ci                            enum pipe_shader_cap param)
254bf215546Sopenharmony_ci{
255bf215546Sopenharmony_ci        if (shader != PIPE_SHADER_VERTEX &&
256bf215546Sopenharmony_ci            shader != PIPE_SHADER_FRAGMENT) {
257bf215546Sopenharmony_ci                return 0;
258bf215546Sopenharmony_ci        }
259bf215546Sopenharmony_ci
260bf215546Sopenharmony_ci        /* this is probably not totally correct.. but it's a start: */
261bf215546Sopenharmony_ci        switch (param) {
262bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
263bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
264bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
265bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
266bf215546Sopenharmony_ci                return 16384;
267bf215546Sopenharmony_ci
268bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
269bf215546Sopenharmony_ci                return vc4_screen(pscreen)->has_control_flow;
270bf215546Sopenharmony_ci
271bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_INPUTS:
272bf215546Sopenharmony_ci                return 8;
273bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_OUTPUTS:
274bf215546Sopenharmony_ci                return shader == PIPE_SHADER_FRAGMENT ? 1 : 8;
275bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_TEMPS:
276bf215546Sopenharmony_ci                return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
277bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE:
278bf215546Sopenharmony_ci                return 16 * 1024 * sizeof(float);
279bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
280bf215546Sopenharmony_ci                return 1;
281bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_CONT_SUPPORTED:
282bf215546Sopenharmony_ci                return 0;
283bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
284bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
285bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
286bf215546Sopenharmony_ci                return 0;
287bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
288bf215546Sopenharmony_ci                return 1;
289bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_SUBROUTINES:
290bf215546Sopenharmony_ci                return 0;
291bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
292bf215546Sopenharmony_ci                return 0;
293bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_INTEGERS:
294bf215546Sopenharmony_ci                return 1;
295bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_INT64_ATOMICS:
296bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_FP16:
297bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_FP16_DERIVATIVES:
298bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
299bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_INT16:
300bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
301bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_DROUND_SUPPORTED:
302bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_DFRACEXP_DLDEXP_SUPPORTED:
303bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_LDEXP_SUPPORTED:
304bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
305bf215546Sopenharmony_ci                return 0;
306bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
307bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
308bf215546Sopenharmony_ci                return VC4_MAX_TEXTURE_SAMPLERS;
309bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_PREFERRED_IR:
310bf215546Sopenharmony_ci                return PIPE_SHADER_IR_NIR;
311bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_SUPPORTED_IRS:
312bf215546Sopenharmony_ci                return 1 << PIPE_SHADER_IR_NIR;
313bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
314bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
315bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
316bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
317bf215546Sopenharmony_ci                return 0;
318bf215546Sopenharmony_ci        default:
319bf215546Sopenharmony_ci                fprintf(stderr, "unknown shader param %d\n", param);
320bf215546Sopenharmony_ci                return 0;
321bf215546Sopenharmony_ci        }
322bf215546Sopenharmony_ci        return 0;
323bf215546Sopenharmony_ci}
324bf215546Sopenharmony_ci
325bf215546Sopenharmony_cistatic bool
326bf215546Sopenharmony_civc4_screen_is_format_supported(struct pipe_screen *pscreen,
327bf215546Sopenharmony_ci                               enum pipe_format format,
328bf215546Sopenharmony_ci                               enum pipe_texture_target target,
329bf215546Sopenharmony_ci                               unsigned sample_count,
330bf215546Sopenharmony_ci                               unsigned storage_sample_count,
331bf215546Sopenharmony_ci                               unsigned usage)
332bf215546Sopenharmony_ci{
333bf215546Sopenharmony_ci        struct vc4_screen *screen = vc4_screen(pscreen);
334bf215546Sopenharmony_ci
335bf215546Sopenharmony_ci        if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
336bf215546Sopenharmony_ci                return false;
337bf215546Sopenharmony_ci
338bf215546Sopenharmony_ci        if (sample_count > 1 && sample_count != VC4_MAX_SAMPLES)
339bf215546Sopenharmony_ci                return false;
340bf215546Sopenharmony_ci
341bf215546Sopenharmony_ci        if (target >= PIPE_MAX_TEXTURE_TYPES) {
342bf215546Sopenharmony_ci                return false;
343bf215546Sopenharmony_ci        }
344bf215546Sopenharmony_ci
345bf215546Sopenharmony_ci        if (usage & PIPE_BIND_VERTEX_BUFFER) {
346bf215546Sopenharmony_ci                switch (format) {
347bf215546Sopenharmony_ci                case PIPE_FORMAT_R32G32B32A32_FLOAT:
348bf215546Sopenharmony_ci                case PIPE_FORMAT_R32G32B32_FLOAT:
349bf215546Sopenharmony_ci                case PIPE_FORMAT_R32G32_FLOAT:
350bf215546Sopenharmony_ci                case PIPE_FORMAT_R32_FLOAT:
351bf215546Sopenharmony_ci                case PIPE_FORMAT_R32G32B32A32_SNORM:
352bf215546Sopenharmony_ci                case PIPE_FORMAT_R32G32B32_SNORM:
353bf215546Sopenharmony_ci                case PIPE_FORMAT_R32G32_SNORM:
354bf215546Sopenharmony_ci                case PIPE_FORMAT_R32_SNORM:
355bf215546Sopenharmony_ci                case PIPE_FORMAT_R32G32B32A32_SSCALED:
356bf215546Sopenharmony_ci                case PIPE_FORMAT_R32G32B32_SSCALED:
357bf215546Sopenharmony_ci                case PIPE_FORMAT_R32G32_SSCALED:
358bf215546Sopenharmony_ci                case PIPE_FORMAT_R32_SSCALED:
359bf215546Sopenharmony_ci                case PIPE_FORMAT_R16G16B16A16_UNORM:
360bf215546Sopenharmony_ci                case PIPE_FORMAT_R16G16B16_UNORM:
361bf215546Sopenharmony_ci                case PIPE_FORMAT_R16G16_UNORM:
362bf215546Sopenharmony_ci                case PIPE_FORMAT_R16_UNORM:
363bf215546Sopenharmony_ci                case PIPE_FORMAT_R16G16B16A16_SNORM:
364bf215546Sopenharmony_ci                case PIPE_FORMAT_R16G16B16_SNORM:
365bf215546Sopenharmony_ci                case PIPE_FORMAT_R16G16_SNORM:
366bf215546Sopenharmony_ci                case PIPE_FORMAT_R16_SNORM:
367bf215546Sopenharmony_ci                case PIPE_FORMAT_R16G16B16A16_USCALED:
368bf215546Sopenharmony_ci                case PIPE_FORMAT_R16G16B16_USCALED:
369bf215546Sopenharmony_ci                case PIPE_FORMAT_R16G16_USCALED:
370bf215546Sopenharmony_ci                case PIPE_FORMAT_R16_USCALED:
371bf215546Sopenharmony_ci                case PIPE_FORMAT_R16G16B16A16_SSCALED:
372bf215546Sopenharmony_ci                case PIPE_FORMAT_R16G16B16_SSCALED:
373bf215546Sopenharmony_ci                case PIPE_FORMAT_R16G16_SSCALED:
374bf215546Sopenharmony_ci                case PIPE_FORMAT_R16_SSCALED:
375bf215546Sopenharmony_ci                case PIPE_FORMAT_R8G8B8A8_UNORM:
376bf215546Sopenharmony_ci                case PIPE_FORMAT_R8G8B8_UNORM:
377bf215546Sopenharmony_ci                case PIPE_FORMAT_R8G8_UNORM:
378bf215546Sopenharmony_ci                case PIPE_FORMAT_R8_UNORM:
379bf215546Sopenharmony_ci                case PIPE_FORMAT_R8G8B8A8_SNORM:
380bf215546Sopenharmony_ci                case PIPE_FORMAT_R8G8B8_SNORM:
381bf215546Sopenharmony_ci                case PIPE_FORMAT_R8G8_SNORM:
382bf215546Sopenharmony_ci                case PIPE_FORMAT_R8_SNORM:
383bf215546Sopenharmony_ci                case PIPE_FORMAT_R8G8B8A8_USCALED:
384bf215546Sopenharmony_ci                case PIPE_FORMAT_R8G8B8_USCALED:
385bf215546Sopenharmony_ci                case PIPE_FORMAT_R8G8_USCALED:
386bf215546Sopenharmony_ci                case PIPE_FORMAT_R8_USCALED:
387bf215546Sopenharmony_ci                case PIPE_FORMAT_R8G8B8A8_SSCALED:
388bf215546Sopenharmony_ci                case PIPE_FORMAT_R8G8B8_SSCALED:
389bf215546Sopenharmony_ci                case PIPE_FORMAT_R8G8_SSCALED:
390bf215546Sopenharmony_ci                case PIPE_FORMAT_R8_SSCALED:
391bf215546Sopenharmony_ci                        break;
392bf215546Sopenharmony_ci                default:
393bf215546Sopenharmony_ci                        return false;
394bf215546Sopenharmony_ci                }
395bf215546Sopenharmony_ci        }
396bf215546Sopenharmony_ci
397bf215546Sopenharmony_ci        if ((usage & PIPE_BIND_RENDER_TARGET) &&
398bf215546Sopenharmony_ci            !vc4_rt_format_supported(format)) {
399bf215546Sopenharmony_ci                return false;
400bf215546Sopenharmony_ci        }
401bf215546Sopenharmony_ci
402bf215546Sopenharmony_ci        if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
403bf215546Sopenharmony_ci            (!vc4_tex_format_supported(format) ||
404bf215546Sopenharmony_ci             (format == PIPE_FORMAT_ETC1_RGB8 && !screen->has_etc1))) {
405bf215546Sopenharmony_ci                return false;
406bf215546Sopenharmony_ci        }
407bf215546Sopenharmony_ci
408bf215546Sopenharmony_ci        if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
409bf215546Sopenharmony_ci            format != PIPE_FORMAT_S8_UINT_Z24_UNORM &&
410bf215546Sopenharmony_ci            format != PIPE_FORMAT_X8Z24_UNORM) {
411bf215546Sopenharmony_ci                return false;
412bf215546Sopenharmony_ci        }
413bf215546Sopenharmony_ci
414bf215546Sopenharmony_ci        if ((usage & PIPE_BIND_INDEX_BUFFER) &&
415bf215546Sopenharmony_ci            format != PIPE_FORMAT_R8_UINT &&
416bf215546Sopenharmony_ci            format != PIPE_FORMAT_R16_UINT) {
417bf215546Sopenharmony_ci                return false;
418bf215546Sopenharmony_ci        }
419bf215546Sopenharmony_ci
420bf215546Sopenharmony_ci        return true;
421bf215546Sopenharmony_ci}
422bf215546Sopenharmony_ci
423bf215546Sopenharmony_cistatic const uint64_t *vc4_get_modifiers(struct pipe_screen *pscreen, int *num)
424bf215546Sopenharmony_ci{
425bf215546Sopenharmony_ci        struct vc4_screen *screen = vc4_screen(pscreen);
426bf215546Sopenharmony_ci        static const uint64_t all_modifiers[] = {
427bf215546Sopenharmony_ci                DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED,
428bf215546Sopenharmony_ci                DRM_FORMAT_MOD_LINEAR,
429bf215546Sopenharmony_ci        };
430bf215546Sopenharmony_ci        int m;
431bf215546Sopenharmony_ci
432bf215546Sopenharmony_ci        /* We support both modifiers (tiled and linear) for all sampler
433bf215546Sopenharmony_ci         * formats, but if we don't have the DRM_VC4_GET_TILING ioctl
434bf215546Sopenharmony_ci         * we shouldn't advertise the tiled formats.
435bf215546Sopenharmony_ci         */
436bf215546Sopenharmony_ci        if (screen->has_tiling_ioctl) {
437bf215546Sopenharmony_ci                m = 0;
438bf215546Sopenharmony_ci                *num = 2;
439bf215546Sopenharmony_ci        } else{
440bf215546Sopenharmony_ci                m = 1;
441bf215546Sopenharmony_ci                *num = 1;
442bf215546Sopenharmony_ci        }
443bf215546Sopenharmony_ci
444bf215546Sopenharmony_ci        return &all_modifiers[m];
445bf215546Sopenharmony_ci}
446bf215546Sopenharmony_ci
447bf215546Sopenharmony_cistatic void
448bf215546Sopenharmony_civc4_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
449bf215546Sopenharmony_ci                                  enum pipe_format format, int max,
450bf215546Sopenharmony_ci                                  uint64_t *modifiers,
451bf215546Sopenharmony_ci                                  unsigned int *external_only,
452bf215546Sopenharmony_ci                                  int *count)
453bf215546Sopenharmony_ci{
454bf215546Sopenharmony_ci        const uint64_t *available_modifiers;
455bf215546Sopenharmony_ci        int i;
456bf215546Sopenharmony_ci        bool tex_will_lower;
457bf215546Sopenharmony_ci        int num_modifiers;
458bf215546Sopenharmony_ci
459bf215546Sopenharmony_ci        available_modifiers = vc4_get_modifiers(pscreen, &num_modifiers);
460bf215546Sopenharmony_ci
461bf215546Sopenharmony_ci        if (!modifiers) {
462bf215546Sopenharmony_ci                *count = num_modifiers;
463bf215546Sopenharmony_ci                return;
464bf215546Sopenharmony_ci        }
465bf215546Sopenharmony_ci
466bf215546Sopenharmony_ci        *count = MIN2(max, num_modifiers);
467bf215546Sopenharmony_ci        tex_will_lower = !vc4_tex_format_supported(format);
468bf215546Sopenharmony_ci        for (i = 0; i < *count; i++) {
469bf215546Sopenharmony_ci                modifiers[i] = available_modifiers[i];
470bf215546Sopenharmony_ci                if (external_only)
471bf215546Sopenharmony_ci                        external_only[i] = tex_will_lower;
472bf215546Sopenharmony_ci       }
473bf215546Sopenharmony_ci}
474bf215546Sopenharmony_ci
475bf215546Sopenharmony_cistatic bool
476bf215546Sopenharmony_civc4_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,
477bf215546Sopenharmony_ci                                        uint64_t modifier,
478bf215546Sopenharmony_ci                                        enum pipe_format format,
479bf215546Sopenharmony_ci                                        bool *external_only)
480bf215546Sopenharmony_ci{
481bf215546Sopenharmony_ci        const uint64_t *available_modifiers;
482bf215546Sopenharmony_ci        int i, num_modifiers;
483bf215546Sopenharmony_ci
484bf215546Sopenharmony_ci        available_modifiers = vc4_get_modifiers(pscreen, &num_modifiers);
485bf215546Sopenharmony_ci
486bf215546Sopenharmony_ci        for (i = 0; i < num_modifiers; i++) {
487bf215546Sopenharmony_ci                if (modifier == available_modifiers[i]) {
488bf215546Sopenharmony_ci                        if (external_only)
489bf215546Sopenharmony_ci                                *external_only = !vc4_tex_format_supported(format);
490bf215546Sopenharmony_ci
491bf215546Sopenharmony_ci                        return true;
492bf215546Sopenharmony_ci                }
493bf215546Sopenharmony_ci        }
494bf215546Sopenharmony_ci
495bf215546Sopenharmony_ci        return false;
496bf215546Sopenharmony_ci}
497bf215546Sopenharmony_ci
498bf215546Sopenharmony_cistatic bool
499bf215546Sopenharmony_civc4_get_chip_info(struct vc4_screen *screen)
500bf215546Sopenharmony_ci{
501bf215546Sopenharmony_ci        struct drm_vc4_get_param ident0 = {
502bf215546Sopenharmony_ci                .param = DRM_VC4_PARAM_V3D_IDENT0,
503bf215546Sopenharmony_ci        };
504bf215546Sopenharmony_ci        struct drm_vc4_get_param ident1 = {
505bf215546Sopenharmony_ci                .param = DRM_VC4_PARAM_V3D_IDENT1,
506bf215546Sopenharmony_ci        };
507bf215546Sopenharmony_ci        int ret;
508bf215546Sopenharmony_ci
509bf215546Sopenharmony_ci        ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident0);
510bf215546Sopenharmony_ci        if (ret != 0) {
511bf215546Sopenharmony_ci                if (errno == EINVAL) {
512bf215546Sopenharmony_ci                        /* Backwards compatibility with 2835 kernels which
513bf215546Sopenharmony_ci                         * only do V3D 2.1.
514bf215546Sopenharmony_ci                         */
515bf215546Sopenharmony_ci                        screen->v3d_ver = 21;
516bf215546Sopenharmony_ci                        return true;
517bf215546Sopenharmony_ci                } else {
518bf215546Sopenharmony_ci                        fprintf(stderr, "Couldn't get V3D IDENT0: %s\n",
519bf215546Sopenharmony_ci                                strerror(errno));
520bf215546Sopenharmony_ci                        return false;
521bf215546Sopenharmony_ci                }
522bf215546Sopenharmony_ci        }
523bf215546Sopenharmony_ci        ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident1);
524bf215546Sopenharmony_ci        if (ret != 0) {
525bf215546Sopenharmony_ci                fprintf(stderr, "Couldn't get V3D IDENT1: %s\n",
526bf215546Sopenharmony_ci                        strerror(errno));
527bf215546Sopenharmony_ci                return false;
528bf215546Sopenharmony_ci        }
529bf215546Sopenharmony_ci
530bf215546Sopenharmony_ci        uint32_t major = (ident0.value >> 24) & 0xff;
531bf215546Sopenharmony_ci        uint32_t minor = (ident1.value >> 0) & 0xf;
532bf215546Sopenharmony_ci        screen->v3d_ver = major * 10 + minor;
533bf215546Sopenharmony_ci
534bf215546Sopenharmony_ci        if (screen->v3d_ver != 21 && screen->v3d_ver != 26) {
535bf215546Sopenharmony_ci                fprintf(stderr,
536bf215546Sopenharmony_ci                        "V3D %d.%d not supported by this version of Mesa.\n",
537bf215546Sopenharmony_ci                        screen->v3d_ver / 10,
538bf215546Sopenharmony_ci                        screen->v3d_ver % 10);
539bf215546Sopenharmony_ci                return false;
540bf215546Sopenharmony_ci        }
541bf215546Sopenharmony_ci
542bf215546Sopenharmony_ci        return true;
543bf215546Sopenharmony_ci}
544bf215546Sopenharmony_ci
545bf215546Sopenharmony_cistruct pipe_screen *
546bf215546Sopenharmony_civc4_screen_create(int fd, struct renderonly *ro)
547bf215546Sopenharmony_ci{
548bf215546Sopenharmony_ci        struct vc4_screen *screen = rzalloc(NULL, struct vc4_screen);
549bf215546Sopenharmony_ci        uint64_t syncobj_cap = 0;
550bf215546Sopenharmony_ci        struct pipe_screen *pscreen;
551bf215546Sopenharmony_ci        int err;
552bf215546Sopenharmony_ci
553bf215546Sopenharmony_ci        pscreen = &screen->base;
554bf215546Sopenharmony_ci
555bf215546Sopenharmony_ci        pscreen->destroy = vc4_screen_destroy;
556bf215546Sopenharmony_ci        pscreen->get_param = vc4_screen_get_param;
557bf215546Sopenharmony_ci        pscreen->get_paramf = vc4_screen_get_paramf;
558bf215546Sopenharmony_ci        pscreen->get_shader_param = vc4_screen_get_shader_param;
559bf215546Sopenharmony_ci        pscreen->context_create = vc4_context_create;
560bf215546Sopenharmony_ci        pscreen->is_format_supported = vc4_screen_is_format_supported;
561bf215546Sopenharmony_ci
562bf215546Sopenharmony_ci        screen->fd = fd;
563bf215546Sopenharmony_ci        screen->ro = ro;
564bf215546Sopenharmony_ci
565bf215546Sopenharmony_ci        list_inithead(&screen->bo_cache.time_list);
566bf215546Sopenharmony_ci        (void) mtx_init(&screen->bo_handles_mutex, mtx_plain);
567bf215546Sopenharmony_ci        screen->bo_handles = util_hash_table_create_ptr_keys();
568bf215546Sopenharmony_ci
569bf215546Sopenharmony_ci        screen->has_control_flow =
570bf215546Sopenharmony_ci                vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_BRANCHES);
571bf215546Sopenharmony_ci        screen->has_etc1 =
572bf215546Sopenharmony_ci                vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_ETC1);
573bf215546Sopenharmony_ci        screen->has_threaded_fs =
574bf215546Sopenharmony_ci                vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_THREADED_FS);
575bf215546Sopenharmony_ci        screen->has_madvise =
576bf215546Sopenharmony_ci                vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_MADVISE);
577bf215546Sopenharmony_ci        screen->has_perfmon_ioctl =
578bf215546Sopenharmony_ci                vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_PERFMON);
579bf215546Sopenharmony_ci
580bf215546Sopenharmony_ci        err = drmGetCap(fd, DRM_CAP_SYNCOBJ, &syncobj_cap);
581bf215546Sopenharmony_ci        if (err == 0 && syncobj_cap)
582bf215546Sopenharmony_ci                screen->has_syncobj = true;
583bf215546Sopenharmony_ci
584bf215546Sopenharmony_ci        if (!vc4_get_chip_info(screen))
585bf215546Sopenharmony_ci                goto fail;
586bf215546Sopenharmony_ci
587bf215546Sopenharmony_ci        slab_create_parent(&screen->transfer_pool, sizeof(struct vc4_transfer), 16);
588bf215546Sopenharmony_ci
589bf215546Sopenharmony_ci        vc4_fence_screen_init(screen);
590bf215546Sopenharmony_ci
591bf215546Sopenharmony_ci        vc4_debug = debug_get_option_vc4_debug();
592bf215546Sopenharmony_ci
593bf215546Sopenharmony_ci#ifdef USE_VC4_SIMULATOR
594bf215546Sopenharmony_ci        vc4_simulator_init(screen);
595bf215546Sopenharmony_ci#endif
596bf215546Sopenharmony_ci
597bf215546Sopenharmony_ci        vc4_resource_screen_init(pscreen);
598bf215546Sopenharmony_ci
599bf215546Sopenharmony_ci        pscreen->get_name = vc4_screen_get_name;
600bf215546Sopenharmony_ci        pscreen->get_vendor = vc4_screen_get_vendor;
601bf215546Sopenharmony_ci        pscreen->get_device_vendor = vc4_screen_get_vendor;
602bf215546Sopenharmony_ci        pscreen->get_compiler_options = vc4_screen_get_compiler_options;
603bf215546Sopenharmony_ci        pscreen->query_dmabuf_modifiers = vc4_screen_query_dmabuf_modifiers;
604bf215546Sopenharmony_ci        pscreen->is_dmabuf_modifier_supported = vc4_screen_is_dmabuf_modifier_supported;
605bf215546Sopenharmony_ci
606bf215546Sopenharmony_ci        if (screen->has_perfmon_ioctl) {
607bf215546Sopenharmony_ci                pscreen->get_driver_query_group_info = vc4_get_driver_query_group_info;
608bf215546Sopenharmony_ci                pscreen->get_driver_query_info = vc4_get_driver_query_info;
609bf215546Sopenharmony_ci        }
610bf215546Sopenharmony_ci
611bf215546Sopenharmony_ci        /* Generate the bitmask of supported draw primitives. */
612bf215546Sopenharmony_ci        screen->prim_types = BITFIELD_BIT(PIPE_PRIM_POINTS) |
613bf215546Sopenharmony_ci                             BITFIELD_BIT(PIPE_PRIM_LINES) |
614bf215546Sopenharmony_ci                             BITFIELD_BIT(PIPE_PRIM_LINE_LOOP) |
615bf215546Sopenharmony_ci                             BITFIELD_BIT(PIPE_PRIM_LINE_STRIP) |
616bf215546Sopenharmony_ci                             BITFIELD_BIT(PIPE_PRIM_TRIANGLES) |
617bf215546Sopenharmony_ci                             BITFIELD_BIT(PIPE_PRIM_TRIANGLE_STRIP) |
618bf215546Sopenharmony_ci                             BITFIELD_BIT(PIPE_PRIM_TRIANGLE_FAN);
619bf215546Sopenharmony_ci
620bf215546Sopenharmony_ci
621bf215546Sopenharmony_ci        return pscreen;
622bf215546Sopenharmony_ci
623bf215546Sopenharmony_cifail:
624bf215546Sopenharmony_ci        close(fd);
625bf215546Sopenharmony_ci        ralloc_free(pscreen);
626bf215546Sopenharmony_ci        return NULL;
627bf215546Sopenharmony_ci}
628