mojoshader.h
branchtrunk
changeset 46 ff5a0ec44f00
parent 36 5ea7c5f6cf2d
child 92 bc1bb138e855
--- a/mojoshader.h	Thu Mar 27 17:10:27 2008 -0400
+++ b/mojoshader.h	Thu Mar 27 22:35:19 2008 -0400
@@ -15,25 +15,154 @@
 #endif
 
 /*
- * const int compiled_against = MOJOSHADER_VERSION;
- * const int linked_against = MOJOSHADER_version();
+ * 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.
  */
 #define MOJOSHADER_VERSION 1
 int MOJOSHADER_version(void);
 
 /*
  * These allocators work just like the C runtime's malloc() and free()
- *  (in fact, they use malloc() and free() internally if you don't
- *  specify your own allocator).
+ *  (in fact, they probably use malloc() and free() internally if you don't
+ *  specify your own allocator, but don't rely on that behaviour).
  */
 typedef void *(*MOJOSHADER_malloc)(int bytes);
 typedef void (*MOJOSHADER_free)(void *ptr);
 
-/* !!! FIXME: documentation. */
-/* !!! FIXME: this needs to change to return a buffer of GLSL code. */
-int MOJOSHADER_parse(const char *profile, const unsigned char *tokenbuf,
-                   const unsigned int bufsize, MOJOSHADER_malloc m,
-                   MOJOSHADER_free f);
+
+/*
+ * 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;
+
+
+/*
+ * 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;
+
+    /*
+     * 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
+     *  produce an ASCII string of source code, but profiles that do binary
+     *  output may not be text at all. Will be 0 on error.
+     */
+    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;
+
+    /*
+     * 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;
+} MOJOSHADER_parseData;
+
+
+/*
+ * Profile string for Direct3D assembly language output.
+ */
+#define MOJOSHADER_PROFILE_D3D "d3d"
+
+/*
+ * Profile string for GLSL: OpenGL high-level shader language output.
+ */
+#define MOJOSHADER_PROFILE_GLSL "glsl"
+
+/*
+ * 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().
+ *  If you don't care, pass NULL in for the allocator functions.
+ *
+ * This function returns a MOJOSHADER_parseData
+ *
+ * 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()).
+ *
+ * This function is thread safe, so long (m) and (f) are too, and that
+ *  (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,
+                                             MOJOSHADER_free f);
+
+/*
+ * 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);
 
 #ifdef __cplusplus
 }