From 42ebe3dfd9b0803913e0d932909ca5872d937c20 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 27 Apr 2010 21:06:44 +1000 Subject: mesa/st: add support for EXT_texture_swizzle. This passes on r300g, the only bit I'm not really sure about is the handling of the sampler_view in st_atom_texture.c, I unreference it there if the swizzle value changes and I also have to create a new set of functions to create a new one since the u_sampler.c ones don't handle swizzle so much. adds r300g + softpipe enables, I think other drivers could pass easily enough. Signed-off-by: Dave Airlie --- src/gallium/drivers/r300/r300_screen.c | 1 + src/gallium/drivers/softpipe/sp_screen.c | 2 ++ src/gallium/include/pipe/p_defines.h | 1 + src/mesa/state_tracker/st_atom_texture.c | 57 ++++++++++++++++++++++++++++++-- src/mesa/state_tracker/st_extensions.c | 4 +++ 5 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index e7db074be6..497e24b760 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -113,6 +113,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_MIRROR_CLAMP: case PIPE_CAP_TEXTURE_MIRROR_REPEAT: case PIPE_CAP_BLEND_EQUATION_SEPARATE: + case PIPE_CAP_TEXTURE_SWIZZLE: return 1; /* Unsupported features (boolean caps). */ diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index cb59040395..8abe7f50e1 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -90,6 +90,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 1; case PIPE_CAP_TEXTURE_SHADOW_MAP: return 1; + case PIPE_CAP_TEXTURE_SWIZZLE: + return 1; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: return SP_MAX_TEXTURE_2D_LEVELS; case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 420649c5a9..b00677425c 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -425,6 +425,7 @@ enum pipe_cap { PIPE_CAP_OCCLUSION_QUERY, PIPE_CAP_TIMER_QUERY, PIPE_CAP_TEXTURE_SHADOW_MAP, + PIPE_CAP_TEXTURE_SWIZZLE, PIPE_CAP_MAX_TEXTURE_2D_LEVELS, PIPE_CAP_MAX_TEXTURE_3D_LEVELS, PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS, diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index d403b7db1e..65b57f1591 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -33,6 +33,7 @@ #include "main/macros.h" +#include "shader/prog_instruction.h" #include "st_context.h" #include "st_atom.h" @@ -42,6 +43,54 @@ #include "util/u_inlines.h" #include "cso_cache/cso_context.h" +static boolean check_sampler_swizzle(struct pipe_sampler_view *sv, + uint32_t _swizzle) +{ + if ((sv->swizzle_r != GET_SWZ(_swizzle, 0)) || + (sv->swizzle_g != GET_SWZ(_swizzle, 1)) || + (sv->swizzle_b != GET_SWZ(_swizzle, 2)) || + (sv->swizzle_a != GET_SWZ(_swizzle, 3))) + return true; + return false; +} + +static INLINE struct pipe_sampler_view * +st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe, + struct st_texture_object *stObj) + +{ + struct pipe_sampler_view templ; + + u_sampler_view_default_template(&templ, + stObj->pt, + stObj->pt->format); + + if (stObj->base._Swizzle != SWIZZLE_NOOP) { + templ.swizzle_r = GET_SWZ(stObj->base._Swizzle, 0); + templ.swizzle_g = GET_SWZ(stObj->base._Swizzle, 1); + templ.swizzle_b = GET_SWZ(stObj->base._Swizzle, 2); + templ.swizzle_a = GET_SWZ(stObj->base._Swizzle, 3); + } + + return pipe->create_sampler_view(pipe, stObj->pt, &templ); +} + + +static INLINE struct pipe_sampler_view * +st_get_texture_sampler_view_from_stobj(struct st_texture_object *stObj, + struct pipe_context *pipe) + +{ + if (!stObj || !stObj->pt) { + return NULL; + } + + if (!stObj->sampler_view) { + stObj->sampler_view = st_create_texture_sampler_view_from_stobj(pipe, stObj); + } + + return stObj->sampler_view; +} static void update_textures(struct st_context *st) @@ -85,9 +134,13 @@ update_textures(struct st_context *st) st->state.num_textures = su + 1; - sampler_view = st_get_texture_sampler_view(stObj, pipe); - } + /* if sampler view has changed dereference it */ + if (stObj->sampler_view) + if (check_sampler_swizzle(stObj->sampler_view, stObj->base._Swizzle)) + pipe_sampler_view_reference(&stObj->sampler_view, NULL); + sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe); + } pipe_sampler_view_reference(&st->state.sampler_views[su], sampler_view); } diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 4093eedde9..2c2e10dead 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -248,6 +248,10 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.ARB_draw_buffers = GL_TRUE; } + if (screen->get_param(screen, PIPE_CAP_TEXTURE_SWIZZLE) > 0) { + ctx->Extensions.EXT_texture_swizzle = GL_TRUE; + } + if (screen->get_param(screen, PIPE_CAP_GLSL)) { ctx->Extensions.ARB_fragment_shader = GL_TRUE; ctx->Extensions.ARB_vertex_shader = GL_TRUE; -- cgit v1.2.3