[Mesa-dev] [PATCH 2/8] i965: Add support for saturating immediates.

Ian Romanick idr at freedesktop.org
Mon Dec 22 18:40:13 PST 2014


On 12/21/2014 03:24 PM, Matt Turner wrote:
> I don't feel great about unreachable("unimplemented: ...") but these
> cases do only seem possible under some currently impossible circumstances.
> ---
>  src/mesa/drivers/dri/i965/brw_fs.cpp     | 16 +++++++++++
>  src/mesa/drivers/dri/i965/brw_shader.cpp | 47 ++++++++++++++++++++++++++++++++
>  src/mesa/drivers/dri/i965/brw_shader.h   |  1 +
>  src/mesa/drivers/dri/i965/brw_vec4.cpp   | 16 +++++++++++
>  4 files changed, 80 insertions(+)
> 
> diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
> index 2837fc0..789f967 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
> @@ -2292,6 +2292,22 @@ fs_visitor::opt_algebraic()
>  
>     foreach_block_and_inst(block, fs_inst, inst, cfg) {
>        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)
> +               unreachable("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:
>  	 if (inst->src[1].file != IMM)
>  	    continue;
> diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
> index 1e5227c..a2fc471 100644
> --- a/src/mesa/drivers/dri/i965/brw_shader.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
> @@ -575,6 +575,53 @@ brw_instruction_name(enum opcode op)
>     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:
> +      unreachable("unimplemented: saturate vector immediate");
> +   case BRW_REGISTER_TYPE_DF:
> +   case BRW_REGISTER_TYPE_HF:
> +      unreachable("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,
>                                   struct gl_shader_program *shader_prog,
>                                   struct gl_program *prog,
> diff --git a/src/mesa/drivers/dri/i965/brw_shader.h b/src/mesa/drivers/dri/i965/brw_shader.h
> index 05434a7..233e224 100644
> --- a/src/mesa/drivers/dri/i965/brw_shader.h
> +++ b/src/mesa/drivers/dri/i965/brw_shader.h
> @@ -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);
>  uint32_t brw_math_function(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
>  extern "C" {
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
> index b303eb6..7619eb6 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
> @@ -572,6 +572,22 @@ vec4_visitor::opt_algebraic()
>  
>     foreach_block_and_inst(block, vec4_instruction, inst, cfg) {
>        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)
> +               unreachable("unimplemented: saturate mixed types");

What does this unreachable() gains compared to an assert()?

> +
> +            if (brw_saturate_immediate(inst->dst.type,
> +                                       &inst->src[0].fixed_hw_reg)) {
> +               inst->saturate = false;
> +               progress = true;
> +            }
> +         }
> +         break;
> +
>        case VEC4_OPCODE_UNPACK_UNIFORM:
>           if (inst->src[0].file != UNIFORM) {
>              inst->opcode = BRW_OPCODE_MOV;
> 



More information about the mesa-dev mailing list