mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 20:10:14 +01:00
i965: Add support for saturating immediates.
I don't feel great about assert(!"unimplemented: ...") but these cases do only seem possible under some currently impossible circumstances. Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
parent
3978585bcc
commit
7bc6e455e2
4 changed files with 80 additions and 0 deletions
|
|
@ -2292,6 +2292,22 @@ fs_visitor::opt_algebraic()
|
||||||
|
|
||||||
foreach_block_and_inst(block, fs_inst, inst, cfg) {
|
foreach_block_and_inst(block, fs_inst, inst, cfg) {
|
||||||
switch (inst->opcode) {
|
switch (inst->opcode) {
|
||||||
|
case BRW_OPCODE_MOV:
|
||||||
|
if (inst->src[0].file != IMM)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (inst->saturate) {
|
||||||
|
if (inst->dst.type != inst->src[0].type)
|
||||||
|
assert(!"unimplemented: saturate mixed types");
|
||||||
|
|
||||||
|
if (brw_saturate_immediate(inst->dst.type,
|
||||||
|
&inst->src[0].fixed_hw_reg)) {
|
||||||
|
inst->saturate = false;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case BRW_OPCODE_MUL:
|
case BRW_OPCODE_MUL:
|
||||||
if (inst->src[1].file != IMM)
|
if (inst->src[1].file != IMM)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -575,6 +575,53 @@ brw_instruction_name(enum opcode op)
|
||||||
unreachable("not reached");
|
unreachable("not reached");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
brw_saturate_immediate(enum brw_reg_type type, struct brw_reg *reg)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
unsigned ud;
|
||||||
|
int d;
|
||||||
|
float f;
|
||||||
|
} imm = { reg->dw1.ud }, sat_imm;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case BRW_REGISTER_TYPE_UD:
|
||||||
|
case BRW_REGISTER_TYPE_D:
|
||||||
|
case BRW_REGISTER_TYPE_UQ:
|
||||||
|
case BRW_REGISTER_TYPE_Q:
|
||||||
|
/* Nothing to do. */
|
||||||
|
return false;
|
||||||
|
case BRW_REGISTER_TYPE_UW:
|
||||||
|
sat_imm.ud = CLAMP(imm.ud, 0, USHRT_MAX);
|
||||||
|
break;
|
||||||
|
case BRW_REGISTER_TYPE_W:
|
||||||
|
sat_imm.d = CLAMP(imm.d, SHRT_MIN, SHRT_MAX);
|
||||||
|
break;
|
||||||
|
case BRW_REGISTER_TYPE_F:
|
||||||
|
sat_imm.f = CLAMP(imm.f, 0.0f, 1.0f);
|
||||||
|
break;
|
||||||
|
case BRW_REGISTER_TYPE_UB:
|
||||||
|
sat_imm.ud = CLAMP(imm.ud, 0, UCHAR_MAX);
|
||||||
|
break;
|
||||||
|
case BRW_REGISTER_TYPE_B:
|
||||||
|
sat_imm.d = CLAMP(imm.d, CHAR_MIN, CHAR_MAX);
|
||||||
|
break;
|
||||||
|
case BRW_REGISTER_TYPE_V:
|
||||||
|
case BRW_REGISTER_TYPE_UV:
|
||||||
|
case BRW_REGISTER_TYPE_VF:
|
||||||
|
assert(!"unimplemented: saturate vector immediate");
|
||||||
|
case BRW_REGISTER_TYPE_DF:
|
||||||
|
case BRW_REGISTER_TYPE_HF:
|
||||||
|
assert(!"unimplemented: saturate DF/HF immediate");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imm.ud != sat_imm.ud) {
|
||||||
|
reg->dw1.ud = sat_imm.ud;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
backend_visitor::backend_visitor(struct brw_context *brw,
|
backend_visitor::backend_visitor(struct brw_context *brw,
|
||||||
struct gl_shader_program *shader_prog,
|
struct gl_shader_program *shader_prog,
|
||||||
struct gl_program *prog,
|
struct gl_program *prog,
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,7 @@ enum brw_reg_type brw_type_for_base_type(const struct glsl_type *type);
|
||||||
enum brw_conditional_mod brw_conditional_for_comparison(unsigned int op);
|
enum brw_conditional_mod brw_conditional_for_comparison(unsigned int op);
|
||||||
uint32_t brw_math_function(enum opcode op);
|
uint32_t brw_math_function(enum opcode op);
|
||||||
const char *brw_instruction_name(enum opcode op);
|
const char *brw_instruction_name(enum opcode op);
|
||||||
|
bool brw_saturate_immediate(enum brw_reg_type type, struct brw_reg *reg);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
||||||
|
|
@ -572,6 +572,22 @@ vec4_visitor::opt_algebraic()
|
||||||
|
|
||||||
foreach_block_and_inst(block, vec4_instruction, inst, cfg) {
|
foreach_block_and_inst(block, vec4_instruction, inst, cfg) {
|
||||||
switch (inst->opcode) {
|
switch (inst->opcode) {
|
||||||
|
case BRW_OPCODE_MOV:
|
||||||
|
if (inst->src[0].file != IMM)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (inst->saturate) {
|
||||||
|
if (inst->dst.type != inst->src[0].type)
|
||||||
|
assert(!"unimplemented: saturate mixed types");
|
||||||
|
|
||||||
|
if (brw_saturate_immediate(inst->dst.type,
|
||||||
|
&inst->src[0].fixed_hw_reg)) {
|
||||||
|
inst->saturate = false;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case VEC4_OPCODE_UNPACK_UNIFORM:
|
case VEC4_OPCODE_UNPACK_UNIFORM:
|
||||||
if (inst->src[0].file != UNIFORM) {
|
if (inst->src[0].file != UNIFORM) {
|
||||||
inst->opcode = BRW_OPCODE_MOV;
|
inst->opcode = BRW_OPCODE_MOV;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue