if (st->shader_has_one_variant[prog->info.stage] && stp->variants)
return stp->variants->driver_shader;
- return st_get_basic_variant(st, pipe_shader, stp)->driver_shader;
+ struct st_basic_variant_key key;
+
+ /* use memset, not an initializer to be sure all memory is zeroed */
+ memset(&key, 0, sizeof(key));
+
+ key.st = st->has_shareable_shaders ? NULL : st;
+
+ if (pipe_shader == PIPE_SHADER_GEOMETRY ||
+ pipe_shader == PIPE_SHADER_TESS_EVAL) {
+ key.clamp_color = st->clamp_vert_color_in_shader &&
+ st->ctx->Light._ClampVertexColor &&
+ (stp->Base.info.outputs_written &
+ (VARYING_SLOT_COL0 |
+ VARYING_SLOT_COL1 |
+ VARYING_SLOT_BFC0 |
+ VARYING_SLOT_BFC1));
+ }
+
+ return st_get_basic_variant(st, pipe_shader, stp, &key)->driver_shader;
}
st->dirty |= ST_NEW_VERTEX_ARRAYS;
/* Update the vertex shader if ctx->Light._ClampVertexColor was changed. */
- if (st->clamp_vert_color_in_shader && (new_state & _NEW_LIGHT))
+ if (st->clamp_vert_color_in_shader && (new_state & _NEW_LIGHT)) {
st->dirty |= ST_NEW_VS_STATE;
+ if (st->ctx->API == API_OPENGL_COMPAT && ctx->Version >= 32) {
+ st->dirty |= ST_NEW_GS_STATE | ST_NEW_TES_STATE;
+ }
+ }
/* Which shaders are dirty will be determined manually. */
if (new_state & _NEW_PROGRAM) {
!st->force_persample_in_shader;
st->shader_has_one_variant[MESA_SHADER_TESS_CTRL] = st->has_shareable_shaders;
- st->shader_has_one_variant[MESA_SHADER_TESS_EVAL] = st->has_shareable_shaders;
- st->shader_has_one_variant[MESA_SHADER_GEOMETRY] = st->has_shareable_shaders;
+ st->shader_has_one_variant[MESA_SHADER_TESS_EVAL] =
+ st->has_shareable_shaders &&
+ !st->clamp_vert_color_in_shader;
+ st->shader_has_one_variant[MESA_SHADER_GEOMETRY] =
+ st->has_shareable_shaders &&
+ !st->clamp_vert_color_in_shader;
st->shader_has_one_variant[MESA_SHADER_COMPUTE] = st->has_shareable_shaders;
st->bitmap.cache.empty = true;
struct st_basic_variant *
st_get_basic_variant(struct st_context *st,
unsigned pipe_shader,
- struct st_common_program *prog)
+ struct st_common_program *prog,
+ const struct st_basic_variant_key *key)
{
struct pipe_context *pipe = st->pipe;
struct st_basic_variant *v;
- struct st_basic_variant_key key;
struct pipe_shader_state tgsi = {0};
- memset(&key, 0, sizeof(key));
- key.st = st->has_shareable_shaders ? NULL : st;
/* Search for existing variant */
for (v = prog->variants; v; v = v->next) {
if (prog->tgsi.type == PIPE_SHADER_IR_NIR) {
tgsi.type = PIPE_SHADER_IR_NIR;
tgsi.ir.nir = nir_shader_clone(NULL, prog->tgsi.ir.nir);
+
+ if (key->clamp_color)
+ NIR_PASS_V(tgsi.ir.nir, nir_lower_clamp_color_outputs);
+
tgsi.stream_output = prog->tgsi.stream_output;
} else
tgsi = prog->tgsi;
return NULL;
}
- v->key = key;
+ v->key = *key;
/* insert into list */
v->next = prog->variants;
case GL_TESS_CONTROL_PROGRAM_NV: {
struct st_common_program *p = st_common_program(prog);
- st_get_basic_variant(st, PIPE_SHADER_TESS_CTRL, p);
+ struct st_basic_variant_key key;
+
+ memset(&key, 0, sizeof(key));
+
+ key.st = st->has_shareable_shaders ? NULL : st;
+ st_get_basic_variant(st, PIPE_SHADER_TESS_CTRL, p, &key);
break;
}
case GL_TESS_EVALUATION_PROGRAM_NV: {
struct st_common_program *p = st_common_program(prog);
- st_get_basic_variant(st, PIPE_SHADER_TESS_EVAL, p);
+ struct st_basic_variant_key key;
+
+ memset(&key, 0, sizeof(key));
+
+ key.st = st->has_shareable_shaders ? NULL : st;
+ st_get_basic_variant(st, PIPE_SHADER_TESS_EVAL, p, &key);
break;
}
case GL_GEOMETRY_PROGRAM_NV: {
struct st_common_program *p = st_common_program(prog);
- st_get_basic_variant(st, PIPE_SHADER_GEOMETRY, p);
+ struct st_basic_variant_key key;
+
+ memset(&key, 0, sizeof(key));
+
+ key.st = st->has_shareable_shaders ? NULL : st;
+ st_get_basic_variant(st, PIPE_SHADER_GEOMETRY, p, &key);
break;
}
struct st_basic_variant_key
{
struct st_context *st; /**< variants are per-context */
+
+ /** For compat profile */
+ bool clamp_color;
};
extern struct st_basic_variant *
st_get_basic_variant(struct st_context *st,
unsigned pipe_shader,
- struct st_common_program *p);
+ struct st_common_program *p,
+ const struct st_basic_variant_key *key);
extern void
st_release_vp_variants( struct st_context *st,