<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Nov 25, 2016 at 12:52 AM, Juan A. Suarez Romero <span dir="ltr"><<a href="mailto:jasuarez@igalia.com" target="_blank">jasuarez@igalia.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Samuel Iglesias Gonsálvez <<a href="mailto:siglesias@igalia.com">siglesias@igalia.com</a>><br>
<br>
SPIR-V does not have special opcodes for DF conversions. We need to identify<br>
them by checking the bit size of the operand and the result.<br>
<br>
Signed-off-by: Samuel Iglesias Gonsálvez <<a href="mailto:siglesias@igalia.com">siglesias@igalia.com</a>><br>
---<br>
src/compiler/spirv/spirv_to_<wbr>nir.c | 29 ++++++++++++++++++++++-------<br>
src/compiler/spirv/vtn_alu.c | 37 +++++++++++++++++++++++++++---<wbr>-------<br>
src/compiler/spirv/vtn_<wbr>private.h | 3 ++-<br>
3 files changed, 51 insertions(+), 18 deletions(-)<br>
<br>
diff --git a/src/compiler/spirv/spirv_to_<wbr>nir.c b/src/compiler/spirv/spirv_to_<wbr>nir.c<br>
index a13f72a..81c73da 100644<br>
--- a/src/compiler/spirv/spirv_to_<wbr>nir.c<br>
+++ b/src/compiler/spirv/spirv_to_<wbr>nir.c<br>
@@ -1211,12 +1211,21 @@ vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,<br>
<br>
default: {<br>
bool swap;<br>
- nir_op op = vtn_nir_alu_op_for_spirv_<wbr>opcode(opcode, &swap);<br>
-<br>
- unsigned num_components = glsl_get_vector_elements(val-><wbr>const_type);<br>
unsigned bit_size =<br>
glsl_get_bit_size(val->const_<wbr>type);<br>
<br>
+ bool is_double_dst = bit_size == 64;<br>
+ bool is_double_src = is_double_dst;<br>
+ /* We assume there is no double conversion here */<br>
+ assert(bit_size != 64 ||<br>
+ (opcode != SpvOpConvertFToU && opcode != SpvOpConvertFToS &&<br>
+ opcode != SpvOpConvertSToF && opcode != SpvOpConvertUToF &&<br>
+ opcode != SpvOpFConvert));<br>
+ nir_op op =<br>
+ vtn_nir_alu_op_for_spirv_<wbr>opcode(opcode, &swap,<br>
+ is_double_dst, is_double_src);<br>
+<br>
+ unsigned num_components = glsl_get_vector_elements(val-><wbr>const_type);<br>
nir_const_value src[4];<br>
assert(count <= 7);<br>
for (unsigned i = 0; i < count - 4; i++) {<br>
@@ -1224,16 +1233,22 @@ vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,<br>
vtn_value(b, w[4 + i], vtn_value_type_constant)-><wbr>constant;<br>
<br>
unsigned j = swap ? 1 - i : i;<br>
- assert(bit_size == 32);<br>
for (unsigned k = 0; k < num_components; k++)<br>
- src[j].u32[k] = c->value.u[k];<br>
+ if (!is_double_src)<br>
+ src[j].u32[k] = c->value.u[k];<br>
+ else<br>
+ src[j].f64[k] = c->value.d[k];<br>
}<br>
<br>
nir_const_value res = nir_eval_const_opcode(op, num_components,<br>
bit_size, src);<br>
<br>
- for (unsigned k = 0; k < num_components; k++)<br>
- val->constant->value.u[k] = res.u32[k];<br>
+ for (unsigned k = 0; k < num_components; k++) {<br>
+ if (!is_double_dst)<br>
+ val->constant->value.u[k] = res.u32[k];<br>
+ else<br>
+ val->constant->value.d[k] = res.f64[k];<br>
+ }<br>
<br>
break;<br>
} /* default */<br>
diff --git a/src/compiler/spirv/vtn_alu.c b/src/compiler/spirv/vtn_alu.c<br>
index 95ff2b1..e444d3f 100644<br>
--- a/src/compiler/spirv/vtn_alu.c<br>
+++ b/src/compiler/spirv/vtn_alu.c<br>
@@ -211,7 +211,8 @@ vtn_handle_matrix_alu(struct vtn_builder *b, SpvOp opcode,<br>
}<br>
<br>
nir_op<br>
-vtn_nir_alu_op_for_spirv_<wbr>opcode(SpvOp opcode, bool *swap)<br>
+vtn_nir_alu_op_for_spirv_<wbr>opcode(SpvOp opcode, bool *swap,<br>
+ bool is_double_dst, bool is_double_src)<br></blockquote><div><br></div><div>I think it would be better if we did this as dst_bit_size and src_bit_size. That would make this simpler for basically every caller. Also, it makes it more 8/16-bit ready.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
{<br>
/* Indicates that the first two arguments should be swapped. This is<br>
* used for implementing greater-than and less-than-or-equal.<br>
@@ -284,16 +285,21 @@ vtn_nir_alu_op_for_spirv_<wbr>opcode(SpvOp opcode, bool *swap)<br>
case SpvOpFUnordGreaterThanEqual: return nir_op_fge;<br>
<br>
/* Conversions: */<br>
- case SpvOpConvertFToU: return nir_op_f2u;<br>
- case SpvOpConvertFToS: return nir_op_f2i;<br>
- case SpvOpConvertSToF: return nir_op_i2f;<br>
- case SpvOpConvertUToF: return nir_op_u2f;<br>
+ case SpvOpConvertFToU: return is_double_src ? nir_op_d2u : nir_op_f2u;<br>
+ case SpvOpConvertFToS: return is_double_src ? nir_op_d2i : nir_op_f2i;<br>
+ case SpvOpConvertSToF: return is_double_dst ? nir_op_i2d : nir_op_i2f;<br>
+ case SpvOpConvertUToF: return is_double_dst ? nir_op_u2d : nir_op_u2f;<br></blockquote><div><br></div><div>The time is soon coming (not sure if you want to do this now or not) to add a nir helper:<br><br></div><div>nir_op nir_type2type_op(nir_alu_type src, nir_alu_type dst);<br><br></div><div>I'm OK open-coding it for now, but as soon as we add int64 or any 8 or 16-bit types, we'll want it.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
case SpvOpBitcast: return nir_op_imov;<br>
case SpvOpUConvert:<br>
case SpvOpQuantizeToF16: return nir_op_fquantize2f16;<br>
- /* TODO: NIR is 32-bit only; these are no-ops. */<br>
+ /* TODO: int64 is not supported yet. This is a no-op. */<br>
case SpvOpSConvert: return nir_op_imov;<br>
- case SpvOpFConvert: return nir_op_fmov;<br>
+ case SpvOpFConvert:<br>
+ if (is_double_src && !is_double_dst)<br>
+ return nir_op_d2f;<br>
+ if (!is_double_src && is_double_dst)<br>
+ return nir_op_f2d;<br>
+ return nir_op_fmov;<br>
<br>
/* Derivatives: */<br>
case SpvOpDPdx: return nir_op_fddx;<br>
@@ -457,7 +463,10 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,<br>
case SpvOpFUnordLessThanEqual:<br>
case SpvOpFUnordGreaterThanEqual: {<br>
bool swap;<br>
- nir_op op = vtn_nir_alu_op_for_spirv_<wbr>opcode(opcode, &swap);<br>
+ bool is_double_src = src[0]->bit_size;<br>
+ bool is_double_dst = glsl_get_bit_size(val->ssa-><wbr>type);<br>
+ nir_op op = vtn_nir_alu_op_for_spirv_<wbr>opcode(opcode, &swap,<br>
+ is_double_dst, is_double_src);<br>
<br>
if (swap) {<br>
nir_ssa_def *tmp = src[0];<br>
@@ -481,7 +490,10 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,<br>
case SpvOpFOrdLessThanEqual:<br>
case SpvOpFOrdGreaterThanEqual: {<br>
bool swap;<br>
- nir_op op = vtn_nir_alu_op_for_spirv_<wbr>opcode(opcode, &swap);<br>
+ bool is_double_src = src[0]->bit_size;<br>
+ bool is_double_dst = glsl_get_bit_size(val->ssa-><wbr>type);<br>
+ nir_op op = vtn_nir_alu_op_for_spirv_<wbr>opcode(opcode, &swap,<br>
+ is_double_dst, is_double_src);<br>
<br>
if (swap) {<br>
nir_ssa_def *tmp = src[0];<br>
@@ -500,7 +512,12 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,<br>
<br>
default: {<br>
bool swap;<br>
- nir_op op = vtn_nir_alu_op_for_spirv_<wbr>opcode(opcode, &swap);<br>
+ bool is_double_src = src[0]->bit_size == 64;<br>
+ bool is_double_dst =<br>
+ glsl_get_bit_size(val->ssa-><wbr>type) == 64;<br>
+<br>
+ nir_op op = vtn_nir_alu_op_for_spirv_<wbr>opcode(opcode, &swap,<br>
+ is_double_dst, is_double_src);<br>
<br>
if (swap) {<br>
nir_ssa_def *tmp = src[0];<br>
diff --git a/src/compiler/spirv/vtn_<wbr>private.h b/src/compiler/spirv/vtn_<wbr>private.h<br>
index 47579fe..7159f8b 100644<br>
--- a/src/compiler/spirv/vtn_<wbr>private.h<br>
+++ b/src/compiler/spirv/vtn_<wbr>private.h<br>
@@ -480,7 +480,8 @@ typedef void (*vtn_execution_mode_foreach_<wbr>cb)(struct vtn_builder *,<br>
void vtn_foreach_execution_mode(<wbr>struct vtn_builder *b, struct vtn_value *value,<br>
vtn_execution_mode_foreach_cb cb, void *data);<br>
<br>
-nir_op vtn_nir_alu_op_for_spirv_<wbr>opcode(SpvOp opcode, bool *swap);<br>
+nir_op vtn_nir_alu_op_for_spirv_<wbr>opcode(SpvOp opcode, bool *swap,<br>
+ bool is_double_dst, bool is_double_src);<br>
<br>
void vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,<br>
const uint32_t *w, unsigned count);<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.7.4<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>