mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 06:48:06 +02:00
i965: Handle negated unsigned immediate values in constant propagation.
Negation of UD/UW sources behaves the same as for D/W sources, taking the two's complement of the source, except for bitwise logical operations on Gen8 and up which take the one's complement. Fixes crash in a GLSL shader with subtraction of two unsigned values. Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
parent
64fde7b31c
commit
aef83957e1
3 changed files with 19 additions and 19 deletions
|
|
@ -453,13 +453,15 @@ fs_visitor::try_constant_propagate(fs_inst *inst, acp_entry *entry)
|
||||||
val.type = inst->src[i].type;
|
val.type = inst->src[i].type;
|
||||||
|
|
||||||
if (inst->src[i].abs) {
|
if (inst->src[i].abs) {
|
||||||
if (!brw_abs_immediate(val.type, &val.fixed_hw_reg)) {
|
if ((brw->gen >= 8 && is_logic_op(inst->opcode)) ||
|
||||||
|
!brw_abs_immediate(val.type, &val.fixed_hw_reg)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst->src[i].negate) {
|
if (inst->src[i].negate) {
|
||||||
if (!brw_negate_immediate(val.type, &val.fixed_hw_reg)) {
|
if ((brw->gen >= 8 && is_logic_op(inst->opcode)) ||
|
||||||
|
!brw_negate_immediate(val.type, &val.fixed_hw_reg)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -625,9 +625,11 @@ brw_negate_immediate(enum brw_reg_type type, struct brw_reg *reg)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BRW_REGISTER_TYPE_D:
|
case BRW_REGISTER_TYPE_D:
|
||||||
|
case BRW_REGISTER_TYPE_UD:
|
||||||
reg->dw1.d = -reg->dw1.d;
|
reg->dw1.d = -reg->dw1.d;
|
||||||
return true;
|
return true;
|
||||||
case BRW_REGISTER_TYPE_W:
|
case BRW_REGISTER_TYPE_W:
|
||||||
|
case BRW_REGISTER_TYPE_UW:
|
||||||
reg->dw1.d = -(int16_t)reg->dw1.ud;
|
reg->dw1.d = -(int16_t)reg->dw1.ud;
|
||||||
return true;
|
return true;
|
||||||
case BRW_REGISTER_TYPE_F:
|
case BRW_REGISTER_TYPE_F:
|
||||||
|
|
@ -639,12 +641,6 @@ brw_negate_immediate(enum brw_reg_type type, struct brw_reg *reg)
|
||||||
case BRW_REGISTER_TYPE_UB:
|
case BRW_REGISTER_TYPE_UB:
|
||||||
case BRW_REGISTER_TYPE_B:
|
case BRW_REGISTER_TYPE_B:
|
||||||
unreachable("no UB/B immediates");
|
unreachable("no UB/B immediates");
|
||||||
case BRW_REGISTER_TYPE_UD:
|
|
||||||
case BRW_REGISTER_TYPE_UW:
|
|
||||||
/* Presumably the negate modifier on an unsigned source is the same as
|
|
||||||
* on a signed source but it would be nice to confirm.
|
|
||||||
*/
|
|
||||||
assert(!"unimplemented: negate UD/UW immediate");
|
|
||||||
case BRW_REGISTER_TYPE_UV:
|
case BRW_REGISTER_TYPE_UV:
|
||||||
case BRW_REGISTER_TYPE_V:
|
case BRW_REGISTER_TYPE_V:
|
||||||
assert(!"unimplemented: negate UV/V immediate");
|
assert(!"unimplemented: negate UV/V immediate");
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,15 @@ swizzle_vf_imm(unsigned vf4, unsigned swizzle)
|
||||||
return ret.vf4;
|
return ret.vf4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_logic_op(enum opcode opcode)
|
||||||
|
{
|
||||||
|
return (opcode == BRW_OPCODE_AND ||
|
||||||
|
opcode == BRW_OPCODE_OR ||
|
||||||
|
opcode == BRW_OPCODE_XOR ||
|
||||||
|
opcode == BRW_OPCODE_NOT);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
try_constant_propagate(struct brw_context *brw, vec4_instruction *inst,
|
try_constant_propagate(struct brw_context *brw, vec4_instruction *inst,
|
||||||
int arg, struct copy_entry *entry)
|
int arg, struct copy_entry *entry)
|
||||||
|
|
@ -114,13 +123,15 @@ try_constant_propagate(struct brw_context *brw, vec4_instruction *inst,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (inst->src[arg].abs) {
|
if (inst->src[arg].abs) {
|
||||||
if (!brw_abs_immediate(value.type, &value.fixed_hw_reg)) {
|
if ((brw->gen >= 8 && is_logic_op(inst->opcode)) ||
|
||||||
|
!brw_abs_immediate(value.type, &value.fixed_hw_reg)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst->src[arg].negate) {
|
if (inst->src[arg].negate) {
|
||||||
if (!brw_negate_immediate(value.type, &value.fixed_hw_reg)) {
|
if ((brw->gen >= 8 && is_logic_op(inst->opcode)) ||
|
||||||
|
!brw_negate_immediate(value.type, &value.fixed_hw_reg)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -225,15 +236,6 @@ try_constant_propagate(struct brw_context *brw, vec4_instruction *inst,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
is_logic_op(enum opcode opcode)
|
|
||||||
{
|
|
||||||
return (opcode == BRW_OPCODE_AND ||
|
|
||||||
opcode == BRW_OPCODE_OR ||
|
|
||||||
opcode == BRW_OPCODE_XOR ||
|
|
||||||
opcode == BRW_OPCODE_NOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
try_copy_propagate(struct brw_context *brw, vec4_instruction *inst,
|
try_copy_propagate(struct brw_context *brw, vec4_instruction *inst,
|
||||||
int arg, struct copy_entry *entry, int reg)
|
int arg, struct copy_entry *entry, int reg)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue