return;
util_queue_destroy(&sscreen->shader_compiler_queue);
+ util_queue_destroy(&sscreen->shader_compiler_queue_low_priority);
for (i = 0; i < ARRAY_SIZE(sscreen->tm); i++)
if (sscreen->tm[i])
LLVMDisposeTargetMachine(sscreen->tm[i]);
+ for (i = 0; i < ARRAY_SIZE(sscreen->tm_low_priority); i++)
+ if (sscreen->tm_low_priority[i])
+ LLVMDisposeTargetMachine(sscreen->tm_low_priority[i]);
+
/* Free shader parts. */
for (i = 0; i < ARRAY_SIZE(parts); i++) {
while (parts[i]) {
struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws)
{
struct si_screen *sscreen = CALLOC_STRUCT(si_screen);
- unsigned num_cpus, num_compiler_threads, i;
+ unsigned num_threads, num_compiler_threads, num_compiler_threads_lowprio, i;
if (!sscreen) {
return NULL;
/* Only enable as many threads as we have target machines, but at most
* the number of CPUs - 1 if there is more than one.
*/
- num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
- num_cpus = MAX2(1, num_cpus - 1);
- num_compiler_threads = MIN2(num_cpus, ARRAY_SIZE(sscreen->tm));
+ num_threads = sysconf(_SC_NPROCESSORS_ONLN);
+ num_threads = MAX2(1, num_threads - 1);
+ num_compiler_threads = MIN2(num_threads, ARRAY_SIZE(sscreen->tm));
+ num_compiler_threads_lowprio =
+ MIN2(num_threads, ARRAY_SIZE(sscreen->tm_low_priority));
if (!util_queue_init(&sscreen->shader_compiler_queue, "si_shader",
32, num_compiler_threads, 0)) {
return NULL;
}
+ /* The queue must be large enough so that adding optimized shaders
+ * doesn't stall draw calls when the queue is full. Especially varying
+ * packing generates a very high volume of optimized shader compilation
+ * jobs.
+ */
+ if (!util_queue_init(&sscreen->shader_compiler_queue_low_priority,
+ "si_shader_low",
+ 1024, num_compiler_threads,
+ UTIL_QUEUE_INIT_USE_MINIMUM_PRIORITY)) {
+ si_destroy_shader_cache(sscreen);
+ FREE(sscreen);
+ return NULL;
+ }
+
si_handle_env_var_force_family(sscreen);
if (!debug_get_bool_option("RADEON_DISABLE_PERFCOUNTERS", false))
for (i = 0; i < num_compiler_threads; i++)
sscreen->tm[i] = si_create_llvm_target_machine(sscreen);
+ for (i = 0; i < num_compiler_threads_lowprio; i++)
+ sscreen->tm_low_priority[i] = si_create_llvm_target_machine(sscreen);
/* Create the auxiliary context. This must be done last. */
sscreen->b.aux_context = si_create_context(&sscreen->b.b, 0);
int r;
if (thread_index >= 0) {
- assert(thread_index < ARRAY_SIZE(sscreen->tm));
- tm = sscreen->tm[thread_index];
+ assert(thread_index < ARRAY_SIZE(sscreen->tm_low_priority));
+ tm = sscreen->tm_low_priority[thread_index];
if (!debug->async)
debug = NULL;
} else {
!is_pure_monolithic &&
thread_index < 0) {
/* Compile it asynchronously. */
- util_queue_add_job(&sscreen->shader_compiler_queue,
+ util_queue_add_job(&sscreen->shader_compiler_queue_low_priority,
shader, &shader->optimized_ready,
si_build_shader_variant, NULL);
static void si_delete_shader(struct si_context *sctx, struct si_shader *shader)
{
if (shader->is_optimized) {
- util_queue_drop_job(&sctx->screen->shader_compiler_queue,
+ util_queue_drop_job(&sctx->screen->shader_compiler_queue_low_priority,
&shader->optimized_ready);
util_queue_fence_destroy(&shader->optimized_ready);
}