/
d3d2glsl.c
2041 lines (1671 loc) · 56.7 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
#include <assert.h>
21
22
#include "d3d2glsl.h"
23
24
25
26
27
// This is the highest shader version we currently support.
#define MAX_SHADER_MAJOR 3
#define MAX_SHADER_MINOR 0
28
29
30
// You get all the profiles unless you go out of your way to disable them.
31
32
33
34
35
36
37
38
#ifndef SUPPORT_PROFILE_D3D
#define SUPPORT_PROFILE_D3D 1
#endif
#ifndef SUPPORT_PROFILE_GLSL
#define SUPPORT_PROFILE_GLSL 1
#endif
39
40
41
42
43
44
45
// 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;
46
47
48
49
50
51
#ifdef __GNUC__
#define ISPRINTF(x,y) __attribute__((format (printf, x, y)))
#else
#define ISPRINTF(x,y)
#endif
52
53
#define STATICARRAYLEN(x) ( (sizeof ((x))) / (sizeof ((x)[0])) )
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// 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
74
75
76
77
78
79
80
81
82
83
// 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))
84
// predeclare.
85
typedef struct Context Context;
86
87
// one emit function for each opcode in each profile.
88
typedef void (*emit_function)(Context *ctx);
89
90
// one emit function for comments in each profile.
91
typedef void (*emit_comment)(Context *ctx, const char *str);
92
93
// one emit function for starting output in each profile.
94
typedef void (*emit_start)(Context *ctx);
95
96
// one emit function for ending output in each profile.
97
typedef void (*emit_end)(Context *ctx);
99
100
101
// one args function for each possible sequence of opcode arguments.
typedef int (*args_function)(Context *ctx);
102
// one state function for each opcode where we have state machine updates.
103
typedef int (*state_function)(Context *ctx);
104
105
106
107
108
109
110
111
112
typedef struct
{
const char *name;
emit_start start_emitter;
emit_end end_emitter;
emit_comment comment_emitter;
} D3D2GLSL_profile;
114
115
116
117
118
119
120
121
typedef enum
{
SHADER_TYPE_UNKNOWN = -1,
SHADER_TYPE_PIXEL,
SHADER_TYPE_VERTEX,
SHADER_TYPE_TOTAL
} D3D2GLSL_shaderType;
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
163
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;
165
166
167
168
169
170
171
172
173
// 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;
175
176
177
178
179
// result modifiers.
#define MOD_SATURATE 0x01
#define MOD_PP 0x02
#define MOD_CENTROID 0x04
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// source modifiers.
typedef enum
{
SRCMOD_NONE,
SRCMOD_NEGATE,
SRCMOD_BIAS,
SRCMOD_BIASNEGATE,
SRCMOD_SIGN,
SRCMOD_SIGNNEGATE,
SRCMOD_COMPLEMENT,
SRCMOD_X2,
SRCMOD_X2NEGATE,
SRCMOD_DZ,
SRCMOD_DW,
SRCMOD_ABS,
SRCMOD_ABSNEGATE,
SRCMOD_NOT,
SRCMOD_TOTAL
} D3D2GLSL_sourceMod;
201
202
typedef struct
{
203
const uint32 *token; // this is the unmolested token in the stream.
204
205
int regnum;
int relative;
206
207
208
209
210
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
211
212
213
214
215
216
217
int result_mod;
int result_shift;
int regtype;
} DestArgInfo;
typedef struct
{
218
const uint32 *token; // this is the unmolested token in the stream.
219
220
int regnum;
int relative;
221
int swizzle; // xyzw (all four, not split out).
222
223
224
225
226
227
228
229
230
int swizzle_x;
int swizzle_y;
int swizzle_z;
int swizzle_w;
int src_mod;
int regtype;
} SourceArgInfo;
231
#define D3D2GLSL_SCRATCH_BUFFER_SIZE 256
232
#define D3D2GLSL_SCRATCH_BUFFERS 10
234
// Context...this is state that changes as we parse through a shader...
237
238
D3D2GLSL_malloc malloc;
D3D2GLSL_free free;
239
240
const uint32 *tokens;
uint32 tokencount;
241
242
243
244
245
246
247
248
249
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;
250
const D3D2GLSL_profile *profile;
251
252
253
D3D2GLSL_shaderType shader_type;
uint32 major_ver;
uint32 minor_ver;
254
255
DestArgInfo dest_args[1];
SourceArgInfo source_args[4];
256
uint32 instruction_count;
257
uint32 instruction_controls;
258
259
260
};
261
static inline char *get_scratch_buffer(Context *ctx)
263
264
ctx->scratchidx = (ctx->scratchidx + 1) % D3D2GLSL_SCRATCH_BUFFERS;
return ctx->scratch[ctx->scratchidx];
265
266
} // get_scratch_buffer
268
269
// Special-case return values from the parsing pipeline...
#define FAIL (-1)
270
#define END_OF_STREAM (-2)
272
273
274
275
276
277
278
279
280
281
282
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, ...)
284
285
if (ctx->failstr == NULL) // don't change existing error.
{
286
char *scratch = get_scratch_buffer(ctx);
287
288
va_list ap;
va_start(ap, fmt);
289
const int len = vsnprintf(scratch,D3D2GLSL_SCRATCH_BUFFER_SIZE,fmt,ap);
290
291
va_end(ap);
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
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
308
309
310
311
312
313
} // if
return FAIL;
} // failf
314
static inline int fail(Context *ctx, const char *reason)
315
316
317
318
319
{
return failf(ctx, "%s", reason);
} // fail
320
321
static int output_line(Context *ctx, const char *fmt, ...) ISPRINTF(2,3);
static int output_line(Context *ctx, const char *fmt, ...)
322
323
324
325
{
if (ctx->failstr != NULL)
return FAIL; // we failed previously, don't go on...
326
327
328
329
330
OutputList *item = (OutputList *) ctx->malloc(sizeof (OutputList));
if (item == NULL)
return out_of_memory(ctx);
char *scratch = get_scratch_buffer(ctx);
331
332
va_list ap;
va_start(ap, fmt);
333
const int len = vsnprintf(scratch, D3D2GLSL_SCRATCH_BUFFER_SIZE, fmt, ap);
334
335
va_end(ap);
336
337
item->str = (char *) ctx->malloc(len + 1);
if (item->str == NULL)
339
340
free(item);
return out_of_memory(ctx);
341
342
} // if
343
344
345
346
347
348
349
350
351
352
353
// 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
355
356
357
358
item->next = NULL;
ctx->output_tail->next = item;
ctx->output_tail = item;
ctx->output_len += len + ctx->endline_len;
359
360
361
362
return 0;
} // output_line
364
// if SUPPORT_PROFILE_* isn't defined, we assume an implicit desire to support.
365
366
367
368
369
370
371
372
373
#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,
374
375
376
377
static const char *get_D3D_register_string(Context *ctx,
D3D2GLSL_registerType regtype,
int regnum, char *regnum_str,
size_t regnum_size)
379
const char *retval = NULL;
381
snprintf(regnum_str, regnum_size, "%u", (uint) regnum);
383
switch (regtype)
384
385
{
case REGISTER_TYPE_TEMP:
386
retval = "r";
387
388
389
break;
case REGISTER_TYPE_INPUT:
390
retval = "v";
391
392
393
394
395
396
break;
case REGISTER_TYPE_CONST:
case REGISTER_TYPE_CONST2:
case REGISTER_TYPE_CONST3:
case REGISTER_TYPE_CONST4:
397
retval = "c";
398
399
400
break;
case REGISTER_TYPE_ADDR: // (or REGISTER_TYPE_TEXTURE, same value.)
401
retval = (ctx->shader_type == SHADER_TYPE_VERTEX) ? "a" : "t";
402
403
404
break;
case REGISTER_TYPE_RASTOUT:
405
switch ((D3D2GLSL_rastoutType) regnum)
407
408
409
case RASTOUT_TYPE_POSITION: retval = "oPos"; break;
case RASTOUT_TYPE_FOG: retval = "oFog"; break;
case RASTOUT_TYPE_POINT_SIZE: retval = "oPts"; break;
410
411
412
413
414
} // switch
regnum_str[0] = '\0'; // no number for this register type.
break;
case REGISTER_TYPE_ATTROUT:
415
retval = "oD";
416
417
418
419
break;
case REGISTER_TYPE_TEXCRDOUT: // (or REGISTER_TYPE_OUTPUT, same value.)
if ((ctx->shader_type==SHADER_TYPE_VERTEX) && (ctx->major_ver>=3))
420
retval = "o";
422
retval = "oT";
423
424
425
break;
case REGISTER_TYPE_CONSTINT:
426
retval = "i";
427
428
429
break;
case REGISTER_TYPE_COLOROUT:
430
retval = "oC";
431
432
433
break;
case REGISTER_TYPE_DEPTHOUT:
434
retval = "oDepth";
435
436
437
438
regnum_str[0] = '\0'; // no number for this register type.
break;
case REGISTER_TYPE_SAMPLER:
439
retval = "s";
440
441
442
break;
case REGISTER_TYPE_CONSTBOOL:
443
retval = "b";
444
445
446
break;
case REGISTER_TYPE_LOOP:
447
retval = "aL";
448
449
450
451
452
453
454
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:
455
switch ((D3D2GLSL_misctypeType) regnum)
457
458
case MISCTYPE_TYPE_POSITION: retval = "vPos"; break;
case MISCTYPE_TYPE_FACE: retval = "vFace"; break;
459
460
461
462
463
} // switch
regnum_str[0] = '\0'; // no number for this register type.
break;
case REGISTER_TYPE_LABEL:
464
retval = "l";
465
466
467
break;
case REGISTER_TYPE_PREDICATE:
468
retval = "p";
469
470
471
break;
} // switch
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
return retval;
} // get_D3D_register_string
static char *make_D3D_destarg_string(Context *ctx, const int idx)
{
if (idx >= STATICARRAYLEN(ctx->dest_args))
{
fail(ctx, "Too many destination args");
return "";
} // if
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];
const char *regtype_str = get_D3D_register_string(ctx,
(D3D2GLSL_registerType) arg->regtype,
arg->regnum, regnum_str,
sizeof (regnum_str));
506
507
508
509
510
511
if (regtype_str == NULL)
{
fail(ctx, "Unknown destination register type.");
return "";
} // if
512
513
514
515
516
517
518
519
520
521
522
523
char writemask_str[6];
int i = 0;
if (arg->writemask != 0xF) // 0xF == 1111. No explicit mask.
{
writemask_str[i++] = '.';
if (arg->writemask0) writemask_str[i++] = 'x';
if (arg->writemask1) writemask_str[i++] = 'y';
if (arg->writemask2) writemask_str[i++] = 'z';
if (arg->writemask3) writemask_str[i++] = 'w';
} // if
writemask_str[i] = '\0';
assert(i < sizeof (writemask_str));
524
525
526
// may turn out something like "_x2_sat_pp_centroid r0.xyzw" ...
char *retval = get_scratch_buffer(ctx);
527
snprintf(retval, D3D2GLSL_SCRATCH_BUFFER_SIZE, "%s%s%s%s %s%s%s",
528
result_shift_str, sat_str, pp_str, cent_str,
529
regtype_str, regnum_str, writemask_str);
530
return retval;
531
} // make_D3D_destarg_string
534
static char *make_D3D_sourcearg_string(Context *ctx, const int idx)
536
537
538
if (idx >= STATICARRAYLEN(ctx->source_args))
{
fail(ctx, "Too many source args");
539
return "";
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
const SourceArgInfo *arg = &ctx->source_args[idx];
const char *premod_str = "";
const char *postmod_str = "";
switch ((D3D2GLSL_sourceMod) arg->src_mod)
{
case SRCMOD_NEGATE:
premod_str = "-";
break;
case SRCMOD_BIASNEGATE:
premod_str = "-";
// fall through.
case SRCMOD_BIAS:
postmod_str = "_bias";
break;
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
case SRCMOD_SIGNNEGATE:
premod_str = "-";
// fall through.
case SRCMOD_SIGN:
postmod_str = "_bx2";
break;
case SRCMOD_COMPLEMENT:
premod_str = "1-";
break;
case SRCMOD_X2NEGATE:
premod_str = "-";
// fall through.
case SRCMOD_X2:
postmod_str = "_x2";
break;
case SRCMOD_DZ:
postmod_str = "_dz";
break;
case SRCMOD_DW:
postmod_str = "_dw";
break;
case SRCMOD_ABSNEGATE:
premod_str = "-";
// fall through.
case SRCMOD_ABS:
postmod_str = "_abs";
break;
case SRCMOD_NOT:
premod_str = "!";
break;
} // switch
char regnum_str[16];
const char *regtype_str = get_D3D_register_string(ctx,
(D3D2GLSL_registerType) arg->regtype,
arg->regnum, regnum_str,
sizeof (regnum_str));
if (regtype_str == NULL)
{
fail(ctx, "Unknown source register type.");
return "";
} // if
char swizzle_str[6];
int i = 0;
612
if (arg->swizzle != 0xE4) // 0xE4 == 11100100 ... 3 2 1 0. No swizzle.
613
614
615
{
static const char channel[] = { 'x', 'y', 'z', 'w' };
swizzle_str[i++] = '.';
616
617
618
619
620
621
622
623
swizzle_str[i++] = channel[arg->swizzle_x];
swizzle_str[i++] = channel[arg->swizzle_y];
swizzle_str[i++] = channel[arg->swizzle_z];
swizzle_str[i++] = channel[arg->swizzle_w];
// .xyzz is the same as .xyz, .z is the same as .zzzz, etc.
while (swizzle_str[i-1] == swizzle_str[i-2])
i--;
624
625
626
627
628
629
630
} // if
swizzle_str[i] = '\0';
assert(i < sizeof (swizzle_str));
char *retval = get_scratch_buffer(ctx);
snprintf(retval, D3D2GLSL_SCRATCH_BUFFER_SIZE, "%s%s%s%s",
premod_str, regtype_str, postmod_str, swizzle_str);
631
return retval;
632
} // make_D3D_sourcearg_string
635
static void emit_D3D_start(Context *ctx)
636
637
638
{
const uint major = (uint) ctx->major_ver;
const uint minor = (uint) ctx->minor_ver;
639
640
641
642
643
644
645
646
647
const char *shadertype_str = NULL;
char minor_str[16];
if (minor == 0xFF)
strcpy(minor_str, "sw");
else if (minor == 0x1) // apparently this is "vs_2_x". Weird.
strcpy(minor_str, "x");
else
snprintf(minor_str, sizeof (minor_str), "%u", (uint) minor);
649
if (ctx->shader_type == SHADER_TYPE_PIXEL)
650
shadertype_str = "ps";
651
else if (ctx->shader_type == SHADER_TYPE_VERTEX)
652
shadertype_str = "vs";
654
655
656
{
failf(ctx, "Shader type %u unsupported in this profile.",
(uint) ctx->shader_type);
658
} // else
659
660
output_line(ctx, "%s_%u_%s", shadertype_str, major, minor_str);
661
662
} // emit_D3D_start
664
static void emit_D3D_end(Context *ctx)
665
666
667
{
output_line(ctx, "END");
} // emit_D3D_end
670
static void emit_D3D_comment(Context *ctx, const char *str)
672
673
output_line(ctx, "; %s", str);
} // emit_D3D_comment
676
static void emit_D3D_RESERVED(Context *ctx)
678
679
680
// do nothing; fails in the state machine.
} // emit_D3D_RESERVED
681
682
683
684
// Generic D3D opcode emitters. A list of macros generate all the entry points
// that call into these...
685
static void emit_D3D_opcode_d(Context *ctx, const char *opcode)
687
const char *dst0 = make_D3D_destarg_string(ctx, 0);
688
output_line(ctx, "%s%s", opcode, dst0);
689
690
691
} // emit_D3D_opcode_d
692
static void emit_D3D_opcode_s(Context *ctx, const char *opcode)
694
695
const char *src0 = make_D3D_destarg_string(ctx, 0);
output_line(ctx, "%s %s", opcode, src0);
696
697
698
} // emit_D3D_opcode_s
699
static void emit_D3D_opcode_ss(Context *ctx, const char *opcode)
701
702
703
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);
704
705
706
} // emit_D3D_opcode_s
707
static void emit_D3D_opcode_ds(Context *ctx, const char *opcode)
709
710
const char *dst0 = make_D3D_destarg_string(ctx, 0);
const char *src0 = make_D3D_sourcearg_string(ctx, 0);
711
output_line(ctx, "%s%s, %s", opcode, dst0, src0);
712
713
714
} // emit_D3D_opcode_ds
715
static void emit_D3D_opcode_dss(Context *ctx, const char *opcode)
717
718
719
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);
720
output_line(ctx, "%s%s, %s, %s", opcode, dst0, src0, src1);
721
722
723
} // emit_D3D_opcode_dss
724
static void emit_D3D_opcode_dsss(Context *ctx, const char *opcode)
726
727
728
729
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);
730
output_line(ctx, "%s%s, %s, %s, %s", opcode, dst0, src0, src1, src2);
731
732
733
} // emit_D3D_opcode_dsss
734
static void emit_D3D_opcode_dssss(Context *ctx, const char *opcode)
736
737
738
739
740
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);
741
output_line(ctx,"%s%s, %s, %s, %s, %s",opcode,dst0,src0,src1,src2,src3);
742
743
744
745
} // emit_D3D_opcode_dssss
#define EMIT_D3D_OPCODE_FUNC(op) \
746
static void emit_D3D_##op(Context *ctx) { \
747
748
749
output_line(ctx, #op); \
}
#define EMIT_D3D_OPCODE_D_FUNC(op) \
750
static void emit_D3D_##op(Context *ctx) { \
751
752
753
emit_D3D_opcode_d(ctx, #op); \
}
#define EMIT_D3D_OPCODE_S_FUNC(op) \
754
static void emit_D3D_##op(Context *ctx) { \
755
756
757
emit_D3D_opcode_s(ctx, #op); \
}
#define EMIT_D3D_OPCODE_SS_FUNC(op) \
758
static void emit_D3D_##op(Context *ctx) { \
759
760
761
emit_D3D_opcode_ss(ctx, #op); \
}
#define EMIT_D3D_OPCODE_DS_FUNC(op) \
762
static void emit_D3D_##op(Context *ctx) { \
763
764
765
emit_D3D_opcode_ds(ctx, #op); \
}
#define EMIT_D3D_OPCODE_DSS_FUNC(op) \
766
static void emit_D3D_##op(Context *ctx) { \
767
768
769
emit_D3D_opcode_dss(ctx, #op); \
}
#define EMIT_D3D_OPCODE_DSSS_FUNC(op) \
770
static void emit_D3D_##op(Context *ctx) { \
771
772
773
emit_D3D_opcode_dsss(ctx, #op); \
}
#define EMIT_D3D_OPCODE_DSSSS_FUNC(op) \
774
static void emit_D3D_##op(Context *ctx) { \
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
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)
805
EMIT_D3D_OPCODE_SS_FUNC(LOOP)
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
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_FUNC(ELSE)
EMIT_D3D_OPCODE_FUNC(ENDIF)
EMIT_D3D_OPCODE_FUNC(BREAK)
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(TEXLDL)
855
EMIT_D3D_OPCODE_S_FUNC(BREAKP)
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
// special cases for comparison opcodes...
static const char *get_D3D_comparison_string(Context *ctx)
{
static const char *comps[] = {
"", "_gt", "_eq", "_ge", "_lt", "_ne", "_le"
};
if (ctx->instruction_controls >= STATICARRAYLEN(comps))
{
fail(ctx, "unknown comparison control");
return "";
} // if
return comps[ctx->instruction_controls];
} // get_D3D_comparison_string
static void emit_D3D_BREAKC(Context *ctx)
{
char op[16];
876
snprintf(op, sizeof (op), "BREAK%s", get_D3D_comparison_string(ctx));
877
878
879
880
881
882
emit_D3D_opcode_ss(ctx, op);
} // emit_D3D_BREAKC
static void emit_D3D_IFC(Context *ctx)
{
char op[16];
883
snprintf(op, sizeof (op), "IF%s", get_D3D_comparison_string(ctx));
884
885
886
887
888
889
890
891
892
893
894
emit_D3D_opcode_ss(ctx, op);
} // emit_D3D_IFC
static void emit_D3D_SETP(Context *ctx)
{
char op[16];
snprintf(op, sizeof (op), "SETP%s", get_D3D_comparison_string(ctx));
emit_D3D_opcode_dss(ctx, op);
} // emit_D3D_SETP
895
896
897
898
899
900
901
902
903
#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
904
905
906
907
908
#endif // SUPPORT_PROFILE_D3D
#if !SUPPORT_PROFILE_GLSL
909
#define PROFILE_EMITTER_GLSL(op)
910
911
912
#else
#undef AT_LEAST_ONE_PROFILE
#define AT_LEAST_ONE_PROFILE 1
913
914
#define PROFILE_EMITTER_GLSL(op) emit_GLSL_##op,
915
static void emit_GLSL_start(Context *ctx)
917
918
919
920
921
922
923
924
925
926
927
928
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
929
930
931
output_line(ctx, "void main() {");
} // emit_GLSL_start
932
static void emit_GLSL_end(Context *ctx)
933
934
935
{
output_line(ctx, "}");
} // emit_GLSL_end
937
static void emit_GLSL_comment(Context *ctx, const char *str)
938
939
940
941
{
output_line(ctx, "// %s", str);
} // emit_GLSL_comment
942
static void emit_GLSL_NOP(Context *ctx)
943
944
945
946
{
// no-op is a no-op. :)
} // emit_GLSL_NOP
947
static void emit_GLSL_MOV(Context *ctx)
948
949
950
951
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_MOV
952
static void emit_GLSL_ADD(Context *ctx)
953
954
955
956
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_ADD
957
static void emit_GLSL_SUB(Context *ctx)
958
959
960
961
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_SUB
962
static void emit_GLSL_MAD(Context *ctx)
963
964
965
966
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_MAD
967
static void emit_GLSL_MUL(Context *ctx)
968
969
970
971
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_MUL
972
static void emit_GLSL_RCP(Context *ctx)
973
974
975
976
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_RCP
977
static void emit_GLSL_RSQ(Context *ctx)
978
979
980
981
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_RSQ
982
static void emit_GLSL_DP3(Context *ctx)
983
984
985
986
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_DP3
987
static void emit_GLSL_DP4(Context *ctx)
988
989
990
991
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_DP4
992
static void emit_GLSL_MIN(Context *ctx)
993
994
995
996
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_MIN
997
static void emit_GLSL_MAX(Context *ctx)
998
999
1000
{
fail(ctx, "unimplemented."); // !!! FIXME
} // emit_GLSL_MAX