1 /* 2 * Copyright 2014-2017 Broadcom 3 * Copyright (C) 2012 Rob Clark <robclark (at) 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 "os/os_misc.h" 26 #include "pipe/p_defines.h" 27 #include "pipe/p_screen.h" 28 #include "pipe/p_state.h" 29 30 #include "util/u_debug.h" 31 #include "util/u_memory.h" 32 #include "util/u_format.h" 33 #include "util/u_hash_table.h" 34 #include "util/ralloc.h" 35 36 #include <xf86drm.h> 37 #include "vc5_drm.h" 38 #include "vc5_screen.h" 39 #include "vc5_context.h" 40 #include "vc5_resource.h" 41 #include "compiler/v3d_compiler.h" 42 43 static const char * 44 vc5_screen_get_name(struct pipe_screen *pscreen) 45 { 46 struct vc5_screen *screen = vc5_screen(pscreen); 47 48 if (!screen->name) { 49 screen->name = ralloc_asprintf(screen, 50 "VC5 V3D %d.%d", 51 screen->devinfo.ver / 10, 52 screen->devinfo.ver % 10); 53 } 54 55 return screen->name; 56 } 57 58 static const char * 59 vc5_screen_get_vendor(struct pipe_screen *pscreen) 60 { 61 return "Broadcom"; 62 } 63 64 static void 65 vc5_screen_destroy(struct pipe_screen *pscreen) 66 { 67 struct vc5_screen *screen = vc5_screen(pscreen); 68 69 util_hash_table_destroy(screen->bo_handles); 70 vc5_bufmgr_destroy(pscreen); 71 slab_destroy_parent(&screen->transfer_pool); 72 73 if (using_vc5_simulator) 74 vc5_simulator_destroy(screen); 75 76 v3d_compiler_free(screen->compiler); 77 78 close(screen->fd); 79 ralloc_free(pscreen); 80 } 81 82 static int 83 vc5_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 84 { 85 struct vc5_screen *screen = vc5_screen(pscreen); 86 87 switch (param) { 88 /* Supported features (boolean caps). */ 89 case PIPE_CAP_VERTEX_COLOR_CLAMPED: 90 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 91 case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: 92 case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: 93 case PIPE_CAP_NPOT_TEXTURES: 94 case PIPE_CAP_SHAREABLE_SHADERS: 95 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 96 case PIPE_CAP_TEXTURE_MULTISAMPLE: 97 case PIPE_CAP_TEXTURE_SWIZZLE: 98 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 99 case PIPE_CAP_START_INSTANCE: 100 case PIPE_CAP_TGSI_INSTANCEID: 101 case PIPE_CAP_SM3: 102 case PIPE_CAP_TEXTURE_QUERY_LOD: 103 case PIPE_CAP_PRIMITIVE_RESTART: 104 case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY: 105 case PIPE_CAP_OCCLUSION_QUERY: 106 case PIPE_CAP_POINT_SPRITE: 107 case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 108 case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION: 109 case PIPE_CAP_COMPUTE: 110 case PIPE_CAP_DRAW_INDIRECT: 111 case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 112 case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET: 113 return 1; 114 115 case PIPE_CAP_INDEP_BLEND_ENABLE: 116 return screen->devinfo.ver >= 40; 117 118 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 119 return 256; 120 121 case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT: 122 return 4; 123 124 case PIPE_CAP_GLSL_FEATURE_LEVEL: 125 return 400; 126 127 case PIPE_CAP_MAX_VIEWPORTS: 128 return 1; 129 130 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 131 return 1; 132 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 133 return 0; 134 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 135 if (screen->devinfo.ver >= 40) 136 return 0; 137 else 138 return 1; 139 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 140 if (screen->devinfo.ver >= 40) 141 return 1; 142 else 143 return 0; 144 145 case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: 146 case PIPE_CAP_MIXED_COLOR_DEPTH_BITS: 147 return 1; 148 149 150 /* Stream output. */ 151 case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 152 return 4; 153 case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 154 case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 155 return 64; 156 157 case PIPE_CAP_MIN_TEXEL_OFFSET: 158 case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET: 159 return -8; 160 case PIPE_CAP_MAX_TEXEL_OFFSET: 161 case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: 162 return 7; 163 164 /* Unsupported features. */ 165 case PIPE_CAP_ANISOTROPIC_FILTER: 166 case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: 167 case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY: 168 case PIPE_CAP_CUBE_MAP_ARRAY: 169 case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 170 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 171 case PIPE_CAP_SEAMLESS_CUBE_MAP: 172 case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: 173 case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: 174 case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: 175 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 176 case PIPE_CAP_SHADER_STENCIL_EXPORT: 177 case PIPE_CAP_TGSI_TEXCOORD: 178 case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: 179 case PIPE_CAP_CONDITIONAL_RENDER: 180 case PIPE_CAP_TEXTURE_BARRIER: 181 case PIPE_CAP_INDEP_BLEND_FUNC: 182 case PIPE_CAP_DEPTH_CLIP_DISABLE: 183 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 184 case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: 185 case PIPE_CAP_USER_VERTEX_BUFFERS: 186 case PIPE_CAP_QUERY_PIPELINE_STATISTICS: 187 case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: 188 case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT: 189 case PIPE_CAP_TGSI_TES_LAYER_VIEWPORT: 190 case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: 191 case PIPE_CAP_TEXTURE_GATHER_SM5: 192 case PIPE_CAP_FAKE_SW_MSAA: 193 case PIPE_CAP_SAMPLE_SHADING: 194 case PIPE_CAP_TEXTURE_GATHER_OFFSETS: 195 case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION: 196 case PIPE_CAP_MAX_VERTEX_STREAMS: 197 case PIPE_CAP_MULTI_DRAW_INDIRECT: 198 case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS: 199 case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE: 200 case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: 201 case PIPE_CAP_SAMPLER_VIEW_TARGET: 202 case PIPE_CAP_CLIP_HALFZ: 203 case PIPE_CAP_VERTEXID_NOBASE: 204 case PIPE_CAP_POLYGON_OFFSET_CLAMP: 205 case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: 206 case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: 207 case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: 208 case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS: 209 case PIPE_CAP_TEXTURE_FLOAT_LINEAR: 210 case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR: 211 case PIPE_CAP_DEPTH_BOUNDS_TEST: 212 case PIPE_CAP_TGSI_TXQS: 213 case PIPE_CAP_FORCE_PERSAMPLE_INTERP: 214 case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS: 215 case PIPE_CAP_CLEAR_TEXTURE: 216 case PIPE_CAP_DRAW_PARAMETERS: 217 case PIPE_CAP_TGSI_PACK_HALF_FLOAT: 218 case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL: 219 case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL: 220 case PIPE_CAP_INVALIDATE_BUFFER: 221 case PIPE_CAP_GENERATE_MIPMAP: 222 case PIPE_CAP_STRING_MARKER: 223 case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS: 224 case PIPE_CAP_QUERY_BUFFER_OBJECT: 225 case PIPE_CAP_QUERY_MEMORY_INFO: 226 case PIPE_CAP_PCI_GROUP: 227 case PIPE_CAP_PCI_BUS: 228 case PIPE_CAP_PCI_DEVICE: 229 case PIPE_CAP_PCI_FUNCTION: 230 case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT: 231 case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR: 232 case PIPE_CAP_CULL_DISTANCE: 233 case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES: 234 case PIPE_CAP_TGSI_VOTE: 235 case PIPE_CAP_MAX_WINDOW_RECTANGLES: 236 case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED: 237 case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS: 238 case PIPE_CAP_TGSI_ARRAY_COMPONENTS: 239 case PIPE_CAP_TGSI_FS_FBFETCH: 240 case PIPE_CAP_INT64: 241 case PIPE_CAP_INT64_DIVMOD: 242 case PIPE_CAP_DOUBLES: 243 case PIPE_CAP_BINDLESS_TEXTURE: 244 case PIPE_CAP_POST_DEPTH_COVERAGE: 245 case PIPE_CAP_CAN_BIND_CONST_BUFFER_AS_VERTEX: 246 case PIPE_CAP_TGSI_BALLOT: 247 case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE: 248 case PIPE_CAP_POLYGON_MODE_FILL_RECTANGLE: 249 case PIPE_CAP_TGSI_CLOCK: 250 case PIPE_CAP_TGSI_TEX_TXF_LZ: 251 case PIPE_CAP_NATIVE_FENCE_FD: 252 case PIPE_CAP_TGSI_MUL_ZERO_WINS: 253 case PIPE_CAP_NIR_SAMPLERS_AS_DEREF: 254 case PIPE_CAP_QUERY_SO_OVERFLOW: 255 case PIPE_CAP_MEMOBJ: 256 case PIPE_CAP_LOAD_CONSTBUF: 257 case PIPE_CAP_TILE_RASTER_ORDER: 258 case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS: 259 case PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES: 260 case PIPE_CAP_CONTEXT_PRIORITY_MASK: 261 return 0; 262 263 /* Geometry shader output, unsupported. */ 264 case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES: 265 case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: 266 return 0; 267 268 /* Texturing. */ 269 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 270 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 271 return VC5_MAX_MIP_LEVELS; 272 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 273 return 256; 274 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 275 return 2048; 276 277 /* Render targets. */ 278 case PIPE_CAP_MAX_RENDER_TARGETS: 279 return 4; 280 281 /* Queries. */ 282 case PIPE_CAP_QUERY_TIME_ELAPSED: 283 case PIPE_CAP_QUERY_TIMESTAMP: 284 return 0; 285 286 case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE: 287 return 2048; 288 289 case PIPE_CAP_ENDIANNESS: 290 return PIPE_ENDIAN_LITTLE; 291 292 case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: 293 return 64; 294 295 case PIPE_CAP_VENDOR_ID: 296 return 0x14E4; 297 case PIPE_CAP_DEVICE_ID: 298 return 0xFFFFFFFF; 299 case PIPE_CAP_ACCELERATED: 300 return 1; 301 case PIPE_CAP_VIDEO_MEMORY: { 302 uint64_t system_memory; 303 304 if (!os_get_total_physical_memory(&system_memory)) 305 return 0; 306 307 return (int)(system_memory >> 20); 308 } 309 case PIPE_CAP_UMA: 310 return 1; 311 312 default: 313 fprintf(stderr, "unknown param %d\n", param); 314 return 0; 315 } 316 } 317 318 static float 319 vc5_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) 320 { 321 switch (param) { 322 case PIPE_CAPF_MAX_LINE_WIDTH: 323 case PIPE_CAPF_MAX_LINE_WIDTH_AA: 324 return 32; 325 326 case PIPE_CAPF_MAX_POINT_WIDTH: 327 case PIPE_CAPF_MAX_POINT_WIDTH_AA: 328 return 512.0f; 329 330 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 331 return 0.0f; 332 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 333 return 16.0f; 334 case PIPE_CAPF_GUARD_BAND_LEFT: 335 case PIPE_CAPF_GUARD_BAND_TOP: 336 case PIPE_CAPF_GUARD_BAND_RIGHT: 337 case PIPE_CAPF_GUARD_BAND_BOTTOM: 338 return 0.0f; 339 default: 340 fprintf(stderr, "unknown paramf %d\n", param); 341 return 0; 342 } 343 } 344 345 static int 346 vc5_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, 347 enum pipe_shader_cap param) 348 { 349 if (shader != PIPE_SHADER_VERTEX && 350 shader != PIPE_SHADER_FRAGMENT) { 351 return 0; 352 } 353 354 /* this is probably not totally correct.. but it's a start: */ 355 switch (param) { 356 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 357 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 358 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 359 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 360 return 16384; 361 362 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 363 return UINT_MAX; 364 365 case PIPE_SHADER_CAP_MAX_INPUTS: 366 if (shader == PIPE_SHADER_FRAGMENT) 367 return VC5_MAX_FS_INPUTS / 4; 368 else 369 return 16; 370 case PIPE_SHADER_CAP_MAX_OUTPUTS: 371 if (shader == PIPE_SHADER_FRAGMENT) 372 return 4; 373 else 374 return VC5_MAX_FS_INPUTS / 4; 375 case PIPE_SHADER_CAP_MAX_TEMPS: 376 return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */ 377 case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE: 378 return 16 * 1024 * sizeof(float); 379 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 380 return 16; 381 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 382 return 0; 383 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 384 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 385 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 386 return 0; 387 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 388 return 1; 389 case PIPE_SHADER_CAP_SUBROUTINES: 390 return 0; 391 case PIPE_SHADER_CAP_INTEGERS: 392 return 1; 393 case PIPE_SHADER_CAP_FP16: 394 case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED: 395 case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED: 396 case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED: 397 case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED: 398 case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: 399 case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: 400 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS: 401 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS: 402 return 0; 403 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 404 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 405 case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: 406 case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: 407 return VC5_MAX_TEXTURE_SAMPLERS; 408 case PIPE_SHADER_CAP_PREFERRED_IR: 409 return PIPE_SHADER_IR_NIR; 410 case PIPE_SHADER_CAP_SUPPORTED_IRS: 411 return 0; 412 case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT: 413 return 32; 414 case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD: 415 case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS: 416 return 0; 417 default: 418 fprintf(stderr, "unknown shader param %d\n", param); 419 return 0; 420 } 421 return 0; 422 } 423 424 static boolean 425 vc5_screen_is_format_supported(struct pipe_screen *pscreen, 426 enum pipe_format format, 427 enum pipe_texture_target target, 428 unsigned sample_count, 429 unsigned usage) 430 { 431 struct vc5_screen *screen = vc5_screen(pscreen); 432 unsigned retval = 0; 433 434 if (sample_count > 1 && sample_count != VC5_MAX_SAMPLES) 435 return FALSE; 436 437 if ((target >= PIPE_MAX_TEXTURE_TYPES) || 438 !util_format_is_supported(format, usage)) { 439 return FALSE; 440 } 441 442 if (usage & PIPE_BIND_VERTEX_BUFFER) { 443 switch (format) { 444 case PIPE_FORMAT_R32G32B32A32_FLOAT: 445 case PIPE_FORMAT_R32G32B32_FLOAT: 446 case PIPE_FORMAT_R32G32_FLOAT: 447 case PIPE_FORMAT_R32_FLOAT: 448 case PIPE_FORMAT_R32G32B32A32_SNORM: 449 case PIPE_FORMAT_R32G32B32_SNORM: 450 case PIPE_FORMAT_R32G32_SNORM: 451 case PIPE_FORMAT_R32_SNORM: 452 case PIPE_FORMAT_R32G32B32A32_SSCALED: 453 case PIPE_FORMAT_R32G32B32_SSCALED: 454 case PIPE_FORMAT_R32G32_SSCALED: 455 case PIPE_FORMAT_R32_SSCALED: 456 case PIPE_FORMAT_R16G16B16A16_UNORM: 457 case PIPE_FORMAT_R16G16B16_UNORM: 458 case PIPE_FORMAT_R16G16_UNORM: 459 case PIPE_FORMAT_R16_UNORM: 460 case PIPE_FORMAT_R16G16B16A16_SNORM: 461 case PIPE_FORMAT_R16G16B16_SNORM: 462 case PIPE_FORMAT_R16G16_SNORM: 463 case PIPE_FORMAT_R16_SNORM: 464 case PIPE_FORMAT_R16G16B16A16_USCALED: 465 case PIPE_FORMAT_R16G16B16_USCALED: 466 case PIPE_FORMAT_R16G16_USCALED: 467 case PIPE_FORMAT_R16_USCALED: 468 case PIPE_FORMAT_R16G16B16A16_SSCALED: 469 case PIPE_FORMAT_R16G16B16_SSCALED: 470 case PIPE_FORMAT_R16G16_SSCALED: 471 case PIPE_FORMAT_R16_SSCALED: 472 case PIPE_FORMAT_R8G8B8A8_UNORM: 473 case PIPE_FORMAT_R8G8B8_UNORM: 474 case PIPE_FORMAT_R8G8_UNORM: 475 case PIPE_FORMAT_R8_UNORM: 476 case PIPE_FORMAT_R8G8B8A8_SNORM: 477 case PIPE_FORMAT_R8G8B8_SNORM: 478 case PIPE_FORMAT_R8G8_SNORM: 479 case PIPE_FORMAT_R8_SNORM: 480 case PIPE_FORMAT_R8G8B8A8_USCALED: 481 case PIPE_FORMAT_R8G8B8_USCALED: 482 case PIPE_FORMAT_R8G8_USCALED: 483 case PIPE_FORMAT_R8_USCALED: 484 case PIPE_FORMAT_R8G8B8A8_SSCALED: 485 case PIPE_FORMAT_R8G8B8_SSCALED: 486 case PIPE_FORMAT_R8G8_SSCALED: 487 case PIPE_FORMAT_R8_SSCALED: 488 retval |= PIPE_BIND_VERTEX_BUFFER; 489 break; 490 default: 491 break; 492 } 493 } 494 495 if ((usage & PIPE_BIND_RENDER_TARGET) && 496 vc5_rt_format_supported(&screen->devinfo, format)) { 497 retval |= PIPE_BIND_RENDER_TARGET; 498 } 499 500 if ((usage & PIPE_BIND_SAMPLER_VIEW) && 501 vc5_tex_format_supported(&screen->devinfo, format)) { 502 retval |= PIPE_BIND_SAMPLER_VIEW; 503 } 504 505 if ((usage & PIPE_BIND_DEPTH_STENCIL) && 506 (format == PIPE_FORMAT_S8_UINT_Z24_UNORM || 507 format == PIPE_FORMAT_X8Z24_UNORM || 508 format == PIPE_FORMAT_Z16_UNORM || 509 format == PIPE_FORMAT_Z32_FLOAT || 510 format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)) { 511 retval |= PIPE_BIND_DEPTH_STENCIL; 512 } 513 514 if ((usage & PIPE_BIND_INDEX_BUFFER) && 515 (format == PIPE_FORMAT_I8_UINT || 516 format == PIPE_FORMAT_I16_UINT || 517 format == PIPE_FORMAT_I32_UINT)) { 518 retval |= PIPE_BIND_INDEX_BUFFER; 519 } 520 521 #if 0 522 if (retval != usage) { 523 fprintf(stderr, 524 "not supported: format=%s, target=%d, sample_count=%d, " 525 "usage=0x%x, retval=0x%x\n", util_format_name(format), 526 target, sample_count, usage, retval); 527 } 528 #endif 529 530 return retval == usage; 531 } 532 533 #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x))) 534 535 static unsigned handle_hash(void *key) 536 { 537 return PTR_TO_UINT(key); 538 } 539 540 static int handle_compare(void *key1, void *key2) 541 { 542 return PTR_TO_UINT(key1) != PTR_TO_UINT(key2); 543 } 544 545 static bool 546 vc5_get_device_info(struct vc5_screen *screen) 547 { 548 struct drm_vc5_get_param ident0 = { 549 .param = DRM_VC5_PARAM_V3D_CORE0_IDENT0, 550 }; 551 struct drm_vc5_get_param ident1 = { 552 .param = DRM_VC5_PARAM_V3D_CORE0_IDENT1, 553 }; 554 int ret; 555 556 ret = vc5_ioctl(screen->fd, DRM_IOCTL_VC5_GET_PARAM, &ident0); 557 if (ret != 0) { 558 fprintf(stderr, "Couldn't get V3D core IDENT0: %s\n", 559 strerror(errno)); 560 return false; 561 } 562 ret = vc5_ioctl(screen->fd, DRM_IOCTL_VC5_GET_PARAM, &ident1); 563 if (ret != 0) { 564 fprintf(stderr, "Couldn't get V3D core IDENT1: %s\n", 565 strerror(errno)); 566 return false; 567 } 568 569 uint32_t major = (ident0.value >> 24) & 0xff; 570 uint32_t minor = (ident1.value >> 0) & 0xf; 571 screen->devinfo.ver = major * 10 + minor; 572 573 if (screen->devinfo.ver != 33 && screen->devinfo.ver != 41) { 574 fprintf(stderr, 575 "V3D %d.%d not supported by this version of Mesa.\n", 576 screen->devinfo.ver / 10, 577 screen->devinfo.ver % 10); 578 return false; 579 } 580 581 return true; 582 } 583 584 static const void * 585 vc5_screen_get_compiler_options(struct pipe_screen *pscreen, 586 enum pipe_shader_ir ir, unsigned shader) 587 { 588 return &v3d_nir_options; 589 } 590 591 struct pipe_screen * 592 vc5_screen_create(int fd) 593 { 594 struct vc5_screen *screen = rzalloc(NULL, struct vc5_screen); 595 struct pipe_screen *pscreen; 596 597 pscreen = &screen->base; 598 599 pscreen->destroy = vc5_screen_destroy; 600 pscreen->get_param = vc5_screen_get_param; 601 pscreen->get_paramf = vc5_screen_get_paramf; 602 pscreen->get_shader_param = vc5_screen_get_shader_param; 603 pscreen->context_create = vc5_context_create; 604 pscreen->is_format_supported = vc5_screen_is_format_supported; 605 606 screen->fd = fd; 607 list_inithead(&screen->bo_cache.time_list); 608 (void)mtx_init(&screen->bo_handles_mutex, mtx_plain); 609 screen->bo_handles = util_hash_table_create(handle_hash, handle_compare); 610 611 #if defined(USE_VC5_SIMULATOR) 612 vc5_simulator_init(screen); 613 #endif 614 615 if (!vc5_get_device_info(screen)) 616 goto fail; 617 618 slab_create_parent(&screen->transfer_pool, sizeof(struct vc5_transfer), 16); 619 620 vc5_fence_init(screen); 621 622 v3d_process_debug_variable(); 623 624 vc5_resource_screen_init(pscreen); 625 626 screen->compiler = v3d_compiler_init(&screen->devinfo); 627 628 pscreen->get_name = vc5_screen_get_name; 629 pscreen->get_vendor = vc5_screen_get_vendor; 630 pscreen->get_device_vendor = vc5_screen_get_vendor; 631 pscreen->get_compiler_options = vc5_screen_get_compiler_options; 632 633 return pscreen; 634 635 fail: 636 close(fd); 637 ralloc_free(pscreen); 638 return NULL; 639 } 640