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 <italonicola@collabora.com>
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
macos/master
Italo Nicola 3 years ago committed by Gert Wollny
parent 2f054bd976
commit 072f30955b
  1. 10
      src/vrend_renderer.c
  2. 31
      src/vrend_shader.c
  3. 3
      src/vrend_shader.h

@ -420,6 +420,7 @@ struct vrend_linked_shader_program {
GLint fs_alpha_ref_val_loc; GLint fs_alpha_ref_val_loc;
GLint fs_alpha_func_loc; GLint fs_alpha_func_loc;
GLint clip_enabled_loc;
GLuint clip_locs[8]; GLuint clip_locs[8];
uint32_t images_used_mask[PIPE_SHADER_TYPES]; uint32_t images_used_mask[PIPE_SHADER_TYPES];
@ -1780,12 +1781,11 @@ static struct vrend_linked_shader_program *add_shader_program(struct vrend_sub_c
sprog->attrib_locs = NULL; sprog->attrib_locs = NULL;
} }
if (vs->var_sinfo.num_ucp) { sprog->clip_enabled_loc = glGetUniformLocation(prog_id, "clip_plane_enabled");
for (i = 0; i < vs->var_sinfo.num_ucp; i++) { for (i = 0; i < VIRGL_NUM_CLIP_PLANES; i++) {
snprintf(name, 32, "clipp[%d]", i); snprintf(name, 32, "clipp[%d]", i);
sprog->clip_locs[i] = glGetUniformLocation(prog_id, name); sprog->clip_locs[i] = glGetUniformLocation(prog_id, name);
} }
}
return sprog; 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->pstipple_tex = sub_ctx->rs_state.poly_stipple_enable;
key->color_two_side = sub_ctx->rs_state.light_twoside; 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; 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) { if (sub_ctx->rs_state.clip_plane_enable) {
glUniform1i(sub_ctx->prog->clip_enabled_loc, 1);
for (i = 0 ; i < 8; i++) { for (i = 0 ; i < 8; i++) {
glUniform4fv(sub_ctx->prog->clip_locs[i], 1, (const GLfloat *)&sub_ctx->ucp_state.ucp[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)) if (has_feature(feat_gles31_vertex_attrib_binding))

@ -2060,14 +2060,13 @@ static void emit_clip_dist_movs(const struct dump_ctx *ctx,
if (ctx->prog_type == PIPE_SHADER_TESS_CTRL) if (ctx->prog_type == PIPE_SHADER_TESS_CTRL)
prefix = "gl_out[gl_InvocationID]."; prefix = "gl_out[gl_InvocationID].";
if (ctx->num_out_clip_dist == 0 && ctx->key->clip_plane_enable) { if (ctx->num_out_clip_dist == 0 && ctx->is_last_vertex_stage) {
if (ctx->is_last_vertex_stage) { emit_buff(glsl_strbufs, "if (clip_plane_enabled) {\n");
for (i = 0; i < 8; i++) { 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, " %sgl_ClipDistance[%d] = dot(%s, clipp[%d]);\n",
} prefix, i, ctx->has_clipvertex ? "clipv_tmp" : "gl_Position", i);
return;
} }
emit_buff(glsl_strbufs, "}\n");
} }
ndists = ctx->num_out_clip_dist; ndists = ctx->num_out_clip_dist;
if (has_prop) 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) { if (ctx->cfg->use_gles) {
emit_ver_extf(glsl_strbufs, "#version %d es\n", ctx->cfg->glsl_version); emit_ver_extf(glsl_strbufs, "#version %d es\n", ctx->cfg->glsl_version);
if ((ctx->shader_req_bits & SHADER_REQ_CLIP_DISTANCE)|| if ((ctx->shader_req_bits & SHADER_REQ_CLIP_DISTANCE) || ctx->num_out_clip_dist == 0) {
(ctx->num_out_clip_dist == 0 && ctx->key->clip_plane_enable)) {
emit_ext(glsl_strbufs, "EXT_clip_cull_distance", "require"); 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 cull_buf[64] = "";
char clip_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_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; 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) if (num_cull_dists)
snprintf(cull_buf, 64, "out float gl_CullDistance[%d];\n", 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"); 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_hdrf(glsl_strbufs, "%s%s", clip_buf, cull_buf);
}
emit_hdr(glsl_strbufs, "vec4 clip_dist_temp[2];\n"); emit_hdr(glsl_strbufs, "vec4 clip_dist_temp[2];\n");
} }
@ -6862,12 +6862,10 @@ static void emit_ios_geom(const struct dump_ctx *ctx,
emit_hdrf(glsl_strbufs, "vec4 clip_dist_temp[2];\n"); emit_hdrf(glsl_strbufs, "vec4 clip_dist_temp[2];\n");
} }
if (ctx->key->clip_plane_enable) { emit_hdr(glsl_strbufs, "uniform bool clip_plane_enabled;\n");
emit_hdr(glsl_strbufs, "uniform vec4 clipp[8];\n"); emit_hdr(glsl_strbufs, "uniform vec4 clipp[8];\n");
} }
}
static void emit_ios_tcs(const struct dump_ctx *ctx, static void emit_ios_tcs(const struct dump_ctx *ctx,
struct vrend_glsl_strbufs *glsl_strbufs, struct vrend_glsl_strbufs *glsl_strbufs,
@ -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_in(ctx, glsl_strbufs, has_pervertex);
emit_ios_per_vertex_out(ctx, glsl_strbufs, ""); 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"); 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) 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.has_sample_input = ctx->has_sample_input;
sinfo->fs_info.num_interps = ctx->num_interps; sinfo->fs_info.num_interps = ctx->num_interps;
sinfo->fs_info.glsl_ver = ctx->glsl_ver_required; sinfo->fs_info.glsl_ver = ctx->glsl_ver_required;

@ -30,6 +30,8 @@
#include "vrend_strbuf.h" #include "vrend_strbuf.h"
#define VIRGL_NUM_CLIP_PLANES 8
enum gl_advanced_blend_mode enum gl_advanced_blend_mode
{ {
BLEND_NONE = 0, BLEND_NONE = 0,
@ -178,7 +180,6 @@ struct vrend_shader_key {
uint32_t sampler_views_lower_swizzle_mask; uint32_t sampler_views_lower_swizzle_mask;
uint16_t tex_swizzle[PIPE_MAX_SHADER_SAMPLER_VIEWS]; uint16_t tex_swizzle[PIPE_MAX_SHADER_SAMPLER_VIEWS];
uint8_t clip_plane_enable;
uint8_t num_in_cull : 4; uint8_t num_in_cull : 4;
uint8_t num_in_clip : 4; uint8_t num_in_clip : 4;
uint8_t num_out_cull : 4; uint8_t num_out_cull : 4;

Loading…
Cancel
Save