1848b8605Smrg/* 2848b8605Smrg * Copyright © 2014 Broadcom 3848b8605Smrg * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> 4848b8605Smrg * 5848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 6848b8605Smrg * copy of this software and associated documentation files (the "Software"), 7848b8605Smrg * to deal in the Software without restriction, including without limitation 8848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 10848b8605Smrg * Software is furnished to do so, subject to the following conditions: 11848b8605Smrg * 12848b8605Smrg * The above copyright notice and this permission notice (including the next 13848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the 14848b8605Smrg * Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22848b8605Smrg * IN THE SOFTWARE. 23848b8605Smrg */ 24848b8605Smrg 25b8e80941Smrg#include "util/os_misc.h" 26848b8605Smrg#include "pipe/p_defines.h" 27848b8605Smrg#include "pipe/p_screen.h" 28848b8605Smrg#include "pipe/p_state.h" 29848b8605Smrg 30b8e80941Smrg#include "util/u_cpu_detect.h" 31848b8605Smrg#include "util/u_debug.h" 32848b8605Smrg#include "util/u_memory.h" 33848b8605Smrg#include "util/u_format.h" 34b8e80941Smrg#include "util/u_hash_table.h" 35b8e80941Smrg#include "util/u_screen.h" 36b8e80941Smrg#include "util/u_transfer_helper.h" 37b8e80941Smrg#include "util/ralloc.h" 38b8e80941Smrg 39b8e80941Smrg#include <xf86drm.h> 40b8e80941Smrg#include "drm-uapi/drm_fourcc.h" 41b8e80941Smrg#include "drm-uapi/vc4_drm.h" 42848b8605Smrg#include "vc4_screen.h" 43848b8605Smrg#include "vc4_context.h" 44848b8605Smrg#include "vc4_resource.h" 45848b8605Smrg 46848b8605Smrgstatic const struct debug_named_value debug_options[] = { 47848b8605Smrg { "cl", VC4_DEBUG_CL, 48848b8605Smrg "Dump command list during creation" }, 49b8e80941Smrg { "surf", VC4_DEBUG_SURFACE, 50b8e80941Smrg "Dump surface layouts" }, 51848b8605Smrg { "qpu", VC4_DEBUG_QPU, 52848b8605Smrg "Dump generated QPU instructions" }, 53848b8605Smrg { "qir", VC4_DEBUG_QIR, 54848b8605Smrg "Dump QPU IR during program compile" }, 55b8e80941Smrg { "nir", VC4_DEBUG_NIR, 56b8e80941Smrg "Dump NIR during program compile" }, 57848b8605Smrg { "tgsi", VC4_DEBUG_TGSI, 58848b8605Smrg "Dump TGSI during program compile" }, 59848b8605Smrg { "shaderdb", VC4_DEBUG_SHADERDB, 60848b8605Smrg "Dump program compile information for shader-db analysis" }, 61848b8605Smrg { "perf", VC4_DEBUG_PERF, 62848b8605Smrg "Print during performance-related events" }, 63848b8605Smrg { "norast", VC4_DEBUG_NORAST, 64848b8605Smrg "Skip actual hardware execution of commands" }, 65b8e80941Smrg { "always_flush", VC4_DEBUG_ALWAYS_FLUSH, 66b8e80941Smrg "Flush after each draw call" }, 67b8e80941Smrg { "always_sync", VC4_DEBUG_ALWAYS_SYNC, 68b8e80941Smrg "Wait for finish after each flush" }, 69b8e80941Smrg#ifdef USE_VC4_SIMULATOR 70b8e80941Smrg { "dump", VC4_DEBUG_DUMP, 71b8e80941Smrg "Write a GPU command stream trace file" }, 72b8e80941Smrg#endif 73b8e80941Smrg { NULL } 74848b8605Smrg}; 75848b8605Smrg 76848b8605SmrgDEBUG_GET_ONCE_FLAGS_OPTION(vc4_debug, "VC4_DEBUG", debug_options, 0) 77848b8605Smrguint32_t vc4_debug; 78848b8605Smrg 79848b8605Smrgstatic const char * 80848b8605Smrgvc4_screen_get_name(struct pipe_screen *pscreen) 81848b8605Smrg{ 82b8e80941Smrg struct vc4_screen *screen = vc4_screen(pscreen); 83b8e80941Smrg 84b8e80941Smrg if (!screen->name) { 85b8e80941Smrg screen->name = ralloc_asprintf(screen, 86b8e80941Smrg "VC4 V3D %d.%d", 87b8e80941Smrg screen->v3d_ver / 10, 88b8e80941Smrg screen->v3d_ver % 10); 89b8e80941Smrg } 90b8e80941Smrg 91b8e80941Smrg return screen->name; 92848b8605Smrg} 93848b8605Smrg 94848b8605Smrgstatic const char * 95848b8605Smrgvc4_screen_get_vendor(struct pipe_screen *pscreen) 96848b8605Smrg{ 97848b8605Smrg return "Broadcom"; 98848b8605Smrg} 99848b8605Smrg 100848b8605Smrgstatic void 101848b8605Smrgvc4_screen_destroy(struct pipe_screen *pscreen) 102848b8605Smrg{ 103b8e80941Smrg struct vc4_screen *screen = vc4_screen(pscreen); 104b8e80941Smrg 105b8e80941Smrg util_hash_table_destroy(screen->bo_handles); 106b8e80941Smrg vc4_bufmgr_destroy(pscreen); 107b8e80941Smrg slab_destroy_parent(&screen->transfer_pool); 108b8e80941Smrg free(screen->ro); 109b8e80941Smrg 110b8e80941Smrg#ifdef USE_VC4_SIMULATOR 111b8e80941Smrg vc4_simulator_destroy(screen); 112b8e80941Smrg#endif 113b8e80941Smrg 114b8e80941Smrg u_transfer_helper_destroy(pscreen->transfer_helper); 115b8e80941Smrg 116b8e80941Smrg close(screen->fd); 117b8e80941Smrg ralloc_free(pscreen); 118b8e80941Smrg} 119b8e80941Smrg 120b8e80941Smrgstatic bool 121b8e80941Smrgvc4_has_feature(struct vc4_screen *screen, uint32_t feature) 122b8e80941Smrg{ 123b8e80941Smrg struct drm_vc4_get_param p = { 124b8e80941Smrg .param = feature, 125b8e80941Smrg }; 126b8e80941Smrg int ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &p); 127b8e80941Smrg 128b8e80941Smrg if (ret != 0) 129b8e80941Smrg return false; 130b8e80941Smrg 131b8e80941Smrg return p.value; 132848b8605Smrg} 133848b8605Smrg 134848b8605Smrgstatic int 135848b8605Smrgvc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 136848b8605Smrg{ 137b8e80941Smrg struct vc4_screen *screen = vc4_screen(pscreen); 138b8e80941Smrg 139848b8605Smrg switch (param) { 140848b8605Smrg /* Supported features (boolean caps). */ 141b8e80941Smrg case PIPE_CAP_VERTEX_COLOR_CLAMPED: 142848b8605Smrg case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 143b8e80941Smrg case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: 144848b8605Smrg case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: 145848b8605Smrg case PIPE_CAP_NPOT_TEXTURES: 146b8e80941Smrg case PIPE_CAP_SHAREABLE_SHADERS: 147848b8605Smrg case PIPE_CAP_BLEND_EQUATION_SEPARATE: 148b8e80941Smrg case PIPE_CAP_TEXTURE_MULTISAMPLE: 149b8e80941Smrg case PIPE_CAP_TEXTURE_SWIZZLE: 150b8e80941Smrg case PIPE_CAP_TEXTURE_BARRIER: 151848b8605Smrg return 1; 152848b8605Smrg 153b8e80941Smrg case PIPE_CAP_NATIVE_FENCE_FD: 154b8e80941Smrg return screen->has_syncobj; 155b8e80941Smrg 156b8e80941Smrg case PIPE_CAP_TILE_RASTER_ORDER: 157b8e80941Smrg return vc4_has_feature(screen, 158b8e80941Smrg DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER); 159b8e80941Smrg 160848b8605Smrg /* lying for GL 2.0 */ 161848b8605Smrg case PIPE_CAP_OCCLUSION_QUERY: 162848b8605Smrg case PIPE_CAP_POINT_SPRITE: 163848b8605Smrg return 1; 164848b8605Smrg 165848b8605Smrg case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 166848b8605Smrg case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 167848b8605Smrg return 1; 168848b8605Smrg 169848b8605Smrg case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: 170b8e80941Smrg case PIPE_CAP_MIXED_COLOR_DEPTH_BITS: 171b8e80941Smrg return 1; 172848b8605Smrg 173848b8605Smrg /* Texturing. */ 174848b8605Smrg case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 175848b8605Smrg case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 176848b8605Smrg return VC4_MAX_MIP_LEVELS; 177848b8605Smrg case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 178848b8605Smrg /* Note: Not supported in hardware, just faking it. */ 179848b8605Smrg return 5; 180848b8605Smrg 181b8e80941Smrg case PIPE_CAP_MAX_VARYINGS: 182b8e80941Smrg return 8; 183848b8605Smrg 184848b8605Smrg case PIPE_CAP_VENDOR_ID: 185848b8605Smrg return 0x14E4; 186848b8605Smrg case PIPE_CAP_ACCELERATED: 187848b8605Smrg return 1; 188848b8605Smrg case PIPE_CAP_VIDEO_MEMORY: { 189848b8605Smrg uint64_t system_memory; 190848b8605Smrg 191848b8605Smrg if (!os_get_total_physical_memory(&system_memory)) 192848b8605Smrg return 0; 193848b8605Smrg 194848b8605Smrg return (int)(system_memory >> 20); 195848b8605Smrg } 196848b8605Smrg case PIPE_CAP_UMA: 197848b8605Smrg return 1; 198848b8605Smrg 199848b8605Smrg default: 200b8e80941Smrg return u_pipe_screen_get_param_defaults(pscreen, param); 201848b8605Smrg } 202848b8605Smrg} 203848b8605Smrg 204848b8605Smrgstatic float 205848b8605Smrgvc4_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) 206848b8605Smrg{ 207848b8605Smrg switch (param) { 208848b8605Smrg case PIPE_CAPF_MAX_LINE_WIDTH: 209848b8605Smrg case PIPE_CAPF_MAX_LINE_WIDTH_AA: 210b8e80941Smrg return 32; 211b8e80941Smrg 212848b8605Smrg case PIPE_CAPF_MAX_POINT_WIDTH: 213848b8605Smrg case PIPE_CAPF_MAX_POINT_WIDTH_AA: 214b8e80941Smrg return 512.0f; 215b8e80941Smrg 216848b8605Smrg case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 217848b8605Smrg return 0.0f; 218848b8605Smrg case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 219848b8605Smrg return 0.0f; 220b8e80941Smrg 221b8e80941Smrg case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE: 222b8e80941Smrg case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE: 223b8e80941Smrg case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY: 224848b8605Smrg return 0.0f; 225848b8605Smrg default: 226848b8605Smrg fprintf(stderr, "unknown paramf %d\n", param); 227848b8605Smrg return 0; 228848b8605Smrg } 229848b8605Smrg} 230848b8605Smrg 231848b8605Smrgstatic int 232b8e80941Smrgvc4_screen_get_shader_param(struct pipe_screen *pscreen, 233b8e80941Smrg enum pipe_shader_type shader, 234b8e80941Smrg enum pipe_shader_cap param) 235848b8605Smrg{ 236848b8605Smrg if (shader != PIPE_SHADER_VERTEX && 237848b8605Smrg shader != PIPE_SHADER_FRAGMENT) { 238848b8605Smrg return 0; 239848b8605Smrg } 240848b8605Smrg 241848b8605Smrg /* this is probably not totally correct.. but it's a start: */ 242848b8605Smrg switch (param) { 243848b8605Smrg case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 244848b8605Smrg case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 245848b8605Smrg case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 246848b8605Smrg case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 247848b8605Smrg return 16384; 248b8e80941Smrg 249848b8605Smrg case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 250b8e80941Smrg return vc4_screen(pscreen)->has_control_flow; 251b8e80941Smrg 252848b8605Smrg case PIPE_SHADER_CAP_MAX_INPUTS: 253b8e80941Smrg return 8; 254b8e80941Smrg case PIPE_SHADER_CAP_MAX_OUTPUTS: 255b8e80941Smrg return shader == PIPE_SHADER_FRAGMENT ? 1 : 8; 256848b8605Smrg case PIPE_SHADER_CAP_MAX_TEMPS: 257b8e80941Smrg return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */ 258848b8605Smrg case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE: 259b8e80941Smrg return 16 * 1024 * sizeof(float); 260848b8605Smrg case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 261848b8605Smrg return 1; 262848b8605Smrg case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 263848b8605Smrg return 0; 264848b8605Smrg case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 265848b8605Smrg case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 266848b8605Smrg case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 267848b8605Smrg return 0; 268b8e80941Smrg case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 269b8e80941Smrg return 1; 270848b8605Smrg case PIPE_SHADER_CAP_SUBROUTINES: 271848b8605Smrg return 0; 272848b8605Smrg case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: 273848b8605Smrg return 0; 274848b8605Smrg case PIPE_SHADER_CAP_INTEGERS: 275b8e80941Smrg return 1; 276b8e80941Smrg case PIPE_SHADER_CAP_INT64_ATOMICS: 277b8e80941Smrg case PIPE_SHADER_CAP_FP16: 278b8e80941Smrg case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED: 279b8e80941Smrg case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED: 280b8e80941Smrg case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED: 281b8e80941Smrg case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED: 282b8e80941Smrg case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: 283848b8605Smrg return 0; 284848b8605Smrg case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 285848b8605Smrg case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 286848b8605Smrg return VC4_MAX_TEXTURE_SAMPLERS; 287848b8605Smrg case PIPE_SHADER_CAP_PREFERRED_IR: 288b8e80941Smrg return PIPE_SHADER_IR_NIR; 289b8e80941Smrg case PIPE_SHADER_CAP_SUPPORTED_IRS: 290848b8605Smrg return 0; 291b8e80941Smrg case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT: 292b8e80941Smrg return 32; 293b8e80941Smrg case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: 294b8e80941Smrg case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: 295b8e80941Smrg case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD: 296b8e80941Smrg case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS: 297b8e80941Smrg case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS: 298b8e80941Smrg case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS: 299848b8605Smrg return 0; 300b8e80941Smrg case PIPE_SHADER_CAP_SCALAR_ISA: 301848b8605Smrg return 1; 302848b8605Smrg default: 303b8e80941Smrg fprintf(stderr, "unknown shader param %d\n", param); 304b8e80941Smrg return 0; 305848b8605Smrg } 306b8e80941Smrg return 0; 307848b8605Smrg} 308848b8605Smrg 309848b8605Smrgstatic boolean 310848b8605Smrgvc4_screen_is_format_supported(struct pipe_screen *pscreen, 311848b8605Smrg enum pipe_format format, 312848b8605Smrg enum pipe_texture_target target, 313848b8605Smrg unsigned sample_count, 314b8e80941Smrg unsigned storage_sample_count, 315848b8605Smrg unsigned usage) 316848b8605Smrg{ 317b8e80941Smrg struct vc4_screen *screen = vc4_screen(pscreen); 318b8e80941Smrg 319b8e80941Smrg if (MAX2(1, sample_count) != MAX2(1, storage_sample_count)) 320b8e80941Smrg return false; 321848b8605Smrg 322b8e80941Smrg if (sample_count > 1 && sample_count != VC4_MAX_SAMPLES) 323b8e80941Smrg return FALSE; 324b8e80941Smrg 325b8e80941Smrg if (target >= PIPE_MAX_TEXTURE_TYPES) { 326848b8605Smrg return FALSE; 327848b8605Smrg } 328848b8605Smrg 329b8e80941Smrg if (usage & PIPE_BIND_VERTEX_BUFFER) { 330b8e80941Smrg switch (format) { 331b8e80941Smrg case PIPE_FORMAT_R32G32B32A32_FLOAT: 332b8e80941Smrg case PIPE_FORMAT_R32G32B32_FLOAT: 333b8e80941Smrg case PIPE_FORMAT_R32G32_FLOAT: 334b8e80941Smrg case PIPE_FORMAT_R32_FLOAT: 335b8e80941Smrg case PIPE_FORMAT_R32G32B32A32_SNORM: 336b8e80941Smrg case PIPE_FORMAT_R32G32B32_SNORM: 337b8e80941Smrg case PIPE_FORMAT_R32G32_SNORM: 338b8e80941Smrg case PIPE_FORMAT_R32_SNORM: 339b8e80941Smrg case PIPE_FORMAT_R32G32B32A32_SSCALED: 340b8e80941Smrg case PIPE_FORMAT_R32G32B32_SSCALED: 341b8e80941Smrg case PIPE_FORMAT_R32G32_SSCALED: 342b8e80941Smrg case PIPE_FORMAT_R32_SSCALED: 343b8e80941Smrg case PIPE_FORMAT_R16G16B16A16_UNORM: 344b8e80941Smrg case PIPE_FORMAT_R16G16B16_UNORM: 345b8e80941Smrg case PIPE_FORMAT_R16G16_UNORM: 346b8e80941Smrg case PIPE_FORMAT_R16_UNORM: 347b8e80941Smrg case PIPE_FORMAT_R16G16B16A16_SNORM: 348b8e80941Smrg case PIPE_FORMAT_R16G16B16_SNORM: 349b8e80941Smrg case PIPE_FORMAT_R16G16_SNORM: 350b8e80941Smrg case PIPE_FORMAT_R16_SNORM: 351b8e80941Smrg case PIPE_FORMAT_R16G16B16A16_USCALED: 352b8e80941Smrg case PIPE_FORMAT_R16G16B16_USCALED: 353b8e80941Smrg case PIPE_FORMAT_R16G16_USCALED: 354b8e80941Smrg case PIPE_FORMAT_R16_USCALED: 355b8e80941Smrg case PIPE_FORMAT_R16G16B16A16_SSCALED: 356b8e80941Smrg case PIPE_FORMAT_R16G16B16_SSCALED: 357b8e80941Smrg case PIPE_FORMAT_R16G16_SSCALED: 358b8e80941Smrg case PIPE_FORMAT_R16_SSCALED: 359b8e80941Smrg case PIPE_FORMAT_R8G8B8A8_UNORM: 360b8e80941Smrg case PIPE_FORMAT_R8G8B8_UNORM: 361b8e80941Smrg case PIPE_FORMAT_R8G8_UNORM: 362b8e80941Smrg case PIPE_FORMAT_R8_UNORM: 363b8e80941Smrg case PIPE_FORMAT_R8G8B8A8_SNORM: 364b8e80941Smrg case PIPE_FORMAT_R8G8B8_SNORM: 365b8e80941Smrg case PIPE_FORMAT_R8G8_SNORM: 366b8e80941Smrg case PIPE_FORMAT_R8_SNORM: 367b8e80941Smrg case PIPE_FORMAT_R8G8B8A8_USCALED: 368b8e80941Smrg case PIPE_FORMAT_R8G8B8_USCALED: 369b8e80941Smrg case PIPE_FORMAT_R8G8_USCALED: 370b8e80941Smrg case PIPE_FORMAT_R8_USCALED: 371b8e80941Smrg case PIPE_FORMAT_R8G8B8A8_SSCALED: 372b8e80941Smrg case PIPE_FORMAT_R8G8B8_SSCALED: 373b8e80941Smrg case PIPE_FORMAT_R8G8_SSCALED: 374b8e80941Smrg case PIPE_FORMAT_R8_SSCALED: 375b8e80941Smrg break; 376b8e80941Smrg default: 377b8e80941Smrg return FALSE; 378b8e80941Smrg } 379848b8605Smrg } 380848b8605Smrg 381848b8605Smrg if ((usage & PIPE_BIND_RENDER_TARGET) && 382b8e80941Smrg !vc4_rt_format_supported(format)) { 383b8e80941Smrg return FALSE; 384848b8605Smrg } 385848b8605Smrg 386848b8605Smrg if ((usage & PIPE_BIND_SAMPLER_VIEW) && 387b8e80941Smrg (!vc4_tex_format_supported(format) || 388b8e80941Smrg (format == PIPE_FORMAT_ETC1_RGB8 && !screen->has_etc1))) { 389b8e80941Smrg return FALSE; 390848b8605Smrg } 391848b8605Smrg 392848b8605Smrg if ((usage & PIPE_BIND_DEPTH_STENCIL) && 393b8e80941Smrg format != PIPE_FORMAT_S8_UINT_Z24_UNORM && 394b8e80941Smrg format != PIPE_FORMAT_X8Z24_UNORM) { 395b8e80941Smrg return FALSE; 396848b8605Smrg } 397848b8605Smrg 398848b8605Smrg if ((usage & PIPE_BIND_INDEX_BUFFER) && 399b8e80941Smrg format != PIPE_FORMAT_I8_UINT && 400b8e80941Smrg format != PIPE_FORMAT_I16_UINT) { 401b8e80941Smrg return FALSE; 402848b8605Smrg } 403848b8605Smrg 404b8e80941Smrg return TRUE; 405b8e80941Smrg} 406848b8605Smrg 407b8e80941Smrgstatic void 408b8e80941Smrgvc4_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, 409b8e80941Smrg enum pipe_format format, int max, 410b8e80941Smrg uint64_t *modifiers, 411b8e80941Smrg unsigned int *external_only, 412b8e80941Smrg int *count) 413b8e80941Smrg{ 414b8e80941Smrg int m, i; 415b8e80941Smrg uint64_t available_modifiers[] = { 416b8e80941Smrg DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, 417b8e80941Smrg DRM_FORMAT_MOD_LINEAR, 418b8e80941Smrg }; 419b8e80941Smrg struct vc4_screen *screen = vc4_screen(pscreen); 420b8e80941Smrg int num_modifiers = screen->has_tiling_ioctl ? 2 : 1; 421b8e80941Smrg 422b8e80941Smrg if (!modifiers) { 423b8e80941Smrg *count = num_modifiers; 424b8e80941Smrg return; 425b8e80941Smrg } 426b8e80941Smrg 427b8e80941Smrg *count = MIN2(max, num_modifiers); 428b8e80941Smrg m = screen->has_tiling_ioctl ? 0 : 1; 429b8e80941Smrg /* We support both modifiers (tiled and linear) for all sampler 430b8e80941Smrg * formats, but if we don't have the DRM_VC4_GET_TILING ioctl 431b8e80941Smrg * we shouldn't advertise the tiled formats. 432b8e80941Smrg */ 433b8e80941Smrg for (i = 0; i < *count; i++) { 434b8e80941Smrg modifiers[i] = available_modifiers[m++]; 435b8e80941Smrg if (external_only) 436b8e80941Smrg external_only[i] = false; 437b8e80941Smrg } 438b8e80941Smrg} 439b8e80941Smrg 440b8e80941Smrg#define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x))) 441b8e80941Smrg 442b8e80941Smrgstatic unsigned handle_hash(void *key) 443b8e80941Smrg{ 444b8e80941Smrg return PTR_TO_UINT(key); 445b8e80941Smrg} 446b8e80941Smrg 447b8e80941Smrgstatic int handle_compare(void *key1, void *key2) 448b8e80941Smrg{ 449b8e80941Smrg return PTR_TO_UINT(key1) != PTR_TO_UINT(key2); 450b8e80941Smrg} 451b8e80941Smrg 452b8e80941Smrgstatic bool 453b8e80941Smrgvc4_get_chip_info(struct vc4_screen *screen) 454b8e80941Smrg{ 455b8e80941Smrg struct drm_vc4_get_param ident0 = { 456b8e80941Smrg .param = DRM_VC4_PARAM_V3D_IDENT0, 457b8e80941Smrg }; 458b8e80941Smrg struct drm_vc4_get_param ident1 = { 459b8e80941Smrg .param = DRM_VC4_PARAM_V3D_IDENT1, 460b8e80941Smrg }; 461b8e80941Smrg int ret; 462b8e80941Smrg 463b8e80941Smrg ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident0); 464b8e80941Smrg if (ret != 0) { 465b8e80941Smrg if (errno == EINVAL) { 466b8e80941Smrg /* Backwards compatibility with 2835 kernels which 467b8e80941Smrg * only do V3D 2.1. 468b8e80941Smrg */ 469b8e80941Smrg screen->v3d_ver = 21; 470b8e80941Smrg return true; 471b8e80941Smrg } else { 472b8e80941Smrg fprintf(stderr, "Couldn't get V3D IDENT0: %s\n", 473b8e80941Smrg strerror(errno)); 474b8e80941Smrg return false; 475b8e80941Smrg } 476b8e80941Smrg } 477b8e80941Smrg ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident1); 478b8e80941Smrg if (ret != 0) { 479b8e80941Smrg fprintf(stderr, "Couldn't get V3D IDENT1: %s\n", 480b8e80941Smrg strerror(errno)); 481b8e80941Smrg return false; 482b8e80941Smrg } 483b8e80941Smrg 484b8e80941Smrg uint32_t major = (ident0.value >> 24) & 0xff; 485b8e80941Smrg uint32_t minor = (ident1.value >> 0) & 0xf; 486b8e80941Smrg screen->v3d_ver = major * 10 + minor; 487b8e80941Smrg 488b8e80941Smrg if (screen->v3d_ver != 21 && screen->v3d_ver != 26) { 489b8e80941Smrg fprintf(stderr, 490b8e80941Smrg "V3D %d.%d not supported by this version of Mesa.\n", 491b8e80941Smrg screen->v3d_ver / 10, 492b8e80941Smrg screen->v3d_ver % 10); 493b8e80941Smrg return false; 494b8e80941Smrg } 495b8e80941Smrg 496b8e80941Smrg return true; 497848b8605Smrg} 498848b8605Smrg 499848b8605Smrgstruct pipe_screen * 500b8e80941Smrgvc4_screen_create(int fd, struct renderonly *ro) 501848b8605Smrg{ 502b8e80941Smrg struct vc4_screen *screen = rzalloc(NULL, struct vc4_screen); 503b8e80941Smrg uint64_t syncobj_cap = 0; 504848b8605Smrg struct pipe_screen *pscreen; 505b8e80941Smrg int err; 506848b8605Smrg 507848b8605Smrg pscreen = &screen->base; 508848b8605Smrg 509848b8605Smrg pscreen->destroy = vc4_screen_destroy; 510848b8605Smrg pscreen->get_param = vc4_screen_get_param; 511848b8605Smrg pscreen->get_paramf = vc4_screen_get_paramf; 512848b8605Smrg pscreen->get_shader_param = vc4_screen_get_shader_param; 513848b8605Smrg pscreen->context_create = vc4_context_create; 514848b8605Smrg pscreen->is_format_supported = vc4_screen_is_format_supported; 515848b8605Smrg 516848b8605Smrg screen->fd = fd; 517b8e80941Smrg if (ro) { 518b8e80941Smrg screen->ro = renderonly_dup(ro); 519b8e80941Smrg if (!screen->ro) { 520b8e80941Smrg fprintf(stderr, "Failed to dup renderonly object\n"); 521b8e80941Smrg ralloc_free(screen); 522b8e80941Smrg return NULL; 523b8e80941Smrg } 524b8e80941Smrg } 525b8e80941Smrg 526b8e80941Smrg list_inithead(&screen->bo_cache.time_list); 527b8e80941Smrg (void) mtx_init(&screen->bo_handles_mutex, mtx_plain); 528b8e80941Smrg screen->bo_handles = util_hash_table_create(handle_hash, handle_compare); 529b8e80941Smrg 530b8e80941Smrg screen->has_control_flow = 531b8e80941Smrg vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_BRANCHES); 532b8e80941Smrg screen->has_etc1 = 533b8e80941Smrg vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_ETC1); 534b8e80941Smrg screen->has_threaded_fs = 535b8e80941Smrg vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_THREADED_FS); 536b8e80941Smrg screen->has_madvise = 537b8e80941Smrg vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_MADVISE); 538b8e80941Smrg screen->has_perfmon_ioctl = 539b8e80941Smrg vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_PERFMON); 540b8e80941Smrg 541b8e80941Smrg err = drmGetCap(fd, DRM_CAP_SYNCOBJ, &syncobj_cap); 542b8e80941Smrg if (err == 0 && syncobj_cap) 543b8e80941Smrg screen->has_syncobj = true; 544b8e80941Smrg 545b8e80941Smrg if (!vc4_get_chip_info(screen)) 546b8e80941Smrg goto fail; 547b8e80941Smrg 548b8e80941Smrg util_cpu_detect(); 549b8e80941Smrg 550b8e80941Smrg slab_create_parent(&screen->transfer_pool, sizeof(struct vc4_transfer), 16); 551848b8605Smrg 552b8e80941Smrg vc4_fence_screen_init(screen); 553b8e80941Smrg 554b8e80941Smrg vc4_debug = debug_get_option_vc4_debug(); 555848b8605Smrg if (vc4_debug & VC4_DEBUG_SHADERDB) 556848b8605Smrg vc4_debug |= VC4_DEBUG_NORAST; 557848b8605Smrg 558b8e80941Smrg#ifdef USE_VC4_SIMULATOR 559848b8605Smrg vc4_simulator_init(screen); 560848b8605Smrg#endif 561848b8605Smrg 562848b8605Smrg vc4_resource_screen_init(pscreen); 563848b8605Smrg 564848b8605Smrg pscreen->get_name = vc4_screen_get_name; 565848b8605Smrg pscreen->get_vendor = vc4_screen_get_vendor; 566b8e80941Smrg pscreen->get_device_vendor = vc4_screen_get_vendor; 567b8e80941Smrg pscreen->get_compiler_options = vc4_screen_get_compiler_options; 568b8e80941Smrg pscreen->query_dmabuf_modifiers = vc4_screen_query_dmabuf_modifiers; 569848b8605Smrg 570b8e80941Smrg if (screen->has_perfmon_ioctl) { 571b8e80941Smrg pscreen->get_driver_query_group_info = vc4_get_driver_query_group_info; 572b8e80941Smrg pscreen->get_driver_query_info = vc4_get_driver_query_info; 573848b8605Smrg } 574848b8605Smrg 575b8e80941Smrg return pscreen; 576848b8605Smrg 577b8e80941Smrgfail: 578b8e80941Smrg close(fd); 579b8e80941Smrg ralloc_free(pscreen); 580b8e80941Smrg return NULL; 581848b8605Smrg} 582