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_format.h" 35 #include "svga_screen.h" 36 #include "svga_resource_texture.h" 37 #include "svga_resource.h" 38 #include "svga_debug.h" 39 40 #include "svga3d_shaderdefs.h" 41 42 43 #ifdef DEBUG 44 int SVGA_DEBUG = 0; 45 46 static const struct debug_named_value svga_debug_flags[] = { 47 { "dma", DEBUG_DMA, NULL }, 48 { "tgsi", DEBUG_TGSI, NULL }, 49 { "pipe", DEBUG_PIPE, NULL }, 50 { "state", DEBUG_STATE, NULL }, 51 { "screen", DEBUG_SCREEN, NULL }, 52 { "tex", DEBUG_TEX, NULL }, 53 { "swtnl", DEBUG_SWTNL, NULL }, 54 { "const", DEBUG_CONSTS, NULL }, 55 { "viewport", DEBUG_VIEWPORT, NULL }, 56 { "views", DEBUG_VIEWS, NULL }, 57 { "perf", DEBUG_PERF, NULL }, 58 { "flush", DEBUG_FLUSH, NULL }, 59 { "sync", DEBUG_SYNC, NULL }, 60 { "cache", DEBUG_CACHE, NULL }, 61 DEBUG_NAMED_VALUE_END 62 }; 63 #endif 64 65 static const char * 66 svga_get_vendor( struct pipe_screen *pscreen ) 67 { 68 return "VMware, Inc."; 69 } 70 71 72 static const char * 73 svga_get_name( struct pipe_screen *pscreen ) 74 { 75 const char *build = "", *llvm = "", *mutex = ""; 76 static char name[100]; 77 #ifdef DEBUG 78 /* Only return internal details in the DEBUG version: 79 */ 80 build = "build: DEBUG;"; 81 mutex = "mutex: " PIPE_ATOMIC ";"; 82 #ifdef HAVE_LLVM 83 llvm = "LLVM;"; 84 #endif 85 #else 86 build = "build: RELEASE;"; 87 #endif 88 89 util_snprintf(name, sizeof(name), "SVGA3D; %s %s %s", build, mutex, llvm); 90 return name; 91 } 92 93 94 95 96 static float 97 svga_get_paramf(struct pipe_screen *screen, enum pipe_capf param) 98 { 99 struct svga_screen *svgascreen = svga_screen(screen); 100 struct svga_winsys_screen *sws = svgascreen->sws; 101 SVGA3dDevCapResult result; 102 103 switch (param) { 104 case PIPE_CAPF_MAX_LINE_WIDTH: 105 /* fall-through */ 106 case PIPE_CAPF_MAX_LINE_WIDTH_AA: 107 return 7.0; 108 109 case PIPE_CAPF_MAX_POINT_WIDTH: 110 /* fall-through */ 111 case PIPE_CAPF_MAX_POINT_WIDTH_AA: 112 return svgascreen->maxPointSize; 113 114 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 115 if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, &result)) 116 return 4.0; 117 return result.u; 118 119 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 120 return 15.0; 121 case PIPE_CAPF_GUARD_BAND_LEFT: 122 case PIPE_CAPF_GUARD_BAND_TOP: 123 case PIPE_CAPF_GUARD_BAND_RIGHT: 124 case PIPE_CAPF_GUARD_BAND_BOTTOM: 125 return 0.0; 126 } 127 128 debug_printf("Unexpected PIPE_CAPF_ query %u\n", param); 129 return 0; 130 } 131 132 133 static int 134 svga_get_param(struct pipe_screen *screen, enum pipe_cap param) 135 { 136 struct svga_screen *svgascreen = svga_screen(screen); 137 struct svga_winsys_screen *sws = svgascreen->sws; 138 SVGA3dDevCapResult result; 139 140 switch (param) { 141 case PIPE_CAP_MAX_COMBINED_SAMPLERS: 142 return 16; 143 case PIPE_CAP_NPOT_TEXTURES: 144 return 1; 145 case PIPE_CAP_TWO_SIDED_STENCIL: 146 return 1; 147 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 148 return 0; 149 case PIPE_CAP_ANISOTROPIC_FILTER: 150 return 1; 151 case PIPE_CAP_POINT_SPRITE: 152 return 1; 153 case PIPE_CAP_MAX_RENDER_TARGETS: 154 if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_RENDER_TARGETS, &result)) 155 return 1; 156 if(!result.u) 157 return 1; 158 return MIN2(result.u, PIPE_MAX_COLOR_BUFS); 159 case PIPE_CAP_OCCLUSION_QUERY: 160 return 1; 161 case PIPE_CAP_TIMER_QUERY: 162 return 0; 163 case PIPE_CAP_TEXTURE_SHADOW_MAP: 164 return 1; 165 case PIPE_CAP_TEXTURE_SWIZZLE: 166 return 1; 167 case PIPE_CAP_USER_VERTEX_BUFFERS: 168 case PIPE_CAP_USER_INDEX_BUFFERS: 169 return 0; 170 case PIPE_CAP_USER_CONSTANT_BUFFERS: 171 return 1; 172 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 173 return 16; 174 175 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 176 { 177 unsigned levels = SVGA_MAX_TEXTURE_LEVELS; 178 if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result)) 179 levels = MIN2(util_logbase2(result.u) + 1, levels); 180 else 181 levels = 12 /* 2048x2048 */; 182 if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result)) 183 levels = MIN2(util_logbase2(result.u) + 1, levels); 184 else 185 levels = 12 /* 2048x2048 */; 186 return levels; 187 } 188 189 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 190 if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result)) 191 return 8; /* max 128x128x128 */ 192 return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS); 193 194 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 195 /* 196 * No mechanism to query the host, and at least limited to 2048x2048 on 197 * certain hardware. 198 */ 199 return MIN2(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS), 200 12 /* 2048x2048 */); 201 202 case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */ 203 return 1; 204 205 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 206 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 207 return 1; 208 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 209 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 210 return 0; 211 212 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: 213 return 1; 214 215 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 216 return 1; /* The color outputs of vertex shaders are not clamped */ 217 case PIPE_CAP_VERTEX_COLOR_CLAMPED: 218 return 0; /* The driver can't clamp vertex colors */ 219 case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: 220 return 0; /* The driver can't clamp fragment colors */ 221 222 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 223 return 1; /* expected for GL_ARB_framebuffer_object */ 224 225 case PIPE_CAP_GLSL_FEATURE_LEVEL: 226 return 120; 227 228 /* Unsupported features */ 229 case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 230 case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 231 case PIPE_CAP_SM3: 232 case PIPE_CAP_SHADER_STENCIL_EXPORT: 233 case PIPE_CAP_DEPTH_CLIP_DISABLE: 234 case PIPE_CAP_SEAMLESS_CUBE_MAP: 235 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 236 case PIPE_CAP_INDEP_BLEND_ENABLE: 237 case PIPE_CAP_INDEP_BLEND_FUNC: 238 case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 239 case PIPE_CAP_PRIMITIVE_RESTART: 240 case PIPE_CAP_TGSI_INSTANCEID: 241 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 242 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 243 case PIPE_CAP_SCALED_RESOLVE: 244 case PIPE_CAP_MIN_TEXEL_OFFSET: 245 case PIPE_CAP_MAX_TEXEL_OFFSET: 246 case PIPE_CAP_CONDITIONAL_RENDER: 247 case PIPE_CAP_TEXTURE_BARRIER: 248 case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 249 case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 250 case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 251 case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS: 252 case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: 253 case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: 254 case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: 255 case PIPE_CAP_COMPUTE: 256 case PIPE_CAP_START_INSTANCE: 257 case PIPE_CAP_QUERY_TIMESTAMP: 258 return 0; 259 case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: 260 return 1; 261 } 262 263 debug_printf("Unexpected PIPE_CAP_ query %u\n", param); 264 return 0; 265 } 266 267 static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param) 268 { 269 struct svga_screen *svgascreen = svga_screen(screen); 270 struct svga_winsys_screen *sws = svgascreen->sws; 271 SVGA3dDevCapResult result; 272 273 switch (shader) 274 { 275 case PIPE_SHADER_FRAGMENT: 276 switch (param) 277 { 278 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 279 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 280 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 281 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 282 return 512; 283 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 284 return SVGA3D_MAX_NESTING_LEVEL; 285 case PIPE_SHADER_CAP_MAX_INPUTS: 286 return 10; 287 case PIPE_SHADER_CAP_MAX_CONSTS: 288 return 224; 289 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 290 return 1; 291 case PIPE_SHADER_CAP_MAX_TEMPS: 292 if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS, &result)) 293 return 32; 294 return MIN2(result.u, SVGA3D_TEMPREG_MAX); 295 case PIPE_SHADER_CAP_MAX_ADDRS: 296 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 297 /* 298 * Although PS 3.0 has some addressing abilities it can only represent 299 * loops that can be statically determined and unrolled. Given we can 300 * only handle a subset of the cases that the state tracker already 301 * does it is better to defer loop unrolling to the state tracker. 302 */ 303 return 0; 304 case PIPE_SHADER_CAP_MAX_PREDS: 305 return 1; 306 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 307 return 1; 308 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 309 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 310 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 311 return 0; 312 case PIPE_SHADER_CAP_SUBROUTINES: 313 return 0; 314 case PIPE_SHADER_CAP_INTEGERS: 315 return 0; 316 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 317 return 16; 318 default: 319 debug_printf("Unexpected vertex shader query %u\n", param); 320 return 0; 321 } 322 break; 323 case PIPE_SHADER_VERTEX: 324 switch (param) 325 { 326 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 327 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 328 if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS, &result)) 329 return 512; 330 return result.u; 331 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 332 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 333 /* XXX: until we have vertex texture support */ 334 return 0; 335 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 336 return SVGA3D_MAX_NESTING_LEVEL; 337 case PIPE_SHADER_CAP_MAX_INPUTS: 338 return 16; 339 case PIPE_SHADER_CAP_MAX_CONSTS: 340 return 256; 341 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 342 return 1; 343 case PIPE_SHADER_CAP_MAX_TEMPS: 344 if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS, &result)) 345 return 32; 346 return MIN2(result.u, SVGA3D_TEMPREG_MAX); 347 case PIPE_SHADER_CAP_MAX_ADDRS: 348 return 1; 349 case PIPE_SHADER_CAP_MAX_PREDS: 350 return 1; 351 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 352 return 1; 353 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 354 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 355 return 1; 356 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 357 return 0; 358 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 359 return 1; 360 case PIPE_SHADER_CAP_SUBROUTINES: 361 return 0; 362 case PIPE_SHADER_CAP_INTEGERS: 363 return 0; 364 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 365 return 0; 366 default: 367 debug_printf("Unexpected vertex shader query %u\n", param); 368 return 0; 369 } 370 break; 371 case PIPE_SHADER_GEOMETRY: 372 /* no support for geometry shaders at this time */ 373 return 0; 374 default: 375 debug_printf("Unexpected shader type (%u) query\n", shader); 376 return 0; 377 } 378 return 0; 379 } 380 381 382 static boolean 383 svga_is_format_supported( struct pipe_screen *screen, 384 enum pipe_format format, 385 enum pipe_texture_target target, 386 unsigned sample_count, 387 unsigned tex_usage) 388 { 389 struct svga_screen *ss = svga_screen(screen); 390 SVGA3dSurfaceFormat svga_format; 391 SVGA3dSurfaceFormatCaps caps; 392 SVGA3dSurfaceFormatCaps mask; 393 394 assert(tex_usage); 395 396 if (sample_count > 1) { 397 return FALSE; 398 } 399 400 svga_format = svga_translate_format(ss, format, tex_usage); 401 if (svga_format == SVGA3D_FORMAT_INVALID) { 402 return FALSE; 403 } 404 405 /* 406 * Override host capabilities, so that we end up with the same 407 * visuals for all virtual hardware implementations. 408 */ 409 410 if (tex_usage & PIPE_BIND_DISPLAY_TARGET) { 411 switch (svga_format) { 412 case SVGA3D_A8R8G8B8: 413 case SVGA3D_X8R8G8B8: 414 case SVGA3D_R5G6B5: 415 break; 416 417 /* Often unsupported/problematic. This means we end up with the same 418 * visuals for all virtual hardware implementations. 419 */ 420 case SVGA3D_A4R4G4B4: 421 case SVGA3D_A1R5G5B5: 422 return FALSE; 423 424 default: 425 return FALSE; 426 } 427 } 428 429 /* 430 * Query the host capabilities. 431 */ 432 433 svga_get_format_cap(ss, svga_format, &caps); 434 435 mask.value = 0; 436 if (tex_usage & PIPE_BIND_RENDER_TARGET) { 437 mask.offscreenRenderTarget = 1; 438 } 439 if (tex_usage & PIPE_BIND_DEPTH_STENCIL) { 440 mask.zStencil = 1; 441 } 442 if (tex_usage & PIPE_BIND_SAMPLER_VIEW) { 443 mask.texture = 1; 444 } 445 446 return (caps.value & mask.value) == mask.value; 447 } 448 449 450 static void 451 svga_fence_reference(struct pipe_screen *screen, 452 struct pipe_fence_handle **ptr, 453 struct pipe_fence_handle *fence) 454 { 455 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 456 sws->fence_reference(sws, ptr, fence); 457 } 458 459 460 static boolean 461 svga_fence_signalled(struct pipe_screen *screen, 462 struct pipe_fence_handle *fence) 463 { 464 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 465 return sws->fence_signalled(sws, fence, 0) == 0; 466 } 467 468 469 static boolean 470 svga_fence_finish(struct pipe_screen *screen, 471 struct pipe_fence_handle *fence, 472 uint64_t timeout) 473 { 474 struct svga_winsys_screen *sws = svga_screen(screen)->sws; 475 476 SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n", 477 __FUNCTION__, fence); 478 479 return sws->fence_finish(sws, fence, 0) == 0; 480 } 481 482 483 static void 484 svga_destroy_screen( struct pipe_screen *screen ) 485 { 486 struct svga_screen *svgascreen = svga_screen(screen); 487 488 svga_screen_cache_cleanup(svgascreen); 489 490 pipe_mutex_destroy(svgascreen->swc_mutex); 491 pipe_mutex_destroy(svgascreen->tex_mutex); 492 493 svgascreen->sws->destroy(svgascreen->sws); 494 495 FREE(svgascreen); 496 } 497 498 499 /** 500 * Create a new svga_screen object 501 */ 502 struct pipe_screen * 503 svga_screen_create(struct svga_winsys_screen *sws) 504 { 505 struct svga_screen *svgascreen; 506 struct pipe_screen *screen; 507 SVGA3dDevCapResult result; 508 boolean use_vs30, use_ps30; 509 510 #ifdef DEBUG 511 SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 ); 512 #endif 513 514 svgascreen = CALLOC_STRUCT(svga_screen); 515 if (!svgascreen) 516 goto error1; 517 518 svgascreen->debug.force_level_surface_view = 519 debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE); 520 svgascreen->debug.force_surface_view = 521 debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE); 522 svgascreen->debug.force_sampler_view = 523 debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE); 524 svgascreen->debug.no_surface_view = 525 debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE); 526 svgascreen->debug.no_sampler_view = 527 debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE); 528 529 screen = &svgascreen->screen; 530 531 screen->destroy = svga_destroy_screen; 532 screen->get_name = svga_get_name; 533 screen->get_vendor = svga_get_vendor; 534 screen->get_param = svga_get_param; 535 screen->get_shader_param = svga_get_shader_param; 536 screen->get_paramf = svga_get_paramf; 537 screen->is_format_supported = svga_is_format_supported; 538 screen->context_create = svga_context_create; 539 screen->fence_reference = svga_fence_reference; 540 screen->fence_signalled = svga_fence_signalled; 541 screen->fence_finish = svga_fence_finish; 542 svgascreen->sws = sws; 543 544 svga_init_screen_resource_functions(svgascreen); 545 546 if (sws->get_hw_version) { 547 svgascreen->hw_version = sws->get_hw_version(sws); 548 } else { 549 svgascreen->hw_version = SVGA3D_HWVERSION_WS65_B1; 550 } 551 552 use_ps30 = 553 sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) && 554 result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE; 555 556 use_vs30 = 557 sws->get_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION, &result) && 558 result.u >= SVGA3DVSVERSION_30 ? TRUE : FALSE; 559 560 /* we require Shader model 3.0 or later */ 561 if (!use_ps30 || !use_vs30) 562 goto error2; 563 564 /* 565 * The D16, D24X8, and D24S8 formats always do an implicit shadow compare 566 * when sampled from, where as the DF16, DF24, and D24S8_INT do not. So 567 * we prefer the later when available. 568 * 569 * This mimics hardware vendors extensions for D3D depth sampling. See also 570 * http://aras-p.info/texts/D3D9GPUHacks.html 571 */ 572 573 { 574 boolean has_df16, has_df24, has_d24s8_int; 575 SVGA3dSurfaceFormatCaps caps; 576 SVGA3dSurfaceFormatCaps mask; 577 mask.value = 0; 578 mask.zStencil = 1; 579 mask.texture = 1; 580 581 svgascreen->depth.z16 = SVGA3D_Z_D16; 582 svgascreen->depth.x8z24 = SVGA3D_Z_D24X8; 583 svgascreen->depth.s8z24 = SVGA3D_Z_D24S8; 584 585 svga_get_format_cap(svgascreen, SVGA3D_Z_DF16, &caps); 586 has_df16 = (caps.value & mask.value) == mask.value; 587 588 svga_get_format_cap(svgascreen, SVGA3D_Z_DF24, &caps); 589 has_df24 = (caps.value & mask.value) == mask.value; 590 591 svga_get_format_cap(svgascreen, SVGA3D_Z_D24S8_INT, &caps); 592 has_d24s8_int = (caps.value & mask.value) == mask.value; 593 594 /* XXX: We might want some other logic here. 595 * Like if we only have d24s8_int we should 596 * emulate the other formats with that. 597 */ 598 if (has_df16) { 599 svgascreen->depth.z16 = SVGA3D_Z_DF16; 600 } 601 if (has_df24) { 602 svgascreen->depth.x8z24 = SVGA3D_Z_DF24; 603 } 604 if (has_d24s8_int) { 605 svgascreen->depth.s8z24 = SVGA3D_Z_D24S8_INT; 606 } 607 } 608 609 if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_POINT_SIZE, &result)) { 610 svgascreen->maxPointSize = 1.0F; 611 } else { 612 /* Keep this to a reasonable size to avoid failures in 613 * conform/pntaa.c: 614 */ 615 svgascreen->maxPointSize = MIN2(result.f, 80.0f); 616 } 617 618 pipe_mutex_init(svgascreen->tex_mutex); 619 pipe_mutex_init(svgascreen->swc_mutex); 620 621 svga_screen_cache_init(svgascreen); 622 623 return screen; 624 error2: 625 FREE(svgascreen); 626 error1: 627 return NULL; 628 } 629 630 struct svga_winsys_screen * 631 svga_winsys_screen(struct pipe_screen *screen) 632 { 633 return svga_screen(screen)->sws; 634 } 635 636 #ifdef DEBUG 637 struct svga_screen * 638 svga_screen(struct pipe_screen *screen) 639 { 640 assert(screen); 641 assert(screen->destroy == svga_destroy_screen); 642 return (struct svga_screen *)screen; 643 } 644 #endif 645