1/* 2 * Copyright © 2014-2017 Broadcom 3 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 */ 24 25#include <sys/sysinfo.h> 26 27#include "common/v3d_device_info.h" 28#include "common/v3d_limits.h" 29#include "util/os_misc.h" 30#include "pipe/p_defines.h" 31#include "pipe/p_screen.h" 32#include "pipe/p_state.h" 33 34#include "util/u_debug.h" 35#include "util/u_memory.h" 36#include "util/format/u_format.h" 37#include "util/u_hash_table.h" 38#include "util/u_screen.h" 39#include "util/u_transfer_helper.h" 40#include "util/ralloc.h" 41#include "util/xmlconfig.h" 42 43#include <xf86drm.h> 44#include "v3d_screen.h" 45#include "v3d_context.h" 46#include "v3d_resource.h" 47#include "compiler/v3d_compiler.h" 48#include "drm-uapi/drm_fourcc.h" 49 50static const char * 51v3d_screen_get_name(struct pipe_screen *pscreen) 52{ 53 struct v3d_screen *screen = v3d_screen(pscreen); 54 55 if (!screen->name) { 56 screen->name = ralloc_asprintf(screen, 57 "V3D %d.%d", 58 screen->devinfo.ver / 10, 59 screen->devinfo.ver % 10); 60 } 61 62 return screen->name; 63} 64 65static const char * 66v3d_screen_get_vendor(struct pipe_screen *pscreen) 67{ 68 return "Broadcom"; 69} 70 71static void 72v3d_screen_destroy(struct pipe_screen *pscreen) 73{ 74 struct v3d_screen *screen = v3d_screen(pscreen); 75 76 _mesa_hash_table_destroy(screen->bo_handles, NULL); 77 v3d_bufmgr_destroy(pscreen); 78 slab_destroy_parent(&screen->transfer_pool); 79 if (screen->ro) 80 screen->ro->destroy(screen->ro); 81 82 if (using_v3d_simulator) 83 v3d_simulator_destroy(screen->sim_file); 84 85 v3d_compiler_free(screen->compiler); 86 87#ifdef ENABLE_SHADER_CACHE 88 if (screen->disk_cache) 89 disk_cache_destroy(screen->disk_cache); 90#endif 91 92 u_transfer_helper_destroy(pscreen->transfer_helper); 93 94 close(screen->fd); 95 ralloc_free(pscreen); 96} 97 98static bool 99v3d_has_feature(struct v3d_screen *screen, enum drm_v3d_param feature) 100{ 101 struct drm_v3d_get_param p = { 102 .param = feature, 103 }; 104 int ret = v3d_ioctl(screen->fd, DRM_IOCTL_V3D_GET_PARAM, &p); 105 106 if (ret != 0) 107 return false; 108 109 return p.value; 110} 111 112static int 113v3d_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 114{ 115 struct v3d_screen *screen = v3d_screen(pscreen); 116 117 switch (param) { 118 /* Supported features (boolean caps). */ 119 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 120 case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: 121 case PIPE_CAP_NPOT_TEXTURES: 122 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 123 case PIPE_CAP_TEXTURE_MULTISAMPLE: 124 case PIPE_CAP_TEXTURE_SWIZZLE: 125 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 126 case PIPE_CAP_START_INSTANCE: 127 case PIPE_CAP_VS_INSTANCEID: 128 case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD: 129 case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES: 130 case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX: 131 case PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART: 132 case PIPE_CAP_PRIMITIVE_RESTART: 133 case PIPE_CAP_OCCLUSION_QUERY: 134 case PIPE_CAP_POINT_SPRITE: 135 case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 136 case PIPE_CAP_DRAW_INDIRECT: 137 case PIPE_CAP_MULTI_DRAW_INDIRECT: 138 case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 139 case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET: 140 case PIPE_CAP_SHADER_CAN_READ_OUTPUTS: 141 case PIPE_CAP_SHADER_PACK_HALF_FLOAT: 142 case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR: 143 case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT: 144 case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL: 145 case PIPE_CAP_TGSI_TEXCOORD: 146 case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE: 147 case PIPE_CAP_SAMPLER_VIEW_TARGET: 148 case PIPE_CAP_ANISOTROPIC_FILTER: 149 case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS: 150 case PIPE_CAP_INDEP_BLEND_FUNC: 151 return 1; 152 153 case PIPE_CAP_POLYGON_OFFSET_CLAMP: 154 return screen->devinfo.ver >= 41; 155 156 case PIPE_CAP_TEXTURE_QUERY_LOD: 157 return screen->devinfo.ver >= 42; 158 break; 159 160 case PIPE_CAP_PACKED_UNIFORMS: 161 /* We can't enable this flag, because it results in load_ubo 162 * intrinsics across a 16b boundary, but v3d's TMU general 163 * memory accesses wrap on 16b boundaries. 164 */ 165 return 0; 166 167 case PIPE_CAP_NIR_IMAGES_AS_DEREF: 168 return 0; 169 170 case PIPE_CAP_TEXTURE_TRANSFER_MODES: 171 /* XXX perf: we don't want to emit these extra blits for 172 * glReadPixels(), since we still have to do an uncached read 173 * from the GPU of the result after waiting for the TFU blit 174 * to happen. However, disabling this introduces instability 175 * in 176 * dEQP-GLES31.functional.image_load_store.early_fragment_tests.* 177 * and corruption in chromium's rendering. 178 */ 179 return PIPE_TEXTURE_TRANSFER_BLIT; 180 181 case PIPE_CAP_COMPUTE: 182 return screen->has_csd && screen->devinfo.ver >= 41; 183 184 case PIPE_CAP_GENERATE_MIPMAP: 185 return v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_TFU); 186 187 case PIPE_CAP_INDEP_BLEND_ENABLE: 188 return screen->devinfo.ver >= 40; 189 190 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 191 return V3D_NON_COHERENT_ATOM_SIZE; 192 193 case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: 194 if (screen->devinfo.ver < 40) 195 return 0; 196 return 4; 197 198 case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT: 199 if (screen->has_cache_flush) 200 return 4; 201 else 202 return 0; /* Disables shader storage */ 203 204 case PIPE_CAP_GLSL_FEATURE_LEVEL: 205 return 330; 206 207 case PIPE_CAP_ESSL_FEATURE_LEVEL: 208 return 310; 209 210 case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY: 211 return 140; 212 213 case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT: 214 return 1; 215 case PIPE_CAP_FS_COORD_ORIGIN_LOWER_LEFT: 216 return 0; 217 case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER: 218 if (screen->devinfo.ver >= 40) 219 return 0; 220 else 221 return 1; 222 case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 223 if (screen->devinfo.ver >= 40) 224 return 1; 225 else 226 return 0; 227 228 case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: 229 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 230 case PIPE_CAP_MIXED_COLOR_DEPTH_BITS: 231 return 1; 232 233 case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 234 return 4; 235 236 case PIPE_CAP_MAX_VARYINGS: 237 return V3D_MAX_FS_INPUTS / 4; 238 239 /* Texturing. */ 240 case PIPE_CAP_MAX_TEXTURE_2D_SIZE: 241 if (screen->devinfo.ver < 40) 242 return 2048; 243 else if (screen->nonmsaa_texture_size_limit) 244 return 7680; 245 else 246 return V3D_MAX_IMAGE_DIMENSION; 247 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 248 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 249 if (screen->devinfo.ver < 40) 250 return 12; 251 else 252 return V3D_MAX_MIP_LEVELS; 253 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 254 return V3D_MAX_ARRAY_LAYERS; 255 256 /* Render targets. */ 257 case PIPE_CAP_MAX_RENDER_TARGETS: 258 return 4; 259 260 case PIPE_CAP_VENDOR_ID: 261 return 0x14E4; 262 case PIPE_CAP_ACCELERATED: 263 return 1; 264 case PIPE_CAP_VIDEO_MEMORY: { 265 uint64_t system_memory; 266 267 if (!os_get_total_physical_memory(&system_memory)) 268 return 0; 269 270 return (int)(system_memory >> 20); 271 } 272 case PIPE_CAP_UMA: 273 return 1; 274 275 case PIPE_CAP_ALPHA_TEST: 276 case PIPE_CAP_FLATSHADE: 277 case PIPE_CAP_TWO_SIDED_COLOR: 278 case PIPE_CAP_VERTEX_COLOR_CLAMPED: 279 case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: 280 case PIPE_CAP_GL_CLAMP: 281 return 0; 282 283 /* Geometry shaders */ 284 case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: 285 /* Minimum required by GLES 3.2 */ 286 return 1024; 287 case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES: 288 /* MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS / 4 */ 289 return 256; 290 case PIPE_CAP_MAX_GS_INVOCATIONS: 291 return 32; 292 293 case PIPE_CAP_SUPPORTED_PRIM_MODES: 294 case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART: 295 return screen->prim_types; 296 297 case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: 298 return true; 299 300 case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: 301 return 256; 302 303 case PIPE_CAP_IMAGE_STORE_FORMATTED: 304 return false; 305 306 default: 307 return u_pipe_screen_get_param_defaults(pscreen, param); 308 } 309} 310 311static float 312v3d_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) 313{ 314 switch (param) { 315 case PIPE_CAPF_MIN_LINE_WIDTH: 316 case PIPE_CAPF_MIN_LINE_WIDTH_AA: 317 case PIPE_CAPF_MIN_POINT_SIZE: 318 case PIPE_CAPF_MIN_POINT_SIZE_AA: 319 return 1; 320 321 case PIPE_CAPF_POINT_SIZE_GRANULARITY: 322 case PIPE_CAPF_LINE_WIDTH_GRANULARITY: 323 return 0.1; 324 325 case PIPE_CAPF_MAX_LINE_WIDTH: 326 case PIPE_CAPF_MAX_LINE_WIDTH_AA: 327 return V3D_MAX_LINE_WIDTH; 328 329 case PIPE_CAPF_MAX_POINT_SIZE: 330 case PIPE_CAPF_MAX_POINT_SIZE_AA: 331 return V3D_MAX_POINT_SIZE; 332 333 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 334 return 16.0f; 335 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 336 return 16.0f; 337 338 case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE: 339 case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE: 340 case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY: 341 return 0.0f; 342 default: 343 fprintf(stderr, "unknown paramf %d\n", param); 344 return 0; 345 } 346} 347 348static int 349v3d_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, 350 enum pipe_shader_cap param) 351{ 352 struct v3d_screen *screen = v3d_screen(pscreen); 353 354 switch (shader) { 355 case PIPE_SHADER_VERTEX: 356 case PIPE_SHADER_FRAGMENT: 357 break; 358 case PIPE_SHADER_COMPUTE: 359 if (!screen->has_csd) 360 return 0; 361 break; 362 case PIPE_SHADER_GEOMETRY: 363 if (screen->devinfo.ver < 41) 364 return 0; 365 break; 366 default: 367 return 0; 368 } 369 370 /* this is probably not totally correct.. but it's a start: */ 371 switch (param) { 372 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 373 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 374 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 375 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 376 return 16384; 377 378 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 379 return UINT_MAX; 380 381 case PIPE_SHADER_CAP_MAX_INPUTS: 382 switch (shader) { 383 case PIPE_SHADER_VERTEX: 384 return V3D_MAX_VS_INPUTS / 4; 385 case PIPE_SHADER_GEOMETRY: 386 return V3D_MAX_GS_INPUTS / 4; 387 case PIPE_SHADER_FRAGMENT: 388 return V3D_MAX_FS_INPUTS / 4; 389 default: 390 return 0; 391 }; 392 case PIPE_SHADER_CAP_MAX_OUTPUTS: 393 if (shader == PIPE_SHADER_FRAGMENT) 394 return 4; 395 else 396 return V3D_MAX_FS_INPUTS / 4; 397 case PIPE_SHADER_CAP_MAX_TEMPS: 398 return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */ 399 case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE: 400 /* Note: Limited by the offset size in 401 * v3d_unit_data_create(). 402 */ 403 return 16 * 1024 * sizeof(float); 404 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 405 return 16; 406 case PIPE_SHADER_CAP_CONT_SUPPORTED: 407 return 0; 408 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 409 /* We don't currently support this in the backend, but that is 410 * okay because our NIR compiler sets the option 411 * lower_all_io_to_temps, which will eliminate indirect 412 * indexing on all input/output variables by translating it to 413 * indirect indexing on temporary variables instead, which we 414 * will then lower to scratch. We prefer this over setting this 415 * to 0, which would cause if-ladder injection to eliminate 416 * indirect indexing on inputs. 417 */ 418 return 1; 419 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 420 return 1; 421 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 422 return 1; 423 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 424 return 1; 425 case PIPE_SHADER_CAP_SUBROUTINES: 426 return 0; 427 case PIPE_SHADER_CAP_INTEGERS: 428 return 1; 429 case PIPE_SHADER_CAP_FP16: 430 case PIPE_SHADER_CAP_FP16_DERIVATIVES: 431 case PIPE_SHADER_CAP_FP16_CONST_BUFFERS: 432 case PIPE_SHADER_CAP_INT16: 433 case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS: 434 case PIPE_SHADER_CAP_DROUND_SUPPORTED: 435 case PIPE_SHADER_CAP_DFRACEXP_DLDEXP_SUPPORTED: 436 case PIPE_SHADER_CAP_LDEXP_SUPPORTED: 437 case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: 438 case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: 439 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS: 440 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS: 441 return 0; 442 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 443 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 444 return V3D_MAX_TEXTURE_SAMPLERS; 445 446 case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: 447 if (screen->has_cache_flush) { 448 if (shader == PIPE_SHADER_VERTEX || 449 shader == PIPE_SHADER_GEOMETRY) { 450 return 0; 451 } 452 return PIPE_MAX_SHADER_BUFFERS; 453 } else { 454 return 0; 455 } 456 457 case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: 458 if (screen->has_cache_flush) { 459 if (screen->devinfo.ver < 41) 460 return 0; 461 else 462 return PIPE_MAX_SHADER_IMAGES; 463 } else { 464 return 0; 465 } 466 467 case PIPE_SHADER_CAP_PREFERRED_IR: 468 return PIPE_SHADER_IR_NIR; 469 case PIPE_SHADER_CAP_SUPPORTED_IRS: 470 return 1 << PIPE_SHADER_IR_NIR; 471 default: 472 fprintf(stderr, "unknown shader param %d\n", param); 473 return 0; 474 } 475 return 0; 476} 477 478static int 479v3d_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type, 480 enum pipe_compute_cap param, void *ret) 481{ 482 struct v3d_screen *screen = v3d_screen(pscreen); 483 484 if (!screen->has_csd) 485 return 0; 486 487#define RET(x) do { \ 488 if (ret) \ 489 memcpy(ret, x, sizeof(x)); \ 490 return sizeof(x); \ 491 } while (0) 492 493 switch (param) { 494 case PIPE_COMPUTE_CAP_ADDRESS_BITS: 495 RET((uint32_t []) { 32 }); 496 break; 497 498 case PIPE_COMPUTE_CAP_IR_TARGET: 499 sprintf(ret, "v3d"); 500 return strlen(ret); 501 502 case PIPE_COMPUTE_CAP_GRID_DIMENSION: 503 RET((uint64_t []) { 3 }); 504 505 case PIPE_COMPUTE_CAP_MAX_GRID_SIZE: 506 /* GL_MAX_COMPUTE_SHADER_WORK_GROUP_COUNT: The CSD has a 507 * 16-bit field for the number of workgroups in each 508 * dimension. 509 */ 510 RET(((uint64_t []) { 65535, 65535, 65535 })); 511 512 case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE: 513 /* GL_MAX_COMPUTE_WORK_GROUP_SIZE */ 514 RET(((uint64_t []) { 256, 256, 256 })); 515 516 case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK: 517 case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK: 518 /* GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: This is 519 * limited by WG_SIZE in the CSD. 520 */ 521 RET((uint64_t []) { 256 }); 522 523 case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE: 524 RET((uint64_t []) { 1024 * 1024 * 1024 }); 525 526 case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE: 527 /* GL_MAX_COMPUTE_SHARED_MEMORY_SIZE */ 528 RET((uint64_t []) { 32768 }); 529 530 case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE: 531 case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE: 532 RET((uint64_t []) { 4096 }); 533 534 case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE: { 535 struct sysinfo si; 536 sysinfo(&si); 537 RET((uint64_t []) { si.totalram }); 538 } 539 540 case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY: 541 /* OpenCL only */ 542 RET((uint32_t []) { 0 }); 543 544 case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS: 545 RET((uint32_t []) { 1 }); 546 547 case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED: 548 RET((uint32_t []) { 1 }); 549 550 case PIPE_COMPUTE_CAP_SUBGROUP_SIZE: 551 RET((uint32_t []) { 16 }); 552 553 } 554 555 return 0; 556} 557 558static bool 559v3d_screen_is_format_supported(struct pipe_screen *pscreen, 560 enum pipe_format format, 561 enum pipe_texture_target target, 562 unsigned sample_count, 563 unsigned storage_sample_count, 564 unsigned usage) 565{ 566 struct v3d_screen *screen = v3d_screen(pscreen); 567 568 if (MAX2(1, sample_count) != MAX2(1, storage_sample_count)) 569 return false; 570 571 if (sample_count > 1 && sample_count != V3D_MAX_SAMPLES) 572 return false; 573 574 if (target >= PIPE_MAX_TEXTURE_TYPES) { 575 return false; 576 } 577 578 if (usage & PIPE_BIND_VERTEX_BUFFER) { 579 switch (format) { 580 case PIPE_FORMAT_R32G32B32A32_FLOAT: 581 case PIPE_FORMAT_R32G32B32_FLOAT: 582 case PIPE_FORMAT_R32G32_FLOAT: 583 case PIPE_FORMAT_R32_FLOAT: 584 case PIPE_FORMAT_R32G32B32A32_SNORM: 585 case PIPE_FORMAT_R32G32B32_SNORM: 586 case PIPE_FORMAT_R32G32_SNORM: 587 case PIPE_FORMAT_R32_SNORM: 588 case PIPE_FORMAT_R32G32B32A32_SSCALED: 589 case PIPE_FORMAT_R32G32B32_SSCALED: 590 case PIPE_FORMAT_R32G32_SSCALED: 591 case PIPE_FORMAT_R32_SSCALED: 592 case PIPE_FORMAT_R16G16B16A16_UNORM: 593 case PIPE_FORMAT_R16G16B16_UNORM: 594 case PIPE_FORMAT_R16G16_UNORM: 595 case PIPE_FORMAT_R16_UNORM: 596 case PIPE_FORMAT_R16G16B16A16_SNORM: 597 case PIPE_FORMAT_R16G16B16_SNORM: 598 case PIPE_FORMAT_R16G16_SNORM: 599 case PIPE_FORMAT_R16_SNORM: 600 case PIPE_FORMAT_R16G16B16A16_USCALED: 601 case PIPE_FORMAT_R16G16B16_USCALED: 602 case PIPE_FORMAT_R16G16_USCALED: 603 case PIPE_FORMAT_R16_USCALED: 604 case PIPE_FORMAT_R16G16B16A16_SSCALED: 605 case PIPE_FORMAT_R16G16B16_SSCALED: 606 case PIPE_FORMAT_R16G16_SSCALED: 607 case PIPE_FORMAT_R16_SSCALED: 608 case PIPE_FORMAT_B8G8R8A8_UNORM: 609 case PIPE_FORMAT_R8G8B8A8_UNORM: 610 case PIPE_FORMAT_R8G8B8_UNORM: 611 case PIPE_FORMAT_R8G8_UNORM: 612 case PIPE_FORMAT_R8_UNORM: 613 case PIPE_FORMAT_R8G8B8A8_SNORM: 614 case PIPE_FORMAT_R8G8B8_SNORM: 615 case PIPE_FORMAT_R8G8_SNORM: 616 case PIPE_FORMAT_R8_SNORM: 617 case PIPE_FORMAT_R8G8B8A8_USCALED: 618 case PIPE_FORMAT_R8G8B8_USCALED: 619 case PIPE_FORMAT_R8G8_USCALED: 620 case PIPE_FORMAT_R8_USCALED: 621 case PIPE_FORMAT_R8G8B8A8_SSCALED: 622 case PIPE_FORMAT_R8G8B8_SSCALED: 623 case PIPE_FORMAT_R8G8_SSCALED: 624 case PIPE_FORMAT_R8_SSCALED: 625 case PIPE_FORMAT_R10G10B10A2_UNORM: 626 case PIPE_FORMAT_B10G10R10A2_UNORM: 627 case PIPE_FORMAT_R10G10B10A2_SNORM: 628 case PIPE_FORMAT_B10G10R10A2_SNORM: 629 case PIPE_FORMAT_R10G10B10A2_USCALED: 630 case PIPE_FORMAT_B10G10R10A2_USCALED: 631 case PIPE_FORMAT_R10G10B10A2_SSCALED: 632 case PIPE_FORMAT_B10G10R10A2_SSCALED: 633 break; 634 default: 635 return false; 636 } 637 } 638 639 /* FORMAT_NONE gets allowed for ARB_framebuffer_no_attachments's probe 640 * of FRAMEBUFFER_MAX_SAMPLES 641 */ 642 if ((usage & PIPE_BIND_RENDER_TARGET) && 643 format != PIPE_FORMAT_NONE && 644 !v3d_rt_format_supported(&screen->devinfo, format)) { 645 return false; 646 } 647 648 if ((usage & PIPE_BIND_SAMPLER_VIEW) && 649 !v3d_tex_format_supported(&screen->devinfo, format)) { 650 return false; 651 } 652 653 if ((usage & PIPE_BIND_DEPTH_STENCIL) && 654 !(format == PIPE_FORMAT_S8_UINT_Z24_UNORM || 655 format == PIPE_FORMAT_X8Z24_UNORM || 656 format == PIPE_FORMAT_Z16_UNORM || 657 format == PIPE_FORMAT_Z32_FLOAT || 658 format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)) { 659 return false; 660 } 661 662 if ((usage & PIPE_BIND_INDEX_BUFFER) && 663 !(format == PIPE_FORMAT_R8_UINT || 664 format == PIPE_FORMAT_R16_UINT || 665 format == PIPE_FORMAT_R32_UINT)) { 666 return false; 667 } 668 669 if (usage & PIPE_BIND_SHADER_IMAGE) { 670 switch (format) { 671 /* FIXME: maybe we can implement a swizzle-on-writes to add 672 * support for BGRA-alike formats. 673 */ 674 case PIPE_FORMAT_A4B4G4R4_UNORM: 675 case PIPE_FORMAT_A1B5G5R5_UNORM: 676 case PIPE_FORMAT_B5G6R5_UNORM: 677 case PIPE_FORMAT_B8G8R8A8_UNORM: 678 case PIPE_FORMAT_X8Z24_UNORM: 679 case PIPE_FORMAT_Z16_UNORM: 680 return false; 681 default: 682 return true; 683 } 684 } 685 686 return true; 687} 688 689static const nir_shader_compiler_options v3d_nir_options = { 690 .lower_uadd_sat = true, 691 .lower_usub_sat = true, 692 .lower_iadd_sat = true, 693 .lower_all_io_to_temps = true, 694 .lower_extract_byte = true, 695 .lower_extract_word = true, 696 .lower_insert_byte = true, 697 .lower_insert_word = true, 698 .lower_bitfield_insert_to_shifts = true, 699 .lower_bitfield_extract_to_shifts = true, 700 .lower_bitfield_reverse = true, 701 .lower_bit_count = true, 702 .lower_cs_local_id_to_index = true, 703 .lower_ffract = true, 704 .lower_fmod = true, 705 .lower_pack_unorm_2x16 = true, 706 .lower_pack_snorm_2x16 = true, 707 .lower_pack_unorm_4x8 = true, 708 .lower_pack_snorm_4x8 = true, 709 .lower_unpack_unorm_4x8 = true, 710 .lower_unpack_snorm_4x8 = true, 711 .lower_pack_half_2x16 = true, 712 .lower_unpack_half_2x16 = true, 713 .lower_pack_32_2x16 = true, 714 .lower_pack_32_2x16_split = true, 715 .lower_unpack_32_2x16_split = true, 716 .lower_fdiv = true, 717 .lower_find_lsb = true, 718 .lower_ffma16 = true, 719 .lower_ffma32 = true, 720 .lower_ffma64 = true, 721 .lower_flrp32 = true, 722 .lower_fpow = true, 723 .lower_fsat = true, 724 .lower_fsqrt = true, 725 .lower_ifind_msb = true, 726 .lower_isign = true, 727 .lower_ldexp = true, 728 .lower_mul_high = true, 729 .lower_wpos_pntc = true, 730 .lower_rotate = true, 731 .lower_to_scalar = true, 732 .lower_int64_options = nir_lower_imul_2x32_64, 733 .has_fsub = true, 734 .has_isub = true, 735 .divergence_analysis_options = 736 nir_divergence_multiple_workgroup_per_compute_subgroup, 737 /* This will enable loop unrolling in the state tracker so we won't 738 * be able to selectively disable it in backend if it leads to 739 * lower thread counts or TMU spills. Choose a conservative maximum to 740 * limit register pressure impact. 741 */ 742 .max_unroll_iterations = 16, 743 .force_indirect_unrolling_sampler = true, 744}; 745 746static const void * 747v3d_screen_get_compiler_options(struct pipe_screen *pscreen, 748 enum pipe_shader_ir ir, unsigned shader) 749{ 750 return &v3d_nir_options; 751} 752 753static const uint64_t v3d_available_modifiers[] = { 754 DRM_FORMAT_MOD_BROADCOM_UIF, 755 DRM_FORMAT_MOD_LINEAR, 756 DRM_FORMAT_MOD_BROADCOM_SAND128, 757}; 758 759static void 760v3d_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, 761 enum pipe_format format, int max, 762 uint64_t *modifiers, 763 unsigned int *external_only, 764 int *count) 765{ 766 int i; 767 int num_modifiers = ARRAY_SIZE(v3d_available_modifiers); 768 769 /* Expose DRM_FORMAT_MOD_BROADCOM_SAND128 only for PIPE_FORMAT_NV12 */ 770 if (format != PIPE_FORMAT_NV12) 771 num_modifiers--; 772 773 if (!modifiers) { 774 *count = num_modifiers; 775 return; 776 } 777 778 *count = MIN2(max, num_modifiers); 779 for (i = 0; i < *count; i++) { 780 modifiers[i] = v3d_available_modifiers[i]; 781 if (external_only) 782 external_only[i] = util_format_is_yuv(format); 783 } 784} 785 786static bool 787v3d_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, 788 uint64_t modifier, 789 enum pipe_format format, 790 bool *external_only) 791{ 792 int i; 793 bool is_sand_col128 = (format == PIPE_FORMAT_NV12) && 794 (fourcc_mod_broadcom_mod(modifier) == DRM_FORMAT_MOD_BROADCOM_SAND128); 795 796 if (is_sand_col128) { 797 if (external_only) 798 *external_only = true; 799 return true; 800 } 801 802 /* We don't want to generally allow DRM_FORMAT_MOD_BROADCOM_SAND128 803 * modifier, that is the last v3d_available_modifiers. We only accept 804 * it in the case of having a PIPE_FORMAT_NV12. 805 */ 806 assert(v3d_available_modifiers[ARRAY_SIZE(v3d_available_modifiers) - 1] == 807 DRM_FORMAT_MOD_BROADCOM_SAND128); 808 for (i = 0; i < ARRAY_SIZE(v3d_available_modifiers) - 1; i++) { 809 if (v3d_available_modifiers[i] == modifier) { 810 if (external_only) 811 *external_only = util_format_is_yuv(format); 812 813 return true; 814 } 815 } 816 817 return false; 818} 819 820static enum pipe_format 821v3d_screen_get_compatible_tlb_format(struct pipe_screen *screen, 822 enum pipe_format format) 823{ 824 switch (format) { 825 case PIPE_FORMAT_R16G16_UNORM: 826 return PIPE_FORMAT_R16G16_UINT; 827 default: 828 return format; 829 } 830} 831 832static struct disk_cache * 833v3d_screen_get_disk_shader_cache(struct pipe_screen *pscreen) 834{ 835 struct v3d_screen *screen = v3d_screen(pscreen); 836 837 return screen->disk_cache; 838} 839 840struct pipe_screen * 841v3d_screen_create(int fd, const struct pipe_screen_config *config, 842 struct renderonly *ro) 843{ 844 struct v3d_screen *screen = rzalloc(NULL, struct v3d_screen); 845 struct pipe_screen *pscreen; 846 847 pscreen = &screen->base; 848 849 pscreen->destroy = v3d_screen_destroy; 850 pscreen->get_param = v3d_screen_get_param; 851 pscreen->get_paramf = v3d_screen_get_paramf; 852 pscreen->get_shader_param = v3d_screen_get_shader_param; 853 pscreen->get_compute_param = v3d_get_compute_param; 854 pscreen->context_create = v3d_context_create; 855 pscreen->is_format_supported = v3d_screen_is_format_supported; 856 pscreen->get_canonical_format = v3d_screen_get_compatible_tlb_format; 857 858 screen->fd = fd; 859 screen->ro = ro; 860 861 list_inithead(&screen->bo_cache.time_list); 862 (void)mtx_init(&screen->bo_handles_mutex, mtx_plain); 863 screen->bo_handles = util_hash_table_create_ptr_keys(); 864 865#if defined(USE_V3D_SIMULATOR) 866 screen->sim_file = v3d_simulator_init(screen->fd); 867#endif 868 869 if (!v3d_get_device_info(screen->fd, &screen->devinfo, &v3d_ioctl)) 870 goto fail; 871 872 driParseConfigFiles(config->options, config->options_info, 0, "v3d", 873 NULL, NULL, NULL, 0, NULL, 0); 874 875 /* We have to driCheckOption for the simulator mode to not assertion 876 * fail on not having our XML config. 877 */ 878 const char *nonmsaa_name = "v3d_nonmsaa_texture_size_limit"; 879 screen->nonmsaa_texture_size_limit = 880 driCheckOption(config->options, nonmsaa_name, DRI_BOOL) && 881 driQueryOptionb(config->options, nonmsaa_name); 882 883 slab_create_parent(&screen->transfer_pool, sizeof(struct v3d_transfer), 16); 884 885 screen->has_csd = v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_CSD); 886 screen->has_cache_flush = 887 v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_CACHE_FLUSH); 888 screen->has_perfmon = v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_PERFMON); 889 890 v3d_fence_init(screen); 891 892 v3d_process_debug_variable(); 893 894 v3d_resource_screen_init(pscreen); 895 896 screen->compiler = v3d_compiler_init(&screen->devinfo, 0); 897 898#ifdef ENABLE_SHADER_CACHE 899 v3d_disk_cache_init(screen); 900#endif 901 902 pscreen->get_name = v3d_screen_get_name; 903 pscreen->get_vendor = v3d_screen_get_vendor; 904 pscreen->get_device_vendor = v3d_screen_get_vendor; 905 pscreen->get_compiler_options = v3d_screen_get_compiler_options; 906 pscreen->get_disk_shader_cache = v3d_screen_get_disk_shader_cache; 907 pscreen->query_dmabuf_modifiers = v3d_screen_query_dmabuf_modifiers; 908 pscreen->is_dmabuf_modifier_supported = 909 v3d_screen_is_dmabuf_modifier_supported; 910 911 if (screen->has_perfmon) { 912 pscreen->get_driver_query_group_info = v3d_get_driver_query_group_info; 913 pscreen->get_driver_query_info = v3d_get_driver_query_info; 914 } 915 916 /* Generate the bitmask of supported draw primitives. */ 917 screen->prim_types = BITFIELD_BIT(PIPE_PRIM_POINTS) | 918 BITFIELD_BIT(PIPE_PRIM_LINES) | 919 BITFIELD_BIT(PIPE_PRIM_LINE_LOOP) | 920 BITFIELD_BIT(PIPE_PRIM_LINE_STRIP) | 921 BITFIELD_BIT(PIPE_PRIM_TRIANGLES) | 922 BITFIELD_BIT(PIPE_PRIM_TRIANGLE_STRIP) | 923 BITFIELD_BIT(PIPE_PRIM_TRIANGLE_FAN) | 924 BITFIELD_BIT(PIPE_PRIM_LINES_ADJACENCY) | 925 BITFIELD_BIT(PIPE_PRIM_LINE_STRIP_ADJACENCY) | 926 BITFIELD_BIT(PIPE_PRIM_TRIANGLES_ADJACENCY) | 927 BITFIELD_BIT(PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY); 928 929 return pscreen; 930 931fail: 932 close(fd); 933 ralloc_free(pscreen); 934 return NULL; 935} 936