svga_screen.c revision 3293bcdc80cdfa20a2381aae2b94505bdf95d857
1/********************************************************** 2 * Copyright 2008-2009 VMware, Inc. All rights reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 **********************************************************/ 25 26#include "util/u_memory.h" 27#include "util/u_inlines.h" 28#include "util/u_string.h" 29#include "util/u_math.h" 30 31#include "svga_winsys.h" 32#include "svga_context.h" 33#include "svga_screen.h" 34#include "svga_resource_texture.h" 35#include "svga_resource.h" 36#include "svga_debug.h" 37#include "svga_surface.h" 38 39#include "svga3d_shaderdefs.h" 40 41 42#ifdef DEBUG 43int SVGA_DEBUG = 0; 44 45static const struct debug_named_value svga_debug_flags[] = { 46 { "dma", DEBUG_DMA }, 47 { "tgsi", DEBUG_TGSI }, 48 { "pipe", DEBUG_PIPE }, 49 { "state", DEBUG_STATE }, 50 { "screen", DEBUG_SCREEN }, 51 { "tex", DEBUG_TEX }, 52 { "swtnl", DEBUG_SWTNL }, 53 { "const", DEBUG_CONSTS }, 54 { "viewport", DEBUG_VIEWPORT }, 55 { "views", DEBUG_VIEWS }, 56 { "perf", DEBUG_PERF }, 57 { "flush", DEBUG_FLUSH }, 58 { "sync", DEBUG_SYNC }, 59 { "cache", DEBUG_CACHE }, 60 {NULL, 0} 61}; 62#endif 63 64static const char * 65svga_get_vendor( struct pipe_screen *pscreen ) 66{ 67 return "VMware, Inc."; 68} 69 70 71static const char * 72svga_get_name( struct pipe_screen *pscreen ) 73{ 74#ifdef DEBUG 75 /* Only return internal details in the DEBUG version: 76 */ 77 return "SVGA3D; build: DEBUG; mutex: " PIPE_ATOMIC; 78#else 79 return "SVGA3D; build: RELEASE; "; 80#endif 81} 82 83 84 85 86static float 87svga_get_paramf(struct pipe_screen *screen, enum pipe_cap param) 88{ 89 struct svga_screen *svgascreen = svga_screen(screen); 90 struct svga_winsys_screen *sws = svgascreen->sws; 91 SVGA3dDevCapResult result; 92 93 switch (param) { 94 case PIPE_CAP_MAX_LINE_WIDTH: 95 /* fall-through */ 96 case PIPE_CAP_MAX_LINE_WIDTH_AA: 97 return 7.0; 98 99 case PIPE_CAP_MAX_POINT_WIDTH: 100 /* fall-through */ 101 case PIPE_CAP_MAX_POINT_WIDTH_AA: 102 /* Keep this to a reasonable size to avoid failures in 103 * conform/pntaa.c: 104 */ 105 return SVGA_MAX_POINTSIZE; 106 107 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: 108 if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, &result)) 109 return 4.0; 110 return result.u; 111 112 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: 113 return 16.0; 114 115 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: 116 return 16; 117 case PIPE_CAP_MAX_COMBINED_SAMPLERS: 118 return 16; 119 case PIPE_CAP_NPOT_TEXTURES: 120 return 1; 121 case PIPE_CAP_TWO_SIDED_STENCIL: 122 return 1; 123 case PIPE_CAP_GLSL: 124 return svgascreen->use_ps30 && svgascreen->use_vs30; 125 case PIPE_CAP_ANISOTROPIC_FILTER: 126 return 1; 127 case PIPE_CAP_POINT_SPRITE: 128 return 1; 129 case PIPE_CAP_MAX_RENDER_TARGETS: 130 if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_RENDER_TARGETS, &result)) 131 return 1; 132 if(!result.u) 133 return 1; 134 return MIN2(result.u, PIPE_MAX_COLOR_BUFS); 135 case PIPE_CAP_OCCLUSION_QUERY: 136 return 1; 137 case PIPE_CAP_TIMER_QUERY: 138 return 0; 139 case PIPE_CAP_TEXTURE_SHADOW_MAP: 140 return 1; 141 142 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 143 { 144 unsigned levels = SVGA_MAX_TEXTURE_LEVELS; 145 if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result)) 146 levels = MIN2(util_logbase2(result.u) + 1, levels); 147 else 148 levels = 12 /* 2048x2048 */; 149 if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result)) 150 levels = MIN2(util_logbase2(result.u) + 1, levels); 151 else 152 levels = 12 /* 2048x2048 */; 153 return levels; 154 } 155 156 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 157 if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result)) 158 return 8; /* max 128x128x128 */ 159 return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS); 160 161 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 162 /* 163 * No mechanism to query the host, and at least limited to 2048x2048 on 164 * certain hardware. 165 */ 166 return MIN2(screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS), 167 12.0 /* 2048x2048 */); 168 169 case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */ 170 return 1; 171 172 case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */ 173 return 1; 174 175 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 176 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 177 return 1; 178 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 179 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 180 return 0; 181 182 /* 183 * Fragment shader limits 184 */ 185 186 case PIPE_CAP_MAX_FS_INSTRUCTIONS: 187 case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS: 188 case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS: 189 case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS: 190 return svgascreen->use_ps30 ? 512 : 96; 191 case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH: 192 return SVGA3D_MAX_NESTING_LEVEL; 193 case PIPE_CAP_MAX_FS_INPUTS: 194 return 10; 195 case PIPE_CAP_MAX_FS_CONSTS: 196 return svgascreen->use_vs30 ? 224 : 16; 197 case PIPE_CAP_MAX_FS_TEMPS: 198 if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS, &result)) 199 return svgascreen->use_ps30 ? 32 : 12; 200 return result.u; 201 case PIPE_CAP_MAX_FS_ADDRS: 202 return svgascreen->use_ps30 ? 1 : 0; 203 case PIPE_CAP_MAX_FS_PREDS: 204 return svgascreen->use_ps30 ? 1 : 0; 205 206 /* 207 * Vertex shader limits 208 */ 209 case PIPE_CAP_MAX_VS_INSTRUCTIONS: 210 case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS: 211 if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS, &result)) 212 return svgascreen->use_vs30 ? 512 : 256; 213 return result.u; 214 case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS: 215 case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS: 216 /* XXX: until we have vertex texture support */ 217 return 0; 218 case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH: 219 return SVGA3D_MAX_NESTING_LEVEL; 220 case PIPE_CAP_MAX_VS_INPUTS: 221 return 16; 222 case PIPE_CAP_MAX_VS_CONSTS: 223 return 256; 224 case PIPE_CAP_MAX_VS_TEMPS: 225 if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS, &result)) 226 return svgascreen->use_vs30 ? 32 : 12; 227 return result.u; 228 case PIPE_CAP_MAX_VS_ADDRS: 229 return svgascreen->use_vs30 ? 1 : 0; 230 case PIPE_CAP_MAX_VS_PREDS: 231 return svgascreen->use_vs30 ? 1 : 0; 232 233 default: 234 return 0; 235 } 236} 237 238 239/* This is a fairly pointless interface 240 */ 241static int 242svga_get_param(struct pipe_screen *screen, enum pipe_cap param) 243{ 244 return (int) svga_get_paramf( screen, param ); 245} 246 247 248static INLINE SVGA3dDevCapIndex 249svga_translate_format_cap(enum pipe_format format) 250{ 251 switch(format) { 252 253 case PIPE_FORMAT_B8G8R8A8_UNORM: 254 return SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8; 255 case PIPE_FORMAT_B8G8R8X8_UNORM: 256 return SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8; 257 258 case PIPE_FORMAT_B5G6R5_UNORM: 259 return SVGA3D_DEVCAP_SURFACEFMT_R5G6B5; 260 case PIPE_FORMAT_B5G5R5A1_UNORM: 261 return SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5; 262 case PIPE_FORMAT_B4G4R4A4_UNORM: 263 return SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4; 264 265 case PIPE_FORMAT_Z16_UNORM: 266 return SVGA3D_DEVCAP_SURFACEFMT_Z_D16; 267 case PIPE_FORMAT_S8_USCALED_Z24_UNORM: 268 return SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8; 269 case PIPE_FORMAT_X8Z24_UNORM: 270 return SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8; 271 272 case PIPE_FORMAT_A8_UNORM: 273 return SVGA3D_DEVCAP_SURFACEFMT_ALPHA8; 274 case PIPE_FORMAT_L8_UNORM: 275 return SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8; 276 277 case PIPE_FORMAT_DXT1_RGB: 278 case PIPE_FORMAT_DXT1_RGBA: 279 return SVGA3D_DEVCAP_SURFACEFMT_DXT1; 280 case PIPE_FORMAT_DXT3_RGBA: 281 return SVGA3D_DEVCAP_SURFACEFMT_DXT3; 282 case PIPE_FORMAT_DXT5_RGBA: 283 return SVGA3D_DEVCAP_SURFACEFMT_DXT5; 284 285 default: 286 return SVGA3D_DEVCAP_MAX; 287 } 288} 289 290 291static boolean 292svga_is_format_supported( struct pipe_screen *screen, 293 enum pipe_format format, 294 enum pipe_texture_target target, 295 unsigned sample_count, 296 unsigned tex_usage, 297 unsigned geom_flags ) 298{ 299 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 300 SVGA3dDevCapIndex index; 301 SVGA3dDevCapResult result; 302 303 assert(tex_usage); 304 305 if (sample_count > 1) 306 return FALSE; 307 308 /* Override host capabilities */ 309 if (tex_usage & PIPE_BIND_RENDER_TARGET) { 310 switch(format) { 311 312 /* Often unsupported/problematic. This means we end up with the same 313 * visuals for all virtual hardware implementations. 314 */ 315 case PIPE_FORMAT_B4G4R4A4_UNORM: 316 case PIPE_FORMAT_B5G5R5A1_UNORM: 317 return FALSE; 318 319 /* Simulate ability to render into compressed textures */ 320 case PIPE_FORMAT_DXT1_RGB: 321 case PIPE_FORMAT_DXT1_RGBA: 322 case PIPE_FORMAT_DXT3_RGBA: 323 case PIPE_FORMAT_DXT5_RGBA: 324 return TRUE; 325 326 default: 327 break; 328 } 329 } 330 331 /* Try to query the host */ 332 index = svga_translate_format_cap(format); 333 if( index < SVGA3D_DEVCAP_MAX && 334 sws->get_cap(sws, index, &result) ) 335 { 336 SVGA3dSurfaceFormatCaps mask; 337 338 mask.value = 0; 339 if (tex_usage & PIPE_BIND_RENDER_TARGET) 340 mask.offscreenRenderTarget = 1; 341 if (tex_usage & PIPE_BIND_DEPTH_STENCIL) 342 mask.zStencil = 1; 343 if (tex_usage & PIPE_BIND_SAMPLER_VIEW) 344 mask.texture = 1; 345 346 if ((result.u & mask.value) == mask.value) 347 return TRUE; 348 else 349 return FALSE; 350 } 351 352 /* Use our translate functions directly rather than relying on a 353 * duplicated list of supported formats which is prone to getting 354 * out of sync: 355 */ 356 if(tex_usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL)) 357 return svga_translate_format_render(format) != SVGA3D_FORMAT_INVALID; 358 else 359 return svga_translate_format(format) != SVGA3D_FORMAT_INVALID; 360} 361 362 363static void 364svga_fence_reference(struct pipe_screen *screen, 365 struct pipe_fence_handle **ptr, 366 struct pipe_fence_handle *fence) 367{ 368 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 369 sws->fence_reference(sws, ptr, fence); 370} 371 372 373static int 374svga_fence_signalled(struct pipe_screen *screen, 375 struct pipe_fence_handle *fence, 376 unsigned flag) 377{ 378 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 379 return sws->fence_signalled(sws, fence, flag); 380} 381 382 383static int 384svga_fence_finish(struct pipe_screen *screen, 385 struct pipe_fence_handle *fence, 386 unsigned flag) 387{ 388 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 389 390 SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n", 391 __FUNCTION__, fence); 392 393 return sws->fence_finish(sws, fence, flag); 394} 395 396 397static void 398svga_destroy_screen( struct pipe_screen *screen ) 399{ 400 struct svga_screen *svgascreen = svga_screen(screen); 401 402 svga_screen_cache_cleanup(svgascreen); 403 404 pipe_mutex_destroy(svgascreen->swc_mutex); 405 pipe_mutex_destroy(svgascreen->tex_mutex); 406 407 svgascreen->sws->destroy(svgascreen->sws); 408 409 FREE(svgascreen); 410} 411 412 413/** 414 * Create a new svga_screen object 415 */ 416struct pipe_screen * 417svga_screen_create(struct svga_winsys_screen *sws) 418{ 419 struct svga_screen *svgascreen; 420 struct pipe_screen *screen; 421 SVGA3dDevCapResult result; 422 423#ifdef DEBUG 424 SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 ); 425#endif 426 427 svgascreen = CALLOC_STRUCT(svga_screen); 428 if (!svgascreen) 429 goto error1; 430 431 svgascreen->debug.force_level_surface_view = 432 debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE); 433 svgascreen->debug.force_surface_view = 434 debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE); 435 svgascreen->debug.force_sampler_view = 436 debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE); 437 svgascreen->debug.no_surface_view = 438 debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE); 439 svgascreen->debug.no_sampler_view = 440 debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE); 441 442 screen = &svgascreen->screen; 443 444 screen->destroy = svga_destroy_screen; 445 screen->get_name = svga_get_name; 446 screen->get_vendor = svga_get_vendor; 447 screen->get_param = svga_get_param; 448 screen->get_paramf = svga_get_paramf; 449 screen->is_format_supported = svga_is_format_supported; 450 screen->context_create = svga_context_create; 451 screen->fence_reference = svga_fence_reference; 452 screen->fence_signalled = svga_fence_signalled; 453 screen->fence_finish = svga_fence_finish; 454 svgascreen->sws = sws; 455 456 svga_screen_init_surface_functions(screen); 457 svga_init_screen_resource_functions(svgascreen); 458 459 svgascreen->use_ps30 = 460 sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) && 461 result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE; 462 463 svgascreen->use_vs30 = 464 sws->get_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION, &result) && 465 result.u >= SVGA3DVSVERSION_30 ? TRUE : FALSE; 466 467#if 1 468 /* Shader model 2.0 is unsupported at the moment. */ 469 if(!svgascreen->use_ps30 || !svgascreen->use_vs30) 470 goto error2; 471#else 472 if(debug_get_bool_option("SVGA_NO_SM30", FALSE)) 473 svgascreen->use_vs30 = svgascreen->use_ps30 = FALSE; 474#endif 475 476 pipe_mutex_init(svgascreen->tex_mutex); 477 pipe_mutex_init(svgascreen->swc_mutex); 478 479 svga_screen_cache_init(svgascreen); 480 481 return screen; 482error2: 483 FREE(svgascreen); 484error1: 485 return NULL; 486} 487 488struct svga_winsys_screen * 489svga_winsys_screen(struct pipe_screen *screen) 490{ 491 return svga_screen(screen)->sws; 492} 493 494#ifdef DEBUG 495struct svga_screen * 496svga_screen(struct pipe_screen *screen) 497{ 498 assert(screen); 499 assert(screen->destroy == svga_destroy_screen); 500 return (struct svga_screen *)screen; 501} 502#endif 503