[Mesa-dev] [PATCH 1/3] gallium/st: add pipe_context::generate_mipmap()
Charmaine Lee
charmainel at vmware.com
Mon Jan 11 18:31:55 PST 2016
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.
---
src/gallium/docs/source/context.rst | 10 ++++++++++
src/gallium/docs/source/screen.rst | 2 ++
src/gallium/drivers/trace/tr_context.c | 30 ++++++++++++++++++++++++++++++
src/gallium/include/pipe/p_context.h | 11 +++++++++++
src/gallium/include/pipe/p_defines.h | 1 +
src/mesa/state_tracker/st_gen_mipmap.c | 17 ++++++++++++-----
6 files changed, 66 insertions(+), 5 deletions(-)
diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
index 9a32716..e33e7a2 100644
--- a/src/gallium/docs/source/context.rst
+++ b/src/gallium/docs/source/context.rst
@@ -648,3 +648,13 @@ 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.
diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
index c8f5f6a..b8d8de5 100644
--- a/src/gallium/docs/source/screen.rst
+++ b/src/gallium/docs/source/screen.rst
@@ -301,6 +301,8 @@ The integer capabilities:
alignment for pipe_shader_buffer::buffer_offset, in bytes. Maximum
value allowed is 256 (for GL conformance). 0 is only allowed if
shader buffers are not supported.
+* ``PIPE_CAP_GENERATE_MIPMAP``: Whether `generate_mipmap` will be
+ available in contexts.
.. _pipe_capf:
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index d4c88c9..17da64e 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -1292,6 +1292,35 @@ trace_context_flush(struct pipe_context *_pipe,
static inline void
+trace_context_generate_mipmap(struct pipe_context *_pipe,
+ struct pipe_resource *res,
+ 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;
+
+ 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(uint, base_level);
+ trace_dump_arg(uint, last_level);
+ trace_dump_arg(uint, first_layer);
+ trace_dump_arg(uint, last_layer);
+
+ pipe->generate_mipmap(pipe, res, base_level, last_level, first_layer, last_layer);
+
+ trace_dump_call_end();
+}
+
+
+static inline void
trace_context_destroy(struct pipe_context *_pipe)
{
struct trace_context *tr_ctx = trace_context(_pipe);
@@ -1620,6 +1649,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);
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index be7447d..a0774c7 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -673,6 +673,17 @@ 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,
+ unsigned base_level,
+ unsigned last_level,
+ unsigned first_layer,
+ unsigned last_layer);
};
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index dd76fe5..40f114f 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -642,6 +642,7 @@ enum pipe_cap
PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL,
PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL,
PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT,
+ PIPE_CAP_GENERATE_MIPMAP,
};
#define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0)
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index b370040..94c1171 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -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, 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 */
--
1.8.1.2
More information about the mesa-dev
mailing list