Path: blob/21.2-virgl/src/gallium/drivers/crocus/crocus_screen.c
4570 views
/*1* Copyright © 2017 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice shall be included11* in all copies or substantial portions of the Software.12*13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS14* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER17* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING18* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER19* DEALINGS IN THE SOFTWARE.20*/2122/**23* @file crocus_screen.c24*25* Screen related driver hooks and capability lists.26*27* A program may use multiple rendering contexts (crocus_context), but28* they all share a common screen (crocus_screen). Global driver state29* can be stored in the screen; it may be accessed by multiple threads.30*/3132#include <stdio.h>33#include <errno.h>34#include <sys/ioctl.h>35#include "pipe/p_defines.h"36#include "pipe/p_state.h"37#include "pipe/p_context.h"38#include "pipe/p_screen.h"39#include "util/debug.h"40#include "util/u_inlines.h"41#include "util/format/u_format.h"42#include "util/u_transfer_helper.h"43#include "util/u_upload_mgr.h"44#include "util/ralloc.h"45#include "util/xmlconfig.h"46#include "drm-uapi/i915_drm.h"47#include "crocus_context.h"48#include "crocus_defines.h"49#include "crocus_fence.h"50#include "crocus_pipe.h"51#include "crocus_resource.h"52#include "crocus_screen.h"53#include "intel/compiler/brw_compiler.h"54#include "intel/common/intel_gem.h"55#include "intel/common/intel_l3_config.h"56#include "intel/common/intel_uuid.h"57#include "crocus_monitor.h"5859#define genX_call(devinfo, func, ...) \60switch ((devinfo)->verx10) { \61case 80: \62gfx8_##func(__VA_ARGS__); \63break; \64case 75: \65gfx75_##func(__VA_ARGS__); \66break; \67case 70: \68gfx7_##func(__VA_ARGS__); \69break; \70case 60: \71gfx6_##func(__VA_ARGS__); \72break; \73case 50: \74gfx5_##func(__VA_ARGS__); \75break; \76case 45: \77gfx45_##func(__VA_ARGS__); \78break; \79case 40: \80gfx4_##func(__VA_ARGS__); \81break; \82default: \83unreachable("Unknown hardware generation"); \84}8586static void87crocus_flush_frontbuffer(struct pipe_screen *_screen,88struct pipe_context *_pipe,89struct pipe_resource *resource,90unsigned level, unsigned layer,91void *context_private, struct pipe_box *box)92{93}9495static const char *96crocus_get_vendor(struct pipe_screen *pscreen)97{98return "Intel";99}100101static const char *102crocus_get_device_vendor(struct pipe_screen *pscreen)103{104return "Intel";105}106107static void108crocus_get_device_uuid(struct pipe_screen *pscreen, char *uuid)109{110struct crocus_screen *screen = (struct crocus_screen *)pscreen;111const struct isl_device *isldev = &screen->isl_dev;112113intel_uuid_compute_device_id((uint8_t *)uuid, isldev, PIPE_UUID_SIZE);114}115116static void117crocus_get_driver_uuid(struct pipe_screen *pscreen, char *uuid)118{119struct crocus_screen *screen = (struct crocus_screen *)pscreen;120const struct intel_device_info *devinfo = &screen->devinfo;121122intel_uuid_compute_driver_id((uint8_t *)uuid, devinfo, PIPE_UUID_SIZE);123}124125static const char *126crocus_get_name(struct pipe_screen *pscreen)127{128struct crocus_screen *screen = (struct crocus_screen *)pscreen;129static char buf[128];130131const char *name = intel_get_device_name(screen->pci_id);132133if (!name)134name = "Intel Unknown";135136snprintf(buf, sizeof(buf), "Mesa %s", name);137return buf;138}139140static uint64_t141get_aperture_size(int fd)142{143struct drm_i915_gem_get_aperture aperture = {};144intel_ioctl(fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);145return aperture.aper_size;146}147148static int149crocus_get_param(struct pipe_screen *pscreen, enum pipe_cap param)150{151struct crocus_screen *screen = (struct crocus_screen *)pscreen;152const struct intel_device_info *devinfo = &screen->devinfo;153154switch (param) {155case PIPE_CAP_NPOT_TEXTURES:156case PIPE_CAP_ANISOTROPIC_FILTER:157case PIPE_CAP_POINT_SPRITE:158case PIPE_CAP_OCCLUSION_QUERY:159case PIPE_CAP_TEXTURE_SWIZZLE:160case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:161case PIPE_CAP_BLEND_EQUATION_SEPARATE:162case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:163case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:164case PIPE_CAP_VERTEX_SHADER_SATURATE:165case PIPE_CAP_PRIMITIVE_RESTART:166case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:167case PIPE_CAP_INDEP_BLEND_ENABLE:168case PIPE_CAP_RGB_OVERRIDE_DST_ALPHA_BLEND:169case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:170case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:171case PIPE_CAP_DEPTH_CLIP_DISABLE:172case PIPE_CAP_TGSI_INSTANCEID:173case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:174case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:175case PIPE_CAP_SEAMLESS_CUBE_MAP:176case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:177case PIPE_CAP_CONDITIONAL_RENDER:178case PIPE_CAP_TEXTURE_BARRIER:179case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:180case PIPE_CAP_START_INSTANCE:181case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:182case PIPE_CAP_FORCE_PERSAMPLE_INTERP:183case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:184case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:185case PIPE_CAP_TGSI_TES_LAYER_VIEWPORT:186case PIPE_CAP_ACCELERATED:187case PIPE_CAP_UMA:188case PIPE_CAP_CLIP_HALFZ:189case PIPE_CAP_TGSI_TEXCOORD:190case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:191case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:192case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET:193case PIPE_CAP_TEXTURE_FLOAT_LINEAR:194case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:195case PIPE_CAP_POLYGON_OFFSET_CLAMP:196case PIPE_CAP_TGSI_TEX_TXF_LZ:197case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:198case PIPE_CAP_CLEAR_TEXTURE:199case PIPE_CAP_TGSI_VOTE:200case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:201case PIPE_CAP_TEXTURE_GATHER_SM5:202case PIPE_CAP_TGSI_ARRAY_COMPONENTS:203case PIPE_CAP_GLSL_TESS_LEVELS_AS_INPUTS:204case PIPE_CAP_NIR_COMPACT_ARRAYS:205case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:206case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:207case PIPE_CAP_INVALIDATE_BUFFER:208case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:209case PIPE_CAP_CS_DERIVED_SYSTEM_VALUES_SUPPORTED:210case PIPE_CAP_FENCE_SIGNAL:211case PIPE_CAP_DEMOTE_TO_HELPER_INVOCATION:212case PIPE_CAP_GL_CLAMP:213return true;214case PIPE_CAP_INT64:215case PIPE_CAP_INT64_DIVMOD:216case PIPE_CAP_TGSI_BALLOT:217case PIPE_CAP_PACKED_UNIFORMS:218return devinfo->ver == 8;219case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:220return devinfo->ver <= 5;221case PIPE_CAP_TEXTURE_QUERY_LOD:222case PIPE_CAP_QUERY_TIME_ELAPSED:223return devinfo->ver >= 5;224case PIPE_CAP_DRAW_INDIRECT:225case PIPE_CAP_MULTI_DRAW_INDIRECT:226case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:227case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:228case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:229case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:230case PIPE_CAP_TGSI_CLOCK:231case PIPE_CAP_TGSI_TXQS:232case PIPE_CAP_COMPUTE:233case PIPE_CAP_SAMPLER_VIEW_TARGET:234case PIPE_CAP_SHADER_SAMPLES_IDENTICAL:235case PIPE_CAP_TGSI_PACK_HALF_FLOAT:236case PIPE_CAP_GL_SPIRV:237case PIPE_CAP_GL_SPIRV_VARIABLE_POINTERS:238case PIPE_CAP_COMPUTE_SHADER_DERIVATIVES:239case PIPE_CAP_DOUBLES:240case PIPE_CAP_MEMOBJ:241return devinfo->ver >= 7;242case PIPE_CAP_QUERY_BUFFER_OBJECT:243case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:244return devinfo->verx10 >= 75;245case PIPE_CAP_CULL_DISTANCE:246case PIPE_CAP_QUERY_PIPELINE_STATISTICS_SINGLE:247case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:248case PIPE_CAP_SAMPLE_SHADING:249case PIPE_CAP_CUBE_MAP_ARRAY:250case PIPE_CAP_QUERY_SO_OVERFLOW:251case PIPE_CAP_TEXTURE_MULTISAMPLE:252case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:253case PIPE_CAP_QUERY_TIMESTAMP:254case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:255case PIPE_CAP_INDEP_BLEND_FUNC:256case PIPE_CAP_TEXTURE_SHADOW_LOD:257case PIPE_CAP_LOAD_CONSTBUF:258case PIPE_CAP_DRAW_PARAMETERS:259case PIPE_CAP_CLEAR_SCISSORED:260return devinfo->ver >= 6;261case PIPE_CAP_FBFETCH:262return devinfo->verx10 >= 45 ? BRW_MAX_DRAW_BUFFERS : 0;263case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:264/* in theory CL (965gm) can do this */265return devinfo->verx10 >= 45 ? 1 : 0;266case PIPE_CAP_MAX_RENDER_TARGETS:267return BRW_MAX_DRAW_BUFFERS;268case PIPE_CAP_MAX_TEXTURE_2D_SIZE:269if (devinfo->ver >= 7)270return 16384;271else272return 8192;273case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:274if (devinfo->ver >= 7)275return CROCUS_MAX_MIPLEVELS; /* 16384x16384 */276else277return CROCUS_MAX_MIPLEVELS - 1; /* 8192x8192 */278case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:279return 12; /* 2048x2048 */280case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:281return (devinfo->ver >= 6) ? 4 : 0;282case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:283return devinfo->ver >= 7 ? 2048 : 512;284case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:285return BRW_MAX_SOL_BINDINGS / CROCUS_MAX_SOL_BUFFERS;286case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:287return BRW_MAX_SOL_BINDINGS;288case PIPE_CAP_GLSL_FEATURE_LEVEL: {289if (devinfo->verx10 >= 75)290return 460;291else if (devinfo->ver >= 7)292return 420;293else if (devinfo->ver >= 6)294return 330;295return 140;296}297case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:298return 140;299300case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:301/* 3DSTATE_CONSTANT_XS requires the start of UBOs to be 32B aligned */302return 32;303case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:304return CROCUS_MAP_BUFFER_ALIGNMENT;305case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:306return devinfo->ver >= 7 ? 4 : 0;307case PIPE_CAP_MAX_SHADER_BUFFER_SIZE:308return devinfo->ver >= 7 ? (1 << 27) : 0;309case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:310return 16; // XXX: u_screen says 256 is the minimum value...311case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:312return true;313case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:314return CROCUS_MAX_TEXTURE_BUFFER_SIZE;315case PIPE_CAP_MAX_VIEWPORTS:316return devinfo->ver >= 6 ? 16 : 1;317case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:318return devinfo->ver >= 6 ? 256 : 0;319case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:320return devinfo->ver >= 6 ? 1024 : 0;321case PIPE_CAP_MAX_GS_INVOCATIONS:322return devinfo->ver >= 7 ? 32 : 1;323case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:324if (devinfo->ver >= 7)325return 4;326else if (devinfo->ver == 6)327return 1;328else329return 0;330case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:331if (devinfo->ver >= 7)332return -32;333else if (devinfo->ver == 6)334return -8;335else336return 0;337case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:338if (devinfo->ver >= 7)339return 31;340else if (devinfo->ver == 6)341return 7;342else343return 0;344case PIPE_CAP_MAX_VERTEX_STREAMS:345return devinfo->ver >= 7 ? 4 : 1;346case PIPE_CAP_VENDOR_ID:347return 0x8086;348case PIPE_CAP_DEVICE_ID:349return screen->pci_id;350case PIPE_CAP_VIDEO_MEMORY: {351/* Once a batch uses more than 75% of the maximum mappable size, we352* assume that there's some fragmentation, and we start doing extra353* flushing, etc. That's the big cliff apps will care about.354*/355const unsigned gpu_mappable_megabytes =356(screen->aperture_bytes * 3 / 4) / (1024 * 1024);357358const long system_memory_pages = sysconf(_SC_PHYS_PAGES);359const long system_page_size = sysconf(_SC_PAGE_SIZE);360361if (system_memory_pages <= 0 || system_page_size <= 0)362return -1;363364const uint64_t system_memory_bytes =365(uint64_t) system_memory_pages * (uint64_t) system_page_size;366367const unsigned system_memory_megabytes =368(unsigned) (system_memory_bytes / (1024 * 1024));369370return MIN2(system_memory_megabytes, gpu_mappable_megabytes);371}372case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:373case PIPE_CAP_MAX_VARYINGS:374return (screen->devinfo.ver >= 6) ? 32 : 16;375case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:376/* AMD_pinned_memory assumes the flexibility of using client memory377* for any buffer (incl. vertex buffers) which rules out the prospect378* of using snooped buffers, as using snooped buffers without379* cogniscience is likely to be detrimental to performance and require380* extensive checking in the driver for correctness, e.g. to prevent381* illegal snoop <-> snoop transfers.382*/383return devinfo->has_llc;384case PIPE_CAP_THROTTLE:385return screen->driconf.disable_throttling ? 0 : 1;386387case PIPE_CAP_CONTEXT_PRIORITY_MASK:388return PIPE_CONTEXT_PRIORITY_LOW |389PIPE_CONTEXT_PRIORITY_MEDIUM |390PIPE_CONTEXT_PRIORITY_HIGH;391392case PIPE_CAP_FRONTEND_NOOP:393return true;394// XXX: don't hardcode 00:00:02.0 PCI here395case PIPE_CAP_PCI_GROUP:396return 0;397case PIPE_CAP_PCI_BUS:398return 0;399case PIPE_CAP_PCI_DEVICE:400return 2;401case PIPE_CAP_PCI_FUNCTION:402return 0;403404default:405return u_pipe_screen_get_param_defaults(pscreen, param);406}407return 0;408}409410static float411crocus_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)412{413struct crocus_screen *screen = (struct crocus_screen *)pscreen;414const struct intel_device_info *devinfo = &screen->devinfo;415416switch (param) {417case PIPE_CAPF_MAX_LINE_WIDTH:418case PIPE_CAPF_MAX_LINE_WIDTH_AA:419if (devinfo->ver >= 6)420return 7.375f;421else422return 7.0f;423424case PIPE_CAPF_MAX_POINT_WIDTH:425case PIPE_CAPF_MAX_POINT_WIDTH_AA:426return 255.0f;427428case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:429return 16.0f;430case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:431return 15.0f;432case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:433case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:434case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:435return 0.0f;436default:437unreachable("unknown param");438}439}440441static int442crocus_get_shader_param(struct pipe_screen *pscreen,443enum pipe_shader_type p_stage,444enum pipe_shader_cap param)445{446gl_shader_stage stage = stage_from_pipe(p_stage);447struct crocus_screen *screen = (struct crocus_screen *)pscreen;448const struct intel_device_info *devinfo = &screen->devinfo;449450if (devinfo->ver < 6 &&451p_stage != PIPE_SHADER_VERTEX &&452p_stage != PIPE_SHADER_FRAGMENT)453return 0;454455if (devinfo->ver == 6 &&456p_stage != PIPE_SHADER_VERTEX &&457p_stage != PIPE_SHADER_FRAGMENT &&458p_stage != PIPE_SHADER_GEOMETRY)459return 0;460461/* this is probably not totally correct.. but it's a start: */462switch (param) {463case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:464return stage == MESA_SHADER_FRAGMENT ? 1024 : 16384;465case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:466case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:467case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:468return stage == MESA_SHADER_FRAGMENT ? 1024 : 0;469470case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:471return UINT_MAX;472473case PIPE_SHADER_CAP_MAX_INPUTS:474if (stage == MESA_SHADER_VERTEX ||475stage == MESA_SHADER_GEOMETRY)476return 16; /* Gen7 vec4 geom backend */477return 32;478case PIPE_SHADER_CAP_MAX_OUTPUTS:479return 32;480case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:481return 16 * 1024 * sizeof(float);482case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:483return devinfo->ver >= 6 ? 16 : 1;484case PIPE_SHADER_CAP_MAX_TEMPS:485return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */486case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:487return 0;488case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:489case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:490case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:491case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:492/* Lie about these to avoid st/mesa's GLSL IR lowering of indirects,493* which we don't want. Our compiler backend will check brw_compiler's494* options and call nir_lower_indirect_derefs appropriately anyway.495*/496return true;497case PIPE_SHADER_CAP_SUBROUTINES:498return 0;499case PIPE_SHADER_CAP_INTEGERS:500return 1;501case PIPE_SHADER_CAP_INT64_ATOMICS:502case PIPE_SHADER_CAP_FP16:503return 0;504case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:505case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:506return (devinfo->verx10 >= 75) ? CROCUS_MAX_TEXTURE_SAMPLERS : 16;507case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:508if (devinfo->ver >= 7 &&509(p_stage == PIPE_SHADER_FRAGMENT ||510p_stage == PIPE_SHADER_COMPUTE))511return CROCUS_MAX_TEXTURE_SAMPLERS;512return 0;513case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:514return devinfo->ver >= 7 ? (CROCUS_MAX_ABOS + CROCUS_MAX_SSBOS) : 0;515case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:516case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:517return 0;518case PIPE_SHADER_CAP_PREFERRED_IR:519return PIPE_SHADER_IR_NIR;520case PIPE_SHADER_CAP_SUPPORTED_IRS:521return 1 << PIPE_SHADER_IR_NIR;522case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:523case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:524return 1;525case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:526case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:527case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:528case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:529case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:530case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:531case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:532case PIPE_SHADER_CAP_FP16_DERIVATIVES:533case PIPE_SHADER_CAP_INT16:534case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:535case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:536return 0;537default:538unreachable("unknown shader param");539}540}541542static int543crocus_get_compute_param(struct pipe_screen *pscreen,544enum pipe_shader_ir ir_type,545enum pipe_compute_cap param,546void *ret)547{548struct crocus_screen *screen = (struct crocus_screen *)pscreen;549const struct intel_device_info *devinfo = &screen->devinfo;550551const unsigned max_threads = MIN2(64, devinfo->max_cs_threads);552const uint32_t max_invocations = 32 * max_threads;553554if (devinfo->ver < 7)555return 0;556#define RET(x) do { \557if (ret) \558memcpy(ret, x, sizeof(x)); \559return sizeof(x); \560} while (0)561562switch (param) {563case PIPE_COMPUTE_CAP_ADDRESS_BITS:564RET((uint32_t []){ 32 });565566case PIPE_COMPUTE_CAP_IR_TARGET:567if (ret)568strcpy(ret, "gen");569return 4;570571case PIPE_COMPUTE_CAP_GRID_DIMENSION:572RET((uint64_t []) { 3 });573574case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:575RET(((uint64_t []) { 65535, 65535, 65535 }));576577case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:578/* MaxComputeWorkGroupSize[0..2] */579RET(((uint64_t []) {max_invocations, max_invocations, max_invocations}));580581case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:582/* MaxComputeWorkGroupInvocations */583RET((uint64_t []) { max_invocations });584585case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:586/* MaxComputeSharedMemorySize */587RET((uint64_t []) { 64 * 1024 });588589case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED:590RET((uint32_t []) { 1 });591592case PIPE_COMPUTE_CAP_SUBGROUP_SIZE:593RET((uint32_t []) { BRW_SUBGROUP_SIZE });594595case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:596RET((uint64_t []) { max_invocations });597598case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE:599case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:600case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:601case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE:602case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE:603case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:604605// XXX: I think these are for Clover...606return 0;607608default:609unreachable("unknown compute param");610}611}612613static uint64_t614crocus_get_timestamp(struct pipe_screen *pscreen)615{616struct crocus_screen *screen = (struct crocus_screen *) pscreen;617const unsigned TIMESTAMP = 0x2358;618uint64_t result;619620crocus_reg_read(screen->bufmgr, TIMESTAMP | 1, &result);621622result = intel_device_info_timebase_scale(&screen->devinfo, result);623result &= (1ull << TIMESTAMP_BITS) - 1;624625return result;626}627628void629crocus_screen_destroy(struct crocus_screen *screen)630{631u_transfer_helper_destroy(screen->base.transfer_helper);632crocus_bufmgr_unref(screen->bufmgr);633disk_cache_destroy(screen->disk_cache);634close(screen->winsys_fd);635ralloc_free(screen);636}637638static void639crocus_screen_unref(struct pipe_screen *pscreen)640{641crocus_pscreen_unref(pscreen);642}643644static void645crocus_query_memory_info(struct pipe_screen *pscreen,646struct pipe_memory_info *info)647{648}649650static const void *651crocus_get_compiler_options(struct pipe_screen *pscreen,652enum pipe_shader_ir ir,653enum pipe_shader_type pstage)654{655struct crocus_screen *screen = (struct crocus_screen *) pscreen;656gl_shader_stage stage = stage_from_pipe(pstage);657assert(ir == PIPE_SHADER_IR_NIR);658659return screen->compiler->glsl_compiler_options[stage].NirOptions;660}661662static struct disk_cache *663crocus_get_disk_shader_cache(struct pipe_screen *pscreen)664{665struct crocus_screen *screen = (struct crocus_screen *) pscreen;666return screen->disk_cache;667}668669static const struct intel_l3_config *670crocus_get_default_l3_config(const struct intel_device_info *devinfo,671bool compute)672{673bool wants_dc_cache = true;674bool has_slm = compute;675const struct intel_l3_weights w =676intel_get_default_l3_weights(devinfo, wants_dc_cache, has_slm);677return intel_get_l3_config(devinfo, w);678}679680static void681crocus_shader_debug_log(void *data, const char *fmt, ...)682{683struct pipe_debug_callback *dbg = data;684unsigned id = 0;685va_list args;686687if (!dbg->debug_message)688return;689690va_start(args, fmt);691dbg->debug_message(dbg->data, &id, PIPE_DEBUG_TYPE_SHADER_INFO, fmt, args);692va_end(args);693}694695static void696crocus_shader_perf_log(void *data, const char *fmt, ...)697{698struct pipe_debug_callback *dbg = data;699unsigned id = 0;700va_list args;701va_start(args, fmt);702703if (unlikely(INTEL_DEBUG & DEBUG_PERF)) {704va_list args_copy;705va_copy(args_copy, args);706vfprintf(stderr, fmt, args_copy);707va_end(args_copy);708}709710if (dbg->debug_message) {711dbg->debug_message(dbg->data, &id, PIPE_DEBUG_TYPE_PERF_INFO, fmt, args);712}713714va_end(args);715}716717static bool718crocus_detect_swizzling(struct crocus_screen *screen)719{720/* Broadwell PRM says:721*722* "Before Gen8, there was a historical configuration control field to723* swizzle address bit[6] for in X/Y tiling modes. This was set in three724* different places: TILECTL[1:0], ARB_MODE[5:4], and725* DISP_ARB_CTL[14:13].726*727* For Gen8 and subsequent generations, the swizzle fields are all728* reserved, and the CPU's memory controller performs all address729* swizzling modifications."730*/731uint32_t tiling = I915_TILING_X;732uint32_t swizzle_mode = 0;733struct crocus_bo *buffer =734crocus_bo_alloc_tiled(screen->bufmgr, "swizzle test", 32768,7350, tiling, 512, 0);736if (buffer == NULL)737return false;738739crocus_bo_get_tiling(buffer, &tiling, &swizzle_mode);740crocus_bo_unreference(buffer);741742return swizzle_mode != I915_BIT_6_SWIZZLE_NONE;743}744745struct pipe_screen *746crocus_screen_create(int fd, const struct pipe_screen_config *config)747{748struct crocus_screen *screen = rzalloc(NULL, struct crocus_screen);749if (!screen)750return NULL;751752if (!intel_get_device_info_from_fd(fd, &screen->devinfo))753return NULL;754screen->pci_id = screen->devinfo.chipset_id;755screen->no_hw = screen->devinfo.no_hw;756757if (screen->devinfo.ver > 8)758return NULL;759760if (screen->devinfo.ver == 8) {761/* bind to cherryview or bdw if forced */762if (!screen->devinfo.is_cherryview &&763!getenv("CROCUS_GEN8"))764return NULL;765}766767p_atomic_set(&screen->refcount, 1);768769screen->aperture_bytes = get_aperture_size(fd);770771if (getenv("INTEL_NO_HW") != NULL)772screen->no_hw = true;773774bool bo_reuse = false;775int bo_reuse_mode = driQueryOptioni(config->options, "bo_reuse");776switch (bo_reuse_mode) {777case DRI_CONF_BO_REUSE_DISABLED:778break;779case DRI_CONF_BO_REUSE_ALL:780bo_reuse = true;781break;782}783784screen->bufmgr = crocus_bufmgr_get_for_fd(&screen->devinfo, fd, bo_reuse);785if (!screen->bufmgr)786return NULL;787screen->fd = crocus_bufmgr_get_fd(screen->bufmgr);788screen->winsys_fd = fd;789790screen->has_swizzling = crocus_detect_swizzling(screen);791brw_process_intel_debug_variable();792793screen->driconf.dual_color_blend_by_location =794driQueryOptionb(config->options, "dual_color_blend_by_location");795screen->driconf.disable_throttling =796driQueryOptionb(config->options, "disable_throttling");797screen->driconf.always_flush_cache =798driQueryOptionb(config->options, "always_flush_cache");799800screen->precompile = env_var_as_boolean("shader_precompile", true);801802isl_device_init(&screen->isl_dev, &screen->devinfo,803screen->has_swizzling);804805screen->compiler = brw_compiler_create(screen, &screen->devinfo);806screen->compiler->shader_debug_log = crocus_shader_debug_log;807screen->compiler->shader_perf_log = crocus_shader_perf_log;808screen->compiler->supports_pull_constants = false;809screen->compiler->supports_shader_constants = false;810screen->compiler->compact_params = false;811screen->compiler->constant_buffer_0_is_relative = true;812813if (screen->devinfo.ver >= 7) {814screen->l3_config_3d = crocus_get_default_l3_config(&screen->devinfo, false);815screen->l3_config_cs = crocus_get_default_l3_config(&screen->devinfo, true);816}817818crocus_disk_cache_init(screen);819820slab_create_parent(&screen->transfer_pool,821sizeof(struct crocus_transfer), 64);822823screen->subslice_total = intel_device_info_subslice_total(&screen->devinfo);824assert(screen->subslice_total >= 1);825826struct pipe_screen *pscreen = &screen->base;827828crocus_init_screen_fence_functions(pscreen);829crocus_init_screen_resource_functions(pscreen);830831pscreen->destroy = crocus_screen_unref;832pscreen->get_name = crocus_get_name;833pscreen->get_vendor = crocus_get_vendor;834pscreen->get_device_vendor = crocus_get_device_vendor;835pscreen->get_param = crocus_get_param;836pscreen->get_shader_param = crocus_get_shader_param;837pscreen->get_compute_param = crocus_get_compute_param;838pscreen->get_paramf = crocus_get_paramf;839pscreen->get_compiler_options = crocus_get_compiler_options;840pscreen->get_device_uuid = crocus_get_device_uuid;841pscreen->get_driver_uuid = crocus_get_driver_uuid;842pscreen->get_disk_shader_cache = crocus_get_disk_shader_cache;843pscreen->is_format_supported = crocus_is_format_supported;844pscreen->context_create = crocus_create_context;845pscreen->flush_frontbuffer = crocus_flush_frontbuffer;846pscreen->get_timestamp = crocus_get_timestamp;847pscreen->query_memory_info = crocus_query_memory_info;848pscreen->get_driver_query_group_info = crocus_get_monitor_group_info;849pscreen->get_driver_query_info = crocus_get_monitor_info;850851genX_call(&screen->devinfo, crocus_init_screen_state, screen);852genX_call(&screen->devinfo, crocus_init_screen_query, screen);853return pscreen;854}855856857