svga_screen.c revision 2d958853080d74da3abb4251fba75cd7df9cd879
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_public.h" 33#include "svga_context.h" 34#include "svga_screen.h" 35#include "svga_resource_texture.h" 36#include "svga_resource.h" 37#include "svga_debug.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, NULL }, 47 { "tgsi", DEBUG_TGSI, NULL }, 48 { "pipe", DEBUG_PIPE, NULL }, 49 { "state", DEBUG_STATE, NULL }, 50 { "screen", DEBUG_SCREEN, NULL }, 51 { "tex", DEBUG_TEX, NULL }, 52 { "swtnl", DEBUG_SWTNL, NULL }, 53 { "const", DEBUG_CONSTS, NULL }, 54 { "viewport", DEBUG_VIEWPORT, NULL }, 55 { "views", DEBUG_VIEWS, NULL }, 56 { "perf", DEBUG_PERF, NULL }, 57 { "flush", DEBUG_FLUSH, NULL }, 58 { "sync", DEBUG_SYNC, NULL }, 59 { "cache", DEBUG_CACHE, NULL }, 60 DEBUG_NAMED_VALUE_END 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 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: 183 return 1; 184 185 default: 186 return 0; 187 } 188} 189 190 191/* This is a fairly pointless interface 192 */ 193static int 194svga_get_param(struct pipe_screen *screen, enum pipe_cap param) 195{ 196 return (int) svga_get_paramf( screen, param ); 197} 198 199static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param) 200{ 201 struct svga_screen *svgascreen = svga_screen(screen); 202 struct svga_winsys_screen *sws = svgascreen->sws; 203 SVGA3dDevCapResult result; 204 205 switch (shader) 206 { 207 case PIPE_SHADER_FRAGMENT: 208 switch (param) 209 { 210 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 211 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 212 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 213 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 214 return svgascreen->use_ps30 ? 512 : 96; 215 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 216 return SVGA3D_MAX_NESTING_LEVEL; 217 case PIPE_SHADER_CAP_MAX_INPUTS: 218 return 10; 219 case PIPE_SHADER_CAP_MAX_CONSTS: 220 return svgascreen->use_ps30 ? 224 : 16; 221 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 222 return 1; 223 case PIPE_SHADER_CAP_MAX_TEMPS: 224 if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS, &result)) 225 return svgascreen->use_ps30 ? 32 : 12; 226 return result.u; 227 case PIPE_SHADER_CAP_MAX_ADDRS: 228 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 229 /* 230 * Although PS 3.0 has some addressing abilities it can only represent 231 * loops that can be statically determined and unrolled. Given we can 232 * only handle a subset of the cases that the state tracker already 233 * does it is better to defer loop unrolling to the state tracker. 234 */ 235 return 0; 236 case PIPE_SHADER_CAP_MAX_PREDS: 237 return svgascreen->use_ps30 ? 1 : 0; 238 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 239 return 1; 240 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 241 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 242 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 243 return 0; 244 case PIPE_SHADER_CAP_SUBROUTINES: 245 return 0; 246 } 247 break; 248 case PIPE_SHADER_VERTEX: 249 switch (param) 250 { 251 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 252 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 253 if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS, &result)) 254 return svgascreen->use_vs30 ? 512 : 256; 255 return result.u; 256 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 257 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 258 /* XXX: until we have vertex texture support */ 259 return 0; 260 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 261 return SVGA3D_MAX_NESTING_LEVEL; 262 case PIPE_SHADER_CAP_MAX_INPUTS: 263 return 16; 264 case PIPE_SHADER_CAP_MAX_CONSTS: 265 return 256; 266 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 267 return 1; 268 case PIPE_SHADER_CAP_MAX_TEMPS: 269 if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS, &result)) 270 return svgascreen->use_vs30 ? 32 : 12; 271 return result.u; 272 case PIPE_SHADER_CAP_MAX_ADDRS: 273 return svgascreen->use_vs30 ? 1 : 0; 274 case PIPE_SHADER_CAP_MAX_PREDS: 275 return svgascreen->use_vs30 ? 1 : 0; 276 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 277 return 1; 278 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 279 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 280 return svgascreen->use_vs30 ? 1 : 0; 281 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 282 return 0; 283 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 284 return 1; 285 case PIPE_SHADER_CAP_SUBROUTINES: 286 return 0; 287 default: 288 break; 289 } 290 break; 291 default: 292 break; 293 } 294 return 0; 295} 296 297static INLINE SVGA3dDevCapIndex 298svga_translate_format_cap(enum pipe_format format) 299{ 300 switch(format) { 301 302 case PIPE_FORMAT_B8G8R8A8_UNORM: 303 return SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8; 304 case PIPE_FORMAT_B8G8R8X8_UNORM: 305 return SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8; 306 307 case PIPE_FORMAT_B5G6R5_UNORM: 308 return SVGA3D_DEVCAP_SURFACEFMT_R5G6B5; 309 case PIPE_FORMAT_B5G5R5A1_UNORM: 310 return SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5; 311 case PIPE_FORMAT_B4G4R4A4_UNORM: 312 return SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4; 313 314 case PIPE_FORMAT_Z16_UNORM: 315 return SVGA3D_DEVCAP_SURFACEFMT_Z_D16; 316 case PIPE_FORMAT_S8_USCALED_Z24_UNORM: 317 return SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8; 318 case PIPE_FORMAT_X8Z24_UNORM: 319 return SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8; 320 321 case PIPE_FORMAT_A8_UNORM: 322 return SVGA3D_DEVCAP_SURFACEFMT_ALPHA8; 323 case PIPE_FORMAT_L8_UNORM: 324 return SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8; 325 326 case PIPE_FORMAT_DXT1_RGB: 327 case PIPE_FORMAT_DXT1_RGBA: 328 return SVGA3D_DEVCAP_SURFACEFMT_DXT1; 329 case PIPE_FORMAT_DXT3_RGBA: 330 return SVGA3D_DEVCAP_SURFACEFMT_DXT3; 331 case PIPE_FORMAT_DXT5_RGBA: 332 return SVGA3D_DEVCAP_SURFACEFMT_DXT5; 333 334 default: 335 return SVGA3D_DEVCAP_MAX; 336 } 337} 338 339 340static boolean 341svga_is_format_supported( struct pipe_screen *screen, 342 enum pipe_format format, 343 enum pipe_texture_target target, 344 unsigned sample_count, 345 unsigned tex_usage, 346 unsigned geom_flags ) 347{ 348 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 349 SVGA3dDevCapIndex index; 350 SVGA3dDevCapResult result; 351 352 assert(tex_usage); 353 354 if (sample_count > 1) 355 return FALSE; 356 357 /* Override host capabilities */ 358 if (tex_usage & PIPE_BIND_RENDER_TARGET) { 359 switch(format) { 360 361 /* Often unsupported/problematic. This means we end up with the same 362 * visuals for all virtual hardware implementations. 363 */ 364 case PIPE_FORMAT_B4G4R4A4_UNORM: 365 case PIPE_FORMAT_B5G5R5A1_UNORM: 366 return FALSE; 367 368 /* Simulate ability to render into compressed textures */ 369 case PIPE_FORMAT_DXT1_RGB: 370 case PIPE_FORMAT_DXT1_RGBA: 371 case PIPE_FORMAT_DXT3_RGBA: 372 case PIPE_FORMAT_DXT5_RGBA: 373 return TRUE; 374 375 default: 376 break; 377 } 378 } 379 380 /* Try to query the host */ 381 index = svga_translate_format_cap(format); 382 if( index < SVGA3D_DEVCAP_MAX && 383 sws->get_cap(sws, index, &result) ) 384 { 385 SVGA3dSurfaceFormatCaps mask; 386 387 mask.value = 0; 388 if (tex_usage & PIPE_BIND_RENDER_TARGET) 389 mask.offscreenRenderTarget = 1; 390 if (tex_usage & PIPE_BIND_DEPTH_STENCIL) 391 mask.zStencil = 1; 392 if (tex_usage & PIPE_BIND_SAMPLER_VIEW) 393 mask.texture = 1; 394 395 if ((result.u & mask.value) == mask.value) 396 return TRUE; 397 else 398 return FALSE; 399 } 400 401 /* Use our translate functions directly rather than relying on a 402 * duplicated list of supported formats which is prone to getting 403 * out of sync: 404 */ 405 if(tex_usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL)) 406 return svga_translate_format_render(format) != SVGA3D_FORMAT_INVALID; 407 else 408 return svga_translate_format(format) != SVGA3D_FORMAT_INVALID; 409} 410 411 412static void 413svga_fence_reference(struct pipe_screen *screen, 414 struct pipe_fence_handle **ptr, 415 struct pipe_fence_handle *fence) 416{ 417 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 418 sws->fence_reference(sws, ptr, fence); 419} 420 421 422static int 423svga_fence_signalled(struct pipe_screen *screen, 424 struct pipe_fence_handle *fence, 425 unsigned flag) 426{ 427 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 428 return sws->fence_signalled(sws, fence, flag); 429} 430 431 432static int 433svga_fence_finish(struct pipe_screen *screen, 434 struct pipe_fence_handle *fence, 435 unsigned flag) 436{ 437 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 438 439 SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n", 440 __FUNCTION__, fence); 441 442 return sws->fence_finish(sws, fence, flag); 443} 444 445 446static void 447svga_destroy_screen( struct pipe_screen *screen ) 448{ 449 struct svga_screen *svgascreen = svga_screen(screen); 450 451 svga_screen_cache_cleanup(svgascreen); 452 453 pipe_mutex_destroy(svgascreen->swc_mutex); 454 pipe_mutex_destroy(svgascreen->tex_mutex); 455 456 svgascreen->sws->destroy(svgascreen->sws); 457 458 FREE(svgascreen); 459} 460 461 462/** 463 * Create a new svga_screen object 464 */ 465struct pipe_screen * 466svga_screen_create(struct svga_winsys_screen *sws) 467{ 468 struct svga_screen *svgascreen; 469 struct pipe_screen *screen; 470 SVGA3dDevCapResult result; 471 472#ifdef DEBUG 473 SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 ); 474#endif 475 476 svgascreen = CALLOC_STRUCT(svga_screen); 477 if (!svgascreen) 478 goto error1; 479 480 svgascreen->debug.force_level_surface_view = 481 debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE); 482 svgascreen->debug.force_surface_view = 483 debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE); 484 svgascreen->debug.force_sampler_view = 485 debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE); 486 svgascreen->debug.no_surface_view = 487 debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE); 488 svgascreen->debug.no_sampler_view = 489 debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE); 490 491 screen = &svgascreen->screen; 492 493 screen->destroy = svga_destroy_screen; 494 screen->get_name = svga_get_name; 495 screen->get_vendor = svga_get_vendor; 496 screen->get_param = svga_get_param; 497 screen->get_shader_param = svga_get_shader_param; 498 screen->get_paramf = svga_get_paramf; 499 screen->is_format_supported = svga_is_format_supported; 500 screen->context_create = svga_context_create; 501 screen->fence_reference = svga_fence_reference; 502 screen->fence_signalled = svga_fence_signalled; 503 screen->fence_finish = svga_fence_finish; 504 svgascreen->sws = sws; 505 506 svga_init_screen_resource_functions(svgascreen); 507 508 svgascreen->use_ps30 = 509 sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) && 510 result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE; 511 512 svgascreen->use_vs30 = 513 sws->get_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION, &result) && 514 result.u >= SVGA3DVSVERSION_30 ? TRUE : FALSE; 515 516#if 1 517 /* Shader model 2.0 is unsupported at the moment. */ 518 if(!svgascreen->use_ps30 || !svgascreen->use_vs30) 519 goto error2; 520#else 521 if(debug_get_bool_option("SVGA_NO_SM30", FALSE)) 522 svgascreen->use_vs30 = svgascreen->use_ps30 = FALSE; 523#endif 524 525 pipe_mutex_init(svgascreen->tex_mutex); 526 pipe_mutex_init(svgascreen->swc_mutex); 527 528 svga_screen_cache_init(svgascreen); 529 530 return screen; 531error2: 532 FREE(svgascreen); 533error1: 534 return NULL; 535} 536 537struct svga_winsys_screen * 538svga_winsys_screen(struct pipe_screen *screen) 539{ 540 return svga_screen(screen)->sws; 541} 542 543#ifdef DEBUG 544struct svga_screen * 545svga_screen(struct pipe_screen *screen) 546{ 547 assert(screen); 548 assert(screen->destroy == svga_destroy_screen); 549 return (struct svga_screen *)screen; 550} 551#endif 552