etnaviv: async shader compile
Passes following piglit: - spec@khr_parallel_shader_compile@basic Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16172>
This commit is contained in:
parent
a427a7f5d4
commit
1141ed5859
|
@ -301,7 +301,7 @@ Khronos, ARB, and OES extensions that are not part of any OpenGL or OpenGL ES ve
|
|||
GL_ARB_ES3_2_compatibility DONE (i965/gen8+, radeonsi, virgl, zink)
|
||||
GL_ARB_fragment_shader_interlock DONE (i965, zink)
|
||||
GL_ARB_gpu_shader_int64 DONE (i965/gen8+, nvc0, radeonsi, softpipe, llvmpipe, zink, d3d12)
|
||||
GL_ARB_parallel_shader_compile DONE (freedreno, iris, radeonsi)
|
||||
GL_ARB_parallel_shader_compile DONE (freedreno, iris, radeonsi, etnaviv)
|
||||
GL_ARB_post_depth_coverage DONE (i965, nvc0, radeonsi, llvmpipe, zink)
|
||||
GL_ARB_robustness_isolation not started
|
||||
GL_ARB_sample_locations DONE (nvc0, zink)
|
||||
|
|
|
@ -632,6 +632,9 @@ etna_set_debug_callback(struct pipe_context *pctx,
|
|||
const struct util_debug_callback *cb)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct etna_screen *screen = ctx->screen;
|
||||
|
||||
util_queue_finish(&screen->shader_compiler_queue);
|
||||
|
||||
if (cb)
|
||||
ctx->debug = *cb;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "util/slab.h"
|
||||
#include "util/u_dynarray.h"
|
||||
#include "util/u_helpers.h"
|
||||
#include "util/u_queue.h"
|
||||
#include "compiler/nir/nir.h"
|
||||
|
||||
struct etna_bo;
|
||||
|
@ -93,6 +94,7 @@ struct etna_screen {
|
|||
|
||||
struct etna_compiler *compiler;
|
||||
nir_shader_compiler_options options;
|
||||
struct util_queue shader_compiler_queue;
|
||||
};
|
||||
|
||||
static inline struct etna_screen *
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "tgsi/tgsi_parse.h"
|
||||
#include "nir/tgsi_to_nir.h"
|
||||
#include "util/u_atomic.h"
|
||||
#include "util/u_cpu_detect.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
|
@ -449,6 +450,30 @@ etna_shader_variant(struct etna_shader *shader, struct etna_shader_key key,
|
|||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should initial variants be compiled synchronously?
|
||||
*
|
||||
* The only case where pipe_debug_message() is used in the initial-variants
|
||||
* path is with ETNA_MESA_DEBUG=shaderdb. So if either debug is disabled (ie.
|
||||
* debug.debug_message==NULL), or shaderdb stats are not enabled, we can
|
||||
* compile the initial shader variant asynchronously.
|
||||
*/
|
||||
static inline bool
|
||||
initial_variants_synchronous(struct etna_context *ctx)
|
||||
{
|
||||
return unlikely(ctx->debug.debug_message) || (etna_mesa_debug & ETNA_DBG_SHADERDB);
|
||||
}
|
||||
|
||||
static void
|
||||
create_initial_variants_async(void *job, void *gdata, int thread_index)
|
||||
{
|
||||
struct etna_shader *shader = job;
|
||||
struct util_debug_callback debug = {};
|
||||
static struct etna_shader_key key;
|
||||
|
||||
etna_shader_variant(shader, key, &debug);
|
||||
}
|
||||
|
||||
static void *
|
||||
etna_create_shader_state(struct pipe_context *pctx,
|
||||
const struct pipe_shader_state *pss)
|
||||
|
@ -464,19 +489,20 @@ etna_create_shader_state(struct pipe_context *pctx,
|
|||
shader->id = p_atomic_inc_return(&compiler->shader_count);
|
||||
shader->specs = &screen->specs;
|
||||
shader->compiler = screen->compiler;
|
||||
util_queue_fence_init(&shader->ready);
|
||||
|
||||
shader->nir = (pss->type == PIPE_SHADER_IR_NIR) ? pss->ir.nir :
|
||||
tgsi_to_nir(pss->tokens, pctx->screen, false);
|
||||
|
||||
etna_disk_cache_init_shader_key(compiler, shader);
|
||||
|
||||
if (etna_mesa_debug & ETNA_DBG_SHADERDB) {
|
||||
/* if shader-db run, create a standard variant immediately
|
||||
* (as otherwise nothing will trigger the shader to be
|
||||
* actually compiled).
|
||||
*/
|
||||
if (initial_variants_synchronous(ctx)) {
|
||||
struct etna_shader_key key = {};
|
||||
etna_shader_variant(shader, key, &ctx->debug);
|
||||
} else {
|
||||
struct etna_screen *screen = ctx->screen;
|
||||
util_queue_add_job(&screen->shader_compiler_queue, shader, &shader->ready,
|
||||
create_initial_variants_async, NULL, 0);
|
||||
}
|
||||
|
||||
return shader;
|
||||
|
@ -521,6 +547,25 @@ etna_bind_vs_state(struct pipe_context *pctx, void *hwcso)
|
|||
ctx->dirty |= ETNA_DIRTY_SHADER;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_set_max_shader_compiler_threads(struct pipe_screen *pscreen,
|
||||
unsigned max_threads)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
|
||||
util_queue_adjust_num_threads(&screen->shader_compiler_queue, max_threads);
|
||||
}
|
||||
|
||||
static bool
|
||||
etna_is_parallel_shader_compilation_finished(struct pipe_screen *pscreen,
|
||||
void *hwcso,
|
||||
enum pipe_shader_type shader_type)
|
||||
{
|
||||
struct etna_shader *shader = (struct etna_shader *)hwcso;
|
||||
|
||||
return util_queue_fence_is_signalled(&shader->ready);
|
||||
}
|
||||
|
||||
void
|
||||
etna_shader_init(struct pipe_context *pctx)
|
||||
{
|
||||
|
@ -536,12 +581,21 @@ bool
|
|||
etna_shader_screen_init(struct pipe_screen *pscreen)
|
||||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
unsigned num_threads = util_get_cpu_caps()->nr_cpus - 1;
|
||||
|
||||
/* Create at least one thread - even on single core CPU systems. */
|
||||
num_threads = MAX2(1, num_threads);
|
||||
|
||||
screen->compiler = etna_compiler_create(pscreen->get_name(pscreen));
|
||||
if (!screen->compiler)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
pscreen->set_max_shader_compiler_threads = etna_set_max_shader_compiler_threads;
|
||||
pscreen->is_parallel_shader_compilation_finished = etna_is_parallel_shader_compilation_finished;
|
||||
|
||||
return util_queue_init(&screen->shader_compiler_queue, "sh", 64, num_threads,
|
||||
UTIL_QUEUE_INIT_RESIZE_IF_FULL | UTIL_QUEUE_INIT_SET_FULL_THREAD_AFFINITY,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -549,5 +603,6 @@ etna_shader_screen_fini(struct pipe_screen *pscreen)
|
|||
{
|
||||
struct etna_screen *screen = etna_screen(pscreen);
|
||||
|
||||
util_queue_destroy(&screen->shader_compiler_queue);
|
||||
etna_compiler_destroy(screen->compiler);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "nir.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "util/disk_cache.h"
|
||||
#include "util/u_queue.h"
|
||||
|
||||
struct etna_context;
|
||||
struct etna_shader_variant;
|
||||
|
@ -85,6 +86,9 @@ struct etna_shader {
|
|||
struct etna_shader_variant *variants;
|
||||
|
||||
cache_key cache_key; /* shader disk-cache key */
|
||||
|
||||
/* parallel shader compiles */
|
||||
struct util_queue_fence ready;
|
||||
};
|
||||
|
||||
bool
|
||||
|
|
Loading…
Reference in New Issue