From 303b5b1e215b7605b6d652d469261aa3bc616715 Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Tue, 9 Feb 2016 00:05:18 -0500 Subject: [PATCH] Effect struct parameter support --- mojoshader.c | 2 +- mojoshader_effects.c | 159 +++++++++++++++++++++++++++++++------------ mojoshader_effects.h | 6 +- mojoshader_opengl.c | 65 ++++++++++++------ utils/testparse.c | 24 +++---- 5 files changed, 174 insertions(+), 82 deletions(-) diff --git a/mojoshader.c b/mojoshader.c index 7a84e9ba..90f0cf9e 100644 --- a/mojoshader.c +++ b/mojoshader.c @@ -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]; diff --git a/mojoshader_effects.c b/mojoshader_effects.c index 6f9d087c..88450779 100644 --- a/mojoshader_effects.c +++ b/mojoshader_effects.c @@ -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); @@ -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) @@ -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 @@ -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); @@ -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, @@ -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); @@ -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, diff --git a/mojoshader_effects.h b/mojoshader_effects.h index f50fca90..715d1710 100644 --- a/mojoshader_effects.h +++ b/mojoshader_effects.h @@ -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 { diff --git a/mojoshader_opengl.c b/mojoshader_opengl.c index 44e77a34..e110b12a 100644 --- a/mojoshader_opengl.c +++ b/mojoshader_opengl.c @@ -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 { @@ -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 { @@ -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 @@ -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) { @@ -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) { diff --git a/utils/testparse.c b/utils/testparse.c index b38e3e17..3ccae52e 100644 --- a/utils/testparse.c +++ b/utils/testparse.c @@ -454,21 +454,21 @@ static void print_value(const MOJOSHADER_effectValue *value, "UNSUPPORTED" }; do_indent(indent + 1); - printf("CLASS: %s\n", classes[value->value_class]); + printf("CLASS: %s\n", classes[value->type.parameter_class]); do_indent(indent + 1); - printf("TYPE: %s\n", types[value->value_type]); + printf("TYPE: %s\n", types[value->type.parameter_type]); do_indent(indent + 1); printf("ROWS/COLUMNS/ELEMENTS: %d, %d, %d\n", - value->row_count, value->column_count, value->element_count); + value->type.rows, value->type.columns, value->type.elements); do_indent(indent + 1); printf("TOTAL VALUES: %d\n", value->value_count); - 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) + 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) { do_indent(indent + 1); printf("SAMPLER VALUES:\n"); @@ -516,7 +516,7 @@ static void print_value(const MOJOSHADER_effectValue *value, else { do_indent(indent + 1); - printf("%s VALUES:\n", types[value->value_type]); + printf("%s VALUES:\n", types[value->type.parameter_type]); for (i = 0; i < value->value_count; i++) { do_indent(indent + 2); @@ -541,10 +541,10 @@ static void print_value(const MOJOSHADER_effectValue *value, "%d\n", "%X\n" }; - if (value->value_type == MOJOSHADER_SYMTYPE_FLOAT) - printf(prints[value->value_type], value->valuesF[i]); + if (value->type.parameter_type == MOJOSHADER_SYMTYPE_FLOAT) + printf(prints[value->type.parameter_type], value->valuesF[i]); else - printf(prints[value->value_type], value->valuesI[i]); + printf(prints[value->type.parameter_type], value->valuesI[i]); } // for } // else } // print_value