2 * Copyright 2014 Ilia Mirkin
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
25 #include "tgsi/tgsi_text.h"
26 #include "util/u_debug.h"
28 #include "codegen/nv50_ir_driver.h"
29 #include "nv50/nv50_context.h"
31 /* these headers weren't really meant to be included together */
34 #include "nv30/nv30_state.h"
35 #include "nv30/nvfx_shader.h"
38 nv30_fp(int chipset
, struct tgsi_token tokens
[],
39 unsigned *size
, unsigned **code
) {
40 struct nv30_fragprog fp
;
41 memset(&fp
, 0, sizeof(fp
));
42 fp
.pipe
.tokens
= tokens
;
43 tgsi_scan_shader(fp
.pipe
.tokens
, &fp
.info
);
44 _nvfx_fragprog_translate(chipset
>= 0x40 ? 0x4097 : 0x3097, &fp
);
45 *size
= fp
.insn_len
* 4;
47 return !fp
.translated
;
51 nv30_vp(int chipset
, struct tgsi_token tokens
[],
52 unsigned *size
, unsigned **code
) {
53 struct nv30_vertprog vp
;
54 memset(&vp
, 0, sizeof(vp
));
56 vp
.pipe
.tokens
= tokens
;
57 tgsi_scan_shader(vp
.pipe
.tokens
, &vp
.info
);
58 _nvfx_vertprog_translate(chipset
>= 0x40 ? 0x4097 : 0x3097, &vp
);
59 *size
= vp
.nr_insns
* 16;
60 *code
= (unsigned *)vp
.insns
;
61 return !vp
.translated
;
65 nv30_codegen(int chipset
, int type
, struct tgsi_token tokens
[],
66 unsigned *size
, unsigned **code
) {
68 case PIPE_SHADER_FRAGMENT
:
69 return nv30_fp(chipset
, tokens
, size
, code
);
70 case PIPE_SHADER_VERTEX
:
71 return nv30_vp(chipset
, tokens
, size
, code
);
73 _debug_printf("Unexpected shader type: %d\n", type
);
78 dummy_assign_slots(struct nv50_ir_prog_info
*info
)
83 for (i
= 0; i
< info
->numInputs
; ++i
) {
84 for (c
= 0; c
< 4; ++c
)
85 if (info
->in
[i
].mask
& (1 << c
))
86 info
->in
[i
].slot
[c
] = n
++;
89 /* VertexID before InstanceID */
90 if (info
->io
.vertexId
< info
->numSysVals
)
91 info
->sv
[info
->io
.vertexId
].slot
[0] = n
++;
92 if (info
->io
.instanceId
< info
->numSysVals
)
93 info
->sv
[info
->io
.instanceId
].slot
[0] = n
++;
96 for (i
= 0; i
< info
->numOutputs
; ++i
) {
97 for (c
= 0; c
< 4; ++c
)
98 if (info
->out
[i
].mask
& (1 << c
))
99 info
->out
[i
].slot
[c
] = n
++;
105 nouveau_codegen(int chipset
, int type
, struct tgsi_token tokens
[],
106 unsigned *size
, unsigned **code
) {
107 struct nv50_ir_prog_info info
= {0};
111 info
.target
= chipset
;
112 info
.bin
.sourceRep
= NV50_PROGRAM_IR_TGSI
;
113 info
.bin
.source
= tokens
;
115 info
.io
.auxCBSlot
= 15;
116 info
.io
.ucpBase
= NV50_CB_AUX_UCP_OFFSET
;
117 info
.io
.suInfoBase
= NV50_CB_AUX_TEX_MS_OFFSET
;
118 info
.io
.msInfoCBSlot
= 15;
119 info
.io
.msInfoBase
= NV50_CB_AUX_MS_OFFSET
;
121 info
.assignSlots
= dummy_assign_slots
;
123 info
.optLevel
= debug_get_num_option("NV50_PROG_OPTIMIZE", 3);
124 info
.dbgFlags
= debug_get_num_option("NV50_PROG_DEBUG", 0);
126 ret
= nv50_ir_generate_code(&info
);
128 _debug_printf("Error compiling program: %d\n", ret
);
132 *size
= info
.bin
.codeSize
;
133 *code
= info
.bin
.code
;
138 main(int argc
, char *argv
[])
140 struct tgsi_token tokens
[4096];
141 int i
, chipset
= 0, type
= -1;
142 const char *filename
= NULL
;
144 char text
[65536] = {0};
145 unsigned size
, *code
;
147 for (i
= 1; i
< argc
; i
++) {
148 if (!strcmp(argv
[i
], "-a"))
149 chipset
= strtol(argv
[++i
], NULL
, 16);
155 _debug_printf("Must specify a chipset (-a)\n");
160 _debug_printf("Must specify a filename\n");
164 if (!strcmp(filename
, "-"))
167 f
= fopen(filename
, "r");
170 _debug_printf("Error opening file '%s': %s\n", filename
, strerror(errno
));
174 if (!fread(text
, 1, sizeof(text
), f
) || ferror(f
)) {
175 _debug_printf("Error reading file '%s'\n", filename
);
181 _debug_printf("Compiling for NV%X\n", chipset
);
183 if (!strncmp(text
, "FRAG", 4))
184 type
= PIPE_SHADER_FRAGMENT
;
185 else if (!strncmp(text
, "VERT", 4))
186 type
= PIPE_SHADER_VERTEX
;
187 else if (!strncmp(text
, "GEOM", 4))
188 type
= PIPE_SHADER_GEOMETRY
;
189 else if (!strncmp(text
, "COMP", 4))
190 type
= PIPE_SHADER_COMPUTE
;
191 else if (!strncmp(text
, "TESS_CTRL", 9))
192 type
= PIPE_SHADER_TESS_CTRL
;
193 else if (!strncmp(text
, "TESS_EVAL", 9))
194 type
= PIPE_SHADER_TESS_EVAL
;
196 _debug_printf("Unrecognized TGSI header\n");
200 if (!tgsi_text_translate(text
, tokens
, ARRAY_SIZE(tokens
))) {
201 _debug_printf("Failed to parse TGSI shader\n");
205 if (chipset
>= 0x50) {
206 i
= nouveau_codegen(chipset
, type
, tokens
, &size
, &code
);
207 } else if (chipset
>= 0x30) {
208 i
= nv30_codegen(chipset
, type
, tokens
, &size
, &code
);
210 _debug_printf("chipset NV%02X not supported\n", chipset
);
216 _debug_printf("program binary (%d bytes)\n", size
);
217 for (i
= 0; i
< size
; i
+= 4) {
218 printf("%08x ", code
[i
/ 4]);
219 if (i
% (8 * 4) == (7 * 4))
222 if (i
% (8 * 4) != 0)