Skip to content

Commit

Permalink
Standalone: Implement -D and -U for preprocessor macros.
Browse files Browse the repository at this point in the history
Works for both GLSL and HLSL.
Fixes KhronosGroup#87.
  • Loading branch information
johnkslang committed Jun 15, 2017
1 parent 04acb1b commit a931366
Show file tree
Hide file tree
Showing 7 changed files with 262 additions and 13 deletions.
73 changes: 68 additions & 5 deletions StandAlone/StandAlone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,53 @@ std::array<unsigned int, EShLangCount> baseSsboBinding;
std::array<unsigned int, EShLangCount> baseUavBinding;
std::array<std::vector<std::string>, EShLangCount> baseResourceSetBinding;


// Add things like "#define ..." to a preamble to use in the beginning of the shader.
class TPreamble {
public:
TPreamble() { }

bool isSet() const { return text.size() > 0; }
const char* get() const { return text.c_str(); }

// #define...
void addDef(std::string def)
{
text.append("#define ");
fixLine(def);

// The first "=" needs to turn into a space
int equal = def.find_first_of("=");
if (equal != def.npos)
def[equal] = ' ';

text.append(def);
text.append("\n");
}

// #undef...
void addUndef(std::string undef)
{
text.append("#undef ");
fixLine(undef);
text.append(undef);
text.append("\n");
}

protected:
void fixLine(std::string& line)
{
// Can't go past a newline in the line
int end = line.find_first_of("\n");
if (end != line.npos)
line = line.substr(0, end);
}

std::string text; // contents of preamble
};

TPreamble UserPreamble;

//
// Create the default name for saving a binary if -o is not provided.
//
Expand Down Expand Up @@ -391,7 +438,10 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
Options |= EOptionCascadingErrors;
break;
case 'D':
Options |= EOptionReadHlsl;
if (argv[0][2] == 0)
Options |= EOptionReadHlsl;
else
UserPreamble.addDef(getStringOperand("-D<macro> macro name"));
break;
case 'E':
Options |= EOptionOutputPreprocessed;
Expand All @@ -412,7 +462,7 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
}
break;
case 'I':
IncludeDirectoryList.push_back(getStringOperand("-I include path"));
IncludeDirectoryList.push_back(getStringOperand("-I<dir> include path"));
break;
case 'S':
shaderStageName = argv[1];
Expand All @@ -422,6 +472,9 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
} else
Error("no <stage> specified for -S");
break;
case 'U':
UserPreamble.addUndef(getStringOperand("-U<macro>: macro name"));
break;
case 'V':
Options |= EOptionSpv;
Options |= EOptionVulkanRules;
Expand Down Expand Up @@ -584,7 +637,7 @@ struct ShaderCompUnit {
EShLanguage stage;
static const int maxCount = 1;
int count; // live number of strings/names
char* text[maxCount]; // memory owned/managed externally
const char* text[maxCount]; // memory owned/managed externally
std::string fileName[maxCount]; // hold's the memory, but...
const char* fileNameList[maxCount]; // downstream interface wants pointers

Expand All @@ -601,7 +654,7 @@ struct ShaderCompUnit {
}
}

void addString(std::string& ifileName, char* itext)
void addString(std::string& ifileName, const char* itext)
{
assert(count < maxCount);
fileName[count] = ifileName;
Expand Down Expand Up @@ -640,6 +693,8 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
shader->setEntryPoint(entryPointName);
if (sourceEntryPointName)
shader->setSourceEntryPoint(sourceEntryPointName);
if (UserPreamble.isSet())
shader->setPreamble(UserPreamble.get());

shader->setShiftSamplerBinding(baseSamplerBinding[compUnit.stage]);
shader->setShiftTextureBinding(baseTextureBinding[compUnit.stage]);
Expand Down Expand Up @@ -806,8 +861,10 @@ void CompileAndLinkShaderFiles(glslang::TWorklist& Worklist)
glslang::OS_DumpMemoryCounters();
}

// free memory from ReadFileData, which got stored in a const char*
// as the first string above
for (auto it = compUnits.begin(); it != compUnits.end(); ++it)
FreeFileData(it->text[0]);
FreeFileData(const_cast<char*>(it->text[0]));
}

int C_DECL main(int argc, char* argv[])
Expand Down Expand Up @@ -966,6 +1023,9 @@ void CompileFile(const char* fileName, ShHandle compiler)
EShMessages messages = EShMsgDefault;
SetMessageOptions(messages);

if (UserPreamble.isSet())
Error("-D and -U options require -l (linking)\n");

for (int i = 0; i < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++i) {
for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j) {
// ret = ShCompile(compiler, shaderStrings, NumShaderStrings, lengths, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
Expand Down Expand Up @@ -1008,6 +1068,8 @@ void usage()
"Options:\n"
" -C cascading errors; risk crash from accumulation of error recoveries\n"
" -D input is HLSL\n"
" -D<macro=def>\n"
" -D<macro> define a pre-processor macro\n"
" -E print pre-processed GLSL; cannot be used with -l;\n"
" errors will appear on stderr.\n"
" -G create SPIR-V binary, under OpenGL semantics; turns on -l;\n"
Expand All @@ -1017,6 +1079,7 @@ void usage()
" is searched first, followed by left-to-right order of -I\n"
" -S <stage> uses specified stage rather than parsing the file extension\n"
" choices for <stage> are vert, tesc, tese, geom, frag, or comp\n"
" -U<macro> undefine a pre-precossor macro\n"
" -V create SPIR-V binary, under Vulkan semantics; turns on -l;\n"
" default file name is <stage>.spv (-o overrides this)\n"
" -c configuration dump;\n"
Expand Down
47 changes: 47 additions & 0 deletions Test/baseResults/glsl.-D-U.frag.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
glsl.-D-U.frag
Shader version: 450
0:? Sequence
0:7 Function Definition: main( ( global void)
0:7 Function Parameters:
0:10 Sequence
0:10 move second child to first child ( temp 4-component vector of float)
0:10 'color' (layout( location=0) out 4-component vector of float)
0:10 Constant:
0:10 1.000000
0:10 1.000000
0:10 1.000000
0:10 1.000000
0:16 Post-Increment ( temp 4-component vector of float)
0:16 'color' (layout( location=0) out 4-component vector of float)
0:24 vector scale second child into first child ( temp 4-component vector of float)
0:24 'color' (layout( location=0) out 4-component vector of float)
0:24 Constant:
0:24 3.000000
0:? Linker Objects
0:? 'color' (layout( location=0) out 4-component vector of float)


Linked fragment stage:


Shader version: 450
0:? Sequence
0:7 Function Definition: main( ( global void)
0:7 Function Parameters:
0:10 Sequence
0:10 move second child to first child ( temp 4-component vector of float)
0:10 'color' (layout( location=0) out 4-component vector of float)
0:10 Constant:
0:10 1.000000
0:10 1.000000
0:10 1.000000
0:10 1.000000
0:16 Post-Increment ( temp 4-component vector of float)
0:16 'color' (layout( location=0) out 4-component vector of float)
0:24 vector scale second child into first child ( temp 4-component vector of float)
0:24 'color' (layout( location=0) out 4-component vector of float)
0:24 Constant:
0:24 3.000000
0:? Linker Objects
0:? 'color' (layout( location=0) out 4-component vector of float)

65 changes: 65 additions & 0 deletions Test/baseResults/hlsl.-D-U.frag.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
hlsl.-D-U.frag
Shader version: 500
gl_FragCoord origin is upper left
0:? Sequence
0:7 Function Definition: @main( ( temp void)
0:7 Function Parameters:
0:? Sequence
0:9 move second child to first child ( temp 4-component vector of float)
0:9 'color' ( global 4-component vector of float)
0:9 Constant:
0:9 1.000000
0:9 1.000000
0:9 1.000000
0:9 1.000000
0:15 subtract second child into first child ( temp 4-component vector of float)
0:15 'color' ( global 4-component vector of float)
0:15 Constant:
0:15 5.000000
0:21 Post-Increment ( temp 4-component vector of float)
0:21 'color' ( global 4-component vector of float)
0:29 vector scale second child into first child ( temp 4-component vector of float)
0:29 'color' ( global 4-component vector of float)
0:29 Constant:
0:29 3.000000
0:7 Function Definition: main( ( temp void)
0:7 Function Parameters:
0:? Sequence
0:7 Function Call: @main( ( temp void)
0:? Linker Objects
0:? 'color' ( global 4-component vector of float)


Linked fragment stage:


Shader version: 500
gl_FragCoord origin is upper left
0:? Sequence
0:7 Function Definition: @main( ( temp void)
0:7 Function Parameters:
0:? Sequence
0:9 move second child to first child ( temp 4-component vector of float)
0:9 'color' ( global 4-component vector of float)
0:9 Constant:
0:9 1.000000
0:9 1.000000
0:9 1.000000
0:9 1.000000
0:15 subtract second child into first child ( temp 4-component vector of float)
0:15 'color' ( global 4-component vector of float)
0:15 Constant:
0:15 5.000000
0:21 Post-Increment ( temp 4-component vector of float)
0:21 'color' ( global 4-component vector of float)
0:29 vector scale second child into first child ( temp 4-component vector of float)
0:29 'color' ( global 4-component vector of float)
0:29 Constant:
0:29 3.000000
0:7 Function Definition: main( ( temp void)
0:7 Function Parameters:
0:? Sequence
0:7 Function Call: @main( ( temp void)
0:? Linker Objects
0:? 'color' ( global 4-component vector of float)

32 changes: 32 additions & 0 deletions Test/glsl.-D-U.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#version 450

#define IN_SHADER

layout(location=0) out vec4 color;

void main()
{
#if FOO==200
color = vec4(1.0);
#else
#error expected FOO 200
#endif

#ifdef IN_SHADER
color++;
#else
#error IN_SHADER was undef
#endif

#ifdef UNDEFED
#error UNDEFED defined
#else
color *= 3.0;
#endif

#if MUL == 400
color *= MUL;
#else
#error bad MUL
#endif
}
31 changes: 31 additions & 0 deletions Test/hlsl.-D-U.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

#define IN_SHADER

static float4 color;

void main()
{
#if FOO==200
color = 1.0;
#else
#error expected FOO 200
#endif

#ifdef FOO
color -= 5.0;
#else
#error expected FOO 200
#endif

#ifdef IN_SHADER
color++;
#else
#error IN_SHADER was undef
#endif

#ifdef UNDEFED
#error UNDEFED defined
#else
color *= 3.0;
#endif
}
8 changes: 8 additions & 0 deletions Test/runtests
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ diff -b $BASEDIR/include.vert.out $TARGETDIR/include.vert.out || HASERROR=1
$EXE -D -e main -H -Iinc1/path1 -Iinc1/path2 hlsl.dashI.vert > $TARGETDIR/hlsl.dashI.vert.out
diff -b $BASEDIR/hlsl.dashI.vert.out $TARGETDIR/hlsl.dashI.vert.out || HASERROR=1

#
# Testing -D and -U
#
$EXE -DUNDEFED -UIN_SHADER -DFOO=200 -i -l -UUNDEFED -DMUL=FOO*2 glsl.-D-U.frag > $TARGETDIR/glsl.-D-U.frag.out
diff -b $BASEDIR/glsl.-D-U.frag.out $TARGETDIR/glsl.-D-U.frag.out || HASERROR=1
$EXE -D -e main -V -i -DUNDEFED -UIN_SHADER -DFOO=200 -UUNDEFED hlsl.-D-U.frag > $TARGETDIR/hlsl.-D-U.frag.out
diff -b $BASEDIR/hlsl.-D-U.frag.out $TARGETDIR/hlsl.-D-U.frag.out || HASERROR=1

#
# Final checking
#
Expand Down
Loading

0 comments on commit a931366

Please sign in to comment.