summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Turner <mattst88@gmail.com>2018-12-10 11:06:16 -0800
committerMatt Turner <mattst88@gmail.com>2019-01-09 16:42:41 -0800
commit613ac3aaa295ad2a6271ee8315e16ee31456fa9d (patch)
treeadbea420332b7522ef0a59bf5b94ec7159a5586f
parent18b4e87370d3ebb9d7dbb51e58b2da1b64a2227f (diff)
i965: Compile fp64 software routines and lower double-ops
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
-rw-r--r--src/intel/compiler/brw_nir.c92
-rw-r--r--src/mesa/drivers/dri/i965/Makefile.am1
-rw-r--r--src/mesa/drivers/dri/i965/brw_program.c61
-rw-r--r--src/mesa/drivers/dri/i965/meson.build2
4 files changed, 133 insertions, 23 deletions
diff --git a/src/intel/compiler/brw_nir.c b/src/intel/compiler/brw_nir.c
index 77c6c4e0e5a..749c00ebcc6 100644
--- a/src/intel/compiler/brw_nir.c
+++ b/src/intel/compiler/brw_nir.c
@@ -612,15 +612,6 @@ brw_nir_optimize(nir_shader *nir, const struct brw_compiler *compiler,
}
OPT(nir_opt_remove_phis);
OPT(nir_opt_undef);
- OPT(nir_lower_doubles, nir_lower_drcp |
- nir_lower_dsqrt |
- nir_lower_drsq |
- nir_lower_dtrunc |
- nir_lower_dfloor |
- nir_lower_dceil |
- nir_lower_dfract |
- nir_lower_dround_even |
- nir_lower_dmod);
OPT(nir_lower_pack);
} while (progress);
@@ -668,6 +659,76 @@ brw_preprocess_nir(const struct brw_compiler *compiler, nir_shader *nir)
const bool is_scalar = compiler->scalar_stage[nir->info.stage];
+ if (is_scalar) {
+ OPT(nir_lower_alu_to_scalar);
+ }
+
+ /* Run opt_algebraic before int64 lowering so we can hopefully get rid
+ * of some int64 instructions.
+ */
+ OPT(nir_opt_algebraic);
+
+ /* Lower 64-bit operations before nir_optimize so that loop unrolling sees
+ * their actual cost.
+ */
+ nir_lower_int64_options int64_options =
+ nir_lower_imul64 |
+ nir_lower_isign64 |
+ nir_lower_divmod64 |
+ nir_lower_imul_high64;
+ nir_lower_doubles_options fp64_options =
+ nir_lower_drcp |
+ nir_lower_dsqrt |
+ nir_lower_drsq |
+ nir_lower_dtrunc |
+ nir_lower_dfloor |
+ nir_lower_dceil |
+ nir_lower_dfract |
+ nir_lower_dround_even |
+ nir_lower_dmod;
+
+ if (!devinfo->has_64bit_types) {
+ int64_options |= nir_lower_mov64 |
+ nir_lower_icmp64 |
+ nir_lower_iadd64 |
+ nir_lower_iabs64 |
+ nir_lower_ineg64 |
+ nir_lower_logic64 |
+ nir_lower_minmax64 |
+ nir_lower_shift64;
+ fp64_options |= nir_lower_fp64_full_software;
+ }
+
+ bool lowered_64bit_ops = false;
+ do {
+ progress = false;
+
+ OPT(nir_lower_int64, int64_options);
+ OPT(nir_lower_doubles, fp64_options);
+
+ /* Necessary to lower add -> sub and div -> mul/rcp */
+ OPT(nir_opt_algebraic);
+
+ lowered_64bit_ops |= progress;
+ } while (progress);
+
+ if (lowered_64bit_ops) {
+ OPT(nir_lower_constant_initializers, nir_var_function);
+ OPT(nir_lower_returns);
+ OPT(nir_inline_functions);
+ OPT(nir_opt_deref);
+ }
+
+ const nir_function *entry_point = nir_shader_get_entrypoint(nir)->function;
+ foreach_list_typed_safe(nir_function, func, node, &nir->functions) {
+ if (func != entry_point) {
+ exec_node_remove(&func->node);
+ }
+ }
+ assert(exec_list_length(&nir->functions) == 1);
+
+ OPT(nir_lower_constant_initializers, ~nir_var_function);
+
if (nir->info.stage == MESA_SHADER_GEOMETRY)
OPT(nir_lower_gs_intrinsics);
@@ -694,19 +755,6 @@ brw_preprocess_nir(const struct brw_compiler *compiler, nir_shader *nir)
OPT(nir_split_var_copies);
OPT(nir_split_struct_vars, nir_var_function);
- /* Run opt_algebraic before int64 lowering so we can hopefully get rid
- * of some int64 instructions.
- */
- OPT(nir_opt_algebraic);
-
- /* Lower int64 instructions before nir_optimize so that loop unrolling
- * sees their actual cost.
- */
- OPT(nir_lower_int64, nir_lower_imul64 |
- nir_lower_isign64 |
- nir_lower_divmod64 |
- nir_lower_imul_high64);
-
nir = brw_nir_optimize(nir, compiler, is_scalar, true);
/* This needs to be run after the first optimization pass but before we
diff --git a/src/mesa/drivers/dri/i965/Makefile.am b/src/mesa/drivers/dri/i965/Makefile.am
index 3df8cdec320..491d3c8f780 100644
--- a/src/mesa/drivers/dri/i965/Makefile.am
+++ b/src/mesa/drivers/dri/i965/Makefile.am
@@ -26,6 +26,7 @@ include Makefile.sources
AM_CFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/ \
+ -I$(top_builddir)/src/ \
-I$(top_srcdir)/src/mapi \
-I$(top_srcdir)/src/mesa/ \
-I$(top_srcdir)/src/gallium/include \
diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c
index 730d6dc0d5a..168a2bd5f50 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -41,6 +41,7 @@
#include "util/ralloc.h"
#include "compiler/glsl/ir.h"
#include "compiler/glsl/glsl_to_nir.h"
+#include "compiler/glsl/float64_glsl.h"
#include "brw_program.h"
#include "brw_context.h"
@@ -53,6 +54,9 @@
#include "brw_vs.h"
#include "brw_wm.h"
+#include "main/shaderapi.h"
+#include "main/shaderobj.h"
+
static bool
brw_nir_lower_uniforms(nir_shader *nir, bool is_scalar)
{
@@ -67,6 +71,54 @@ brw_nir_lower_uniforms(nir_shader *nir, bool is_scalar)
}
}
+static struct gl_program *brwNewProgram(struct gl_context *ctx, GLenum target,
+ GLuint id, bool is_arb_asm);
+
+static nir_shader *
+compile_fp64_funcs(struct gl_context *ctx,
+ const nir_shader_compiler_options *options,
+ void *mem_ctx,
+ gl_shader_stage stage)
+{
+ const GLuint name = ~0;
+ struct gl_shader *sh;
+
+ sh = _mesa_new_shader(name, stage);
+
+ sh->Source = float64_source;
+ sh->CompileStatus = COMPILE_FAILURE;
+ _mesa_compile_shader(ctx, sh);
+
+ if (!sh->CompileStatus) {
+ if (sh->InfoLog) {
+ _mesa_problem(ctx,
+ "fp64 software impl compile failed:\n%s\nsource:\n%s\n",
+ sh->InfoLog, float64_source);
+ }
+ }
+
+ struct gl_shader_program *sh_prog;
+ sh_prog = _mesa_new_shader_program(name);
+ sh_prog->Label = NULL;
+ sh_prog->NumShaders = 1;
+ sh_prog->Shaders = malloc(sizeof(struct gl_shader *));
+ sh_prog->Shaders[0] = sh;
+
+ struct gl_linked_shader *linked = rzalloc(NULL, struct gl_linked_shader);
+ linked->Stage = stage;
+ linked->Program =
+ brwNewProgram(ctx,
+ _mesa_shader_stage_to_program(stage),
+ name, false);
+
+ linked->ir = sh->ir;
+ sh_prog->_LinkedShaders[stage] = linked;
+
+ nir_shader *nir = glsl_to_nir(sh_prog, stage, options);
+
+ return nir_shader_clone(mem_ctx, nir);
+}
+
nir_shader *
brw_create_nir(struct brw_context *brw,
const struct gl_shader_program *shader_prog,
@@ -101,6 +153,15 @@ brw_create_nir(struct brw_context *brw,
}
nir_validate_shader(nir, "before brw_preprocess_nir");
+ nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
+
+ if (nir->info.uses_64bit) {
+ nir_shader *fp64 = compile_fp64_funcs(ctx, options, ralloc_parent(nir), stage);
+
+ nir_validate_shader(fp64, "fp64");
+ exec_list_append(&nir->functions, &fp64->functions);
+ }
+
nir = brw_preprocess_nir(brw->screen->compiler, nir);
NIR_PASS_V(nir, brw_nir_lower_image_load_store, devinfo);
diff --git a/src/mesa/drivers/dri/i965/meson.build b/src/mesa/drivers/dri/i965/meson.build
index 24172955e9b..3b71cf2605b 100644
--- a/src/mesa/drivers/dri/i965/meson.build
+++ b/src/mesa/drivers/dri/i965/meson.build
@@ -213,7 +213,7 @@ endif
libi965 = static_library(
'i965',
[files_i965, i965_oa_sources, ir_expression_operation_h,
- xmlpool_options_h],
+ xmlpool_options_h, float64_glsl_h],
include_directories : [
inc_common, inc_intel, inc_dri_common, inc_util, inc_drm_uapi,
],