Add .constfa for creating floating-point vector constant arrays.

This commit is contained in:
fincs 2016-02-20 00:24:34 +01:00
parent d97de2e8dc
commit 5a597fb870
3 changed files with 165 additions and 11 deletions

View File

@ -150,6 +150,32 @@ Reserves a new integer vector uniform to be preloaded with the specified constan
.constf loopParams(16, 0, 1, 0)
```
### .constfa
```
.constfa arrayName[]
.constfa arrayName[size]
.constfa (x, y, z, w)
```
Reserves a new array of floating-point vector uniforms to be preloaded with the specified constants; creates an alias for it that points to the first element. Example:
```
; Create an array of two elements
.constfa myArray[]
.constfa (1.0, 2.0, 3.0, 4.0)
.constfa (5.0, 6.0, 7.0, 8.0)
.end
```
Optionally the size of the array may be specified. If a number of elements less than the size is specified, the missing elements are initialized to zero. Example:
```
.constfa myArray[4]
.constfa (1.0, 2.0, 3.0, 4.0)
.constfa (5.0, 6.0, 7.0, 8.0)
; The remaining two elements are vectors full of zeroes.
.end
```
### .out
```
.out outName propName

View File

@ -74,6 +74,7 @@ enum
SE_PROC,
SE_FOR,
SE_IF,
SE_ARRAY,
};
struct StackEntry

View File

@ -19,6 +19,10 @@ int g_opdescMasks[MAX_OPDESC];
Uniform g_uniformTable[MAX_UNIFORM];
int g_uniformCount;
std::vector<Constant> g_constArray;
int g_constArraySize = -1;
const char* g_constArrayName;
class UniformAlloc
{
int start, end, bound, tend;
@ -44,6 +48,17 @@ public:
static UniformAlloc fvecAlloc(0x20, 0x80), ivecAlloc(0x80, 0x84), boolAlloc(0x88, 0x98);
static inline UniformAlloc& getAlloc(int type)
{
switch (type)
{
default:
case UTYPE_FVEC: return fvecAlloc;
case UTYPE_IVEC: return ivecAlloc;
case UTYPE_BOOL: return boolAlloc;
}
}
procTableType g_procTable;
dvleTableType g_dvleTable;
relocTableType g_procRelocTable;
@ -1226,6 +1241,52 @@ DEF_DIRECTIVE(end)
}
break;
}
case SE_ARRAY:
{
#ifdef DEBUG
printf("ENDARRAY\n");
#endif
DVLEData* dvle = GetDvleData();
UniformAlloc& alloc = getAlloc(UTYPE_FVEC);
if (g_aliases.find(g_constArrayName) != g_aliases.end())
return duplicateIdentifier(g_constArrayName);
int size = g_constArray.size();
if (g_constArraySize >= 0) for (; size < g_constArraySize; size ++)
{
Constant c;
memset(&c, 0, sizeof(c));
c.type = UTYPE_FVEC;
g_constArray.push_back(c);
}
if (size == 0)
return throwError("no elements have been specified in array '%s'\n", g_constArrayName);
int uniformPos = alloc.AllocLocal(size);
if (uniformPos < 0)
return throwError("not enough space for local constant array '%s'\n", g_constArrayName);
if ((dvle->constantCount+size) > MAX_CONSTANT)
return throwError("too many local constants\n");
for (int i = 0; i < size; i ++)
{
Constant& src = g_constArray[i];
Constant& dst = dvle->constantTable[dvle->constantCount++];
src.regId = uniformPos+i;
memcpy(&dst, &src, sizeof(src));
}
g_aliases.insert( std::pair<std::string,int>(g_constArrayName, uniformPos | (DEFAULT_OPSRC<<8)) );
g_constArray.clear();
g_constArraySize = -1;
g_constArrayName = NULL;
break;
}
}
return 0;
@ -1250,17 +1311,6 @@ DEF_DIRECTIVE(alias)
return 0;
}
static inline UniformAlloc& getAlloc(int type)
{
switch (type)
{
default:
case UTYPE_FVEC: return fvecAlloc;
case UTYPE_IVEC: return ivecAlloc;
case UTYPE_BOOL: return boolAlloc;
}
}
DEF_DIRECTIVE(uniform)
{
UniformAlloc& alloc = getAlloc(dirParam);
@ -1398,6 +1448,80 @@ DEF_DIRECTIVE(const)
return 0;
};
DEF_DIRECTIVE(constfa)
{
bool inArray = g_stackPos && g_stack[g_stackPos-1].type == SE_ARRAY;
if (!inArray)
{
NEXT_ARG(constName);
ENSURE_NO_MORE_ARGS();
if (NO_MORE_STACK)
return throwError("too many nested blocks\n");
char* sizePos = strchr(constName, '[');
if (!sizePos)
return throwError("missing opening bracket: %s\n", constName);
char* closePos = strchr(sizePos, ']');
if (!closePos)
return throwError("missing closing bracket: %s\n", constName);
*closePos++ = 0;
*sizePos++ = 0;
closePos = trim_whitespace(closePos);
sizePos = trim_whitespace(sizePos);
if (*closePos)
return throwError("garbage found: %s\n", closePos);
if (*sizePos)
{
g_constArraySize = atoi(sizePos);
if (g_constArraySize <= 0)
return throwError("invalid array size: %s[%s]\n", constName, sizePos);
}
if (!validateIdentifier(constName))
return throwError("invalid array name: %s\n", constName);
g_constArrayName = constName;
StackEntry& elem = g_stack[g_stackPos++];
elem.type = SE_ARRAY;
} else
{
if (g_constArraySize >= 0 && g_constArraySize == g_constArray.size())
return throwError("too many elements in the array, expected %d\n", g_constArraySize);
NEXT_ARG(arg0Text);
if (*arg0Text != '(')
return throwError("invalid syntax\n");
arg0Text++;
NEXT_ARG(arg1Text);
NEXT_ARG(arg2Text);
char* arg3Text = mystrtok_pos;
if (!mystrtok_pos) return missingParam();
char* parenPos = strchr(arg3Text, ')');
if (!parenPos) return throwError("invalid syntax\n");
*parenPos = 0;
arg3Text = trim_whitespace(arg3Text);
Constant ct;
ct.type = UTYPE_FVEC;
ct.fparam[0] = atof(arg0Text);
ct.fparam[1] = atof(arg1Text);
ct.fparam[2] = atof(arg2Text);
ct.fparam[3] = atof(arg3Text);
g_constArray.push_back(ct);
}
return 0;
}
DEF_DIRECTIVE(setfi)
{
DVLEData* dvle = GetDvleData();
@ -1574,6 +1698,8 @@ DEF_DIRECTIVE(nodvle)
dvle->nodvle = true;
g_totalDvleCount --;
}
return 0;
}
DEF_DIRECTIVE(gsh)
@ -1600,6 +1726,7 @@ static const cmdTableType dirTable[] =
DEC_DIRECTIVE2(bool, uniform, UTYPE_BOOL),
DEC_DIRECTIVE2(constf, const, UTYPE_FVEC),
DEC_DIRECTIVE2(consti, const, UTYPE_IVEC),
DEC_DIRECTIVE(constfa),
DEC_DIRECTIVE(out),
DEC_DIRECTIVE(entry),
DEC_DIRECTIVE(nodvle),