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)
|
.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
|
||||||
```
|
```
|
||||||
.out outName propName
|
.out outName propName
|
||||||
|
@ -74,6 +74,7 @@ enum
|
|||||||
SE_PROC,
|
SE_PROC,
|
||||||
SE_FOR,
|
SE_FOR,
|
||||||
SE_IF,
|
SE_IF,
|
||||||
|
SE_ARRAY,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StackEntry
|
struct StackEntry
|
||||||
|
@ -19,6 +19,10 @@ int g_opdescMasks[MAX_OPDESC];
|
|||||||
Uniform g_uniformTable[MAX_UNIFORM];
|
Uniform g_uniformTable[MAX_UNIFORM];
|
||||||
int g_uniformCount;
|
int g_uniformCount;
|
||||||
|
|
||||||
|
std::vector<Constant> g_constArray;
|
||||||
|
int g_constArraySize = -1;
|
||||||
|
const char* g_constArrayName;
|
||||||
|
|
||||||
class UniformAlloc
|
class UniformAlloc
|
||||||
{
|
{
|
||||||
int start, end, bound, tend;
|
int start, end, bound, tend;
|
||||||
@ -44,6 +48,17 @@ public:
|
|||||||
|
|
||||||
static UniformAlloc fvecAlloc(0x20, 0x80), ivecAlloc(0x80, 0x84), boolAlloc(0x88, 0x98);
|
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;
|
procTableType g_procTable;
|
||||||
dvleTableType g_dvleTable;
|
dvleTableType g_dvleTable;
|
||||||
relocTableType g_procRelocTable;
|
relocTableType g_procRelocTable;
|
||||||
@ -1226,6 +1241,52 @@ DEF_DIRECTIVE(end)
|
|||||||
}
|
}
|
||||||
break;
|
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;
|
return 0;
|
||||||
@ -1250,17 +1311,6 @@ DEF_DIRECTIVE(alias)
|
|||||||
return 0;
|
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)
|
DEF_DIRECTIVE(uniform)
|
||||||
{
|
{
|
||||||
UniformAlloc& alloc = getAlloc(dirParam);
|
UniformAlloc& alloc = getAlloc(dirParam);
|
||||||
@ -1398,6 +1448,80 @@ DEF_DIRECTIVE(const)
|
|||||||
return 0;
|
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)
|
DEF_DIRECTIVE(setfi)
|
||||||
{
|
{
|
||||||
DVLEData* dvle = GetDvleData();
|
DVLEData* dvle = GetDvleData();
|
||||||
@ -1574,6 +1698,8 @@ DEF_DIRECTIVE(nodvle)
|
|||||||
dvle->nodvle = true;
|
dvle->nodvle = true;
|
||||||
g_totalDvleCount --;
|
g_totalDvleCount --;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEF_DIRECTIVE(gsh)
|
DEF_DIRECTIVE(gsh)
|
||||||
@ -1600,6 +1726,7 @@ static const cmdTableType dirTable[] =
|
|||||||
DEC_DIRECTIVE2(bool, uniform, UTYPE_BOOL),
|
DEC_DIRECTIVE2(bool, uniform, UTYPE_BOOL),
|
||||||
DEC_DIRECTIVE2(constf, const, UTYPE_FVEC),
|
DEC_DIRECTIVE2(constf, const, UTYPE_FVEC),
|
||||||
DEC_DIRECTIVE2(consti, const, UTYPE_IVEC),
|
DEC_DIRECTIVE2(consti, const, UTYPE_IVEC),
|
||||||
|
DEC_DIRECTIVE(constfa),
|
||||||
DEC_DIRECTIVE(out),
|
DEC_DIRECTIVE(out),
|
||||||
DEC_DIRECTIVE(entry),
|
DEC_DIRECTIVE(entry),
|
||||||
DEC_DIRECTIVE(nodvle),
|
DEC_DIRECTIVE(nodvle),
|
||||||
|
Loading…
Reference in New Issue
Block a user