Path: blob/21.2-virgl/src/gallium/drivers/vc4/vc4_screen.c
4570 views
/*1* Copyright © 2014 Broadcom2* Copyright (C) 2012 Rob Clark <[email protected]>3*4* Permission is hereby granted, free of charge, to any person obtaining a5* copy of this software and associated documentation files (the "Software"),6* to deal in the Software without restriction, including without limitation7* the rights to use, copy, modify, merge, publish, distribute, sublicense,8* and/or sell copies of the Software, and to permit persons to whom the9* Software is furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice (including the next12* paragraph) shall be included in all copies or substantial portions of the13* Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING20* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS21* IN THE SOFTWARE.22*/2324#include "util/os_misc.h"25#include "pipe/p_defines.h"26#include "pipe/p_screen.h"27#include "pipe/p_state.h"2829#include "util/u_cpu_detect.h"30#include "util/u_debug.h"31#include "util/u_memory.h"32#include "util/format/u_format.h"33#include "util/u_hash_table.h"34#include "util/u_screen.h"35#include "util/u_transfer_helper.h"36#include "util/ralloc.h"3738#include <xf86drm.h>39#include "drm-uapi/drm_fourcc.h"40#include "drm-uapi/vc4_drm.h"41#include "vc4_screen.h"42#include "vc4_context.h"43#include "vc4_resource.h"4445static const struct debug_named_value vc4_debug_options[] = {46{ "cl", VC4_DEBUG_CL,47"Dump command list during creation" },48{ "surf", VC4_DEBUG_SURFACE,49"Dump surface layouts" },50{ "qpu", VC4_DEBUG_QPU,51"Dump generated QPU instructions" },52{ "qir", VC4_DEBUG_QIR,53"Dump QPU IR during program compile" },54{ "nir", VC4_DEBUG_NIR,55"Dump NIR during program compile" },56{ "tgsi", VC4_DEBUG_TGSI,57"Dump TGSI during program compile" },58{ "shaderdb", VC4_DEBUG_SHADERDB,59"Dump program compile information for shader-db analysis" },60{ "perf", VC4_DEBUG_PERF,61"Print during performance-related events" },62{ "norast", VC4_DEBUG_NORAST,63"Skip actual hardware execution of commands" },64{ "always_flush", VC4_DEBUG_ALWAYS_FLUSH,65"Flush after each draw call" },66{ "always_sync", VC4_DEBUG_ALWAYS_SYNC,67"Wait for finish after each flush" },68#ifdef USE_VC4_SIMULATOR69{ "dump", VC4_DEBUG_DUMP,70"Write a GPU command stream trace file" },71#endif72{ NULL }73};7475DEBUG_GET_ONCE_FLAGS_OPTION(vc4_debug, "VC4_DEBUG", vc4_debug_options, 0)76uint32_t vc4_debug;7778static const char *79vc4_screen_get_name(struct pipe_screen *pscreen)80{81struct vc4_screen *screen = vc4_screen(pscreen);8283if (!screen->name) {84screen->name = ralloc_asprintf(screen,85"VC4 V3D %d.%d",86screen->v3d_ver / 10,87screen->v3d_ver % 10);88}8990return screen->name;91}9293static const char *94vc4_screen_get_vendor(struct pipe_screen *pscreen)95{96return "Broadcom";97}9899static void100vc4_screen_destroy(struct pipe_screen *pscreen)101{102struct vc4_screen *screen = vc4_screen(pscreen);103104_mesa_hash_table_destroy(screen->bo_handles, NULL);105vc4_bufmgr_destroy(pscreen);106slab_destroy_parent(&screen->transfer_pool);107if (screen->ro)108screen->ro->destroy(screen->ro);109110#ifdef USE_VC4_SIMULATOR111vc4_simulator_destroy(screen);112#endif113114u_transfer_helper_destroy(pscreen->transfer_helper);115116close(screen->fd);117ralloc_free(pscreen);118}119120static bool121vc4_has_feature(struct vc4_screen *screen, uint32_t feature)122{123struct drm_vc4_get_param p = {124.param = feature,125};126int ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &p);127128if (ret != 0)129return false;130131return p.value;132}133134static int135vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)136{137struct vc4_screen *screen = vc4_screen(pscreen);138139switch (param) {140/* Supported features (boolean caps). */141case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:142case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:143case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:144case PIPE_CAP_NPOT_TEXTURES:145case PIPE_CAP_BLEND_EQUATION_SEPARATE:146case PIPE_CAP_TEXTURE_MULTISAMPLE:147case PIPE_CAP_TEXTURE_SWIZZLE:148case PIPE_CAP_TEXTURE_BARRIER:149case PIPE_CAP_TGSI_TEXCOORD:150return 1;151152case PIPE_CAP_NATIVE_FENCE_FD:153return screen->has_syncobj;154155case PIPE_CAP_TILE_RASTER_ORDER:156return vc4_has_feature(screen,157DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER);158159/* lying for GL 2.0 */160case PIPE_CAP_OCCLUSION_QUERY:161case PIPE_CAP_POINT_SPRITE:162return 1;163164case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:165case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:166case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:167return 1;168169case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:170case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:171return 1;172173/* Texturing. */174case PIPE_CAP_MAX_TEXTURE_2D_SIZE:175return 2048;176case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:177return VC4_MAX_MIP_LEVELS;178case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:179/* Note: Not supported in hardware, just faking it. */180return 5;181182case PIPE_CAP_MAX_VARYINGS:183return 8;184185case PIPE_CAP_VENDOR_ID:186return 0x14E4;187case PIPE_CAP_ACCELERATED:188return 1;189case PIPE_CAP_VIDEO_MEMORY: {190uint64_t system_memory;191192if (!os_get_total_physical_memory(&system_memory))193return 0;194195return (int)(system_memory >> 20);196}197case PIPE_CAP_UMA:198return 1;199200case PIPE_CAP_ALPHA_TEST:201case PIPE_CAP_VERTEX_COLOR_CLAMPED:202case PIPE_CAP_TWO_SIDED_COLOR:203case PIPE_CAP_TEXRECT:204return 0;205206default:207return u_pipe_screen_get_param_defaults(pscreen, param);208}209}210211static float212vc4_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)213{214switch (param) {215case PIPE_CAPF_MAX_LINE_WIDTH:216case PIPE_CAPF_MAX_LINE_WIDTH_AA:217return 32;218219case PIPE_CAPF_MAX_POINT_WIDTH:220case PIPE_CAPF_MAX_POINT_WIDTH_AA:221return 512.0f;222223case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:224return 0.0f;225case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:226return 0.0f;227228case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:229case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:230case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:231return 0.0f;232default:233fprintf(stderr, "unknown paramf %d\n", param);234return 0;235}236}237238static int239vc4_screen_get_shader_param(struct pipe_screen *pscreen,240enum pipe_shader_type shader,241enum pipe_shader_cap param)242{243if (shader != PIPE_SHADER_VERTEX &&244shader != PIPE_SHADER_FRAGMENT) {245return 0;246}247248/* this is probably not totally correct.. but it's a start: */249switch (param) {250case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:251case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:252case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:253case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:254return 16384;255256case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:257return vc4_screen(pscreen)->has_control_flow;258259case PIPE_SHADER_CAP_MAX_INPUTS:260return 8;261case PIPE_SHADER_CAP_MAX_OUTPUTS:262return shader == PIPE_SHADER_FRAGMENT ? 1 : 8;263case PIPE_SHADER_CAP_MAX_TEMPS:264return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */265case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:266return 16 * 1024 * sizeof(float);267case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:268return 1;269case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:270return 0;271case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:272case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:273case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:274return 0;275case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:276return 1;277case PIPE_SHADER_CAP_SUBROUTINES:278return 0;279case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:280return 0;281case PIPE_SHADER_CAP_INTEGERS:282return 1;283case PIPE_SHADER_CAP_INT64_ATOMICS:284case PIPE_SHADER_CAP_FP16:285case PIPE_SHADER_CAP_FP16_DERIVATIVES:286case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:287case PIPE_SHADER_CAP_INT16:288case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:289case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:290case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:291case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:292case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:293case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:294return 0;295case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:296case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:297return VC4_MAX_TEXTURE_SAMPLERS;298case PIPE_SHADER_CAP_PREFERRED_IR:299return PIPE_SHADER_IR_NIR;300case PIPE_SHADER_CAP_SUPPORTED_IRS:301return 1 << PIPE_SHADER_IR_NIR;302case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:303return 32;304case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:305case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:306case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:307case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:308case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:309case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:310return 0;311default:312fprintf(stderr, "unknown shader param %d\n", param);313return 0;314}315return 0;316}317318static bool319vc4_screen_is_format_supported(struct pipe_screen *pscreen,320enum pipe_format format,321enum pipe_texture_target target,322unsigned sample_count,323unsigned storage_sample_count,324unsigned usage)325{326struct vc4_screen *screen = vc4_screen(pscreen);327328if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))329return false;330331if (sample_count > 1 && sample_count != VC4_MAX_SAMPLES)332return false;333334if (target >= PIPE_MAX_TEXTURE_TYPES) {335return false;336}337338if (usage & PIPE_BIND_VERTEX_BUFFER) {339switch (format) {340case PIPE_FORMAT_R32G32B32A32_FLOAT:341case PIPE_FORMAT_R32G32B32_FLOAT:342case PIPE_FORMAT_R32G32_FLOAT:343case PIPE_FORMAT_R32_FLOAT:344case PIPE_FORMAT_R32G32B32A32_SNORM:345case PIPE_FORMAT_R32G32B32_SNORM:346case PIPE_FORMAT_R32G32_SNORM:347case PIPE_FORMAT_R32_SNORM:348case PIPE_FORMAT_R32G32B32A32_SSCALED:349case PIPE_FORMAT_R32G32B32_SSCALED:350case PIPE_FORMAT_R32G32_SSCALED:351case PIPE_FORMAT_R32_SSCALED:352case PIPE_FORMAT_R16G16B16A16_UNORM:353case PIPE_FORMAT_R16G16B16_UNORM:354case PIPE_FORMAT_R16G16_UNORM:355case PIPE_FORMAT_R16_UNORM:356case PIPE_FORMAT_R16G16B16A16_SNORM:357case PIPE_FORMAT_R16G16B16_SNORM:358case PIPE_FORMAT_R16G16_SNORM:359case PIPE_FORMAT_R16_SNORM:360case PIPE_FORMAT_R16G16B16A16_USCALED:361case PIPE_FORMAT_R16G16B16_USCALED:362case PIPE_FORMAT_R16G16_USCALED:363case PIPE_FORMAT_R16_USCALED:364case PIPE_FORMAT_R16G16B16A16_SSCALED:365case PIPE_FORMAT_R16G16B16_SSCALED:366case PIPE_FORMAT_R16G16_SSCALED:367case PIPE_FORMAT_R16_SSCALED:368case PIPE_FORMAT_R8G8B8A8_UNORM:369case PIPE_FORMAT_R8G8B8_UNORM:370case PIPE_FORMAT_R8G8_UNORM:371case PIPE_FORMAT_R8_UNORM:372case PIPE_FORMAT_R8G8B8A8_SNORM:373case PIPE_FORMAT_R8G8B8_SNORM:374case PIPE_FORMAT_R8G8_SNORM:375case PIPE_FORMAT_R8_SNORM:376case PIPE_FORMAT_R8G8B8A8_USCALED:377case PIPE_FORMAT_R8G8B8_USCALED:378case PIPE_FORMAT_R8G8_USCALED:379case PIPE_FORMAT_R8_USCALED:380case PIPE_FORMAT_R8G8B8A8_SSCALED:381case PIPE_FORMAT_R8G8B8_SSCALED:382case PIPE_FORMAT_R8G8_SSCALED:383case PIPE_FORMAT_R8_SSCALED:384break;385default:386return false;387}388}389390if ((usage & PIPE_BIND_RENDER_TARGET) &&391!vc4_rt_format_supported(format)) {392return false;393}394395if ((usage & PIPE_BIND_SAMPLER_VIEW) &&396(!vc4_tex_format_supported(format) ||397(format == PIPE_FORMAT_ETC1_RGB8 && !screen->has_etc1))) {398return false;399}400401if ((usage & PIPE_BIND_DEPTH_STENCIL) &&402format != PIPE_FORMAT_S8_UINT_Z24_UNORM &&403format != PIPE_FORMAT_X8Z24_UNORM) {404return false;405}406407if ((usage & PIPE_BIND_INDEX_BUFFER) &&408format != PIPE_FORMAT_R8_UINT &&409format != PIPE_FORMAT_R16_UINT) {410return false;411}412413return true;414}415416static const uint64_t *vc4_get_modifiers(struct pipe_screen *pscreen, int *num)417{418struct vc4_screen *screen = vc4_screen(pscreen);419static const uint64_t all_modifiers[] = {420DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED,421DRM_FORMAT_MOD_LINEAR,422};423int m;424425/* We support both modifiers (tiled and linear) for all sampler426* formats, but if we don't have the DRM_VC4_GET_TILING ioctl427* we shouldn't advertise the tiled formats.428*/429if (screen->has_tiling_ioctl) {430m = 0;431*num = 2;432} else{433m = 1;434*num = 1;435}436437return &all_modifiers[m];438}439440static void441vc4_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,442enum pipe_format format, int max,443uint64_t *modifiers,444unsigned int *external_only,445int *count)446{447const uint64_t *available_modifiers;448int i;449bool tex_will_lower;450int num_modifiers;451452available_modifiers = vc4_get_modifiers(pscreen, &num_modifiers);453454if (!modifiers) {455*count = num_modifiers;456return;457}458459*count = MIN2(max, num_modifiers);460tex_will_lower = !vc4_tex_format_supported(format);461for (i = 0; i < *count; i++) {462modifiers[i] = available_modifiers[i];463if (external_only)464external_only[i] = tex_will_lower;465}466}467468static bool469vc4_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,470uint64_t modifier,471enum pipe_format format,472bool *external_only)473{474const uint64_t *available_modifiers;475int i, num_modifiers;476477available_modifiers = vc4_get_modifiers(pscreen, &num_modifiers);478479for (i = 0; i < num_modifiers; i++) {480if (modifier == available_modifiers[i]) {481if (external_only)482*external_only = !vc4_tex_format_supported(format);483484return true;485}486}487488return false;489}490491static bool492vc4_get_chip_info(struct vc4_screen *screen)493{494struct drm_vc4_get_param ident0 = {495.param = DRM_VC4_PARAM_V3D_IDENT0,496};497struct drm_vc4_get_param ident1 = {498.param = DRM_VC4_PARAM_V3D_IDENT1,499};500int ret;501502ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident0);503if (ret != 0) {504if (errno == EINVAL) {505/* Backwards compatibility with 2835 kernels which506* only do V3D 2.1.507*/508screen->v3d_ver = 21;509return true;510} else {511fprintf(stderr, "Couldn't get V3D IDENT0: %s\n",512strerror(errno));513return false;514}515}516ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident1);517if (ret != 0) {518fprintf(stderr, "Couldn't get V3D IDENT1: %s\n",519strerror(errno));520return false;521}522523uint32_t major = (ident0.value >> 24) & 0xff;524uint32_t minor = (ident1.value >> 0) & 0xf;525screen->v3d_ver = major * 10 + minor;526527if (screen->v3d_ver != 21 && screen->v3d_ver != 26) {528fprintf(stderr,529"V3D %d.%d not supported by this version of Mesa.\n",530screen->v3d_ver / 10,531screen->v3d_ver % 10);532return false;533}534535return true;536}537538struct pipe_screen *539vc4_screen_create(int fd, struct renderonly *ro)540{541struct vc4_screen *screen = rzalloc(NULL, struct vc4_screen);542uint64_t syncobj_cap = 0;543struct pipe_screen *pscreen;544int err;545546pscreen = &screen->base;547548pscreen->destroy = vc4_screen_destroy;549pscreen->get_param = vc4_screen_get_param;550pscreen->get_paramf = vc4_screen_get_paramf;551pscreen->get_shader_param = vc4_screen_get_shader_param;552pscreen->context_create = vc4_context_create;553pscreen->is_format_supported = vc4_screen_is_format_supported;554555screen->fd = fd;556screen->ro = ro;557558list_inithead(&screen->bo_cache.time_list);559(void) mtx_init(&screen->bo_handles_mutex, mtx_plain);560screen->bo_handles = util_hash_table_create_ptr_keys();561562screen->has_control_flow =563vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_BRANCHES);564screen->has_etc1 =565vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_ETC1);566screen->has_threaded_fs =567vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_THREADED_FS);568screen->has_madvise =569vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_MADVISE);570screen->has_perfmon_ioctl =571vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_PERFMON);572573err = drmGetCap(fd, DRM_CAP_SYNCOBJ, &syncobj_cap);574if (err == 0 && syncobj_cap)575screen->has_syncobj = true;576577if (!vc4_get_chip_info(screen))578goto fail;579580util_cpu_detect();581582slab_create_parent(&screen->transfer_pool, sizeof(struct vc4_transfer), 16);583584vc4_fence_screen_init(screen);585586vc4_debug = debug_get_option_vc4_debug();587if (vc4_debug & VC4_DEBUG_SHADERDB)588vc4_debug |= VC4_DEBUG_NORAST;589590#ifdef USE_VC4_SIMULATOR591vc4_simulator_init(screen);592#endif593594vc4_resource_screen_init(pscreen);595596pscreen->get_name = vc4_screen_get_name;597pscreen->get_vendor = vc4_screen_get_vendor;598pscreen->get_device_vendor = vc4_screen_get_vendor;599pscreen->get_compiler_options = vc4_screen_get_compiler_options;600pscreen->query_dmabuf_modifiers = vc4_screen_query_dmabuf_modifiers;601pscreen->is_dmabuf_modifier_supported = vc4_screen_is_dmabuf_modifier_supported;602603if (screen->has_perfmon_ioctl) {604pscreen->get_driver_query_group_info = vc4_get_driver_query_group_info;605pscreen->get_driver_query_info = vc4_get_driver_query_info;606}607608return pscreen;609610fail:611close(fd);612ralloc_free(pscreen);613return NULL;614}615616617