summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2015-10-24 14:30:31 -0400
committerRob Clark <[email protected]>2016-01-03 09:11:27 -0500
commit74135f804a4f18040a0a62664df67d35c8090d1d (patch)
treeb40783bee441273a7d63758ab4838d953a1f5dec /src/gallium/drivers
parentab4efb19dc4dd5f4e5822f90178f0edba1c4095a (diff)
freedreno/ir3: refactor NIR IR handling
Immediately convert into NIR and do an initial key-agnostic lowering/ optimization pass. This should let us share most of the per-variant transformations between each variant, and hopefully minimize the draw- time variant creation part of the compilation process. Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/freedreno/Makefile.sources1
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_cmdline.c15
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c118
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_nir.c144
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_nir.h7
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_shader.c24
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_shader.h4
7 files changed, 202 insertions, 111 deletions
diff --git a/src/gallium/drivers/freedreno/Makefile.sources b/src/gallium/drivers/freedreno/Makefile.sources
index baae9144005..74ef4168655 100644
--- a/src/gallium/drivers/freedreno/Makefile.sources
+++ b/src/gallium/drivers/freedreno/Makefile.sources
@@ -128,6 +128,7 @@ ir3_SOURCES := \
ir3/ir3_group.c \
ir3/ir3.h \
ir3/ir3_legalize.c \
+ ir3/ir3_nir.c \
ir3/ir3_nir.h \
ir3/ir3_nir_lower_if_else.c \
ir3/ir3_print.c \
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c
index d55daeefe06..481859efb17 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c
@@ -40,6 +40,7 @@
#include "freedreno_util.h"
#include "ir3_compiler.h"
+#include "ir3_nir.h"
#include "instr-a3xx.h"
#include "ir3.h"
@@ -105,10 +106,10 @@ int main(int argc, char **argv)
const char *filename;
struct tgsi_token toks[65536];
struct tgsi_parse_context parse;
- struct ir3_compiler *compiler;
struct ir3_shader_variant v;
struct ir3_shader s;
struct ir3_shader_key key = {};
+ /* TODO cmdline option to target different gpus: */
unsigned gpu_id = 320;
const char *info;
void *ptr;
@@ -228,7 +229,12 @@ int main(int argc, char **argv)
if (!tgsi_text_translate(ptr, toks, Elements(toks)))
errx(1, "could not parse `%s'", filename);
- s.tokens = toks;
+ if (fd_mesa_debug & FD_DBG_OPTMSGS)
+ tgsi_dump(toks, 0);
+
+ nir_shader *nir = ir3_tgsi_to_nir(toks);
+ s.compiler = ir3_compiler_create(gpu_id);
+ s.nir = ir3_optimize_nir(&s, nir, NULL);
v.key = key;
v.shader = &s;
@@ -246,11 +252,8 @@ int main(int argc, char **argv)
break;
}
- /* TODO cmdline option to target different gpus: */
- compiler = ir3_compiler_create(gpu_id);
-
info = "NIR compiler";
- ret = ir3_compile_shader_nir(compiler, &v);
+ ret = ir3_compile_shader_nir(s.compiler, &v);
if (ret) {
fprintf(stderr, "compiler failed!\n");
return ret;
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
index bb2221d17d3..0a25d5252a1 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
@@ -32,10 +32,6 @@
#include "util/u_string.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
-#include "tgsi/tgsi_lowering.h"
-#include "tgsi/tgsi_strings.h"
-
-#include "nir/tgsi_to_nir.h"
#include "freedreno_util.h"
@@ -123,97 +119,10 @@ struct ir3_compile {
static struct ir3_instruction * create_immed(struct ir3_block *block, uint32_t val);
static struct ir3_block * get_block(struct ir3_compile *ctx, nir_block *nblock);
-static struct nir_shader *to_nir(struct ir3_compile *ctx,
- const struct tgsi_token *tokens, struct ir3_shader_variant *so)
-{
- static const nir_shader_compiler_options options = {
- .lower_fpow = true,
- .lower_fsat = true,
- .lower_scmp = true,
- .lower_flrp = true,
- .lower_ffract = true,
- .native_integers = true,
- };
- struct nir_lower_tex_options tex_options = {
- .lower_rect = 0,
- };
- bool progress;
-
- switch (so->type) {
- case SHADER_FRAGMENT:
- case SHADER_COMPUTE:
- tex_options.saturate_s = so->key.fsaturate_s;
- tex_options.saturate_t = so->key.fsaturate_t;
- tex_options.saturate_r = so->key.fsaturate_r;
- break;
- case SHADER_VERTEX:
- tex_options.saturate_s = so->key.vsaturate_s;
- tex_options.saturate_t = so->key.vsaturate_t;
- tex_options.saturate_r = so->key.vsaturate_r;
- break;
- }
-
- if (ctx->compiler->gpu_id >= 400) {
- /* a4xx seems to have *no* sam.p */
- tex_options.lower_txp = ~0; /* lower all txp */
- } else {
- /* a3xx just needs to avoid sam.p for 3d tex */
- tex_options.lower_txp = (1 << GLSL_SAMPLER_DIM_3D);
- }
-
- struct nir_shader *s = tgsi_to_nir(tokens, &options);
-
- if (fd_mesa_debug & FD_DBG_DISASM) {
- debug_printf("----------------------\n");
- nir_print_shader(s, stdout);
- debug_printf("----------------------\n");
- }
-
- nir_opt_global_to_local(s);
- nir_convert_to_ssa(s);
- if (s->stage == MESA_SHADER_VERTEX) {
- nir_lower_clip_vs(s, so->key.ucp_enables);
- } else if (s->stage == MESA_SHADER_FRAGMENT) {
- nir_lower_clip_fs(s, so->key.ucp_enables);
- }
- nir_lower_tex(s, &tex_options);
- if (so->key.color_two_side)
- nir_lower_two_sided_color(s);
- nir_lower_idiv(s);
- nir_lower_load_const_to_scalar(s);
-
- do {
- progress = false;
-
- nir_lower_vars_to_ssa(s);
- nir_lower_alu_to_scalar(s);
- nir_lower_phis_to_scalar(s);
-
- progress |= nir_copy_prop(s);
- progress |= nir_opt_dce(s);
- progress |= nir_opt_cse(s);
- progress |= ir3_nir_lower_if_else(s);
- progress |= nir_opt_algebraic(s);
- progress |= nir_opt_constant_folding(s);
-
- } while (progress);
-
- nir_remove_dead_variables(s);
- nir_validate_shader(s);
-
- if (fd_mesa_debug & FD_DBG_DISASM) {
- debug_printf("----------------------\n");
- nir_print_shader(s, stdout);
- debug_printf("----------------------\n");
- }
-
- return s;
-}
static struct ir3_compile *
compile_init(struct ir3_compiler *compiler,
- struct ir3_shader_variant *so,
- const struct tgsi_token *tokens)
+ struct ir3_shader_variant *so)
{
struct ir3_compile *ctx = rzalloc(NULL, struct ir3_compile);
@@ -239,7 +148,28 @@ compile_init(struct ir3_compiler *compiler,
ctx->block_ht = _mesa_hash_table_create(ctx,
_mesa_hash_pointer, _mesa_key_pointer_equal);
- ctx->s = to_nir(ctx, tokens, so);
+ /* TODO: maybe generate some sort of bitmask of what key
+ * lowers vs what shader has (ie. no need to lower
+ * texture clamp lowering if no texture sample instrs)..
+ * although should be done further up the stack to avoid
+ * creating duplicate variants..
+ */
+
+ if (ir3_key_lowers_nir(&so->key)) {
+ nir_shader *s = nir_shader_clone(ctx, so->shader->nir);
+ ctx->s = ir3_optimize_nir(so->shader, s, &so->key);
+ } else {
+ /* fast-path for shader key that lowers nothing in NIR: */
+ ctx->s = so->shader->nir;
+ }
+
+ if (fd_mesa_debug & FD_DBG_DISASM) {
+ DBG("dump nir%dv%d: type=%d, k={bp=%u,cts=%u,hp=%u}",
+ so->shader->id, so->id, so->type,
+ so->key.binning_pass, so->key.color_two_side,
+ so->key.half_precision);
+ nir_print_shader(ctx->s, stdout);
+ }
so->first_driver_param = so->first_immediate = ctx->s->num_uniforms;
@@ -2497,7 +2427,7 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,
assert(!so->ir);
- ctx = compile_init(compiler, so, so->shader->tokens);
+ ctx = compile_init(compiler, so);
if (!ctx) {
DBG("INIT failed!");
ret = -1;
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_nir.c
new file mode 100644
index 00000000000..4d83ee6a987
--- /dev/null
+++ b/src/gallium/drivers/freedreno/ir3/ir3_nir.c
@@ -0,0 +1,144 @@
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2015 Rob Clark <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <[email protected]>
+ */
+
+
+#include "freedreno_util.h"
+
+#include "ir3_nir.h"
+#include "ir3_compiler.h"
+#include "ir3_shader.h"
+
+#include "nir/tgsi_to_nir.h"
+
+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_flrp = true,
+ .lower_ffract = true,
+ .native_integers = true,
+ };
+ return tgsi_to_nir(tokens, &options);
+}
+
+/* for given shader key, are any steps handled in nir? */
+bool
+ir3_key_lowers_nir(const struct ir3_shader_key *key)
+{
+ return key->fsaturate_s | key->fsaturate_t | key->fsaturate_r |
+ key->vsaturate_s | key->vsaturate_t | key->vsaturate_r |
+ key->ucp_enables | key->color_two_side;
+}
+
+struct nir_shader *
+ir3_optimize_nir(struct ir3_shader *shader, nir_shader *s,
+ const struct ir3_shader_key *key)
+{
+ struct nir_lower_tex_options tex_options = {
+ .lower_rect = 0,
+ };
+ bool progress;
+
+ if (key) {
+ switch (shader->type) {
+ case SHADER_FRAGMENT:
+ case SHADER_COMPUTE:
+ tex_options.saturate_s = key->fsaturate_s;
+ tex_options.saturate_t = key->fsaturate_t;
+ tex_options.saturate_r = key->fsaturate_r;
+ break;
+ case SHADER_VERTEX:
+ tex_options.saturate_s = key->vsaturate_s;
+ tex_options.saturate_t = key->vsaturate_t;
+ tex_options.saturate_r = key->vsaturate_r;
+ break;
+ }
+ }
+
+ if (shader->compiler->gpu_id >= 400) {
+ /* a4xx seems to have *no* sam.p */
+ tex_options.lower_txp = ~0; /* lower all txp */
+ } else {
+ /* a3xx just needs to avoid sam.p for 3d tex */
+ tex_options.lower_txp = (1 << GLSL_SAMPLER_DIM_3D);
+ }
+
+ if (fd_mesa_debug & FD_DBG_DISASM) {
+ debug_printf("----------------------\n");
+ nir_print_shader(s, stdout);
+ debug_printf("----------------------\n");
+ }
+
+ nir_opt_global_to_local(s);
+ nir_convert_to_ssa(s);
+ if (key) {
+ if (s->stage == MESA_SHADER_VERTEX) {
+ nir_lower_clip_vs(s, key->ucp_enables);
+ } else if (s->stage == MESA_SHADER_FRAGMENT) {
+ nir_lower_clip_fs(s, key->ucp_enables);
+ }
+ if (key->color_two_side) {
+ nir_lower_two_sided_color(s);
+ }
+ }
+ nir_lower_tex(s, &tex_options);
+ nir_lower_idiv(s);
+ nir_lower_load_const_to_scalar(s);
+
+ do {
+ progress = false;
+
+ nir_lower_vars_to_ssa(s);
+ nir_lower_alu_to_scalar(s);
+ nir_lower_phis_to_scalar(s);
+
+ progress |= nir_copy_prop(s);
+ progress |= nir_opt_dce(s);
+ progress |= nir_opt_cse(s);
+ progress |= ir3_nir_lower_if_else(s);
+ progress |= nir_opt_algebraic(s);
+ progress |= nir_opt_constant_folding(s);
+
+ } while (progress);
+
+ nir_remove_dead_variables(s);
+ nir_validate_shader(s);
+
+ if (fd_mesa_debug & FD_DBG_DISASM) {
+ debug_printf("----------------------\n");
+ nir_print_shader(s, stdout);
+ debug_printf("----------------------\n");
+ }
+
+ nir_sweep(s);
+
+ return s;
+}
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_nir.h b/src/gallium/drivers/freedreno/ir3/ir3_nir.h
index 9950782dc38..534199d3744 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_nir.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3_nir.h
@@ -32,6 +32,13 @@
#include "glsl/nir/nir.h"
#include "glsl/nir/shader_enums.h"
+#include "ir3_shader.h"
+
bool ir3_nir_lower_if_else(nir_shader *shader);
+struct nir_shader * ir3_tgsi_to_nir(const struct tgsi_token *tokens);
+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);
+
#endif /* IR3_NIR_H_ */
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.c b/src/gallium/drivers/freedreno/ir3/ir3_shader.c
index 7b565332256..7d17f426ad3 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_shader.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.c
@@ -39,7 +39,7 @@
#include "ir3_shader.h"
#include "ir3_compiler.h"
-
+#include "ir3_nir.h"
static void
delete_variant(struct ir3_shader_variant *v)
@@ -187,12 +187,6 @@ create_variant(struct ir3_shader *shader, struct ir3_shader_key key)
v->key = key;
v->type = shader->type;
- if (fd_mesa_debug & FD_DBG_DISASM) {
- DBG("dump tgsi: type=%d, k={bp=%u,cts=%u,hp=%u}", shader->type,
- key.binning_pass, key.color_two_side, key.half_precision);
- tgsi_dump(shader->tokens, 0);
- }
-
ret = ir3_compile_shader_nir(shader->compiler, v);
if (ret) {
debug_error("compile failed!");
@@ -267,7 +261,7 @@ ir3_shader_destroy(struct ir3_shader *shader)
v = v->next;
delete_variant(t);
}
- free((void *)shader->tokens);
+ ralloc_free(shader->nir);
free(shader);
}
@@ -281,14 +275,24 @@ ir3_shader_create(struct pipe_context *pctx,
shader->id = ++shader->compiler->shader_count;
shader->pctx = pctx;
shader->type = type;
- shader->tokens = tgsi_dup_tokens(cso->tokens);
+ if (fd_mesa_debug & FD_DBG_DISASM) {
+ DBG("dump tgsi: type=%d", shader->type);
+ tgsi_dump(cso->tokens, 0);
+ }
+ 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
* (as otherwise nothing will trigger the shader to be
* actually compiled)
*/
- static struct ir3_shader_key key = {};
+ static struct ir3_shader_key key = {0};
ir3_shader_variant(shader, key);
}
return shader;
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.h b/src/gallium/drivers/freedreno/ir3/ir3_shader.h
index cf99a4c05ed..b3c28a41387 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_shader.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.h
@@ -230,6 +230,8 @@ struct ir3_shader_variant {
struct ir3_shader *shader;
};
+typedef struct nir_shader nir_shader;
+
struct ir3_shader {
enum shader_t type;
@@ -240,7 +242,7 @@ struct ir3_shader {
struct ir3_compiler *compiler;
struct pipe_context *pctx; /* TODO replace w/ pipe_screen */
- const struct tgsi_token *tokens;
+ nir_shader *nir;
struct pipe_stream_output_info stream_output;
struct ir3_shader_variant *variants;