i965/fs: Implement support for extract_word.

The vec4 backend will lower it.

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
This commit is contained in:
Matt Turner 2016-01-20 18:56:37 -08:00
parent 68f8c5730b
commit 1dc312e295
5 changed files with 56 additions and 0 deletions

View file

@ -1085,6 +1085,18 @@ enum opcode {
*/
SHADER_OPCODE_BROADCAST,
/**
* Pick the byte from its first source register given by the index
* specified as second source.
*/
SHADER_OPCODE_EXTRACT_BYTE,
/**
* Pick the word from its first source register given by the index
* specified as second source.
*/
SHADER_OPCODE_EXTRACT_WORD,
VEC4_OPCODE_MOV_BYTES,
VEC4_OPCODE_PACK_BYTES,
VEC4_OPCODE_UNPACK_UNIFORM,

View file

@ -78,6 +78,8 @@ is_expression(const fs_visitor *v, const fs_inst *const inst)
case FS_OPCODE_LINTERP:
case SHADER_OPCODE_FIND_LIVE_CHANNEL:
case SHADER_OPCODE_BROADCAST:
case SHADER_OPCODE_EXTRACT_BYTE:
case SHADER_OPCODE_EXTRACT_WORD:
case SHADER_OPCODE_MOV_INDIRECT:
return true;
case SHADER_OPCODE_RCP:

View file

@ -2201,6 +2201,28 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
brw_broadcast(p, dst, src[0], src[1]);
break;
case SHADER_OPCODE_EXTRACT_BYTE: {
assert(src[0].type == BRW_REGISTER_TYPE_D ||
src[0].type == BRW_REGISTER_TYPE_UD);
enum brw_reg_type type =
src[0].type == BRW_REGISTER_TYPE_D ? BRW_REGISTER_TYPE_B
: BRW_REGISTER_TYPE_UB;
brw_MOV(p, dst, spread(suboffset(retype(src[0], type), src[1].ud), 4));
break;
}
case SHADER_OPCODE_EXTRACT_WORD: {
assert(src[0].type == BRW_REGISTER_TYPE_D ||
src[0].type == BRW_REGISTER_TYPE_UD);
enum brw_reg_type type =
src[0].type == BRW_REGISTER_TYPE_D ? BRW_REGISTER_TYPE_W
: BRW_REGISTER_TYPE_UW;
brw_MOV(p, dst, spread(suboffset(retype(src[0], type), src[1].ud), 2));
break;
}
case FS_OPCODE_SET_SAMPLE_ID:
generate_set_sample_id(inst, dst, src[0], src[1]);
break;

View file

@ -1079,6 +1079,22 @@ fs_visitor::nir_emit_alu(const fs_builder &bld, nir_alu_instr *instr)
inst->predicate = BRW_PREDICATE_NORMAL;
break;
case nir_op_extract_u8:
case nir_op_extract_i8: {
nir_const_value *byte = nir_src_as_const_value(instr->src[1].src);
bld.emit(SHADER_OPCODE_EXTRACT_BYTE,
result, op[0], brw_imm_ud(byte->u[0]));
break;
}
case nir_op_extract_u16:
case nir_op_extract_i16: {
nir_const_value *word = nir_src_as_const_value(instr->src[1].src);
bld.emit(SHADER_OPCODE_EXTRACT_WORD,
result, op[0], brw_imm_ud(word->u[0]));
break;
}
default:
unreachable("unhandled instruction");
}

View file

@ -312,6 +312,10 @@ brw_instruction_name(enum opcode op)
case SHADER_OPCODE_BROADCAST:
return "broadcast";
case SHADER_OPCODE_EXTRACT_BYTE:
return "extract_byte";
case SHADER_OPCODE_EXTRACT_WORD:
return "extract_word";
case VEC4_OPCODE_MOV_BYTES:
return "mov_bytes";
case VEC4_OPCODE_PACK_BYTES: