2 * Copyright (C) 2009 Nicolai Haehnle.
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:
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.
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.
28 #include "radeon_mesa_to_rc.h"
30 #include "main/mtypes.h"
31 #include "shader/prog_instruction.h"
32 #include "shader/prog_parameter.h"
34 #include "compiler/radeon_compiler.h"
35 #include "compiler/radeon_program.h"
38 static rc_opcode
translate_opcode(gl_inst_opcode 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
;
91 static rc_saturate_mode
translate_saturate(unsigned int saturate
)
95 case SATURATE_OFF
: return RC_SATURATE_NONE
;
96 case SATURATE_ZERO_ONE
: return RC_SATURATE_ZERO_ONE
;
100 static rc_register_file
translate_register_file(unsigned int 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
;
117 static void translate_srcreg(struct rc_src_register
* dest
, struct prog_src_register
* src
)
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
;
127 static void translate_dstreg(struct rc_dst_register
* dest
, struct prog_dst_register
* src
)
129 dest
->File
= translate_register_file(src
->File
);
130 dest
->Index
= src
->Index
;
131 dest
->RelAddr
= src
->RelAddr
;
132 dest
->WriteMask
= src
->WriteMask
;
135 static rc_texture_target
translate_tex_target(gl_texture_index target
)
138 case TEXTURE_2D_ARRAY_INDEX
: return RC_TEXTURE_2D_ARRAY
;
139 case TEXTURE_1D_ARRAY_INDEX
: return RC_TEXTURE_1D_ARRAY
;
140 case TEXTURE_CUBE_INDEX
: return RC_TEXTURE_CUBE
;
141 case TEXTURE_3D_INDEX
: return RC_TEXTURE_3D
;
142 case TEXTURE_RECT_INDEX
: return RC_TEXTURE_RECT
;
144 case TEXTURE_2D_INDEX
: return RC_TEXTURE_2D
;
145 case TEXTURE_1D_INDEX
: return RC_TEXTURE_1D
;
149 static void translate_instruction(struct radeon_compiler
* c
,
150 struct rc_instruction
* dest
, struct prog_instruction
* src
)
152 const struct rc_opcode_info
* opcode
;
155 dest
->U
.I
.Opcode
= translate_opcode(src
->Opcode
);
156 if (dest
->U
.I
.Opcode
== RC_OPCODE_ILLEGAL_OPCODE
) {
157 rc_error(c
, "Unsupported opcode %i\n", src
->Opcode
);
160 dest
->U
.I
.SaturateMode
= translate_saturate(src
->SaturateMode
);
162 opcode
= rc_get_opcode_info(dest
->U
.I
.Opcode
);
164 for(i
= 0; i
< opcode
->NumSrcRegs
; ++i
)
165 translate_srcreg(&dest
->U
.I
.SrcReg
[i
], &src
->SrcReg
[i
]);
167 if (opcode
->HasDstReg
)
168 translate_dstreg(&dest
->U
.I
.DstReg
, &src
->DstReg
);
170 if (opcode
->HasTexture
) {
171 dest
->U
.I
.TexSrcUnit
= src
->TexSrcUnit
;
172 dest
->U
.I
.TexSrcTarget
= translate_tex_target(src
->TexSrcTarget
);
173 dest
->U
.I
.TexShadow
= src
->TexShadow
;
177 void radeon_mesa_to_rc_program(struct radeon_compiler
* c
, struct gl_program
* program
)
179 struct prog_instruction
*source
;
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
);
187 c
->Program
.ShadowSamplers
= program
->ShadowSamplers
;
188 c
->Program
.InputsRead
= program
->InputsRead
;
189 c
->Program
.OutputsWritten
= program
->OutputsWritten
;
193 if (program
->Target
== GL_VERTEX_PROGRAM_ARB
) {
194 struct gl_vertex_program
* vp
= (struct gl_vertex_program
*) program
;
195 isNVProgram
= vp
->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.
203 for(i
= 0; i
< 96; ++i
) {
204 struct rc_constant constant
;
206 constant
.Type
= RC_CONSTANT_EXTERNAL
;
208 constant
.u
.External
= i
;
210 rc_constants_add(&c
->Program
.Constants
, &constant
);
213 for(i
= 0; i
< program
->Parameters
->NumParameters
; ++i
) {
214 struct rc_constant constant
;
216 constant
.Type
= RC_CONSTANT_EXTERNAL
;
218 constant
.u
.External
= i
;
220 rc_constants_add(&c
->Program
.Constants
, &constant
);