1/* 2 * Copyright © 2017 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 * DEALINGS IN THE SOFTWARE. 21 */ 22 23/** 24 * @file crocus_screen.c 25 * 26 * Screen related driver hooks and capability lists. 27 * 28 * A program may use multiple rendering contexts (crocus_context), but 29 * they all share a common screen (crocus_screen). Global driver state 30 * can be stored in the screen; it may be accessed by multiple threads. 31 */ 32 33#include <stdio.h> 34#include <errno.h> 35#include <sys/ioctl.h> 36#include "pipe/p_defines.h" 37#include "pipe/p_state.h" 38#include "pipe/p_context.h" 39#include "pipe/p_screen.h" 40#include "util/debug.h" 41#include "util/u_inlines.h" 42#include "util/format/u_format.h" 43#include "util/u_transfer_helper.h" 44#include "util/u_upload_mgr.h" 45#include "util/ralloc.h" 46#include "util/xmlconfig.h" 47#include "drm-uapi/i915_drm.h" 48#include "crocus_context.h" 49#include "crocus_defines.h" 50#include "crocus_fence.h" 51#include "crocus_pipe.h" 52#include "crocus_resource.h" 53#include "crocus_screen.h" 54#include "intel/compiler/brw_compiler.h" 55#include "intel/common/intel_gem.h" 56#include "intel/common/intel_l3_config.h" 57#include "intel/common/intel_uuid.h" 58#include "crocus_monitor.h" 59 60#define genX_call(devinfo, func, ...) \ 61 switch ((devinfo)->verx10) { \ 62 case 80: \ 63 gfx8_##func(__VA_ARGS__); \ 64 break; \ 65 case 75: \ 66 gfx75_##func(__VA_ARGS__); \ 67 break; \ 68 case 70: \ 69 gfx7_##func(__VA_ARGS__); \ 70 break; \ 71 case 60: \ 72 gfx6_##func(__VA_ARGS__); \ 73 break; \ 74 case 50: \ 75 gfx5_##func(__VA_ARGS__); \ 76 break; \ 77 case 45: \ 78 gfx45_##func(__VA_ARGS__); \ 79 break; \ 80 case 40: \ 81 gfx4_##func(__VA_ARGS__); \ 82 break; \ 83 default: \ 84 unreachable("Unknown hardware generation"); \ 85 } 86 87static const char * 88crocus_get_vendor(struct pipe_screen *pscreen) 89{ 90 return "Intel"; 91} 92 93static const char * 94crocus_get_device_vendor(struct pipe_screen *pscreen) 95{ 96 return "Intel"; 97} 98 99static void 100crocus_get_device_uuid(struct pipe_screen *pscreen, char *uuid) 101{ 102 struct crocus_screen *screen = (struct crocus_screen *)pscreen; 103 104 intel_uuid_compute_device_id((uint8_t *)uuid, &screen->devinfo, PIPE_UUID_SIZE); 105} 106 107static void 108crocus_get_driver_uuid(struct pipe_screen *pscreen, char *uuid) 109{ 110 struct crocus_screen *screen = (struct crocus_screen *)pscreen; 111 const struct intel_device_info *devinfo = &screen->devinfo; 112 113 intel_uuid_compute_driver_id((uint8_t *)uuid, devinfo, PIPE_UUID_SIZE); 114} 115 116static const char * 117crocus_get_name(struct pipe_screen *pscreen) 118{ 119 struct crocus_screen *screen = (struct crocus_screen *)pscreen; 120 const struct intel_device_info *devinfo = &screen->devinfo; 121 static char buf[128]; 122 123 snprintf(buf, sizeof(buf), "Mesa %s", devinfo->name); 124 return buf; 125} 126 127static uint64_t 128get_aperture_size(int fd) 129{ 130 struct drm_i915_gem_get_aperture aperture = {}; 131 intel_ioctl(fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture); 132 return aperture.aper_size; 133} 134 135static int 136crocus_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 137{ 138 struct crocus_screen *screen = (struct crocus_screen *)pscreen; 139 const struct intel_device_info *devinfo = &screen->devinfo; 140 141 switch (param) { 142 case PIPE_CAP_NPOT_TEXTURES: 143 case PIPE_CAP_ANISOTROPIC_FILTER: 144 case PIPE_CAP_POINT_SPRITE: 145 case PIPE_CAP_OCCLUSION_QUERY: 146 case PIPE_CAP_TEXTURE_SWIZZLE: 147 case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE: 148 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 149 case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD: 150 case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES: 151 case PIPE_CAP_PRIMITIVE_RESTART: 152 case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX: 153 case PIPE_CAP_INDEP_BLEND_ENABLE: 154 case PIPE_CAP_RGB_OVERRIDE_DST_ALPHA_BLEND: 155 case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT: 156 case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER: 157 case PIPE_CAP_DEPTH_CLIP_DISABLE: 158 case PIPE_CAP_VS_INSTANCEID: 159 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 160 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 161 case PIPE_CAP_SEAMLESS_CUBE_MAP: 162 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 163 case PIPE_CAP_CONDITIONAL_RENDER: 164 case PIPE_CAP_TEXTURE_BARRIER: 165 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 166 case PIPE_CAP_START_INSTANCE: 167 case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: 168 case PIPE_CAP_FORCE_PERSAMPLE_INTERP: 169 case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: 170 case PIPE_CAP_VS_LAYER_VIEWPORT: 171 case PIPE_CAP_TES_LAYER_VIEWPORT: 172 case PIPE_CAP_ACCELERATED: 173 case PIPE_CAP_UMA: 174 case PIPE_CAP_CLIP_HALFZ: 175 case PIPE_CAP_TGSI_TEXCOORD: 176 case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: 177 case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS: 178 case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET: 179 case PIPE_CAP_TEXTURE_FLOAT_LINEAR: 180 case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR: 181 case PIPE_CAP_POLYGON_OFFSET_CLAMP: 182 case PIPE_CAP_TGSI_TEX_TXF_LZ: 183 case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: 184 case PIPE_CAP_CLEAR_TEXTURE: 185 case PIPE_CAP_SHADER_GROUP_VOTE: 186 case PIPE_CAP_VS_WINDOW_SPACE_POSITION: 187 case PIPE_CAP_TEXTURE_GATHER_SM5: 188 case PIPE_CAP_SHADER_ARRAY_COMPONENTS: 189 case PIPE_CAP_GLSL_TESS_LEVELS_AS_INPUTS: 190 case PIPE_CAP_NIR_COMPACT_ARRAYS: 191 case PIPE_CAP_FS_POSITION_IS_SYSVAL: 192 case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL: 193 case PIPE_CAP_INVALIDATE_BUFFER: 194 case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS: 195 case PIPE_CAP_CS_DERIVED_SYSTEM_VALUES_SUPPORTED: 196 case PIPE_CAP_FENCE_SIGNAL: 197 case PIPE_CAP_DEMOTE_TO_HELPER_INVOCATION: 198 case PIPE_CAP_GL_CLAMP: 199 case PIPE_CAP_LEGACY_MATH_RULES: 200 return true; 201 case PIPE_CAP_INT64: 202 case PIPE_CAP_INT64_DIVMOD: 203 case PIPE_CAP_SHADER_BALLOT: 204 case PIPE_CAP_PACKED_UNIFORMS: 205 return devinfo->ver == 8; 206 case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 207 return devinfo->ver <= 5; 208 case PIPE_CAP_TEXTURE_QUERY_LOD: 209 case PIPE_CAP_QUERY_TIME_ELAPSED: 210 return devinfo->ver >= 5; 211 case PIPE_CAP_DRAW_INDIRECT: 212 case PIPE_CAP_MULTI_DRAW_INDIRECT: 213 case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS: 214 case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT: 215 case PIPE_CAP_FS_FINE_DERIVATIVE: 216 case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS: 217 case PIPE_CAP_SHADER_CLOCK: 218 case PIPE_CAP_TEXTURE_QUERY_SAMPLES: 219 case PIPE_CAP_COMPUTE: 220 case PIPE_CAP_SAMPLER_VIEW_TARGET: 221 case PIPE_CAP_SHADER_SAMPLES_IDENTICAL: 222 case PIPE_CAP_SHADER_PACK_HALF_FLOAT: 223 case PIPE_CAP_GL_SPIRV: 224 case PIPE_CAP_GL_SPIRV_VARIABLE_POINTERS: 225 case PIPE_CAP_COMPUTE_SHADER_DERIVATIVES: 226 case PIPE_CAP_DOUBLES: 227 case PIPE_CAP_MEMOBJ: 228 case PIPE_CAP_IMAGE_STORE_FORMATTED: 229 return devinfo->ver >= 7; 230 case PIPE_CAP_QUERY_BUFFER_OBJECT: 231 case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR: 232 return devinfo->verx10 >= 75; 233 case PIPE_CAP_CULL_DISTANCE: 234 case PIPE_CAP_QUERY_PIPELINE_STATISTICS_SINGLE: 235 case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 236 case PIPE_CAP_SAMPLE_SHADING: 237 case PIPE_CAP_CUBE_MAP_ARRAY: 238 case PIPE_CAP_QUERY_SO_OVERFLOW: 239 case PIPE_CAP_TEXTURE_MULTISAMPLE: 240 case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: 241 case PIPE_CAP_QUERY_TIMESTAMP: 242 case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: 243 case PIPE_CAP_INDEP_BLEND_FUNC: 244 case PIPE_CAP_TEXTURE_SHADOW_LOD: 245 case PIPE_CAP_LOAD_CONSTBUF: 246 case PIPE_CAP_DRAW_PARAMETERS: 247 case PIPE_CAP_CLEAR_SCISSORED: 248 return devinfo->ver >= 6; 249 case PIPE_CAP_FBFETCH: 250 return devinfo->verx10 >= 45 ? BRW_MAX_DRAW_BUFFERS : 0; 251 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 252 /* in theory CL (965gm) can do this */ 253 return devinfo->verx10 >= 45 ? 1 : 0; 254 case PIPE_CAP_MAX_RENDER_TARGETS: 255 return BRW_MAX_DRAW_BUFFERS; 256 case PIPE_CAP_MAX_TEXTURE_2D_SIZE: 257 if (devinfo->ver >= 7) 258 return 16384; 259 else 260 return 8192; 261 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 262 if (devinfo->ver >= 7) 263 return CROCUS_MAX_MIPLEVELS; /* 16384x16384 */ 264 else 265 return CROCUS_MAX_MIPLEVELS - 1; /* 8192x8192 */ 266 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 267 return 12; /* 2048x2048 */ 268 case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 269 return (devinfo->ver >= 6) ? 4 : 0; 270 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 271 return devinfo->ver >= 7 ? 2048 : 512; 272 case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 273 return BRW_MAX_SOL_BINDINGS / CROCUS_MAX_SOL_BUFFERS; 274 case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 275 return BRW_MAX_SOL_BINDINGS; 276 case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY: 277 case PIPE_CAP_GLSL_FEATURE_LEVEL: { 278 if (devinfo->verx10 >= 75) 279 return 460; 280 else if (devinfo->ver >= 7) 281 return 420; 282 else if (devinfo->ver >= 6) 283 return 330; 284 return 140; 285 } 286 case PIPE_CAP_CLIP_PLANES: 287 if (devinfo->verx10 < 45) 288 return 6; 289 else 290 return 1; // defaults to MAX (8) 291 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 292 /* 3DSTATE_CONSTANT_XS requires the start of UBOs to be 32B aligned */ 293 return 32; 294 case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: 295 return CROCUS_MAP_BUFFER_ALIGNMENT; 296 case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT: 297 return devinfo->ver >= 7 ? 4 : 0; 298 case PIPE_CAP_MAX_SHADER_BUFFER_SIZE_UINT: 299 return devinfo->ver >= 7 ? (1 << 27) : 0; 300 case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: 301 return 16; // XXX: u_screen says 256 is the minimum value... 302 case PIPE_CAP_TEXTURE_TRANSFER_MODES: 303 return PIPE_TEXTURE_TRANSFER_BLIT; 304 case PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT: 305 return CROCUS_MAX_TEXTURE_BUFFER_SIZE; 306 case PIPE_CAP_MAX_VIEWPORTS: 307 return devinfo->ver >= 6 ? 16 : 1; 308 case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES: 309 return devinfo->ver >= 6 ? 256 : 0; 310 case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: 311 return devinfo->ver >= 6 ? 1024 : 0; 312 case PIPE_CAP_MAX_GS_INVOCATIONS: 313 return devinfo->ver >= 7 ? 32 : 1; 314 case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: 315 if (devinfo->ver >= 7) 316 return 4; 317 else if (devinfo->ver == 6) 318 return 1; 319 else 320 return 0; 321 case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET: 322 if (devinfo->ver >= 7) 323 return -32; 324 else if (devinfo->ver == 6) 325 return -8; 326 else 327 return 0; 328 case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: 329 if (devinfo->ver >= 7) 330 return 31; 331 else if (devinfo->ver == 6) 332 return 7; 333 else 334 return 0; 335 case PIPE_CAP_MAX_VERTEX_STREAMS: 336 return devinfo->ver >= 7 ? 4 : 1; 337 case PIPE_CAP_VENDOR_ID: 338 return 0x8086; 339 case PIPE_CAP_DEVICE_ID: 340 return screen->pci_id; 341 case PIPE_CAP_VIDEO_MEMORY: { 342 /* Once a batch uses more than 75% of the maximum mappable size, we 343 * assume that there's some fragmentation, and we start doing extra 344 * flushing, etc. That's the big cliff apps will care about. 345 */ 346 const unsigned gpu_mappable_megabytes = 347 (screen->aperture_threshold) / (1024 * 1024); 348 349 const long system_memory_pages = sysconf(_SC_PHYS_PAGES); 350 const long system_page_size = sysconf(_SC_PAGE_SIZE); 351 352 if (system_memory_pages <= 0 || system_page_size <= 0) 353 return -1; 354 355 const uint64_t system_memory_bytes = 356 (uint64_t) system_memory_pages * (uint64_t) system_page_size; 357 358 const unsigned system_memory_megabytes = 359 (unsigned) (system_memory_bytes / (1024 * 1024)); 360 361 return MIN2(system_memory_megabytes, gpu_mappable_megabytes); 362 } 363 case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS: 364 case PIPE_CAP_MAX_VARYINGS: 365 return (screen->devinfo.ver >= 6) ? 32 : 16; 366 case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: 367 /* AMD_pinned_memory assumes the flexibility of using client memory 368 * for any buffer (incl. vertex buffers) which rules out the prospect 369 * of using snooped buffers, as using snooped buffers without 370 * cogniscience is likely to be detrimental to performance and require 371 * extensive checking in the driver for correctness, e.g. to prevent 372 * illegal snoop <-> snoop transfers. 373 */ 374 return devinfo->has_llc; 375 case PIPE_CAP_THROTTLE: 376 return screen->driconf.disable_throttling ? 0 : 1; 377 378 case PIPE_CAP_CONTEXT_PRIORITY_MASK: 379 return PIPE_CONTEXT_PRIORITY_LOW | 380 PIPE_CONTEXT_PRIORITY_MEDIUM | 381 PIPE_CONTEXT_PRIORITY_HIGH; 382 383 case PIPE_CAP_FRONTEND_NOOP: 384 return true; 385 // XXX: don't hardcode 00:00:02.0 PCI here 386 case PIPE_CAP_PCI_GROUP: 387 return 0; 388 case PIPE_CAP_PCI_BUS: 389 return 0; 390 case PIPE_CAP_PCI_DEVICE: 391 return 2; 392 case PIPE_CAP_PCI_FUNCTION: 393 return 0; 394 395 case PIPE_CAP_HARDWARE_GL_SELECT: 396 return 0; 397 398 default: 399 return u_pipe_screen_get_param_defaults(pscreen, param); 400 } 401 return 0; 402} 403 404static float 405crocus_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) 406{ 407 struct crocus_screen *screen = (struct crocus_screen *)pscreen; 408 const struct intel_device_info *devinfo = &screen->devinfo; 409 410 switch (param) { 411 case PIPE_CAPF_MIN_LINE_WIDTH: 412 case PIPE_CAPF_MIN_LINE_WIDTH_AA: 413 case PIPE_CAPF_MIN_POINT_SIZE: 414 case PIPE_CAPF_MIN_POINT_SIZE_AA: 415 return 1; 416 417 case PIPE_CAPF_POINT_SIZE_GRANULARITY: 418 case PIPE_CAPF_LINE_WIDTH_GRANULARITY: 419 return 0.1; 420 421 case PIPE_CAPF_MAX_LINE_WIDTH: 422 case PIPE_CAPF_MAX_LINE_WIDTH_AA: 423 if (devinfo->ver >= 6) 424 return 7.375f; 425 else 426 return 7.0f; 427 428 case PIPE_CAPF_MAX_POINT_SIZE: 429 case PIPE_CAPF_MAX_POINT_SIZE_AA: 430 return 255.0f; 431 432 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 433 return 16.0f; 434 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 435 return 15.0f; 436 case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE: 437 case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE: 438 case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY: 439 return 0.0f; 440 default: 441 unreachable("unknown param"); 442 } 443} 444 445static int 446crocus_get_shader_param(struct pipe_screen *pscreen, 447 enum pipe_shader_type p_stage, 448 enum pipe_shader_cap param) 449{ 450 gl_shader_stage stage = stage_from_pipe(p_stage); 451 struct crocus_screen *screen = (struct crocus_screen *)pscreen; 452 const struct intel_device_info *devinfo = &screen->devinfo; 453 454 if (devinfo->ver < 6 && 455 p_stage != PIPE_SHADER_VERTEX && 456 p_stage != PIPE_SHADER_FRAGMENT) 457 return 0; 458 459 if (devinfo->ver == 6 && 460 p_stage != PIPE_SHADER_VERTEX && 461 p_stage != PIPE_SHADER_FRAGMENT && 462 p_stage != PIPE_SHADER_GEOMETRY) 463 return 0; 464 465 /* this is probably not totally correct.. but it's a start: */ 466 switch (param) { 467 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 468 return stage == MESA_SHADER_FRAGMENT ? 1024 : 16384; 469 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 470 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 471 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 472 return stage == MESA_SHADER_FRAGMENT ? 1024 : 0; 473 474 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 475 return UINT_MAX; 476 477 case PIPE_SHADER_CAP_MAX_INPUTS: 478 if (stage == MESA_SHADER_VERTEX || 479 stage == MESA_SHADER_GEOMETRY) 480 return 16; /* Gen7 vec4 geom backend */ 481 return 32; 482 case PIPE_SHADER_CAP_MAX_OUTPUTS: 483 return 32; 484 case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE: 485 return 16 * 1024 * sizeof(float); 486 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 487 return devinfo->ver >= 6 ? 16 : 1; 488 case PIPE_SHADER_CAP_MAX_TEMPS: 489 return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */ 490 case PIPE_SHADER_CAP_CONT_SUPPORTED: 491 return 0; 492 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 493 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 494 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 495 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 496 /* Lie about these to avoid st/mesa's GLSL IR lowering of indirects, 497 * which we don't want. Our compiler backend will check brw_compiler's 498 * options and call nir_lower_indirect_derefs appropriately anyway. 499 */ 500 return true; 501 case PIPE_SHADER_CAP_SUBROUTINES: 502 return 0; 503 case PIPE_SHADER_CAP_INTEGERS: 504 return 1; 505 case PIPE_SHADER_CAP_INT64_ATOMICS: 506 case PIPE_SHADER_CAP_FP16: 507 return 0; 508 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 509 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 510 return (devinfo->verx10 >= 75) ? CROCUS_MAX_TEXTURE_SAMPLERS : 16; 511 case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: 512 if (devinfo->ver >= 7 && 513 (p_stage == PIPE_SHADER_FRAGMENT || 514 p_stage == PIPE_SHADER_COMPUTE)) 515 return CROCUS_MAX_TEXTURE_SAMPLERS; 516 return 0; 517 case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: 518 return devinfo->ver >= 7 ? (CROCUS_MAX_ABOS + CROCUS_MAX_SSBOS) : 0; 519 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS: 520 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS: 521 return 0; 522 case PIPE_SHADER_CAP_PREFERRED_IR: 523 return PIPE_SHADER_IR_NIR; 524 case PIPE_SHADER_CAP_SUPPORTED_IRS: 525 return 1 << PIPE_SHADER_IR_NIR; 526 case PIPE_SHADER_CAP_DROUND_SUPPORTED: 527 case PIPE_SHADER_CAP_LDEXP_SUPPORTED: 528 return 1; 529 case PIPE_SHADER_CAP_DFRACEXP_DLDEXP_SUPPORTED: 530 case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: 531 case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: 532 case PIPE_SHADER_CAP_FP16_DERIVATIVES: 533 case PIPE_SHADER_CAP_INT16: 534 case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS: 535 case PIPE_SHADER_CAP_FP16_CONST_BUFFERS: 536 return 0; 537 default: 538 unreachable("unknown shader param"); 539 } 540} 541 542static int 543crocus_get_compute_param(struct pipe_screen *pscreen, 544 enum pipe_shader_ir ir_type, 545 enum pipe_compute_cap param, 546 void *ret) 547{ 548 struct crocus_screen *screen = (struct crocus_screen *)pscreen; 549 const struct intel_device_info *devinfo = &screen->devinfo; 550 551 const uint32_t max_invocations = 32 * devinfo->max_cs_workgroup_threads; 552 553 if (devinfo->ver < 7) 554 return 0; 555#define RET(x) do { \ 556 if (ret) \ 557 memcpy(ret, x, sizeof(x)); \ 558 return sizeof(x); \ 559} while (0) 560 561 switch (param) { 562 case PIPE_COMPUTE_CAP_ADDRESS_BITS: 563 RET((uint32_t []){ 32 }); 564 565 case PIPE_COMPUTE_CAP_IR_TARGET: 566 if (ret) 567 strcpy(ret, "gen"); 568 return 4; 569 570 case PIPE_COMPUTE_CAP_GRID_DIMENSION: 571 RET((uint64_t []) { 3 }); 572 573 case PIPE_COMPUTE_CAP_MAX_GRID_SIZE: 574 RET(((uint64_t []) { 65535, 65535, 65535 })); 575 576 case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE: 577 /* MaxComputeWorkGroupSize[0..2] */ 578 RET(((uint64_t []) {max_invocations, max_invocations, max_invocations})); 579 580 case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK: 581 /* MaxComputeWorkGroupInvocations */ 582 RET((uint64_t []) { max_invocations }); 583 584 case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE: 585 /* MaxComputeSharedMemorySize */ 586 RET((uint64_t []) { 64 * 1024 }); 587 588 case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED: 589 RET((uint32_t []) { 1 }); 590 591 case PIPE_COMPUTE_CAP_SUBGROUP_SIZE: 592 RET((uint32_t []) { BRW_SUBGROUP_SIZE }); 593 594 case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK: 595 RET((uint64_t []) { max_invocations }); 596 597 case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE: 598 case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY: 599 case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS: 600 case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE: 601 case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE: 602 case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE: 603 604 // XXX: I think these are for Clover... 605 return 0; 606 607 default: 608 unreachable("unknown compute param"); 609 } 610} 611 612static uint64_t 613crocus_get_timestamp(struct pipe_screen *pscreen) 614{ 615 struct crocus_screen *screen = (struct crocus_screen *) pscreen; 616 const unsigned TIMESTAMP = 0x2358; 617 uint64_t result; 618 619 crocus_reg_read(screen->bufmgr, TIMESTAMP | 1, &result); 620 621 result = intel_device_info_timebase_scale(&screen->devinfo, result); 622 result &= (1ull << TIMESTAMP_BITS) - 1; 623 624 return result; 625} 626 627void 628crocus_screen_destroy(struct crocus_screen *screen) 629{ 630 u_transfer_helper_destroy(screen->base.transfer_helper); 631 crocus_bufmgr_unref(screen->bufmgr); 632 disk_cache_destroy(screen->disk_cache); 633 close(screen->winsys_fd); 634 ralloc_free(screen); 635} 636 637static void 638crocus_screen_unref(struct pipe_screen *pscreen) 639{ 640 crocus_pscreen_unref(pscreen); 641} 642 643static void 644crocus_query_memory_info(struct pipe_screen *pscreen, 645 struct pipe_memory_info *info) 646{ 647} 648 649static const void * 650crocus_get_compiler_options(struct pipe_screen *pscreen, 651 enum pipe_shader_ir ir, 652 enum pipe_shader_type pstage) 653{ 654 struct crocus_screen *screen = (struct crocus_screen *) pscreen; 655 gl_shader_stage stage = stage_from_pipe(pstage); 656 assert(ir == PIPE_SHADER_IR_NIR); 657 658 return screen->compiler->nir_options[stage]; 659} 660 661static struct disk_cache * 662crocus_get_disk_shader_cache(struct pipe_screen *pscreen) 663{ 664 struct crocus_screen *screen = (struct crocus_screen *) pscreen; 665 return screen->disk_cache; 666} 667 668static const struct intel_l3_config * 669crocus_get_default_l3_config(const struct intel_device_info *devinfo, 670 bool compute) 671{ 672 bool wants_dc_cache = true; 673 bool has_slm = compute; 674 const struct intel_l3_weights w = 675 intel_get_default_l3_weights(devinfo, wants_dc_cache, has_slm); 676 return intel_get_l3_config(devinfo, w); 677} 678 679static void 680crocus_shader_debug_log(void *data, unsigned *id, const char *fmt, ...) 681{ 682 struct util_debug_callback *dbg = data; 683 va_list args; 684 685 if (!dbg->debug_message) 686 return; 687 688 va_start(args, fmt); 689 dbg->debug_message(dbg->data, id, UTIL_DEBUG_TYPE_SHADER_INFO, fmt, args); 690 va_end(args); 691} 692 693static void 694crocus_shader_perf_log(void *data, unsigned *id, const char *fmt, ...) 695{ 696 struct util_debug_callback *dbg = data; 697 va_list args; 698 va_start(args, fmt); 699 700 if (INTEL_DEBUG(DEBUG_PERF)) { 701 va_list args_copy; 702 va_copy(args_copy, args); 703 vfprintf(stderr, fmt, args_copy); 704 va_end(args_copy); 705 } 706 707 if (dbg->debug_message) { 708 dbg->debug_message(dbg->data, id, UTIL_DEBUG_TYPE_PERF_INFO, fmt, args); 709 } 710 711 va_end(args); 712} 713 714struct pipe_screen * 715crocus_screen_create(int fd, const struct pipe_screen_config *config) 716{ 717 struct crocus_screen *screen = rzalloc(NULL, struct crocus_screen); 718 if (!screen) 719 return NULL; 720 721 if (!intel_get_device_info_from_fd(fd, &screen->devinfo)) 722 return NULL; 723 screen->pci_id = screen->devinfo.pci_device_id; 724 725 if (screen->devinfo.ver > 8) 726 return NULL; 727 728 if (screen->devinfo.ver == 8) { 729 /* bind to cherryview or bdw if forced */ 730 if (screen->devinfo.platform != INTEL_PLATFORM_CHV && 731 !getenv("CROCUS_GEN8")) 732 return NULL; 733 } 734 735 p_atomic_set(&screen->refcount, 1); 736 737 screen->aperture_bytes = get_aperture_size(fd); 738 screen->aperture_threshold = screen->aperture_bytes * 3 / 4; 739 740 driParseConfigFiles(config->options, config->options_info, 0, "crocus", 741 NULL, NULL, NULL, 0, NULL, 0); 742 743 bool bo_reuse = false; 744 int bo_reuse_mode = driQueryOptioni(config->options, "bo_reuse"); 745 switch (bo_reuse_mode) { 746 case DRI_CONF_BO_REUSE_DISABLED: 747 break; 748 case DRI_CONF_BO_REUSE_ALL: 749 bo_reuse = true; 750 break; 751 } 752 753 screen->bufmgr = crocus_bufmgr_get_for_fd(&screen->devinfo, fd, bo_reuse); 754 if (!screen->bufmgr) 755 return NULL; 756 screen->fd = crocus_bufmgr_get_fd(screen->bufmgr); 757 screen->winsys_fd = fd; 758 759 brw_process_intel_debug_variable(); 760 761 screen->driconf.dual_color_blend_by_location = 762 driQueryOptionb(config->options, "dual_color_blend_by_location"); 763 screen->driconf.disable_throttling = 764 driQueryOptionb(config->options, "disable_throttling"); 765 screen->driconf.always_flush_cache = 766 driQueryOptionb(config->options, "always_flush_cache"); 767 screen->driconf.limit_trig_input_range = 768 driQueryOptionb(config->options, "limit_trig_input_range"); 769 770 screen->precompile = env_var_as_boolean("shader_precompile", true); 771 772 isl_device_init(&screen->isl_dev, &screen->devinfo); 773 774 screen->compiler = brw_compiler_create(screen, &screen->devinfo); 775 screen->compiler->shader_debug_log = crocus_shader_debug_log; 776 screen->compiler->shader_perf_log = crocus_shader_perf_log; 777 screen->compiler->supports_shader_constants = false; 778 screen->compiler->constant_buffer_0_is_relative = true; 779 780 if (screen->devinfo.ver >= 7) { 781 screen->l3_config_3d = crocus_get_default_l3_config(&screen->devinfo, false); 782 screen->l3_config_cs = crocus_get_default_l3_config(&screen->devinfo, true); 783 } 784 785 crocus_disk_cache_init(screen); 786 787 slab_create_parent(&screen->transfer_pool, 788 sizeof(struct crocus_transfer), 64); 789 790 struct pipe_screen *pscreen = &screen->base; 791 792 crocus_init_screen_fence_functions(pscreen); 793 crocus_init_screen_resource_functions(pscreen); 794 795 pscreen->destroy = crocus_screen_unref; 796 pscreen->get_name = crocus_get_name; 797 pscreen->get_vendor = crocus_get_vendor; 798 pscreen->get_device_vendor = crocus_get_device_vendor; 799 pscreen->get_param = crocus_get_param; 800 pscreen->get_shader_param = crocus_get_shader_param; 801 pscreen->get_compute_param = crocus_get_compute_param; 802 pscreen->get_paramf = crocus_get_paramf; 803 pscreen->get_compiler_options = crocus_get_compiler_options; 804 pscreen->get_device_uuid = crocus_get_device_uuid; 805 pscreen->get_driver_uuid = crocus_get_driver_uuid; 806 pscreen->get_disk_shader_cache = crocus_get_disk_shader_cache; 807 pscreen->is_format_supported = crocus_is_format_supported; 808 pscreen->context_create = crocus_create_context; 809 pscreen->get_timestamp = crocus_get_timestamp; 810 pscreen->query_memory_info = crocus_query_memory_info; 811 pscreen->get_driver_query_group_info = crocus_get_monitor_group_info; 812 pscreen->get_driver_query_info = crocus_get_monitor_info; 813 814 genX_call(&screen->devinfo, crocus_init_screen_state, screen); 815 genX_call(&screen->devinfo, crocus_init_screen_query, screen); 816 return pscreen; 817} 818