From 072f30955b427c0e9bbc7b1c290e196b846a7598 Mon Sep 17 00:00:00 2001 From: Italo Nicola Date: Wed, 3 Nov 2021 07:40:36 -0300 Subject: [PATCH] shader: Always write code to toggle clip plane This prevents shader recompilation when the guest only wants to enable/disable clip plane in a compatibility profile. Can improve performance if many shaders have to be recompiled because of this, which happens in some games like Portal 2. Signed-off-by: Italo Nicola Reviewed-by: Gert Wollny --- src/vrend_renderer.c | 14 ++++++++------ src/vrend_shader.c | 35 +++++++++++++++++------------------ src/vrend_shader.h | 3 ++- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index 6137d88..0737f19 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -420,6 +420,7 @@ struct vrend_linked_shader_program { GLint fs_alpha_ref_val_loc; GLint fs_alpha_func_loc; + GLint clip_enabled_loc; GLuint clip_locs[8]; uint32_t images_used_mask[PIPE_SHADER_TYPES]; @@ -1780,11 +1781,10 @@ static struct vrend_linked_shader_program *add_shader_program(struct vrend_sub_c sprog->attrib_locs = NULL; } - if (vs->var_sinfo.num_ucp) { - for (i = 0; i < vs->var_sinfo.num_ucp; i++) { - snprintf(name, 32, "clipp[%d]", i); - sprog->clip_locs[i] = glGetUniformLocation(prog_id, name); - } + sprog->clip_enabled_loc = glGetUniformLocation(prog_id, "clip_plane_enabled"); + for (i = 0; i < VIRGL_NUM_CLIP_PLANES; i++) { + snprintf(name, 32, "clipp[%d]", i); + sprog->clip_locs[i] = glGetUniformLocation(prog_id, name); } return sprog; } @@ -3565,7 +3565,6 @@ static inline void vrend_fill_shader_key(struct vrend_sub_context *sub_ctx, key->pstipple_tex = sub_ctx->rs_state.poly_stipple_enable; key->color_two_side = sub_ctx->rs_state.light_twoside; - key->clip_plane_enable = sub_ctx->rs_state.clip_plane_enable; key->flatshade = sub_ctx->rs_state.flatshade ? true : false; } @@ -4949,9 +4948,12 @@ int vrend_draw_vbo(struct vrend_context *ctx, } if (sub_ctx->rs_state.clip_plane_enable) { + glUniform1i(sub_ctx->prog->clip_enabled_loc, 1); for (i = 0 ; i < 8; i++) { glUniform4fv(sub_ctx->prog->clip_locs[i], 1, (const GLfloat *)&sub_ctx->ucp_state.ucp[i]); } + } else { + glUniform1i(sub_ctx->prog->clip_enabled_loc, 0); } if (has_feature(feat_gles31_vertex_attrib_binding)) diff --git a/src/vrend_shader.c b/src/vrend_shader.c index 6371166..b9dc4fe 100644 --- a/src/vrend_shader.c +++ b/src/vrend_shader.c @@ -2060,14 +2060,13 @@ static void emit_clip_dist_movs(const struct dump_ctx *ctx, if (ctx->prog_type == PIPE_SHADER_TESS_CTRL) prefix = "gl_out[gl_InvocationID]."; - if (ctx->num_out_clip_dist == 0 && ctx->key->clip_plane_enable) { - if (ctx->is_last_vertex_stage) { - - for (i = 0; i < 8; i++) { - emit_buff(glsl_strbufs, "%sgl_ClipDistance[%d] = dot(%s, clipp[%d]);\n", prefix, i, ctx->has_clipvertex ? "clipv_tmp" : "gl_Position", i); - } - return; + if (ctx->num_out_clip_dist == 0 && ctx->is_last_vertex_stage) { + emit_buff(glsl_strbufs, "if (clip_plane_enabled) {\n"); + for (i = 0; i < 8; i++) { + emit_buff(glsl_strbufs, " %sgl_ClipDistance[%d] = dot(%s, clipp[%d]);\n", + prefix, i, ctx->has_clipvertex ? "clipv_tmp" : "gl_Position", i); } + emit_buff(glsl_strbufs, "}\n"); } ndists = ctx->num_out_clip_dist; if (has_prop) @@ -5642,8 +5641,7 @@ static void emit_header(const struct dump_ctx *ctx, struct vrend_glsl_strbufs *g if (ctx->cfg->use_gles) { emit_ver_extf(glsl_strbufs, "#version %d es\n", ctx->cfg->glsl_version); - if ((ctx->shader_req_bits & SHADER_REQ_CLIP_DISTANCE)|| - (ctx->num_out_clip_dist == 0 && ctx->key->clip_plane_enable)) { + if ((ctx->shader_req_bits & SHADER_REQ_CLIP_DISTANCE) || ctx->num_out_clip_dist == 0) { emit_ext(glsl_strbufs, "EXT_clip_cull_distance", "require"); } @@ -6522,7 +6520,7 @@ static void emit_ios_vs(const struct dump_ctx *ctx, char cull_buf[64] = ""; char clip_buf[64] = ""; - if (ctx->num_out_clip_dist || (ctx->key->clip_plane_enable && ctx->is_last_vertex_stage)) { + if (ctx->num_out_clip_dist || ctx->is_last_vertex_stage) { int num_clip_dists = ctx->num_clip_dist_prop ? ctx->num_clip_dist_prop : 0; int num_cull_dists = ctx->num_cull_dist_prop ? ctx->num_cull_dist_prop : 0; @@ -6535,11 +6533,13 @@ static void emit_ios_vs(const struct dump_ctx *ctx, if (num_cull_dists) snprintf(cull_buf, 64, "out float gl_CullDistance[%d];\n", num_cull_dists); - if (ctx->key->clip_plane_enable && ctx->is_last_vertex_stage) + if (ctx->is_last_vertex_stage) { + emit_hdr(glsl_strbufs, "uniform bool clip_plane_enabled;\n"); emit_hdr(glsl_strbufs, "uniform vec4 clipp[8];\n"); - if (ctx->is_last_vertex_stage) emit_hdrf(glsl_strbufs, "%s%s", clip_buf, cull_buf); + } + emit_hdr(glsl_strbufs, "vec4 clip_dist_temp[2];\n"); } @@ -6862,10 +6862,8 @@ static void emit_ios_geom(const struct dump_ctx *ctx, emit_hdrf(glsl_strbufs, "vec4 clip_dist_temp[2];\n"); } - if (ctx->key->clip_plane_enable) { - emit_hdr(glsl_strbufs, "uniform vec4 clipp[8];\n"); - } - + emit_hdr(glsl_strbufs, "uniform bool clip_plane_enabled;\n"); + emit_hdr(glsl_strbufs, "uniform vec4 clipp[8];\n"); } @@ -6955,7 +6953,8 @@ static void emit_ios_tes(const struct dump_ctx *ctx, emit_ios_per_vertex_in(ctx, glsl_strbufs, has_pervertex); emit_ios_per_vertex_out(ctx, glsl_strbufs, ""); - if (ctx->key->clip_plane_enable && !ctx->key->gs_present) { + if (ctx->is_last_vertex_stage) { + emit_hdr(glsl_strbufs, "uniform bool clip_plane_enabled;\n"); emit_hdr(glsl_strbufs, "uniform vec4 clipp[8];\n"); } @@ -7114,7 +7113,7 @@ static boolean analyze_instruction(struct tgsi_iterate_context *iter, static void fill_var_sinfo(const struct dump_ctx *ctx, struct vrend_variable_shader_info *sinfo) { - sinfo->num_ucp = ctx->key->clip_plane_enable ? 8 : 0; + sinfo->num_ucp = ctx->is_last_vertex_stage ? VIRGL_NUM_CLIP_PLANES : 0; sinfo->fs_info.has_sample_input = ctx->has_sample_input; sinfo->fs_info.num_interps = ctx->num_interps; sinfo->fs_info.glsl_ver = ctx->glsl_ver_required; diff --git a/src/vrend_shader.h b/src/vrend_shader.h index 604cada..5288a77 100644 --- a/src/vrend_shader.h +++ b/src/vrend_shader.h @@ -30,6 +30,8 @@ #include "vrend_strbuf.h" +#define VIRGL_NUM_CLIP_PLANES 8 + enum gl_advanced_blend_mode { BLEND_NONE = 0, @@ -178,7 +180,6 @@ struct vrend_shader_key { uint32_t sampler_views_lower_swizzle_mask; uint16_t tex_swizzle[PIPE_MAX_SHADER_SAMPLER_VIEWS]; - uint8_t clip_plane_enable; uint8_t num_in_cull : 4; uint8_t num_in_clip : 4; uint8_t num_out_cull : 4;