* uploaded to a buffer).
*/
struct si_shader *main_shader_part;
+ struct si_shader *main_shader_part_ls; /* as_ls is set in the key */
+ struct si_shader *main_shader_part_es; /* as_es is set in the key */
struct si_shader *gs_copy_shader;
bool writes_samplemask);
const char *si_get_shader_name(struct si_shader *shader, unsigned processor);
+/* Inline helpers. */
+
+/* Return the pointer to the main shader part's pointer. */
+static inline struct si_shader **
+si_get_main_shader_part(struct si_shader_selector *sel,
+ struct si_shader_key *key)
+{
+ if (key->as_ls)
+ return &sel->main_shader_part_ls;
+ if (key->as_es)
+ return &sel->main_shader_part_es;
+ return &sel->main_shader_part;
+}
+
#endif
shader->key = *key;
shader->compiler_ctx_state = *compiler_state;
+ /* Compile the main shader part if it doesn't exist. This can happen
+ * if the initial guess was wrong. */
+ struct si_shader **mainp = si_get_main_shader_part(sel, key);
bool is_pure_monolithic =
memcmp(&key->mono, &zeroed.mono, sizeof(key->mono)) != 0;
+ if (!*mainp && !is_pure_monolithic) {
+ struct si_shader *main_part = CALLOC_STRUCT(si_shader);
+
+ if (!main_part) {
+ FREE(shader);
+ pipe_mutex_unlock(sel->mutex);
+ return -ENOMEM; /* skip the draw call */
+ }
+
+ main_part->selector = sel;
+ main_part->key.as_es = key->as_es;
+ main_part->key.as_ls = key->as_ls;
+
+ if (si_compile_tgsi_shader(sscreen, compiler_state->tm,
+ main_part, false,
+ &compiler_state->debug) != 0) {
+ FREE(main_part);
+ FREE(shader);
+ pipe_mutex_unlock(sel->mutex);
+ return -ENOMEM; /* skip the draw call */
+ }
+ *mainp = main_part;
+ }
+
/* Monolithic-only shaders don't make a distinction between optimized
* and unoptimized. */
shader->is_monolithic =
- !sel->main_shader_part ||
- sel->main_shader_part->key.as_ls != key->as_ls ||
- sel->main_shader_part->key.as_es != key->as_es ||
is_pure_monolithic ||
memcmp(&key->opt, &zeroed.opt, sizeof(key->opt)) != 0;
}
}
- sel->main_shader_part = shader;
+ *si_get_main_shader_part(sel, &shader->key) = shader;
/* Unset "outputs_written" flags for outputs converted to
* DEFAULT_VAL, so that later inter-shader optimizations don't
if (sel->main_shader_part)
si_delete_shader(sctx, sel->main_shader_part);
+ if (sel->main_shader_part_ls)
+ si_delete_shader(sctx, sel->main_shader_part_ls);
+ if (sel->main_shader_part_es)
+ si_delete_shader(sctx, sel->main_shader_part_es);
if (sel->gs_copy_shader)
si_delete_shader(sctx, sel->gs_copy_shader);