i915_screen.c revision 848b8605
1/************************************************************************** 2 * 3 * Copyright 2008 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 29#include "draw/draw_context.h" 30#include "os/os_misc.h" 31#include "util/u_format.h" 32#include "util/u_format_s3tc.h" 33#include "util/u_inlines.h" 34#include "util/u_memory.h" 35#include "util/u_string.h" 36 37#include "i915_reg.h" 38#include "i915_debug.h" 39#include "i915_context.h" 40#include "i915_screen.h" 41#include "i915_resource.h" 42#include "i915_winsys.h" 43#include "i915_public.h" 44 45 46/* 47 * Probe functions 48 */ 49 50 51static const char * 52i915_get_vendor(struct pipe_screen *screen) 53{ 54 return "Mesa Project"; 55} 56 57static const char * 58i915_get_name(struct pipe_screen *screen) 59{ 60 static char buffer[128]; 61 const char *chipset; 62 63 switch (i915_screen(screen)->iws->pci_id) { 64 case PCI_CHIP_I915_G: 65 chipset = "915G"; 66 break; 67 case PCI_CHIP_I915_GM: 68 chipset = "915GM"; 69 break; 70 case PCI_CHIP_I945_G: 71 chipset = "945G"; 72 break; 73 case PCI_CHIP_I945_GM: 74 chipset = "945GM"; 75 break; 76 case PCI_CHIP_I945_GME: 77 chipset = "945GME"; 78 break; 79 case PCI_CHIP_G33_G: 80 chipset = "G33"; 81 break; 82 case PCI_CHIP_Q35_G: 83 chipset = "Q35"; 84 break; 85 case PCI_CHIP_Q33_G: 86 chipset = "Q33"; 87 break; 88 case PCI_CHIP_PINEVIEW_G: 89 chipset = "Pineview G"; 90 break; 91 case PCI_CHIP_PINEVIEW_M: 92 chipset = "Pineview M"; 93 break; 94 default: 95 chipset = "unknown"; 96 break; 97 } 98 99 util_snprintf(buffer, sizeof(buffer), "i915 (chipset: %s)", chipset); 100 return buffer; 101} 102 103static int 104i915_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap cap) 105{ 106 switch(shader) { 107 case PIPE_SHADER_VERTEX: 108 switch (cap) { 109 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 110 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 111 if (debug_get_bool_option("DRAW_USE_LLVM", TRUE)) 112 return PIPE_MAX_SAMPLERS; 113 else 114 return 0; 115 default: 116 return draw_get_shader_param(shader, cap); 117 } 118 case PIPE_SHADER_FRAGMENT: 119 /* XXX: some of these are just shader model 2.0 values, fix this! */ 120 switch(cap) { 121 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 122 return I915_MAX_ALU_INSN + I915_MAX_TEX_INSN; 123 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 124 return I915_MAX_ALU_INSN; 125 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 126 return I915_MAX_TEX_INSN; 127 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 128 return 8; 129 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 130 return 0; 131 case PIPE_SHADER_CAP_MAX_INPUTS: 132 return 10; 133 case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE: 134 return 32 * sizeof(float[4]); 135 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 136 return 1; 137 case PIPE_SHADER_CAP_MAX_TEMPS: 138 return 12; /* XXX: 12 -> 32 ? */ 139 case PIPE_SHADER_CAP_MAX_PREDS: 140 return 0; 141 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 142 case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: 143 return 0; 144 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 145 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 146 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 147 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 148 return 1; 149 case PIPE_SHADER_CAP_SUBROUTINES: 150 return 0; 151 case PIPE_SHADER_CAP_INTEGERS: 152 return 0; 153 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 154 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 155 return I915_TEX_UNITS; 156 default: 157 debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); 158 return 0; 159 } 160 break; 161 default: 162 return 0; 163 } 164 165} 166 167static int 168i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) 169{ 170 struct i915_screen *is = i915_screen(screen); 171 172 switch (cap) { 173 /* Supported features (boolean caps). */ 174 case PIPE_CAP_ANISOTROPIC_FILTER: 175 case PIPE_CAP_NPOT_TEXTURES: 176 case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: 177 case PIPE_CAP_POINT_SPRITE: 178 case PIPE_CAP_PRIMITIVE_RESTART: /* draw module */ 179 case PIPE_CAP_TEXTURE_SHADOW_MAP: 180 case PIPE_CAP_TWO_SIDED_STENCIL: 181 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 182 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 183 case PIPE_CAP_TGSI_INSTANCEID: 184 case PIPE_CAP_VERTEX_COLOR_CLAMPED: 185 case PIPE_CAP_USER_VERTEX_BUFFERS: 186 case PIPE_CAP_USER_INDEX_BUFFERS: 187 case PIPE_CAP_USER_CONSTANT_BUFFERS: 188 return 1; 189 190 /* Unsupported features (boolean caps). */ 191 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 192 case PIPE_CAP_DEPTH_CLIP_DISABLE: 193 case PIPE_CAP_INDEP_BLEND_ENABLE: 194 case PIPE_CAP_INDEP_BLEND_FUNC: 195 case PIPE_CAP_SHADER_STENCIL_EXPORT: 196 case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 197 case PIPE_CAP_TEXTURE_SWIZZLE: 198 case PIPE_CAP_QUERY_TIME_ELAPSED: 199 case PIPE_CAP_SM3: 200 case PIPE_CAP_SEAMLESS_CUBE_MAP: 201 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 202 case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: 203 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 204 case PIPE_CAP_CONDITIONAL_RENDER: 205 case PIPE_CAP_TEXTURE_BARRIER: 206 case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: 207 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 208 case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 209 case PIPE_CAP_START_INSTANCE: 210 case PIPE_CAP_QUERY_TIMESTAMP: 211 case PIPE_CAP_QUERY_PIPELINE_STATISTICS: 212 case PIPE_CAP_TEXTURE_MULTISAMPLE: 213 case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: 214 case PIPE_CAP_CUBE_MAP_ARRAY: 215 case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: 216 case PIPE_CAP_TGSI_TEXCOORD: 217 case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: 218 case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: 219 case PIPE_CAP_TEXTURE_GATHER_SM5: 220 case PIPE_CAP_FAKE_SW_MSAA: 221 case PIPE_CAP_TEXTURE_QUERY_LOD: 222 case PIPE_CAP_SAMPLE_SHADING: 223 case PIPE_CAP_TEXTURE_GATHER_OFFSETS: 224 case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION: 225 case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: 226 return 0; 227 228 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 229 case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 230 case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: 231 case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: 232 case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: 233 case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT: 234 case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: 235 case PIPE_CAP_DRAW_INDIRECT: 236 case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE: 237 return 0; 238 239 case PIPE_CAP_MAX_VIEWPORTS: 240 return 1; 241 242 case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: 243 return 64; 244 245 case PIPE_CAP_GLSL_FEATURE_LEVEL: 246 return 120; 247 248 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 249 return 16; 250 251 /* Features we can lie about (boolean caps). */ 252 case PIPE_CAP_OCCLUSION_QUERY: 253 return is->debug.lie ? 1 : 0; 254 255 /* Texturing. */ 256 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 257 return I915_MAX_TEXTURE_2D_LEVELS; 258 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 259 return I915_MAX_TEXTURE_3D_LEVELS; 260 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 261 return I915_MAX_TEXTURE_2D_LEVELS; 262 case PIPE_CAP_MIN_TEXEL_OFFSET: 263 case PIPE_CAP_MAX_TEXEL_OFFSET: 264 case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET: 265 case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: 266 case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 267 case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 268 case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 269 return 0; 270 271 /* Render targets. */ 272 case PIPE_CAP_MAX_RENDER_TARGETS: 273 return 1; 274 275 /* Geometry shader output, unsupported. */ 276 case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES: 277 case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: 278 case PIPE_CAP_MAX_VERTEX_STREAMS: 279 return 0; 280 281 /* Fragment coordinate conventions. */ 282 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 283 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 284 return 1; 285 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 286 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 287 return 0; 288 case PIPE_CAP_ENDIANNESS: 289 return PIPE_ENDIAN_LITTLE; 290 291 case PIPE_CAP_VENDOR_ID: 292 return 0x8086; 293 case PIPE_CAP_DEVICE_ID: 294 return is->iws->pci_id; 295 case PIPE_CAP_ACCELERATED: 296 return 1; 297 case PIPE_CAP_VIDEO_MEMORY: { 298 /* Once a batch uses more than 75% of the maximum mappable size, we 299 * assume that there's some fragmentation, and we start doing extra 300 * flushing, etc. That's the big cliff apps will care about. 301 */ 302 const int gpu_mappable_megabytes = is->iws->aperture_size(is->iws) * 3 / 4; 303 uint64_t system_memory; 304 305 if (!os_get_total_physical_memory(&system_memory)) 306 return 0; 307 308 return MIN2(gpu_mappable_megabytes, (int)(system_memory >> 20)); 309 } 310 case PIPE_CAP_UMA: 311 return 1; 312 313 default: 314 debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); 315 return 0; 316 } 317} 318 319static float 320i915_get_paramf(struct pipe_screen *screen, enum pipe_capf cap) 321{ 322 switch(cap) { 323 case PIPE_CAPF_MAX_LINE_WIDTH: 324 /* fall-through */ 325 case PIPE_CAPF_MAX_LINE_WIDTH_AA: 326 return 7.5; 327 328 case PIPE_CAPF_MAX_POINT_WIDTH: 329 /* fall-through */ 330 case PIPE_CAPF_MAX_POINT_WIDTH_AA: 331 return 255.0; 332 333 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 334 return 4.0; 335 336 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 337 return 16.0; 338 339 default: 340 debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); 341 return 0; 342 } 343} 344 345boolean 346i915_is_format_supported(struct pipe_screen *screen, 347 enum pipe_format format, 348 enum pipe_texture_target target, 349 unsigned sample_count, 350 unsigned tex_usage) 351{ 352 static const enum pipe_format tex_supported[] = { 353 PIPE_FORMAT_B8G8R8A8_UNORM, 354 PIPE_FORMAT_B8G8R8A8_SRGB, 355 PIPE_FORMAT_B8G8R8X8_UNORM, 356 PIPE_FORMAT_R8G8B8A8_UNORM, 357 PIPE_FORMAT_R8G8B8X8_UNORM, 358 PIPE_FORMAT_B5G6R5_UNORM, 359 PIPE_FORMAT_B10G10R10A2_UNORM, 360 PIPE_FORMAT_L8_UNORM, 361 PIPE_FORMAT_A8_UNORM, 362 PIPE_FORMAT_I8_UNORM, 363 PIPE_FORMAT_L8A8_UNORM, 364 PIPE_FORMAT_UYVY, 365 PIPE_FORMAT_YUYV, 366 /* XXX why not? 367 PIPE_FORMAT_Z16_UNORM, */ 368 PIPE_FORMAT_DXT1_RGB, 369 PIPE_FORMAT_DXT1_RGBA, 370 PIPE_FORMAT_DXT3_RGBA, 371 PIPE_FORMAT_DXT5_RGBA, 372 PIPE_FORMAT_Z24X8_UNORM, 373 PIPE_FORMAT_Z24_UNORM_S8_UINT, 374 PIPE_FORMAT_NONE /* list terminator */ 375 }; 376 static const enum pipe_format render_supported[] = { 377 PIPE_FORMAT_B8G8R8A8_UNORM, 378 PIPE_FORMAT_B8G8R8X8_UNORM, 379 PIPE_FORMAT_R8G8B8A8_UNORM, 380 PIPE_FORMAT_R8G8B8X8_UNORM, 381 PIPE_FORMAT_B5G6R5_UNORM, 382 PIPE_FORMAT_B10G10R10A2_UNORM, 383 PIPE_FORMAT_L8_UNORM, 384 PIPE_FORMAT_A8_UNORM, 385 PIPE_FORMAT_I8_UNORM, 386 PIPE_FORMAT_NONE /* list terminator */ 387 }; 388 static const enum pipe_format depth_supported[] = { 389 /* XXX why not? 390 PIPE_FORMAT_Z16_UNORM, */ 391 PIPE_FORMAT_Z24X8_UNORM, 392 PIPE_FORMAT_Z24_UNORM_S8_UINT, 393 PIPE_FORMAT_NONE /* list terminator */ 394 }; 395 const enum pipe_format *list; 396 uint i; 397 398 if (!util_format_is_supported(format, tex_usage)) 399 return FALSE; 400 401 if (sample_count > 1) 402 return FALSE; 403 404 if(tex_usage & PIPE_BIND_DEPTH_STENCIL) 405 list = depth_supported; 406 else if (tex_usage & PIPE_BIND_RENDER_TARGET) 407 list = render_supported; 408 else if (tex_usage & PIPE_BIND_SAMPLER_VIEW) 409 list = tex_supported; 410 else 411 return TRUE; /* PIPE_BIND_{VERTEX,INDEX}_BUFFER */ 412 413 for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) { 414 if (list[i] == format) 415 return TRUE; 416 } 417 418 return FALSE; 419} 420 421 422/* 423 * Fence functions 424 */ 425 426 427static void 428i915_fence_reference(struct pipe_screen *screen, 429 struct pipe_fence_handle **ptr, 430 struct pipe_fence_handle *fence) 431{ 432 struct i915_screen *is = i915_screen(screen); 433 434 is->iws->fence_reference(is->iws, ptr, fence); 435} 436 437static boolean 438i915_fence_signalled(struct pipe_screen *screen, 439 struct pipe_fence_handle *fence) 440{ 441 struct i915_screen *is = i915_screen(screen); 442 443 return is->iws->fence_signalled(is->iws, fence) == 1; 444} 445 446static boolean 447i915_fence_finish(struct pipe_screen *screen, 448 struct pipe_fence_handle *fence, 449 uint64_t timeout) 450{ 451 struct i915_screen *is = i915_screen(screen); 452 453 return is->iws->fence_finish(is->iws, fence) == 1; 454} 455 456 457/* 458 * Generic functions 459 */ 460 461 462static void 463i915_flush_frontbuffer(struct pipe_screen *screen, 464 struct pipe_resource *resource, 465 unsigned level, unsigned layer, 466 void *winsys_drawable_handle, 467 struct pipe_box *sub_box) 468{ 469 /* XXX: Dummy right now. */ 470 (void)screen; 471 (void)resource; 472 (void)level; 473 (void)layer; 474 (void)winsys_drawable_handle; 475 (void)sub_box; 476} 477 478static void 479i915_destroy_screen(struct pipe_screen *screen) 480{ 481 struct i915_screen *is = i915_screen(screen); 482 483 if (is->iws) 484 is->iws->destroy(is->iws); 485 486 FREE(is); 487} 488 489/** 490 * Create a new i915_screen object 491 */ 492struct pipe_screen * 493i915_screen_create(struct i915_winsys *iws) 494{ 495 struct i915_screen *is = CALLOC_STRUCT(i915_screen); 496 497 if (!is) 498 return NULL; 499 500 switch (iws->pci_id) { 501 case PCI_CHIP_I915_G: 502 case PCI_CHIP_I915_GM: 503 is->is_i945 = FALSE; 504 break; 505 506 case PCI_CHIP_I945_G: 507 case PCI_CHIP_I945_GM: 508 case PCI_CHIP_I945_GME: 509 case PCI_CHIP_G33_G: 510 case PCI_CHIP_Q33_G: 511 case PCI_CHIP_Q35_G: 512 case PCI_CHIP_PINEVIEW_G: 513 case PCI_CHIP_PINEVIEW_M: 514 is->is_i945 = TRUE; 515 break; 516 517 default: 518 debug_printf("%s: unknown pci id 0x%x, cannot create screen\n", 519 __FUNCTION__, iws->pci_id); 520 FREE(is); 521 return NULL; 522 } 523 524 is->iws = iws; 525 526 is->base.destroy = i915_destroy_screen; 527 is->base.flush_frontbuffer = i915_flush_frontbuffer; 528 529 is->base.get_name = i915_get_name; 530 is->base.get_vendor = i915_get_vendor; 531 is->base.get_param = i915_get_param; 532 is->base.get_shader_param = i915_get_shader_param; 533 is->base.get_paramf = i915_get_paramf; 534 is->base.is_format_supported = i915_is_format_supported; 535 536 is->base.context_create = i915_create_context; 537 538 is->base.fence_reference = i915_fence_reference; 539 is->base.fence_signalled = i915_fence_signalled; 540 is->base.fence_finish = i915_fence_finish; 541 542 i915_init_screen_resource_functions(is); 543 544 i915_debug_init(is); 545 546 util_format_s3tc_init(); 547 548 return &is->base; 549} 550