Geoshader support!

This commit is contained in:
fincs 2015-03-04 22:42:34 +01:00
parent 01104710fd
commit 6e176f33c5
4 changed files with 66 additions and 11 deletions

View File

@ -137,10 +137,10 @@ Reserves a new integer vector uniform to be preloaded with the specified constan
```
Allocates a new output register, wires it to a certain output property and creates an alias for it that points to the allocated register. The following property names are supported:
- `position` (or `pos`): In vertex shaders, this represents the position of the outputted vertex.
- `position` (or `pos`): Represents the position of the outputted vertex.
- `normalquat` (or `nquat`): Under investigation.
- `color` (or `clr`): In vertex shaders, this represents the color of the outputted vertex. Its format is (R, G, B, xx) where R,G,B are values ranging from 0.0 to 1.0. The W component isn't used.
- `texcoord0` (or `tcoord0`): In vertex shaders, this represents the texture coordinate that is fed to the Texture Unit 0. The Z and W components are not used.
- `color` (or `clr`): Represents the color of the outputted vertex. Its format is (R, G, B, xx) where R,G,B are values ranging from 0.0 to 1.0. The W component isn't used.
- `texcoord0` (or `tcoord0`): Represents the texture coordinate that is fed to the Texture Unit 0. The Z and W components are not used.
- `texcoord0w` (or `tcoord0w`): Under investigation.
- `texcoord1` (or `tcoord1`): As `texcoord0`, but for the Texture Unit 1.
- `texcoord2` (or `tcoord2`): As `texcoord0`, but for the Texture Unit 2.
@ -163,6 +163,8 @@ Syntax | Description
--------------------------------- | -----------------------------------
`nop` | No operation.
`end` | Signals the end of the program.
`emit` | (Geoshader-only) Emits a vertex configured by a prior `setemit`.
`setemit vtxId, emitFlags | (Geoshader-only) Configures a vertex for emission. The `emitFlags` parameter can be omitted.
`add rDest, rSrc1, rSrc2` |
`dp3 rDest, rSrc1, rSrc2` |
`dp4 rDest, rSrc1, rSrc2` |
@ -217,3 +219,7 @@ Syntax | Description
- `flag1`: It tests a single flag.
- `flag1 && flag2`: It performs AND between the two flags. Optionally, a single `&` may be specified.
- `flag1 || flag2`: It performs OR between the two flags. Optionally, a single `|` may be specified.
- `vtxId`: An integer ranging from 0 to 3 specifying the vertex ID used in geoshader vertex emission.
- `emitFlags`: A space delimited combination of the following words:
- `primitive` (or `prim`): Specifies that after emitting the vertex, a primitive should also be emitted.
- `inv` (or `invert`): Specifies that the order of the vertices in the emitted primitive is inverted.

View File

@ -61,6 +61,7 @@ enum
typedef std::vector<u32> outputBufType;
typedef outputBufType::iterator outputBufIter;
extern bool g_isGeoShader;
extern outputBufType g_outputBuf;
enum

View File

@ -7,6 +7,7 @@
static const char* curFile = NULL;
static int curLine = -1;
bool g_isGeoShader = false;
std::vector<u32> g_outputBuf;
StackEntry g_stack[MAX_STACK];
@ -561,9 +562,12 @@ static int parseReg(char* pos, int& outReg, int& outSw, int* idxType = NULL)
switch (*pos)
{
case 'o': // Output registers
case 'v': // Input attributes
if (outReg < 0x00 || outReg >= 0x08)
return throwError("invalid input/output register: %s(%d)\n", pos);
return throwError("invalid output register: %s(%d)\n", pos);
break;
case 'v': // Input attributes
if (outReg < 0x00 || outReg >= 0x0F)
return throwError("invalid input register: %s(%d)\n", pos);
break;
case 'r': // Temporary registers
outReg += 0x10;
@ -805,6 +809,46 @@ DEF_COMMAND(formatmova)
return 0;
}
static inline int parseSetEmitFlags(char* flags, bool& isPrim, bool& isInv)
{
isPrim = false;
isInv = false;
if (!flags)
return 0;
mystrtok_pos = flags;
while (char* flag = mystrtok_spc(NULL))
{
if (stricmp(flag, "prim")==0 || stricmp(flag, "primitive")==0)
isPrim = true;
else if (stricmp(flag, "inv")==0 || stricmp(flag, "invert")==0)
isInv = true;
else
throwError("unknown setemit flag: %s\n", flag);
}
return 0;
}
DEF_COMMAND(formatsetemit)
{
NEXT_ARG(vtxIdStr);
NEXT_ARG_OPT(flagStr, NULL);
ENSURE_NO_MORE_ARGS();
ARG_TO_INT(vtxId, vtxIdStr, 0, 3);
bool isPrim, isInv;
safe_call(parseSetEmitFlags(flagStr, isPrim, isInv));
#ifdef DEBUG
printf("%s:%02X vtx%d, %s, %s\n", cmdName, opcode, vtxId, isPrim?"true":"false", isInv=?"true":"false");
#endif
BUF.push_back(FMT_OPCODE(opcode) | ((u32)isInv<<22) | ((u32)isPrim<<23) | (vtxId<<24));
g_isGeoShader = true;
return 0;
}
DEF_COMMAND(formatcall)
{
NEXT_ARG(procName);
@ -967,6 +1011,7 @@ static const cmdTableType cmdTable[] =
{
DEC_COMMAND(NOP, format0),
DEC_COMMAND(END, format0),
DEC_COMMAND(EMIT, format0),
DEC_COMMAND(ADD, format1),
DEC_COMMAND(DP3, format1),
@ -1009,6 +1054,8 @@ static const cmdTableType cmdTable[] =
DEC_COMMAND(MADI, format5i),
DEC_COMMAND(MAD, format5),
DEC_COMMAND(SETEMIT, formatsetemit),
{ NULL, NULL },
};

View File

@ -105,7 +105,7 @@ int main(int argc, char* argv[])
f.WriteWord(0x454C5644); // DVLE
f.WriteHword(0); // padding?
f.WriteHword(0); // Vertex shader
f.WriteHword(g_isGeoShader ? 1 : 0); // Shader type
f.WriteWord(mainIt->second.first); // offset to main
f.WriteWord(mainIt->second.first+mainIt->second.second); // offset to end of main
f.WriteWord(0); // ???
@ -192,21 +192,22 @@ int main(int argc, char* argv[])
fprintf(f2, "// Generated by picasso\n");
fprintf(f2, "#pragma once\n");
const char* prefix = g_isGeoShader ? "GSH" : "VSH";
for (int i = 0; i < g_uniformCount; i ++)
{
Uniform& u = g_uniformTable[i];
if (u.type == UTYPE_FVEC)
fprintf(f2, "#define SHADER_FVEC_%s 0x%02X\n", u.name, u.pos-0x20);
fprintf(f2, "#define %s_FVEC_%s 0x%02X\n", prefix, u.name, u.pos-0x20);
else if (u.type == UTYPE_IVEC)
fprintf(f2, "#define SHADER_IVEC_%s 0x%02X\n", u.name, u.pos-0x80);
fprintf(f2, "#define %s_IVEC_%s 0x%02X\n", prefix, u.name, u.pos-0x80);
else if (u.type == UTYPE_BOOL)
{
if (u.size == 1)
fprintf(f2, "#define SHADER_FLAG_%s BIT(%d)\n", u.name, u.pos-0x88);
fprintf(f2, "#define %s_FLAG_%s BIT(%d)\n", prefix, u.name, u.pos-0x88);
else
fprintf(f2, "#define SHADER_FLAG_%s(_n) BIT(%d+(_n))\n", u.name, u.pos-0x88);
fprintf(f2, "#define %s_FLAG_%s(_n) BIT(%d+(_n))\n", prefix, u.name, u.pos-0x88);
}
fprintf(f2, "#define SHADER_ULEN_%s %d\n", u.name, u.size);
fprintf(f2, "#define %s_ULEN_%s %d\n", prefix, u.name, u.size);
}
fclose(f2);