From 7124feba1b879deb88dbf2baf600ed42309d9839 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 14 Jul 2015 12:32:04 -0700 Subject: [PATCH] vc4: Cache the texture p1 for the sampler. Cuts another 12% of vc4_uniforms.o, in exchange for computing it at CSO creation time. --- src/gallium/drivers/vc4/vc4_context.h | 11 ++++++ src/gallium/drivers/vc4/vc4_state.c | 55 +++++++++++++++++++++++++- src/gallium/drivers/vc4/vc4_uniforms.c | 52 ++---------------------- 3 files changed, 69 insertions(+), 49 deletions(-) diff --git a/src/gallium/drivers/vc4/vc4_context.h b/src/gallium/drivers/vc4/vc4_context.h index be7df1bd347..7faf5223630 100644 --- a/src/gallium/drivers/vc4/vc4_context.h +++ b/src/gallium/drivers/vc4/vc4_context.h @@ -75,6 +75,11 @@ struct vc4_sampler_view { uint32_t texture_p1; }; +struct vc4_sampler_state { + struct pipe_sampler_state base; + uint32_t texture_p1; +}; + struct vc4_texture_stateobj { struct pipe_sampler_view *textures[PIPE_MAX_SAMPLERS]; unsigned num_textures; @@ -338,6 +343,12 @@ vc4_sampler_view(struct pipe_sampler_view *psview) return (struct vc4_sampler_view *)psview; } +static inline struct vc4_sampler_state * +vc4_sampler_state(struct pipe_sampler_state *psampler) +{ + return (struct vc4_sampler_state *)psampler; +} + struct pipe_context *vc4_context_create(struct pipe_screen *pscreen, void *priv); void vc4_draw_init(struct pipe_context *pctx); diff --git a/src/gallium/drivers/vc4/vc4_state.c b/src/gallium/drivers/vc4/vc4_state.c index 46852b6628c..8a759c2ca4c 100644 --- a/src/gallium/drivers/vc4/vc4_state.c +++ b/src/gallium/drivers/vc4/vc4_state.c @@ -461,11 +461,64 @@ vc4_get_stage_tex(struct vc4_context *vc4, unsigned shader) } } +static uint32_t translate_wrap(uint32_t p_wrap, bool using_nearest) +{ + switch (p_wrap) { + case PIPE_TEX_WRAP_REPEAT: + return 0; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + return 1; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + return 2; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return 3; + case PIPE_TEX_WRAP_CLAMP: + return (using_nearest ? 1 : 3); + default: + fprintf(stderr, "Unknown wrap mode %d\n", p_wrap); + assert(!"not reached"); + return 0; + } +} + static void * vc4_create_sampler_state(struct pipe_context *pctx, const struct pipe_sampler_state *cso) { - return vc4_generic_cso_state_create(cso, sizeof(*cso)); + static const uint8_t minfilter_map[6] = { + VC4_TEX_P1_MINFILT_NEAR_MIP_NEAR, + VC4_TEX_P1_MINFILT_LIN_MIP_NEAR, + VC4_TEX_P1_MINFILT_NEAR_MIP_LIN, + VC4_TEX_P1_MINFILT_LIN_MIP_LIN, + VC4_TEX_P1_MINFILT_NEAREST, + VC4_TEX_P1_MINFILT_LINEAR, + }; + static const uint32_t magfilter_map[] = { + [PIPE_TEX_FILTER_NEAREST] = VC4_TEX_P1_MAGFILT_NEAREST, + [PIPE_TEX_FILTER_LINEAR] = VC4_TEX_P1_MAGFILT_LINEAR, + }; + bool either_nearest = + (cso->mag_img_filter == PIPE_TEX_MIPFILTER_NEAREST || + cso->min_img_filter == PIPE_TEX_MIPFILTER_NEAREST); + struct vc4_sampler_state *so = CALLOC_STRUCT(vc4_sampler_state); + + if (!so) + return NULL; + + memcpy(so, cso, sizeof(*cso)); + + so->texture_p1 = + (VC4_SET_FIELD(magfilter_map[cso->mag_img_filter], + VC4_TEX_P1_MAGFILT) | + VC4_SET_FIELD(minfilter_map[cso->min_mip_filter * 2 + + cso->min_img_filter], + VC4_TEX_P1_MINFILT) | + VC4_SET_FIELD(translate_wrap(cso->wrap_s, either_nearest), + VC4_TEX_P1_WRAP_S) | + VC4_SET_FIELD(translate_wrap(cso->wrap_t, either_nearest), + VC4_TEX_P1_WRAP_T)); + + return so; } static void diff --git a/src/gallium/drivers/vc4/vc4_uniforms.c b/src/gallium/drivers/vc4/vc4_uniforms.c index e8e9d6b0119..5613d6b28c0 100644 --- a/src/gallium/drivers/vc4/vc4_uniforms.c +++ b/src/gallium/drivers/vc4/vc4_uniforms.c @@ -27,26 +27,6 @@ #include "vc4_context.h" #include "vc4_qir.h" -static uint32_t translate_wrap(uint32_t p_wrap, bool using_nearest) -{ - switch (p_wrap) { - case PIPE_TEX_WRAP_REPEAT: - return 0; - case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - return 1; - case PIPE_TEX_WRAP_MIRROR_REPEAT: - return 2; - case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - return 3; - case PIPE_TEX_WRAP_CLAMP: - return (using_nearest ? 1 : 3); - default: - fprintf(stderr, "Unknown wrap mode %d\n", p_wrap); - assert(!"not reached"); - return 0; - } -} - static void write_texture_p0(struct vc4_context *vc4, struct vc4_cl_out **uniforms, @@ -68,34 +48,10 @@ write_texture_p1(struct vc4_context *vc4, { struct vc4_sampler_view *sview = vc4_sampler_view(texstate->textures[unit]); - struct pipe_sampler_state *sampler = texstate->samplers[unit]; - static const uint8_t minfilter_map[6] = { - VC4_TEX_P1_MINFILT_NEAR_MIP_NEAR, - VC4_TEX_P1_MINFILT_LIN_MIP_NEAR, - VC4_TEX_P1_MINFILT_NEAR_MIP_LIN, - VC4_TEX_P1_MINFILT_LIN_MIP_LIN, - VC4_TEX_P1_MINFILT_NEAREST, - VC4_TEX_P1_MINFILT_LINEAR, - }; - static const uint32_t magfilter_map[] = { - [PIPE_TEX_FILTER_NEAREST] = VC4_TEX_P1_MAGFILT_NEAREST, - [PIPE_TEX_FILTER_LINEAR] = VC4_TEX_P1_MAGFILT_LINEAR, - }; - - bool either_nearest = - (sampler->mag_img_filter == PIPE_TEX_MIPFILTER_NEAREST || - sampler->min_img_filter == PIPE_TEX_MIPFILTER_NEAREST); - - cl_aligned_u32(uniforms, sview->texture_p1 | - VC4_SET_FIELD(magfilter_map[sampler->mag_img_filter], - VC4_TEX_P1_MAGFILT) | - VC4_SET_FIELD(minfilter_map[sampler->min_mip_filter * 2 + - sampler->min_img_filter], - VC4_TEX_P1_MINFILT) | - VC4_SET_FIELD(translate_wrap(sampler->wrap_s, either_nearest), - VC4_TEX_P1_WRAP_S) | - VC4_SET_FIELD(translate_wrap(sampler->wrap_t, either_nearest), - VC4_TEX_P1_WRAP_T)); + struct vc4_sampler_state *sampler = + vc4_sampler_state(texstate->samplers[unit]); + + cl_aligned_u32(uniforms, sview->texture_p1 | sampler->texture_p1); } static void -- 2.30.2