From 76670ade68d4a4003c1bfddebfedb8ee808fa591 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Fri, 24 Aug 2018 12:40:27 +0200 Subject: [PATCH] vrend: do not overwrite a sampler-object that might be in use When we set the srgb-decode state, we might overwrite another incompatible usage of the same sampler object. To avoid this, create two sampler-objects, one for the decode-state and one for the skip-decode state. This fixes the following dEQP-tests on GLES: - dEQP-GLES31.functional.srgb_texture_decode.skip_decode.srgba8.conversion_gpu - dEQP-GLES31.functional.srgb_texture_decode.skip_decode.srgba8.toggled - dEQP-GLES31.functional.srgb_texture_decode.skip_decode.srgba8.multiple_textures Signed-off-by: Erik Faye-Lund Reviewed-by: Dave Airlie --- src/vrend_renderer.c | 56 +++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index cdedd20..d31588c 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -333,7 +333,7 @@ struct vrend_surface { struct vrend_sampler_state { struct pipe_sampler_state base; - GLuint id; + GLuint ids[2]; }; struct vrend_so_target { @@ -1618,7 +1618,7 @@ static void vrend_destroy_sampler_state_object(void *obj_ptr) struct vrend_sampler_state *state = obj_ptr; if (has_feature(feat_samplers)) - glDeleteSamplers(1, &state->id); + glDeleteSamplers(2, state->ids); FREE(state); } @@ -1680,33 +1680,36 @@ int vrend_create_sampler_state(struct vrend_context *ctx, state->base = *templ; if (has_feature(feat_samplers)) { - glGenSamplers(1, &state->id); - - glSamplerParameteri(state->id, GL_TEXTURE_WRAP_S, convert_wrap(templ->wrap_s)); - glSamplerParameteri(state->id, GL_TEXTURE_WRAP_T, convert_wrap(templ->wrap_t)); - glSamplerParameteri(state->id, GL_TEXTURE_WRAP_R, convert_wrap(templ->wrap_r)); - glSamplerParameterf(state->id, GL_TEXTURE_MIN_FILTER, convert_min_filter(templ->min_img_filter, templ->min_mip_filter)); - glSamplerParameterf(state->id, GL_TEXTURE_MAG_FILTER, convert_mag_filter(templ->mag_img_filter)); - glSamplerParameterf(state->id, GL_TEXTURE_MIN_LOD, templ->min_lod); - glSamplerParameterf(state->id, GL_TEXTURE_MAX_LOD, templ->max_lod); - glSamplerParameteri(state->id, GL_TEXTURE_COMPARE_MODE, templ->compare_mode ? GL_COMPARE_R_TO_TEXTURE : GL_NONE); - glSamplerParameteri(state->id, GL_TEXTURE_COMPARE_FUNC, GL_NEVER + templ->compare_func); - if (vrend_state.use_gles) { - if (templ->lod_bias != 0.0f) { - report_gles_warn(ctx, GLES_WARN_LOD_BIAS, 0); + glGenSamplers(2, state->ids); + + for (int i = 0; i < 2; ++i) { + glSamplerParameteri(state->ids[i], GL_TEXTURE_WRAP_S, convert_wrap(templ->wrap_s)); + glSamplerParameteri(state->ids[i], GL_TEXTURE_WRAP_T, convert_wrap(templ->wrap_t)); + glSamplerParameteri(state->ids[i], GL_TEXTURE_WRAP_R, convert_wrap(templ->wrap_r)); + glSamplerParameterf(state->ids[i], GL_TEXTURE_MIN_FILTER, convert_min_filter(templ->min_img_filter, templ->min_mip_filter)); + glSamplerParameterf(state->ids[i], GL_TEXTURE_MAG_FILTER, convert_mag_filter(templ->mag_img_filter)); + glSamplerParameterf(state->ids[i], GL_TEXTURE_MIN_LOD, templ->min_lod); + glSamplerParameterf(state->ids[i], GL_TEXTURE_MAX_LOD, templ->max_lod); + glSamplerParameteri(state->ids[i], GL_TEXTURE_COMPARE_MODE, templ->compare_mode ? GL_COMPARE_R_TO_TEXTURE : GL_NONE); + glSamplerParameteri(state->ids[i], GL_TEXTURE_COMPARE_FUNC, GL_NEVER + templ->compare_func); + if (vrend_state.use_gles) { + if (templ->lod_bias != 0.0f) { + report_gles_warn(ctx, GLES_WARN_LOD_BIAS, 0); + } + } else { + glSamplerParameteri(state->ids[i], GL_TEXTURE_CUBE_MAP_SEAMLESS, templ->seamless_cube_map); + glSamplerParameterf(state->ids[i], GL_TEXTURE_LOD_BIAS, templ->lod_bias); } - } else { - glSamplerParameteri(state->id, GL_TEXTURE_CUBE_MAP_SEAMLESS, templ->seamless_cube_map); - glSamplerParameterf(state->id, GL_TEXTURE_LOD_BIAS, templ->lod_bias); - } - glSamplerParameterIuiv(state->id, GL_TEXTURE_BORDER_COLOR, templ->border_color.ui); + glSamplerParameterIuiv(state->ids[i], GL_TEXTURE_BORDER_COLOR, templ->border_color.ui); + glSamplerParameteri(state->ids[i], GL_TEXTURE_SRGB_DECODE_EXT, i == 0 ? GL_SKIP_DECODE_EXT : GL_DECODE_EXT); + } } ret_handle = vrend_renderer_object_insert(ctx, state, sizeof(struct vrend_sampler_state), handle, VIRGL_OBJECT_SAMPLER_STATE); if (!ret_handle) { if (has_feature(feat_samplers)) - glDeleteSamplers(1, &state->id); + glDeleteSamplers(2, state->ids); FREE(state); return ENOMEM; } @@ -4830,17 +4833,16 @@ static void vrend_apply_sampler_state(struct vrend_context *ctx, */ bool is_emulated_alpha = vrend_format_is_emulated_alpha(res->base.format); if (has_feature(feat_samplers)) { + int sampler = vstate->ids[srgb_decode == GL_SKIP_DECODE_EXT ? 0 : 1]; if (is_emulated_alpha) { union pipe_color_union border_color; border_color = state->border_color; border_color.ui[0] = border_color.ui[3]; border_color.ui[3] = 0; - glSamplerParameterIuiv(vstate->id, GL_TEXTURE_BORDER_COLOR, border_color.ui); + glSamplerParameterIuiv(sampler, GL_TEXTURE_BORDER_COLOR, border_color.ui); } - glBindSampler(sampler_id, vstate->id); - if (has_feature(feat_texture_srgb_decode)) - glSamplerParameteri(vstate->id, GL_TEXTURE_SRGB_DECODE_EXT, - srgb_decode); + + glBindSampler(sampler_id, sampler); return; }