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