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