aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker/st_glsl_to_nir.cpp
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2019-01-10 16:24:57 +1000
committerJordan Justen <[email protected]>2019-03-02 14:33:44 -0800
commitcb4e3e3ef6e47811303ad3413a4ab2048696a6f6 (patch)
treeac5fec4d31abae35e1b5605f24ffabe5e1b77178 /src/mesa/state_tracker/st_glsl_to_nir.cpp
parent7de056e1a9661273ba5055d094f17cf0b9ca92f3 (diff)
st/mesa: add support for lowering fp64/int64 for nir drivers
This might enough for iris and possible r600 (when it gets NIR) This appears to work for iris. v2: * change cap return so DOUBLES == 2 means sw emu v3: * Refactor using int64/doubles lowering options which were added into nir options * Remove DOUBLES == 2 added in v2 [jordan: Remove "2" value on PIPE_CAP_DOUBLES] [jordan: Use lowering options added to nir options] Signed-off-by: Jordan Justen <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]> Acked-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/mesa/state_tracker/st_glsl_to_nir.cpp')
-rw-r--r--src/mesa/state_tracker/st_glsl_to_nir.cpp99
1 files changed, 98 insertions, 1 deletions
diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp
index 89f7424e4db..a1e3b6233c6 100644
--- a/src/mesa/state_tracker/st_glsl_to_nir.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp
@@ -36,6 +36,7 @@
#include "main/shaderapi.h"
#include "main/uniforms.h"
+#include "main/shaderobj.h"
#include "st_context.h"
#include "st_glsl_types.h"
#include "st_program.h"
@@ -47,7 +48,7 @@
#include "compiler/glsl/ir.h"
#include "compiler/glsl/ir_optimization.h"
#include "compiler/glsl/string_to_uint_map.h"
-
+#include "compiler/glsl/float64_glsl.h"
static int
type_size(const struct glsl_type *type)
@@ -340,6 +341,50 @@ st_nir_opts(nir_shader *nir, bool scalar)
} while (progress);
}
+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 = (struct gl_shader **)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 =
+ ctx->Driver.NewProgram(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);
+}
+
/* First third of converting glsl_to_nir.. this leaves things in a pre-
* nir_lower_io state, so that shader variants can more easily insert/
* replace variables, etc.
@@ -355,6 +400,8 @@ st_glsl_to_nir(struct st_context *st, struct gl_program *prog,
struct pipe_screen *screen = st->pipe->screen;
bool is_scalar = screen->get_shader_param(screen, type, PIPE_SHADER_CAP_SCALAR_ISA);
assert(options);
+ bool lower_64bit =
+ options->lower_int64_options || options->lower_doubles_options;
if (prog->nir)
return prog->nir;
@@ -376,6 +423,16 @@ st_glsl_to_nir(struct st_context *st, struct gl_program *prog,
nir->info.next_stage = MESA_SHADER_FRAGMENT;
}
+ nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
+ if (nir->info.uses_64bit &&
+ (options->lower_doubles_options & nir_lower_fp64_full_software) != 0) {
+ nir_shader *fp64 =
+ compile_fp64_funcs(st->ctx, options, ralloc_parent(nir),
+ nir->info.stage);
+ nir_validate_shader(fp64, "fp64");
+ exec_list_append(&nir->functions, &fp64->functions);
+ }
+
nir_variable_mode mask =
(nir_variable_mode) (nir_var_shader_in | nir_var_shader_out);
nir_remove_dead_variables(nir, mask);
@@ -396,6 +453,46 @@ st_glsl_to_nir(struct st_context *st, struct gl_program *prog,
NIR_PASS_V(nir, nir_split_var_copies);
NIR_PASS_V(nir, nir_lower_var_copies);
+ if (is_scalar) {
+ NIR_PASS_V(nir, nir_lower_alu_to_scalar);
+ }
+
+ if (lower_64bit) {
+ bool lowered_64bit_ops = false;
+ bool progress = false;
+
+ NIR_PASS_V(nir, nir_opt_algebraic);
+
+ do {
+ progress = false;
+ if (options->lower_int64_options) {
+ NIR_PASS(progress, nir, nir_lower_int64,
+ options->lower_int64_options);
+ }
+ if (options->lower_doubles_options) {
+ NIR_PASS(progress, nir, nir_lower_doubles,
+ options->lower_doubles_options);
+ }
+ NIR_PASS(progress, nir, nir_opt_algebraic);
+ lowered_64bit_ops |= progress;
+ } while (progress);
+
+ if (lowered_64bit_ops) {
+ NIR_PASS_V(nir, nir_lower_constant_initializers, nir_var_function_temp);
+ NIR_PASS_V(nir, nir_lower_returns);
+ NIR_PASS_V(nir, nir_inline_functions);
+ NIR_PASS_V(nir, 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);
+ }
+
st_nir_opts(nir, is_scalar);
return nir;