/
d3d2glsl.c
1860 lines (1516 loc) · 52 KB
1
2
3
4
5
6
7
8
/**
* d3d2glsl; generate GLSL programs from bytecode of compiled Direct3D shaders.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
9
10
// !!! FIXME: I keep changing coding styles for symbols and typedefs.
11
12
13
// Shader bytecode format is described at MSDN:
// http://msdn2.microsoft.com/en-us/library/ms800307.aspx
14
#include <stdio.h>
15
#include <string.h>
16
#include <stdlib.h>
17
#include <stdint.h>
18
#include <stdarg.h>
19
20
21
#include "d3d2glsl.h"
22
23
24
25
26
// This is the highest shader version we currently support.
#define MAX_SHADER_MAJOR 3
#define MAX_SHADER_MINOR 0
27
28
29
// You get all the profiles unless you go out of your way to disable them.
30
31
32
33
34
35
36
37
#ifndef SUPPORT_PROFILE_D3D
#define SUPPORT_PROFILE_D3D 1
#endif
#ifndef SUPPORT_PROFILE_GLSL
#define SUPPORT_PROFILE_GLSL 1
#endif
38
39
40
41
42
43
44
// Get basic wankery out of the way here...
typedef unsigned int uint; // this is a printf() helper. don't use for code.
typedef uint8_t uint8;
typedef uint32_t uint32;
45
46
47
48
49
50
#ifdef __GNUC__
#define ISPRINTF(x,y) __attribute__((format (printf, x, y)))
#else
#define ISPRINTF(x,y)
#endif
51
52
#define STATICARRAYLEN(x) ( (sizeof ((x))) / (sizeof ((x)[0])) )
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Byteswap magic...
#if ((defined __GNUC__) && (defined __POWERPC__))
static inline uint32 SWAP32(uint32 x)
{
__asm__ __volatile__("lwbrx %0,0,%1" : "=r" (x) : "r" (&x));
return x;
} // SWAP32
#elif defined(__POWERPC__)
static inline uint32 SWAP32(uint32 x)
{
return ( (((x) >> 24) & 0x000000FF) | (((x) >> 8) & 0x0000FF00) |
(((x) << 8) & 0x00FF0000) | (((x) << 24) & 0xFF000000) );
} // SWAP32
#else
# define SWAP32(x) (x)
#endif
72
73
74
75
76
77
78
79
80
81
82
// Shader model version magic.
static inline uint32 ver_ui32(const uint8 major, const uint8 minor)
{
return ( (((uint32) major) << 16) | (((minor) == 0xFF) ? 0 : (minor)) );
} // version_ui32
#define SHADER_VERSION_SUPPORTED(maj, min) \
(ver_ui32(maj, min) <= ver_ui32(MAX_SHADER_MAJOR, MAX_SHADER_MINOR))
83
// predeclare.
84
typedef struct Context Context;
85
86
// one emit function for each opcode in each profile.
87
typedef void (*emit_function)(Context *ctx);
88
89
// one emit function for comments in each profile.
90
typedef void (*emit_comment)(Context *ctx, const char *str);
91
92
// one emit function for starting output in each profile.
93
typedef void (*emit_start)(Context *ctx);
94
95
// one emit function for ending output in each profile.
96
typedef void (*emit_end)(Context *ctx);
97
98
99
100
// one args function for each possible sequence of opcode arguments.
typedef int (*args_function)(Context *ctx);
101
// one state function for each opcode where we have state machine updates.
102
typedef int (*state_function)(Context *ctx);
103
104
105
106
107
108
109
110
111
typedef struct
{
const char *name;
emit_start start_emitter;
emit_end end_emitter;
emit_comment comment_emitter;
} D3D2GLSL_profile;
112
113
114
115
116
117
118
119
120
typedef enum
{
SHADER_TYPE_UNKNOWN = -1,
SHADER_TYPE_PIXEL,
SHADER_TYPE_VERTEX,
SHADER_TYPE_TOTAL
} D3D2GLSL_shaderType;
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
typedef enum
{
REGISTER_TYPE_TEMP = 0,
REGISTER_TYPE_INPUT = 1,
REGISTER_TYPE_CONST = 2,
REGISTER_TYPE_ADDR = 3,
REGISTER_TYPE_TEXTURE = 3, // ALSO 3!
REGISTER_TYPE_RASTOUT = 4,
REGISTER_TYPE_ATTROUT = 5,
REGISTER_TYPE_TEXCRDOUT = 6,
REGISTER_TYPE_OUTPUT = 6, // ALSO 6!
REGISTER_TYPE_CONSTINT = 7,
REGISTER_TYPE_COLOROUT = 8,
REGISTER_TYPE_DEPTHOUT = 9,
REGISTER_TYPE_SAMPLER = 10,
REGISTER_TYPE_CONST2 = 11,
REGISTER_TYPE_CONST3 = 12,
REGISTER_TYPE_CONST4 = 13,
REGISTER_TYPE_CONSTBOOL = 14,
REGISTER_TYPE_LOOP = 15,
REGISTER_TYPE_TEMPFLOAT16 = 16,
REGISTER_TYPE_MISCTYPE = 17,
REGISTER_TYPE_LABEL = 18,
REGISTER_TYPE_PREDICATE = 19,
REGISTER_TYPE_MAX = 19
} D3D2GLSL_registerType;
typedef enum
{
RASTOUT_TYPE_POSITION = 0,
RASTOUT_TYPE_FOG = 1,
RASTOUT_TYPE_POINT_SIZE = 2,
RASTOUT_TYPE_MAX = 2
} D3D2GLSL_rastoutType;
typedef enum
{
MISCTYPE_TYPE_POSITION = 0,
MISCTYPE_TYPE_FACE = 1,
MISCTYPE_TYPE_MAX = 1
} D3D2GLSL_misctypeType;
163
164
165
166
167
168
169
170
171
172
// A simple linked list of strings, so we can build the final output without
// realloc()ing for each new line, and easily insert lines into the middle
// of the output without much trouble.
typedef struct OutputList
{
char *str;
struct OutputList *next;
} OutputList;
173
174
175
176
177
178
179
// result modifiers.
#define MOD_SATURATE 0x01
#define MOD_PP 0x02
#define MOD_CENTROID 0x04
180
181
typedef struct
{
182
const uint32 *token; // this is the unmolested token in the stream.
183
184
int regnum;
int relative;
185
186
187
188
189
int writemask; // xyzw or rgba (all four, not split out).
int writemask0; // x or red
int writemask1; // y or green
int writemask2; // z or blue
int writemask3; // w or alpha
190
191
192
193
194
195
196
int result_mod;
int result_shift;
int regtype;
} DestArgInfo;
typedef struct
{
197
const uint32 *token; // this is the unmolested token in the stream.
198
199
int regnum;
int relative;
200
int swizzle; // xyzw (all four, not split out).
201
202
203
204
205
206
207
208
209
int swizzle_x;
int swizzle_y;
int swizzle_z;
int swizzle_w;
int src_mod;
int regtype;
} SourceArgInfo;
210
#define D3D2GLSL_SCRATCH_BUFFER_SIZE 256
211
#define D3D2GLSL_SCRATCH_BUFFERS 10
212
213
// Context...this is state that changes as we parse through a shader...
214
struct Context
215
{
216
217
D3D2GLSL_malloc malloc;
D3D2GLSL_free free;
218
219
const uint32 *tokens;
uint32 tokencount;
220
221
222
223
224
225
226
227
228
OutputList output;
OutputList *output_tail;
int output_len; // total strlen; prevents walking the list just to malloc.
const char *endline;
int endline_len;
const char *failstr;
char scratch[D3D2GLSL_SCRATCH_BUFFERS][D3D2GLSL_SCRATCH_BUFFER_SIZE];
int scratchidx; // current scratch buffer.
int profileid;
229
const D3D2GLSL_profile *profile;
230
231
232
D3D2GLSL_shaderType shader_type;
uint32 major_ver;
uint32 minor_ver;
233
234
DestArgInfo dest_args[1];
SourceArgInfo source_args[4];
235
236
237
};
238
static inline char *get_scratch_buffer(Context *ctx)
239
{
240
241
ctx->scratchidx = (ctx->scratchidx + 1) % D3D2GLSL_SCRATCH_BUFFERS;
return ctx->scratch[ctx->scratchidx];
242
243
} // get_scratch_buffer
244
245
246
// Special-case return values from the parsing pipeline...
#define FAIL (-1)
247
#define END_OF_STREAM (-2)
248
249
250
251
252
253
254
255
256
257
258
259
static const char *out_of_mem_string = "Out of memory";
static inline int out_of_memory(Context *ctx)
{
if (ctx->failstr == NULL)
ctx->failstr = out_of_mem_string; // fail() would call malloc().
return FAIL;
} // out_of_memory
static int failf(Context *ctx, const char *fmt, ...) ISPRINTF(2,3);
static int failf(Context *ctx, const char *fmt, ...)
260
{
261
262
if (ctx->failstr == NULL) // don't change existing error.
{
263
char *scratch = get_scratch_buffer(ctx);
264
265
va_list ap;
va_start(ap, fmt);
266
const int len = vsnprintf(scratch,D3D2GLSL_SCRATCH_BUFFER_SIZE,fmt,ap);
267
268
va_end(ap);
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
char *failstr = (char *) ctx->malloc(len + 1);
if (failstr == NULL)
out_of_memory(ctx);
else
{
// see comments about scratch buffer overflow in output_line().
if (len < D3D2GLSL_SCRATCH_BUFFER_SIZE)
strcpy(failstr, scratch); // copy it over.
else
{
va_start(ap, fmt);
vsnprintf(failstr, len + 1, fmt, ap); // rebuild it.
va_end(ap);
} // else
ctx->failstr = failstr;
} // else
285
286
287
288
289
290
} // if
return FAIL;
} // failf
291
static inline int fail(Context *ctx, const char *reason)
292
293
294
295
296
{
return failf(ctx, "%s", reason);
} // fail
297
298
static int output_line(Context *ctx, const char *fmt, ...) ISPRINTF(2,3);
static int output_line(Context *ctx, const char *fmt, ...)
299
300
301
302
{
if (ctx->failstr != NULL)
return FAIL; // we failed previously, don't go on...
303
304
305
306
307
OutputList *item = (OutputList *) ctx->malloc(sizeof (OutputList));
if (item == NULL)
return out_of_memory(ctx);
char *scratch = get_scratch_buffer(ctx);
308
309
va_list ap;
va_start(ap, fmt);
310
const int len = vsnprintf(scratch, D3D2GLSL_SCRATCH_BUFFER_SIZE, fmt, ap);
311
312
va_end(ap);
313
314
item->str = (char *) ctx->malloc(len + 1);
if (item->str == NULL)
315
{
316
317
free(item);
return out_of_memory(ctx);
318
319
} // if
320
321
322
323
324
325
326
327
328
329
330
// If we overflowed our scratch buffer, that's okay. We were going to
// allocate anyhow...the scratch buffer just lets us avoid a second
// run of vsnprintf().
if (len < D3D2GLSL_SCRATCH_BUFFER_SIZE)
strcpy(item->str, scratch); // copy it over.
else
{
va_start(ap, fmt);
vsnprintf(item->str, len + 1, fmt, ap); // rebuild it.
va_end(ap);
} // else
331
332
333
334
335
item->next = NULL;
ctx->output_tail->next = item;
ctx->output_tail = item;
ctx->output_len += len + ctx->endline_len;
336
337
338
339
return 0;
} // output_line
340
341
// if SUPPORT_PROFILE_* isn't defined, we assume an implicit desire to support.
342
343
344
345
346
347
348
349
350
#define AT_LEAST_ONE_PROFILE 0
#if !SUPPORT_PROFILE_D3D
#define PROFILE_EMITTER_D3D(op)
#else
#undef AT_LEAST_ONE_PROFILE
#define AT_LEAST_ONE_PROFILE 1
#define PROFILE_EMITTER_D3D(op) emit_D3D_##op,
351
static char *make_D3D_destarg_string(Context *ctx, const int idx)
352
{
353
354
355
if (idx >= STATICARRAYLEN(ctx->dest_args))
{
fail(ctx, "Too many destination args");
356
return "";
357
} // if
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
const DestArgInfo *arg = &ctx->dest_args[idx];
const char *result_shift_str = "";
switch (arg->result_shift)
{
case 0x1: result_shift_str = "_x2"; break;
case 0x2: result_shift_str = "_x4"; break;
case 0x3: result_shift_str = "_x8"; break;
case 0xD: result_shift_str = "_d8"; break;
case 0xE: result_shift_str = "_d4"; break;
case 0xF: result_shift_str = "_d2"; break;
} // switch
const char *sat_str = (arg->result_mod & MOD_SATURATE) ? "_sat" : "";
const char *pp_str = (arg->result_mod & MOD_PP) ? "_pp" : "";
const char *cent_str = (arg->result_mod & MOD_CENTROID) ? "_centroid" : "";
char regnum_str[16];
snprintf(regnum_str, sizeof (regnum_str), "%u", (uint) arg->regnum);
static const char *regtypes[] = {
"r", "v", "c", NULL, NULL, "oD", NULL, "i", "oC", "oDepth",
"s", "c", "c", "c", "b", "aL", NULL, NULL, "l", "p"
};
const char *regtype_str = NULL;
switch ((D3D2GLSL_registerType) arg->regtype)
{
case REGISTER_TYPE_TEMP:
regtype_str = "r";
break;
case REGISTER_TYPE_INPUT:
regtype_str = "v";
break;
case REGISTER_TYPE_CONST:
case REGISTER_TYPE_CONST2:
case REGISTER_TYPE_CONST3:
case REGISTER_TYPE_CONST4:
regtype_str = "c";
break;
case REGISTER_TYPE_ADDR: // (or REGISTER_TYPE_TEXTURE, same value.)
regtype_str = (ctx->shader_type == SHADER_TYPE_VERTEX) ? "a" : "t";
break;
case REGISTER_TYPE_RASTOUT:
switch ((D3D2GLSL_rastoutType) arg->regnum)
{
case RASTOUT_TYPE_POSITION: regtype_str = "oPos"; break;
case RASTOUT_TYPE_FOG: regtype_str = "oFog"; break;
case RASTOUT_TYPE_POINT_SIZE: regtype_str = "oPts"; break;
} // switch
regnum_str[0] = '\0'; // no number for this register type.
break;
case REGISTER_TYPE_ATTROUT:
regtype_str = "oD";
break;
case REGISTER_TYPE_TEXCRDOUT: // (or REGISTER_TYPE_OUTPUT, same value.)
if ((ctx->shader_type==SHADER_TYPE_VERTEX) && (ctx->major_ver>=3))
regtype_str = "o";
else
regtype_str = "oT";
break;
case REGISTER_TYPE_CONSTINT:
regtype_str = "i";
break;
case REGISTER_TYPE_COLOROUT:
regtype_str = "oC";
break;
case REGISTER_TYPE_DEPTHOUT:
regtype_str = "oDepth";
regnum_str[0] = '\0'; // no number for this register type.
break;
case REGISTER_TYPE_SAMPLER:
regtype_str = "s";
break;
case REGISTER_TYPE_CONSTBOOL:
regtype_str = "b";
break;
case REGISTER_TYPE_LOOP:
regtype_str = "aL";
regnum_str[0] = '\0'; // no number for this register type.
break;
// !!! FIXME: don't know what the asm string is for this..
// case REGISTER_TYPE_TEMPFLOAT16:
case REGISTER_TYPE_MISCTYPE:
switch ((D3D2GLSL_misctypeType) arg->regnum)
{
case MISCTYPE_TYPE_POSITION: regtype_str = "vPos"; break;
case MISCTYPE_TYPE_FACE: regtype_str = "vFace"; break;
} // switch
regnum_str[0] = '\0'; // no number for this register type.
break;
case REGISTER_TYPE_LABEL:
regtype_str = "l";
break;
case REGISTER_TYPE_PREDICATE:
regtype_str = "p";
break;
} // switch
if (regtype_str == NULL)
{
fail(ctx, "Unknown destination register type.");
return "";
} // if
const char *dot_str = (arg->writemask != 0) ? "." : "";
const char *x_str = (arg->writemask0 != 0) ? "x" : "";
const char *y_str = (arg->writemask1 != 0) ? "y" : "";
const char *z_str = (arg->writemask2 != 0) ? "z" : "";
const char *w_str = (arg->writemask3 != 0) ? "w" : "";
// may turn out something like "_x2_sat_pp_centroid r0.xyzw" ...
char *retval = get_scratch_buffer(ctx);
snprintf(retval, D3D2GLSL_SCRATCH_BUFFER_SIZE, "%s%s%s%s %s%s%s%s%s%s",
result_shift_str, sat_str, pp_str, cent_str,
regtype_str, regnum_str, dot_str, x_str, y_str, z_str, w_str);
491
492
return retval;
493
} // make_D3D_destarg_string
494
495
496
static char *make_D3D_sourcearg_string(Context *ctx, const int idx)
497
{
498
499
500
if (idx >= STATICARRAYLEN(ctx->source_args))
{
fail(ctx, "Too many source args");
501
return "";
502
} // if
503
504
char *retval = get_scratch_buffer(ctx);
505
506
507
strcpy(retval, "SRC"); // !!! FIXME
return retval;
508
} // make_D3D_sourcearg_string
509
510
511
static void emit_D3D_start(Context *ctx)
512
513
514
{
const uint major = (uint) ctx->major_ver;
const uint minor = (uint) ctx->minor_ver;
515
516
517
518
if (ctx->shader_type == SHADER_TYPE_PIXEL)
output_line(ctx, "ps_%u_%u", major, minor);
else if (ctx->shader_type == SHADER_TYPE_VERTEX)
519
520
521
522
523
524
525
526
527
{
char minorstr[16];
if (minor == 0xFF)
strcpy(minorstr, "sw");
else
snprintf(minorstr, sizeof (minorstr), "%u", (uint) minor);
output_line(ctx, "vs_%u_%s", major, minorstr);
} // else if
528
else
529
530
531
532
{
failf(ctx, "Shader type %u unsupported in this profile.",
(uint) ctx->shader_type);
} // else
533
534
} // emit_D3D_start
535
536
static void emit_D3D_end(Context *ctx)
537
538
539
{
output_line(ctx, "END");
} // emit_D3D_end
540
541
542
static void emit_D3D_comment(Context *ctx, const char *str)
543
{
544
545
output_line(ctx, "; %s", str);
} // emit_D3D_comment
546
547
548
static void emit_D3D_RESERVED(Context *ctx)
549
{
550
551
552
// do nothing; fails in the state machine.
} // emit_D3D_RESERVED
553
554
555
556
// Generic D3D opcode emitters. A list of macros generate all the entry points
// that call into these...
557
static void emit_D3D_opcode_d(Context *ctx, const char *opcode)
558
{
559
const char *dst0 = make_D3D_destarg_string(ctx, 0);
560
output_line(ctx, "%s%s", opcode, dst0);
561
562
563
} // emit_D3D_opcode_d
564
static void emit_D3D_opcode_s(Context *ctx, const char *opcode)
565
{
566
567
const char *src0 = make_D3D_destarg_string(ctx, 0);
output_line(ctx, "%s %s", opcode, src0);
568
569
570
} // emit_D3D_opcode_s
571
static void emit_D3D_opcode_ss(Context *ctx, const char *opcode)
572
{
573
574
575
const char *src0 = make_D3D_sourcearg_string(ctx, 0);
const char *src1 = make_D3D_sourcearg_string(ctx, 1);
output_line(ctx, "%s %s, %s", opcode, src0, src1);
576
577
578
} // emit_D3D_opcode_s
579
static void emit_D3D_opcode_ds(Context *ctx, const char *opcode)
580
{
581
582
const char *dst0 = make_D3D_destarg_string(ctx, 0);
const char *src0 = make_D3D_sourcearg_string(ctx, 0);
583
output_line(ctx, "%s%s, %s", opcode, dst0, src0);
584
585
586
} // emit_D3D_opcode_ds
587
static void emit_D3D_opcode_dss(Context *ctx, const char *opcode)
588
{
589
590
591
const char *dst0 = make_D3D_destarg_string(ctx, 0);
const char *src0 = make_D3D_sourcearg_string(ctx, 0);
const char *src1 = make_D3D_sourcearg_string(ctx, 1);
592
output_line(ctx, "%s%s, %s, %s", opcode, dst0, src0, src1);
593
594
595
} // emit_D3D_opcode_dss
596
static void emit_D3D_opcode_dsss(Context *ctx, const char *opcode)
597
{
598
599
600
601
const char *dst0 = make_D3D_destarg_string(ctx, 0);
const char *src0 = make_D3D_sourcearg_string(ctx, 0);
const char *src1 = make_D3D_sourcearg_string(ctx, 1);
const char *src2 = make_D3D_sourcearg_string(ctx, 2);
602
output_line(ctx, "%s%s, %s, %s, %s", opcode, dst0, src0, src1, src2);
603
604
605
} // emit_D3D_opcode_dsss
606
static void emit_D3D_opcode_dssss(Context *ctx, const char *opcode)
607
{
608
609
610
611
612
const char *dst0 = make_D3D_destarg_string(ctx, 0);
const char *src0 = make_D3D_sourcearg_string(ctx, 0);
const char *src1 = make_D3D_sourcearg_string(ctx, 1);
const char *src2 = make_D3D_sourcearg_string(ctx, 2);
const char *src3 = make_D3D_sourcearg_string(ctx, 3);
613
output_line(ctx,"%s%s, %s, %s, %s, %s",opcode,dst0,src0,src1,src2,src3);
614
615
616
617
} // emit_D3D_opcode_dssss
#define EMIT_D3D_OPCODE_FUNC(op) \
618
static void emit_D3D_##op(Context *ctx) { \
619
620
621
output_line(ctx, #op); \
}
#define EMIT_D3D_OPCODE_D_FUNC(op) \
622
static void emit_D3D_##op(Context *ctx) { \
623
624
625
emit_D3D_opcode_d(ctx, #op); \
}
#define EMIT_D3D_OPCODE_S_FUNC(op) \
626
static void emit_D3D_##op(Context *ctx) { \
627
628
629
emit_D3D_opcode_s(ctx, #op); \
}
#define EMIT_D3D_OPCODE_SS_FUNC(op) \
630
static void emit_D3D_##op(Context *ctx) { \
631
632
633
emit_D3D_opcode_ss(ctx, #op); \
}
#define EMIT_D3D_OPCODE_DS_FUNC(op) \
634
static void emit_D3D_##op(Context *ctx) { \
635
636
637
emit_D3D_opcode_ds(ctx, #op); \
}
#define EMIT_D3D_OPCODE_DSS_FUNC(op) \
638
static void emit_D3D_##op(Context *ctx) { \
639
640
641
emit_D3D_opcode_dss(ctx, #op); \
}
#define EMIT_D3D_OPCODE_DSSS_FUNC(op) \
642
static void emit_D3D_##op(Context *ctx) { \
643
644
645
emit_D3D_opcode_dsss(ctx, #op); \
}
#define EMIT_D3D_OPCODE_DSSSS_FUNC(op) \
646
static void emit_D3D_##op(Context *ctx) { \
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
emit_D3D_opcode_dssss(ctx, #op); \
}
EMIT_D3D_OPCODE_FUNC(NOP)
EMIT_D3D_OPCODE_DS_FUNC(MOV)
EMIT_D3D_OPCODE_DSS_FUNC(ADD)
EMIT_D3D_OPCODE_DSS_FUNC(SUB)
EMIT_D3D_OPCODE_DSSS_FUNC(MAD)
EMIT_D3D_OPCODE_DSS_FUNC(MUL)
EMIT_D3D_OPCODE_DS_FUNC(RCP)
EMIT_D3D_OPCODE_DS_FUNC(RSQ)
EMIT_D3D_OPCODE_DSS_FUNC(DP3)
EMIT_D3D_OPCODE_DSS_FUNC(DP4)
EMIT_D3D_OPCODE_DSS_FUNC(MIN)
EMIT_D3D_OPCODE_DSS_FUNC(MAX)
EMIT_D3D_OPCODE_DSS_FUNC(SLT)
EMIT_D3D_OPCODE_DSS_FUNC(SGE)
EMIT_D3D_OPCODE_DS_FUNC(EXP)
EMIT_D3D_OPCODE_DS_FUNC(LOG)
EMIT_D3D_OPCODE_DS_FUNC(LIT)
EMIT_D3D_OPCODE_DSS_FUNC(DST)
EMIT_D3D_OPCODE_DSSS_FUNC(LRP)
EMIT_D3D_OPCODE_DS_FUNC(FRC)
EMIT_D3D_OPCODE_DSS_FUNC(M4X4)
EMIT_D3D_OPCODE_DSS_FUNC(M4X3)
EMIT_D3D_OPCODE_DSS_FUNC(M3X4)
EMIT_D3D_OPCODE_DSS_FUNC(M3X3)
EMIT_D3D_OPCODE_DSS_FUNC(M3X2)
EMIT_D3D_OPCODE_S_FUNC(CALL)
EMIT_D3D_OPCODE_SS_FUNC(CALLNZ)
677
EMIT_D3D_OPCODE_SS_FUNC(LOOP)
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
EMIT_D3D_OPCODE_FUNC(RET)
EMIT_D3D_OPCODE_FUNC(ENDLOOP)
EMIT_D3D_OPCODE_S_FUNC(LABEL)
EMIT_D3D_OPCODE_FUNC(DCL) // !!! FIXME!
EMIT_D3D_OPCODE_DSS_FUNC(POW)
EMIT_D3D_OPCODE_DSS_FUNC(CRS)
EMIT_D3D_OPCODE_DSSS_FUNC(SGN)
EMIT_D3D_OPCODE_DS_FUNC(ABS)
EMIT_D3D_OPCODE_DS_FUNC(NRM)
EMIT_D3D_OPCODE_DS_FUNC(SINCOS)
EMIT_D3D_OPCODE_S_FUNC(REP)
EMIT_D3D_OPCODE_FUNC(ENDREP)
EMIT_D3D_OPCODE_S_FUNC(IF)
EMIT_D3D_OPCODE_SS_FUNC(IFC)
EMIT_D3D_OPCODE_FUNC(ELSE)
EMIT_D3D_OPCODE_FUNC(ENDIF)
EMIT_D3D_OPCODE_FUNC(BREAK)
EMIT_D3D_OPCODE_SS_FUNC(BREAKC)
EMIT_D3D_OPCODE_DS_FUNC(MOVA)
EMIT_D3D_OPCODE_FUNC(DEFB) // !!! FIXME!
EMIT_D3D_OPCODE_FUNC(DEFI) // !!! FIXME!
EMIT_D3D_OPCODE_FUNC(TEXCOORD) // !!! FIXME!
EMIT_D3D_OPCODE_D_FUNC(TEXKILL)
EMIT_D3D_OPCODE_FUNC(TEX) // !!! FIXME!
EMIT_D3D_OPCODE_DS_FUNC(TEXBEM)
EMIT_D3D_OPCODE_DS_FUNC(TEXBEML)
EMIT_D3D_OPCODE_DS_FUNC(TEXREG2AR)
EMIT_D3D_OPCODE_DS_FUNC(TEXREG2GB)
EMIT_D3D_OPCODE_DS_FUNC(TEXM3X2PAD)
EMIT_D3D_OPCODE_DS_FUNC(TEXM3X2TEX)
EMIT_D3D_OPCODE_DS_FUNC(TEXM3X3PAD)
EMIT_D3D_OPCODE_DS_FUNC(TEXM3X3TEX)
EMIT_D3D_OPCODE_DSS_FUNC(TEXM3X3SPEC)
EMIT_D3D_OPCODE_DS_FUNC(TEXM3X3VSPEC)
EMIT_D3D_OPCODE_DS_FUNC(EXPP)
EMIT_D3D_OPCODE_DS_FUNC(LOGP)
EMIT_D3D_OPCODE_DSSS_FUNC(CND)
EMIT_D3D_OPCODE_FUNC(DEF) // !!! FIXME!
EMIT_D3D_OPCODE_DS_FUNC(TEXREG2RGB)
EMIT_D3D_OPCODE_DS_FUNC(TEXDP3TEX)
EMIT_D3D_OPCODE_DS_FUNC(TEXM3X2DEPTH)
EMIT_D3D_OPCODE_DS_FUNC(TEXDP3)
EMIT_D3D_OPCODE_DS_FUNC(TEXM3X3)
EMIT_D3D_OPCODE_D_FUNC(TEXDEPTH)
EMIT_D3D_OPCODE_DSSS_FUNC(CMP)
EMIT_D3D_OPCODE_DSS_FUNC(BEM)
EMIT_D3D_OPCODE_DSSS_FUNC(DP2ADD)
EMIT_D3D_OPCODE_DS_FUNC(DSX)
EMIT_D3D_OPCODE_DS_FUNC(DSY)
EMIT_D3D_OPCODE_DSSSS_FUNC(TEXLDD)
EMIT_D3D_OPCODE_DSS_FUNC(SETP)
EMIT_D3D_OPCODE_DSS_FUNC(TEXLDL)
730
EMIT_D3D_OPCODE_S_FUNC(BREAKP)
731
732
733
734
735
736
737
738
739
740
#undef EMIT_D3D_OPCODE_FUNC
#undef EMIT_D3D_OPCODE_D_FUNC
#undef EMIT_D3D_OPCODE_S_FUNC
#undef EMIT_D3D_OPCODE_SS_FUNC
#undef EMIT_D3D_OPCODE_DS_FUNC
#undef EMIT_D3D_OPCODE_DSS_FUNC
#undef EMIT_D3D_OPCODE_DSSS_FUNC
#undef EMIT_D3D_OPCODE_DSSSS_FUNC
741
742
743
744
745
#endif // SUPPORT_PROFILE_D3D
#if !SUPPORT_PROFILE_GLSL
746
#define PROFILE_EMITTER_GLSL(op)
747
748
749
#else
#undef AT_LEAST_ONE_PROFILE
#define AT_LEAST_ONE_PROFILE 1
750
751
#define PROFILE_EMITTER_GLSL(op) emit_GLSL_##op,
752
static void emit_GLSL_start(Context *ctx)
753
{
754
755
756
757
758
759
760
761
762
763
764
765
const uint major = (uint) ctx->major_ver;
const uint minor = (uint) ctx->minor_ver;
if (ctx->shader_type == SHADER_TYPE_PIXEL)
output_line(ctx, "// Pixel shader, version %u.%u", major, minor);
else if (ctx->shader_type == SHADER_TYPE_VERTEX)
output_line(ctx, "// Vertex shader, version %u.%u", major, minor);
else
{
failf(ctx, "Shader type %u unsupported in this profile.",
(uint) ctx->shader_type);
} // else
766
767
768
output_line(ctx, "void main() {");
} // emit_GLSL_start
769
static void emit_GLSL_end(Context *ctx)
770
771
772
{
output_line(ctx, "}");
} // emit_GLSL_end
773
774
static void emit_GLSL_comment(Context *ctx, const char *str)
775
776
777
778
{
output_line(ctx, "// %s", str);
} // emit_GLSL_comment
779
static void emit_GLSL_NOP(Context *ctx)
780
781
782
783
{
// no-op is a no-op. :)
} // emit_GLSL_NOP
784
static void emit_GLSL_MOV(Context *ctx)
785
786
787
788
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_MOV
789
static void emit_GLSL_ADD(Context *ctx)
790
791
792
793
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_ADD
794
static void emit_GLSL_SUB(Context *ctx)
795
796
797
798
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_SUB
799
static void emit_GLSL_MAD(Context *ctx)
800
801
802
803
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_MAD
804
static void emit_GLSL_MUL(Context *ctx)
805
806
807
808
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_MUL
809
static void emit_GLSL_RCP(Context *ctx)
810
811
812
813
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_RCP
814
static void emit_GLSL_RSQ(Context *ctx)
815
816
817
818
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_RSQ
819
static void emit_GLSL_DP3(Context *ctx)
820
821
822
823
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_DP3
824
static void emit_GLSL_DP4(Context *ctx)
825
826
827
828
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_DP4
829
static void emit_GLSL_MIN(Context *ctx)
830
831
832
833
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_MIN
834
static void emit_GLSL_MAX(Context *ctx)
835
836
837
838
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_MAX
839
static void emit_GLSL_SLT(Context *ctx)
840
841
842
843
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_SLT
844
static void emit_GLSL_SGE(Context *ctx)
845
846
847
848
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_SGE
849
static void emit_GLSL_EXP(Context *ctx)
850
851
852
853
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_EXP
854
static void emit_GLSL_LOG(Context *ctx)
855
856
857
858
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_LOG
859
static void emit_GLSL_LIT(Context *ctx)
860
861
862
863
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_LIT
864
static void emit_GLSL_DST(Context *ctx)
865
866
867
868
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_DST
869
static void emit_GLSL_LRP(Context *ctx)
870
871
872
873
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_LRP
874
static void emit_GLSL_FRC(Context *ctx)
875
876
877
878
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_FRC
879
static void emit_GLSL_M4X4(Context *ctx)
880
881
882
883
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_M4X4
884
static void emit_GLSL_M4X3(Context *ctx)
885
886
887
888
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_M4X3
889
static void emit_GLSL_M3X4(Context *ctx)
890
891
892
893
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_M3X4
894
static void emit_GLSL_M3X3(Context *ctx)
895
896
897
898
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_M3X3
899
static void emit_GLSL_M3X2(Context *ctx)
900
901
902
903
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_M3X2
904
static void emit_GLSL_CALL(Context *ctx)
905
906
907
908
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_CALL
909
static void emit_GLSL_CALLNZ(Context *ctx)
910
911
912
913
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_CALLNZ
914
static void emit_GLSL_LOOP(Context *ctx)
915
916
917
918
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_LOOP
919
static void emit_GLSL_RET(Context *ctx)
920
921
922
923
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_RET
924
static void emit_GLSL_ENDLOOP(Context *ctx)
925
926
927
928
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_ENDLOOP
929
static void emit_GLSL_LABEL(Context *ctx)
930
931
932
933
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_LABEL
934
static void emit_GLSL_DCL(Context *ctx)
935
936
937
938
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_DCL
939
static void emit_GLSL_POW(Context *ctx)
940
941
942
943
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_POW
944
static void emit_GLSL_CRS(Context *ctx)
945
946
947
948
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_CRS
949
static void emit_GLSL_SGN(Context *ctx)
950
951
952
953
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_SGN
954
static void emit_GLSL_ABS(Context *ctx)
955
956
957
958
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_ABS
959
static void emit_GLSL_NRM(Context *ctx)
960
961
962
963
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_NRM
964
static void emit_GLSL_SINCOS(Context *ctx)
965
966
967
968
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_SINCOS
969
static void emit_GLSL_REP(Context *ctx)
970
971
972
973
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_REP
974
static void emit_GLSL_ENDREP(Context *ctx)
975
976
977
978
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_ENDREP
979
static void emit_GLSL_IF(Context *ctx)
980
981
982
983
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_IF
984
static void emit_GLSL_IFC(Context *ctx)
985
986
987
988
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_IFC
989
static void emit_GLSL_ELSE(Context *ctx)
990
991
992
993
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_ELSE
994
static void emit_GLSL_ENDIF(Context *ctx)
995
996
997
998
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_ENDIF
999
static void emit_GLSL_BREAK(Context *ctx)
1000
{