diff options
Diffstat (limited to 'src/gallium/drivers/freedreno/ir3')
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3_shader.c | 27 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3_shader.h | 58 |
2 files changed, 55 insertions, 30 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.c b/src/gallium/drivers/freedreno/ir3/ir3_shader.c index c77cec10cc7..1f7e869d9f3 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.c @@ -182,23 +182,30 @@ ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key) * so normalize the key to avoid constructing multiple identical * variants: */ - if (shader->type == SHADER_FRAGMENT) { + switch (shader->type) { + case SHADER_FRAGMENT: + case SHADER_COMPUTE: key.binning_pass = false; - key.vsaturate_s = 0; - key.vsaturate_t = 0; - key.vsaturate_r = 0; - } - if (shader->type == SHADER_VERTEX) { + if (key.has_per_samp) { + key.vsaturate_s = 0; + key.vsaturate_t = 0; + key.vsaturate_r = 0; + } + break; + case SHADER_VERTEX: key.color_two_side = false; key.half_precision = false; key.alpha = false; - key.fsaturate_s = 0; - key.fsaturate_t = 0; - key.fsaturate_r = 0; + if (key.has_per_samp) { + key.fsaturate_s = 0; + key.fsaturate_t = 0; + key.fsaturate_r = 0; + } + break; } for (v = shader->variants; v; v = v->next) - if (!memcmp(&key, &v->key, sizeof(key))) + if (ir3_shader_key_equal(&key, &v->key)) return v; /* compile new variant if it doesn't exist already: */ diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.h b/src/gallium/drivers/freedreno/ir3/ir3_shader.h index c531ad704cc..628c09e1be3 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.h +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.h @@ -54,36 +54,54 @@ static inline uint16_t sem2idx(ir3_semantic sem) * in hw (two sided color), binning-pass vertex shader, etc. */ struct ir3_shader_key { + union { + struct { + /* do we need to check {v,f}saturate_{s,t,r}? */ + unsigned has_per_samp : 1; + + /* + * Vertex shader variant parameters: + */ + unsigned binning_pass : 1; + + /* + * Fragment shader variant parameters: + */ + unsigned color_two_side : 1; + unsigned half_precision : 1; + /* For rendering to alpha, we need a bit of special handling + * since the hw always takes gl_FragColor starting from x + * component, rather than figuring out to take the w component. + * We could be more clever and generate variants for other + * render target formats (ie. luminance formats are xxx1), but + * let's start with this and see how it goes: + */ + unsigned alpha : 1; + }; + uint32_t global; + }; + /* bitmask of sampler which needs coords clamped for vertex * shader: */ - unsigned vsaturate_s, vsaturate_t, vsaturate_r; + uint16_t vsaturate_s, vsaturate_t, vsaturate_r; /* bitmask of sampler which needs coords clamped for frag * shader: */ - unsigned fsaturate_s, fsaturate_t, fsaturate_r; - - /* - * Vertex shader variant parameters: - */ - unsigned binning_pass : 1; + uint16_t fsaturate_s, fsaturate_t, fsaturate_r; - /* - * Fragment shader variant parameters: - */ - unsigned color_two_side : 1; - unsigned half_precision : 1; - /* For rendering to alpha, we need a bit of special handling - * since the hw always takes gl_FragColor starting from x - * component, rather than figuring out to take the w component. - * We could be more clever and generate variants for other - * render target formats (ie. luminance formats are xxx1), but - * let's start with this and see how it goes: - */ - unsigned alpha : 1; }; +static inline bool +ir3_shader_key_equal(struct ir3_shader_key *a, struct ir3_shader_key *b) +{ + /* slow-path if we need to check {v,f}saturate_{s,t,r} */ + if (a->has_per_samp || b->has_per_samp) + return memcmp(a, b, sizeof(struct ir3_shader_key)) == 0; + return a->global == b->global; +} + struct ir3_shader_variant { struct fd_bo *bo; |