spirv/nir: implement DF conversions

SPIR-V does not have special opcodes for DF conversions. We need to identify
them by checking the bit size of the operand and the result.

Signed-off-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
Samuel Iglesias Gonsálvez
2016-12-07 08:10:16 +01:00
parent 27cf6a369f
commit c332432bae
3 changed files with 23 additions and 13 deletions

View File

@@ -1213,7 +1213,9 @@ vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
default: { default: {
bool swap; bool swap;
nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap); nir_alu_type dst_alu_type = nir_get_nir_type_for_glsl_type(val->const_type);
nir_alu_type src_alu_type = dst_alu_type;
nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap, src_alu_type, dst_alu_type);
unsigned num_components = glsl_get_vector_elements(val->const_type); unsigned num_components = glsl_get_vector_elements(val->const_type);
unsigned bit_size = unsigned bit_size =

View File

@@ -211,7 +211,8 @@ vtn_handle_matrix_alu(struct vtn_builder *b, SpvOp opcode,
} }
nir_op nir_op
vtn_nir_alu_op_for_spirv_opcode(SpvOp opcode, bool *swap) vtn_nir_alu_op_for_spirv_opcode(SpvOp opcode, bool *swap,
nir_alu_type src, nir_alu_type dst)
{ {
/* Indicates that the first two arguments should be swapped. This is /* Indicates that the first two arguments should be swapped. This is
* used for implementing greater-than and less-than-or-equal. * used for implementing greater-than and less-than-or-equal.
@@ -284,16 +285,16 @@ vtn_nir_alu_op_for_spirv_opcode(SpvOp opcode, bool *swap)
case SpvOpFUnordGreaterThanEqual: return nir_op_fge; case SpvOpFUnordGreaterThanEqual: return nir_op_fge;
/* Conversions: */ /* Conversions: */
case SpvOpConvertFToU: return nir_op_f2u;
case SpvOpConvertFToS: return nir_op_f2i;
case SpvOpConvertSToF: return nir_op_i2f;
case SpvOpConvertUToF: return nir_op_u2f;
case SpvOpBitcast: return nir_op_imov; case SpvOpBitcast: return nir_op_imov;
case SpvOpUConvert: case SpvOpUConvert:
case SpvOpQuantizeToF16: return nir_op_fquantize2f16; case SpvOpQuantizeToF16: return nir_op_fquantize2f16;
/* TODO: NIR is 32-bit only; these are no-ops. */ case SpvOpConvertFToU:
case SpvOpSConvert: return nir_op_imov; case SpvOpConvertFToS:
case SpvOpFConvert: return nir_op_fmov; case SpvOpConvertSToF:
case SpvOpConvertUToF:
case SpvOpSConvert:
case SpvOpFConvert:
return nir_type_conversion_op(src, dst);
/* Derivatives: */ /* Derivatives: */
case SpvOpDPdx: return nir_op_fddx; case SpvOpDPdx: return nir_op_fddx;
@@ -457,7 +458,9 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
case SpvOpFUnordLessThanEqual: case SpvOpFUnordLessThanEqual:
case SpvOpFUnordGreaterThanEqual: { case SpvOpFUnordGreaterThanEqual: {
bool swap; bool swap;
nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap); nir_alu_type src_alu_type = nir_get_nir_type_for_glsl_type(vtn_src[0]->type);
nir_alu_type dst_alu_type = nir_get_nir_type_for_glsl_type(type);
nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap, src_alu_type, dst_alu_type);
if (swap) { if (swap) {
nir_ssa_def *tmp = src[0]; nir_ssa_def *tmp = src[0];
@@ -481,7 +484,9 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
case SpvOpFOrdLessThanEqual: case SpvOpFOrdLessThanEqual:
case SpvOpFOrdGreaterThanEqual: { case SpvOpFOrdGreaterThanEqual: {
bool swap; bool swap;
nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap); nir_alu_type src_alu_type = nir_get_nir_type_for_glsl_type(vtn_src[0]->type);
nir_alu_type dst_alu_type = nir_get_nir_type_for_glsl_type(type);
nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap, src_alu_type, dst_alu_type);
if (swap) { if (swap) {
nir_ssa_def *tmp = src[0]; nir_ssa_def *tmp = src[0];
@@ -500,7 +505,9 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
default: { default: {
bool swap; bool swap;
nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap); nir_alu_type src_alu_type = nir_get_nir_type_for_glsl_type(vtn_src[0]->type);
nir_alu_type dst_alu_type = nir_get_nir_type_for_glsl_type(type);
nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap, src_alu_type, dst_alu_type);
if (swap) { if (swap) {
nir_ssa_def *tmp = src[0]; nir_ssa_def *tmp = src[0];

View File

@@ -481,7 +481,8 @@ typedef void (*vtn_execution_mode_foreach_cb)(struct vtn_builder *,
void vtn_foreach_execution_mode(struct vtn_builder *b, struct vtn_value *value, void vtn_foreach_execution_mode(struct vtn_builder *b, struct vtn_value *value,
vtn_execution_mode_foreach_cb cb, void *data); vtn_execution_mode_foreach_cb cb, void *data);
nir_op vtn_nir_alu_op_for_spirv_opcode(SpvOp opcode, bool *swap); nir_op vtn_nir_alu_op_for_spirv_opcode(SpvOp opcode, bool *swap,
nir_alu_type src, nir_alu_type dst);
void vtn_handle_alu(struct vtn_builder *b, SpvOp opcode, void vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
const uint32_t *w, unsigned count); const uint32_t *w, unsigned count);