gallium/st: add pipe_context::generate_mipmap()
authorCharmaine Lee <charmainel@vmware.com>
Thu, 14 Jan 2016 17:22:17 +0000 (10:22 -0700)
committerBrian Paul <brianp@vmware.com>
Thu, 14 Jan 2016 17:39:53 +0000 (10:39 -0700)
This patch adds a new interface to support hardware mipmap generation.
PIPE_CAP_GENERATE_MIPMAP is added to allow a driver to specify
if this new interface is supported; if not supported, the state tracker will
fallback to mipmap generation by rendering/texturing.

v2: add PIPE_CAP_GENERATE_MIPMAP to the disabled section for all drivers
v3: add format to the generate_mipmap interface to allow mipmap generation
    using a format other than the resource format
v4: fix return type of trace_context_generate_mipmap()

Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
20 files changed:
src/gallium/docs/source/context.rst
src/gallium/docs/source/screen.rst
src/gallium/drivers/freedreno/freedreno_screen.c
src/gallium/drivers/i915/i915_screen.c
src/gallium/drivers/ilo/ilo_screen.c
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/drivers/nouveau/nv30/nv30_screen.c
src/gallium/drivers/nouveau/nv50/nv50_screen.c
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/radeonsi/si_pipe.c
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/svga/svga_screen.c
src/gallium/drivers/trace/tr_context.c
src/gallium/drivers/vc4/vc4_screen.c
src/gallium/drivers/virgl/virgl_screen.c
src/gallium/include/pipe/p_context.h
src/gallium/include/pipe/p_defines.h
src/mesa/state_tracker/st_gen_mipmap.c

index 9a32716f9214fd31574f9c5801d195135e859c5b..4c03e00008c2ac0ae03df499a293711902e1b54d 100644 (file)
@@ -648,3 +648,14 @@ In addition, normal texture sampling is allowed from the compute
 program: ``bind_sampler_states`` may be used to set up texture
 samplers for the compute stage and ``set_sampler_views`` may
 be used to bind a number of sampler views to it.
+
+Mipmap generation
+^^^^^^^^^^^^^^^^^
+
+If PIPE_CAP_GENERATE_MIPMAP is true, ``generate_mipmap`` can be used
+to generate mipmaps for the specified texture resource.
+It replaces texel image levels base_level+1 through
+last_level for layers range from first_layer through last_layer.
+It returns TRUE if mipmap generation succeeds, otherwise it
+returns FALSE. Mipmap generation may fail when it is not supported
+for particular texture types or formats.
index 81de7f857084725e356a7f95675d70d91c570dda..d7ea123b0e9ea8375b6c1a20a6b5774f183540e4 100644 (file)
@@ -303,6 +303,8 @@ The integer capabilities:
   shader buffers are not supported.
 * ``PIPE_CAP_INVALIDATE_BUFFER``: Whether the use of ``invalidate_resource``
   for buffers is supported.
+* ``PIPE_CAP_GENERATE_MIPMAP``: Indicates whether pipe_context::generate_mipmap
+  is supported.
 
 
 .. _pipe_capf:
index 70af03851112cf24e3e0194d93e1a2135ed967ae..a75b04b327a134b9dcce84adfa6ef506065b49e1 100644 (file)
@@ -246,6 +246,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
        case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
        case PIPE_CAP_INVALIDATE_BUFFER:
+       case PIPE_CAP_GENERATE_MIPMAP:
                return 0;
 
        case PIPE_CAP_MAX_VIEWPORTS:
index fa3e8163273a2500a2fc9c078c10789988d43574..ede5558a11e543b84433dc27ec4d4f0d356de96d 100644 (file)
@@ -260,6 +260,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
    case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
    case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
    case PIPE_CAP_INVALIDATE_BUFFER:
+   case PIPE_CAP_GENERATE_MIPMAP:
       return 0;
 
    case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
index 0306542fac0c7f6ca7ada326393afd397a5659a2..fa327571b9bf739e78a5e16ba177df5bb3c29fa5 100644 (file)
@@ -484,6 +484,7 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
    case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
    case PIPE_CAP_INVALIDATE_BUFFER:
+   case PIPE_CAP_GENERATE_MIPMAP:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
index eadbbb31d1933fd29881389c08db186b42ab0c53..fb52f5dc06331ac14d340f89a8650c1f5de9d01b 100644 (file)
@@ -309,6 +309,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
    case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
    case PIPE_CAP_INVALIDATE_BUFFER:
+   case PIPE_CAP_GENERATE_MIPMAP:
       return 0;
    }
    /* should only get here on unhandled cases */
index 421bf65559036986adc0b580d19299091b560280..933330f107a20a9cbff3851b26dfae5b1e028a49 100644 (file)
@@ -182,6 +182,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
    case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
    case PIPE_CAP_INVALIDATE_BUFFER:
+   case PIPE_CAP_GENERATE_MIPMAP:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
index 2b7f928b15a4ff2bf3608e8033c59adfd16a31c4..712835c1ce15c1143318226cee4fa378375358a8 100644 (file)
@@ -225,6 +225,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
    case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
    case PIPE_CAP_INVALIDATE_BUFFER:
+   case PIPE_CAP_GENERATE_MIPMAP:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
index cd8e950e2ba5f1b06b7c70e611af0a5bef4e50a2..ccf96fb28151967a299c4f247c8c5c1ac2c2fc1b 100644 (file)
@@ -214,6 +214,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
    case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
    case PIPE_CAP_INVALIDATE_BUFFER:
+   case PIPE_CAP_GENERATE_MIPMAP:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
index a0afef7d80fc457de21698b125222a5ebdc847cb..8823b8d3197bb64ad9df4e2d74dc6f8bd77e874e 100644 (file)
@@ -208,6 +208,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
         case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
         case PIPE_CAP_INVALIDATE_BUFFER:
+        case PIPE_CAP_GENERATE_MIPMAP:
             return 0;
 
         /* SWTCL-only features. */
index 569f77c2b850fbed0af3623c4cc9c2843f103285..08fdd361049d73501747b246049d08172adabd93 100644 (file)
@@ -356,6 +356,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
        case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
        case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
+       case PIPE_CAP_GENERATE_MIPMAP:
                return 0;
 
        case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
index cb80a72f94b5c6e649662e1bacc82f8fef719122..f6ff4a81bd458cfdd8a71c339146bab9514d4508 100644 (file)
@@ -348,6 +348,7 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_MULTI_DRAW_INDIRECT:
        case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
        case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
+       case PIPE_CAP_GENERATE_MIPMAP:
                return 0;
 
        case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
index f2d1dee58d9df0406ce6ed81474d16363072d1a1..143702a5650c323d6025649d1c29d9dadb81cfda 100644 (file)
@@ -259,6 +259,7 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
    case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
    case PIPE_CAP_INVALIDATE_BUFFER:
+   case PIPE_CAP_GENERATE_MIPMAP:
       return 0;
    }
    /* should only get here on unhandled cases */
index b506019cb5eee4929f3f2045bb58c9e752395e83..0528d8df833e14bc6312820875d99511add164d5 100644 (file)
@@ -392,6 +392,7 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_DRAW_PARAMETERS:
    case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
    case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
+   case PIPE_CAP_GENERATE_MIPMAP:
       return 0;
    }
 
index d4c88c9be6d0528974ab839b70686513bd7a8dd0..b5ab92498351d29ccea9a3435a4b112f51621153 100644 (file)
@@ -1291,6 +1291,42 @@ trace_context_flush(struct pipe_context *_pipe,
 }
 
 
+static inline boolean
+trace_context_generate_mipmap(struct pipe_context *_pipe,
+                              struct pipe_resource *res,
+                              enum pipe_format format,
+                              unsigned base_level,
+                              unsigned last_level,
+                              unsigned first_layer,
+                              unsigned last_layer)
+{
+   struct trace_context *tr_ctx = trace_context(_pipe);
+   struct pipe_context *pipe = tr_ctx->pipe;
+   boolean ret;
+
+   res = trace_resource_unwrap(tr_ctx, res);
+
+   trace_dump_call_begin("pipe_context", "generate_mipmap");
+
+   trace_dump_arg(ptr, pipe);
+   trace_dump_arg(ptr, res);
+
+   trace_dump_arg(format, format);
+   trace_dump_arg(uint, base_level);
+   trace_dump_arg(uint, last_level);
+   trace_dump_arg(uint, first_layer);
+   trace_dump_arg(uint, last_layer);
+
+   ret = pipe->generate_mipmap(pipe, res, format, base_level, last_level,
+                               first_layer, last_layer);
+
+   trace_dump_ret(bool, ret);
+   trace_dump_call_end();
+
+   return ret;
+}
+
+
 static inline void
 trace_context_destroy(struct pipe_context *_pipe)
 {
@@ -1620,6 +1656,7 @@ trace_context_create(struct trace_screen *tr_scr,
    TR_CTX_INIT(clear_render_target);
    TR_CTX_INIT(clear_depth_stencil);
    TR_CTX_INIT(flush);
+   TR_CTX_INIT(generate_mipmap);
    TR_CTX_INIT(texture_barrier);
    TR_CTX_INIT(memory_barrier);
    TR_CTX_INIT(set_tess_state);
index 5a9483797a9f1d21c49b66b56f3eb105868b8e2a..fb41877017d0530aa914456a755761fabcec0403 100644 (file)
@@ -197,6 +197,7 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
         case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
         case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
         case PIPE_CAP_INVALIDATE_BUFFER:
+        case PIPE_CAP_GENERATE_MIPMAP:
                 return 0;
 
                 /* Stream output. */
index 63af8dd6419f19c8f1ae9a25db159ab7ef2fb8e1..fb2e5670ef0709c39b015ab1e60c6bfaa1451d36 100644 (file)
@@ -227,6 +227,7 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
    case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
    case PIPE_CAP_INVALIDATE_BUFFER:
+   case PIPE_CAP_GENERATE_MIPMAP:
       return 0;
    case PIPE_CAP_VENDOR_ID:
       return 0x1af4;
index 78155c0534834f467ba21ec9fb78d97310fe66d8..4b551ed0b413bd1bee810a704542a684bc525170 100644 (file)
@@ -677,6 +677,18 @@ struct pipe_context {
     */
    void (*dump_debug_state)(struct pipe_context *ctx, FILE *stream,
                             unsigned flags);
+
+   /**
+    * Generate mipmap.
+    * \return TRUE if mipmap generation succeeds, FALSE otherwise
+    */
+   boolean (*generate_mipmap)(struct pipe_context *ctx,
+                              struct pipe_resource *resource,
+                              enum pipe_format format,
+                              unsigned base_level,
+                              unsigned last_level,
+                              unsigned first_layer,
+                              unsigned last_layer);
 };
 
 
index 0655f080e426e750729f7a478dfc7eb0d74a6dba..cb837cd25978b7ffa68e6852ca9c87ec34b85523 100644 (file)
@@ -643,6 +643,7 @@ enum pipe_cap
    PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL,
    PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT,
    PIPE_CAP_INVALIDATE_BUFFER,
+   PIPE_CAP_GENERATE_MIPMAP,
 };
 
 #define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0)
index b3700406df0a820d665305d609ac3ca98ffeb647..3e6c0a73bc75fb060f385af8f80ca30edf0c5db1 100644 (file)
@@ -149,12 +149,19 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target,
       last_layer = util_max_layer(pt, baseLevel);
    }
 
-   /* Try to generate the mipmap by rendering/texturing.  If that fails,
-    * use the software fallback.
+   /* First see if the driver supports hardware mipmap generation,
+    * if not then generate the mipmap by rendering/texturing.
+    * If that fails, use the software fallback.
     */
-   if (!util_gen_mipmap(st->pipe, pt, pt->format, baseLevel, lastLevel,
-                        first_layer, last_layer, PIPE_TEX_FILTER_LINEAR)) {
-      _mesa_generate_mipmap(ctx, target, texObj);
+   if (!st->pipe->screen->get_param(st->pipe->screen,
+                                    PIPE_CAP_GENERATE_MIPMAP) ||
+       !st->pipe->generate_mipmap(st->pipe, pt, pt->format, baseLevel,
+                                  lastLevel, first_layer, last_layer)) {
+
+      if (!util_gen_mipmap(st->pipe, pt, pt->format, baseLevel, lastLevel,
+                           first_layer, last_layer, PIPE_TEX_FILTER_LINEAR)) {
+         _mesa_generate_mipmap(ctx, target, texObj);
+      }
    }
 
    /* Fill in the Mesa gl_texture_image fields */