~ubuntu-branches/ubuntu/precise/mesa-lts-quantal/precise-updates

« back to all changes in this revision

Viewing changes to src/gallium/drivers/llvmpipe/lp_screen.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2012-11-30 20:58:34 UTC
  • Revision ID: package-import@ubuntu.com-20121130205834-gazuvne3fpwlf012
Tags: upstream-9.0
ImportĀ upstreamĀ versionĀ 9.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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_math.h"
 
31
#include "util/u_cpu_detect.h"
 
32
#include "util/u_format.h"
 
33
#include "util/u_string.h"
 
34
#include "util/u_format_s3tc.h"
 
35
#include "pipe/p_defines.h"
 
36
#include "pipe/p_screen.h"
 
37
#include "draw/draw_context.h"
 
38
 
 
39
#include "lp_texture.h"
 
40
#include "lp_fence.h"
 
41
#include "lp_jit.h"
 
42
#include "lp_screen.h"
 
43
#include "lp_context.h"
 
44
#include "lp_debug.h"
 
45
#include "lp_public.h"
 
46
#include "lp_limits.h"
 
47
#include "lp_rast.h"
 
48
 
 
49
#include "state_tracker/sw_winsys.h"
 
50
 
 
51
#ifdef DEBUG
 
52
int LP_DEBUG = 0;
 
53
 
 
54
static const struct debug_named_value lp_debug_flags[] = {
 
55
   { "pipe",   DEBUG_PIPE, NULL },
 
56
   { "tgsi",   DEBUG_TGSI, NULL },
 
57
   { "tex",    DEBUG_TEX, NULL },
 
58
   { "setup",  DEBUG_SETUP, NULL },
 
59
   { "rast",   DEBUG_RAST, NULL },
 
60
   { "query",  DEBUG_QUERY, NULL },
 
61
   { "screen", DEBUG_SCREEN, NULL },
 
62
   { "show_tiles",    DEBUG_SHOW_TILES, NULL },
 
63
   { "show_subtiles", DEBUG_SHOW_SUBTILES, NULL },
 
64
   { "counters", DEBUG_COUNTERS, NULL },
 
65
   { "scene", DEBUG_SCENE, NULL },
 
66
   { "fence", DEBUG_FENCE, NULL },
 
67
   { "mem", DEBUG_MEM, NULL },
 
68
   { "fs", DEBUG_FS, NULL },
 
69
   DEBUG_NAMED_VALUE_END
 
70
};
 
71
#endif
 
72
 
 
73
int LP_PERF = 0;
 
74
static const struct debug_named_value lp_perf_flags[] = {
 
75
   { "texmem",         PERF_TEX_MEM, NULL },
 
76
   { "no_mipmap",      PERF_NO_MIPMAPS, NULL },
 
77
   { "no_linear",      PERF_NO_LINEAR, NULL },
 
78
   { "no_mip_linear",  PERF_NO_MIP_LINEAR, NULL },
 
79
   { "no_tex",         PERF_NO_TEX, NULL },
 
80
   { "no_blend",       PERF_NO_BLEND, NULL },
 
81
   { "no_depth",       PERF_NO_DEPTH, NULL },
 
82
   { "no_alphatest",   PERF_NO_ALPHATEST, NULL },
 
83
   DEBUG_NAMED_VALUE_END
 
84
};
 
85
 
 
86
 
 
87
static const char *
 
88
llvmpipe_get_vendor(struct pipe_screen *screen)
 
89
{
 
90
   return "VMware, Inc.";
 
91
}
 
92
 
 
93
 
 
94
static const char *
 
95
llvmpipe_get_name(struct pipe_screen *screen)
 
96
{
 
97
   static char buf[100];
 
98
   util_snprintf(buf, sizeof(buf), "llvmpipe (LLVM 0x%x)", HAVE_LLVM);
 
99
   return buf;
 
100
}
 
101
 
 
102
 
 
103
static int
 
104
llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
 
105
{
 
106
   switch (param) {
 
107
   case PIPE_CAP_MAX_COMBINED_SAMPLERS:
 
108
      return 2 * PIPE_MAX_SAMPLERS;  /* VS + FS samplers */
 
109
   case PIPE_CAP_NPOT_TEXTURES:
 
110
      return 1;
 
111
   case PIPE_CAP_TWO_SIDED_STENCIL:
 
112
      return 1;
 
113
   case PIPE_CAP_SM3:
 
114
      return 1;
 
115
   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
 
116
      return 0;
 
117
   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
 
118
      return 0;
 
119
   case PIPE_CAP_ANISOTROPIC_FILTER:
 
120
      return 0;
 
121
   case PIPE_CAP_POINT_SPRITE:
 
122
      return 1;
 
123
   case PIPE_CAP_MAX_RENDER_TARGETS:
 
124
      return PIPE_MAX_COLOR_BUFS;
 
125
   case PIPE_CAP_OCCLUSION_QUERY:
 
126
      return 1;
 
127
   case PIPE_CAP_TIMER_QUERY:
 
128
      return 0;
 
129
   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
 
130
      return 1;
 
131
   case PIPE_CAP_TEXTURE_SHADOW_MAP:
 
132
      return 1;
 
133
   case PIPE_CAP_TEXTURE_SWIZZLE:
 
134
      return 1;
 
135
   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
 
136
      return LP_MAX_TEXTURE_2D_LEVELS;
 
137
   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
 
138
      return LP_MAX_TEXTURE_3D_LEVELS;
 
139
   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
 
140
      return LP_MAX_TEXTURE_2D_LEVELS;
 
141
   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
 
142
      return 1;
 
143
   case PIPE_CAP_INDEP_BLEND_ENABLE:
 
144
      return 1;
 
145
   case PIPE_CAP_INDEP_BLEND_FUNC:
 
146
      return 1;
 
147
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
 
148
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
 
149
      return 1;
 
150
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
 
151
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
 
152
      return 0;
 
153
   case PIPE_CAP_PRIMITIVE_RESTART:
 
154
      return 1;
 
155
   case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
 
156
      return 1;
 
157
   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
 
158
      return 0;
 
159
   case PIPE_CAP_DEPTH_CLIP_DISABLE:
 
160
      return 0;
 
161
   case PIPE_CAP_SHADER_STENCIL_EXPORT:
 
162
      return 0;
 
163
   case PIPE_CAP_TGSI_INSTANCEID:
 
164
   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
 
165
      return 1;
 
166
   case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
 
167
      return 0;
 
168
   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
 
169
      return 1;
 
170
   case PIPE_CAP_SEAMLESS_CUBE_MAP:
 
171
   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
 
172
      return 0;
 
173
   case PIPE_CAP_SCALED_RESOLVE:
 
174
      return 0;
 
175
   case PIPE_CAP_MIN_TEXEL_OFFSET:
 
176
   case PIPE_CAP_MAX_TEXEL_OFFSET:
 
177
      return 0;
 
178
   case PIPE_CAP_CONDITIONAL_RENDER:
 
179
      return 1;
 
180
   case PIPE_CAP_TEXTURE_BARRIER:
 
181
      return 0;
 
182
   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
 
183
   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
 
184
   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
 
185
      return 0;
 
186
   case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
 
187
   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
 
188
      return 0;
 
189
   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
 
190
   case PIPE_CAP_VERTEX_COLOR_CLAMPED:
 
191
      return 0;
 
192
   case PIPE_CAP_GLSL_FEATURE_LEVEL:
 
193
      return 120;
 
194
   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
 
195
      return 0;
 
196
   case PIPE_CAP_COMPUTE:
 
197
      return 0;
 
198
   case PIPE_CAP_USER_VERTEX_BUFFERS:
 
199
   case PIPE_CAP_USER_INDEX_BUFFERS:
 
200
   case PIPE_CAP_USER_CONSTANT_BUFFERS:
 
201
      return 1;
 
202
   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
 
203
   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
 
204
   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
 
205
      return 0;
 
206
 
 
207
   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
 
208
      return 16;
 
209
   case PIPE_CAP_START_INSTANCE:
 
210
   case PIPE_CAP_QUERY_TIMESTAMP:
 
211
      return 0;
 
212
   }
 
213
   /* should only get here on unhandled cases */
 
214
   debug_printf("Unexpected PIPE_CAP %d query\n", param);
 
215
   return 0;
 
216
}
 
217
 
 
218
static int
 
219
llvmpipe_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param)
 
220
{
 
221
   switch(shader)
 
222
   {
 
223
   case PIPE_SHADER_FRAGMENT:
 
224
      switch (param) {
 
225
      default:
 
226
         return gallivm_get_shader_param(param);
 
227
      }
 
228
   case PIPE_SHADER_VERTEX:
 
229
   case PIPE_SHADER_GEOMETRY:
 
230
      switch (param) {
 
231
      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
 
232
         /* At this time, the draw module and llvmpipe driver only
 
233
          * support vertex shader texture lookups when LLVM is enabled in
 
234
          * the draw module.
 
235
          */
 
236
         if (debug_get_bool_option("DRAW_USE_LLVM", TRUE))
 
237
            return PIPE_MAX_SAMPLERS;
 
238
         else
 
239
            return 0;
 
240
      default:
 
241
         return draw_get_shader_param(shader, param);
 
242
      }
 
243
   default:
 
244
      return 0;
 
245
   }
 
246
}
 
247
 
 
248
static float
 
249
llvmpipe_get_paramf(struct pipe_screen *screen, enum pipe_capf param)
 
250
{
 
251
   switch (param) {
 
252
   case PIPE_CAPF_MAX_LINE_WIDTH:
 
253
      /* fall-through */
 
254
   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
 
255
      return 255.0; /* arbitrary */
 
256
   case PIPE_CAPF_MAX_POINT_WIDTH:
 
257
      /* fall-through */
 
258
   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
 
259
      return 255.0; /* arbitrary */
 
260
   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
 
261
      return 16.0; /* not actually signficant at this time */
 
262
   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
 
263
      return 16.0; /* arbitrary */
 
264
   case PIPE_CAPF_GUARD_BAND_LEFT:
 
265
   case PIPE_CAPF_GUARD_BAND_TOP:
 
266
   case PIPE_CAPF_GUARD_BAND_RIGHT:
 
267
   case PIPE_CAPF_GUARD_BAND_BOTTOM:
 
268
      return 0.0;
 
269
   }
 
270
   /* should only get here on unhandled cases */
 
271
   debug_printf("Unexpected PIPE_CAP %d query\n", param);
 
272
   return 0.0;
 
273
}
 
274
 
 
275
 
 
276
/**
 
277
 * Query format support for creating a texture, drawing surface, etc.
 
278
 * \param format  the format to test
 
279
 * \param type  one of PIPE_TEXTURE, PIPE_SURFACE
 
280
 */
 
281
static boolean
 
282
llvmpipe_is_format_supported( struct pipe_screen *_screen,
 
283
                              enum pipe_format format,
 
284
                              enum pipe_texture_target target,
 
285
                              unsigned sample_count,
 
286
                              unsigned bind)
 
287
{
 
288
   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
 
289
   struct sw_winsys *winsys = screen->winsys;
 
290
   const struct util_format_description *format_desc;
 
291
 
 
292
   format_desc = util_format_description(format);
 
293
   if (!format_desc)
 
294
      return FALSE;
 
295
 
 
296
   assert(target == PIPE_BUFFER ||
 
297
          target == PIPE_TEXTURE_1D ||
 
298
          target == PIPE_TEXTURE_2D ||
 
299
          target == PIPE_TEXTURE_RECT ||
 
300
          target == PIPE_TEXTURE_3D ||
 
301
          target == PIPE_TEXTURE_CUBE);
 
302
 
 
303
   if (sample_count > 1)
 
304
      return FALSE;
 
305
 
 
306
   if (format_desc->format == PIPE_FORMAT_R11G11B10_FLOAT ||
 
307
       format_desc->format == PIPE_FORMAT_R9G9B9E5_FLOAT) 
 
308
     return TRUE;
 
309
 
 
310
   if (bind & PIPE_BIND_RENDER_TARGET) {
 
311
      if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ||
 
312
          format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
 
313
         return FALSE;
 
314
 
 
315
      if (format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
 
316
         return FALSE;
 
317
 
 
318
      if (format_desc->block.width != 1 ||
 
319
          format_desc->block.height != 1)
 
320
         return FALSE;
 
321
   }
 
322
 
 
323
   if (bind & PIPE_BIND_DISPLAY_TARGET) {
 
324
      if(!winsys->is_displaytarget_format_supported(winsys, bind, format))
 
325
         return FALSE;
 
326
   }
 
327
 
 
328
   if (bind & PIPE_BIND_DEPTH_STENCIL) {
 
329
      if (format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
 
330
         return FALSE;
 
331
 
 
332
      if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
 
333
         return FALSE;
 
334
 
 
335
      /* FIXME: Temporary restriction. See lp_state_fs.c. */
 
336
      if (format_desc->block.bits != 32)
 
337
         return FALSE;
 
338
   }
 
339
 
 
340
   if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
 
341
      return util_format_s3tc_enabled;
 
342
   }
 
343
 
 
344
   /*
 
345
    * Everything can be supported by u_format.
 
346
    */
 
347
 
 
348
   if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
 
349
       !format_desc->fetch_rgba_float) {
 
350
      return FALSE;
 
351
   }
 
352
 
 
353
   return TRUE;
 
354
}
 
355
 
 
356
 
 
357
 
 
358
 
 
359
static void
 
360
llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
 
361
                           struct pipe_resource *resource,
 
362
                           unsigned level, unsigned layer,
 
363
                           void *context_private)
 
364
{
 
365
   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
 
366
   struct sw_winsys *winsys = screen->winsys;
 
367
   struct llvmpipe_resource *texture = llvmpipe_resource(resource);
 
368
 
 
369
   assert(texture->dt);
 
370
   if (texture->dt)
 
371
      winsys->displaytarget_display(winsys, texture->dt, context_private);
 
372
}
 
373
 
 
374
 
 
375
static void
 
376
llvmpipe_destroy_screen( struct pipe_screen *_screen )
 
377
{
 
378
   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
 
379
   struct sw_winsys *winsys = screen->winsys;
 
380
 
 
381
   if (screen->rast)
 
382
      lp_rast_destroy(screen->rast);
 
383
 
 
384
   lp_jit_screen_cleanup(screen);
 
385
 
 
386
   if(winsys->destroy)
 
387
      winsys->destroy(winsys);
 
388
 
 
389
   pipe_mutex_destroy(screen->rast_mutex);
 
390
 
 
391
   FREE(screen);
 
392
}
 
393
 
 
394
 
 
395
 
 
396
 
 
397
/**
 
398
 * Fence reference counting.
 
399
 */
 
400
static void
 
401
llvmpipe_fence_reference(struct pipe_screen *screen,
 
402
                         struct pipe_fence_handle **ptr,
 
403
                         struct pipe_fence_handle *fence)
 
404
{
 
405
   struct lp_fence **old = (struct lp_fence **) ptr;
 
406
   struct lp_fence *f = (struct lp_fence *) fence;
 
407
 
 
408
   lp_fence_reference(old, f);
 
409
}
 
410
 
 
411
 
 
412
/**
 
413
 * Has the fence been executed/finished?
 
414
 */
 
415
static boolean
 
416
llvmpipe_fence_signalled(struct pipe_screen *screen,
 
417
                         struct pipe_fence_handle *fence)
 
418
{
 
419
   struct lp_fence *f = (struct lp_fence *) fence;
 
420
   return lp_fence_signalled(f);
 
421
}
 
422
 
 
423
 
 
424
/**
 
425
 * Wait for the fence to finish.
 
426
 */
 
427
static boolean
 
428
llvmpipe_fence_finish(struct pipe_screen *screen,
 
429
                      struct pipe_fence_handle *fence_handle,
 
430
                      uint64_t timeout)
 
431
{
 
432
   struct lp_fence *f = (struct lp_fence *) fence_handle;
 
433
 
 
434
   lp_fence_wait(f);
 
435
   return TRUE;
 
436
}
 
437
 
 
438
 
 
439
 
 
440
/**
 
441
 * Create a new pipe_screen object
 
442
 * Note: we're not presently subclassing pipe_screen (no llvmpipe_screen).
 
443
 */
 
444
struct pipe_screen *
 
445
llvmpipe_create_screen(struct sw_winsys *winsys)
 
446
{
 
447
   struct llvmpipe_screen *screen;
 
448
 
 
449
#ifdef PIPE_ARCH_X86
 
450
   /* require SSE2 due to LLVM PR6960. */
 
451
   util_cpu_detect();
 
452
   if (!util_cpu_caps.has_sse2)
 
453
       return NULL;
 
454
#endif
 
455
 
 
456
#ifdef DEBUG
 
457
   LP_DEBUG = debug_get_flags_option("LP_DEBUG", lp_debug_flags, 0 );
 
458
#endif
 
459
 
 
460
   LP_PERF = debug_get_flags_option("LP_PERF", lp_perf_flags, 0 );
 
461
 
 
462
   screen = CALLOC_STRUCT(llvmpipe_screen);
 
463
   if (!screen)
 
464
      return NULL;
 
465
 
 
466
   screen->winsys = winsys;
 
467
 
 
468
   screen->base.destroy = llvmpipe_destroy_screen;
 
469
 
 
470
   screen->base.get_name = llvmpipe_get_name;
 
471
   screen->base.get_vendor = llvmpipe_get_vendor;
 
472
   screen->base.get_param = llvmpipe_get_param;
 
473
   screen->base.get_shader_param = llvmpipe_get_shader_param;
 
474
   screen->base.get_paramf = llvmpipe_get_paramf;
 
475
   screen->base.is_format_supported = llvmpipe_is_format_supported;
 
476
 
 
477
   screen->base.context_create = llvmpipe_create_context;
 
478
   screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer;
 
479
   screen->base.fence_reference = llvmpipe_fence_reference;
 
480
   screen->base.fence_signalled = llvmpipe_fence_signalled;
 
481
   screen->base.fence_finish = llvmpipe_fence_finish;
 
482
 
 
483
   llvmpipe_init_screen_resource_funcs(&screen->base);
 
484
 
 
485
   lp_jit_screen_init(screen);
 
486
 
 
487
   screen->num_threads = util_cpu_caps.nr_cpus > 1 ? util_cpu_caps.nr_cpus : 0;
 
488
#ifdef PIPE_SUBSYSTEM_EMBEDDED
 
489
   screen->num_threads = 0;
 
490
#endif
 
491
   screen->num_threads = debug_get_num_option("LP_NUM_THREADS", screen->num_threads);
 
492
   screen->num_threads = MIN2(screen->num_threads, LP_MAX_THREADS);
 
493
 
 
494
   screen->rast = lp_rast_create(screen->num_threads);
 
495
   if (!screen->rast) {
 
496
      lp_jit_screen_cleanup(screen);
 
497
      FREE(screen);
 
498
      return NULL;
 
499
   }
 
500
   pipe_mutex_init(screen->rast_mutex);
 
501
 
 
502
   util_format_s3tc_init();
 
503
 
 
504
   return &screen->base;
 
505
}