9a2e7c6f5b0da27d632a80a6177a53e4d94d06d4
[profile/ivi/mesa.git] / src / gallium / drivers / svga / svga_screen.c
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_screen_texture.h"
35 #include "svga_screen_buffer.h"
36 #include "svga_debug.h"
37
38 #include "svga3d_shaderdefs.h"
39
40
41 #ifdef DEBUG
42 int SVGA_DEBUG = 0;
43
44 static const struct debug_named_value svga_debug_flags[] = {
45    { "dma",      DEBUG_DMA },
46    { "tgsi",     DEBUG_TGSI },
47    { "pipe",     DEBUG_PIPE },
48    { "state",    DEBUG_STATE },
49    { "screen",   DEBUG_SCREEN },
50    { "tex",      DEBUG_TEX },
51    { "swtnl",    DEBUG_SWTNL },
52    { "const",    DEBUG_CONSTS },
53    { "viewport", DEBUG_VIEWPORT },
54    { "views",    DEBUG_VIEWS },
55    { "perf",     DEBUG_PERF },
56    { "flush",    DEBUG_FLUSH },
57    { "sync",     DEBUG_SYNC },
58    { "cache",    DEBUG_CACHE },
59    {NULL, 0}
60 };
61 #endif
62
63 static const char *
64 svga_get_vendor( struct pipe_screen *pscreen )
65 {
66    return "VMware, Inc.";
67 }
68
69
70 static const char *
71 svga_get_name( struct pipe_screen *pscreen )
72 {
73 #ifdef DEBUG
74    /* Only return internal details in the DEBUG version:
75     */
76    return "SVGA3D; build: DEBUG; mutex: " PIPE_ATOMIC;
77 #else
78    return "SVGA3D; build: RELEASE; ";
79 #endif
80 }
81
82
83
84
85 static float
86 svga_get_paramf(struct pipe_screen *screen, int param)
87 {
88    struct svga_screen *svgascreen = svga_screen(screen);
89    struct svga_winsys_screen *sws = svgascreen->sws;
90    SVGA3dDevCapResult result;
91
92    switch (param) {
93    case PIPE_CAP_MAX_LINE_WIDTH:
94       /* fall-through */
95    case PIPE_CAP_MAX_LINE_WIDTH_AA:
96       return 7.0;
97
98    case PIPE_CAP_MAX_POINT_WIDTH:
99       /* fall-through */
100    case PIPE_CAP_MAX_POINT_WIDTH_AA:
101       /* Keep this to a reasonable size to avoid failures in
102        * conform/pntaa.c:
103        */
104       return SVGA_MAX_POINTSIZE;
105
106    case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
107       if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, &result))
108          return 4.0;
109       return result.u;
110
111    case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
112       return 16.0;
113
114    case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
115       return 16;
116    case PIPE_CAP_MAX_COMBINED_SAMPLERS:
117       return 16;
118    case PIPE_CAP_NPOT_TEXTURES:
119       return 1;
120    case PIPE_CAP_TWO_SIDED_STENCIL:
121       return 1;
122    case PIPE_CAP_GLSL:
123       return svgascreen->use_ps30 && svgascreen->use_vs30;
124    case PIPE_CAP_ANISOTROPIC_FILTER:
125       return 1;
126    case PIPE_CAP_POINT_SPRITE:
127       return 1;
128    case PIPE_CAP_MAX_RENDER_TARGETS:
129       if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_RENDER_TARGETS, &result))
130          return 1;
131       if(!result.u)
132          return 1;
133       return MIN2(result.u, PIPE_MAX_COLOR_BUFS);
134    case PIPE_CAP_OCCLUSION_QUERY:
135       return 1;
136    case PIPE_CAP_TEXTURE_SHADOW_MAP:
137       return 1;
138
139    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
140       {
141          unsigned levels = SVGA_MAX_TEXTURE_LEVELS;
142          if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result))
143             levels = MIN2(util_logbase2(result.u) + 1, levels);
144          else
145             levels = 12 /* 2048x2048 */;
146          if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result))
147             levels = MIN2(util_logbase2(result.u) + 1, levels);
148          else
149             levels = 12 /* 2048x2048 */;
150          return levels;
151       }
152
153    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
154       if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result))
155          return 8;  /* max 128x128x128 */
156       return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS);
157
158    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
159       /*
160        * No mechanism to query the host, and at least limited to 2048x2048 on
161        * certain hardware.
162        */
163       return MIN2(screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
164                   12.0 /* 2048x2048 */);
165
166    case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */
167       return 1;
168
169    case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */
170       return 1;
171
172    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
173    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
174       return 1;
175    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
176    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
177       return 0;
178
179    default:
180       return 0;
181    }
182 }
183
184
185 /* This is a fairly pointless interface
186  */
187 static int
188 svga_get_param(struct pipe_screen *screen, int param)
189 {
190    return (int) svga_get_paramf( screen, param );
191 }
192
193
194 static INLINE SVGA3dDevCapIndex
195 svga_translate_format_cap(enum pipe_format format)
196 {
197    switch(format) {
198    
199    case PIPE_FORMAT_B8G8R8A8_UNORM:
200       return SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8;
201    case PIPE_FORMAT_B8G8R8X8_UNORM:
202       return SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8;
203
204    case PIPE_FORMAT_B5G6R5_UNORM:
205       return SVGA3D_DEVCAP_SURFACEFMT_R5G6B5;
206    case PIPE_FORMAT_B5G5R5A1_UNORM:
207       return SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5;
208    case PIPE_FORMAT_B4G4R4A4_UNORM:
209       return SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4;
210
211    case PIPE_FORMAT_Z16_UNORM:
212       return SVGA3D_DEVCAP_SURFACEFMT_Z_D16;
213    case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
214       return SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8;
215    case PIPE_FORMAT_X8Z24_UNORM:
216       return SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8;
217
218    case PIPE_FORMAT_A8_UNORM:
219       return SVGA3D_DEVCAP_SURFACEFMT_ALPHA8;
220    case PIPE_FORMAT_L8_UNORM:
221       return SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8;
222
223    case PIPE_FORMAT_DXT1_RGB:
224    case PIPE_FORMAT_DXT1_RGBA:
225       return SVGA3D_DEVCAP_SURFACEFMT_DXT1;
226    case PIPE_FORMAT_DXT3_RGBA:
227       return SVGA3D_DEVCAP_SURFACEFMT_DXT3;
228    case PIPE_FORMAT_DXT5_RGBA:
229       return SVGA3D_DEVCAP_SURFACEFMT_DXT5;
230
231    default:
232       return SVGA3D_DEVCAP_MAX;
233    }
234 }
235
236
237 static boolean
238 svga_is_format_supported( struct pipe_screen *screen,
239                           enum pipe_format format, 
240                           enum pipe_texture_target target,
241                           unsigned tex_usage, 
242                           unsigned geom_flags )
243 {
244    struct svga_winsys_screen *sws = svga_screen(screen)->sws;
245    SVGA3dDevCapIndex index;
246    SVGA3dDevCapResult result;
247    
248    assert(tex_usage);
249
250    /* Override host capabilities */
251    if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
252       switch(format) { 
253
254       /* Often unsupported/problematic. This means we end up with the same
255        * visuals for all virtual hardware implementations.
256        */
257       case PIPE_FORMAT_B4G4R4A4_UNORM:
258       case PIPE_FORMAT_B5G5R5A1_UNORM:
259          return FALSE;
260          
261       /* Simulate ability to render into compressed textures */
262       case PIPE_FORMAT_DXT1_RGB:
263       case PIPE_FORMAT_DXT1_RGBA:
264       case PIPE_FORMAT_DXT3_RGBA:
265       case PIPE_FORMAT_DXT5_RGBA:
266          return TRUE;
267
268       default:
269          break;
270       }
271    }
272    
273    /* Try to query the host */
274    index = svga_translate_format_cap(format);
275    if( index < SVGA3D_DEVCAP_MAX && 
276        sws->get_cap(sws, index, &result) )
277    {
278       SVGA3dSurfaceFormatCaps mask;
279       
280       mask.value = 0;
281       if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET)
282          mask.offscreenRenderTarget = 1;
283       if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL)
284          mask.zStencil = 1;
285       if (tex_usage & PIPE_TEXTURE_USAGE_SAMPLER)
286          mask.texture = 1;
287
288       if ((result.u & mask.value) == mask.value)
289          return TRUE;
290       else
291          return FALSE;
292    }
293
294    /* Use our translate functions directly rather than relying on a
295     * duplicated list of supported formats which is prone to getting
296     * out of sync:
297     */
298    if(tex_usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
299       return svga_translate_format_render(format) != SVGA3D_FORMAT_INVALID;
300    else
301       return svga_translate_format(format) != SVGA3D_FORMAT_INVALID;
302 }
303
304
305 static void
306 svga_fence_reference(struct pipe_screen *screen,
307                      struct pipe_fence_handle **ptr,
308                      struct pipe_fence_handle *fence)
309 {
310    struct svga_winsys_screen *sws = svga_screen(screen)->sws;
311    sws->fence_reference(sws, ptr, fence);
312 }
313
314
315 static int
316 svga_fence_signalled(struct pipe_screen *screen,
317                      struct pipe_fence_handle *fence,
318                      unsigned flag)
319 {
320    struct svga_winsys_screen *sws = svga_screen(screen)->sws;
321    return sws->fence_signalled(sws, fence, flag);
322 }
323
324
325 static int
326 svga_fence_finish(struct pipe_screen *screen,
327                   struct pipe_fence_handle *fence,
328                   unsigned flag)
329 {
330    struct svga_winsys_screen *sws = svga_screen(screen)->sws;
331
332    SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n",
333             __FUNCTION__, fence);
334
335    return sws->fence_finish(sws, fence, flag);
336 }
337
338
339 static void
340 svga_destroy_screen( struct pipe_screen *screen )
341 {
342    struct svga_screen *svgascreen = svga_screen(screen);
343    
344    svga_screen_cache_cleanup(svgascreen);
345
346    pipe_mutex_destroy(svgascreen->swc_mutex);
347    pipe_mutex_destroy(svgascreen->tex_mutex);
348
349    svgascreen->swc->destroy(svgascreen->swc);
350    
351    svgascreen->sws->destroy(svgascreen->sws);
352    
353    FREE(svgascreen);
354 }
355
356
357 /**
358  * Create a new svga_screen object
359  */
360 struct pipe_screen *
361 svga_screen_create(struct svga_winsys_screen *sws)
362 {
363    struct svga_screen *svgascreen;
364    struct pipe_screen *screen;
365    SVGA3dDevCapResult result;
366
367 #ifdef DEBUG
368    SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 );
369 #endif
370
371    svgascreen = CALLOC_STRUCT(svga_screen);
372    if (!svgascreen)
373       goto error1;
374
375    svgascreen->debug.force_level_surface_view =
376       debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE);
377    svgascreen->debug.force_surface_view =
378       debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE);
379    svgascreen->debug.force_sampler_view =
380       debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE);
381    svgascreen->debug.no_surface_view =
382       debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE);
383    svgascreen->debug.no_sampler_view =
384       debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE);
385
386    screen = &svgascreen->screen;
387
388    screen->destroy = svga_destroy_screen;
389    screen->get_name = svga_get_name;
390    screen->get_vendor = svga_get_vendor;
391    screen->get_param = svga_get_param;
392    screen->get_paramf = svga_get_paramf;
393    screen->is_format_supported = svga_is_format_supported;
394    screen->context_create = svga_context_create;
395    screen->fence_reference = svga_fence_reference;
396    screen->fence_signalled = svga_fence_signalled;
397    screen->fence_finish = svga_fence_finish;
398    svgascreen->sws = sws;
399
400    svga_screen_init_texture_functions(screen);
401    svga_screen_init_buffer_functions(screen);
402
403    svgascreen->use_ps30 =
404       sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) &&
405       result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE;
406
407    svgascreen->use_vs30 =
408       sws->get_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION, &result) &&
409       result.u >= SVGA3DVSVERSION_30 ? TRUE : FALSE;
410
411 #if 1
412    /* Shader model 2.0 is unsupported at the moment. */
413    if(!svgascreen->use_ps30 || !svgascreen->use_vs30)
414       goto error2;
415 #else
416    if(debug_get_bool_option("SVGA_NO_SM30", FALSE))
417       svgascreen->use_vs30 = svgascreen->use_ps30 = FALSE;
418 #endif
419
420    svgascreen->swc = sws->context_create(sws);
421    if(!svgascreen->swc)
422       goto error2;
423
424    pipe_mutex_init(svgascreen->tex_mutex);
425    pipe_mutex_init(svgascreen->swc_mutex);
426
427    svga_screen_cache_init(svgascreen);
428
429    return screen;
430 error2:
431    FREE(svgascreen);
432 error1:
433    return NULL;
434 }
435
436 void svga_screen_flush( struct svga_screen *svgascreen, 
437                         struct pipe_fence_handle **pfence )
438 {
439    struct pipe_fence_handle *fence = NULL;
440
441    SVGA_DBG(DEBUG_PERF, "%s\n", __FUNCTION__);
442    
443    pipe_mutex_lock(svgascreen->swc_mutex);
444    svgascreen->swc->flush(svgascreen->swc, &fence);
445    pipe_mutex_unlock(svgascreen->swc_mutex);
446    
447    svga_screen_cache_flush(svgascreen, fence);
448    
449    if(pfence)
450       *pfence = fence;
451    else
452       svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL);
453 }
454
455 struct svga_winsys_screen *
456 svga_winsys_screen(struct pipe_screen *screen)
457 {
458    return svga_screen(screen)->sws;
459 }
460
461 #ifdef DEBUG
462 struct svga_screen *
463 svga_screen(struct pipe_screen *screen)
464 {
465    assert(screen);
466    assert(screen->destroy == svga_destroy_screen);
467    return (struct svga_screen *)screen;
468 }
469 #endif