From 784086f3c1f50ca78fe62f925dfe66fb3aa5f22c Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 28 Mar 2016 10:28:29 -0400 Subject: [PATCH] freedreno/ir3: add support for NIR as preferred IR For now under debug flag, since only suitable for debugging/testing. Signed-off-by: Rob Clark --- .../drivers/freedreno/freedreno_screen.c | 20 ++++++++++- .../drivers/freedreno/freedreno_util.h | 1 + .../drivers/freedreno/ir3/ir3_compiler_nir.c | 8 +++++ src/gallium/drivers/freedreno/ir3/ir3_nir.c | 33 +++++++++++-------- src/gallium/drivers/freedreno/ir3/ir3_nir.h | 1 + .../drivers/freedreno/ir3/ir3_shader.c | 16 ++++++--- 6 files changed, 61 insertions(+), 18 deletions(-) diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 916151c52c3..32db3e2ed96 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -54,6 +54,8 @@ #include "a3xx/fd3_screen.h" #include "a4xx/fd4_screen.h" +#include "ir3/ir3_nir.h" + /* XXX this should go away */ #include "state_tracker/drm_driver.h" @@ -72,6 +74,7 @@ static const struct debug_named_value debug_options[] = { {"shaderdb", FD_DBG_SHADERDB, "Enable shaderdb output"}, {"flush", FD_DBG_FLUSH, "Force flush after every draw"}, {"deqp", FD_DBG_DEQP, "Enable dEQP hacks"}, + {"nir", FD_DBG_NIR, "Prefer NIR as native IR"}, DEBUG_NAMED_VALUE_END }; @@ -447,7 +450,7 @@ fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED: case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED: case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED: - case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: + case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: return 0; case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: return 1; @@ -459,6 +462,8 @@ fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: return 16; case PIPE_SHADER_CAP_PREFERRED_IR: + if ((fd_mesa_debug & FD_DBG_NIR) && is_ir3(screen)) + return PIPE_SHADER_IR_NIR; return PIPE_SHADER_IR_TGSI; case PIPE_SHADER_CAP_SUPPORTED_IRS: return 0; @@ -472,6 +477,18 @@ fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, return 0; } +static const void * +fd_get_compiler_options(struct pipe_screen *pscreen, + enum pipe_shader_ir ir, unsigned shader) +{ + struct fd_screen *screen = fd_screen(pscreen); + + if (is_ir3(screen)) + return ir3_get_compiler_options(); + + return NULL; +} + boolean fd_screen_bo_get_handle(struct pipe_screen *pscreen, struct fd_bo *bo, @@ -630,6 +647,7 @@ fd_screen_create(struct fd_device *dev) pscreen->get_param = fd_screen_get_param; pscreen->get_paramf = fd_screen_get_paramf; pscreen->get_shader_param = fd_screen_get_shader_param; + pscreen->get_compiler_options = fd_get_compiler_options; fd_resource_screen_init(pscreen); fd_query_screen_init(pscreen); diff --git a/src/gallium/drivers/freedreno/freedreno_util.h b/src/gallium/drivers/freedreno/freedreno_util.h index 34b21a3d42d..330cff9c0fb 100644 --- a/src/gallium/drivers/freedreno/freedreno_util.h +++ b/src/gallium/drivers/freedreno/freedreno_util.h @@ -74,6 +74,7 @@ enum adreno_stencil_op fd_stencil_op(unsigned op); #define FD_DBG_SHADERDB 0x0800 #define FD_DBG_FLUSH 0x1000 #define FD_DBG_DEQP 0x2000 +#define FD_DBG_NIR 0x4000 extern int fd_mesa_debug; extern bool fd_binning_enabled; diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c index 5f23272426e..a81aee38f36 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c @@ -2013,6 +2013,10 @@ setup_input(struct ir3_compile *ctx, nir_variable *in) DBG("; in: slot=%u, len=%ux%u, drvloc=%u", slot, array_len, ncomp, n); + /* let's pretend things other than vec4 don't exist: */ + ncomp = MAX2(ncomp, 4); + compile_assert(ctx, ncomp == 4); + so->inputs[n].slot = slot; so->inputs[n].compmask = (1 << ncomp) - 1; so->inputs_count = MAX2(so->inputs_count, n + 1); @@ -2094,6 +2098,10 @@ setup_output(struct ir3_compile *ctx, nir_variable *out) DBG("; out: slot=%u, len=%ux%u, drvloc=%u", slot, array_len, ncomp, n); + /* let's pretend things other than vec4 don't exist: */ + ncomp = MAX2(ncomp, 4); + compile_assert(ctx, ncomp == 4); + if (ctx->so->type == SHADER_FRAGMENT) { switch (slot) { case FRAG_RESULT_DEPTH: diff --git a/src/gallium/drivers/freedreno/ir3/ir3_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_nir.c index d93765cdd32..eda8ce20472 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_nir.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_nir.c @@ -35,25 +35,32 @@ #include "nir/tgsi_to_nir.h" +static const nir_shader_compiler_options options = { + .lower_fpow = true, + .lower_fsat = true, + .lower_scmp = true, + .lower_flrp32 = true, + .lower_flrp64 = true, + .lower_ffract = true, + .fuse_ffma = true, + .native_integers = true, + .vertex_id_zero_based = true, + .lower_extract_byte = true, + .lower_extract_word = true, +}; + struct nir_shader * ir3_tgsi_to_nir(const struct tgsi_token *tokens) { - static const nir_shader_compiler_options options = { - .lower_fpow = true, - .lower_fsat = true, - .lower_scmp = true, - .lower_flrp32 = true, - .lower_flrp64 = true, - .lower_ffract = true, - .fuse_ffma = true, - .native_integers = true, - .vertex_id_zero_based = true, - .lower_extract_byte = true, - .lower_extract_word = true, - }; return tgsi_to_nir(tokens, &options); } +const nir_shader_compiler_options * +ir3_get_compiler_options(void) +{ + return &options; +} + /* for given shader key, are any steps handled in nir? */ bool ir3_key_lowers_nir(const struct ir3_shader_key *key) diff --git a/src/gallium/drivers/freedreno/ir3/ir3_nir.h b/src/gallium/drivers/freedreno/ir3/ir3_nir.h index a2cf3478936..e1e95238c20 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_nir.h +++ b/src/gallium/drivers/freedreno/ir3/ir3_nir.h @@ -38,6 +38,7 @@ bool ir3_nir_lower_if_else(nir_shader *shader); bool ir3_nir_apply_trig_workarounds(nir_shader *shader); struct nir_shader * ir3_tgsi_to_nir(const struct tgsi_token *tokens); +const nir_shader_compiler_options * ir3_get_compiler_options(void); bool ir3_key_lowers_nir(const struct ir3_shader_key *key); struct nir_shader * ir3_optimize_nir(struct ir3_shader *shader, nir_shader *s, const struct ir3_shader_key *key); diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.c b/src/gallium/drivers/freedreno/ir3/ir3_shader.c index 4062ca989f0..cd596cf25a8 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.c @@ -283,17 +283,25 @@ ir3_shader_create(struct ir3_compiler *compiler, shader->compiler = compiler; shader->id = ++shader->compiler->shader_count; shader->type = type; - if (fd_mesa_debug & FD_DBG_DISASM) { - DBG("dump tgsi: type=%d", shader->type); - tgsi_dump(cso->tokens, 0); + + nir_shader *nir; + if (cso->type == PIPE_SHADER_IR_NIR) { + /* we take ownership of the reference: */ + nir = cso->ir.nir; + } else { + if (fd_mesa_debug & FD_DBG_DISASM) { + DBG("dump tgsi: type=%d", shader->type); + tgsi_dump(cso->tokens, 0); + } + nir = ir3_tgsi_to_nir(cso->tokens); } - nir_shader *nir = ir3_tgsi_to_nir(cso->tokens); /* do first pass optimization, ignoring the key: */ shader->nir = ir3_optimize_nir(shader, nir, NULL); if (fd_mesa_debug & FD_DBG_DISASM) { DBG("dump nir%d: type=%d", shader->id, shader->type); nir_print_shader(shader->nir, stdout); } + shader->stream_output = cso->stream_output; if (fd_mesa_debug & FD_DBG_SHADERDB) { /* if shader-db run, create a standard variant immediately -- 2.30.2