svga_screen.c revision b84590994c4261d85485357263146d5e3d8827eb
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, int 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_TEXTURE_SHADOW_MAP: 138 return 1; 139 140 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 141 { 142 unsigned levels = SVGA_MAX_TEXTURE_LEVELS; 143 if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result)) 144 levels = MIN2(util_logbase2(result.u) + 1, levels); 145 else 146 levels = 12 /* 2048x2048 */; 147 if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result)) 148 levels = MIN2(util_logbase2(result.u) + 1, levels); 149 else 150 levels = 12 /* 2048x2048 */; 151 return levels; 152 } 153 154 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 155 if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result)) 156 return 8; /* max 128x128x128 */ 157 return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS); 158 159 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 160 /* 161 * No mechanism to query the host, and at least limited to 2048x2048 on 162 * certain hardware. 163 */ 164 return MIN2(screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS), 165 12.0 /* 2048x2048 */); 166 167 case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */ 168 return 1; 169 170 case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */ 171 return 1; 172 173 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 174 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 175 return 1; 176 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 177 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 178 return 0; 179 180 default: 181 return 0; 182 } 183} 184 185 186/* This is a fairly pointless interface 187 */ 188static int 189svga_get_param(struct pipe_screen *screen, int param) 190{ 191 return (int) svga_get_paramf( screen, param ); 192} 193 194 195static INLINE SVGA3dDevCapIndex 196svga_translate_format_cap(enum pipe_format format) 197{ 198 switch(format) { 199 200 case PIPE_FORMAT_B8G8R8A8_UNORM: 201 return SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8; 202 case PIPE_FORMAT_B8G8R8X8_UNORM: 203 return SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8; 204 205 case PIPE_FORMAT_B5G6R5_UNORM: 206 return SVGA3D_DEVCAP_SURFACEFMT_R5G6B5; 207 case PIPE_FORMAT_B5G5R5A1_UNORM: 208 return SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5; 209 case PIPE_FORMAT_B4G4R4A4_UNORM: 210 return SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4; 211 212 case PIPE_FORMAT_Z16_UNORM: 213 return SVGA3D_DEVCAP_SURFACEFMT_Z_D16; 214 case PIPE_FORMAT_S8_USCALED_Z24_UNORM: 215 return SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8; 216 case PIPE_FORMAT_X8Z24_UNORM: 217 return SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8; 218 219 case PIPE_FORMAT_A8_UNORM: 220 return SVGA3D_DEVCAP_SURFACEFMT_ALPHA8; 221 case PIPE_FORMAT_L8_UNORM: 222 return SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8; 223 224 case PIPE_FORMAT_DXT1_RGB: 225 case PIPE_FORMAT_DXT1_RGBA: 226 return SVGA3D_DEVCAP_SURFACEFMT_DXT1; 227 case PIPE_FORMAT_DXT3_RGBA: 228 return SVGA3D_DEVCAP_SURFACEFMT_DXT3; 229 case PIPE_FORMAT_DXT5_RGBA: 230 return SVGA3D_DEVCAP_SURFACEFMT_DXT5; 231 232 default: 233 return SVGA3D_DEVCAP_MAX; 234 } 235} 236 237 238static boolean 239svga_is_format_supported( struct pipe_screen *screen, 240 enum pipe_format format, 241 enum pipe_texture_target target, 242 unsigned tex_usage, 243 unsigned geom_flags ) 244{ 245 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 246 SVGA3dDevCapIndex index; 247 SVGA3dDevCapResult result; 248 249 assert(tex_usage); 250 251 /* Override host capabilities */ 252 if (tex_usage & PIPE_BIND_RENDER_TARGET) { 253 switch(format) { 254 255 /* Often unsupported/problematic. This means we end up with the same 256 * visuals for all virtual hardware implementations. 257 */ 258 case PIPE_FORMAT_B4G4R4A4_UNORM: 259 case PIPE_FORMAT_B5G5R5A1_UNORM: 260 return FALSE; 261 262 /* Simulate ability to render into compressed textures */ 263 case PIPE_FORMAT_DXT1_RGB: 264 case PIPE_FORMAT_DXT1_RGBA: 265 case PIPE_FORMAT_DXT3_RGBA: 266 case PIPE_FORMAT_DXT5_RGBA: 267 return TRUE; 268 269 default: 270 break; 271 } 272 } 273 274 /* Try to query the host */ 275 index = svga_translate_format_cap(format); 276 if( index < SVGA3D_DEVCAP_MAX && 277 sws->get_cap(sws, index, &result) ) 278 { 279 SVGA3dSurfaceFormatCaps mask; 280 281 mask.value = 0; 282 if (tex_usage & PIPE_BIND_RENDER_TARGET) 283 mask.offscreenRenderTarget = 1; 284 if (tex_usage & PIPE_BIND_DEPTH_STENCIL) 285 mask.zStencil = 1; 286 if (tex_usage & PIPE_BIND_SAMPLER_VIEW) 287 mask.texture = 1; 288 289 if ((result.u & mask.value) == mask.value) 290 return TRUE; 291 else 292 return FALSE; 293 } 294 295 /* Use our translate functions directly rather than relying on a 296 * duplicated list of supported formats which is prone to getting 297 * out of sync: 298 */ 299 if(tex_usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL)) 300 return svga_translate_format_render(format) != SVGA3D_FORMAT_INVALID; 301 else 302 return svga_translate_format(format) != SVGA3D_FORMAT_INVALID; 303} 304 305 306static void 307svga_fence_reference(struct pipe_screen *screen, 308 struct pipe_fence_handle **ptr, 309 struct pipe_fence_handle *fence) 310{ 311 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 312 sws->fence_reference(sws, ptr, fence); 313} 314 315 316static int 317svga_fence_signalled(struct pipe_screen *screen, 318 struct pipe_fence_handle *fence, 319 unsigned flag) 320{ 321 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 322 return sws->fence_signalled(sws, fence, flag); 323} 324 325 326static int 327svga_fence_finish(struct pipe_screen *screen, 328 struct pipe_fence_handle *fence, 329 unsigned flag) 330{ 331 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 332 333 SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n", 334 __FUNCTION__, fence); 335 336 return sws->fence_finish(sws, fence, flag); 337} 338 339 340static void 341svga_destroy_screen( struct pipe_screen *screen ) 342{ 343 struct svga_screen *svgascreen = svga_screen(screen); 344 345 svga_screen_cache_cleanup(svgascreen); 346 347 pipe_mutex_destroy(svgascreen->swc_mutex); 348 pipe_mutex_destroy(svgascreen->tex_mutex); 349 350 svgascreen->sws->destroy(svgascreen->sws); 351 352 FREE(svgascreen); 353} 354 355 356/** 357 * Create a new svga_screen object 358 */ 359struct pipe_screen * 360svga_screen_create(struct svga_winsys_screen *sws) 361{ 362 struct svga_screen *svgascreen; 363 struct pipe_screen *screen; 364 SVGA3dDevCapResult result; 365 366#ifdef DEBUG 367 SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 ); 368#endif 369 370 svgascreen = CALLOC_STRUCT(svga_screen); 371 if (!svgascreen) 372 goto error1; 373 374 svgascreen->debug.force_level_surface_view = 375 debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE); 376 svgascreen->debug.force_surface_view = 377 debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE); 378 svgascreen->debug.force_sampler_view = 379 debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE); 380 svgascreen->debug.no_surface_view = 381 debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE); 382 svgascreen->debug.no_sampler_view = 383 debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE); 384 385 screen = &svgascreen->screen; 386 387 screen->destroy = svga_destroy_screen; 388 screen->get_name = svga_get_name; 389 screen->get_vendor = svga_get_vendor; 390 screen->get_param = svga_get_param; 391 screen->get_paramf = svga_get_paramf; 392 screen->is_format_supported = svga_is_format_supported; 393 screen->context_create = svga_context_create; 394 screen->fence_reference = svga_fence_reference; 395 screen->fence_signalled = svga_fence_signalled; 396 screen->fence_finish = svga_fence_finish; 397 svgascreen->sws = sws; 398 399 svga_screen_init_surface_functions(svgascreen); 400 svga_init_screen_resource_functions(svgascreen); 401 402 svgascreen->use_ps30 = 403 sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) && 404 result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE; 405 406 svgascreen->use_vs30 = 407 sws->get_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION, &result) && 408 result.u >= SVGA3DVSVERSION_30 ? TRUE : FALSE; 409 410#if 1 411 /* Shader model 2.0 is unsupported at the moment. */ 412 if(!svgascreen->use_ps30 || !svgascreen->use_vs30) 413 goto error2; 414#else 415 if(debug_get_bool_option("SVGA_NO_SM30", FALSE)) 416 svgascreen->use_vs30 = svgascreen->use_ps30 = FALSE; 417#endif 418 419 pipe_mutex_init(svgascreen->tex_mutex); 420 pipe_mutex_init(svgascreen->swc_mutex); 421 422 svga_screen_cache_init(svgascreen); 423 424 return screen; 425error2: 426 FREE(svgascreen); 427error1: 428 return NULL; 429} 430 431struct svga_winsys_screen * 432svga_winsys_screen(struct pipe_screen *screen) 433{ 434 return svga_screen(screen)->sws; 435} 436 437#ifdef DEBUG 438struct svga_screen * 439svga_screen(struct pipe_screen *screen) 440{ 441 assert(screen); 442 assert(screen->destroy == svga_destroy_screen); 443 return (struct svga_screen *)screen; 444} 445#endif 446