glsl: replace LowerPrecisionFP16/Int16 with pipe caps

Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36582>
This commit is contained in:
Marek Olšák 2025-08-05 14:53:54 -04:00
parent 7fa7240ae1
commit 3b252cbe92
6 changed files with 59 additions and 27 deletions

View file

@ -1331,7 +1331,8 @@ preprocess_shader(const struct pipe_screen *screen,
NIR_PASS(_, nir, nir_lower_global_vars_to_local);
NIR_PASS(_, nir, nir_lower_var_copies);
if (gl_options->LowerPrecisionFloat16 && gl_options->LowerPrecisionInt16) {
if (screen->shader_caps[nir->info.stage].fp16 &&
screen->shader_caps[nir->info.stage].int16) {
NIR_PASS(_, nir, nir_lower_mediump_vars, nir_var_function_temp | nir_var_shader_temp | nir_var_mem_shared);
}

View file

@ -2396,8 +2396,10 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
if (!state->error && !shader->ir->is_empty()) {
if (state->es_shader &&
(options->LowerPrecisionFloat16 || options->LowerPrecisionInt16))
lower_precision(options, shader->ir);
(ctx->screen->shader_caps[shader->Stage].fp16 ||
ctx->screen->shader_caps[shader->Stage].int16))
lower_precision(ctx->screen, shader->Stage, options, shader->ir);
lower_builtins(shader->ir);
assign_subroutine_indexes(state);
lower_subroutine(shader->ir, state);

View file

@ -65,7 +65,9 @@ bool propagate_invariance(ir_exec_list *instructions);
namespace ir_builder { class ir_factory; };
void lower_precision(const struct gl_shader_compiler_options *options,
void lower_precision(const struct pipe_screen *screen,
mesa_shader_stage stage,
const struct gl_shader_compiler_options *options,
ir_exec_list *instructions);
#endif /* GLSL_IR_OPTIMIZATION_H */

View file

@ -27,6 +27,7 @@
#include "main/macros.h"
#include "main/consts_exts.h"
#include "pipe/p_screen.h"
#include "compiler/glsl_types.h"
#include "ir.h"
#include "ir_builder.h"
@ -41,7 +42,9 @@ namespace {
class find_precision_visitor : public ir_rvalue_enter_visitor {
public:
find_precision_visitor(const struct gl_shader_compiler_options *options);
find_precision_visitor(const struct pipe_screen *screen,
mesa_shader_stage stage,
const struct gl_shader_compiler_options *options);
find_precision_visitor(const find_precision_visitor &) = delete;
~find_precision_visitor();
find_precision_visitor & operator=(const find_precision_visitor &) = delete;
@ -67,6 +70,8 @@ public:
*/
struct hash_table *clone_ht;
const struct pipe_screen *screen;
mesa_shader_stage stage;
const struct gl_shader_compiler_options *options;
};
@ -104,6 +109,8 @@ public:
};
find_lowerable_rvalues_visitor(struct set *result,
const struct pipe_screen *screen,
mesa_shader_stage stage,
const struct gl_shader_compiler_options *options);
static void stack_enter(class ir_instruction *ir, void *data);
@ -126,6 +133,8 @@ public:
static parent_relation get_parent_relation(ir_instruction *parent,
ir_instruction *child);
const struct pipe_screen *screen;
mesa_shader_stage stage;
std::vector<stack_entry> stack;
struct set *lowerable_rvalues;
const struct gl_shader_compiler_options *options;
@ -145,7 +154,7 @@ public:
};
static bool
can_lower_type(const struct gl_shader_compiler_options *options,
can_lower_type(const struct pipe_screen *screen, mesa_shader_stage stage,
const glsl_type *type)
{
/* Dont lower any expressions involving non-float types except bool and
@ -165,11 +174,11 @@ can_lower_type(const struct gl_shader_compiler_options *options,
return true;
case GLSL_TYPE_FLOAT:
return options->LowerPrecisionFloat16;
return screen->shader_caps[stage].fp16;
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
return options->LowerPrecisionInt16;
return screen->shader_caps[stage].int16;
default:
return false;
@ -177,8 +186,12 @@ can_lower_type(const struct gl_shader_compiler_options *options,
}
find_lowerable_rvalues_visitor::find_lowerable_rvalues_visitor(struct set *res,
const struct pipe_screen *screen,
mesa_shader_stage stage,
const struct gl_shader_compiler_options *opts)
{
this->screen = screen;
this->stage = stage;
lowerable_rvalues = res;
options = opts;
callback_enter = stack_enter;
@ -288,7 +301,7 @@ enum find_lowerable_rvalues_visitor::can_lower_state
find_lowerable_rvalues_visitor::handle_precision(const glsl_type *type,
int precision) const
{
if (!can_lower_type(options, type))
if (!can_lower_type(screen, stage, type))
return CANT_LOWER;
switch (precision) {
@ -330,7 +343,7 @@ find_lowerable_rvalues_visitor::visit(ir_constant *ir)
{
stack_enter(ir, this);
if (!can_lower_type(options, ir->type))
if (!can_lower_type(screen, stage, ir->type))
stack.back().state = CANT_LOWER;
stack_leave(ir, this);
@ -391,7 +404,7 @@ find_lowerable_rvalues_visitor::visit_enter(ir_expression *ir)
{
ir_hierarchical_visitor::visit_enter(ir);
if (!can_lower_type(options, ir->type))
if (!can_lower_type(screen, stage, ir->type))
stack.back().state = CANT_LOWER;
/* Don't lower precision for derivative calculations */
@ -601,12 +614,14 @@ find_lowerable_rvalues_visitor::visit_leave(ir_assignment *ir)
return visit_continue;
}
void
find_lowerable_rvalues(const struct gl_shader_compiler_options *options,
static void
find_lowerable_rvalues(const struct pipe_screen *screen,
mesa_shader_stage stage,
const struct gl_shader_compiler_options *options,
ir_exec_list *instructions,
struct set *result)
{
find_lowerable_rvalues_visitor v(result, options);
find_lowerable_rvalues_visitor v(result, screen, stage, options);
visit_list_elements(&v, instructions);
@ -912,7 +927,7 @@ find_precision_visitor::map_builtin(linear_ctx *linalloc, ir_function_signature
}
}
lower_precision(options, &lowered_sig->body);
lower_precision(screen, stage, options, &lowered_sig->body);
_mesa_hash_table_clear(clone_ht, NULL);
@ -921,10 +936,14 @@ find_precision_visitor::map_builtin(linear_ctx *linalloc, ir_function_signature
return lowered_sig;
}
find_precision_visitor::find_precision_visitor(const struct gl_shader_compiler_options *options)
find_precision_visitor::find_precision_visitor(const struct pipe_screen *screen,
mesa_shader_stage stage,
const struct gl_shader_compiler_options *options)
: lowerable_rvalues(_mesa_pointer_set_create(NULL)),
lowered_builtins(NULL),
clone_ht(NULL),
screen(screen),
stage(stage),
options(options)
{
}
@ -949,8 +968,10 @@ find_precision_visitor::~find_precision_visitor()
*/
class lower_variables_visitor : public ir_rvalue_enter_visitor {
public:
lower_variables_visitor(const struct gl_shader_compiler_options *options)
: options(options) {
lower_variables_visitor(const struct pipe_screen *screen,
mesa_shader_stage stage,
const struct gl_shader_compiler_options *options)
: screen(screen), stage(stage), options(options) {
lower_vars = _mesa_pointer_set_create(NULL);
}
@ -972,6 +993,8 @@ public:
void convert_split_assignment(ir_dereference *lhs, ir_rvalue *rhs,
bool insert_before);
const struct pipe_screen *screen;
mesa_shader_stage stage;
const struct gl_shader_compiler_options *options;
set *lower_vars;
};
@ -1019,7 +1042,7 @@ lower_variables_visitor::visit(ir_variable *var)
!glsl_type_is_32bit(glsl_without_array(var->type)) ||
(var->data.precision != GLSL_PRECISION_MEDIUM &&
var->data.precision != GLSL_PRECISION_LOW) ||
!can_lower_type(options, var->type))
!can_lower_type(screen, stage, var->type))
return visit_continue;
/* Lower constant initializers. */
@ -1339,13 +1362,16 @@ lower_variables_visitor::visit_enter(ir_call *ir)
}
void
lower_precision(const struct gl_shader_compiler_options *options,
lower_precision(const struct pipe_screen *screen,
mesa_shader_stage stage,
const struct gl_shader_compiler_options *options,
ir_exec_list *instructions)
{
find_precision_visitor v(options);
find_lowerable_rvalues(options, instructions, v.lowerable_rvalues);
find_precision_visitor v(screen, stage, options);
find_lowerable_rvalues(screen, stage, options, instructions,
v.lowerable_rvalues);
visit_list_elements(&v, instructions);
lower_variables_visitor vars(options);
lower_variables_visitor vars(screen, stage, options);
visit_list_elements(&vars, instructions);
}

View file

@ -365,10 +365,11 @@ standalone_compile_shader(const struct standalone_options *_options,
if (options->lower_precision) {
for (unsigned i = MESA_SHADER_VERTEX; i <= MESA_SHADER_COMPUTE; i++) {
((struct pipe_shader_caps*)&ctx->screen->shader_caps[i])->fp16 = true;
((struct pipe_shader_caps*)&ctx->screen->shader_caps[i])->int16 = true;
struct gl_shader_compiler_options *options =
&ctx->Const.ShaderCompilerOptions[i];
options->LowerPrecisionFloat16 = true;
options->LowerPrecisionInt16 = true;
options->LowerPrecisionDerivatives = true;
options->LowerPrecisionConstants = true;
options->LowerPrecisionFloat16Uniforms = true;

View file

@ -173,8 +173,8 @@ namespace
initialize_context_to_defaults(ctx, API_OPENGLES2);
ctx->Version = 31;
for (int i = 0; i < MESA_SHADER_STAGES; i++) {
ctx->Const.ShaderCompilerOptions[i].LowerPrecisionFloat16 = true;
ctx->Const.ShaderCompilerOptions[i].LowerPrecisionInt16 = true;
((struct pipe_shader_caps*)&ctx->screen->shader_caps[i])->fp16 = true;
((struct pipe_shader_caps*)&ctx->screen->shader_caps[i])->int16 = true;
ctx->screen->nir_options[i] = &compiler_options;
}