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