2 * Copyright © 2015 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 * Jason Ekstrand (jason@jlekstrand.net)
28 #include "spirv_to_nir_private.h"
29 #include "spirv_glsl450.h"
32 build_length(nir_builder
*b
, nir_ssa_def
*vec
)
34 switch (vec
->num_components
) {
35 case 1: return nir_fsqrt(b
, nir_fmul(b
, vec
, vec
));
36 case 2: return nir_fsqrt(b
, nir_fdot2(b
, vec
, vec
));
37 case 3: return nir_fsqrt(b
, nir_fdot3(b
, vec
, vec
));
38 case 4: return nir_fsqrt(b
, nir_fdot4(b
, vec
, vec
));
40 unreachable("Invalid number of components");
45 handle_glsl450_alu(struct vtn_builder
*b
, enum GLSLstd450 entrypoint
,
46 const uint32_t *w
, unsigned count
)
48 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
49 val
->ssa
= rzalloc(b
, struct vtn_ssa_value
);
50 val
->ssa
->type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
->type
;
52 /* Collect the various SSA sources */
53 unsigned num_inputs
= count
- 5;
55 for (unsigned i
= 0; i
< num_inputs
; i
++)
56 src
[i
] = vtn_ssa_value(b
, w
[i
+ 5])->def
;
60 case GLSLstd450Round
: op
= nir_op_fround_even
; break; /* TODO */
61 case GLSLstd450RoundEven
: op
= nir_op_fround_even
; break;
62 case GLSLstd450Trunc
: op
= nir_op_ftrunc
; break;
63 case GLSLstd450FAbs
: op
= nir_op_fabs
; break;
64 case GLSLstd450FSign
: op
= nir_op_fsign
; break;
65 case GLSLstd450Floor
: op
= nir_op_ffloor
; break;
66 case GLSLstd450Ceil
: op
= nir_op_fceil
; break;
67 case GLSLstd450Fract
: op
= nir_op_ffract
; break;
68 case GLSLstd450Radians
:
69 val
->ssa
->def
= nir_fmul(&b
->nb
, src
[0], nir_imm_float(&b
->nb
, 0.01745329251));
71 case GLSLstd450Degrees
:
72 val
->ssa
->def
= nir_fmul(&b
->nb
, src
[0], nir_imm_float(&b
->nb
, 57.2957795131));
74 case GLSLstd450Sin
: op
= nir_op_fsin
; break;
75 case GLSLstd450Cos
: op
= nir_op_fcos
; break;
77 val
->ssa
->def
= nir_fdiv(&b
->nb
, nir_fsin(&b
->nb
, src
[0]),
78 nir_fcos(&b
->nb
, src
[0]));
80 case GLSLstd450Pow
: op
= nir_op_fpow
; break;
81 case GLSLstd450Exp2
: op
= nir_op_fexp2
; break;
82 case GLSLstd450Log2
: op
= nir_op_flog2
; break;
83 case GLSLstd450Sqrt
: op
= nir_op_fsqrt
; break;
84 case GLSLstd450InverseSqrt
: op
= nir_op_frsq
; break;
86 case GLSLstd450Modf
: op
= nir_op_fmod
; break;
87 case GLSLstd450FMin
: op
= nir_op_fmin
; break;
88 case GLSLstd450FMax
: op
= nir_op_fmax
; break;
89 case GLSLstd450Mix
: op
= nir_op_flrp
; break;
91 val
->ssa
->def
= nir_sge(&b
->nb
, src
[1], src
[0]);
94 case GLSLstd450Fma
: op
= nir_op_ffma
; break;
95 case GLSLstd450Ldexp
: op
= nir_op_ldexp
; break;
97 /* Packing/Unpacking functions */
98 case GLSLstd450PackSnorm4x8
: op
= nir_op_pack_snorm_4x8
; break;
99 case GLSLstd450PackUnorm4x8
: op
= nir_op_pack_unorm_4x8
; break;
100 case GLSLstd450PackSnorm2x16
: op
= nir_op_pack_snorm_2x16
; break;
101 case GLSLstd450PackUnorm2x16
: op
= nir_op_pack_unorm_2x16
; break;
102 case GLSLstd450PackHalf2x16
: op
= nir_op_pack_half_2x16
; break;
103 case GLSLstd450UnpackSnorm4x8
: op
= nir_op_unpack_snorm_4x8
; break;
104 case GLSLstd450UnpackUnorm4x8
: op
= nir_op_unpack_unorm_4x8
; break;
105 case GLSLstd450UnpackSnorm2x16
: op
= nir_op_unpack_snorm_2x16
; break;
106 case GLSLstd450UnpackUnorm2x16
: op
= nir_op_unpack_unorm_2x16
; break;
107 case GLSLstd450UnpackHalf2x16
: op
= nir_op_unpack_half_2x16
; break;
109 case GLSLstd450Length
:
110 val
->ssa
->def
= build_length(&b
->nb
, src
[0]);
112 case GLSLstd450Distance
:
113 val
->ssa
->def
= build_length(&b
->nb
, nir_fsub(&b
->nb
, src
[0], src
[1]));
115 case GLSLstd450Normalize
:
116 val
->ssa
->def
= nir_fdiv(&b
->nb
, src
[0], build_length(&b
->nb
, src
[0]));
119 case GLSLstd450AddCarry
: op
= nir_op_uadd_carry
; break;
120 case GLSLstd450SubBorrow
: op
= nir_op_usub_borrow
; break;
124 case GLSLstd450FClamp
:
125 case GLSLstd450UClamp
:
126 case GLSLstd450SClamp
:
130 case GLSLstd450Atan2
:
134 case GLSLstd450Asinh
:
135 case GLSLstd450Acosh
:
136 case GLSLstd450Atanh
:
137 case GLSLstd450SmoothStep
:
138 case GLSLstd450Frexp
:
139 case GLSLstd450PackDouble2x32
:
140 case GLSLstd450UnpackDouble2x32
:
141 case GLSLstd450Cross
:
142 case GLSLstd450FaceForward
:
143 case GLSLstd450Reflect
:
144 case GLSLstd450Refract
:
145 case GLSLstd450MulExtended
:
147 unreachable("Unhandled opcode");
150 nir_alu_instr
*instr
= nir_alu_instr_create(b
->shader
, op
);
151 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
.dest
,
152 glsl_get_vector_elements(val
->ssa
->type
), val
->name
);
153 instr
->dest
.write_mask
= (1 << instr
->dest
.dest
.ssa
.num_components
) - 1;
154 val
->ssa
->def
= &instr
->dest
.dest
.ssa
;
156 for (unsigned i
= 0; i
< nir_op_infos
[op
].num_inputs
; i
++)
157 instr
->src
[i
].src
= nir_src_for_ssa(src
[i
]);
159 nir_builder_instr_insert(&b
->nb
, &instr
->instr
);
163 vtn_handle_glsl450_instruction(struct vtn_builder
*b
, uint32_t ext_opcode
,
164 const uint32_t *words
, unsigned count
)
166 switch ((enum GLSLstd450
)ext_opcode
) {
167 case GLSLstd450Determinant
:
168 case GLSLstd450MatrixInverse
:
169 case GLSLstd450InterpolateAtCentroid
:
170 case GLSLstd450InterpolateAtSample
:
171 case GLSLstd450InterpolateAtOffset
:
172 unreachable("Unhandled opcode");
175 handle_glsl450_alu(b
, (enum GLSLstd450
)ext_opcode
, words
, count
);