/
mojoshader.h
326 lines (286 loc) · 10.3 KB
1
/**
2
3
* MojoShader; generate shader programs from bytecode of compiled
* Direct3D shaders.
4
5
6
7
8
9
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
10
11
#ifndef __INCL_MOJOSHADER_H_
#define __INCL_MOJOSHADER_H_
12
13
14
15
16
#ifdef __cplusplus
extern "C" {
#endif
17
/*
18
19
20
21
22
* For determining the version of MojoShader you are using:
* const int compiled_against = MOJOSHADER_VERSION;
* const int linked_against = MOJOSHADER_version();
*
* The version is a single integer that increments, not a major/minor value.
23
*/
24
25
#define MOJOSHADER_VERSION 1
int MOJOSHADER_version(void);
26
27
28
/*
* These allocators work just like the C runtime's malloc() and free()
29
30
* (in fact, they probably use malloc() and free() internally if you don't
* specify your own allocator, but don't rely on that behaviour).
31
32
33
* (data) is the pointer you supplied when specifying these allocator
* callbacks, in case you need instance-specific data...it is passed through
* to your allocator unmolested, and can be NULL if you like.
34
*/
35
36
typedef void *(*MOJOSHADER_malloc)(int bytes, void *data);
typedef void (*MOJOSHADER_free)(void *ptr, void *data);
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
* These are enum values, but they also can be used in bitmasks, so we can
* test if an opcode is acceptable: if (op->shader_types & ourtype) {} ...
*/
typedef enum
{
MOJOSHADER_TYPE_UNKNOWN = 0,
MOJOSHADER_TYPE_PIXEL = (1 << 0),
MOJOSHADER_TYPE_VERTEX = (1 << 1),
MOJOSHADER_TYPE_GEOMETRY = (1 << 2), /* (not supported yet.) */
MOJOSHADER_TYPE_ANY = 0xFFFFFFFF /* used for bitmasks */
} MOJOSHADER_shaderType;
52
53
54
/*
* Data types for uniforms. See MOJOSHADER_uniform for more information.
*/
55
56
typedef enum
{
57
58
59
MOJOSHADER_UNIFORM_FLOAT,
MOJOSHADER_UNIFORM_INT,
MOJOSHADER_UNIFORM_BOOL,
60
} MOJOSHADER_uniformType;
61
62
63
64
65
66
67
68
/*
* These are the uniforms to be set for a shader. "Uniforms" are what Direct3D
* calls "Constants" ... IDirect3DDevice::SetVertexShaderConstantF() would
* need this data, for example. These integers are register indexes. So if
* index==6 and type==MOJOSHADER_UNIFORM_FLOAT, that means we'd expect a
* 4-float vector to be specified for what would be register "c6" in D3D
* assembly language, before drawing with the shader.
69
70
* (name) is a profile-specific variable name; it may be NULL if it isn't
* applicable to the requested profile.
71
*/
72
73
typedef struct
{
74
MOJOSHADER_uniformType type;
75
int index;
76
const char *name;
77
78
} MOJOSHADER_uniform;
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
* Data types for samplers. See MOJOSHADER_sampler for more information.
*/
typedef enum
{
MOJOSHADER_SAMPLER_2D,
MOJOSHADER_SAMPLER_CUBE,
MOJOSHADER_SAMPLER_VOLUME,
} MOJOSHADER_samplerType;
/*
* These are the samplers to be set for a shader. ...
* IDirect3DDevice::SetTexture() would need this data, for example.
* These integers are the sampler "stage". So if index==6 and
* type==MOJOSHADER_SAMPLER_2D, that means we'd expect a regular 2D texture
* to be specified for what would be register "s6" in D3D assembly language,
* before drawing with the shader.
96
97
* (name) is a profile-specific variable name; it may be NULL if it isn't
* applicable to the requested profile.
98
99
100
101
102
*/
typedef struct
{
MOJOSHADER_samplerType type;
int index;
103
const char *name;
104
105
} MOJOSHADER_sampler;
106
107
108
109
110
/*
* Data types for attributes. See MOJOSHADER_attribute for more information.
*/
typedef enum
{
111
112
113
114
115
116
117
118
119
120
121
122
123
124
MOJOSHADER_USAGE_POSITION,
MOJOSHADER_USAGE_BLENDWEIGHT,
MOJOSHADER_USAGE_BLENDINDICES,
MOJOSHADER_USAGE_NORMAL,
MOJOSHADER_USAGE_POINTSIZE,
MOJOSHADER_USAGE_TEXCOORD,
MOJOSHADER_USAGE_TANGENT,
MOJOSHADER_USAGE_BINORMAL,
MOJOSHADER_USAGE_TESSFACTOR,
MOJOSHADER_USAGE_POSITIONT,
MOJOSHADER_USAGE_COLOR,
MOJOSHADER_USAGE_FOG,
MOJOSHADER_USAGE_DEPTH,
MOJOSHADER_USAGE_SAMPLE,
125
MOJOSHADER_USAGE_TOTAL, /* housekeeping value; not ever returned. */
126
127
128
129
130
131
132
133
134
135
} MOJOSHADER_usage;
/*
* These are the attributes to be set for a shader. "Attributes" are what
* Direct3D calls "Vertex Declarations Usages" ...
* IDirect3DDevice::CreateVertexDeclaration() would need this data, for
* example. Each attribute is associated with an array of data that uses one
* element per-vertex. So if usage==MOJOSHADER_USAGE_COLOR and index==1, that
* means we'd expect a secondary color array to be bound to this shader
* before drawing.
136
137
* (name) is a profile-specific variable name; it may be NULL if it isn't
* applicable to the requested profile.
138
139
140
141
142
*/
typedef struct
{
MOJOSHADER_usage usage;
int index;
143
const char *name;
144
} MOJOSHADER_attribute;
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
* Structure used to return data from parsing of a shader...
*/
typedef struct
{
/*
* Human-readable error, if there is one. Will be NULL if there was no
* error. The string will be UTF-8 encoded, and English only. Most of
* these shouldn't be shown to the end-user anyhow.
*/
const char *error;
158
159
160
161
162
/*
* The name of the profile used to parse the shader. Will be NULL on error.
*/
const char *profile;
163
164
165
166
167
168
169
170
171
/*
* Bytes of output from parsing. Most profiles produce a string of source
* code, but profiles that do binary output may not be text at all.
* Will be NULL on error.
*/
const char *output;
/*
* Byte count for output, not counting any null terminator. Most profiles
172
173
174
* produce an ASCII string of source code (which will be null-terminated
* even though that null char isn't included in output_len), but profiles
* that do binary output may not be text at all. Will be 0 on error.
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
*/
int output_len;
/*
* Count of Direct3D instructions we parsed. This is meaningless in terms
* of the actual output, as the profile will probably grow or reduce
* the count (or for high-level languages, not have that information at
* all), but it can give you a rough idea of the size of your shader.
* Will be zero on error.
*/
int instruction_count;
/*
* The type of shader we parsed. Will be MOJOSHADER_TYPE_UNKNOWN on error.
*/
MOJOSHADER_shaderType shader_type;
/*
* The shader's major version. If this was a "vs_3_0", this would be 3.
*/
int major_ver;
/*
* The shader's minor version. If this was a "ps_1_4", this would be 4.
* Two notes: for "vs_2_x", this is 1, and for "vs_3_sw", this is 255.
*/
int minor_ver;
203
204
205
206
207
208
/*
* The number of elements pointed to by (uniforms).
*/
int uniform_count;
/*
209
210
* (uniform_count) elements of data that specify Uniforms to be set for
* this shader. See discussion on MOJOSHADER_uniform for details.
211
* This can be NULL on error or if (uniform_count) is zero.
212
213
214
*/
MOJOSHADER_uniform *uniforms;
215
216
217
218
219
220
221
222
223
224
225
226
/*
* The number of elements pointed to by (samplers).
*/
int sampler_count;
/*
* (sampler_count) elements of data that specify Samplers to be set for
* this shader. See discussion on MOJOSHADER_sampler for details.
* This can be NULL on error or if (sampler_count) is zero.
*/
MOJOSHADER_sampler *samplers;
227
228
229
230
231
232
233
234
/*
* The number of elements pointed to by (attributes).
*/
int attribute_count;
/*
* (attribute_count) elements of data that specify Attributes to be set
* for this shader. See discussion on MOJOSHADER_attribute for details.
235
* This can be NULL on error or if (attribute_count) is zero.
236
237
238
*/
MOJOSHADER_attribute *attributes;
239
240
241
242
243
244
245
246
247
/*
* This is the malloc implementation you passed to MOJOSHADER_parse().
*/
MOJOSHADER_malloc malloc;
/*
* This is the free implementation you passed to MOJOSHADER_parse().
*/
MOJOSHADER_free free;
248
249
250
251
252
/*
* This is the pointer you passed as opaque data for your allocator.
*/
void *malloc_data;
253
254
255
256
257
258
259
260
} MOJOSHADER_parseData;
/*
* Profile string for Direct3D assembly language output.
*/
#define MOJOSHADER_PROFILE_D3D "d3d"
261
262
263
264
265
/*
* Profile string for passthrough of the original bytecode, unchanged.
*/
#define MOJOSHADER_PROFILE_PASSTHROUGH "passthrough"
266
267
268
269
270
/*
* Profile string for GLSL: OpenGL high-level shader language output.
*/
#define MOJOSHADER_PROFILE_GLSL "glsl"
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
/*
* Parse a compiled Direct3D shader's bytecode.
*
* This is your primary entry point into MojoShader. You need to pass it
* a compiled D3D shader and tell it which "profile" you want to use to
* convert it into useful data.
*
* The available profiles are the set of MOJOSHADER_PROFILE_* defines.
* Note that MojoShader may be built without support for all listed
* profiles (in which case using one here will return with an error).
*
* As parsing requires some memory to be allocated, you may provide a custom
* allocator to this function, which will be used to allocate/free memory.
* They function just like malloc() and free(). We do not use realloc().
286
287
288
* If you don't care, pass NULL in for the allocator functions. If your
* allocator needs instance-specific data, you may supply it with the
* (d) parameter. This pointer is passed as-is to your (m) and (f) functions.
289
*
290
* This function returns a MOJOSHADER_parseData.
291
292
293
294
295
296
*
* This function will never return NULL, even if the system is completely
* out of memory upon entry (in which case, this function returns a static
* MOJOSHADER_parseData object, which is still safe to pass to
* MOJOSHADER_freeParseData()).
*
297
* This function is thread safe, so long as (m) and (f) are too, and that
298
299
300
301
302
303
304
* (tokenbuf) remains intact for the duration of the call. This allows you
* to parse several shaders on separate CPU cores at the same time.
*/
const MOJOSHADER_parseData *MOJOSHADER_parse(const char *profile,
const unsigned char *tokenbuf,
const unsigned int bufsize,
MOJOSHADER_malloc m,
305
306
MOJOSHADER_free f,
void *d);
307
308
309
310
311
312
313
314
315
316
317
/*
* Call this to dispose of parsing results when you are done with them.
* This will call the MOJOSHADER_free function you provided to
* MOJOSHADER_parse multiple times, if you provided one.
* Passing a NULL here is a safe no-op.
*
* This function is thread safe, so long as any allocator you passed into
* MOJOSHADER_parse() is, too.
*/
void MOJOSHADER_freeParseData(const MOJOSHADER_parseData *data);
318
319
320
321
322
323
324
#ifdef __cplusplus
}
#endif
#endif /* include-once blocker. */
325
/* end of mojoshader.h ... */