Skip to content

Commit 6e176f3

Browse files
committed
Geoshader support!
1 parent 0110471 commit 6e176f3

4 files changed

Lines changed: 66 additions & 11 deletions

File tree

Manual.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,10 @@ Reserves a new integer vector uniform to be preloaded with the specified constan
137137
```
138138
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:
139139

140-
- `position` (or `pos`): In vertex shaders, this represents the position of the outputted vertex.
140+
- `position` (or `pos`): Represents the position of the outputted vertex.
141141
- `normalquat` (or `nquat`): Under investigation.
142-
- `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.
143-
- `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.
142+
- `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.
143+
- `texcoord0` (or `tcoord0`): Represents the texture coordinate that is fed to the Texture Unit 0. The Z and W components are not used.
144144
- `texcoord0w` (or `tcoord0w`): Under investigation.
145145
- `texcoord1` (or `tcoord1`): As `texcoord0`, but for the Texture Unit 1.
146146
- `texcoord2` (or `tcoord2`): As `texcoord0`, but for the Texture Unit 2.
@@ -163,6 +163,8 @@ Syntax | Description
163163
--------------------------------- | -----------------------------------
164164
`nop` | No operation.
165165
`end` | Signals the end of the program.
166+
`emit` | (Geoshader-only) Emits a vertex configured by a prior `setemit`.
167+
`setemit vtxId, emitFlags | (Geoshader-only) Configures a vertex for emission. The `emitFlags` parameter can be omitted.
166168
`add rDest, rSrc1, rSrc2` |
167169
`dp3 rDest, rSrc1, rSrc2` |
168170
`dp4 rDest, rSrc1, rSrc2` |
@@ -217,3 +219,7 @@ Syntax | Description
217219
- `flag1`: It tests a single flag.
218220
- `flag1 && flag2`: It performs AND between the two flags. Optionally, a single `&` may be specified.
219221
- `flag1 || flag2`: It performs OR between the two flags. Optionally, a single `|` may be specified.
222+
- `vtxId`: An integer ranging from 0 to 3 specifying the vertex ID used in geoshader vertex emission.
223+
- `emitFlags`: A space delimited combination of the following words:
224+
- `primitive` (or `prim`): Specifies that after emitting the vertex, a primitive should also be emitted.
225+
- `inv` (or `invert`): Specifies that the order of the vertices in the emitted primitive is inverted.

source/picasso.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ enum
6161
typedef std::vector<u32> outputBufType;
6262
typedef outputBufType::iterator outputBufIter;
6363

64+
extern bool g_isGeoShader;
6465
extern outputBufType g_outputBuf;
6566

6667
enum

source/picasso_assembler.cpp

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
static const char* curFile = NULL;
88
static int curLine = -1;
99

10+
bool g_isGeoShader = false;
1011
std::vector<u32> g_outputBuf;
1112

1213
StackEntry g_stack[MAX_STACK];
@@ -561,9 +562,12 @@ static int parseReg(char* pos, int& outReg, int& outSw, int* idxType = NULL)
561562
switch (*pos)
562563
{
563564
case 'o': // Output registers
564-
case 'v': // Input attributes
565565
if (outReg < 0x00 || outReg >= 0x08)
566-
return throwError("invalid input/output register: %s(%d)\n", pos);
566+
return throwError("invalid output register: %s(%d)\n", pos);
567+
break;
568+
case 'v': // Input attributes
569+
if (outReg < 0x00 || outReg >= 0x0F)
570+
return throwError("invalid input register: %s(%d)\n", pos);
567571
break;
568572
case 'r': // Temporary registers
569573
outReg += 0x10;
@@ -805,6 +809,46 @@ DEF_COMMAND(formatmova)
805809
return 0;
806810
}
807811

812+
static inline int parseSetEmitFlags(char* flags, bool& isPrim, bool& isInv)
813+
{
814+
isPrim = false;
815+
isInv = false;
816+
if (!flags)
817+
return 0;
818+
819+
mystrtok_pos = flags;
820+
while (char* flag = mystrtok_spc(NULL))
821+
{
822+
if (stricmp(flag, "prim")==0 || stricmp(flag, "primitive")==0)
823+
isPrim = true;
824+
else if (stricmp(flag, "inv")==0 || stricmp(flag, "invert")==0)
825+
isInv = true;
826+
else
827+
throwError("unknown setemit flag: %s\n", flag);
828+
829+
}
830+
return 0;
831+
}
832+
833+
DEF_COMMAND(formatsetemit)
834+
{
835+
NEXT_ARG(vtxIdStr);
836+
NEXT_ARG_OPT(flagStr, NULL);
837+
ENSURE_NO_MORE_ARGS();
838+
839+
ARG_TO_INT(vtxId, vtxIdStr, 0, 3);
840+
bool isPrim, isInv;
841+
safe_call(parseSetEmitFlags(flagStr, isPrim, isInv));
842+
843+
#ifdef DEBUG
844+
printf("%s:%02X vtx%d, %s, %s\n", cmdName, opcode, vtxId, isPrim?"true":"false", isInv=?"true":"false");
845+
#endif
846+
BUF.push_back(FMT_OPCODE(opcode) | ((u32)isInv<<22) | ((u32)isPrim<<23) | (vtxId<<24));
847+
g_isGeoShader = true;
848+
849+
return 0;
850+
}
851+
808852
DEF_COMMAND(formatcall)
809853
{
810854
NEXT_ARG(procName);
@@ -967,6 +1011,7 @@ static const cmdTableType cmdTable[] =
9671011
{
9681012
DEC_COMMAND(NOP, format0),
9691013
DEC_COMMAND(END, format0),
1014+
DEC_COMMAND(EMIT, format0),
9701015

9711016
DEC_COMMAND(ADD, format1),
9721017
DEC_COMMAND(DP3, format1),
@@ -1009,6 +1054,8 @@ static const cmdTableType cmdTable[] =
10091054
DEC_COMMAND(MADI, format5i),
10101055
DEC_COMMAND(MAD, format5),
10111056

1057+
DEC_COMMAND(SETEMIT, formatsetemit),
1058+
10121059
{ NULL, NULL },
10131060
};
10141061

source/picasso_frontend.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ int main(int argc, char* argv[])
105105

106106
f.WriteWord(0x454C5644); // DVLE
107107
f.WriteHword(0); // padding?
108-
f.WriteHword(0); // Vertex shader
108+
f.WriteHword(g_isGeoShader ? 1 : 0); // Shader type
109109
f.WriteWord(mainIt->second.first); // offset to main
110110
f.WriteWord(mainIt->second.first+mainIt->second.second); // offset to end of main
111111
f.WriteWord(0); // ???
@@ -192,21 +192,22 @@ int main(int argc, char* argv[])
192192

193193
fprintf(f2, "// Generated by picasso\n");
194194
fprintf(f2, "#pragma once\n");
195+
const char* prefix = g_isGeoShader ? "GSH" : "VSH";
195196
for (int i = 0; i < g_uniformCount; i ++)
196197
{
197198
Uniform& u = g_uniformTable[i];
198199
if (u.type == UTYPE_FVEC)
199-
fprintf(f2, "#define SHADER_FVEC_%s 0x%02X\n", u.name, u.pos-0x20);
200+
fprintf(f2, "#define %s_FVEC_%s 0x%02X\n", prefix, u.name, u.pos-0x20);
200201
else if (u.type == UTYPE_IVEC)
201-
fprintf(f2, "#define SHADER_IVEC_%s 0x%02X\n", u.name, u.pos-0x80);
202+
fprintf(f2, "#define %s_IVEC_%s 0x%02X\n", prefix, u.name, u.pos-0x80);
202203
else if (u.type == UTYPE_BOOL)
203204
{
204205
if (u.size == 1)
205-
fprintf(f2, "#define SHADER_FLAG_%s BIT(%d)\n", u.name, u.pos-0x88);
206+
fprintf(f2, "#define %s_FLAG_%s BIT(%d)\n", prefix, u.name, u.pos-0x88);
206207
else
207-
fprintf(f2, "#define SHADER_FLAG_%s(_n) BIT(%d+(_n))\n", u.name, u.pos-0x88);
208+
fprintf(f2, "#define %s_FLAG_%s(_n) BIT(%d+(_n))\n", prefix, u.name, u.pos-0x88);
208209
}
209-
fprintf(f2, "#define SHADER_ULEN_%s %d\n", u.name, u.size);
210+
fprintf(f2, "#define %s_ULEN_%s %d\n", prefix, u.name, u.size);
210211
}
211212

212213
fclose(f2);

0 commit comments

Comments
 (0)