mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 04:58:05 +02:00
brw/algebraic: Allow mixed types in saturate constant folding
Prevents assertion failures in func.shader-ballot.basic.q0 and other
tests starting with "nir/algebraic: Optimize some b2f of integer
comparison".
Vector immediates, bfloat, and 8-bit floats are still not supported.
v2: Almost complete re-write based on suggestions from Ken.
v3: Don't retype() on a brw_imm_f value.
Fixes: f8e54d02f7 ("intel/compiler: Relax mixed type restriction for saturating immediates")
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38978>
This commit is contained in:
parent
dee99b38c5
commit
985ace332b
4 changed files with 76 additions and 78 deletions
|
|
@ -411,22 +411,35 @@ brw_opt_algebraic(brw_shader &s)
|
||||||
if (inst->src[0].file != IMM)
|
if (inst->src[0].file != IMM)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (inst->saturate) {
|
if (inst->saturate && brw_type_is_float(inst->dst.type)) {
|
||||||
/* Full mixed-type saturates don't happen. However, we can end up
|
switch (inst->src[0].type) {
|
||||||
* with things like:
|
case BRW_TYPE_UW:
|
||||||
*
|
case BRW_TYPE_UD:
|
||||||
* mov.sat(8) g21<1>DF -1F
|
case BRW_TYPE_UQ:
|
||||||
*
|
inst->src[0] = brw_imm_f(src_as_uint(inst->src[0]) != 0);
|
||||||
* Other mixed-size-but-same-base-type cases may also be possible.
|
|
||||||
*/
|
|
||||||
if (inst->dst.type != inst->src[0].type &&
|
|
||||||
inst->dst.type != BRW_TYPE_DF &&
|
|
||||||
inst->src[0].type != BRW_TYPE_F)
|
|
||||||
UNREACHABLE("unimplemented: saturate mixed types");
|
|
||||||
|
|
||||||
if (brw_reg_saturate_immediate(&inst->src[0])) {
|
|
||||||
inst->saturate = false;
|
inst->saturate = false;
|
||||||
progress = true;
|
progress = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BRW_TYPE_W:
|
||||||
|
case BRW_TYPE_D:
|
||||||
|
case BRW_TYPE_Q:
|
||||||
|
inst->src[0] = brw_imm_f((int64_t)src_as_uint(inst->src[0]) > 0);
|
||||||
|
inst->saturate = false;
|
||||||
|
progress = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BRW_TYPE_HF:
|
||||||
|
case BRW_TYPE_F:
|
||||||
|
case BRW_TYPE_DF:
|
||||||
|
inst->src[0] = brw_imm_f(SATURATE(src_as_float(inst->src[0])));
|
||||||
|
inst->saturate = false;
|
||||||
|
progress = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* VF, BF, BF8, HF8 and others are not handled. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -8,69 +8,6 @@
|
||||||
#include "brw_reg.h"
|
#include "brw_reg.h"
|
||||||
#include "util/macros.h"
|
#include "util/macros.h"
|
||||||
|
|
||||||
bool
|
|
||||||
brw_reg_saturate_immediate(brw_reg *reg)
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
unsigned ud;
|
|
||||||
int d;
|
|
||||||
float f;
|
|
||||||
double df;
|
|
||||||
} imm, sat_imm = { 0 };
|
|
||||||
|
|
||||||
const unsigned size = brw_type_size_bytes(reg->type);
|
|
||||||
|
|
||||||
/* We want to either do a 32-bit or 64-bit data copy, the type is otherwise
|
|
||||||
* irrelevant, so just check the size of the type and copy from/to an
|
|
||||||
* appropriately sized field.
|
|
||||||
*/
|
|
||||||
if (size < 8)
|
|
||||||
imm.ud = reg->ud;
|
|
||||||
else
|
|
||||||
imm.df = reg->df;
|
|
||||||
|
|
||||||
switch (reg->type) {
|
|
||||||
case BRW_TYPE_UD:
|
|
||||||
case BRW_TYPE_D:
|
|
||||||
case BRW_TYPE_UW:
|
|
||||||
case BRW_TYPE_W:
|
|
||||||
case BRW_TYPE_UQ:
|
|
||||||
case BRW_TYPE_Q:
|
|
||||||
/* Nothing to do. */
|
|
||||||
return false;
|
|
||||||
case BRW_TYPE_F:
|
|
||||||
sat_imm.f = SATURATE(imm.f);
|
|
||||||
break;
|
|
||||||
case BRW_TYPE_DF:
|
|
||||||
sat_imm.df = SATURATE(imm.df);
|
|
||||||
break;
|
|
||||||
case BRW_TYPE_UB:
|
|
||||||
case BRW_TYPE_B:
|
|
||||||
UNREACHABLE("no UB/B immediates");
|
|
||||||
case BRW_TYPE_V:
|
|
||||||
case BRW_TYPE_UV:
|
|
||||||
case BRW_TYPE_VF:
|
|
||||||
UNREACHABLE("unimplemented: saturate vector immediate");
|
|
||||||
case BRW_TYPE_HF:
|
|
||||||
UNREACHABLE("unimplemented: saturate HF immediate");
|
|
||||||
default:
|
|
||||||
UNREACHABLE("invalid type");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size < 8) {
|
|
||||||
if (imm.ud != sat_imm.ud) {
|
|
||||||
reg->ud = sat_imm.ud;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (imm.df != sat_imm.df) {
|
|
||||||
reg->df = sat_imm.df;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
brw_reg_negate_immediate(brw_reg *reg)
|
brw_reg_negate_immediate(brw_reg *reg)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1322,7 +1322,6 @@ element_sz(struct brw_reg reg)
|
||||||
int brw_float_to_vf(float f);
|
int brw_float_to_vf(float f);
|
||||||
float brw_vf_to_float(unsigned char vf);
|
float brw_vf_to_float(unsigned char vf);
|
||||||
|
|
||||||
bool brw_reg_saturate_immediate(brw_reg *reg);
|
|
||||||
bool brw_reg_negate_immediate(brw_reg *reg);
|
bool brw_reg_negate_immediate(brw_reg *reg);
|
||||||
bool brw_reg_abs_immediate(brw_reg *reg);
|
bool brw_reg_abs_immediate(brw_reg *reg);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,4 +96,53 @@ TEST_F(algebraic_test, mad_with_all_immediates)
|
||||||
EXPECT_SHADERS_MATCH(bld, exp);
|
EXPECT_SHADERS_MATCH(bld, exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(algebraic_test, mov_sat_neg_constant_type_d_conversion)
|
||||||
|
{
|
||||||
|
brw_builder bld = make_shader(MESA_SHADER_FRAGMENT, 16);
|
||||||
|
brw_builder exp = make_shader(MESA_SHADER_FRAGMENT, 16);
|
||||||
|
|
||||||
|
brw_reg dst0 = vgrf(bld, exp, BRW_TYPE_F);
|
||||||
|
|
||||||
|
bld.MOV(dst0, brw_imm_d(-5))
|
||||||
|
->saturate = true;
|
||||||
|
|
||||||
|
EXPECT_PROGRESS(brw_opt_algebraic, bld);
|
||||||
|
|
||||||
|
exp.MOV(dst0, brw_imm_f(0.0));
|
||||||
|
|
||||||
|
EXPECT_SHADERS_MATCH(bld, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(algebraic_test, mov_sat_neg_constant_type_ud_conversion)
|
||||||
|
{
|
||||||
|
brw_builder bld = make_shader(MESA_SHADER_FRAGMENT, 16);
|
||||||
|
brw_builder exp = make_shader(MESA_SHADER_FRAGMENT, 16);
|
||||||
|
|
||||||
|
brw_reg dst0 = vgrf(bld, exp, BRW_TYPE_F);
|
||||||
|
|
||||||
|
bld.MOV(dst0, brw_imm_ud(-5))
|
||||||
|
->saturate = true;
|
||||||
|
|
||||||
|
EXPECT_PROGRESS(brw_opt_algebraic, bld);
|
||||||
|
|
||||||
|
exp.MOV(dst0, brw_imm_f(1.0));
|
||||||
|
|
||||||
|
EXPECT_SHADERS_MATCH(bld, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(algebraic_test, mov_sat_pos_constant_type_conversion)
|
||||||
|
{
|
||||||
|
brw_builder bld = make_shader(MESA_SHADER_FRAGMENT, 16);
|
||||||
|
brw_builder exp = make_shader(MESA_SHADER_FRAGMENT, 16);
|
||||||
|
|
||||||
|
brw_reg dst0 = vgrf(bld, exp, BRW_TYPE_F);
|
||||||
|
|
||||||
|
bld.MOV(dst0, brw_imm_ud(37))
|
||||||
|
->saturate = true;
|
||||||
|
|
||||||
|
EXPECT_PROGRESS(brw_opt_algebraic, bld);
|
||||||
|
|
||||||
|
exp.MOV(dst0, brw_imm_f(1.0));
|
||||||
|
|
||||||
|
EXPECT_SHADERS_MATCH(bld, exp);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue