Skip to content
Permalink
Browse files
First (incomplete!) shot at more robust CTAB support.
Assembler can now add it, but we still need to parse it better and report it
 all back to the app in MOJOSHADER_parse().
  • Loading branch information
icculus committed Dec 20, 2008
1 parent d3f911b commit 6c918ef5696034d55848b3dab1bfdad4634da6b4
Showing with 272 additions and 93 deletions.
  1. +1 −1 assemble.c
  2. +1 −1 finderrors.c
  3. +17 −6 mojoshader.c
  4. +110 −1 mojoshader.h
  5. +137 −83 mojoshader_assembler.c
  6. +6 −1 mojoshader_internal.h
@@ -23,7 +23,7 @@ static int assemble(const char *buf, const char *outfile)
const MOJOSHADER_parseData *pd;
int retval = 0;

pd = MOJOSHADER_assemble(buf, NULL, NULL, NULL);
pd = MOJOSHADER_assemble(buf, NULL, 0, NULL, 0, NULL, NULL, NULL);
if (pd->error != NULL)
printf("ERROR: (line %d) %s\n", pd->error_position, pd->error);
else
@@ -84,7 +84,7 @@ static int do_file(const char *profile, const char *dname, const char *fn, int *
const MOJOSHADER_parseData *a;

buf[rc] = '\0'; // make sure the source is null-terminated.
a = MOJOSHADER_assemble((char *) buf, 0, 0, 0);
a = MOJOSHADER_assemble((char *) buf, 0, 0, 0, 0, 0, 0, 0);
if (a->error)
{
report("FAIL: %s (line %d) %s\n", fname, a->error_position, a->error);
@@ -5737,6 +5737,7 @@ static ConstantsList *alloc_constant_listitem(Context *ctx)
return item;
} // alloc_constant_listitem


static void state_DEF(Context *ctx)
{
const RegisterType regtype = ctx->dest_arg.regtype;
@@ -6517,24 +6518,22 @@ static void parse_constant_table(Context *ctx, const uint32 bytes)
const uint32 target = SWAP32(ctx->tokens[8]);
uint32 i = 0;

if (id != 0x42415443) // 0x42415443 == 'CTAB'
if (id != CTAB_ID)
return; // not the constant table.

if (size != 28)
if (size != CTAB_SIZE)
return; // only handle this version of the struct.

if (version != ctx->version_token) goto corrupt_ctab;
if (creator >= bytes) goto corrupt_ctab;
if ((constantinfo + (constants * 20)) >= bytes) goto corrupt_ctab;
if ((constantinfo + (constants * CINFO_SIZE)) >= bytes) goto corrupt_ctab;
if (target >= bytes) goto corrupt_ctab;

ctx->have_ctab = 1;

for (i = 0; i < constants; i++)
{
// we only care about deciding which variables might be arrays at
// the moment, but there's lots of other good info in the CTAB.
const uint8 *ptr = start + constantinfo + (i * 20);
const uint8 *ptr = start + constantinfo + (i * CINFO_SIZE);
const uint32 name = SWAP32(*((uint32 *) (ptr + 0)));
const uint16 regset = SWAP16(*((uint16 *) (ptr + 4)));
const uint16 regidx = SWAP16(*((uint16 *) (ptr + 6)));
@@ -7471,6 +7470,18 @@ void MOJOSHADER_freeParseData(const MOJOSHADER_parseData *_data)
f((void *) data->samplers, d);
} // if

if (data->symbols != NULL)
{
for (i = 0; i < data->symbol_count; i++)
{
if (data->symbols[i].name != NULL)
f((void *) data->symbols[i].name, d);
if (data->symbols[i].default_value != NULL)
f((void *) data->symbols[i].default_value, d);
} // for
f((void *) data->symbols, d);
} // if

if ((data->error != NULL) && (data->error != out_of_mem_str))
f((void *) data->error, d);

@@ -239,9 +239,90 @@ typedef struct MOJOSHADER_swizzle
} MOJOSHADER_swizzle;


/*
* MOJOSHADER_symbol data.
*
* These are used to expose high-level information in shader bytecode.
* They associate HLSL variables with registers. This data is used for both
* debugging and optimization.
*/

typedef enum
{
MOJOSHADER_SYMREGSET_BOOL,
MOJOSHADER_SYMREGSET_INT4,
MOJOSHADER_SYMREGSET_FLOAT4,
MOJOSHADER_SYMREGSET_SAMPLER,
} MOJOSHADER_symbolRegisterSet;

typedef enum
{
MOJOSHADER_SYMCLASS_SCALAR,
MOJOSHADER_SYMCLASS_VECTOR,
MOJOSHADER_SYMCLASS_MATRIX_ROWS,
MOJOSHADER_SYMCLASS_MATRIX_COLUMNS,
MOJOSHADER_SYMCLASS_OBJECT,
MOJOSHADER_SYMCLASS_STRUCT,
} MOJOSHADER_symbolClass;

typedef enum
{
MOJOSHADER_SYMTYPE_VOID,
MOJOSHADER_SYMTYPE_BOOL,
MOJOSHADER_SYMTYPE_INT,
MOJOSHADER_SYMTYPE_FLOAT,
MOJOSHADER_SYMTYPE_STRING,
MOJOSHADER_SYMTYPE_TEXTURE,
MOJOSHADER_SYMTYPE_TEXTURE1D,
MOJOSHADER_SYMTYPE_TEXTURE2D,
MOJOSHADER_SYMTYPE_TEXTURE3D,
MOJOSHADER_SYMTYPE_TEXTURECUBE,
MOJOSHADER_SYMTYPE_SAMPLER,
MOJOSHADER_SYMTYPE_SAMPLER1D,
MOJOSHADER_SYMTYPE_SAMPLER2D,
MOJOSHADER_SYMTYPE_SAMPLER3D,
MOJOSHADER_SYMTYPE_SAMPLERCUBE,
MOJOSHADER_SYMTYPE_PIXELSHADER,
MOJOSHADER_SYMTYPE_VERTEXSHADER,
MOJOSHADER_SYMTYPE_PIXELFRAGMENT,
MOJOSHADER_SYMTYPE_VERTEXFRAGMENT,
MOJOSHADER_SYMTYPE_UNSUPPORTED,
} MOJOSHADER_symbolType;

typedef struct MOJOSHADER_symbolStructMember MOJOSHADER_symbolStructMember;

typedef struct MOJOSHADER_symbolTypeInfo
{
MOJOSHADER_symbolClass parameter_class;
MOJOSHADER_symbolType parameter_type;
unsigned int rows;
unsigned int columns;
unsigned int elements;
unsigned int member_count;
MOJOSHADER_symbolStructMember *members;
} MOJOSHADER_symbolTypeInfo;

struct MOJOSHADER_symbolStructMember
{
const char *name;
MOJOSHADER_symbolTypeInfo info;
};

typedef struct MOJOSHADER_symbol
{
const char *name;
MOJOSHADER_symbolRegisterSet register_set;
unsigned int register_index;
unsigned int register_count;
MOJOSHADER_symbolTypeInfo info;
void *default_value;
} MOJOSHADER_symbol;


/*
* Structure used to return data from parsing of a shader...
*/
/* !!! FIXME: most of these ints should be unsigned. */
typedef struct MOJOSHADER_parseData
{
/*
@@ -372,6 +453,20 @@ typedef struct MOJOSHADER_parseData
*/
MOJOSHADER_swizzle *swizzles;

/*
* The number of elements pointed to by (symbols).
*/
int symbol_count;

/*
* (symbol_count) elements of data that specify high-level symbol data
* for the shader. This will be parsed from the CTAB section
* in bytecode, and will be a copy of what you provide to
* MOJOSHADER_assemble(). This data is optional.
* This can be NULL on error or if (symbol_count) is zero.
*/
MOJOSHADER_symbol *symbols;

/*
* This is the malloc implementation you passed to MOJOSHADER_parse().
*/
@@ -504,6 +599,17 @@ void MOJOSHADER_freeParseData(const MOJOSHADER_parseData *data);
* (source) is an ASCII, NULL-terminated string of valid Direct3D shader
* assembly source code.
*
* (comments) points to (comment_count) NULL-terminated ASCII strings, and
* can be NULL. These strings are inserted as comments in the bytecode.
*
* (symbols) points to (symbol_count) symbol structs, and can be NULL. These
* become a CTAB field in the bytecode. This is optional, but
* MOJOSHADER_parse() needs CTAB data for all arrays used in a program, or
* relative addressing will not be permitted, so you'll want to at least
* provide symbol information for those. The symbol data is 100% trusted
* at this time; it will not be checked to see if it matches what was
* assembled in any way whatsoever.
*
* This will return a MOJOSHADER_parseData(), like MOJOSHADER_parse() would,
* except the profile will be MOJOSHADER_PROFILE_BYTECODE and the output
* will be the assembled bytecode instead of some other language. This output
@@ -526,7 +632,10 @@ void MOJOSHADER_freeParseData(const MOJOSHADER_parseData *data);
* to assemble several shaders on separate CPU cores at the same time.
*/
const MOJOSHADER_parseData *MOJOSHADER_assemble(const char *source,
MOJOSHADER_malloc m, MOJOSHADER_free f, void *d);
const char **comments, unsigned int comment_count,
const MOJOSHADER_symbol *symbols,
unsigned int symbol_count,
MOJOSHADER_malloc m, MOJOSHADER_free f, void *d);



0 comments on commit 6c918ef

Please sign in to comment.