Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Effect struct parameter support
  • Loading branch information
flibitijibibo committed Feb 9, 2016
1 parent 8a755b1 commit 303b5b1
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 82 deletions.
2 changes: 1 addition & 1 deletion mojoshader.c
Expand Up @@ -8125,7 +8125,7 @@ static int parse_ctab_typeinfo(Context *ctx, const uint8 *start,
} // else

int i;
const uint32 *member = (const uint32 *)((const uint8 *) (&typeptr[6]));
const uint32 *member = (const uint32 *) (start + typeptr[6]);
for (i = 0; i < info->member_count; i++)
{
MOJOSHADER_symbolStructMember *mbr = &info->members[i];
Expand Down
159 changes: 117 additions & 42 deletions mojoshader_effects.c
Expand Up @@ -261,11 +261,11 @@ static void readvalue(const uint8 *base,
const uint32 semantic = readui32(&typeptr, &typelen);
const uint32 numelements = readui32(&typeptr, &typelen);

value->value_type = (MOJOSHADER_symbolType) type;
value->value_class = (MOJOSHADER_symbolClass) valclass;
value->type.parameter_type = (MOJOSHADER_symbolType) type;
value->type.parameter_class = (MOJOSHADER_symbolClass) valclass;
value->name = readstring(base, name, m, d);
value->semantic = readstring(base, semantic, m, d);
value->element_count = numelements;
value->type.elements = numelements;

/* Class sanity check */
assert(valclass >= MOJOSHADER_SYMCLASS_SCALAR && valclass <= MOJOSHADER_SYMCLASS_STRUCT);
Expand All @@ -281,8 +281,8 @@ static void readvalue(const uint8 *base,
const uint32 columncount = readui32(&typeptr, &typelen);
const uint32 rowcount = readui32(&typeptr, &typelen);

value->column_count = columncount;
value->row_count = rowcount;
value->type.columns = columncount;
value->type.rows = rowcount;

uint32 siz = columncount * rowcount;
if (numelements > 0)
Expand Down Expand Up @@ -346,8 +346,51 @@ static void readvalue(const uint8 *base,
} // else if
else if (valclass == MOJOSHADER_SYMCLASS_STRUCT)
{
/* TODO: Maybe this is like parse_ctab_typeinfo? -flibit */
assert(0 && "Effect struct value parsing not implemented!");
uint32 siz;

value->type.member_count = readui32(&typeptr, &typelen);
siz = value->type.member_count * sizeof (MOJOSHADER_symbolStructMember);
value->type.members = (MOJOSHADER_symbolStructMember *) m(siz, d);

uint32 structsize = 0;
for (i = 0; i < value->type.member_count; i++)
{
MOJOSHADER_symbolStructMember *mem = &value->type.members[i];

mem->info.parameter_type = (MOJOSHADER_symbolType) readui32(&typeptr, &typelen);
mem->info.parameter_class = (MOJOSHADER_symbolClass) readui32(&typeptr, &typelen);

const uint32 memname = readui32(&typeptr, &typelen);
/*const uint32 memsemantic =*/ readui32(&typeptr, &typelen);
mem->name = readstring(base, memname, m, d);

mem->info.elements = readui32(&typeptr, &typelen);
mem->info.columns = readui32(&typeptr, &typelen);
mem->info.rows = readui32(&typeptr, &typelen);

// !!! FIXME: Nested structs! -flibit
assert(mem->info.parameter_class >= MOJOSHADER_SYMCLASS_SCALAR
&& mem->info.parameter_class <= MOJOSHADER_SYMCLASS_VECTOR);
assert(mem->info.parameter_type >= MOJOSHADER_SYMTYPE_BOOL
&& mem->info.parameter_type <= MOJOSHADER_SYMTYPE_FLOAT);
mem->info.member_count = 0;
mem->info.members = NULL;

uint32 memsize = mem->info.columns * mem->info.rows;
if (mem->info.elements > 0)
memsize *= mem->info.elements;
structsize += memsize;
} // for

value->type.columns = structsize;
value->type.rows = 1;
value->value_count = structsize;
if (numelements > 0)
value->value_count *= numelements;

siz = value->value_count * 4;
value->values = m(siz, d);
memcpy(value->values, typeptr, siz); /* Yes, typeptr. -flibit */
} // else if
} // readvalue

Expand Down Expand Up @@ -897,16 +940,30 @@ MOJOSHADER_effect *MOJOSHADER_parseEffect(const char *profile,
} // MOJOSHADER_parseEffect


void freetypeinfo(MOJOSHADER_symbolTypeInfo *typeinfo,
MOJOSHADER_free f, void *d)
{
int i;
for (i = 0; i < typeinfo->member_count; i++)
{
f((void *) typeinfo->members[i].name, d);
freetypeinfo(&typeinfo->members[i].info, f, d);
} // for
f((void *) typeinfo->members, d);
} // freetypeinfo


void freevalue(MOJOSHADER_effectValue *value, MOJOSHADER_free f, void *d)
{
int i;
f((void *) value->name, d);
f((void *) value->semantic, d);
if (value->value_type == MOJOSHADER_SYMTYPE_SAMPLER
|| value->value_type == MOJOSHADER_SYMTYPE_SAMPLER1D
|| value->value_type == MOJOSHADER_SYMTYPE_SAMPLER2D
|| value->value_type == MOJOSHADER_SYMTYPE_SAMPLER3D
|| value->value_type == MOJOSHADER_SYMTYPE_SAMPLERCUBE)
freetypeinfo(&value->type, f, d);
if (value->type.parameter_type == MOJOSHADER_SYMTYPE_SAMPLER
|| value->type.parameter_type == MOJOSHADER_SYMTYPE_SAMPLER1D
|| value->type.parameter_type == MOJOSHADER_SYMTYPE_SAMPLER2D
|| value->type.parameter_type == MOJOSHADER_SYMTYPE_SAMPLER3D
|| value->type.parameter_type == MOJOSHADER_SYMTYPE_SAMPLERCUBE)
for (i = 0; i < value->value_count; i++)
freevalue(&value->valuesSS[i].value, f, d);
f(value->values, d);
Expand Down Expand Up @@ -1007,6 +1064,39 @@ void MOJOSHADER_freeEffect(const MOJOSHADER_effect *_effect)
} // MOJOSHADER_freeEffect


// !!! FIXME: Out of memory check!
#define COPY_STRING(location) \
if (src->location != NULL) \
{ \
siz = strlen(src->location) + 1; \
stringcopy = (char *) m(siz, d); \
strcpy(stringcopy, src->location); \
dst->location = stringcopy; \
} // if


void copysymboltypeinfo(MOJOSHADER_symbolTypeInfo *dst,
MOJOSHADER_symbolTypeInfo *src,
MOJOSHADER_malloc m,
void *d)
{
int i;
uint32 siz = 0;
char *stringcopy = NULL;
memcpy(dst, src, sizeof (MOJOSHADER_symbolTypeInfo));
if (dst->member_count > 0)
{
siz = dst->member_count * sizeof (MOJOSHADER_symbolStructMember);
dst->members = (MOJOSHADER_symbolStructMember *) m(siz, d);
for (i = 0; i < dst->member_count; i++)
{
COPY_STRING(members[i].name)
copysymboltypeinfo(&dst->members[i].info, &src->members[i].info, m, d);
} // for
} // if
} // copysymboltypeinfo


void copyvalue(MOJOSHADER_effectValue *dst,
MOJOSHADER_effectValue *src,
MOJOSHADER_malloc m,
Expand All @@ -1016,42 +1106,29 @@ void copyvalue(MOJOSHADER_effectValue *dst,
uint32 siz = 0;
char *stringcopy = NULL;

// !!! FIXME: Out of memory check!
#define COPY_STRING(location) \
if (src->location != NULL) \
{ \
siz = strlen(src->location) + 1; \
stringcopy = (char *) m(siz, d); \
strcpy(stringcopy, src->location); \
dst->location = stringcopy; \
} // if

COPY_STRING(name)
COPY_STRING(semantic)
dst->element_count = src->element_count;
dst->row_count = src->row_count;
dst->column_count = src->column_count;
dst->value_class = src->value_class;
dst->value_type = src->value_type;
copysymboltypeinfo(&dst->type, &src->type, m, d);
dst->value_count = src->value_count;

if (dst->value_class == MOJOSHADER_SYMCLASS_SCALAR
|| dst->value_class == MOJOSHADER_SYMCLASS_VECTOR
|| dst->value_class == MOJOSHADER_SYMCLASS_MATRIX_ROWS
|| dst->value_class == MOJOSHADER_SYMCLASS_MATRIX_COLUMNS)
if (dst->type.parameter_class == MOJOSHADER_SYMCLASS_SCALAR
|| dst->type.parameter_class == MOJOSHADER_SYMCLASS_VECTOR
|| dst->type.parameter_class == MOJOSHADER_SYMCLASS_MATRIX_ROWS
|| dst->type.parameter_class == MOJOSHADER_SYMCLASS_MATRIX_COLUMNS
|| dst->type.parameter_class == MOJOSHADER_SYMCLASS_STRUCT)
{
siz = dst->value_count * 4;
dst->values = m(siz, d);
// !!! FIXME: Out of memory check!
memcpy(dst->values, src->values, siz);
} // if
else if (dst->value_class == MOJOSHADER_SYMCLASS_OBJECT)
else if (dst->type.parameter_class == MOJOSHADER_SYMCLASS_OBJECT)
{
if (dst->value_type == MOJOSHADER_SYMTYPE_SAMPLER
|| dst->value_type == MOJOSHADER_SYMTYPE_SAMPLER1D
|| dst->value_type == MOJOSHADER_SYMTYPE_SAMPLER2D
|| dst->value_type == MOJOSHADER_SYMTYPE_SAMPLER3D
|| dst->value_type == MOJOSHADER_SYMTYPE_SAMPLERCUBE)
if (dst->type.parameter_type == MOJOSHADER_SYMTYPE_SAMPLER
|| dst->type.parameter_type == MOJOSHADER_SYMTYPE_SAMPLER1D
|| dst->type.parameter_type == MOJOSHADER_SYMTYPE_SAMPLER2D
|| dst->type.parameter_type == MOJOSHADER_SYMTYPE_SAMPLER3D
|| dst->type.parameter_type == MOJOSHADER_SYMTYPE_SAMPLERCUBE)
{
siz = dst->value_count * sizeof (MOJOSHADER_effectSamplerState);
dst->values = m(siz, d);
Expand All @@ -1073,15 +1150,13 @@ void copyvalue(MOJOSHADER_effectValue *dst,
memcpy(dst->values, src->values, siz);
} // else
} // else if
else if (dst->value_class == MOJOSHADER_SYMCLASS_STRUCT)
{
/* TODO: See readvalue! -flibit */
} // else if

#undef COPY_STRING
} // copyvalue


#undef COPY_STRING


void copysymbolinfo(MOJOSHADER_symbolTypeInfo *dst,
MOJOSHADER_symbolTypeInfo *src,
MOJOSHADER_malloc m,
Expand Down
6 changes: 1 addition & 5 deletions mojoshader_effects.h
Expand Up @@ -316,11 +316,7 @@ typedef struct MOJOSHADER_effectValue
{
const char *name;
const char *semantic;
unsigned int element_count;
unsigned int row_count;
unsigned int column_count;
MOJOSHADER_symbolClass value_class;
MOJOSHADER_symbolType value_type;
MOJOSHADER_symbolTypeInfo type;
unsigned int value_count;
union
{
Expand Down
65 changes: 43 additions & 22 deletions mojoshader_opengl.c
Expand Up @@ -2860,14 +2860,14 @@ static inline void copy_parameter_data(MOJOSHADER_effectParam *params,
// float/int registers are vec4, so they have 4 elements each
const uint32 start = sym->register_index << 2;

if (param->value_type == MOJOSHADER_SYMTYPE_FLOAT)
if (param->type.parameter_type == MOJOSHADER_SYMTYPE_FLOAT)
{
// Matrices have to be transposed from row-major to column-major!
if (param->value_class == MOJOSHADER_SYMCLASS_MATRIX_ROWS)
if (param->type.parameter_class == MOJOSHADER_SYMCLASS_MATRIX_ROWS)
{
if (param->element_count > 1)
if (param->type.elements > 1)
{
const uint32 regcount = sym->register_count / param->element_count;
const uint32 regcount = sym->register_count / param->type.elements;
j = 0;
do
{
Expand All @@ -2881,12 +2881,12 @@ static inline void copy_parameter_data(MOJOSHADER_effectParam *params,
(r << 2) +
((j << 2) * regcount);
const uint32 src = r +
(c * param->row_count) +
(j * param->row_count * param->column_count);
(c * param->type.rows) +
(j * param->type.rows * param->type.columns);
regf[dest] = param->valuesF[src];
} while (++c < param->column_count);
} while (++c < param->type.columns);
} while (++r < regcount);
} while (++j < param->element_count);
} while (++j < param->type.elements);
} // if
else
{
Expand All @@ -2896,8 +2896,8 @@ static inline void copy_parameter_data(MOJOSHADER_effectParam *params,
c = 0;
do
{
regf[start + (r << 2 ) + c] = param->valuesF[r + (c * param->row_count)];
} while (++c < param->column_count);
regf[start + (r << 2 ) + c] = param->valuesF[r + (c * param->type.rows)];
} while (++c < param->type.columns);
} while (++r < sym->register_count);
} // else
} // if
Expand All @@ -2907,25 +2907,46 @@ static inline void copy_parameter_data(MOJOSHADER_effectParam *params,
do
{
memcpy(regf + start + (j << 2),
param->valuesF + (j * param->column_count),
param->column_count << 2);
param->valuesF + (j * param->type.columns),
param->type.columns << 2);
} while (++j < sym->register_count);
} // else if
else
memcpy(regf + start, param->valuesF, param->column_count << 2);
memcpy(regf + start, param->valuesF, param->type.columns << 2);
} // if
else if (sym->register_set == MOJOSHADER_SYMREGSET_FLOAT4)
{
// Sometimes int/bool parameters get thrown into float registers...
j = 0;
do
if (param->type.parameter_class == MOJOSHADER_SYMCLASS_STRUCT)
{
c = 0;
float *struct_offset = param->valuesF;
r = 0; /* Register offset */
j = 0;
do
{
regf[start + (j << 2) + c] = (float) param->valuesI[(j * param->column_count) + c];
} while (++c < param->column_count);
} while (++j < sym->register_count);
c = 0;
do
{
memcpy(regf + start + (r << 2),
struct_offset,
param->type.members[c].info.columns << 2);
struct_offset += param->type.members[c].info.columns;
r++;
} while (++c < param->type.member_count);
} while (++j < param->type.elements);
} // if
else
{
j = 0;
do
{
c = 0;
do
{
regf[start + (j << 2) + c] = (float) param->valuesI[(j * param->type.columns) + c];
} while (++c < param->type.columns);
} while (++j < sym->register_count);
} // else
} // else if
else if (sym->register_set == MOJOSHADER_SYMREGSET_INT4)
{
Expand All @@ -2935,12 +2956,12 @@ static inline void copy_parameter_data(MOJOSHADER_effectParam *params,
do
{
memcpy(regi + start + (j << 2),
param->valuesI + (j * param->column_count),
param->column_count << 2);
param->valuesI + (j * param->type.columns),
param->type.columns << 2);
} while (++j < sym->register_count);
} // if
else
memcpy(regi + start, param->valuesI, param->column_count << 2);
memcpy(regi + start, param->valuesI, param->type.columns << 2);
} // else if
else if (sym->register_set == MOJOSHADER_SYMREGSET_BOOL)
{
Expand Down

0 comments on commit 303b5b1

Please sign in to comment.