lp_screen.c revision 080c40ab32b2abd6d8381b4a0cc143d36a1652b2
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 "pipe/p_defines.h"
32#include "pipe/p_screen.h"
33
34#include "lp_texture.h"
35#include "lp_buffer.h"
36#include "lp_fence.h"
37#include "lp_winsys.h"
38#include "lp_jit.h"
39#include "lp_screen.h"
40#include "lp_debug.h"
41
42#ifdef DEBUG
43int LP_DEBUG = 0;
44
45static const struct debug_named_value lp_debug_flags[] = {
46   { "pipe",   DEBUG_PIPE },
47   { "tgsi",   DEBUG_TGSI },
48   { "tex",    DEBUG_TEX },
49   { "asm",    DEBUG_ASM },
50   { "setup",  DEBUG_SETUP },
51   { "rast",   DEBUG_RAST },
52   { "query",  DEBUG_QUERY },
53   { "screen", DEBUG_SCREEN },
54   { "jit",    DEBUG_JIT },
55   {NULL, 0}
56};
57#endif
58
59
60static const char *
61llvmpipe_get_vendor(struct pipe_screen *screen)
62{
63   return "VMware, Inc.";
64}
65
66
67static const char *
68llvmpipe_get_name(struct pipe_screen *screen)
69{
70   return "llvmpipe";
71}
72
73
74static int
75llvmpipe_get_param(struct pipe_screen *screen, int param)
76{
77   switch (param) {
78   case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
79      return PIPE_MAX_SAMPLERS;
80   case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
81      return PIPE_MAX_VERTEX_SAMPLERS;
82   case PIPE_CAP_MAX_COMBINED_SAMPLERS:
83      return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;
84   case PIPE_CAP_NPOT_TEXTURES:
85      return 1;
86   case PIPE_CAP_TWO_SIDED_STENCIL:
87      return 1;
88   case PIPE_CAP_GLSL:
89      return 1;
90   case PIPE_CAP_ANISOTROPIC_FILTER:
91      return 0;
92   case PIPE_CAP_POINT_SPRITE:
93      return 1;
94   case PIPE_CAP_MAX_RENDER_TARGETS:
95      return PIPE_MAX_COLOR_BUFS;
96   case PIPE_CAP_OCCLUSION_QUERY:
97      return 1;
98   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
99      return 1;
100   case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
101      return 1;
102   case PIPE_CAP_TEXTURE_SHADOW_MAP:
103      return 1;
104   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
105      return 13; /* max 4Kx4K */
106   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
107      return 9;  /* max 256x256x256 */
108   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
109      return 13; /* max 4Kx4K */
110   case PIPE_CAP_TGSI_CONT_SUPPORTED:
111      return 1;
112   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
113      return 1;
114   default:
115      return 0;
116   }
117}
118
119
120static float
121llvmpipe_get_paramf(struct pipe_screen *screen, int param)
122{
123   switch (param) {
124   case PIPE_CAP_MAX_LINE_WIDTH:
125      /* fall-through */
126   case PIPE_CAP_MAX_LINE_WIDTH_AA:
127      return 255.0; /* arbitrary */
128   case PIPE_CAP_MAX_POINT_WIDTH:
129      /* fall-through */
130   case PIPE_CAP_MAX_POINT_WIDTH_AA:
131      return 255.0; /* arbitrary */
132   case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
133      return 16.0; /* not actually signficant at this time */
134   case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
135      return 16.0; /* arbitrary */
136   default:
137      return 0;
138   }
139}
140
141
142/**
143 * Query format support for creating a texture, drawing surface, etc.
144 * \param format  the format to test
145 * \param type  one of PIPE_TEXTURE, PIPE_SURFACE
146 */
147static boolean
148llvmpipe_is_format_supported( struct pipe_screen *_screen,
149                              enum pipe_format format,
150                              enum pipe_texture_target target,
151                              unsigned tex_usage,
152                              unsigned geom_flags )
153{
154   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
155   struct llvmpipe_winsys *winsys = screen->winsys;
156   const struct util_format_description *format_desc;
157
158   format_desc = util_format_description(format);
159   if(!format_desc)
160      return FALSE;
161
162   assert(target == PIPE_TEXTURE_1D ||
163          target == PIPE_TEXTURE_2D ||
164          target == PIPE_TEXTURE_3D ||
165          target == PIPE_TEXTURE_CUBE);
166
167   switch(format) {
168   case PIPE_FORMAT_DXT1_RGB:
169   case PIPE_FORMAT_DXT1_RGBA:
170   case PIPE_FORMAT_DXT3_RGBA:
171   case PIPE_FORMAT_DXT5_RGBA:
172      return FALSE;
173   default:
174      break;
175   }
176
177   if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
178      if(format_desc->block.width != 1 ||
179         format_desc->block.height != 1)
180         return FALSE;
181
182      if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR &&
183         format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
184         format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY)
185         return FALSE;
186
187      if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
188         format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB)
189         return FALSE;
190   }
191
192   if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
193      if(!winsys->is_displaytarget_format_supported(winsys, format))
194         return FALSE;
195   }
196
197   if(tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
198      if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
199         return FALSE;
200
201      /* FIXME: Temporary restriction. See lp_state_fs.c. */
202      if(format_desc->block.bits != 32)
203         return FALSE;
204   }
205
206   /* FIXME: Temporary restrictions. See lp_bld_sample_soa.c */
207   if(tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) {
208      if(format_desc->block.width != 1 ||
209         format_desc->block.height != 1)
210         return FALSE;
211
212      if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR &&
213         format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
214         format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY)
215         return FALSE;
216
217      if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
218         format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB &&
219         format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
220         return FALSE;
221   }
222
223   return TRUE;
224}
225
226
227static struct pipe_buffer *
228llvmpipe_surface_buffer_create(struct pipe_screen *screen,
229                               unsigned width, unsigned height,
230                               enum pipe_format format,
231                               unsigned tex_usage,
232                               unsigned usage,
233                               unsigned *stride)
234{
235   /* This function should never be used */
236   assert(0);
237   return NULL;
238}
239
240
241static void
242llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
243                           struct pipe_surface *surface,
244                           void *context_private)
245{
246   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
247   struct llvmpipe_winsys *winsys = screen->winsys;
248   struct llvmpipe_texture *texture = llvmpipe_texture(surface->texture);
249
250   assert(texture->dt);
251   if (texture->dt)
252      winsys->displaytarget_display(winsys, texture->dt, context_private);
253}
254
255
256static void
257llvmpipe_destroy_screen( struct pipe_screen *_screen )
258{
259   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
260   struct llvmpipe_winsys *winsys = screen->winsys;
261
262   lp_jit_screen_cleanup(screen);
263
264   if(winsys->destroy)
265      winsys->destroy(winsys);
266
267   FREE(screen);
268}
269
270
271
272/**
273 * Create a new pipe_screen object
274 * Note: we're not presently subclassing pipe_screen (no llvmpipe_screen).
275 */
276struct pipe_screen *
277llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
278{
279   struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
280
281#ifdef DEBUG
282   LP_DEBUG = debug_get_flags_option("LP_DEBUG", lp_debug_flags, 0 );
283#endif
284
285   if (!screen)
286      return NULL;
287
288   screen->winsys = winsys;
289
290   screen->base.destroy = llvmpipe_destroy_screen;
291
292   screen->base.get_name = llvmpipe_get_name;
293   screen->base.get_vendor = llvmpipe_get_vendor;
294   screen->base.get_param = llvmpipe_get_param;
295   screen->base.get_paramf = llvmpipe_get_paramf;
296   screen->base.is_format_supported = llvmpipe_is_format_supported;
297
298   screen->base.surface_buffer_create = llvmpipe_surface_buffer_create;
299   screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer;
300
301   llvmpipe_init_screen_texture_funcs(&screen->base);
302   llvmpipe_init_screen_buffer_funcs(&screen->base);
303   llvmpipe_init_screen_fence_funcs(&screen->base);
304
305   lp_jit_screen_init(screen);
306
307   return &screen->base;
308}
309