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