Squashed commit of the following:
[profile/ivi/mesa.git] / src / gallium / drivers / llvmpipe / lp_screen.c
1 /**************************************************************************
2  * 
3  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4  * All Rights Reserved.
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  * 
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  * 
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  * 
26  **************************************************************************/
27
28
29 #include "util/u_memory.h"
30 #include "util/u_format.h"
31 #include "util/u_format_s3tc.h"
32 #include "pipe/p_defines.h"
33 #include "pipe/p_screen.h"
34
35 #include "lp_texture.h"
36 #include "lp_fence.h"
37 #include "lp_jit.h"
38 #include "lp_screen.h"
39 #include "lp_context.h"
40 #include "lp_debug.h"
41 #include "lp_public.h"
42
43 #include "state_tracker/sw_winsys.h"
44
45 #ifdef DEBUG
46 int LP_DEBUG = 0;
47
48 static const struct debug_named_value lp_debug_flags[] = {
49    { "pipe",   DEBUG_PIPE },
50    { "tgsi",   DEBUG_TGSI },
51    { "tex",    DEBUG_TEX },
52    { "asm",    DEBUG_ASM },
53    { "setup",  DEBUG_SETUP },
54    { "rast",   DEBUG_RAST },
55    { "query",  DEBUG_QUERY },
56    { "screen", DEBUG_SCREEN },
57    { "jit",    DEBUG_JIT },
58    { "show_tiles",    DEBUG_SHOW_TILES },
59    { "show_subtiles", DEBUG_SHOW_SUBTILES },
60    { "counters", DEBUG_COUNTERS },
61    { "nopt", DEBUG_NO_LLVM_OPT },
62    {NULL, 0}
63 };
64 #endif
65
66
67 static const char *
68 llvmpipe_get_vendor(struct pipe_screen *screen)
69 {
70    return "VMware, Inc.";
71 }
72
73
74 static const char *
75 llvmpipe_get_name(struct pipe_screen *screen)
76 {
77    return "llvmpipe";
78 }
79
80
81 static int
82 llvmpipe_get_param(struct pipe_screen *screen, int param)
83 {
84    switch (param) {
85    case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
86       return PIPE_MAX_SAMPLERS;
87    case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
88       return 0;
89    case PIPE_CAP_MAX_COMBINED_SAMPLERS:
90       return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;
91    case PIPE_CAP_NPOT_TEXTURES:
92       return 1;
93    case PIPE_CAP_TWO_SIDED_STENCIL:
94       return 1;
95    case PIPE_CAP_GLSL:
96       return 1;
97    case PIPE_CAP_ANISOTROPIC_FILTER:
98       return 0;
99    case PIPE_CAP_POINT_SPRITE:
100       return 1;
101    case PIPE_CAP_MAX_RENDER_TARGETS:
102       return PIPE_MAX_COLOR_BUFS;
103    case PIPE_CAP_OCCLUSION_QUERY:
104       return 1;
105    case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
106       return 1;
107    case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
108       return 1;
109    case PIPE_CAP_TEXTURE_SHADOW_MAP:
110       return 1;
111    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
112       return LP_MAX_TEXTURE_2D_LEVELS;
113    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
114       return LP_MAX_TEXTURE_3D_LEVELS;
115    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
116       return LP_MAX_TEXTURE_2D_LEVELS;
117    case PIPE_CAP_TGSI_CONT_SUPPORTED:
118       return 1;
119    case PIPE_CAP_BLEND_EQUATION_SEPARATE:
120       return 1;
121    case PIPE_CAP_INDEP_BLEND_ENABLE:
122       return 0;
123    case PIPE_CAP_INDEP_BLEND_FUNC:
124       return 0;
125    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
126    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
127       return 1;
128    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
129    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
130       return 0;
131    default:
132       return 0;
133    }
134 }
135
136
137 static float
138 llvmpipe_get_paramf(struct pipe_screen *screen, int param)
139 {
140    switch (param) {
141    case PIPE_CAP_MAX_LINE_WIDTH:
142       /* fall-through */
143    case PIPE_CAP_MAX_LINE_WIDTH_AA:
144       return 255.0; /* arbitrary */
145    case PIPE_CAP_MAX_POINT_WIDTH:
146       /* fall-through */
147    case PIPE_CAP_MAX_POINT_WIDTH_AA:
148       return 255.0; /* arbitrary */
149    case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
150       return 16.0; /* not actually signficant at this time */
151    case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
152       return 16.0; /* arbitrary */
153    default:
154       return 0;
155    }
156 }
157
158
159 /**
160  * Query format support for creating a texture, drawing surface, etc.
161  * \param format  the format to test
162  * \param type  one of PIPE_TEXTURE, PIPE_SURFACE
163  */
164 static boolean
165 llvmpipe_is_format_supported( struct pipe_screen *_screen,
166                               enum pipe_format format, 
167                               enum pipe_texture_target target,
168                               unsigned tex_usage, 
169                               unsigned geom_flags )
170 {
171    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
172    struct sw_winsys *winsys = screen->winsys;
173    const struct util_format_description *format_desc;
174
175    format_desc = util_format_description(format);
176    if(!format_desc)
177       return FALSE;
178
179    assert(target == PIPE_TEXTURE_1D ||
180           target == PIPE_TEXTURE_2D ||
181           target == PIPE_TEXTURE_3D ||
182           target == PIPE_TEXTURE_CUBE);
183
184    switch(format) {
185    case PIPE_FORMAT_DXT1_RGB:
186    case PIPE_FORMAT_DXT1_RGBA:
187    case PIPE_FORMAT_DXT3_RGBA:
188    case PIPE_FORMAT_DXT5_RGBA:
189       return util_format_s3tc_enabled;
190    default:
191       break;
192    }
193
194    if(tex_usage & PIPE_BIND_RENDER_TARGET) {
195       if(format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
196          return FALSE;
197
198       if(format_desc->block.width != 1 ||
199          format_desc->block.height != 1)
200          return FALSE;
201
202       if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
203          format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB)
204          return FALSE;
205    }
206
207    if(tex_usage & (PIPE_BIND_DISPLAY_TARGET |
208                    PIPE_BIND_SCANOUT |
209                    PIPE_BIND_SHARED)) {
210       if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format))
211          return FALSE;
212    }
213
214    if(tex_usage & PIPE_BIND_DEPTH_STENCIL) {
215       if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
216          return FALSE;
217
218       /* FIXME: Temporary restriction. See lp_state_fs.c. */
219       if(format_desc->block.bits != 32)
220          return FALSE;
221    }
222
223    return TRUE;
224 }
225
226
227
228
229 static void
230 llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
231                            struct pipe_surface *surface,
232                            void *context_private)
233 {
234    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
235    struct sw_winsys *winsys = screen->winsys;
236    struct llvmpipe_resource *texture = llvmpipe_resource(surface->texture);
237
238    assert(texture->dt);
239    if (texture->dt)
240       winsys->displaytarget_display(winsys, texture->dt, context_private);
241 }
242
243
244 static void
245 llvmpipe_destroy_screen( struct pipe_screen *_screen )
246 {
247    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
248    struct sw_winsys *winsys = screen->winsys;
249
250    lp_jit_screen_cleanup(screen);
251
252    if(winsys->destroy)
253       winsys->destroy(winsys);
254
255    FREE(screen);
256 }
257
258
259
260 /**
261  * Create a new pipe_screen object
262  * Note: we're not presently subclassing pipe_screen (no llvmpipe_screen).
263  */
264 struct pipe_screen *
265 llvmpipe_create_screen(struct sw_winsys *winsys)
266 {
267    struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
268
269 #ifdef DEBUG
270    LP_DEBUG = debug_get_flags_option("LP_DEBUG", lp_debug_flags, 0 );
271 #endif
272
273    if (!screen)
274       return NULL;
275
276    screen->winsys = winsys;
277
278    screen->base.destroy = llvmpipe_destroy_screen;
279
280    screen->base.get_name = llvmpipe_get_name;
281    screen->base.get_vendor = llvmpipe_get_vendor;
282    screen->base.get_param = llvmpipe_get_param;
283    screen->base.get_paramf = llvmpipe_get_paramf;
284    screen->base.is_format_supported = llvmpipe_is_format_supported;
285
286    screen->base.context_create = llvmpipe_create_context;
287    screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer;
288
289    util_format_s3tc_init();
290
291    llvmpipe_init_screen_resource_funcs(&screen->base);
292    llvmpipe_init_screen_fence_funcs(&screen->base);
293
294    lp_jit_screen_init(screen);
295
296    return &screen->base;
297 }