radeonsi/gfx10: update a tunable max_es_verts_base for NGG
[mesa.git] / src / gallium / drivers / virgl / virgl_screen.c
index 66cb6b7a21955fd338277f9da1ab27f1917fa72e..db3a520508ef1d388e766d621c0a10ea895e6008 100644 (file)
@@ -27,6 +27,7 @@
 #include "util/u_video.h"
 #include "util/u_math.h"
 #include "util/os_time.h"
+#include "util/xmlconfig.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_screen.h"
 
 #include "virgl_resource.h"
 #include "virgl_public.h"
 #include "virgl_context.h"
+#include "virgl_protocol.h"
 
 int virgl_debug = 0;
 static const struct debug_named_value debug_options[] = {
-   { "verbose", VIRGL_DEBUG_VERBOSE, NULL },
-   { "tgsi", VIRGL_DEBUG_TGSI, NULL },
+   { "verbose",   VIRGL_DEBUG_VERBOSE,             NULL },
+   { "tgsi",      VIRGL_DEBUG_TGSI,                NULL },
+   { "emubgra",   VIRGL_DEBUG_EMULATE_BGRA,        "Enable tweak to emulate BGRA as RGBA on GLES hosts"},
+   { "bgraswz",   VIRGL_DEBUG_BGRA_DEST_SWIZZLE,   "Enable tweak to swizzle emulated BGRA on GLES hosts" },
+   { "sync",      VIRGL_DEBUG_SYNC,                "Sync after every flush" },
+   { "xfer",      VIRGL_DEBUG_XFER,                "Do not optimize for transfers" },
    DEBUG_NAMED_VALUE_END
 };
 DEBUG_GET_ONCE_FLAGS_OPTION(virgl_debug, "VIRGL_DEBUG", debug_options, 0)
@@ -65,7 +71,9 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
    switch (param) {
    case PIPE_CAP_NPOT_TEXTURES:
       return 1;
-   case PIPE_CAP_SM3:
+   case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
+   case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
+   case PIPE_CAP_VERTEX_SHADER_SATURATE:
       return 1;
    case PIPE_CAP_ANISOTROPIC_FILTER:
       return 1;
@@ -246,8 +254,9 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_FB_NO_ATTACH;
    case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
       return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_ROBUST_BUFFER_ACCESS;
-   case PIPE_CAP_TGSI_FS_FBFETCH:
-      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_TGSI_FBFETCH;
+   case PIPE_CAP_FBFETCH:
+      return (vscreen->caps.caps.v2.capability_bits &
+              VIRGL_CAP_TGSI_FBFETCH) ? 1 : 0;
    case PIPE_CAP_TGSI_CLOCK:
       return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_SHADER_CLOCK;
    case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
@@ -279,7 +288,6 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
    case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
    case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
-   case PIPE_CAP_CLIP_HALFZ:
    case PIPE_CAP_VERTEXID_NOBASE:
    case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
    case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
@@ -340,6 +348,8 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
    case PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET:
       return 0;
+   case PIPE_CAP_CLIP_HALFZ:
+      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_CLIP_HALFZ;
    case PIPE_CAP_MAX_GS_INVOCATIONS:
       return 32;
    case PIPE_CAP_MAX_SHADER_BUFFER_SIZE:
@@ -356,7 +366,8 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_NATIVE_FENCE_FD:
       return vscreen->vws->supports_fences;
    case PIPE_CAP_DEST_SURFACE_SRGB_CONTROL:
-      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_SRGB_WRITE_CONTROL;
+      return (vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_SRGB_WRITE_CONTROL) ||
+            (vscreen->caps.caps.v2.host_feature_check_version < 1);
    case PIPE_CAP_TGSI_SKIP_SHRINK_IO_ARRAYS:
       return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_INDIRECT_INPUT_ADDR;
    default:
@@ -590,6 +601,35 @@ virgl_is_vertex_format_supported(struct pipe_screen *screen,
    return TRUE;
 }
 
+static boolean
+virgl_format_check_bitmask(enum pipe_format format,
+                           uint32_t bitmask[16],
+                           boolean may_emulate_bgra)
+{
+   int big = format / 32;
+   int small = format % 32;
+   if ((bitmask[big] & (1 << small)))
+      return TRUE;
+
+   /* On GLES hosts we don't advertise BGRx_SRGB, but we may be able
+    * emulate it by using a swizzled RGBx */
+   if (may_emulate_bgra) {
+      if (format == PIPE_FORMAT_B8G8R8A8_SRGB)
+         format = PIPE_FORMAT_R8G8B8A8_SRGB;
+      else if (format == PIPE_FORMAT_B8G8R8X8_SRGB)
+         format = PIPE_FORMAT_R8G8B8X8_SRGB;
+      else {
+         return FALSE;
+      }
+
+      big = format / 32;
+      small = format % 32;
+      if (bitmask[big] & (1 << small))
+         return TRUE;
+   }
+   return FALSE;
+}
+
 /**
  * Query format support for creating a texture, drawing surface, etc.
  * \param format  the format to test
@@ -607,6 +647,8 @@ virgl_is_format_supported( struct pipe_screen *screen,
    const struct util_format_description *format_desc;
    int i;
 
+   boolean may_emulate_bgra = false;
+
    if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
       return false;
 
@@ -660,6 +702,10 @@ virgl_is_format_supported( struct pipe_screen *screen,
        target == PIPE_TEXTURE_3D)
       return FALSE;
 
+   may_emulate_bgra = (vscreen->caps.caps.v2.capability_bits &
+                       VIRGL_CAP_APP_TWEAK_SUPPORT) &&
+                      vscreen->tweak_gles_emulate_bgra;
+
    if (bind & PIPE_BIND_RENDER_TARGET) {
       /* For ARB_framebuffer_no_attachments. */
       if (format == PIPE_FORMAT_NONE)
@@ -677,12 +723,10 @@ virgl_is_format_supported( struct pipe_screen *screen,
           format_desc->block.height != 1)
          return FALSE;
 
-      {
-         int big = format / 32;
-         int small = format % 32;
-         if (!(vscreen->caps.caps.v1.render.bitmask[big] & (1 << small)))
-            return FALSE;
-      }
+      if (!virgl_format_check_bitmask(format,
+                                      vscreen->caps.caps.v1.render.bitmask,
+                                      may_emulate_bgra))
+         return FALSE;
    }
 
    if (bind & PIPE_BIND_DEPTH_STENCIL) {
@@ -725,16 +769,9 @@ virgl_is_format_supported( struct pipe_screen *screen,
       return FALSE;
 
  out_lookup:
-   {
-      int big = format / 32;
-      int small = format % 32;
-      if (!(vscreen->caps.caps.v1.sampler.bitmask[big] & (1 << small)))
-         return FALSE;
-   }
-   /*
-    * Everything else should be supported by u_format.
-    */
-   return TRUE;
+   return virgl_format_check_bitmask(format,
+                                     vscreen->caps.caps.v1.sampler.bitmask,
+                                     may_emulate_bgra);
 }
 
 static void virgl_flush_frontbuffer(struct pipe_screen *screen,
@@ -819,15 +856,31 @@ fixup_readback_format(union virgl_caps *caps)
 }
 
 struct pipe_screen *
-virgl_create_screen(struct virgl_winsys *vws)
+virgl_create_screen(struct virgl_winsys *vws, const struct pipe_screen_config *config)
 {
    struct virgl_screen *screen = CALLOC_STRUCT(virgl_screen);
 
+   const char *VIRGL_GLES_EMULATE_BGRA = "gles_emulate_bgra";
+   const char *VIRGL_GLES_APPLY_BGRA_DEST_SWIZZLE = "gles_apply_bgra_dest_swizzle";
+   const char *VIRGL_GLES_SAMPLES_PASSED_VALUE = "gles_samples_passed_value";
+
    if (!screen)
       return NULL;
 
    virgl_debug = debug_get_option_virgl_debug();
 
+   if (config && config->options) {
+      screen->tweak_gles_emulate_bgra =
+            driQueryOptionb(config->options, VIRGL_GLES_EMULATE_BGRA);
+      screen->tweak_gles_apply_bgra_dest_swizzle =
+            driQueryOptionb(config->options, VIRGL_GLES_APPLY_BGRA_DEST_SWIZZLE);
+      screen->tweak_gles_tf3_value =
+            driQueryOptioni(config->options, VIRGL_GLES_SAMPLES_PASSED_VALUE);
+   }
+
+   screen->tweak_gles_emulate_bgra |= !!(virgl_debug & VIRGL_DEBUG_EMULATE_BGRA);
+   screen->tweak_gles_apply_bgra_dest_swizzle |= !!(virgl_debug & VIRGL_DEBUG_BGRA_DEST_SWIZZLE);
+
    screen->vws = vws;
    screen->base.get_name = virgl_get_name;
    screen->base.get_vendor = virgl_get_vendor;