i915_screen.c revision 3464ebd5
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 50static const char * 51i915_get_vendor(struct pipe_screen *screen) 52{ 53 return "VMware, Inc."; 54} 55 56static const char * 57i915_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 102static int 103i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) 104{ 105 struct i915_screen *is = i915_screen(screen); 106 107 switch (cap) { 108 /* Supported features (boolean caps). */ 109 case PIPE_CAP_ANISOTROPIC_FILTER: 110 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: 111 case PIPE_CAP_NPOT_TEXTURES: 112 case PIPE_CAP_POINT_SPRITE: 113 case PIPE_CAP_PRIMITIVE_RESTART: /* draw module */ 114 case PIPE_CAP_TEXTURE_MIRROR_REPEAT: 115 case PIPE_CAP_TEXTURE_SHADOW_MAP: 116 case PIPE_CAP_TWO_SIDED_STENCIL: 117 return 1; 118 119 /* Features that should be supported (boolean caps). */ 120 /* XXX: Just test the code */ 121 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 122 /* Also lie about these when asked to (needed for GLSL / GL 2.0) */ 123 return is->debug.lie ? 1 : 0; 124 125 /* Unsupported features (boolean caps). */ 126 case PIPE_CAP_ARRAY_TEXTURES: 127 case PIPE_CAP_DEPTH_CLAMP: 128 case PIPE_CAP_INDEP_BLEND_ENABLE: 129 case PIPE_CAP_INDEP_BLEND_FUNC: 130 case PIPE_CAP_TGSI_INSTANCEID: 131 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 132 case PIPE_CAP_SHADER_STENCIL_EXPORT: 133 case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 134 case PIPE_CAP_TEXTURE_SWIZZLE: 135 case PIPE_CAP_TIMER_QUERY: 136 case PIPE_CAP_SM3: 137 case PIPE_CAP_SEAMLESS_CUBE_MAP: 138 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 139 case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: 140 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 141 return 0; 142 143 /* Features we can lie about (boolean caps). */ 144 case PIPE_CAP_GLSL: 145 case PIPE_CAP_OCCLUSION_QUERY: 146 return is->debug.lie ? 1 : 0; 147 148 /* Texturing. */ 149 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: 150 case PIPE_CAP_MAX_COMBINED_SAMPLERS: 151 return 8; 152 case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: 153 return 0; 154 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 155 return I915_MAX_TEXTURE_2D_LEVELS; 156 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 157 return I915_MAX_TEXTURE_3D_LEVELS; 158 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 159 return I915_MAX_TEXTURE_2D_LEVELS; 160 161 /* Render targets. */ 162 case PIPE_CAP_MAX_RENDER_TARGETS: 163 return 1; 164 165 /* Fragment coordinate conventions. */ 166 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 167 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 168 return 1; 169 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 170 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 171 return 0; 172 173 default: 174 debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); 175 return 0; 176 } 177} 178 179static int 180i915_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap cap) 181{ 182 switch(shader) { 183 case PIPE_SHADER_VERTEX: 184 return draw_get_shader_param(shader, cap); 185 case PIPE_SHADER_FRAGMENT: 186 break; 187 default: 188 return 0; 189 } 190 191 /* XXX: these are just shader model 2.0 values, fix this! */ 192 switch(cap) { 193 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 194 return 96; 195 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 196 return 64; 197 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 198 return 32; 199 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 200 return 8; 201 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 202 return 0; 203 case PIPE_SHADER_CAP_MAX_INPUTS: 204 return 10; 205 case PIPE_SHADER_CAP_MAX_CONSTS: 206 return 32; 207 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 208 return 1; 209 case PIPE_SHADER_CAP_MAX_TEMPS: 210 return 12; /* XXX: 12 -> 32 ? */ 211 case PIPE_SHADER_CAP_MAX_ADDRS: 212 return 0; 213 case PIPE_SHADER_CAP_MAX_PREDS: 214 return 0; 215 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 216 return 0; 217 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 218 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 219 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 220 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 221 return 1; 222 case PIPE_SHADER_CAP_SUBROUTINES: 223 return 0; 224 default: 225 debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); 226 return 0; 227 } 228} 229 230static float 231i915_get_paramf(struct pipe_screen *screen, enum pipe_cap cap) 232{ 233 switch(cap) { 234 case PIPE_CAP_MAX_LINE_WIDTH: 235 /* fall-through */ 236 case PIPE_CAP_MAX_LINE_WIDTH_AA: 237 return 7.5; 238 239 case PIPE_CAP_MAX_POINT_WIDTH: 240 /* fall-through */ 241 case PIPE_CAP_MAX_POINT_WIDTH_AA: 242 return 255.0; 243 244 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: 245 return 4.0; 246 247 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: 248 return 16.0; 249 250 default: 251 debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); 252 return 0; 253 } 254} 255 256boolean 257i915_is_format_supported(struct pipe_screen *screen, 258 enum pipe_format format, 259 enum pipe_texture_target target, 260 unsigned sample_count, 261 unsigned tex_usage) 262{ 263 static const enum pipe_format tex_supported[] = { 264 PIPE_FORMAT_B8G8R8A8_UNORM, 265 PIPE_FORMAT_B8G8R8X8_UNORM, 266 PIPE_FORMAT_R8G8B8A8_UNORM, 267 PIPE_FORMAT_R8G8B8X8_UNORM, 268 PIPE_FORMAT_B5G6R5_UNORM, 269 PIPE_FORMAT_L8_UNORM, 270 PIPE_FORMAT_A8_UNORM, 271 PIPE_FORMAT_I8_UNORM, 272 PIPE_FORMAT_L8A8_UNORM, 273 PIPE_FORMAT_UYVY, 274 PIPE_FORMAT_YUYV, 275 /* XXX why not? 276 PIPE_FORMAT_Z16_UNORM, */ 277 PIPE_FORMAT_DXT1_RGB, 278 PIPE_FORMAT_DXT1_RGBA, 279 PIPE_FORMAT_DXT3_RGBA, 280 PIPE_FORMAT_DXT5_RGBA, 281 PIPE_FORMAT_Z24X8_UNORM, 282 PIPE_FORMAT_Z24_UNORM_S8_USCALED, 283 PIPE_FORMAT_NONE /* list terminator */ 284 }; 285 static const enum pipe_format render_supported[] = { 286 PIPE_FORMAT_B8G8R8A8_UNORM, 287 PIPE_FORMAT_R8G8B8A8_UNORM, 288 PIPE_FORMAT_B5G6R5_UNORM, 289 PIPE_FORMAT_L8_UNORM, 290 PIPE_FORMAT_A8_UNORM, 291 PIPE_FORMAT_I8_UNORM, 292 PIPE_FORMAT_NONE /* list terminator */ 293 }; 294 static const enum pipe_format depth_supported[] = { 295 /* XXX why not? 296 PIPE_FORMAT_Z16_UNORM, */ 297 PIPE_FORMAT_Z24X8_UNORM, 298 PIPE_FORMAT_Z24_UNORM_S8_USCALED, 299 PIPE_FORMAT_NONE /* list terminator */ 300 }; 301 const enum pipe_format *list; 302 uint i; 303 304 if (!util_format_is_supported(format, tex_usage)) 305 return FALSE; 306 307 if (sample_count > 1) 308 return FALSE; 309 310 if(tex_usage & PIPE_BIND_DEPTH_STENCIL) 311 list = depth_supported; 312 else if (tex_usage & PIPE_BIND_RENDER_TARGET) 313 list = render_supported; 314 else 315 list = tex_supported; 316 317 for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) { 318 if (list[i] == format) 319 return TRUE; 320 } 321 322 return FALSE; 323} 324 325 326/* 327 * Fence functions 328 */ 329 330 331static void 332i915_fence_reference(struct pipe_screen *screen, 333 struct pipe_fence_handle **ptr, 334 struct pipe_fence_handle *fence) 335{ 336 struct i915_screen *is = i915_screen(screen); 337 338 is->iws->fence_reference(is->iws, ptr, fence); 339} 340 341static boolean 342i915_fence_signalled(struct pipe_screen *screen, 343 struct pipe_fence_handle *fence) 344{ 345 struct i915_screen *is = i915_screen(screen); 346 347 return is->iws->fence_signalled(is->iws, fence) == 0; 348} 349 350static boolean 351i915_fence_finish(struct pipe_screen *screen, 352 struct pipe_fence_handle *fence, 353 uint64_t timeout) 354{ 355 struct i915_screen *is = i915_screen(screen); 356 357 return is->iws->fence_finish(is->iws, fence) == 0; 358} 359 360 361/* 362 * Generic functions 363 */ 364 365 366static void 367i915_flush_frontbuffer(struct pipe_screen *screen, 368 struct pipe_resource *resource, 369 unsigned level, unsigned layer, 370 void *winsys_drawable_handle) 371{ 372 /* XXX: Dummy right now. */ 373 (void)screen; 374 (void)resource; 375 (void)level; 376 (void)layer; 377 (void)winsys_drawable_handle; 378} 379 380static void 381i915_destroy_screen(struct pipe_screen *screen) 382{ 383 struct i915_screen *is = i915_screen(screen); 384 385 if (is->iws) 386 is->iws->destroy(is->iws); 387 388 FREE(is); 389} 390 391/** 392 * Create a new i915_screen object 393 */ 394struct pipe_screen * 395i915_screen_create(struct i915_winsys *iws) 396{ 397 struct i915_screen *is = CALLOC_STRUCT(i915_screen); 398 399 if (!is) 400 return NULL; 401 402 switch (iws->pci_id) { 403 case PCI_CHIP_I915_G: 404 case PCI_CHIP_I915_GM: 405 is->is_i945 = FALSE; 406 break; 407 408 case PCI_CHIP_I945_G: 409 case PCI_CHIP_I945_GM: 410 case PCI_CHIP_I945_GME: 411 case PCI_CHIP_G33_G: 412 case PCI_CHIP_Q33_G: 413 case PCI_CHIP_Q35_G: 414 case PCI_CHIP_PINEVIEW_G: 415 case PCI_CHIP_PINEVIEW_M: 416 is->is_i945 = TRUE; 417 break; 418 419 default: 420 debug_printf("%s: unknown pci id 0x%x, cannot create screen\n", 421 __FUNCTION__, iws->pci_id); 422 FREE(is); 423 return NULL; 424 } 425 426 is->iws = iws; 427 428 is->base.winsys = NULL; 429 430 is->base.destroy = i915_destroy_screen; 431 is->base.flush_frontbuffer = i915_flush_frontbuffer; 432 433 is->base.get_name = i915_get_name; 434 is->base.get_vendor = i915_get_vendor; 435 is->base.get_param = i915_get_param; 436 is->base.get_shader_param = i915_get_shader_param; 437 is->base.get_paramf = i915_get_paramf; 438 is->base.is_format_supported = i915_is_format_supported; 439 440 is->base.context_create = i915_create_context; 441 442 is->base.fence_reference = i915_fence_reference; 443 is->base.fence_signalled = i915_fence_signalled; 444 is->base.fence_finish = i915_fence_finish; 445 446 i915_init_screen_resource_functions(is); 447 448 i915_debug_init(is); 449 450 util_format_s3tc_init(); 451 452 return &is->base; 453} 454