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 "program/prog_instruction.h"
32
#include "program/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->WriteMask = src->WriteMask;
134
static rc_texture_target translate_tex_target(gl_texture_index 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;
143
case TEXTURE_2D_INDEX: return RC_TEXTURE_2D;
144
case TEXTURE_1D_INDEX: return RC_TEXTURE_1D;
148
static void translate_instruction(struct radeon_compiler * c,
149
struct rc_instruction * dest, struct prog_instruction * src)
151
const struct rc_opcode_info * opcode;
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);
159
dest->U.I.SaturateMode = translate_saturate(src->SaturateMode);
161
opcode = rc_get_opcode_info(dest->U.I.Opcode);
163
for(i = 0; i < opcode->NumSrcRegs; ++i)
164
translate_srcreg(&dest->U.I.SrcReg[i], &src->SrcReg[i]);
166
if (opcode->HasDstReg)
167
translate_dstreg(&dest->U.I.DstReg, &src->DstReg);
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;
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);