svga_screen.c revision 3192633d4abe262d413e41feb871fe8deed409d8
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 "pipe/p_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_cmd.h" 37#include "svga_debug.h" 38 39#include "svga_hw_reg.h" 40#include "svga3d_shaderdefs.h" 41 42 43#ifdef DEBUG 44int SVGA_DEBUG = 0; 45 46static const struct debug_named_value svga_debug_flags[] = { 47 { "dma", DEBUG_DMA }, 48 { "tgsi", DEBUG_TGSI }, 49 { "pipe", DEBUG_PIPE }, 50 { "state", DEBUG_STATE }, 51 { "screen", DEBUG_SCREEN }, 52 { "tex", DEBUG_TEX }, 53 { "swtnl", DEBUG_SWTNL }, 54 { "const", DEBUG_CONSTS }, 55 { "viewport", DEBUG_VIEWPORT }, 56 { "views", DEBUG_VIEWS }, 57 { "perf", DEBUG_PERF }, 58 { "flush", DEBUG_FLUSH }, 59 { "sync", DEBUG_SYNC }, 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 80.0; 106 107 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: 108 return 4.0; 109 110 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: 111 return 16.0; 112 113 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: 114 return 16; 115 case PIPE_CAP_NPOT_TEXTURES: 116 return 1; 117 case PIPE_CAP_TWO_SIDED_STENCIL: 118 return 1; 119 case PIPE_CAP_GLSL: 120 return svgascreen->use_ps30 && svgascreen->use_vs30; 121 case PIPE_CAP_ANISOTROPIC_FILTER: 122 return 1; 123 case PIPE_CAP_POINT_SPRITE: 124 return 1; 125 case PIPE_CAP_MAX_RENDER_TARGETS: 126 if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_RENDER_TARGETS, &result)) 127 return 1; 128 if(!result.u) 129 return 1; 130 return MIN2(result.u, PIPE_MAX_COLOR_BUFS); 131 case PIPE_CAP_OCCLUSION_QUERY: 132 return 1; 133 case PIPE_CAP_TEXTURE_SHADOW_MAP: 134 return 1; 135 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 136 return SVGA_MAX_TEXTURE_LEVELS; 137 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 138 return 8; /* max 128x128x128 */ 139 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 140 return SVGA_MAX_TEXTURE_LEVELS; 141 142 case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */ 143 return 1; 144 145 case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */ 146 return 1; 147 148 default: 149 return 0; 150 } 151} 152 153 154/* This is a fairly pointless interface 155 */ 156static int 157svga_get_param(struct pipe_screen *screen, int param) 158{ 159 return (int) svga_get_paramf( screen, param ); 160} 161 162 163static INLINE SVGA3dDevCapIndex 164svga_translate_format_cap(enum pipe_format format) 165{ 166 switch(format) { 167 168 case PIPE_FORMAT_A8R8G8B8_UNORM: 169 return SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8; 170 case PIPE_FORMAT_X8R8G8B8_UNORM: 171 return SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8; 172 173 case PIPE_FORMAT_R5G6B5_UNORM: 174 return SVGA3D_DEVCAP_SURFACEFMT_R5G6B5; 175 case PIPE_FORMAT_A1R5G5B5_UNORM: 176 return SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5; 177 case PIPE_FORMAT_A4R4G4B4_UNORM: 178 return SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4; 179 180 case PIPE_FORMAT_Z16_UNORM: 181 return SVGA3D_DEVCAP_SURFACEFMT_Z_D16; 182 case PIPE_FORMAT_Z24S8_UNORM: 183 return SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8; 184 case PIPE_FORMAT_Z24X8_UNORM: 185 return SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8; 186 187 case PIPE_FORMAT_A8_UNORM: 188 return SVGA3D_DEVCAP_SURFACEFMT_ALPHA8; 189 case PIPE_FORMAT_L8_UNORM: 190 return SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8; 191 192 case PIPE_FORMAT_DXT1_RGB: 193 case PIPE_FORMAT_DXT1_RGBA: 194 return SVGA3D_DEVCAP_SURFACEFMT_DXT1; 195 case PIPE_FORMAT_DXT3_RGBA: 196 return SVGA3D_DEVCAP_SURFACEFMT_DXT3; 197 case PIPE_FORMAT_DXT5_RGBA: 198 return SVGA3D_DEVCAP_SURFACEFMT_DXT5; 199 200 default: 201 return SVGA3D_DEVCAP_MAX; 202 } 203} 204 205 206static boolean 207svga_is_format_supported( struct pipe_screen *screen, 208 enum pipe_format format, 209 enum pipe_texture_target target, 210 unsigned tex_usage, 211 unsigned geom_flags ) 212{ 213 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 214 SVGA3dDevCapIndex index; 215 SVGA3dDevCapResult result; 216 217 assert(tex_usage); 218 219 /* Override host capabilities */ 220 if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { 221 switch(format) { 222 223 /* Often unsupported/problematic. This means we end up with the same 224 * visuals for all virtual hardware implementations. 225 */ 226 case PIPE_FORMAT_A4R4G4B4_UNORM: 227 case PIPE_FORMAT_A1R5G5B5_UNORM: 228 return FALSE; 229 230 /* Simulate ability to render into compressed textures */ 231 case PIPE_FORMAT_DXT1_RGB: 232 case PIPE_FORMAT_DXT1_RGBA: 233 case PIPE_FORMAT_DXT3_RGBA: 234 case PIPE_FORMAT_DXT5_RGBA: 235 return TRUE; 236 237 default: 238 break; 239 } 240 } 241 242 /* Try to query the host */ 243 index = svga_translate_format_cap(format); 244 if( index < SVGA3D_DEVCAP_MAX && 245 sws->get_cap(sws, index, &result) ) 246 { 247 SVGA3dSurfaceFormatCaps mask; 248 249 mask.value = 0; 250 if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) 251 mask.offscreenRenderTarget = 1; 252 if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) 253 mask.zStencil = 1; 254 if (tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) 255 mask.texture = 1; 256 257 if ((result.u & mask.value) == mask.value) 258 return TRUE; 259 else 260 return FALSE; 261 } 262 263 /* Use our translate functions directly rather than relying on a 264 * duplicated list of supported formats which is prone to getting 265 * out of sync: 266 */ 267 if(tex_usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DEPTH_STENCIL)) 268 return svga_translate_format_render(format) != SVGA3D_FORMAT_INVALID; 269 else 270 return svga_translate_format(format) != SVGA3D_FORMAT_INVALID; 271} 272 273 274static void 275svga_fence_reference(struct pipe_screen *screen, 276 struct pipe_fence_handle **ptr, 277 struct pipe_fence_handle *fence) 278{ 279 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 280 sws->fence_reference(sws, ptr, fence); 281} 282 283 284static int 285svga_fence_signalled(struct pipe_screen *screen, 286 struct pipe_fence_handle *fence, 287 unsigned flag) 288{ 289 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 290 return sws->fence_signalled(sws, fence, flag); 291} 292 293 294static int 295svga_fence_finish(struct pipe_screen *screen, 296 struct pipe_fence_handle *fence, 297 unsigned flag) 298{ 299 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 300 return sws->fence_finish(sws, fence, flag); 301} 302 303 304static void 305svga_destroy_screen( struct pipe_screen *screen ) 306{ 307 struct svga_screen *svgascreen = svga_screen(screen); 308 309 svga_screen_cache_cleanup(svgascreen); 310 311 pipe_mutex_destroy(svgascreen->swc_mutex); 312 pipe_mutex_destroy(svgascreen->tex_mutex); 313 314 svgascreen->swc->destroy(svgascreen->swc); 315 316 svgascreen->sws->destroy(svgascreen->sws); 317 318 FREE(svgascreen); 319} 320 321 322/** 323 * Create a new svga_screen object 324 */ 325struct pipe_screen * 326svga_screen_create(struct svga_winsys_screen *sws) 327{ 328 struct svga_screen *svgascreen; 329 struct pipe_screen *screen; 330 SVGA3dDevCapResult result; 331 332#ifdef DEBUG 333 SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 ); 334#endif 335 336 svgascreen = CALLOC_STRUCT(svga_screen); 337 if (!svgascreen) 338 goto error1; 339 340 svgascreen->debug.force_level_surface_view = 341 debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE); 342 svgascreen->debug.force_surface_view = 343 debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE); 344 svgascreen->debug.force_sampler_view = 345 debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE); 346 svgascreen->debug.no_surface_view = 347 debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE); 348 svgascreen->debug.no_sampler_view = 349 debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE); 350 351 screen = &svgascreen->screen; 352 353 screen->destroy = svga_destroy_screen; 354 screen->get_name = svga_get_name; 355 screen->get_vendor = svga_get_vendor; 356 screen->get_param = svga_get_param; 357 screen->get_paramf = svga_get_paramf; 358 screen->is_format_supported = svga_is_format_supported; 359 screen->fence_reference = svga_fence_reference; 360 screen->fence_signalled = svga_fence_signalled; 361 screen->fence_finish = svga_fence_finish; 362 svgascreen->sws = sws; 363 364 svga_screen_init_texture_functions(screen); 365 svga_screen_init_buffer_functions(screen); 366 367 svgascreen->use_ps30 = 368 sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) && 369 result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE; 370 371 svgascreen->use_vs30 = 372 sws->get_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION, &result) && 373 result.u >= SVGA3DVSVERSION_30 ? TRUE : FALSE; 374 375#if 1 376 /* Shader model 2.0 is unsupported at the moment. */ 377 if(!svgascreen->use_ps30 || !svgascreen->use_vs30) 378 goto error2; 379#else 380 if(debug_get_bool_option("SVGA_NO_SM30", FALSE)) 381 svgascreen->use_vs30 = svgascreen->use_ps30 = FALSE; 382#endif 383 384 svgascreen->swc = sws->context_create(sws); 385 if(!svgascreen->swc) 386 goto error2; 387 388 pipe_mutex_init(svgascreen->tex_mutex); 389 pipe_mutex_init(svgascreen->swc_mutex); 390 391 LIST_INITHEAD(&svgascreen->cached_buffers); 392 393 svga_screen_cache_init(svgascreen); 394 395 return screen; 396error2: 397 FREE(svgascreen); 398error1: 399 return NULL; 400} 401 402void svga_screen_flush( struct svga_screen *svgascreen, 403 struct pipe_fence_handle **pfence ) 404{ 405 struct pipe_fence_handle *fence = NULL; 406 407 SVGA_DBG(DEBUG_PERF, "%s\n", __FUNCTION__); 408 409 pipe_mutex_lock(svgascreen->swc_mutex); 410 svgascreen->swc->flush(svgascreen->swc, &fence); 411 pipe_mutex_unlock(svgascreen->swc_mutex); 412 413 svga_screen_cache_flush(svgascreen, fence); 414 415 if(pfence) 416 *pfence = fence; 417 else 418 svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL); 419} 420 421struct svga_winsys_screen * 422svga_winsys_screen(struct pipe_screen *screen) 423{ 424 return svga_screen(screen)->sws; 425} 426 427#ifdef DEBUG 428struct svga_screen * 429svga_screen(struct pipe_screen *screen) 430{ 431 assert(screen); 432 assert(screen->destroy == svga_destroy_screen); 433 return (struct svga_screen *)screen; 434} 435#endif 436