mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 09:08:10 +02:00
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 <jordan.l.justen@intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Acked-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
parent
7de056e1a9
commit
cb4e3e3ef6
1 changed files with 98 additions and 1 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue