Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / r300 / radeon_mesa_to_rc.c
1 /*
2  * Copyright (C) 2009 Nicolai Haehnle.
3  *
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial
16  * portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  */
27
28 #include "radeon_mesa_to_rc.h"
29
30 #include "main/mtypes.h"
31 #include "program/prog_instruction.h"
32 #include "program/prog_parameter.h"
33
34 #include "compiler/radeon_compiler.h"
35 #include "compiler/radeon_program.h"
36
37
38 static rc_opcode translate_opcode(gl_inst_opcode opcode)
39 {
40         switch(opcode) {
41         case OPCODE_NOP: return RC_OPCODE_NOP;
42         case OPCODE_ABS: return RC_OPCODE_ABS;
43         case OPCODE_ADD: return RC_OPCODE_ADD;
44         case OPCODE_ARL: return RC_OPCODE_ARL;
45         case OPCODE_CMP: return RC_OPCODE_CMP;
46         case OPCODE_COS: return RC_OPCODE_COS;
47         case OPCODE_DDX: return RC_OPCODE_DDX;
48         case OPCODE_DDY: return RC_OPCODE_DDY;
49         case OPCODE_DP3: return RC_OPCODE_DP3;
50         case OPCODE_DP4: return RC_OPCODE_DP4;
51         case OPCODE_DPH: return RC_OPCODE_DPH;
52         case OPCODE_DST: return RC_OPCODE_DST;
53         case OPCODE_EX2: return RC_OPCODE_EX2;
54         case OPCODE_EXP: return RC_OPCODE_EXP;
55         case OPCODE_FLR: return RC_OPCODE_FLR;
56         case OPCODE_FRC: return RC_OPCODE_FRC;
57         case OPCODE_KIL: return RC_OPCODE_KIL;
58         case OPCODE_LG2: return RC_OPCODE_LG2;
59         case OPCODE_LIT: return RC_OPCODE_LIT;
60         case OPCODE_LOG: return RC_OPCODE_LOG;
61         case OPCODE_LRP: return RC_OPCODE_LRP;
62         case OPCODE_MAD: return RC_OPCODE_MAD;
63         case OPCODE_MAX: return RC_OPCODE_MAX;
64         case OPCODE_MIN: return RC_OPCODE_MIN;
65         case OPCODE_MOV: return RC_OPCODE_MOV;
66         case OPCODE_MUL: return RC_OPCODE_MUL;
67         case OPCODE_POW: return RC_OPCODE_POW;
68         case OPCODE_RCP: return RC_OPCODE_RCP;
69         case OPCODE_RSQ: return RC_OPCODE_RSQ;
70         case OPCODE_SCS: return RC_OPCODE_SCS;
71         case OPCODE_SEQ: return RC_OPCODE_SEQ;
72         case OPCODE_SFL: return RC_OPCODE_SFL;
73         case OPCODE_SGE: return RC_OPCODE_SGE;
74         case OPCODE_SGT: return RC_OPCODE_SGT;
75         case OPCODE_SIN: return RC_OPCODE_SIN;
76         case OPCODE_SLE: return RC_OPCODE_SLE;
77         case OPCODE_SLT: return RC_OPCODE_SLT;
78         case OPCODE_SNE: return RC_OPCODE_SNE;
79         case OPCODE_SUB: return RC_OPCODE_SUB;
80         case OPCODE_SWZ: return RC_OPCODE_SWZ;
81         case OPCODE_TEX: return RC_OPCODE_TEX;
82         case OPCODE_TXB: return RC_OPCODE_TXB;
83         case OPCODE_TXD: return RC_OPCODE_TXD;
84         case OPCODE_TXL: return RC_OPCODE_TXL;
85         case OPCODE_TXP: return RC_OPCODE_TXP;
86         case OPCODE_XPD: return RC_OPCODE_XPD;
87         default: return RC_OPCODE_ILLEGAL_OPCODE;
88         }
89 }
90
91 static rc_saturate_mode translate_saturate(unsigned int saturate)
92 {
93         switch(saturate) {
94         default:
95         case SATURATE_OFF: return RC_SATURATE_NONE;
96         case SATURATE_ZERO_ONE: return RC_SATURATE_ZERO_ONE;
97         }
98 }
99
100 static rc_register_file translate_register_file(unsigned int file)
101 {
102         switch(file) {
103         case PROGRAM_TEMPORARY: return RC_FILE_TEMPORARY;
104         case PROGRAM_INPUT: return RC_FILE_INPUT;
105         case PROGRAM_OUTPUT: return RC_FILE_OUTPUT;
106         case PROGRAM_LOCAL_PARAM:
107         case PROGRAM_ENV_PARAM:
108         case PROGRAM_STATE_VAR:
109         case PROGRAM_NAMED_PARAM:
110         case PROGRAM_CONSTANT:
111         case PROGRAM_UNIFORM: return RC_FILE_CONSTANT;
112         case PROGRAM_ADDRESS: return RC_FILE_ADDRESS;
113         default: return RC_FILE_NONE;
114         }
115 }
116
117 static void translate_srcreg(struct rc_src_register * dest, struct prog_src_register * src)
118 {
119         dest->File = translate_register_file(src->File);
120         dest->Index = src->Index;
121         dest->RelAddr = src->RelAddr;
122         dest->Swizzle = src->Swizzle;
123         dest->Abs = src->Abs;
124         dest->Negate = src->Negate;
125 }
126
127 static void translate_dstreg(struct rc_dst_register * dest, struct prog_dst_register * src)
128 {
129         dest->File = translate_register_file(src->File);
130         dest->Index = src->Index;
131         dest->WriteMask = src->WriteMask;
132 }
133
134 static rc_texture_target translate_tex_target(gl_texture_index target)
135 {
136         switch(target) {
137         case TEXTURE_2D_ARRAY_INDEX: return RC_TEXTURE_2D_ARRAY;
138         case TEXTURE_1D_ARRAY_INDEX: return RC_TEXTURE_1D_ARRAY;
139         case TEXTURE_CUBE_INDEX: return RC_TEXTURE_CUBE;
140         case TEXTURE_3D_INDEX: return RC_TEXTURE_3D;
141         case TEXTURE_RECT_INDEX: return RC_TEXTURE_RECT;
142         default:
143         case TEXTURE_2D_INDEX: return RC_TEXTURE_2D;
144         case TEXTURE_1D_INDEX: return RC_TEXTURE_1D;
145         }
146 }
147
148 static void translate_instruction(struct radeon_compiler * c,
149                 struct rc_instruction * dest, struct prog_instruction * src)
150 {
151         const struct rc_opcode_info * opcode;
152         unsigned int i;
153
154         dest->U.I.Opcode = translate_opcode(src->Opcode);
155         if (dest->U.I.Opcode == RC_OPCODE_ILLEGAL_OPCODE) {
156                 rc_error(c, "Unsupported opcode %i\n", src->Opcode);
157                 return;
158         }
159         dest->U.I.SaturateMode = translate_saturate(src->SaturateMode);
160
161         opcode = rc_get_opcode_info(dest->U.I.Opcode);
162
163         for(i = 0; i < opcode->NumSrcRegs; ++i)
164                 translate_srcreg(&dest->U.I.SrcReg[i], &src->SrcReg[i]);
165
166         if (opcode->HasDstReg)
167                 translate_dstreg(&dest->U.I.DstReg, &src->DstReg);
168
169         if (opcode->HasTexture) {
170                 dest->U.I.TexSrcUnit = src->TexSrcUnit;
171                 dest->U.I.TexSrcTarget = translate_tex_target(src->TexSrcTarget);
172                 dest->U.I.TexShadow = src->TexShadow;
173                 dest->U.I.TexSwizzle = RC_SWIZZLE_XYZW;
174         }
175 }
176
177 void radeon_mesa_to_rc_program(struct radeon_compiler * c, struct gl_program * program)
178 {
179         struct prog_instruction *source;
180         unsigned int i;
181
182         for(source = program->Instructions; source->Opcode != OPCODE_END; ++source) {
183                 struct rc_instruction * dest = rc_insert_new_instruction(c, c->Program.Instructions.Prev);
184                 translate_instruction(c, dest, source);
185         }
186
187         c->Program.ShadowSamplers = program->ShadowSamplers;
188         c->Program.InputsRead = program->InputsRead;
189         c->Program.OutputsWritten = program->OutputsWritten;
190
191         int isNVProgram = 0;
192
193         if (program->Target == GL_VERTEX_PROGRAM_ARB) {
194                 struct gl_vertex_program * vp = (struct gl_vertex_program *) program;
195                 isNVProgram = vp->IsNVProgram;
196         }
197
198         if (isNVProgram) {
199                 /* NV_vertex_program has a fixed-sized constant environment.
200                  * This could be handled more efficiently for programs that
201                  * do not use relative addressing.
202                  */
203                 for(i = 0; i < 96; ++i) {
204                         struct rc_constant constant;
205
206                         constant.Type = RC_CONSTANT_EXTERNAL;
207                         constant.Size = 4;
208                         constant.u.External = i;
209
210                         rc_constants_add(&c->Program.Constants, &constant);
211                 }
212         } else {
213                 for(i = 0; i < program->Parameters->NumParameters; ++i) {
214                         struct rc_constant constant;
215
216                         constant.Type = RC_CONSTANT_EXTERNAL;
217                         constant.Size = 4;
218                         constant.u.External = i;
219
220                         rc_constants_add(&c->Program.Constants, &constant);
221                 }
222         }
223 }