Implement .setf/.seti/.setb with documentation
This commit is contained in:
parent
fd8532c55b
commit
011668baef
31
Manual.md
31
Manual.md
@ -55,12 +55,23 @@ Some source operands of instructions (called SRC1) support relative addressing.
|
||||
|
||||
Normal floating-point vector registers may also be negated by prepending a minus sign before it, e.g. `-r2` or `-someArray[lcnt+2]`.
|
||||
|
||||
## Command Line Usage
|
||||
|
||||
```
|
||||
Usage: picasso [options] files...
|
||||
Options:
|
||||
-o, --out=<file> Specifies the name of the SHBIN file to generate
|
||||
-h, --header=<file> Specifies the name of the header file to generate
|
||||
```
|
||||
|
||||
## Linking Model
|
||||
|
||||
`picasso` takes one or more source code files, and assembles them into a single `.shbin` file. A DVLE object is generated for each source code file, unless the `.nodvle` directive is used (see below). Procedures are shared amongst all source code files, and they may be defined and called wherever. Uniform space is also shared, that is, if two source code files declare the same uniform, they are assigned the same location. Constants however are not shared, and the same space is reused for the constants of each DVLE. Outputs and aliases are necessarily not shared either.
|
||||
|
||||
The entry point of a DVLE may be set with the `.entry` directive. If this directive is not used, `main` is assumed as the entrypoint.
|
||||
|
||||
Uniforms that start with the underscore (`_`) character are not exposed in the DVLE table of uniforms. This allows for creating private uniforms that can be internally used to configure the behaviour of shared procedures.
|
||||
|
||||
## Supported Directives
|
||||
|
||||
### .proc
|
||||
@ -173,6 +184,24 @@ Specifies the name of the procedure to use as the entrypoint of the current DVLE
|
||||
```
|
||||
This directive tells `picasso` not to generate a DVLE for the source code file that is being processed. This allows for writing files that contain shared procedures to be used by other files.
|
||||
|
||||
### .setf
|
||||
```
|
||||
.setf register(x, y, z, w)
|
||||
```
|
||||
Similar to `.constf`, this directive adds a DVLE constant entry for the specified floating-point vector uniform register to be loaded with the specified value. This is useful in order to instantiate a generalized shared procedure with the specified parameters.
|
||||
|
||||
### .seti
|
||||
```
|
||||
.seti register(x, y, z, w)
|
||||
```
|
||||
Similar to `.consti`, this directive adds a DVLE constant entry for the specified integer vector uniform register to be loaded with the specified value. This is useful in order to instantiate a generalized shared procedure with the specified parameters.
|
||||
|
||||
### .setb
|
||||
```
|
||||
.setb register value
|
||||
```
|
||||
This directive adds a DVLE constant entry for the specified boolean uniform register to be loaded with the specified value (which may be `true`, `false`, `on`, `off`, `1` or `0`). This is useful in order to control the flow of a generalized shared procedure.
|
||||
|
||||
## Supported Instructions
|
||||
|
||||
See [Shader Instruction Set](http://3dbrew.org/wiki/Shader_Instruction_Set) for more details.
|
||||
@ -221,7 +250,7 @@ Syntax | Description
|
||||
- In instructions that take one source operand, it is always wide.
|
||||
- In instructions that take two source operands, the first is wide and the second is narrow.
|
||||
- `dph`/`sge`/`slt` have a special form where the first operand is narrow and the second is wide. This usage is detected automatically by `picasso`.
|
||||
- `mad`, which takes three source operands, has two forms: the first is wide-wide-narrow, and the second is wide-narrow-wide. This is also detected automatically.
|
||||
- `mad`, which takes three source operands, has two forms: the first is wide-wide-narrow, and the second is wide-narrow-wide. This is also detected automatically. Additionally, relative addressing is not supported.
|
||||
- `iReg`: Represents an integer vector uniform source operand.
|
||||
- `bReg`: Represents a boolean uniform source operand.
|
||||
- `procName`: Represents the name of a procedure.
|
||||
|
@ -171,6 +171,7 @@ struct Constant
|
||||
{
|
||||
float fparam[4];
|
||||
u8 iparam[4];
|
||||
bool bparam;
|
||||
};
|
||||
};
|
||||
|
||||
@ -191,7 +192,6 @@ struct DVLEData
|
||||
#define MAX_CONSTANT 0x60
|
||||
Constant constantTable[MAX_CONSTANT];
|
||||
int constantCount;
|
||||
size_t constantSize;
|
||||
|
||||
// Outputs
|
||||
#define MAX_OUTPUT 8
|
||||
@ -201,5 +201,5 @@ struct DVLEData
|
||||
DVLEData(const char* filename) :
|
||||
filename(filename), entrypoint("main"),
|
||||
nodvle(false), isGeoShader(false),
|
||||
uniformCount(0), symbolSize(0), constantCount(0), constantSize(0), outputCount(0) { }
|
||||
uniformCount(0), symbolSize(0), constantCount(0), outputCount(0) { }
|
||||
};
|
||||
|
@ -1361,14 +1361,12 @@ DEF_DIRECTIVE(const)
|
||||
ct.fparam[1] = atof(arg1Text);
|
||||
ct.fparam[2] = atof(arg2Text);
|
||||
ct.fparam[3] = atof(arg3Text);
|
||||
dvle->constantSize += 4 + 4*4;
|
||||
} else if (dirParam == UTYPE_IVEC)
|
||||
{
|
||||
ct.iparam[0] = atoi(arg0Text) & 0xFF;
|
||||
ct.iparam[1] = atoi(arg1Text) & 0xFF;
|
||||
ct.iparam[2] = atoi(arg2Text) & 0xFF;
|
||||
ct.iparam[3] = atoi(arg3Text) & 0xFF;
|
||||
dvle->constantSize += 4 + 4;
|
||||
}
|
||||
|
||||
g_aliases.insert( std::pair<std::string,int>(constName, ct.regId | (DEFAULT_OPSRC<<8)) );
|
||||
@ -1382,6 +1380,93 @@ DEF_DIRECTIVE(const)
|
||||
return 0;
|
||||
};
|
||||
|
||||
DEF_DIRECTIVE(setfi)
|
||||
{
|
||||
DVLEData* dvle = GetDvleData();
|
||||
|
||||
NEXT_ARG_CPAREN(constName);
|
||||
NEXT_ARG(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);
|
||||
|
||||
ARG_TO_REG(constReg, constName);
|
||||
if (dirParam == UTYPE_FVEC)
|
||||
{
|
||||
if (constReg < 0x20 || constReg >= 0x80)
|
||||
return throwError("invalid floating point vector uniform: %s\n", constName);
|
||||
} else if (dirParam == UTYPE_IVEC)
|
||||
{
|
||||
if (constReg < 0x80 || constReg >= 0x84)
|
||||
return throwError("invalid integer vector uniform: %s\n", constName);
|
||||
}
|
||||
|
||||
if (dvle->constantCount == MAX_CONSTANT)
|
||||
return throwError("too many local constants\n");
|
||||
|
||||
Constant& ct = dvle->constantTable[dvle->constantCount++];
|
||||
ct.regId = constReg;
|
||||
ct.type = dirParam;
|
||||
if (dirParam == UTYPE_FVEC)
|
||||
{
|
||||
ct.fparam[0] = atof(arg0Text);
|
||||
ct.fparam[1] = atof(arg1Text);
|
||||
ct.fparam[2] = atof(arg2Text);
|
||||
ct.fparam[3] = atof(arg3Text);
|
||||
} else if (dirParam == UTYPE_IVEC)
|
||||
{
|
||||
ct.iparam[0] = atoi(arg0Text) & 0xFF;
|
||||
ct.iparam[1] = atoi(arg1Text) & 0xFF;
|
||||
ct.iparam[2] = atoi(arg2Text) & 0xFF;
|
||||
ct.iparam[3] = atoi(arg3Text) & 0xFF;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parseBool(bool& out, const char* text)
|
||||
{
|
||||
if (stricmp(text, "true")==0 || stricmp(text, "on")==0 || stricmp(text, "1")==0)
|
||||
{
|
||||
out = true;
|
||||
return 0;
|
||||
}
|
||||
if (stricmp(text, "false")==0 || stricmp(text, "off")==0 || stricmp(text, "0")==0)
|
||||
{
|
||||
out = false;
|
||||
return 0;
|
||||
}
|
||||
return throwError("invalid bool value: %s\n", text);
|
||||
}
|
||||
|
||||
DEF_DIRECTIVE(setb)
|
||||
{
|
||||
DVLEData* dvle = GetDvleData();
|
||||
|
||||
NEXT_ARG_SPC(constName);
|
||||
NEXT_ARG_SPC(valueText);
|
||||
ENSURE_NO_MORE_ARGS();
|
||||
ARG_TO_BREG(constReg, constName);
|
||||
|
||||
bool constVal = false;
|
||||
safe_call(parseBool(constVal, valueText));
|
||||
|
||||
if (dvle->constantCount == MAX_CONSTANT)
|
||||
return throwError("too many local constants\n");
|
||||
|
||||
Constant& ct = dvle->constantTable[dvle->constantCount++];
|
||||
ct.regId = constReg;
|
||||
ct.type = UTYPE_BOOL;
|
||||
ct.bparam = constVal;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parseOutType(const char* text)
|
||||
{
|
||||
if (stricmp(text,"pos")==0 || stricmp(text,"position")==0)
|
||||
@ -1487,6 +1572,9 @@ static const cmdTableType dirTable[] =
|
||||
DEC_DIRECTIVE(out),
|
||||
DEC_DIRECTIVE(entry),
|
||||
DEC_DIRECTIVE(nodvle),
|
||||
DEC_DIRECTIVE2(setf, setfi, UTYPE_FVEC),
|
||||
DEC_DIRECTIVE2(seti, setfi, UTYPE_IVEC),
|
||||
DEC_DIRECTIVE(setb),
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
|
@ -129,7 +129,7 @@ int main(int argc, char* argv[])
|
||||
if (dvle->nodvle) continue;
|
||||
f.WriteWord(curOff);
|
||||
curOff += 16*4; // Header
|
||||
curOff += dvle->constantSize;
|
||||
curOff += dvle->constantCount*20;
|
||||
curOff += dvle->outputCount*8;
|
||||
curOff += dvle->uniformCount*8;
|
||||
curOff += dvle->symbolSize;
|
||||
@ -171,7 +171,7 @@ int main(int argc, char* argv[])
|
||||
f.WriteWord(0); // ???
|
||||
f.WriteWord(curOff); // offset to constant table
|
||||
f.WriteWord(dvle->constantCount); // size of constant table
|
||||
curOff += dvle->constantSize;
|
||||
curOff += dvle->constantCount*5*4;
|
||||
f.WriteWord(curOff); // offset to label table (TODO)
|
||||
f.WriteWord(0); // size of label table (TODO)
|
||||
f.WriteWord(curOff); // offset to output table
|
||||
@ -199,7 +199,14 @@ int main(int argc, char* argv[])
|
||||
f.WriteHword(ct.regId-0x80);
|
||||
for (int j = 0; j < 4; j ++)
|
||||
f.WriteByte(ct.iparam[j]);
|
||||
} else if (ct.type == UTYPE_BOOL)
|
||||
{
|
||||
f.WriteHword(ct.regId-0x88);
|
||||
f.WriteWord(ct.bparam ? 1 : 0);
|
||||
}
|
||||
if (ct.type != UTYPE_FVEC)
|
||||
for (int j = 0; j < 3; j ++)
|
||||
f.WriteWord(0); // Padding
|
||||
}
|
||||
|
||||
// Write outputs
|
||||
|
Loading…
Reference in New Issue
Block a user