1 /*
2 * Copyright (c) 2012 Rob Clark <robdclark@gmail.com>
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 FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24 #ifndef IR2_H_
25 #define IR2_H_
26
27 #include <stdint.h>
28 #include <stdbool.h>
29
30 #include "instr-a2xx.h"
31
32 /* low level intermediate representation of an adreno a2xx shader program */
33
34 struct ir2_shader;
35
36 struct ir2_shader_info {
37 uint16_t sizedwords;
38 int8_t max_reg; /* highest GPR # used by shader */
39 uint8_t max_input_reg;
40 uint64_t regs_written;
41 };
42
43 struct ir2_register {
44 enum {
45 IR2_REG_CONST = 0x1,
46 IR2_REG_EXPORT = 0x2,
47 IR2_REG_NEGATE = 0x4,
48 IR2_REG_ABS = 0x8,
49 } flags;
50 int num;
51 char *swizzle;
52 };
53
54 enum ir2_pred {
55 IR2_PRED_NONE = 0,
56 IR2_PRED_EQ = 1,
57 IR2_PRED_NE = 2,
58 };
59
60 struct ir2_instruction {
61 struct ir2_shader *shader;
62 enum {
63 IR2_FETCH,
64 IR2_ALU,
65 } instr_type;
66 enum ir2_pred pred;
67 int sync;
68 unsigned regs_count;
69 struct ir2_register *regs[5];
70 union {
71 /* FETCH specific: */
72 struct {
73 instr_fetch_opc_t opc;
74 unsigned const_idx;
75 /* texture fetch specific: */
76 bool is_cube : 1;
77 /* vertex fetch specific: */
78 unsigned const_idx_sel;
79 enum a2xx_sq_surfaceformat fmt;
80 bool is_signed : 1;
81 bool is_normalized : 1;
82 uint32_t stride;
83 uint32_t offset;
84 } fetch;
85 /* ALU specific: */
86 struct {
87 instr_vector_opc_t vector_opc;
88 instr_scalar_opc_t scalar_opc;
89 bool vector_clamp : 1;
90 bool scalar_clamp : 1;
91 } alu;
92 };
93 };
94
95 struct ir2_cf {
96 struct ir2_shader *shader;
97 instr_cf_opc_t cf_type;
98
99 union {
100 /* EXEC/EXEC_END specific: */
101 struct {
102 unsigned instrs_count;
103 struct ir2_instruction *instrs[6];
104 uint32_t addr, cnt, sequence;
105 } exec;
106 /* ALLOC specific: */
107 struct {
108 instr_alloc_type_t type; /* SQ_POSITION or SQ_PARAMETER_PIXEL */
109 int size;
110 } alloc;
111 };
112 };
113
114 struct ir2_shader {
115 unsigned cfs_count;
116 struct ir2_cf *cfs[0x56];
117 uint32_t heap[100 * 4096];
118 unsigned heap_idx;
119
120 enum ir2_pred pred; /* pred inherited by newly created instrs */
121 };
122
123 struct ir2_shader * ir2_shader_create(void);
124 void ir2_shader_destroy(struct ir2_shader *shader);
125 void * ir2_shader_assemble(struct ir2_shader *shader,
126 struct ir2_shader_info *info);
127
128 struct ir2_cf * ir2_cf_create(struct ir2_shader *shader, instr_cf_opc_t cf_type);
129
130 struct ir2_instruction * ir2_instr_create(struct ir2_cf *cf, int instr_type);
131
132 struct ir2_register * ir2_reg_create(struct ir2_instruction *instr,
133 int num, const char *swizzle, int flags);
134
135 /* some helper fxns: */
136
137 static inline struct ir2_cf *
ir2_cf_create_alloc(struct ir2_shader * shader,instr_alloc_type_t type,int size)138 ir2_cf_create_alloc(struct ir2_shader *shader, instr_alloc_type_t type, int size)
139 {
140 struct ir2_cf *cf = ir2_cf_create(shader, ALLOC);
141 if (!cf)
142 return cf;
143 cf->alloc.type = type;
144 cf->alloc.size = size;
145 return cf;
146 }
147 static inline struct ir2_instruction *
ir2_instr_create_alu(struct ir2_cf * cf,instr_vector_opc_t vop,instr_scalar_opc_t sop)148 ir2_instr_create_alu(struct ir2_cf *cf, instr_vector_opc_t vop, instr_scalar_opc_t sop)
149 {
150 struct ir2_instruction *instr = ir2_instr_create(cf, IR2_ALU);
151 if (!instr)
152 return instr;
153 instr->alu.vector_opc = vop;
154 instr->alu.scalar_opc = sop;
155 return instr;
156 }
157 static inline struct ir2_instruction *
ir2_instr_create_vtx_fetch(struct ir2_cf * cf,int ci,int cis,enum a2xx_sq_surfaceformat fmt,bool is_signed,int stride)158 ir2_instr_create_vtx_fetch(struct ir2_cf *cf, int ci, int cis,
159 enum a2xx_sq_surfaceformat fmt, bool is_signed, int stride)
160 {
161 struct ir2_instruction *instr = ir2_instr_create(cf, IR2_FETCH);
162 instr->fetch.opc = VTX_FETCH;
163 instr->fetch.const_idx = ci;
164 instr->fetch.const_idx_sel = cis;
165 instr->fetch.fmt = fmt;
166 instr->fetch.is_signed = is_signed;
167 instr->fetch.stride = stride;
168 return instr;
169 }
170 static inline struct ir2_instruction *
ir2_instr_create_tex_fetch(struct ir2_cf * cf,int ci)171 ir2_instr_create_tex_fetch(struct ir2_cf *cf, int ci)
172 {
173 struct ir2_instruction *instr = ir2_instr_create(cf, IR2_FETCH);
174 instr->fetch.opc = TEX_FETCH;
175 instr->fetch.const_idx = ci;
176 return instr;
177 }
178
179
180 #endif /* IR2_H_ */
181