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:
@@ -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 =
|
||||||
|
@@ -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];
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user