Merge branch 'gallium-newclear'
[mesa.git] / src / gallium / drivers / llvmpipe / lp_screen.c
index 9b47415f003350c7592894fb6338f50c7943e2b6..2fc5d6ecff6ed9779759e2b595a98289d751d670 100644 (file)
 
 
 #include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_cpu_detect.h"
 #include "util/u_format.h"
+#include "util/u_format_s3tc.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_screen.h"
 
+#include "gallivm/lp_bld_limits.h"
 #include "lp_texture.h"
-#include "lp_buffer.h"
-#include "lp_winsys.h"
+#include "lp_fence.h"
 #include "lp_jit.h"
 #include "lp_screen.h"
+#include "lp_context.h"
 #include "lp_debug.h"
+#include "lp_public.h"
+#include "lp_limits.h"
+
+#include "state_tracker/sw_winsys.h"
 
 #ifdef DEBUG
 int LP_DEBUG = 0;
 
 static const struct debug_named_value lp_debug_flags[] = {
-   { "pipe",   DEBUG_PIPE },
-   { "tgsi",   DEBUG_TGSI },
-   { "tex",    DEBUG_TEX },
-   { "asm",    DEBUG_ASM },
-   { "setup",  DEBUG_SETUP },
-   { "rast",   DEBUG_RAST },
-   { "query",  DEBUG_QUERY },
-   { "screen", DEBUG_SCREEN },
-   { "jit",    DEBUG_JIT },
-   {NULL, 0}
+   { "pipe",   DEBUG_PIPE, NULL },
+   { "tgsi",   DEBUG_TGSI, NULL },
+   { "tex",    DEBUG_TEX, NULL },
+   { "setup",  DEBUG_SETUP, NULL },
+   { "rast",   DEBUG_RAST, NULL },
+   { "query",  DEBUG_QUERY, NULL },
+   { "screen", DEBUG_SCREEN, NULL },
+   { "show_tiles",    DEBUG_SHOW_TILES, NULL },
+   { "show_subtiles", DEBUG_SHOW_SUBTILES, NULL },
+   { "counters", DEBUG_COUNTERS, NULL },
+   DEBUG_NAMED_VALUE_END
 };
 #endif
 
@@ -71,13 +80,13 @@ llvmpipe_get_name(struct pipe_screen *screen)
 
 
 static int
-llvmpipe_get_param(struct pipe_screen *screen, int param)
+llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
 {
    switch (param) {
    case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
       return PIPE_MAX_SAMPLERS;
    case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
-      return PIPE_MAX_VERTEX_SAMPLERS;
+      return 0;
    case PIPE_CAP_MAX_COMBINED_SAMPLERS:
       return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;
    case PIPE_CAP_NPOT_TEXTURES:
@@ -86,6 +95,8 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
       return 1;
    case PIPE_CAP_GLSL:
       return 1;
+   case PIPE_CAP_SM3:
+      return 1;
    case PIPE_CAP_ANISOTROPIC_FILTER:
       return 0;
    case PIPE_CAP_POINT_SPRITE:
@@ -94,6 +105,8 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
       return PIPE_MAX_COLOR_BUFS;
    case PIPE_CAP_OCCLUSION_QUERY:
       return 1;
+   case PIPE_CAP_TIMER_QUERY:
+      return 0;
    case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
       return 1;
    case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
@@ -101,23 +114,65 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
    case PIPE_CAP_TEXTURE_SHADOW_MAP:
       return 1;
    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
-      return 13; /* max 4Kx4K */
+      return LP_MAX_TEXTURE_2D_LEVELS;
    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
-      return 9;  /* max 256x256x256 */
+      return LP_MAX_TEXTURE_3D_LEVELS;
    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
-      return 13; /* max 4Kx4K */
+      return LP_MAX_TEXTURE_2D_LEVELS;
    case PIPE_CAP_TGSI_CONT_SUPPORTED:
       return 1;
    case PIPE_CAP_BLEND_EQUATION_SEPARATE:
       return 1;
+   case PIPE_CAP_INDEP_BLEND_ENABLE:
+      return 1;
+   case PIPE_CAP_INDEP_BLEND_FUNC:
+      return 0;
+   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+      return 1;
+   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+      return 0;
+   case PIPE_CAP_MAX_VS_INSTRUCTIONS:
+   case PIPE_CAP_MAX_FS_INSTRUCTIONS:
+   case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS:
+   case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS:
+   case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS:
+   case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS:
+   case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS:
+   case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS:
+      /* There is no limit in number of instructions beyond available memory */
+      return 32768;
+   case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH:
+   case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH:
+      return LP_MAX_TGSI_NESTING;
+   case PIPE_CAP_MAX_VS_INPUTS:
+   case PIPE_CAP_MAX_FS_INPUTS:
+      return PIPE_MAX_ATTRIBS;
+   case PIPE_CAP_MAX_FS_CONSTS:
+   case PIPE_CAP_MAX_VS_CONSTS:
+      /* There is no limit in number of constants beyond available memory */
+      return 32768;
+   case PIPE_CAP_MAX_VS_TEMPS:
+   case PIPE_CAP_MAX_FS_TEMPS:
+      return LP_MAX_TGSI_TEMPS;
+   case PIPE_CAP_MAX_VS_ADDRS:
+   case PIPE_CAP_MAX_FS_ADDRS:
+      return LP_MAX_TGSI_ADDRS;
+   case PIPE_CAP_MAX_VS_PREDS:
+   case PIPE_CAP_MAX_FS_PREDS:
+      return LP_MAX_TGSI_PREDS;
+   case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
+      return 1;
    default:
+      assert(0);
       return 0;
    }
 }
 
 
 static float
-llvmpipe_get_paramf(struct pipe_screen *screen, int param)
+llvmpipe_get_paramf(struct pipe_screen *screen, enum pipe_cap param)
 {
    switch (param) {
    case PIPE_CAP_MAX_LINE_WIDTH:
@@ -132,7 +187,13 @@ llvmpipe_get_paramf(struct pipe_screen *screen, int param)
       return 16.0; /* not actually signficant at this time */
    case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
       return 16.0; /* arbitrary */
+   case PIPE_CAP_GUARD_BAND_LEFT:
+   case PIPE_CAP_GUARD_BAND_TOP:
+   case PIPE_CAP_GUARD_BAND_RIGHT:
+   case PIPE_CAP_GUARD_BAND_BOTTOM:
+      return 0.0;
    default:
+      assert(0);
       return 0;
    }
 }
@@ -145,96 +206,69 @@ llvmpipe_get_paramf(struct pipe_screen *screen, int param)
  */
 static boolean
 llvmpipe_is_format_supported( struct pipe_screen *_screen,
-                              enum pipe_format format, 
+                              enum pipe_format format,
                               enum pipe_texture_target target,
-                              unsigned tex_usage, 
+                              unsigned sample_count,
+                              unsigned bind,
                               unsigned geom_flags )
 {
    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
-   struct llvmpipe_winsys *winsys = screen->winsys;
+   struct sw_winsys *winsys = screen->winsys;
    const struct util_format_description *format_desc;
 
    format_desc = util_format_description(format);
-   if(!format_desc)
+   if (!format_desc)
       return FALSE;
 
-   assert(target == PIPE_TEXTURE_1D ||
+   assert(target == PIPE_BUFFER ||
+          target == PIPE_TEXTURE_1D ||
           target == PIPE_TEXTURE_2D ||
           target == PIPE_TEXTURE_3D ||
           target == PIPE_TEXTURE_CUBE);
 
-   switch(format) {
-   case PIPE_FORMAT_DXT1_RGB:
-   case PIPE_FORMAT_DXT1_RGBA:
-   case PIPE_FORMAT_DXT3_RGBA:
-   case PIPE_FORMAT_DXT5_RGBA:
+   if (sample_count > 1)
       return FALSE;
-   default:
-      break;
-   }
 
-   if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
-      if(format_desc->block.width != 1 ||
-         format_desc->block.height != 1)
+   if (bind & PIPE_BIND_RENDER_TARGET) {
+      if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
          return FALSE;
 
-      if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR &&
-         format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
-         format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY)
+      if (format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
          return FALSE;
 
-      if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
-         format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB)
+      if (format_desc->block.width != 1 ||
+          format_desc->block.height != 1)
          return FALSE;
    }
 
-   if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
-      if(!winsys->is_displaytarget_format_supported(winsys, format))
+   if (bind & PIPE_BIND_DISPLAY_TARGET) {
+      if(!winsys->is_displaytarget_format_supported(winsys, bind, format))
          return FALSE;
    }
 
-   if(tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
-      if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
+   if (bind & PIPE_BIND_DEPTH_STENCIL) {
+      if (format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
          return FALSE;
 
-      /* FIXME: Temporary restriction. See lp_state_fs.c. */
-      if(format_desc->block.bits != 32)
+      if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
          return FALSE;
-   }
 
-   /* FIXME: Temporary restrictions. See lp_bld_sample_soa.c */
-   if(tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) {
-      if(format_desc->block.width != 1 ||
-         format_desc->block.height != 1)
-         return FALSE;
-
-      if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR &&
-         format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
-         format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY)
+      /* FIXME: Temporary restriction. See lp_state_fs.c. */
+      if (format_desc->block.bits != 32)
          return FALSE;
+   }
 
-      if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
-         format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB &&
-         format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
-         return FALSE;
+   if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
+      return util_format_s3tc_enabled;
    }
 
+   /*
+    * Everything else should be supported by u_format.
+    */
    return TRUE;
 }
 
 
-static struct pipe_buffer *
-llvmpipe_surface_buffer_create(struct pipe_screen *screen,
-                               unsigned width, unsigned height,
-                               enum pipe_format format,
-                               unsigned tex_usage,
-                               unsigned usage,
-                               unsigned *stride)
-{
-   /* This function should never be used */
-   assert(0);
-   return NULL;
-}
 
 
 static void
@@ -243,8 +277,8 @@ llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
                            void *context_private)
 {
    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
-   struct llvmpipe_winsys *winsys = screen->winsys;
-   struct llvmpipe_texture *texture = llvmpipe_texture(surface->texture);
+   struct sw_winsys *winsys = screen->winsys;
+   struct llvmpipe_resource *texture = llvmpipe_resource(surface->texture);
 
    assert(texture->dt);
    if (texture->dt)
@@ -256,7 +290,7 @@ static void
 llvmpipe_destroy_screen( struct pipe_screen *_screen )
 {
    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
-   struct llvmpipe_winsys *winsys = screen->winsys;
+   struct sw_winsys *winsys = screen->winsys;
 
    lp_jit_screen_cleanup(screen);
 
@@ -273,9 +307,18 @@ llvmpipe_destroy_screen( struct pipe_screen *_screen )
  * Note: we're not presently subclassing pipe_screen (no llvmpipe_screen).
  */
 struct pipe_screen *
-llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
+llvmpipe_create_screen(struct sw_winsys *winsys)
 {
-   struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
+   struct llvmpipe_screen *screen;
+
+#ifdef PIPE_ARCH_X86
+   /* require SSE2 due to LLVM PR6960. */
+   util_cpu_detect();
+   if (!util_cpu_caps.has_sse2)
+       return NULL;
+#endif
+
+   screen = CALLOC_STRUCT(llvmpipe_screen);
 
 #ifdef DEBUG
    LP_DEBUG = debug_get_flags_option("LP_DEBUG", lp_debug_flags, 0 );
@@ -294,13 +337,29 @@ llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
    screen->base.get_paramf = llvmpipe_get_paramf;
    screen->base.is_format_supported = llvmpipe_is_format_supported;
 
-   screen->base.surface_buffer_create = llvmpipe_surface_buffer_create;
+   screen->base.context_create = llvmpipe_create_context;
    screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer;
 
-   llvmpipe_init_screen_texture_funcs(&screen->base);
-   llvmpipe_init_screen_buffer_funcs(&screen->base);
+   llvmpipe_init_screen_resource_funcs(&screen->base);
+   llvmpipe_init_screen_fence_funcs(&screen->base);
 
    lp_jit_screen_init(screen);
 
+#ifdef PIPE_OS_WINDOWS
+   /* Multithreading not supported on windows until conditions and barriers are
+    * properly implemented. */
+   screen->num_threads = 0;
+#else
+#ifdef PIPE_OS_EMBEDDED
+   screen->num_threads = 0;
+#else
+   screen->num_threads = util_cpu_caps.nr_cpus;
+#endif
+   screen->num_threads = debug_get_num_option("LP_NUM_THREADS", screen->num_threads);
+   screen->num_threads = MIN2(screen->num_threads, LP_MAX_THREADS);
+#endif
+
+   util_format_s3tc_init();
+
    return &screen->base;
 }