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