1 /************************************************************************** 2 * 3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 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 TUNGSTEN GRAPHICS 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 "util/u_format.h" 31 #include "util/u_format_s3tc.h" 32 #include "util/u_inlines.h" 33 #include "util/u_memory.h" 34 #include "util/u_string.h" 35 36 #include "i915_reg.h" 37 #include "i915_debug.h" 38 #include "i915_context.h" 39 #include "i915_screen.h" 40 #include "i915_resource.h" 41 #include "i915_winsys.h" 42 #include "i915_public.h" 43 44 45 /* 46 * Probe functions 47 */ 48 49 50 static const char * 51 i915_get_vendor(struct pipe_screen *screen) 52 { 53 return "VMware, Inc."; 54 } 55 56 static const char * 57 i915_get_name(struct pipe_screen *screen) 58 { 59 static char buffer[128]; 60 const char *chipset; 61 62 switch (i915_screen(screen)->iws->pci_id) { 63 case PCI_CHIP_I915_G: 64 chipset = "915G"; 65 break; 66 case PCI_CHIP_I915_GM: 67 chipset = "915GM"; 68 break; 69 case PCI_CHIP_I945_G: 70 chipset = "945G"; 71 break; 72 case PCI_CHIP_I945_GM: 73 chipset = "945GM"; 74 break; 75 case PCI_CHIP_I945_GME: 76 chipset = "945GME"; 77 break; 78 case PCI_CHIP_G33_G: 79 chipset = "G33"; 80 break; 81 case PCI_CHIP_Q35_G: 82 chipset = "Q35"; 83 break; 84 case PCI_CHIP_Q33_G: 85 chipset = "Q33"; 86 break; 87 case PCI_CHIP_PINEVIEW_G: 88 chipset = "Pineview G"; 89 break; 90 case PCI_CHIP_PINEVIEW_M: 91 chipset = "Pineview M"; 92 break; 93 default: 94 chipset = "unknown"; 95 break; 96 } 97 98 util_snprintf(buffer, sizeof(buffer), "i915 (chipset: %s)", chipset); 99 return buffer; 100 } 101 102 static int 103 i915_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap cap) 104 { 105 switch(shader) { 106 case PIPE_SHADER_VERTEX: 107 switch (cap) { 108 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 109 if (debug_get_bool_option("DRAW_USE_LLVM", TRUE)) 110 return PIPE_MAX_SAMPLERS; 111 else 112 return 0; 113 default: 114 return draw_get_shader_param(shader, cap); 115 } 116 case PIPE_SHADER_FRAGMENT: 117 /* XXX: some of these are just shader model 2.0 values, fix this! */ 118 switch(cap) { 119 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 120 return I915_MAX_ALU_INSN + I915_MAX_TEX_INSN; 121 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 122 return I915_MAX_ALU_INSN; 123 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 124 return I915_MAX_TEX_INSN; 125 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 126 return 8; 127 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 128 return 0; 129 case PIPE_SHADER_CAP_MAX_INPUTS: 130 return 10; 131 case PIPE_SHADER_CAP_MAX_CONSTS: 132 return 32; 133 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 134 return 1; 135 case PIPE_SHADER_CAP_MAX_TEMPS: 136 return 12; /* XXX: 12 -> 32 ? */ 137 case PIPE_SHADER_CAP_MAX_ADDRS: 138 return 0; 139 case PIPE_SHADER_CAP_MAX_PREDS: 140 return 0; 141 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 142 return 0; 143 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 144 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 145 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 146 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 147 return 1; 148 case PIPE_SHADER_CAP_SUBROUTINES: 149 return 0; 150 case PIPE_SHADER_CAP_INTEGERS: 151 return 0; 152 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 153 return I915_TEX_UNITS; 154 default: 155 debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); 156 return 0; 157 } 158 break; 159 default: 160 return 0; 161 } 162 163 } 164 165 static int 166 i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) 167 { 168 struct i915_screen *is = i915_screen(screen); 169 170 switch (cap) { 171 /* Supported features (boolean caps). */ 172 case PIPE_CAP_ANISOTROPIC_FILTER: 173 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: 174 case PIPE_CAP_NPOT_TEXTURES: 175 case PIPE_CAP_POINT_SPRITE: 176 case PIPE_CAP_PRIMITIVE_RESTART: /* draw module */ 177 case PIPE_CAP_TEXTURE_SHADOW_MAP: 178 case PIPE_CAP_TWO_SIDED_STENCIL: 179 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 180 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 181 case PIPE_CAP_TGSI_INSTANCEID: 182 case PIPE_CAP_VERTEX_COLOR_CLAMPED: 183 case PIPE_CAP_USER_VERTEX_BUFFERS: 184 case PIPE_CAP_USER_INDEX_BUFFERS: 185 case PIPE_CAP_USER_CONSTANT_BUFFERS: 186 return 1; 187 188 /* Unsupported features (boolean caps). */ 189 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 190 case PIPE_CAP_DEPTH_CLIP_DISABLE: 191 case PIPE_CAP_INDEP_BLEND_ENABLE: 192 case PIPE_CAP_INDEP_BLEND_FUNC: 193 case PIPE_CAP_SHADER_STENCIL_EXPORT: 194 case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 195 case PIPE_CAP_TEXTURE_SWIZZLE: 196 case PIPE_CAP_TIMER_QUERY: 197 case PIPE_CAP_SM3: 198 case PIPE_CAP_SEAMLESS_CUBE_MAP: 199 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 200 case PIPE_CAP_SCALED_RESOLVE: 201 case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: 202 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 203 case PIPE_CAP_CONDITIONAL_RENDER: 204 case PIPE_CAP_TEXTURE_BARRIER: 205 case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS: 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 return 0; 212 213 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 214 return 16; 215 216 /* Features we can lie about (boolean caps). */ 217 case PIPE_CAP_OCCLUSION_QUERY: 218 return is->debug.lie ? 1 : 0; 219 220 /* Texturing. */ 221 case PIPE_CAP_MAX_COMBINED_SAMPLERS: 222 return i915_get_shader_param(screen, 223 PIPE_SHADER_VERTEX, 224 PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS) + 225 i915_get_shader_param(screen, 226 PIPE_SHADER_FRAGMENT, 227 PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS); 228 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 229 return I915_MAX_TEXTURE_2D_LEVELS; 230 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 231 return I915_MAX_TEXTURE_3D_LEVELS; 232 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 233 return I915_MAX_TEXTURE_2D_LEVELS; 234 case PIPE_CAP_MIN_TEXEL_OFFSET: 235 case PIPE_CAP_MAX_TEXEL_OFFSET: 236 case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 237 case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 238 case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 239 return 0; 240 241 /* Render targets. */ 242 case PIPE_CAP_MAX_RENDER_TARGETS: 243 return 1; 244 245 /* Fragment coordinate conventions. */ 246 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 247 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 248 return 1; 249 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 250 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 251 return 0; 252 253 default: 254 debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); 255 return 0; 256 } 257 } 258 259 static float 260 i915_get_paramf(struct pipe_screen *screen, enum pipe_capf cap) 261 { 262 switch(cap) { 263 case PIPE_CAPF_MAX_LINE_WIDTH: 264 /* fall-through */ 265 case PIPE_CAPF_MAX_LINE_WIDTH_AA: 266 return 7.5; 267 268 case PIPE_CAPF_MAX_POINT_WIDTH: 269 /* fall-through */ 270 case PIPE_CAPF_MAX_POINT_WIDTH_AA: 271 return 255.0; 272 273 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 274 return 4.0; 275 276 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 277 return 16.0; 278 279 default: 280 debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); 281 return 0; 282 } 283 } 284 285 boolean 286 i915_is_format_supported(struct pipe_screen *screen, 287 enum pipe_format format, 288 enum pipe_texture_target target, 289 unsigned sample_count, 290 unsigned tex_usage) 291 { 292 static const enum pipe_format tex_supported[] = { 293 PIPE_FORMAT_B8G8R8A8_UNORM, 294 PIPE_FORMAT_B8G8R8A8_SRGB, 295 PIPE_FORMAT_B8G8R8X8_UNORM, 296 PIPE_FORMAT_R8G8B8A8_UNORM, 297 PIPE_FORMAT_R8G8B8X8_UNORM, 298 PIPE_FORMAT_B5G6R5_UNORM, 299 PIPE_FORMAT_B10G10R10A2_UNORM, 300 PIPE_FORMAT_L8_UNORM, 301 PIPE_FORMAT_A8_UNORM, 302 PIPE_FORMAT_I8_UNORM, 303 PIPE_FORMAT_L8A8_UNORM, 304 PIPE_FORMAT_UYVY, 305 PIPE_FORMAT_YUYV, 306 /* XXX why not? 307 PIPE_FORMAT_Z16_UNORM, */ 308 PIPE_FORMAT_DXT1_RGB, 309 PIPE_FORMAT_DXT1_RGBA, 310 PIPE_FORMAT_DXT3_RGBA, 311 PIPE_FORMAT_DXT5_RGBA, 312 PIPE_FORMAT_Z24X8_UNORM, 313 PIPE_FORMAT_Z24_UNORM_S8_UINT, 314 PIPE_FORMAT_NONE /* list terminator */ 315 }; 316 static const enum pipe_format render_supported[] = { 317 PIPE_FORMAT_B8G8R8A8_UNORM, 318 PIPE_FORMAT_B8G8R8X8_UNORM, 319 PIPE_FORMAT_R8G8B8A8_UNORM, 320 PIPE_FORMAT_R8G8B8X8_UNORM, 321 PIPE_FORMAT_B5G6R5_UNORM, 322 PIPE_FORMAT_B10G10R10A2_UNORM, 323 PIPE_FORMAT_L8_UNORM, 324 PIPE_FORMAT_A8_UNORM, 325 PIPE_FORMAT_I8_UNORM, 326 PIPE_FORMAT_NONE /* list terminator */ 327 }; 328 static const enum pipe_format depth_supported[] = { 329 /* XXX why not? 330 PIPE_FORMAT_Z16_UNORM, */ 331 PIPE_FORMAT_Z24X8_UNORM, 332 PIPE_FORMAT_Z24_UNORM_S8_UINT, 333 PIPE_FORMAT_NONE /* list terminator */ 334 }; 335 const enum pipe_format *list; 336 uint i; 337 338 if (!util_format_is_supported(format, tex_usage)) 339 return FALSE; 340 341 if (sample_count > 1) 342 return FALSE; 343 344 if(tex_usage & PIPE_BIND_DEPTH_STENCIL) 345 list = depth_supported; 346 else if (tex_usage & PIPE_BIND_RENDER_TARGET) 347 list = render_supported; 348 else if (tex_usage & PIPE_BIND_SAMPLER_VIEW) 349 list = tex_supported; 350 else 351 return TRUE; /* PIPE_BIND_{VERTEX,INDEX}_BUFFER */ 352 353 for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) { 354 if (list[i] == format) 355 return TRUE; 356 } 357 358 return FALSE; 359 } 360 361 362 /* 363 * Fence functions 364 */ 365 366 367 static void 368 i915_fence_reference(struct pipe_screen *screen, 369 struct pipe_fence_handle **ptr, 370 struct pipe_fence_handle *fence) 371 { 372 struct i915_screen *is = i915_screen(screen); 373 374 is->iws->fence_reference(is->iws, ptr, fence); 375 } 376 377 static boolean 378 i915_fence_signalled(struct pipe_screen *screen, 379 struct pipe_fence_handle *fence) 380 { 381 struct i915_screen *is = i915_screen(screen); 382 383 return is->iws->fence_signalled(is->iws, fence) == 1; 384 } 385 386 static boolean 387 i915_fence_finish(struct pipe_screen *screen, 388 struct pipe_fence_handle *fence, 389 uint64_t timeout) 390 { 391 struct i915_screen *is = i915_screen(screen); 392 393 return is->iws->fence_finish(is->iws, fence) == 1; 394 } 395 396 397 /* 398 * Generic functions 399 */ 400 401 402 static void 403 i915_flush_frontbuffer(struct pipe_screen *screen, 404 struct pipe_resource *resource, 405 unsigned level, unsigned layer, 406 void *winsys_drawable_handle) 407 { 408 /* XXX: Dummy right now. */ 409 (void)screen; 410 (void)resource; 411 (void)level; 412 (void)layer; 413 (void)winsys_drawable_handle; 414 } 415 416 static void 417 i915_destroy_screen(struct pipe_screen *screen) 418 { 419 struct i915_screen *is = i915_screen(screen); 420 421 if (is->iws) 422 is->iws->destroy(is->iws); 423 424 FREE(is); 425 } 426 427 /** 428 * Create a new i915_screen object 429 */ 430 struct pipe_screen * 431 i915_screen_create(struct i915_winsys *iws) 432 { 433 struct i915_screen *is = CALLOC_STRUCT(i915_screen); 434 435 if (!is) 436 return NULL; 437 438 switch (iws->pci_id) { 439 case PCI_CHIP_I915_G: 440 case PCI_CHIP_I915_GM: 441 is->is_i945 = FALSE; 442 break; 443 444 case PCI_CHIP_I945_G: 445 case PCI_CHIP_I945_GM: 446 case PCI_CHIP_I945_GME: 447 case PCI_CHIP_G33_G: 448 case PCI_CHIP_Q33_G: 449 case PCI_CHIP_Q35_G: 450 case PCI_CHIP_PINEVIEW_G: 451 case PCI_CHIP_PINEVIEW_M: 452 is->is_i945 = TRUE; 453 break; 454 455 default: 456 debug_printf("%s: unknown pci id 0x%x, cannot create screen\n", 457 __FUNCTION__, iws->pci_id); 458 FREE(is); 459 return NULL; 460 } 461 462 is->iws = iws; 463 464 is->base.destroy = i915_destroy_screen; 465 is->base.flush_frontbuffer = i915_flush_frontbuffer; 466 467 is->base.get_name = i915_get_name; 468 is->base.get_vendor = i915_get_vendor; 469 is->base.get_param = i915_get_param; 470 is->base.get_shader_param = i915_get_shader_param; 471 is->base.get_paramf = i915_get_paramf; 472 is->base.is_format_supported = i915_is_format_supported; 473 474 is->base.context_create = i915_create_context; 475 476 is->base.fence_reference = i915_fence_reference; 477 is->base.fence_signalled = i915_fence_signalled; 478 is->base.fence_finish = i915_fence_finish; 479 480 i915_init_screen_resource_functions(is); 481 482 i915_debug_init(is); 483 484 util_format_s3tc_init(); 485 486 return &is->base; 487 } 488