Am Dienstag, den 11.07.2017, 15:07 +0200 schrieb Wladimir J. van der Laan: > GC3000 has a new LOG instruction, similar to the new SIN and COS instructions. > > Generate the new instruction sequence when appropriate; there are > two occasions, as part of LIT and the generator for the LG2 > instruction itself. > > Signed-off-by: Wladimir J. van der Laan <laa...@gmail.com>
In a quick test this fixes all the misrendering I was observing in the various glmark2 benchmarks on GC3000. Tested-by: Lucas Stach <l.st...@pengutronix.de> > --- > src/gallium/drivers/etnaviv/etnaviv_compiler.c | 63 > +++++++++++++++++++++++--- > src/gallium/drivers/etnaviv/etnaviv_internal.h | 4 +- > src/gallium/drivers/etnaviv/etnaviv_screen.c | 2 +- > 3 files changed, 59 insertions(+), 10 deletions(-) > > diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler.c > b/src/gallium/drivers/etnaviv/etnaviv_compiler.c > index 07315f7..6435b84 100644 > --- a/src/gallium/drivers/etnaviv/etnaviv_compiler.c > +++ b/src/gallium/drivers/etnaviv/etnaviv_compiler.c > @@ -1389,12 +1389,27 @@ trans_lit(const struct instr_translater *t, struct > etna_compile *c, > else > src_w = swizzle(src[0], SWIZZLE(W, W, W, W)); > > - struct etna_inst ins[3] = { }; > - ins[0].opcode = INST_OPCODE_LOG; > - ins[0].dst = etna_native_to_dst(inner_temp, INST_COMPS_X); > - ins[0].src[2] = src_y; > + if (c->specs->has_new_transcendentals) { /* Alternative LOG sequence */ > + emit_inst(c, &(struct etna_inst) { > + .opcode = INST_OPCODE_LOG, > + .dst = etna_native_to_dst(inner_temp, INST_COMPS_X | INST_COMPS_Y), > + .src[2] = src_y, > + .tex = { .amode=1 }, /* Unknown bit needs to be set */ > + }); > + emit_inst(c, &(struct etna_inst) { > + .opcode = INST_OPCODE_MUL, > + .dst = etna_native_to_dst(inner_temp, INST_COMPS_X), > + .src[0] = etna_native_to_src(inner_temp, SWIZZLE(X, X, X, X)), > + .src[1] = etna_native_to_src(inner_temp, SWIZZLE(Y, Y, Y, Y)), > + }); > + } else { > + struct etna_inst ins[3] = { }; > + ins[0].opcode = INST_OPCODE_LOG; > + ins[0].dst = etna_native_to_dst(inner_temp, INST_COMPS_X); > + ins[0].src[2] = src_y; > > - emit_inst(c, &ins[0]); > + emit_inst(c, &ins[0]); > + } > emit_inst(c, &(struct etna_inst) { > .opcode = INST_OPCODE_MUL, > .sat = 0, > @@ -1450,7 +1465,7 @@ static void > trans_trig(const struct instr_translater *t, struct etna_compile *c, > const struct tgsi_full_instruction *inst, struct etna_inst_src > *src) > { > - if (c->specs->has_new_sin_cos) { /* Alternative SIN/COS */ > + if (c->specs->has_new_transcendentals) { /* Alternative SIN/COS */ > /* On newer chips alternative SIN/COS instructions are implemented, > * which: > * - Need their input scaled by 1/pi instead of 2/pi > @@ -1613,6 +1628,40 @@ trans_trig(const struct instr_translater *t, struct > etna_compile *c, > } > > static void > +trans_lg2(const struct instr_translater *t, struct etna_compile *c, > + const struct tgsi_full_instruction *inst, struct etna_inst_src > *src) > +{ > + if (c->specs->has_new_transcendentals) { > + /* On newer chips alternative LOG instruction is implemented, > + * which outputs an x and y component, which need to be multiplied to > + * get the result. > + */ > + struct etna_native_reg temp = etna_compile_get_inner_temp(c); /* only > using .xy */ > + emit_inst(c, &(struct etna_inst) { > + .opcode = INST_OPCODE_LOG, > + .sat = 0, > + .dst = etna_native_to_dst(temp, INST_COMPS_X | INST_COMPS_Y), > + .src[2] = src[0], > + .tex = { .amode=1 }, /* Unknown bit needs to be set */ > + }); > + emit_inst(c, &(struct etna_inst) { > + .opcode = INST_OPCODE_MUL, > + .sat = inst->Instruction.Saturate, > + .dst = convert_dst(c, &inst->Dst[0]), > + .src[0] = etna_native_to_src(temp, SWIZZLE(X, X, X, X)), > + .src[1] = etna_native_to_src(temp, SWIZZLE(Y, Y, Y, Y)), > + }); > + } else { > + emit_inst(c, &(struct etna_inst) { > + .opcode = INST_OPCODE_LOG, > + .sat = inst->Instruction.Saturate, > + .dst = convert_dst(c, &inst->Dst[0]), > + .src[2] = src[0], > + }); > + } > +} > + > +static void > trans_dph(const struct instr_translater *t, struct etna_compile *c, > const struct tgsi_full_instruction *inst, struct etna_inst_src > *src) > { > @@ -1753,7 +1802,7 @@ static const struct instr_translater > translaters[TGSI_OPCODE_LAST] = { > INSTR(DST, trans_instr, .opc = INST_OPCODE_DST, .src = {0, 1, -1}), > INSTR(MAD, trans_instr, .opc = INST_OPCODE_MAD, .src = {0, 1, 2}), > INSTR(EX2, trans_instr, .opc = INST_OPCODE_EXP, .src = {2, -1, -1}), > - INSTR(LG2, trans_instr, .opc = INST_OPCODE_LOG, .src = {2, -1, -1}), > + INSTR(LG2, trans_lg2), > INSTR(SQRT, trans_instr, .opc = INST_OPCODE_SQRT, .src = {2, -1, -1}), > INSTR(FRC, trans_instr, .opc = INST_OPCODE_FRC, .src = {2, -1, -1}), > INSTR(CEIL, trans_instr, .opc = INST_OPCODE_CEIL, .src = {2, -1, -1}), > diff --git a/src/gallium/drivers/etnaviv/etnaviv_internal.h > b/src/gallium/drivers/etnaviv/etnaviv_internal.h > index 1212fdf..8a31167 100644 > --- a/src/gallium/drivers/etnaviv/etnaviv_internal.h > +++ b/src/gallium/drivers/etnaviv/etnaviv_internal.h > @@ -70,8 +70,8 @@ struct etna_specs { > unsigned has_sign_floor_ceil : 1; > /* can use VS_RANGE, PS_RANGE registers*/ > unsigned has_shader_range_registers : 1; > - /* has the new sin/cos functions */ > - unsigned has_new_sin_cos : 1; > + /* has the new sin/cos/log functions */ > + unsigned has_new_transcendentals : 1; > /* supports single-buffer rendering with multiple pixel pipes */ > unsigned single_buffer : 1; > /* can use any kind of wrapping mode on npot textures */ > diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c > b/src/gallium/drivers/etnaviv/etnaviv_screen.c > index 60679fb..ec8de96 100644 > --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c > +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c > @@ -642,7 +642,7 @@ etna_get_specs(struct etna_screen *screen) > screen->model >= 0x1000 || screen->model == 0x880; > screen->specs.npot_tex_any_wrap = > VIV_FEATURE(screen, chipMinorFeatures1, NON_POWER_OF_TWO); > - screen->specs.has_new_sin_cos = > + screen->specs.has_new_transcendentals = > VIV_FEATURE(screen, chipMinorFeatures3, HAS_FAST_TRANSCENDENTALS); > > if (VIV_FEATURE(screen, chipMinorFeatures3, INSTRUCTION_CACHE)) { _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev