Add .constfa for creating floating-point vector constant arrays.
This commit is contained in:
parent
d97de2e8dc
commit
5a597fb870
26
Manual.md
26
Manual.md
@ -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
|
||||
|
@ -74,6 +74,7 @@ enum
|
||||
SE_PROC,
|
||||
SE_FOR,
|
||||
SE_IF,
|
||||
SE_ARRAY,
|
||||
};
|
||||
|
||||
struct StackEntry
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user