1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21bf215546Sopenharmony_ci * SOFTWARE. 22bf215546Sopenharmony_ci * 23bf215546Sopenharmony_ci * Authors: 24bf215546Sopenharmony_ci * Rob Clark <robclark@freedesktop.org> 25bf215546Sopenharmony_ci */ 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "pipe/p_defines.h" 28bf215546Sopenharmony_ci#include "pipe/p_screen.h" 29bf215546Sopenharmony_ci#include "pipe/p_state.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "util/format/u_format.h" 32bf215546Sopenharmony_ci#include "util/format/u_format_s3tc.h" 33bf215546Sopenharmony_ci#include "util/u_debug.h" 34bf215546Sopenharmony_ci#include "util/u_inlines.h" 35bf215546Sopenharmony_ci#include "util/u_memory.h" 36bf215546Sopenharmony_ci#include "util/u_screen.h" 37bf215546Sopenharmony_ci#include "util/u_string.h" 38bf215546Sopenharmony_ci#include "util/xmlconfig.h" 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci#include "util/os_time.h" 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci#include <errno.h> 43bf215546Sopenharmony_ci#include <stdio.h> 44bf215546Sopenharmony_ci#include <stdlib.h> 45bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h" 46bf215546Sopenharmony_ci#include <sys/sysinfo.h> 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci#include "freedreno_fence.h" 49bf215546Sopenharmony_ci#include "freedreno_perfetto.h" 50bf215546Sopenharmony_ci#include "freedreno_query.h" 51bf215546Sopenharmony_ci#include "freedreno_resource.h" 52bf215546Sopenharmony_ci#include "freedreno_screen.h" 53bf215546Sopenharmony_ci#include "freedreno_util.h" 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci#include "a2xx/fd2_screen.h" 56bf215546Sopenharmony_ci#include "a3xx/fd3_screen.h" 57bf215546Sopenharmony_ci#include "a4xx/fd4_screen.h" 58bf215546Sopenharmony_ci#include "a5xx/fd5_screen.h" 59bf215546Sopenharmony_ci#include "a6xx/fd6_screen.h" 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci/* for fd_get_driver/device_uuid() */ 62bf215546Sopenharmony_ci#include "common/freedreno_uuid.h" 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci#include "a2xx/ir2.h" 65bf215546Sopenharmony_ci#include "ir3/ir3_gallium.h" 66bf215546Sopenharmony_ci#include "ir3/ir3_nir.h" 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci/* clang-format off */ 69bf215546Sopenharmony_cistatic const struct debug_named_value fd_debug_options[] = { 70bf215546Sopenharmony_ci {"msgs", FD_DBG_MSGS, "Print debug messages"}, 71bf215546Sopenharmony_ci {"disasm", FD_DBG_DISASM, "Dump TGSI and adreno shader disassembly (a2xx only, see IR3_SHADER_DEBUG)"}, 72bf215546Sopenharmony_ci {"dclear", FD_DBG_DCLEAR, "Mark all state dirty after clear"}, 73bf215546Sopenharmony_ci {"ddraw", FD_DBG_DDRAW, "Mark all state dirty after draw"}, 74bf215546Sopenharmony_ci {"noscis", FD_DBG_NOSCIS, "Disable scissor optimization"}, 75bf215546Sopenharmony_ci {"direct", FD_DBG_DIRECT, "Force inline (SS_DIRECT) state loads"}, 76bf215546Sopenharmony_ci {"gmem", FD_DBG_GMEM, "Use gmem rendering when it is permitted"}, 77bf215546Sopenharmony_ci {"perf", FD_DBG_PERF, "Enable performance warnings"}, 78bf215546Sopenharmony_ci {"nobin", FD_DBG_NOBIN, "Disable hw binning"}, 79bf215546Sopenharmony_ci {"sysmem", FD_DBG_SYSMEM, "Use sysmem only rendering (no tiling)"}, 80bf215546Sopenharmony_ci {"serialc", FD_DBG_SERIALC,"Disable asynchronous shader compile"}, 81bf215546Sopenharmony_ci {"shaderdb", FD_DBG_SHADERDB, "Enable shaderdb output"}, 82bf215546Sopenharmony_ci {"flush", FD_DBG_FLUSH, "Force flush after every draw"}, 83bf215546Sopenharmony_ci {"deqp", FD_DBG_DEQP, "Enable dEQP hacks"}, 84bf215546Sopenharmony_ci {"inorder", FD_DBG_INORDER, "Disable reordering for draws/blits"}, 85bf215546Sopenharmony_ci {"bstat", FD_DBG_BSTAT, "Print batch stats at context destroy"}, 86bf215546Sopenharmony_ci {"nogrow", FD_DBG_NOGROW, "Disable \"growable\" cmdstream buffers, even if kernel supports it"}, 87bf215546Sopenharmony_ci {"lrz", FD_DBG_LRZ, "Enable experimental LRZ support (a5xx)"}, 88bf215546Sopenharmony_ci {"noindirect",FD_DBG_NOINDR, "Disable hw indirect draws (emulate on CPU)"}, 89bf215546Sopenharmony_ci {"noblit", FD_DBG_NOBLIT, "Disable blitter (fallback to generic blit path)"}, 90bf215546Sopenharmony_ci {"hiprio", FD_DBG_HIPRIO, "Force high-priority context"}, 91bf215546Sopenharmony_ci {"ttile", FD_DBG_TTILE, "Enable texture tiling (a2xx/a3xx/a5xx)"}, 92bf215546Sopenharmony_ci {"perfcntrs", FD_DBG_PERFC, "Expose performance counters"}, 93bf215546Sopenharmony_ci {"noubwc", FD_DBG_NOUBWC, "Disable UBWC for all internal buffers"}, 94bf215546Sopenharmony_ci {"nolrz", FD_DBG_NOLRZ, "Disable LRZ (a6xx)"}, 95bf215546Sopenharmony_ci {"notile", FD_DBG_NOTILE, "Disable tiling for all internal buffers"}, 96bf215546Sopenharmony_ci {"layout", FD_DBG_LAYOUT, "Dump resource layouts"}, 97bf215546Sopenharmony_ci {"nofp16", FD_DBG_NOFP16, "Disable mediump precision lowering"}, 98bf215546Sopenharmony_ci {"nohw", FD_DBG_NOHW, "Disable submitting commands to the HW"}, 99bf215546Sopenharmony_ci {"nosbin", FD_DBG_NOSBIN, "Execute GMEM bins in raster order instead of 'S' pattern"}, 100bf215546Sopenharmony_ci DEBUG_NAMED_VALUE_END 101bf215546Sopenharmony_ci}; 102bf215546Sopenharmony_ci/* clang-format on */ 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ciDEBUG_GET_ONCE_FLAGS_OPTION(fd_mesa_debug, "FD_MESA_DEBUG", fd_debug_options, 0) 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ciint fd_mesa_debug = 0; 107bf215546Sopenharmony_cibool fd_binning_enabled = true; 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_cistatic const char * 110bf215546Sopenharmony_cifd_screen_get_name(struct pipe_screen *pscreen) 111bf215546Sopenharmony_ci{ 112bf215546Sopenharmony_ci return fd_dev_name(fd_screen(pscreen)->dev_id); 113bf215546Sopenharmony_ci} 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_cistatic const char * 116bf215546Sopenharmony_cifd_screen_get_vendor(struct pipe_screen *pscreen) 117bf215546Sopenharmony_ci{ 118bf215546Sopenharmony_ci return "freedreno"; 119bf215546Sopenharmony_ci} 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_cistatic const char * 122bf215546Sopenharmony_cifd_screen_get_device_vendor(struct pipe_screen *pscreen) 123bf215546Sopenharmony_ci{ 124bf215546Sopenharmony_ci return "Qualcomm"; 125bf215546Sopenharmony_ci} 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_cistatic uint64_t 128bf215546Sopenharmony_cifd_screen_get_timestamp(struct pipe_screen *pscreen) 129bf215546Sopenharmony_ci{ 130bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci if (screen->has_timestamp) { 133bf215546Sopenharmony_ci uint64_t n; 134bf215546Sopenharmony_ci fd_pipe_get_param(screen->pipe, FD_TIMESTAMP, &n); 135bf215546Sopenharmony_ci assert(screen->max_freq > 0); 136bf215546Sopenharmony_ci return n * 1000000000 / screen->max_freq; 137bf215546Sopenharmony_ci } else { 138bf215546Sopenharmony_ci int64_t cpu_time = os_time_get() * 1000; 139bf215546Sopenharmony_ci return cpu_time + screen->cpu_gpu_time_delta; 140bf215546Sopenharmony_ci } 141bf215546Sopenharmony_ci} 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_cistatic void 144bf215546Sopenharmony_cifd_screen_destroy(struct pipe_screen *pscreen) 145bf215546Sopenharmony_ci{ 146bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci if (screen->tess_bo) 149bf215546Sopenharmony_ci fd_bo_del(screen->tess_bo); 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci if (screen->pipe) 152bf215546Sopenharmony_ci fd_pipe_del(screen->pipe); 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci if (screen->dev) { 155bf215546Sopenharmony_ci fd_device_purge(screen->dev); 156bf215546Sopenharmony_ci fd_device_del(screen->dev); 157bf215546Sopenharmony_ci } 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci if (screen->ro) 160bf215546Sopenharmony_ci screen->ro->destroy(screen->ro); 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci fd_bc_fini(&screen->batch_cache); 163bf215546Sopenharmony_ci fd_gmem_screen_fini(pscreen); 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci slab_destroy_parent(&screen->transfer_pool); 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci simple_mtx_destroy(&screen->lock); 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci util_idalloc_mt_fini(&screen->buffer_ids); 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci u_transfer_helper_destroy(pscreen->transfer_helper); 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci if (screen->compiler) 174bf215546Sopenharmony_ci ir3_screen_fini(pscreen); 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci free(screen->perfcntr_queries); 177bf215546Sopenharmony_ci free(screen); 178bf215546Sopenharmony_ci} 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci/* 181bf215546Sopenharmony_ciTODO either move caps to a2xx/a3xx specific code, or maybe have some 182bf215546Sopenharmony_citables for things that differ if the delta is not too much.. 183bf215546Sopenharmony_ci */ 184bf215546Sopenharmony_cistatic int 185bf215546Sopenharmony_cifd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 186bf215546Sopenharmony_ci{ 187bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci /* this is probably not totally correct.. but it's a start: */ 190bf215546Sopenharmony_ci switch (param) { 191bf215546Sopenharmony_ci /* Supported features (boolean caps). */ 192bf215546Sopenharmony_ci case PIPE_CAP_NPOT_TEXTURES: 193bf215546Sopenharmony_ci case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: 194bf215546Sopenharmony_ci case PIPE_CAP_ANISOTROPIC_FILTER: 195bf215546Sopenharmony_ci case PIPE_CAP_POINT_SPRITE: 196bf215546Sopenharmony_ci case PIPE_CAP_BLEND_EQUATION_SEPARATE: 197bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_SWIZZLE: 198bf215546Sopenharmony_ci case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 199bf215546Sopenharmony_ci case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT: 200bf215546Sopenharmony_ci case PIPE_CAP_SEAMLESS_CUBE_MAP: 201bf215546Sopenharmony_ci case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 202bf215546Sopenharmony_ci case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 203bf215546Sopenharmony_ci case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: 204bf215546Sopenharmony_ci case PIPE_CAP_STRING_MARKER: 205bf215546Sopenharmony_ci case PIPE_CAP_MIXED_COLOR_DEPTH_BITS: 206bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_BARRIER: 207bf215546Sopenharmony_ci case PIPE_CAP_INVALIDATE_BUFFER: 208bf215546Sopenharmony_ci case PIPE_CAP_RGB_OVERRIDE_DST_ALPHA_BLEND: 209bf215546Sopenharmony_ci case PIPE_CAP_GLSL_TESS_LEVELS_AS_INPUTS: 210bf215546Sopenharmony_ci case PIPE_CAP_NIR_COMPACT_ARRAYS: 211bf215546Sopenharmony_ci return 1; 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS: 214bf215546Sopenharmony_ci return is_a6xx(screen); 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: 217bf215546Sopenharmony_ci case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: 218bf215546Sopenharmony_ci case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: 219bf215546Sopenharmony_ci return is_a2xx(screen); 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER: 222bf215546Sopenharmony_ci return is_a2xx(screen); 223bf215546Sopenharmony_ci case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 224bf215546Sopenharmony_ci return !is_a2xx(screen); 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci case PIPE_CAP_PACKED_UNIFORMS: 227bf215546Sopenharmony_ci return !is_a2xx(screen); 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR: 230bf215546Sopenharmony_ci case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: 231bf215546Sopenharmony_ci return screen->has_robustness; 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci case PIPE_CAP_VERTEXID_NOBASE: 234bf215546Sopenharmony_ci return is_a3xx(screen) || is_a4xx(screen); 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci case PIPE_CAP_COMPUTE: 237bf215546Sopenharmony_ci return has_compute(screen); 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_TRANSFER_MODES: 240bf215546Sopenharmony_ci case PIPE_CAP_PCI_GROUP: 241bf215546Sopenharmony_ci case PIPE_CAP_PCI_BUS: 242bf215546Sopenharmony_ci case PIPE_CAP_PCI_DEVICE: 243bf215546Sopenharmony_ci case PIPE_CAP_PCI_FUNCTION: 244bf215546Sopenharmony_ci return 0; 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci case PIPE_CAP_SUPPORTED_PRIM_MODES: 247bf215546Sopenharmony_ci case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART: 248bf215546Sopenharmony_ci return screen->primtypes_mask; 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD: 251bf215546Sopenharmony_ci case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES: 252bf215546Sopenharmony_ci case PIPE_CAP_PRIMITIVE_RESTART: 253bf215546Sopenharmony_ci case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX: 254bf215546Sopenharmony_ci case PIPE_CAP_VS_INSTANCEID: 255bf215546Sopenharmony_ci case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 256bf215546Sopenharmony_ci case PIPE_CAP_INDEP_BLEND_ENABLE: 257bf215546Sopenharmony_ci case PIPE_CAP_INDEP_BLEND_FUNC: 258bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: 259bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR: 260bf215546Sopenharmony_ci case PIPE_CAP_CONDITIONAL_RENDER: 261bf215546Sopenharmony_ci case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: 262bf215546Sopenharmony_ci case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 263bf215546Sopenharmony_ci case PIPE_CAP_CLIP_HALFZ: 264bf215546Sopenharmony_ci return is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) || 265bf215546Sopenharmony_ci is_a6xx(screen); 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_ci case PIPE_CAP_FAKE_SW_MSAA: 268bf215546Sopenharmony_ci return !fd_screen_get_param(pscreen, PIPE_CAP_TEXTURE_MULTISAMPLE); 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_MULTISAMPLE: 271bf215546Sopenharmony_ci case PIPE_CAP_IMAGE_STORE_FORMATTED: 272bf215546Sopenharmony_ci return is_a5xx(screen) || is_a6xx(screen); 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci case PIPE_CAP_SURFACE_SAMPLE_COUNT: 275bf215546Sopenharmony_ci return is_a6xx(screen); 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci case PIPE_CAP_DEPTH_CLIP_DISABLE: 278bf215546Sopenharmony_ci return is_a3xx(screen) || is_a4xx(screen) || is_a6xx(screen); 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE: 281bf215546Sopenharmony_ci return is_a6xx(screen); 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci case PIPE_CAP_POLYGON_OFFSET_CLAMP: 284bf215546Sopenharmony_ci return is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen); 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ci case PIPE_CAP_PREFER_IMM_ARRAYS_AS_CONSTBUF: 287bf215546Sopenharmony_ci return 0; 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: 290bf215546Sopenharmony_ci if (is_a3xx(screen)) 291bf215546Sopenharmony_ci return 16; 292bf215546Sopenharmony_ci if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen)) 293bf215546Sopenharmony_ci return 64; 294bf215546Sopenharmony_ci return 0; 295bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT: 296bf215546Sopenharmony_ci /* We could possibly emulate more by pretending 2d/rect textures and 297bf215546Sopenharmony_ci * splitting high bits of index into 2nd dimension.. 298bf215546Sopenharmony_ci */ 299bf215546Sopenharmony_ci if (is_a3xx(screen)) 300bf215546Sopenharmony_ci return 8192; 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci /* Note that the Vulkan blob on a540 and 640 report a 303bf215546Sopenharmony_ci * maxTexelBufferElements of just 65536 (the GLES3.2 and Vulkan 304bf215546Sopenharmony_ci * minimum). 305bf215546Sopenharmony_ci */ 306bf215546Sopenharmony_ci if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen)) 307bf215546Sopenharmony_ci return 1 << 27; 308bf215546Sopenharmony_ci return 0; 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_FLOAT_LINEAR: 311bf215546Sopenharmony_ci case PIPE_CAP_CUBE_MAP_ARRAY: 312bf215546Sopenharmony_ci case PIPE_CAP_SAMPLER_VIEW_TARGET: 313bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_QUERY_LOD: 314bf215546Sopenharmony_ci return is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen); 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_ci case PIPE_CAP_START_INSTANCE: 317bf215546Sopenharmony_ci /* Note that a5xx can do this, it just can't (at least with 318bf215546Sopenharmony_ci * current firmware) do draw_indirect with base_instance. 319bf215546Sopenharmony_ci * Since draw_indirect is needed sooner (gles31 and gl40 vs 320bf215546Sopenharmony_ci * gl42), hide base_instance on a5xx. :-/ 321bf215546Sopenharmony_ci */ 322bf215546Sopenharmony_ci return is_a4xx(screen); 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 325bf215546Sopenharmony_ci return 64; 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_ci case PIPE_CAP_GLSL_FEATURE_LEVEL: 328bf215546Sopenharmony_ci case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY: 329bf215546Sopenharmony_ci if (is_a6xx(screen)) 330bf215546Sopenharmony_ci return 330; 331bf215546Sopenharmony_ci else if (is_ir3(screen)) 332bf215546Sopenharmony_ci return 140; 333bf215546Sopenharmony_ci else 334bf215546Sopenharmony_ci return 120; 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci case PIPE_CAP_ESSL_FEATURE_LEVEL: 337bf215546Sopenharmony_ci if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen)) 338bf215546Sopenharmony_ci return 320; 339bf215546Sopenharmony_ci if (is_ir3(screen)) 340bf215546Sopenharmony_ci return 300; 341bf215546Sopenharmony_ci return 120; 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT: 344bf215546Sopenharmony_ci if (is_a6xx(screen)) 345bf215546Sopenharmony_ci return 64; 346bf215546Sopenharmony_ci if (is_a5xx(screen)) 347bf215546Sopenharmony_ci return 4; 348bf215546Sopenharmony_ci if (is_a4xx(screen)) 349bf215546Sopenharmony_ci return 4; 350bf215546Sopenharmony_ci return 0; 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: 353bf215546Sopenharmony_ci if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen)) 354bf215546Sopenharmony_ci return 4; 355bf215546Sopenharmony_ci return 0; 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci /* TODO if we need this, do it in nir/ir3 backend to avoid breaking 358bf215546Sopenharmony_ci * precompile: */ 359bf215546Sopenharmony_ci case PIPE_CAP_FORCE_PERSAMPLE_INTERP: 360bf215546Sopenharmony_ci return 0; 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci case PIPE_CAP_FBFETCH: 363bf215546Sopenharmony_ci if (fd_device_version(screen->dev) >= FD_VERSION_GMEM_BASE && 364bf215546Sopenharmony_ci is_a6xx(screen)) 365bf215546Sopenharmony_ci return 1; 366bf215546Sopenharmony_ci return 0; 367bf215546Sopenharmony_ci case PIPE_CAP_SAMPLE_SHADING: 368bf215546Sopenharmony_ci if (is_a6xx(screen)) 369bf215546Sopenharmony_ci return 1; 370bf215546Sopenharmony_ci return 0; 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci case PIPE_CAP_CONTEXT_PRIORITY_MASK: 373bf215546Sopenharmony_ci return screen->priority_mask; 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ci case PIPE_CAP_DRAW_INDIRECT: 376bf215546Sopenharmony_ci if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen)) 377bf215546Sopenharmony_ci return 1; 378bf215546Sopenharmony_ci return 0; 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT: 381bf215546Sopenharmony_ci if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen)) 382bf215546Sopenharmony_ci return 1; 383bf215546Sopenharmony_ci return 0; 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci case PIPE_CAP_LOAD_CONSTBUF: 386bf215546Sopenharmony_ci /* name is confusing, but this turns on std430 packing */ 387bf215546Sopenharmony_ci if (is_ir3(screen)) 388bf215546Sopenharmony_ci return 1; 389bf215546Sopenharmony_ci return 0; 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci case PIPE_CAP_NIR_IMAGES_AS_DEREF: 392bf215546Sopenharmony_ci return 0; 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci case PIPE_CAP_MAX_VIEWPORTS: 395bf215546Sopenharmony_ci return 1; 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_ci case PIPE_CAP_MAX_VARYINGS: 398bf215546Sopenharmony_ci return is_a6xx(screen) ? 31 : 16; 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS: 401bf215546Sopenharmony_ci /* We don't really have a limit on this, it all goes into the main 402bf215546Sopenharmony_ci * memory buffer. Needs to be at least 120 / 4 (minimum requirement 403bf215546Sopenharmony_ci * for GL_MAX_TESS_PATCH_COMPONENTS). 404bf215546Sopenharmony_ci */ 405bf215546Sopenharmony_ci return 128; 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET: 408bf215546Sopenharmony_ci return 64 * 1024 * 1024; 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci case PIPE_CAP_SHAREABLE_SHADERS: 411bf215546Sopenharmony_ci if (is_ir3(screen)) 412bf215546Sopenharmony_ci return 1; 413bf215546Sopenharmony_ci return 0; 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_ci /* Geometry shaders.. */ 416bf215546Sopenharmony_ci case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES: 417bf215546Sopenharmony_ci return 512; 418bf215546Sopenharmony_ci case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: 419bf215546Sopenharmony_ci return 2048; 420bf215546Sopenharmony_ci case PIPE_CAP_MAX_GS_INVOCATIONS: 421bf215546Sopenharmony_ci return 32; 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci /* Only a2xx has the half-border clamp mode in HW, just have mesa/st lower 424bf215546Sopenharmony_ci * it for later HW. 425bf215546Sopenharmony_ci */ 426bf215546Sopenharmony_ci case PIPE_CAP_GL_CLAMP: 427bf215546Sopenharmony_ci return is_a2xx(screen); 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci case PIPE_CAP_CLIP_PLANES: 430bf215546Sopenharmony_ci /* Gens that support GS, have GS lowered into a quasi-VS which confuses 431bf215546Sopenharmony_ci * the frontend clip-plane lowering. So we handle this in the backend 432bf215546Sopenharmony_ci * 433bf215546Sopenharmony_ci */ 434bf215546Sopenharmony_ci if (pscreen->get_shader_param(pscreen, PIPE_SHADER_GEOMETRY, 435bf215546Sopenharmony_ci PIPE_SHADER_CAP_MAX_INSTRUCTIONS)) 436bf215546Sopenharmony_ci return 1; 437bf215546Sopenharmony_ci 438bf215546Sopenharmony_ci /* On a3xx, there is HW support for GL user clip planes that 439bf215546Sopenharmony_ci * occasionally has to fall back to shader key-based lowering to clip 440bf215546Sopenharmony_ci * distances in the VS, and we don't support clip distances so that is 441bf215546Sopenharmony_ci * always shader-based lowering in the FS. 442bf215546Sopenharmony_ci * 443bf215546Sopenharmony_ci * On a4xx, there is no HW support for clip planes, so they are 444bf215546Sopenharmony_ci * always lowered to clip distances. We also lack SW support for the 445bf215546Sopenharmony_ci * HW's clip distances in HW, so we do shader-based lowering in the FS 446bf215546Sopenharmony_ci * in the driver backend. 447bf215546Sopenharmony_ci * 448bf215546Sopenharmony_ci * On a5xx-a6xx, we have the HW clip distances hooked up, so we just let 449bf215546Sopenharmony_ci * mesa/st lower desktop GL's clip planes to clip distances in the last 450bf215546Sopenharmony_ci * vertex shader stage. 451bf215546Sopenharmony_ci * 452bf215546Sopenharmony_ci * NOTE: but see comment above about geometry shaders 453bf215546Sopenharmony_ci */ 454bf215546Sopenharmony_ci return !is_a5xx(screen); 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_ci /* Stream output. */ 457bf215546Sopenharmony_ci case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 458bf215546Sopenharmony_ci if (is_ir3(screen)) 459bf215546Sopenharmony_ci return PIPE_MAX_SO_BUFFERS; 460bf215546Sopenharmony_ci return 0; 461bf215546Sopenharmony_ci case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 462bf215546Sopenharmony_ci case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS: 463bf215546Sopenharmony_ci case PIPE_CAP_FS_POSITION_IS_SYSVAL: 464bf215546Sopenharmony_ci case PIPE_CAP_TGSI_TEXCOORD: 465bf215546Sopenharmony_ci if (is_ir3(screen)) 466bf215546Sopenharmony_ci return 1; 467bf215546Sopenharmony_ci return 0; 468bf215546Sopenharmony_ci case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL: 469bf215546Sopenharmony_ci return 1; 470bf215546Sopenharmony_ci case PIPE_CAP_FS_POINT_IS_SYSVAL: 471bf215546Sopenharmony_ci return is_a2xx(screen); 472bf215546Sopenharmony_ci case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 473bf215546Sopenharmony_ci case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 474bf215546Sopenharmony_ci if (is_ir3(screen)) 475bf215546Sopenharmony_ci return 16 * 4; /* should only be shader out limit? */ 476bf215546Sopenharmony_ci return 0; 477bf215546Sopenharmony_ci 478bf215546Sopenharmony_ci /* Texturing. */ 479bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_2D_SIZE: 480bf215546Sopenharmony_ci if (is_a6xx(screen) || is_a5xx(screen) || is_a4xx(screen)) 481bf215546Sopenharmony_ci return 16384; 482bf215546Sopenharmony_ci else 483bf215546Sopenharmony_ci return 8192; 484bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 485bf215546Sopenharmony_ci if (is_a6xx(screen) || is_a5xx(screen) || is_a4xx(screen)) 486bf215546Sopenharmony_ci return 15; 487bf215546Sopenharmony_ci else 488bf215546Sopenharmony_ci return 14; 489bf215546Sopenharmony_ci 490bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 491bf215546Sopenharmony_ci if (is_a3xx(screen)) 492bf215546Sopenharmony_ci return 11; 493bf215546Sopenharmony_ci return 12; 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 496bf215546Sopenharmony_ci return (is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) || 497bf215546Sopenharmony_ci is_a6xx(screen)) 498bf215546Sopenharmony_ci ? 256 499bf215546Sopenharmony_ci : 0; 500bf215546Sopenharmony_ci 501bf215546Sopenharmony_ci /* Render targets. */ 502bf215546Sopenharmony_ci case PIPE_CAP_MAX_RENDER_TARGETS: 503bf215546Sopenharmony_ci return screen->max_rts; 504bf215546Sopenharmony_ci case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 505bf215546Sopenharmony_ci return (is_a3xx(screen) || is_a6xx(screen)) ? 1 : 0; 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci /* Queries. */ 508bf215546Sopenharmony_ci case PIPE_CAP_OCCLUSION_QUERY: 509bf215546Sopenharmony_ci return is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) || 510bf215546Sopenharmony_ci is_a6xx(screen); 511bf215546Sopenharmony_ci case PIPE_CAP_QUERY_TIMESTAMP: 512bf215546Sopenharmony_ci case PIPE_CAP_QUERY_TIME_ELAPSED: 513bf215546Sopenharmony_ci /* only a4xx, requires new enough kernel so we know max_freq: */ 514bf215546Sopenharmony_ci return (screen->max_freq > 0) && 515bf215546Sopenharmony_ci (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen)); 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_ci case PIPE_CAP_VENDOR_ID: 518bf215546Sopenharmony_ci return 0x5143; 519bf215546Sopenharmony_ci case PIPE_CAP_DEVICE_ID: 520bf215546Sopenharmony_ci return 0xFFFFFFFF; 521bf215546Sopenharmony_ci case PIPE_CAP_ACCELERATED: 522bf215546Sopenharmony_ci return 1; 523bf215546Sopenharmony_ci 524bf215546Sopenharmony_ci case PIPE_CAP_VIDEO_MEMORY: { 525bf215546Sopenharmony_ci uint64_t system_memory; 526bf215546Sopenharmony_ci 527bf215546Sopenharmony_ci if (!os_get_total_physical_memory(&system_memory)) 528bf215546Sopenharmony_ci return 0; 529bf215546Sopenharmony_ci 530bf215546Sopenharmony_ci return (int)(system_memory >> 20); 531bf215546Sopenharmony_ci } 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_ci case PIPE_CAP_UMA: 534bf215546Sopenharmony_ci return 1; 535bf215546Sopenharmony_ci case PIPE_CAP_MEMOBJ: 536bf215546Sopenharmony_ci return fd_device_version(screen->dev) >= FD_VERSION_MEMORY_FD; 537bf215546Sopenharmony_ci case PIPE_CAP_NATIVE_FENCE_FD: 538bf215546Sopenharmony_ci return fd_device_version(screen->dev) >= FD_VERSION_FENCE_FD; 539bf215546Sopenharmony_ci case PIPE_CAP_FENCE_SIGNAL: 540bf215546Sopenharmony_ci return screen->has_syncobj; 541bf215546Sopenharmony_ci case PIPE_CAP_CULL_DISTANCE: 542bf215546Sopenharmony_ci return is_a6xx(screen); 543bf215546Sopenharmony_ci case PIPE_CAP_SHADER_STENCIL_EXPORT: 544bf215546Sopenharmony_ci return is_a6xx(screen); 545bf215546Sopenharmony_ci case PIPE_CAP_TWO_SIDED_COLOR: 546bf215546Sopenharmony_ci return 0; 547bf215546Sopenharmony_ci default: 548bf215546Sopenharmony_ci return u_pipe_screen_get_param_defaults(pscreen, param); 549bf215546Sopenharmony_ci } 550bf215546Sopenharmony_ci} 551bf215546Sopenharmony_ci 552bf215546Sopenharmony_cistatic float 553bf215546Sopenharmony_cifd_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) 554bf215546Sopenharmony_ci{ 555bf215546Sopenharmony_ci switch (param) { 556bf215546Sopenharmony_ci case PIPE_CAPF_MIN_LINE_WIDTH: 557bf215546Sopenharmony_ci case PIPE_CAPF_MIN_LINE_WIDTH_AA: 558bf215546Sopenharmony_ci case PIPE_CAPF_MIN_POINT_SIZE: 559bf215546Sopenharmony_ci case PIPE_CAPF_MIN_POINT_SIZE_AA: 560bf215546Sopenharmony_ci return 1; 561bf215546Sopenharmony_ci case PIPE_CAPF_POINT_SIZE_GRANULARITY: 562bf215546Sopenharmony_ci case PIPE_CAPF_LINE_WIDTH_GRANULARITY: 563bf215546Sopenharmony_ci return 0.1f; 564bf215546Sopenharmony_ci case PIPE_CAPF_MAX_LINE_WIDTH: 565bf215546Sopenharmony_ci case PIPE_CAPF_MAX_LINE_WIDTH_AA: 566bf215546Sopenharmony_ci /* NOTE: actual value is 127.0f, but this is working around a deqp 567bf215546Sopenharmony_ci * bug.. dEQP-GLES3.functional.rasterization.primitives.lines_wide 568bf215546Sopenharmony_ci * uses too small of a render target size, and gets confused when 569bf215546Sopenharmony_ci * the lines start going offscreen. 570bf215546Sopenharmony_ci * 571bf215546Sopenharmony_ci * See: https://code.google.com/p/android/issues/detail?id=206513 572bf215546Sopenharmony_ci */ 573bf215546Sopenharmony_ci if (FD_DBG(DEQP)) 574bf215546Sopenharmony_ci return 48.0f; 575bf215546Sopenharmony_ci return 127.0f; 576bf215546Sopenharmony_ci case PIPE_CAPF_MAX_POINT_SIZE: 577bf215546Sopenharmony_ci case PIPE_CAPF_MAX_POINT_SIZE_AA: 578bf215546Sopenharmony_ci return 4092.0f; 579bf215546Sopenharmony_ci case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 580bf215546Sopenharmony_ci return 16.0f; 581bf215546Sopenharmony_ci case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 582bf215546Sopenharmony_ci return 15.0f; 583bf215546Sopenharmony_ci case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE: 584bf215546Sopenharmony_ci case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE: 585bf215546Sopenharmony_ci case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY: 586bf215546Sopenharmony_ci return 0.0f; 587bf215546Sopenharmony_ci } 588bf215546Sopenharmony_ci mesa_loge("unknown paramf %d", param); 589bf215546Sopenharmony_ci return 0; 590bf215546Sopenharmony_ci} 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_cistatic int 593bf215546Sopenharmony_cifd_screen_get_shader_param(struct pipe_screen *pscreen, 594bf215546Sopenharmony_ci enum pipe_shader_type shader, 595bf215546Sopenharmony_ci enum pipe_shader_cap param) 596bf215546Sopenharmony_ci{ 597bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 598bf215546Sopenharmony_ci 599bf215546Sopenharmony_ci switch (shader) { 600bf215546Sopenharmony_ci case PIPE_SHADER_FRAGMENT: 601bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 602bf215546Sopenharmony_ci break; 603bf215546Sopenharmony_ci case PIPE_SHADER_TESS_CTRL: 604bf215546Sopenharmony_ci case PIPE_SHADER_TESS_EVAL: 605bf215546Sopenharmony_ci case PIPE_SHADER_GEOMETRY: 606bf215546Sopenharmony_ci if (is_a6xx(screen)) 607bf215546Sopenharmony_ci break; 608bf215546Sopenharmony_ci return 0; 609bf215546Sopenharmony_ci case PIPE_SHADER_COMPUTE: 610bf215546Sopenharmony_ci if (has_compute(screen)) 611bf215546Sopenharmony_ci break; 612bf215546Sopenharmony_ci return 0; 613bf215546Sopenharmony_ci default: 614bf215546Sopenharmony_ci mesa_loge("unknown shader type %d", shader); 615bf215546Sopenharmony_ci return 0; 616bf215546Sopenharmony_ci } 617bf215546Sopenharmony_ci 618bf215546Sopenharmony_ci /* this is probably not totally correct.. but it's a start: */ 619bf215546Sopenharmony_ci switch (param) { 620bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 621bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 622bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 623bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 624bf215546Sopenharmony_ci return 16384; 625bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 626bf215546Sopenharmony_ci return 8; /* XXX */ 627bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_INPUTS: 628bf215546Sopenharmony_ci if (shader == PIPE_SHADER_GEOMETRY && is_a6xx(screen)) 629bf215546Sopenharmony_ci return 16; 630bf215546Sopenharmony_ci return is_a6xx(screen) ? 32 : 16; 631bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_OUTPUTS: 632bf215546Sopenharmony_ci return is_a6xx(screen) ? 32 : 16; 633bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_TEMPS: 634bf215546Sopenharmony_ci return 64; /* Max native temporaries. */ 635bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE: 636bf215546Sopenharmony_ci /* NOTE: seems to be limit for a3xx is actually 512 but 637bf215546Sopenharmony_ci * split between VS and FS. Use lower limit of 256 to 638bf215546Sopenharmony_ci * avoid getting into impossible situations: 639bf215546Sopenharmony_ci */ 640bf215546Sopenharmony_ci return ((is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) || 641bf215546Sopenharmony_ci is_a6xx(screen)) 642bf215546Sopenharmony_ci ? 4096 643bf215546Sopenharmony_ci : 64) * 644bf215546Sopenharmony_ci sizeof(float[4]); 645bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 646bf215546Sopenharmony_ci return is_ir3(screen) ? 16 : 1; 647bf215546Sopenharmony_ci case PIPE_SHADER_CAP_CONT_SUPPORTED: 648bf215546Sopenharmony_ci return 1; 649bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 650bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 651bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 652bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 653bf215546Sopenharmony_ci /* a2xx compiler doesn't handle indirect: */ 654bf215546Sopenharmony_ci return is_ir3(screen) ? 1 : 0; 655bf215546Sopenharmony_ci case PIPE_SHADER_CAP_SUBROUTINES: 656bf215546Sopenharmony_ci case PIPE_SHADER_CAP_DROUND_SUPPORTED: 657bf215546Sopenharmony_ci case PIPE_SHADER_CAP_DFRACEXP_DLDEXP_SUPPORTED: 658bf215546Sopenharmony_ci case PIPE_SHADER_CAP_LDEXP_SUPPORTED: 659bf215546Sopenharmony_ci case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: 660bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS: 661bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS: 662bf215546Sopenharmony_ci return 0; 663bf215546Sopenharmony_ci case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: 664bf215546Sopenharmony_ci return 1; 665bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INTEGERS: 666bf215546Sopenharmony_ci return is_ir3(screen) ? 1 : 0; 667bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INT64_ATOMICS: 668bf215546Sopenharmony_ci case PIPE_SHADER_CAP_FP16_DERIVATIVES: 669bf215546Sopenharmony_ci case PIPE_SHADER_CAP_FP16_CONST_BUFFERS: 670bf215546Sopenharmony_ci case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS: 671bf215546Sopenharmony_ci return 0; 672bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INT16: 673bf215546Sopenharmony_ci case PIPE_SHADER_CAP_FP16: 674bf215546Sopenharmony_ci return ( 675bf215546Sopenharmony_ci (is_a5xx(screen) || is_a6xx(screen)) && 676bf215546Sopenharmony_ci (shader == PIPE_SHADER_COMPUTE || shader == PIPE_SHADER_FRAGMENT) && 677bf215546Sopenharmony_ci !FD_DBG(NOFP16)); 678bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 679bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 680bf215546Sopenharmony_ci return 16; 681bf215546Sopenharmony_ci case PIPE_SHADER_CAP_PREFERRED_IR: 682bf215546Sopenharmony_ci return PIPE_SHADER_IR_NIR; 683bf215546Sopenharmony_ci case PIPE_SHADER_CAP_SUPPORTED_IRS: 684bf215546Sopenharmony_ci return (1 << PIPE_SHADER_IR_NIR) | 685bf215546Sopenharmony_ci COND(has_compute(screen) && (shader == PIPE_SHADER_COMPUTE), 686bf215546Sopenharmony_ci (1 << PIPE_SHADER_IR_NIR_SERIALIZED)) | 687bf215546Sopenharmony_ci (1 << PIPE_SHADER_IR_TGSI); 688bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: 689bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: 690bf215546Sopenharmony_ci if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen)) { 691bf215546Sopenharmony_ci /* a5xx (and a4xx for that matter) has one state-block 692bf215546Sopenharmony_ci * for compute-shader SSBO's and another that is shared 693bf215546Sopenharmony_ci * by VS/HS/DS/GS/FS.. so to simplify things for now 694bf215546Sopenharmony_ci * just advertise SSBOs for FS and CS. We could possibly 695bf215546Sopenharmony_ci * do what blob does, and partition the space for 696bf215546Sopenharmony_ci * VS/HS/DS/GS/FS. The blob advertises: 697bf215546Sopenharmony_ci * 698bf215546Sopenharmony_ci * GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: 4 699bf215546Sopenharmony_ci * GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS: 4 700bf215546Sopenharmony_ci * GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS: 4 701bf215546Sopenharmony_ci * GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS: 4 702bf215546Sopenharmony_ci * GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: 4 703bf215546Sopenharmony_ci * GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: 24 704bf215546Sopenharmony_ci * GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: 24 705bf215546Sopenharmony_ci * 706bf215546Sopenharmony_ci * I think that way we could avoid having to patch shaders 707bf215546Sopenharmony_ci * for actual SSBO indexes by using a static partitioning. 708bf215546Sopenharmony_ci * 709bf215546Sopenharmony_ci * Note same state block is used for images and buffers, 710bf215546Sopenharmony_ci * but images also need texture state for read access 711bf215546Sopenharmony_ci * (isam/isam.3d) 712bf215546Sopenharmony_ci */ 713bf215546Sopenharmony_ci switch (shader) { 714bf215546Sopenharmony_ci case PIPE_SHADER_FRAGMENT: 715bf215546Sopenharmony_ci case PIPE_SHADER_COMPUTE: 716bf215546Sopenharmony_ci return 24; 717bf215546Sopenharmony_ci default: 718bf215546Sopenharmony_ci return 0; 719bf215546Sopenharmony_ci } 720bf215546Sopenharmony_ci } 721bf215546Sopenharmony_ci return 0; 722bf215546Sopenharmony_ci } 723bf215546Sopenharmony_ci mesa_loge("unknown shader param %d", param); 724bf215546Sopenharmony_ci return 0; 725bf215546Sopenharmony_ci} 726bf215546Sopenharmony_ci 727bf215546Sopenharmony_ci/* TODO depending on how much the limits differ for a3xx/a4xx, maybe move this 728bf215546Sopenharmony_ci * into per-generation backend? 729bf215546Sopenharmony_ci */ 730bf215546Sopenharmony_cistatic int 731bf215546Sopenharmony_cifd_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type, 732bf215546Sopenharmony_ci enum pipe_compute_cap param, void *ret) 733bf215546Sopenharmony_ci{ 734bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 735bf215546Sopenharmony_ci const char *const ir = "ir3"; 736bf215546Sopenharmony_ci 737bf215546Sopenharmony_ci if (!has_compute(screen)) 738bf215546Sopenharmony_ci return 0; 739bf215546Sopenharmony_ci 740bf215546Sopenharmony_ci struct ir3_compiler *compiler = screen->compiler; 741bf215546Sopenharmony_ci 742bf215546Sopenharmony_ci#define RET(x) \ 743bf215546Sopenharmony_ci do { \ 744bf215546Sopenharmony_ci if (ret) \ 745bf215546Sopenharmony_ci memcpy(ret, x, sizeof(x)); \ 746bf215546Sopenharmony_ci return sizeof(x); \ 747bf215546Sopenharmony_ci } while (0) 748bf215546Sopenharmony_ci 749bf215546Sopenharmony_ci switch (param) { 750bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_ADDRESS_BITS: 751bf215546Sopenharmony_ci if (screen->gen >= 5) 752bf215546Sopenharmony_ci RET((uint32_t[]){64}); 753bf215546Sopenharmony_ci RET((uint32_t[]){32}); 754bf215546Sopenharmony_ci 755bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_IR_TARGET: 756bf215546Sopenharmony_ci if (ret) 757bf215546Sopenharmony_ci sprintf(ret, "%s", ir); 758bf215546Sopenharmony_ci return strlen(ir) * sizeof(char); 759bf215546Sopenharmony_ci 760bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_GRID_DIMENSION: 761bf215546Sopenharmony_ci RET((uint64_t[]){3}); 762bf215546Sopenharmony_ci 763bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_GRID_SIZE: 764bf215546Sopenharmony_ci RET(((uint64_t[]){65535, 65535, 65535})); 765bf215546Sopenharmony_ci 766bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE: 767bf215546Sopenharmony_ci RET(((uint64_t[]){1024, 1024, 64})); 768bf215546Sopenharmony_ci 769bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK: 770bf215546Sopenharmony_ci RET((uint64_t[]){1024}); 771bf215546Sopenharmony_ci 772bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE: 773bf215546Sopenharmony_ci RET((uint64_t[]){screen->ram_size}); 774bf215546Sopenharmony_ci 775bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE: 776bf215546Sopenharmony_ci RET((uint64_t[]){32768}); 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE: 779bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE: 780bf215546Sopenharmony_ci RET((uint64_t[]){4096}); 781bf215546Sopenharmony_ci 782bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE: 783bf215546Sopenharmony_ci RET((uint64_t[]){screen->ram_size}); 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY: 786bf215546Sopenharmony_ci RET((uint32_t[]){screen->max_freq / 1000000}); 787bf215546Sopenharmony_ci 788bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS: 789bf215546Sopenharmony_ci RET((uint32_t[]){9999}); // TODO 790bf215546Sopenharmony_ci 791bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED: 792bf215546Sopenharmony_ci RET((uint32_t[]){1}); 793bf215546Sopenharmony_ci 794bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_SUBGROUP_SIZE: 795bf215546Sopenharmony_ci RET((uint32_t[]){32}); // TODO 796bf215546Sopenharmony_ci 797bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK: 798bf215546Sopenharmony_ci RET((uint64_t[]){ compiler->max_variable_workgroup_size }); 799bf215546Sopenharmony_ci } 800bf215546Sopenharmony_ci 801bf215546Sopenharmony_ci return 0; 802bf215546Sopenharmony_ci} 803bf215546Sopenharmony_ci 804bf215546Sopenharmony_cistatic const void * 805bf215546Sopenharmony_cifd_get_compiler_options(struct pipe_screen *pscreen, enum pipe_shader_ir ir, 806bf215546Sopenharmony_ci unsigned shader) 807bf215546Sopenharmony_ci{ 808bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_ci if (is_ir3(screen)) 811bf215546Sopenharmony_ci return ir3_get_compiler_options(screen->compiler); 812bf215546Sopenharmony_ci 813bf215546Sopenharmony_ci return ir2_get_compiler_options(); 814bf215546Sopenharmony_ci} 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_cistatic struct disk_cache * 817bf215546Sopenharmony_cifd_get_disk_shader_cache(struct pipe_screen *pscreen) 818bf215546Sopenharmony_ci{ 819bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci if (is_ir3(screen)) { 822bf215546Sopenharmony_ci struct ir3_compiler *compiler = screen->compiler; 823bf215546Sopenharmony_ci return compiler->disk_cache; 824bf215546Sopenharmony_ci } 825bf215546Sopenharmony_ci 826bf215546Sopenharmony_ci return NULL; 827bf215546Sopenharmony_ci} 828bf215546Sopenharmony_ci 829bf215546Sopenharmony_cibool 830bf215546Sopenharmony_cifd_screen_bo_get_handle(struct pipe_screen *pscreen, struct fd_bo *bo, 831bf215546Sopenharmony_ci struct renderonly_scanout *scanout, unsigned stride, 832bf215546Sopenharmony_ci struct winsys_handle *whandle) 833bf215546Sopenharmony_ci{ 834bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 835bf215546Sopenharmony_ci 836bf215546Sopenharmony_ci whandle->stride = stride; 837bf215546Sopenharmony_ci 838bf215546Sopenharmony_ci if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) { 839bf215546Sopenharmony_ci return fd_bo_get_name(bo, &whandle->handle) == 0; 840bf215546Sopenharmony_ci } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) { 841bf215546Sopenharmony_ci if (screen->ro) { 842bf215546Sopenharmony_ci return renderonly_get_handle(scanout, whandle); 843bf215546Sopenharmony_ci } else { 844bf215546Sopenharmony_ci whandle->handle = fd_bo_handle(bo); 845bf215546Sopenharmony_ci return true; 846bf215546Sopenharmony_ci } 847bf215546Sopenharmony_ci } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) { 848bf215546Sopenharmony_ci whandle->handle = fd_bo_dmabuf(bo); 849bf215546Sopenharmony_ci return true; 850bf215546Sopenharmony_ci } else { 851bf215546Sopenharmony_ci return false; 852bf215546Sopenharmony_ci } 853bf215546Sopenharmony_ci} 854bf215546Sopenharmony_ci 855bf215546Sopenharmony_cistatic void 856bf215546Sopenharmony_cifd_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, 857bf215546Sopenharmony_ci enum pipe_format format, int max, 858bf215546Sopenharmony_ci uint64_t *modifiers, 859bf215546Sopenharmony_ci unsigned int *external_only, int *count) 860bf215546Sopenharmony_ci{ 861bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 862bf215546Sopenharmony_ci int i, num = 0; 863bf215546Sopenharmony_ci 864bf215546Sopenharmony_ci max = MIN2(max, screen->num_supported_modifiers); 865bf215546Sopenharmony_ci 866bf215546Sopenharmony_ci if (!max) { 867bf215546Sopenharmony_ci max = screen->num_supported_modifiers; 868bf215546Sopenharmony_ci external_only = NULL; 869bf215546Sopenharmony_ci modifiers = NULL; 870bf215546Sopenharmony_ci } 871bf215546Sopenharmony_ci 872bf215546Sopenharmony_ci for (i = 0; i < max; i++) { 873bf215546Sopenharmony_ci if (modifiers) 874bf215546Sopenharmony_ci modifiers[num] = screen->supported_modifiers[i]; 875bf215546Sopenharmony_ci 876bf215546Sopenharmony_ci if (external_only) 877bf215546Sopenharmony_ci external_only[num] = 0; 878bf215546Sopenharmony_ci 879bf215546Sopenharmony_ci num++; 880bf215546Sopenharmony_ci } 881bf215546Sopenharmony_ci 882bf215546Sopenharmony_ci *count = num; 883bf215546Sopenharmony_ci} 884bf215546Sopenharmony_ci 885bf215546Sopenharmony_cistatic bool 886bf215546Sopenharmony_cifd_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, 887bf215546Sopenharmony_ci uint64_t modifier, 888bf215546Sopenharmony_ci enum pipe_format format, 889bf215546Sopenharmony_ci bool *external_only) 890bf215546Sopenharmony_ci{ 891bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 892bf215546Sopenharmony_ci int i; 893bf215546Sopenharmony_ci 894bf215546Sopenharmony_ci for (i = 0; i < screen->num_supported_modifiers; i++) { 895bf215546Sopenharmony_ci if (modifier == screen->supported_modifiers[i]) { 896bf215546Sopenharmony_ci if (external_only) 897bf215546Sopenharmony_ci *external_only = false; 898bf215546Sopenharmony_ci 899bf215546Sopenharmony_ci return true; 900bf215546Sopenharmony_ci } 901bf215546Sopenharmony_ci } 902bf215546Sopenharmony_ci 903bf215546Sopenharmony_ci return false; 904bf215546Sopenharmony_ci} 905bf215546Sopenharmony_ci 906bf215546Sopenharmony_cistruct fd_bo * 907bf215546Sopenharmony_cifd_screen_bo_from_handle(struct pipe_screen *pscreen, 908bf215546Sopenharmony_ci struct winsys_handle *whandle) 909bf215546Sopenharmony_ci{ 910bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 911bf215546Sopenharmony_ci struct fd_bo *bo; 912bf215546Sopenharmony_ci 913bf215546Sopenharmony_ci if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) { 914bf215546Sopenharmony_ci bo = fd_bo_from_name(screen->dev, whandle->handle); 915bf215546Sopenharmony_ci } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) { 916bf215546Sopenharmony_ci bo = fd_bo_from_handle(screen->dev, whandle->handle, 0); 917bf215546Sopenharmony_ci } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) { 918bf215546Sopenharmony_ci bo = fd_bo_from_dmabuf(screen->dev, whandle->handle); 919bf215546Sopenharmony_ci } else { 920bf215546Sopenharmony_ci DBG("Attempt to import unsupported handle type %d", whandle->type); 921bf215546Sopenharmony_ci return NULL; 922bf215546Sopenharmony_ci } 923bf215546Sopenharmony_ci 924bf215546Sopenharmony_ci if (!bo) { 925bf215546Sopenharmony_ci DBG("ref name 0x%08x failed", whandle->handle); 926bf215546Sopenharmony_ci return NULL; 927bf215546Sopenharmony_ci } 928bf215546Sopenharmony_ci 929bf215546Sopenharmony_ci return bo; 930bf215546Sopenharmony_ci} 931bf215546Sopenharmony_ci 932bf215546Sopenharmony_cistatic void 933bf215546Sopenharmony_ci_fd_fence_ref(struct pipe_screen *pscreen, struct pipe_fence_handle **ptr, 934bf215546Sopenharmony_ci struct pipe_fence_handle *pfence) 935bf215546Sopenharmony_ci{ 936bf215546Sopenharmony_ci fd_fence_ref(ptr, pfence); 937bf215546Sopenharmony_ci} 938bf215546Sopenharmony_ci 939bf215546Sopenharmony_cistatic void 940bf215546Sopenharmony_cifd_screen_get_device_uuid(struct pipe_screen *pscreen, char *uuid) 941bf215546Sopenharmony_ci{ 942bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 943bf215546Sopenharmony_ci 944bf215546Sopenharmony_ci fd_get_device_uuid(uuid, screen->dev_id); 945bf215546Sopenharmony_ci} 946bf215546Sopenharmony_ci 947bf215546Sopenharmony_cistatic void 948bf215546Sopenharmony_cifd_screen_get_driver_uuid(struct pipe_screen *pscreen, char *uuid) 949bf215546Sopenharmony_ci{ 950bf215546Sopenharmony_ci fd_get_driver_uuid(uuid); 951bf215546Sopenharmony_ci} 952bf215546Sopenharmony_ci 953bf215546Sopenharmony_cistruct pipe_screen * 954bf215546Sopenharmony_cifd_screen_create(struct fd_device *dev, struct renderonly *ro, 955bf215546Sopenharmony_ci const struct pipe_screen_config *config) 956bf215546Sopenharmony_ci{ 957bf215546Sopenharmony_ci struct fd_screen *screen = CALLOC_STRUCT(fd_screen); 958bf215546Sopenharmony_ci struct pipe_screen *pscreen; 959bf215546Sopenharmony_ci uint64_t val; 960bf215546Sopenharmony_ci 961bf215546Sopenharmony_ci fd_mesa_debug = debug_get_option_fd_mesa_debug(); 962bf215546Sopenharmony_ci 963bf215546Sopenharmony_ci if (FD_DBG(NOBIN)) 964bf215546Sopenharmony_ci fd_binning_enabled = false; 965bf215546Sopenharmony_ci 966bf215546Sopenharmony_ci if (!screen) 967bf215546Sopenharmony_ci return NULL; 968bf215546Sopenharmony_ci 969bf215546Sopenharmony_ci#ifdef HAVE_PERFETTO 970bf215546Sopenharmony_ci fd_perfetto_init(); 971bf215546Sopenharmony_ci#endif 972bf215546Sopenharmony_ci 973bf215546Sopenharmony_ci pscreen = &screen->base; 974bf215546Sopenharmony_ci 975bf215546Sopenharmony_ci screen->dev = dev; 976bf215546Sopenharmony_ci screen->ro = ro; 977bf215546Sopenharmony_ci screen->refcnt = 1; 978bf215546Sopenharmony_ci 979bf215546Sopenharmony_ci // maybe this should be in context? 980bf215546Sopenharmony_ci screen->pipe = fd_pipe_new(screen->dev, FD_PIPE_3D); 981bf215546Sopenharmony_ci if (!screen->pipe) { 982bf215546Sopenharmony_ci DBG("could not create 3d pipe"); 983bf215546Sopenharmony_ci goto fail; 984bf215546Sopenharmony_ci } 985bf215546Sopenharmony_ci 986bf215546Sopenharmony_ci if (fd_pipe_get_param(screen->pipe, FD_GMEM_SIZE, &val)) { 987bf215546Sopenharmony_ci DBG("could not get GMEM size"); 988bf215546Sopenharmony_ci goto fail; 989bf215546Sopenharmony_ci } 990bf215546Sopenharmony_ci screen->gmemsize_bytes = env_var_as_unsigned("FD_MESA_GMEM", val); 991bf215546Sopenharmony_ci 992bf215546Sopenharmony_ci if (fd_device_version(dev) >= FD_VERSION_GMEM_BASE) { 993bf215546Sopenharmony_ci fd_pipe_get_param(screen->pipe, FD_GMEM_BASE, &screen->gmem_base); 994bf215546Sopenharmony_ci } 995bf215546Sopenharmony_ci 996bf215546Sopenharmony_ci if (fd_pipe_get_param(screen->pipe, FD_MAX_FREQ, &val)) { 997bf215546Sopenharmony_ci DBG("could not get gpu freq"); 998bf215546Sopenharmony_ci /* this limits what performance related queries are 999bf215546Sopenharmony_ci * supported but is not fatal 1000bf215546Sopenharmony_ci */ 1001bf215546Sopenharmony_ci screen->max_freq = 0; 1002bf215546Sopenharmony_ci } else { 1003bf215546Sopenharmony_ci screen->max_freq = val; 1004bf215546Sopenharmony_ci if (fd_pipe_get_param(screen->pipe, FD_TIMESTAMP, &val) == 0) 1005bf215546Sopenharmony_ci screen->has_timestamp = true; 1006bf215546Sopenharmony_ci } 1007bf215546Sopenharmony_ci 1008bf215546Sopenharmony_ci screen->dev_id = fd_pipe_dev_id(screen->pipe); 1009bf215546Sopenharmony_ci 1010bf215546Sopenharmony_ci if (fd_pipe_get_param(screen->pipe, FD_GPU_ID, &val)) { 1011bf215546Sopenharmony_ci DBG("could not get gpu-id"); 1012bf215546Sopenharmony_ci goto fail; 1013bf215546Sopenharmony_ci } 1014bf215546Sopenharmony_ci screen->gpu_id = val; 1015bf215546Sopenharmony_ci 1016bf215546Sopenharmony_ci if (fd_pipe_get_param(screen->pipe, FD_CHIP_ID, &val)) { 1017bf215546Sopenharmony_ci DBG("could not get chip-id"); 1018bf215546Sopenharmony_ci /* older kernels may not have this property: */ 1019bf215546Sopenharmony_ci unsigned core = screen->gpu_id / 100; 1020bf215546Sopenharmony_ci unsigned major = (screen->gpu_id % 100) / 10; 1021bf215546Sopenharmony_ci unsigned minor = screen->gpu_id % 10; 1022bf215546Sopenharmony_ci unsigned patch = 0; /* assume the worst */ 1023bf215546Sopenharmony_ci val = (patch & 0xff) | ((minor & 0xff) << 8) | ((major & 0xff) << 16) | 1024bf215546Sopenharmony_ci ((core & 0xff) << 24); 1025bf215546Sopenharmony_ci } 1026bf215546Sopenharmony_ci screen->chip_id = val; 1027bf215546Sopenharmony_ci screen->gen = fd_dev_gen(screen->dev_id); 1028bf215546Sopenharmony_ci 1029bf215546Sopenharmony_ci if (fd_pipe_get_param(screen->pipe, FD_NR_RINGS, &val)) { 1030bf215546Sopenharmony_ci DBG("could not get # of rings"); 1031bf215546Sopenharmony_ci screen->priority_mask = 0; 1032bf215546Sopenharmony_ci } else { 1033bf215546Sopenharmony_ci /* # of rings equates to number of unique priority values: */ 1034bf215546Sopenharmony_ci screen->priority_mask = (1 << val) - 1; 1035bf215546Sopenharmony_ci } 1036bf215546Sopenharmony_ci 1037bf215546Sopenharmony_ci if (fd_device_version(dev) >= FD_VERSION_ROBUSTNESS) 1038bf215546Sopenharmony_ci screen->has_robustness = true; 1039bf215546Sopenharmony_ci 1040bf215546Sopenharmony_ci screen->has_syncobj = fd_has_syncobj(screen->dev); 1041bf215546Sopenharmony_ci 1042bf215546Sopenharmony_ci /* parse driconf configuration now for device specific overrides: */ 1043bf215546Sopenharmony_ci driParseConfigFiles(config->options, config->options_info, 0, "msm", 1044bf215546Sopenharmony_ci NULL, fd_dev_name(screen->dev_id), NULL, 0, NULL, 0); 1045bf215546Sopenharmony_ci 1046bf215546Sopenharmony_ci struct sysinfo si; 1047bf215546Sopenharmony_ci sysinfo(&si); 1048bf215546Sopenharmony_ci screen->ram_size = si.totalram; 1049bf215546Sopenharmony_ci 1050bf215546Sopenharmony_ci DBG("Pipe Info:"); 1051bf215546Sopenharmony_ci DBG(" GPU-id: %s", fd_dev_name(screen->dev_id)); 1052bf215546Sopenharmony_ci DBG(" Chip-id: 0x%016"PRIx64, screen->chip_id); 1053bf215546Sopenharmony_ci DBG(" GMEM size: 0x%08x", screen->gmemsize_bytes); 1054bf215546Sopenharmony_ci 1055bf215546Sopenharmony_ci const struct fd_dev_info *info = fd_dev_info(screen->dev_id); 1056bf215546Sopenharmony_ci if (!info) { 1057bf215546Sopenharmony_ci mesa_loge("unsupported GPU: a%03d", screen->gpu_id); 1058bf215546Sopenharmony_ci goto fail; 1059bf215546Sopenharmony_ci } 1060bf215546Sopenharmony_ci 1061bf215546Sopenharmony_ci screen->info = info; 1062bf215546Sopenharmony_ci 1063bf215546Sopenharmony_ci /* explicitly checking for GPU revisions that are known to work. This 1064bf215546Sopenharmony_ci * may be overly conservative for a3xx, where spoofing the gpu_id with 1065bf215546Sopenharmony_ci * the blob driver seems to generate identical cmdstream dumps. But 1066bf215546Sopenharmony_ci * on a2xx, there seem to be small differences between the GPU revs 1067bf215546Sopenharmony_ci * so it is probably better to actually test first on real hardware 1068bf215546Sopenharmony_ci * before enabling: 1069bf215546Sopenharmony_ci * 1070bf215546Sopenharmony_ci * If you have a different adreno version, feel free to add it to one 1071bf215546Sopenharmony_ci * of the cases below and see what happens. And if it works, please 1072bf215546Sopenharmony_ci * send a patch ;-) 1073bf215546Sopenharmony_ci */ 1074bf215546Sopenharmony_ci switch (screen->gen) { 1075bf215546Sopenharmony_ci case 2: 1076bf215546Sopenharmony_ci fd2_screen_init(pscreen); 1077bf215546Sopenharmony_ci break; 1078bf215546Sopenharmony_ci case 3: 1079bf215546Sopenharmony_ci fd3_screen_init(pscreen); 1080bf215546Sopenharmony_ci break; 1081bf215546Sopenharmony_ci case 4: 1082bf215546Sopenharmony_ci fd4_screen_init(pscreen); 1083bf215546Sopenharmony_ci break; 1084bf215546Sopenharmony_ci case 5: 1085bf215546Sopenharmony_ci fd5_screen_init(pscreen); 1086bf215546Sopenharmony_ci break; 1087bf215546Sopenharmony_ci case 6: 1088bf215546Sopenharmony_ci fd6_screen_init(pscreen); 1089bf215546Sopenharmony_ci break; 1090bf215546Sopenharmony_ci default: 1091bf215546Sopenharmony_ci mesa_loge("unsupported GPU generation: a%uxx", screen->gen); 1092bf215546Sopenharmony_ci goto fail; 1093bf215546Sopenharmony_ci } 1094bf215546Sopenharmony_ci 1095bf215546Sopenharmony_ci /* fdN_screen_init() should set this: */ 1096bf215546Sopenharmony_ci assert(screen->primtypes); 1097bf215546Sopenharmony_ci screen->primtypes_mask = 0; 1098bf215546Sopenharmony_ci for (unsigned i = 0; i <= PIPE_PRIM_MAX; i++) 1099bf215546Sopenharmony_ci if (screen->primtypes[i]) 1100bf215546Sopenharmony_ci screen->primtypes_mask |= (1 << i); 1101bf215546Sopenharmony_ci 1102bf215546Sopenharmony_ci if (FD_DBG(PERFC)) { 1103bf215546Sopenharmony_ci screen->perfcntr_groups = 1104bf215546Sopenharmony_ci fd_perfcntrs(screen->dev_id, &screen->num_perfcntr_groups); 1105bf215546Sopenharmony_ci } 1106bf215546Sopenharmony_ci 1107bf215546Sopenharmony_ci /* NOTE: don't enable if we have too old of a kernel to support 1108bf215546Sopenharmony_ci * growable cmdstream buffers, since memory requirement for cmdstream 1109bf215546Sopenharmony_ci * buffers would be too much otherwise. 1110bf215546Sopenharmony_ci */ 1111bf215546Sopenharmony_ci if (fd_device_version(dev) >= FD_VERSION_UNLIMITED_CMDS) 1112bf215546Sopenharmony_ci screen->reorder = !FD_DBG(INORDER); 1113bf215546Sopenharmony_ci 1114bf215546Sopenharmony_ci fd_bc_init(&screen->batch_cache); 1115bf215546Sopenharmony_ci 1116bf215546Sopenharmony_ci list_inithead(&screen->context_list); 1117bf215546Sopenharmony_ci 1118bf215546Sopenharmony_ci util_idalloc_mt_init_tc(&screen->buffer_ids); 1119bf215546Sopenharmony_ci 1120bf215546Sopenharmony_ci (void)simple_mtx_init(&screen->lock, mtx_plain); 1121bf215546Sopenharmony_ci 1122bf215546Sopenharmony_ci pscreen->destroy = fd_screen_destroy; 1123bf215546Sopenharmony_ci pscreen->get_param = fd_screen_get_param; 1124bf215546Sopenharmony_ci pscreen->get_paramf = fd_screen_get_paramf; 1125bf215546Sopenharmony_ci pscreen->get_shader_param = fd_screen_get_shader_param; 1126bf215546Sopenharmony_ci pscreen->get_compute_param = fd_get_compute_param; 1127bf215546Sopenharmony_ci pscreen->get_compiler_options = fd_get_compiler_options; 1128bf215546Sopenharmony_ci pscreen->get_disk_shader_cache = fd_get_disk_shader_cache; 1129bf215546Sopenharmony_ci 1130bf215546Sopenharmony_ci fd_resource_screen_init(pscreen); 1131bf215546Sopenharmony_ci fd_query_screen_init(pscreen); 1132bf215546Sopenharmony_ci fd_gmem_screen_init(pscreen); 1133bf215546Sopenharmony_ci 1134bf215546Sopenharmony_ci pscreen->get_name = fd_screen_get_name; 1135bf215546Sopenharmony_ci pscreen->get_vendor = fd_screen_get_vendor; 1136bf215546Sopenharmony_ci pscreen->get_device_vendor = fd_screen_get_device_vendor; 1137bf215546Sopenharmony_ci 1138bf215546Sopenharmony_ci pscreen->get_timestamp = fd_screen_get_timestamp; 1139bf215546Sopenharmony_ci 1140bf215546Sopenharmony_ci pscreen->fence_reference = _fd_fence_ref; 1141bf215546Sopenharmony_ci pscreen->fence_finish = fd_fence_finish; 1142bf215546Sopenharmony_ci pscreen->fence_get_fd = fd_fence_get_fd; 1143bf215546Sopenharmony_ci 1144bf215546Sopenharmony_ci pscreen->query_dmabuf_modifiers = fd_screen_query_dmabuf_modifiers; 1145bf215546Sopenharmony_ci pscreen->is_dmabuf_modifier_supported = 1146bf215546Sopenharmony_ci fd_screen_is_dmabuf_modifier_supported; 1147bf215546Sopenharmony_ci 1148bf215546Sopenharmony_ci pscreen->get_device_uuid = fd_screen_get_device_uuid; 1149bf215546Sopenharmony_ci pscreen->get_driver_uuid = fd_screen_get_driver_uuid; 1150bf215546Sopenharmony_ci 1151bf215546Sopenharmony_ci slab_create_parent(&screen->transfer_pool, sizeof(struct fd_transfer), 16); 1152bf215546Sopenharmony_ci 1153bf215546Sopenharmony_ci return pscreen; 1154bf215546Sopenharmony_ci 1155bf215546Sopenharmony_cifail: 1156bf215546Sopenharmony_ci fd_screen_destroy(pscreen); 1157bf215546Sopenharmony_ci return NULL; 1158bf215546Sopenharmony_ci} 1159