svga_screen.c revision b34d138d8453d45f29632d4dcbe040be11265d26
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_screen_texture.h" 35#include "svga_screen_buffer.h" 36#include "svga_debug.h" 37 38#include "svga3d_shaderdefs.h" 39 40 41#ifdef DEBUG 42int SVGA_DEBUG = 0; 43 44static const struct debug_named_value svga_debug_flags[] = { 45 { "dma", DEBUG_DMA }, 46 { "tgsi", DEBUG_TGSI }, 47 { "pipe", DEBUG_PIPE }, 48 { "state", DEBUG_STATE }, 49 { "screen", DEBUG_SCREEN }, 50 { "tex", DEBUG_TEX }, 51 { "swtnl", DEBUG_SWTNL }, 52 { "const", DEBUG_CONSTS }, 53 { "viewport", DEBUG_VIEWPORT }, 54 { "views", DEBUG_VIEWS }, 55 { "perf", DEBUG_PERF }, 56 { "flush", DEBUG_FLUSH }, 57 { "sync", DEBUG_SYNC }, 58 { "cache", DEBUG_CACHE }, 59 {NULL, 0} 60}; 61#endif 62 63static const char * 64svga_get_vendor( struct pipe_screen *pscreen ) 65{ 66 return "VMware, Inc."; 67} 68 69 70static const char * 71svga_get_name( struct pipe_screen *pscreen ) 72{ 73#ifdef DEBUG 74 /* Only return internal details in the DEBUG version: 75 */ 76 return "SVGA3D; build: DEBUG; mutex: " PIPE_ATOMIC; 77#else 78 return "SVGA3D; build: RELEASE; "; 79#endif 80} 81 82 83 84 85static float 86svga_get_paramf(struct pipe_screen *screen, int param) 87{ 88 struct svga_screen *svgascreen = svga_screen(screen); 89 struct svga_winsys_screen *sws = svgascreen->sws; 90 SVGA3dDevCapResult result; 91 92 switch (param) { 93 case PIPE_CAP_MAX_LINE_WIDTH: 94 /* fall-through */ 95 case PIPE_CAP_MAX_LINE_WIDTH_AA: 96 return 7.0; 97 98 case PIPE_CAP_MAX_POINT_WIDTH: 99 /* fall-through */ 100 case PIPE_CAP_MAX_POINT_WIDTH_AA: 101 /* Keep this to a reasonable size to avoid failures in 102 * conform/pntaa.c: 103 */ 104 return SVGA_MAX_POINTSIZE; 105 106 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: 107 if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, &result)) 108 return 4.0; 109 return result.u; 110 111 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: 112 return 16.0; 113 114 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: 115 return 16; 116 case PIPE_CAP_MAX_COMBINED_SAMPLERS: 117 return 16; 118 case PIPE_CAP_NPOT_TEXTURES: 119 return 1; 120 case PIPE_CAP_TWO_SIDED_STENCIL: 121 return 1; 122 case PIPE_CAP_GLSL: 123 return svgascreen->use_ps30 && svgascreen->use_vs30; 124 case PIPE_CAP_ANISOTROPIC_FILTER: 125 return 1; 126 case PIPE_CAP_POINT_SPRITE: 127 return 1; 128 case PIPE_CAP_MAX_RENDER_TARGETS: 129 if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_RENDER_TARGETS, &result)) 130 return 1; 131 if(!result.u) 132 return 1; 133 return MIN2(result.u, PIPE_MAX_COLOR_BUFS); 134 case PIPE_CAP_OCCLUSION_QUERY: 135 return 1; 136 case PIPE_CAP_TEXTURE_SHADOW_MAP: 137 return 1; 138 139 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 140 { 141 unsigned levels = SVGA_MAX_TEXTURE_LEVELS; 142 if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result)) 143 levels = MIN2(util_logbase2(result.u) + 1, levels); 144 else 145 levels = 12 /* 2048x2048 */; 146 if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result)) 147 levels = MIN2(util_logbase2(result.u) + 1, levels); 148 else 149 levels = 12 /* 2048x2048 */; 150 return levels; 151 } 152 153 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 154 if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result)) 155 return 8; /* max 128x128x128 */ 156 return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS); 157 158 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 159 /* 160 * No mechanism to query the host, and at least limited to 2048x2048 on 161 * certain hardware. 162 */ 163 return MIN2(screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS), 164 12.0 /* 2048x2048 */); 165 166 case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */ 167 return 1; 168 169 case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */ 170 return 1; 171 172 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 173 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 174 return 1; 175 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 176 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 177 return 0; 178 179 default: 180 return 0; 181 } 182} 183 184 185/* This is a fairly pointless interface 186 */ 187static int 188svga_get_param(struct pipe_screen *screen, int param) 189{ 190 return (int) svga_get_paramf( screen, param ); 191} 192 193 194static INLINE SVGA3dDevCapIndex 195svga_translate_format_cap(enum pipe_format format) 196{ 197 switch(format) { 198 199 case PIPE_FORMAT_B8G8R8A8_UNORM: 200 return SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8; 201 case PIPE_FORMAT_B8G8R8X8_UNORM: 202 return SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8; 203 204 case PIPE_FORMAT_B5G6R5_UNORM: 205 return SVGA3D_DEVCAP_SURFACEFMT_R5G6B5; 206 case PIPE_FORMAT_B5G5R5A1_UNORM: 207 return SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5; 208 case PIPE_FORMAT_B4G4R4A4_UNORM: 209 return SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4; 210 211 case PIPE_FORMAT_Z16_UNORM: 212 return SVGA3D_DEVCAP_SURFACEFMT_Z_D16; 213 case PIPE_FORMAT_S8Z24_UNORM: 214 return SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8; 215 case PIPE_FORMAT_X8Z24_UNORM: 216 return SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8; 217 218 case PIPE_FORMAT_A8_UNORM: 219 return SVGA3D_DEVCAP_SURFACEFMT_ALPHA8; 220 case PIPE_FORMAT_L8_UNORM: 221 return SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8; 222 223 case PIPE_FORMAT_DXT1_RGB: 224 case PIPE_FORMAT_DXT1_RGBA: 225 return SVGA3D_DEVCAP_SURFACEFMT_DXT1; 226 case PIPE_FORMAT_DXT3_RGBA: 227 return SVGA3D_DEVCAP_SURFACEFMT_DXT3; 228 case PIPE_FORMAT_DXT5_RGBA: 229 return SVGA3D_DEVCAP_SURFACEFMT_DXT5; 230 231 default: 232 return SVGA3D_DEVCAP_MAX; 233 } 234} 235 236 237static boolean 238svga_is_format_supported( struct pipe_screen *screen, 239 enum pipe_format format, 240 enum pipe_texture_target target, 241 unsigned tex_usage, 242 unsigned geom_flags ) 243{ 244 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 245 SVGA3dDevCapIndex index; 246 SVGA3dDevCapResult result; 247 248 assert(tex_usage); 249 250 /* Override host capabilities */ 251 if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { 252 switch(format) { 253 254 /* Often unsupported/problematic. This means we end up with the same 255 * visuals for all virtual hardware implementations. 256 */ 257 case PIPE_FORMAT_B4G4R4A4_UNORM: 258 case PIPE_FORMAT_B5G5R5A1_UNORM: 259 return FALSE; 260 261 /* Simulate ability to render into compressed textures */ 262 case PIPE_FORMAT_DXT1_RGB: 263 case PIPE_FORMAT_DXT1_RGBA: 264 case PIPE_FORMAT_DXT3_RGBA: 265 case PIPE_FORMAT_DXT5_RGBA: 266 return TRUE; 267 268 default: 269 break; 270 } 271 } 272 273 /* Try to query the host */ 274 index = svga_translate_format_cap(format); 275 if( index < SVGA3D_DEVCAP_MAX && 276 sws->get_cap(sws, index, &result) ) 277 { 278 SVGA3dSurfaceFormatCaps mask; 279 280 mask.value = 0; 281 if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) 282 mask.offscreenRenderTarget = 1; 283 if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) 284 mask.zStencil = 1; 285 if (tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) 286 mask.texture = 1; 287 288 if ((result.u & mask.value) == mask.value) 289 return TRUE; 290 else 291 return FALSE; 292 } 293 294 /* Use our translate functions directly rather than relying on a 295 * duplicated list of supported formats which is prone to getting 296 * out of sync: 297 */ 298 if(tex_usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DEPTH_STENCIL)) 299 return svga_translate_format_render(format) != SVGA3D_FORMAT_INVALID; 300 else 301 return svga_translate_format(format) != SVGA3D_FORMAT_INVALID; 302} 303 304 305static void 306svga_fence_reference(struct pipe_screen *screen, 307 struct pipe_fence_handle **ptr, 308 struct pipe_fence_handle *fence) 309{ 310 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 311 sws->fence_reference(sws, ptr, fence); 312} 313 314 315static int 316svga_fence_signalled(struct pipe_screen *screen, 317 struct pipe_fence_handle *fence, 318 unsigned flag) 319{ 320 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 321 return sws->fence_signalled(sws, fence, flag); 322} 323 324 325static int 326svga_fence_finish(struct pipe_screen *screen, 327 struct pipe_fence_handle *fence, 328 unsigned flag) 329{ 330 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 331 332 SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n", 333 __FUNCTION__, fence); 334 335 return sws->fence_finish(sws, fence, flag); 336} 337 338 339static void 340svga_destroy_screen( struct pipe_screen *screen ) 341{ 342 struct svga_screen *svgascreen = svga_screen(screen); 343 344 svga_screen_cache_cleanup(svgascreen); 345 346 pipe_mutex_destroy(svgascreen->swc_mutex); 347 pipe_mutex_destroy(svgascreen->tex_mutex); 348 349 svgascreen->swc->destroy(svgascreen->swc); 350 351 svgascreen->sws->destroy(svgascreen->sws); 352 353 FREE(svgascreen); 354} 355 356 357/** 358 * Create a new svga_screen object 359 */ 360struct pipe_screen * 361svga_screen_create(struct svga_winsys_screen *sws) 362{ 363 struct svga_screen *svgascreen; 364 struct pipe_screen *screen; 365 SVGA3dDevCapResult result; 366 367#ifdef DEBUG 368 SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 ); 369#endif 370 371 svgascreen = CALLOC_STRUCT(svga_screen); 372 if (!svgascreen) 373 goto error1; 374 375 svgascreen->debug.force_level_surface_view = 376 debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE); 377 svgascreen->debug.force_surface_view = 378 debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE); 379 svgascreen->debug.force_sampler_view = 380 debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE); 381 svgascreen->debug.no_surface_view = 382 debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE); 383 svgascreen->debug.no_sampler_view = 384 debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE); 385 386 screen = &svgascreen->screen; 387 388 screen->destroy = svga_destroy_screen; 389 screen->get_name = svga_get_name; 390 screen->get_vendor = svga_get_vendor; 391 screen->get_param = svga_get_param; 392 screen->get_paramf = svga_get_paramf; 393 screen->is_format_supported = svga_is_format_supported; 394 screen->context_create = svga_context_create; 395 screen->fence_reference = svga_fence_reference; 396 screen->fence_signalled = svga_fence_signalled; 397 screen->fence_finish = svga_fence_finish; 398 svgascreen->sws = sws; 399 400 svga_screen_init_texture_functions(screen); 401 svga_screen_init_buffer_functions(screen); 402 403 svgascreen->use_ps30 = 404 sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) && 405 result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE; 406 407 svgascreen->use_vs30 = 408 sws->get_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION, &result) && 409 result.u >= SVGA3DVSVERSION_30 ? TRUE : FALSE; 410 411#if 1 412 /* Shader model 2.0 is unsupported at the moment. */ 413 if(!svgascreen->use_ps30 || !svgascreen->use_vs30) 414 goto error2; 415#else 416 if(debug_get_bool_option("SVGA_NO_SM30", FALSE)) 417 svgascreen->use_vs30 = svgascreen->use_ps30 = FALSE; 418#endif 419 420 svgascreen->swc = sws->context_create(sws); 421 if(!svgascreen->swc) 422 goto error2; 423 424 pipe_mutex_init(svgascreen->tex_mutex); 425 pipe_mutex_init(svgascreen->swc_mutex); 426 427 svga_screen_cache_init(svgascreen); 428 429 return screen; 430error2: 431 FREE(svgascreen); 432error1: 433 return NULL; 434} 435 436void svga_screen_flush( struct svga_screen *svgascreen, 437 struct pipe_fence_handle **pfence ) 438{ 439 struct pipe_fence_handle *fence = NULL; 440 441 SVGA_DBG(DEBUG_PERF, "%s\n", __FUNCTION__); 442 443 pipe_mutex_lock(svgascreen->swc_mutex); 444 svgascreen->swc->flush(svgascreen->swc, &fence); 445 pipe_mutex_unlock(svgascreen->swc_mutex); 446 447 svga_screen_cache_flush(svgascreen, fence); 448 449 if(pfence) 450 *pfence = fence; 451 else 452 svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL); 453} 454 455struct svga_winsys_screen * 456svga_winsys_screen(struct pipe_screen *screen) 457{ 458 return svga_screen(screen)->sws; 459} 460 461#ifdef DEBUG 462struct svga_screen * 463svga_screen(struct pipe_screen *screen) 464{ 465 assert(screen); 466 assert(screen->destroy == svga_destroy_screen); 467 return (struct svga_screen *)screen; 468} 469#endif 470