From 900bc6fd961005859e6bc889e0b8da904398800b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 19 Jul 2021 06:04:58 +1000 Subject: [PATCH] virgl: add support for anisotropic texture filtering Although anisotropic filtering uses a float value, most hw doesn't care below integer levels, so just transmit 1-16 for the sampler value not the full float. Reviewed-by: Gert Wollny --- src/virgl_hw.h | 1 + src/virgl_protocol.h | 1 + src/vrend_decode.c | 1 + src/vrend_renderer.c | 11 +++++++++++ 4 files changed, 14 insertions(+) diff --git a/src/virgl_hw.h b/src/virgl_hw.h index edf0bb2..81cef9c 100644 --- a/src/virgl_hw.h +++ b/src/virgl_hw.h @@ -596,6 +596,7 @@ struct virgl_caps_v2 { uint32_t capability_bits_v2; uint32_t max_video_memory; char renderer[64]; + float max_anisotropy; }; union virgl_caps { diff --git a/src/virgl_protocol.h b/src/virgl_protocol.h index ec3c458..c1797d9 100644 --- a/src/virgl_protocol.h +++ b/src/virgl_protocol.h @@ -370,6 +370,7 @@ enum virgl_context_cmd { #define VIRGL_OBJ_SAMPLE_STATE_S0_COMPARE_MODE(x) (((x) & 0x1) << 15) #define VIRGL_OBJ_SAMPLE_STATE_S0_COMPARE_FUNC(x) (((x) & 0x7) << 16) #define VIRGL_OBJ_SAMPLE_STATE_S0_SEAMLESS_CUBE_MAP(x) (((x) & 0x1) << 19) +#define VIRGL_OBJ_SAMPLE_STATE_MAX_ANISOTROPY (((x & 0x3f)) << 20) #define VIRGL_OBJ_SAMPLER_STATE_LOD_BIAS 3 #define VIRGL_OBJ_SAMPLER_STATE_MIN_LOD 4 diff --git a/src/vrend_decode.c b/src/vrend_decode.c index 34d7abb..c25a565 100644 --- a/src/vrend_decode.c +++ b/src/vrend_decode.c @@ -675,6 +675,7 @@ static int vrend_decode_create_sampler_state(struct vrend_context *ctx, const ui state.compare_mode = (tmp >> 15) & 0x1; state.compare_func = (tmp >> 16) & 0x7; state.seamless_cube_map = (tmp >> 19) & 0x1; + state.max_anisotropy = (float)((tmp >> 20) & 0x3f); state.lod_bias = uif(get_buf_entry(buf, VIRGL_OBJ_SAMPLER_STATE_LOD_BIAS)); state.min_lod = uif(get_buf_entry(buf, VIRGL_OBJ_SAMPLER_STATE_MIN_LOD)); diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index 804d7c4..fc767a2 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -203,6 +203,7 @@ enum features_id feat_ubo, feat_viewport_array, feat_implicit_msaa, + feat_anisotropic_filter, feat_last, }; @@ -304,6 +305,7 @@ static const struct { FEAT(ubo, 31, 30, "GL_ARB_uniform_buffer_object" ), FEAT(viewport_array, 41, UNAVAIL, "GL_ARB_viewport_array", "GL_OES_viewport_array"), FEAT(implicit_msaa, UNAVAIL, UNAVAIL, "GL_EXT_multisampled_render_to_texture"), + FEAT(anisotropic_filter, 46, UNAVAIL, "GL_EXT_texture_filter_anisotropic", "GL_ARB_texture_filter_anisotropic"), }; struct global_renderer_state { @@ -5921,6 +5923,8 @@ static void vrend_apply_sampler_state(struct vrend_sub_context *sub_ctx, glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, state->compare_mode ? GL_COMPARE_R_TO_TEXTURE : GL_NONE); if (tex->state.compare_func != state->compare_func || set_all) glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_NEVER + state->compare_func); + if (has_feature(feat_anisotropic_filter) && (tex->state.max_anisotropy != state->max_anisotropy || set_all)) + glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY, state->max_anisotropy); /* * Oh this is a fun one. On GLES 2.0 all cubemap MUST NOT be seamless. @@ -10708,6 +10712,13 @@ static void vrend_renderer_fill_caps_v2(int gl_ver, int gles_ver, union virgl_c if (vrend_winsys_different_gpu()) caps->v2.capability_bits_v2 |= VIRGL_CAP_V2_DIFFERENT_GPU; + + if (has_feature(feat_anisotropic_filter)) { + float max_aniso; + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &max_aniso); + caps->v2.max_anisotropy = MIN2(max_aniso, 16.0); + } + } void vrend_renderer_fill_caps(uint32_t set, uint32_t version,