vc4_qir.h revision e51e20c35ef89409494161010f86750366faef4c
1/*
2 * Copyright © 2014 Broadcom
3 *
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:
10 *
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
13 * Software.
14 *
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
21 * IN THE SOFTWARE.
22 */
23
24#ifndef VC4_QIR_H
25#define VC4_QIR_H
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <stdbool.h>
30#include <stdint.h>
31
32#include "util/u_simple_list.h"
33
34enum qfile {
35        QFILE_NULL,
36        QFILE_TEMP,
37        QFILE_VARY,
38        QFILE_UNIF,
39};
40
41struct qreg {
42        enum qfile file;
43        uint32_t index;
44};
45
46enum qop {
47        QOP_UNDEF,
48        QOP_MOV,
49        QOP_FADD,
50        QOP_FSUB,
51        QOP_FMUL,
52        QOP_FMIN,
53        QOP_FMAX,
54        QOP_FMINABS,
55        QOP_FMAXABS,
56
57        QOP_SEQ,
58        QOP_SNE,
59        QOP_SGE,
60        QOP_SLT,
61        QOP_CMP,
62
63        QOP_FTOI,
64        QOP_ITOF,
65        QOP_RCP,
66        QOP_RSQ,
67        QOP_EXP2,
68        QOP_LOG2,
69        QOP_VW_SETUP,
70        QOP_VR_SETUP,
71        QOP_PACK_SCALED,
72        QOP_PACK_COLORS,
73        QOP_VPM_WRITE,
74        QOP_VPM_READ,
75        QOP_TLB_DISCARD_SETUP,
76        QOP_TLB_PASSTHROUGH_Z_WRITE,
77        QOP_TLB_COLOR_WRITE,
78        QOP_TLB_COLOR_READ,
79        QOP_VARY_ADD_C,
80
81        QOP_FRAG_X,
82        QOP_FRAG_Y,
83        QOP_FRAG_Z,
84        QOP_FRAG_RCP_W,
85
86        /** Texture x coordinate parameter write */
87        QOP_TEX_S,
88        /** Texture y coordinate parameter write */
89        QOP_TEX_T,
90        /** Texture border color parameter or cube map z coordinate write */
91        QOP_TEX_R,
92        /** Texture LOD bias parameter write */
93        QOP_TEX_B,
94        /**
95         * Signal of texture read being necessary and then reading r4 into
96         * the destination
97         */
98        QOP_TEX_RESULT,
99        QOP_R4_UNPACK_A,
100        QOP_R4_UNPACK_B,
101        QOP_R4_UNPACK_C,
102        QOP_R4_UNPACK_D
103};
104
105struct simple_node {
106        struct simple_node *next;
107        struct simple_node *prev;
108};
109
110struct qinst {
111        struct simple_node link;
112
113        enum qop op;
114        struct qreg dst;
115        struct qreg *src;
116};
117
118enum qstage {
119        /**
120         * Coordinate shader, runs during binning, before the VS, and just
121         * outputs position.
122         */
123        QSTAGE_COORD,
124        QSTAGE_VERT,
125        QSTAGE_FRAG,
126};
127
128enum quniform_contents {
129        /**
130         * Indicates that a constant 32-bit value is copied from the program's
131         * uniform contents.
132         */
133        QUNIFORM_CONSTANT,
134        /**
135         * Indicates that the program's uniform contents are used as an index
136         * into the GL uniform storage.
137         */
138        QUNIFORM_UNIFORM,
139
140        /** @{
141         * Scaling factors from clip coordinates to relative to the viewport
142         * center.
143         *
144         * This is used by the coordinate and vertex shaders to produce the
145         * 32-bit entry consisting of 2 16-bit fields with 12.4 signed fixed
146         * point offsets from the viewport ccenter.
147         */
148        QUNIFORM_VIEWPORT_X_SCALE,
149        QUNIFORM_VIEWPORT_Y_SCALE,
150        /** @} */
151
152        QUNIFORM_VIEWPORT_Z_OFFSET,
153        QUNIFORM_VIEWPORT_Z_SCALE,
154
155        /**
156         * A reference to a texture config parameter 0 uniform.
157         *
158         * This is a uniform implicitly loaded with a QPU_W_TMU* write, which
159         * defines texture type, miplevels, and such.  It will be found as a
160         * parameter to the first QOP_TEX_[STRB] instruction in a sequence.
161         */
162        QUNIFORM_TEXTURE_CONFIG_P0,
163
164        /**
165         * A reference to a texture config parameter 1 uniform.
166         *
167         * This is a uniform implicitly loaded with a QPU_W_TMU* write, which
168         * defines texture width, height, filters, and wrap modes.  It will be
169         * found as a parameter to the second QOP_TEX_[STRB] instruction in a
170         * sequence.
171         */
172        QUNIFORM_TEXTURE_CONFIG_P1,
173
174        QUNIFORM_TEXRECT_SCALE_X,
175        QUNIFORM_TEXRECT_SCALE_Y,
176
177        QUNIFORM_BLEND_CONST_COLOR,
178};
179
180struct qcompile {
181        struct qreg undef;
182        enum qstage stage;
183        uint32_t num_temps;
184        struct simple_node instructions;
185        uint32_t immediates[1024];
186
187        struct simple_node qpu_inst_list;
188        uint64_t *qpu_insts;
189        uint32_t qpu_inst_count;
190        uint32_t qpu_inst_size;
191        uint32_t num_inputs;
192};
193
194struct qcompile *qir_compile_init(void);
195void qir_compile_destroy(struct qcompile *c);
196struct qinst *qir_inst(enum qop op, struct qreg dst,
197                       struct qreg src0, struct qreg src1);
198struct qinst *qir_inst4(enum qop op, struct qreg dst,
199                        struct qreg a,
200                        struct qreg b,
201                        struct qreg c,
202                        struct qreg d);
203void qir_emit(struct qcompile *c, struct qinst *inst);
204struct qreg qir_get_temp(struct qcompile *c);
205int qir_get_op_nsrc(enum qop qop);
206bool qir_reg_equals(struct qreg a, struct qreg b);
207bool qir_has_side_effects(struct qinst *inst);
208
209void qir_dump(struct qcompile *c);
210void qir_dump_inst(struct qinst *inst);
211const char *qir_get_stage_name(enum qstage stage);
212
213void qir_optimize(struct qcompile *c);
214bool qir_opt_algebraic(struct qcompile *c);
215bool qir_opt_copy_propagation(struct qcompile *c);
216bool qir_opt_dead_code(struct qcompile *c);
217
218#define QIR_ALU0(name)                                                   \
219static inline struct qreg                                                \
220qir_##name(struct qcompile *c)                                           \
221{                                                                        \
222        struct qreg t = qir_get_temp(c);                                 \
223        qir_emit(c, qir_inst(QOP_##name, t, c->undef, c->undef));        \
224        return t;                                                        \
225}
226
227#define QIR_ALU1(name)                                                   \
228static inline struct qreg                                                \
229qir_##name(struct qcompile *c, struct qreg a)                            \
230{                                                                        \
231        struct qreg t = qir_get_temp(c);                                 \
232        qir_emit(c, qir_inst(QOP_##name, t, a, c->undef));               \
233        return t;                                                        \
234}
235
236#define QIR_ALU2(name)                                                   \
237static inline struct qreg                                                \
238qir_##name(struct qcompile *c, struct qreg a, struct qreg b)             \
239{                                                                        \
240        struct qreg t = qir_get_temp(c);                                 \
241        qir_emit(c, qir_inst(QOP_##name, t, a, b));                      \
242        return t;                                                        \
243}
244
245#define QIR_NODST_1(name)                                               \
246static inline void                                                      \
247qir_##name(struct qcompile *c, struct qreg a)                           \
248{                                                                       \
249        qir_emit(c, qir_inst(QOP_##name, c->undef, a, c->undef));       \
250}
251
252#define QIR_NODST_2(name)                                               \
253static inline void                                                      \
254qir_##name(struct qcompile *c, struct qreg a, struct qreg b)            \
255{                                                                       \
256        qir_emit(c, qir_inst(QOP_##name, c->undef, a, b));       \
257}
258
259QIR_ALU1(MOV)
260QIR_ALU2(FADD)
261QIR_ALU2(FSUB)
262QIR_ALU2(FMUL)
263QIR_ALU2(FMIN)
264QIR_ALU2(FMAX)
265QIR_ALU2(FMINABS)
266QIR_ALU2(FMAXABS)
267QIR_ALU1(FTOI)
268QIR_ALU1(ITOF)
269QIR_ALU1(RCP)
270QIR_ALU1(RSQ)
271QIR_ALU1(EXP2)
272QIR_ALU1(LOG2)
273QIR_ALU2(PACK_SCALED)
274QIR_ALU1(VARY_ADD_C)
275QIR_NODST_1(VPM_WRITE)
276QIR_NODST_2(TEX_S)
277QIR_NODST_2(TEX_T)
278QIR_NODST_2(TEX_R)
279QIR_NODST_2(TEX_B)
280QIR_ALU0(FRAG_X)
281QIR_ALU0(FRAG_Y)
282QIR_ALU0(FRAG_Z)
283QIR_ALU0(FRAG_RCP_W)
284QIR_NODST_1(TLB_DISCARD_SETUP)
285
286static inline struct qreg
287qir_CMP(struct qcompile *c, struct qreg cmp, struct qreg a, struct qreg b)
288{
289        struct qreg t = qir_get_temp(c);
290        qir_emit(c, qir_inst4(QOP_CMP, t, cmp, a, b, c->undef));
291        return t;
292}
293
294static inline struct qreg
295qir_R4_UNPACK(struct qcompile *c, int i)
296{
297        struct qreg t = qir_get_temp(c);
298        qir_emit(c, qir_inst(QOP_R4_UNPACK_A + i, t, c->undef, c->undef));
299        return t;
300}
301
302#endif /* VC4_QIR_H */
303