Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
glslang
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
glslang
Commits
a8a83204
Commit
a8a83204
authored
Jun 26, 2017
by
John Kessenich
Committed by
GitHub
Jun 26, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #948 from KhronosGroup/env-control
Compilation-environment control
parents
4fbb8cb4
6353d55e
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
325 additions
and
83 deletions
+325
-83
StandAlone.cpp
StandAlone/StandAlone.cpp
+125
-50
runtests
Test/runtests
+10
-0
spv.targetOpenGL.vert
Test/spv.targetOpenGL.vert
+9
-0
spv.targetVulkan.vert
Test/spv.targetVulkan.vert
+9
-0
ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.cpp
+2
-1
ShaderLang.cpp
glslang/MachineIndependent/ShaderLang.cpp
+98
-23
Versions.cpp
glslang/MachineIndependent/Versions.cpp
+2
-2
Versions.h
glslang/MachineIndependent/Versions.h
+11
-6
ShaderLang.h
glslang/Public/ShaderLang.h
+59
-1
No files found.
StandAlone/StandAlone.cpp
View file @
a8a83204
...
...
@@ -148,6 +148,10 @@ const char* sourceEntryPointName = nullptr;
const
char
*
shaderStageName
=
nullptr
;
const
char
*
variableName
=
nullptr
;
std
::
vector
<
std
::
string
>
IncludeDirectoryList
;
int
ClientInputSemanticsVersion
=
100
;
// maps to, say, #define VULKAN 100
int
VulkanClientVersion
=
100
;
// would map to, say, Vulkan 1.0
int
OpenGLClientVersion
=
450
;
// doesn't influence anything yet, but maps to OpenGL 4.50
unsigned
int
TargetVersion
=
0x00001000
;
// maps to, say, SPIR-V 1.0
std
::
array
<
unsigned
int
,
EShLangCount
>
baseSamplerBinding
;
std
::
array
<
unsigned
int
,
EShLangCount
>
baseTextureBinding
;
...
...
@@ -157,7 +161,6 @@ 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
:
...
...
@@ -295,15 +298,15 @@ void ProcessResourceSetBindingBase(int& argc, char**& argv, std::array<std::vect
base
[
lang
].
push_back
(
argv
[
2
]);
base
[
lang
].
push_back
(
argv
[
3
]);
base
[
lang
].
push_back
(
argv
[
4
]);
argc
-=
4
;
argv
+=
4
;
argc
-=
4
;
argv
+=
4
;
while
(
argv
[
1
]
!=
NULL
)
{
if
(
argv
[
1
][
0
]
!=
'-'
)
{
base
[
lang
].
push_back
(
argv
[
1
]);
base
[
lang
].
push_back
(
argv
[
2
]);
base
[
lang
].
push_back
(
argv
[
3
]);
argc
-=
3
;
argv
+=
3
;
argc
-=
3
;
argv
+=
3
;
}
else
{
break
;
...
...
@@ -337,6 +340,14 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
ExecutableName
=
argv
[
0
];
workItems
.
reserve
(
argc
);
const
auto
bumpArg
=
[
&
]()
{
if
(
argc
>
0
)
{
argc
--
;
argv
++
;
}
};
// read a string directly attached to a single-letter option
const
auto
getStringOperand
=
[
&
](
const
char
*
desc
)
{
if
(
argv
[
0
][
2
]
==
0
)
{
printf
(
"%s must immediately follow option (no spaces)
\n
"
,
desc
);
...
...
@@ -345,9 +356,32 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
return
argv
[
0
]
+
2
;
};
argc
--
;
argv
++
;
for
(;
argc
>=
1
;
argc
--
,
argv
++
)
{
// read a number attached to a single-letter option
const
auto
getAttachedNumber
=
[
&
](
const
char
*
desc
)
{
int
num
=
atoi
(
argv
[
0
]
+
2
);
if
(
num
==
0
)
{
printf
(
"%s: expected attached non-0 number
\n
"
,
desc
);
exit
(
EFailUsage
);
}
return
num
;
};
// minimum needed (without overriding something else) to target Vulkan SPIR-V
const
auto
setVulkanSpv
=
[]()
{
Options
|=
EOptionSpv
;
Options
|=
EOptionVulkanRules
;
Options
|=
EOptionLinkProgram
;
};
// minimum needed (without overriding something else) to target OpenGL SPIR-V
const
auto
setOpenGlSpv
=
[]()
{
Options
|=
EOptionSpv
;
Options
|=
EOptionLinkProgram
;
// undo a -H default to Vulkan
Options
&=
~
EOptionVulkanRules
;
};
for
(
bumpArg
();
argc
>=
1
;
bumpArg
())
{
if
(
argv
[
0
][
0
]
==
'-'
)
{
switch
(
argv
[
0
][
1
])
{
case
'-'
:
...
...
@@ -357,12 +391,22 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
// handle --word style options
if
(
lowerword
==
"auto-map-bindings"
||
// synonyms
lowerword
==
"auto-map-binding"
||
lowerword
==
"amb"
)
{
lowerword
==
"auto-map-binding"
||
lowerword
==
"amb"
)
{
Options
|=
EOptionAutoMapBindings
;
}
else
if
(
lowerword
==
"auto-map-locations"
||
// synonyms
lowerword
==
"aml"
)
{
Options
|=
EOptionAutoMapLocations
;
}
else
if
(
lowerword
==
"client"
)
{
if
(
argc
>
1
)
{
if
(
strcmp
(
argv
[
1
],
"vulkan100"
)
==
0
)
setVulkanSpv
();
else
if
(
strcmp
(
argv
[
1
],
"opengl100"
)
==
0
)
setOpenGlSpv
();
else
Error
(
"--client expects vulkan100 or opengl100"
);
}
bumpArg
();
}
else
if
(
lowerword
==
"flatten-uniform-arrays"
||
// synonyms
lowerword
==
"flatten-uniform-array"
||
lowerword
==
"fua"
)
{
...
...
@@ -412,22 +456,30 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
ProcessBindingBase
(
argc
,
argv
,
baseSsboBinding
);
}
else
if
(
lowerword
==
"source-entrypoint"
||
// synonyms
lowerword
==
"sep"
)
{
sourceEntryPointName
=
argv
[
1
];
if
(
argc
>
0
)
{
argc
--
;
argv
++
;
}
else
if
(
argc
<=
1
)
Error
(
"no <entry-point> provided for --source-entrypoint"
);
sourceEntryPointName
=
argv
[
1
];
bumpArg
();
break
;
}
else
if
(
lowerword
==
"target-env"
)
{
if
(
argc
>
1
)
{
if
(
strcmp
(
argv
[
1
],
"vulkan1.0"
)
==
0
)
{
setVulkanSpv
();
VulkanClientVersion
=
100
;
}
else
if
(
strcmp
(
argv
[
1
],
"opengl"
)
==
0
)
{
setOpenGlSpv
();
OpenGLClientVersion
=
450
;
}
else
Error
(
"--target-env expected vulkan1.0 or opengl"
);
}
bumpArg
();
}
else
if
(
lowerword
==
"variable-name"
||
// synonyms
lowerword
==
"vn"
)
{
Options
|=
EOptionOutputHexadecimal
;
variableName
=
argv
[
1
];
if
(
argc
>
0
)
{
argc
--
;
argv
++
;
}
else
if
(
argc
<=
1
)
Error
(
"no <C-variable-name> provided for --variable-name"
);
variableName
=
argv
[
1
];
bumpArg
();
break
;
}
else
{
usage
();
...
...
@@ -447,38 +499,34 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
Options
|=
EOptionOutputPreprocessed
;
break
;
case
'G'
:
Options
|=
EOptionSpv
;
Options
|=
EOptionLinkProgram
;
// undo a -H default to Vulkan
Options
&=
~
EOptionVulkanRules
;
// OpenGL Client
setOpenGlSpv
()
;
if
(
argv
[
0
][
2
]
!=
0
)
ClientInputSemanticsVersion
=
getAttachedNumber
(
"-G<num> client input semantics"
)
;
break
;
case
'H'
:
Options
|=
EOptionHumanReadableSpv
;
if
((
Options
&
EOptionSpv
)
==
0
)
{
// default to Vulkan
Options
|=
EOptionSpv
;
Options
|=
EOptionVulkanRules
;
Options
|=
EOptionLinkProgram
;
setVulkanSpv
();
}
break
;
case
'I'
:
IncludeDirectoryList
.
push_back
(
getStringOperand
(
"-I<dir> include path"
));
break
;
case
'S'
:
shaderStageName
=
argv
[
1
];
if
(
argc
>
0
)
{
argc
--
;
argv
++
;
}
else
if
(
argc
<=
1
)
Error
(
"no <stage> specified for -S"
);
shaderStageName
=
argv
[
1
];
bumpArg
();
break
;
case
'U'
:
UserPreamble
.
addUndef
(
getStringOperand
(
"-U<macro>: macro name"
));
break
;
case
'V'
:
Options
|=
EOptionSpv
;
Options
|=
EOptionVulkanRules
;
Options
|=
EOptionLinkProgram
;
setVulkanSpv
()
;
if
(
argv
[
0
][
2
]
!=
0
)
ClientInputSemanticsVersion
=
getAttachedNumber
(
"-G<num> client input semantics"
)
;
break
;
case
'c'
:
Options
|=
EOptionDumpConfig
;
...
...
@@ -490,11 +538,9 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
// HLSL todo: entry point handle needs much more sophistication.
// This is okay for one compilation unit with one entry point.
entryPointName
=
argv
[
1
];
if
(
argc
>
0
)
{
argc
--
;
argv
++
;
}
else
if
(
argc
<=
1
)
Error
(
"no <entry-point> provided for -e"
);
bumpArg
();
break
;
case
'g'
:
Options
|=
EOptionDebug
;
...
...
@@ -512,12 +558,10 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
Options
|=
EOptionMemoryLeakMode
;
break
;
case
'o'
:
binaryFileName
=
argv
[
1
];
if
(
argc
>
0
)
{
argc
--
;
argv
++
;
}
else
if
(
argc
<=
1
)
Error
(
"no <file> provided for -o"
);
binaryFileName
=
argv
[
1
];
bumpArg
();
break
;
case
'q'
:
Options
|=
EOptionDumpReflection
;
...
...
@@ -715,9 +759,27 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
if
(
Options
&
EOptionAutoMapLocations
)
shader
->
setAutoMapLocations
(
true
);
// Set up the environment, some subsettings take precedence over earlier
// ways of setting things.
if
(
Options
&
EOptionSpv
)
{
if
(
Options
&
EOptionVulkanRules
)
{
shader
->
setEnvInput
((
Options
&
EOptionReadHlsl
)
?
glslang
::
EShSourceHlsl
:
glslang
::
EShSourceGlsl
,
compUnit
.
stage
,
glslang
::
EShClientVulkan
,
ClientInputSemanticsVersion
);
shader
->
setEnvClient
(
glslang
::
EShClientVulkan
,
VulkanClientVersion
);
shader
->
setEnvTarget
(
glslang
::
EshTargetSpv
,
TargetVersion
);
}
else
{
shader
->
setEnvInput
((
Options
&
EOptionReadHlsl
)
?
glslang
::
EShSourceHlsl
:
glslang
::
EShSourceGlsl
,
compUnit
.
stage
,
glslang
::
EShClientOpenGL
,
ClientInputSemanticsVersion
);
shader
->
setEnvClient
(
glslang
::
EShClientOpenGL
,
OpenGLClientVersion
);
shader
->
setEnvTarget
(
glslang
::
EshTargetSpv
,
TargetVersion
);
}
}
shaders
.
push_back
(
shader
);
const
int
defaultVersion
=
Options
&
EOptionDefaultDesktop
?
110
:
100
;
const
int
defaultVersion
=
Options
&
EOptionDefaultDesktop
?
110
:
100
;
DirStackFileIncluder
includer
;
std
::
for_each
(
IncludeDirectoryList
.
rbegin
(),
IncludeDirectoryList
.
rend
(),
[
&
includer
](
const
std
::
string
&
dir
)
{
...
...
@@ -1072,16 +1134,24 @@ void usage()
" -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
"
" -G
[ver]
create SPIR-V binary, under OpenGL semantics; turns on -l;
\n
"
" default file name is <stage>.spv (-o overrides this)
\n
"
" 'ver', when present, is the version of the input semantics,
\n
"
" which will appear in #define GL_SPIRV ver
\n
"
" '--client opengl100' is the same as -G100
\n
"
" a '--target-env' for OpenGL will also imply '-G'
\n
"
" -H print human readable form of SPIR-V; turns on -V
\n
"
" -I<dir> add dir to the include search path; includer's directory
\n
"
" 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-pr
eco
ssor macro
\n
"
" -V
create SPIR-V binary, under Vulkan semantics; turns on -l;
\n
"
" -U<macro> undefine a pre-pr
oce
ssor macro
\n
"
" -V
[ver]
create SPIR-V binary, under Vulkan semantics; turns on -l;
\n
"
" default file name is <stage>.spv (-o overrides this)
\n
"
" 'ver', when present, is the version of the input semantics,
\n
"
" which will appear in #define VULKAN ver
\n
"
" '--client vulkan100' is the same as -V100
\n
"
" a '--target-env' for Vulkan will also imply '-V'
\n
"
" -c configuration dump;
\n
"
" creates the default configuration file (redirect to a .conf file)
\n
"
" -d default to desktop (#version 110) when there is no shader #version
\n
"
...
...
@@ -1104,12 +1174,12 @@ void usage()
" without explicit bindings.
\n
"
" --amb synonym for --auto-map-bindings
\n
"
" --auto-map-locations automatically locate input/output lacking
\n
"
" 'location'
\n
(fragile, not cross stage)
\n
"
" 'location' (fragile, not cross stage)
\n
"
" --aml synonym for --auto-map-locations
\n
"
" --client {vulkan<ver>|opengl<ver>} see -V and -G
\n
"
" --flatten-uniform-arrays flatten uniform texture/sampler arrays to
\n
"
" scalars
\n
"
" --fua synonym for --flatten-uniform-arrays
\n
"
"
\n
"
" --hlsl-offsets Allow block offsets to follow HLSL rules
\n
"
" Works independently of source language
\n
"
" --hlsl-iomap Perform IO mapping in HLSL register space
\n
"
...
...
@@ -1135,6 +1205,11 @@ void usage()
" --source-entrypoint name the given shader source function is
\n
"
" renamed to be the entry point given in -e
\n
"
" --sep synonym for --source-entrypoint
\n
"
" --target-env {vulkan1.0|opengl} set the execution environment the generated
\n
"
" code will execute in (as opposed to language
\n
"
" semantics selected by --client)
\n
"
" default is 'vulkan1.0' under '--client vulkan'
\n
"
" default is 'opengl' under '--client opengl'
\n
"
" --variable-name <name> Creates a C header file that contains a
\n
"
" uint32_t array named <name>
\n
"
" initialized with the shader binary code.
\n
"
...
...
Test/runtests
View file @
a8a83204
...
...
@@ -128,6 +128,16 @@ $EXE -D -e main -V -i -DUNDEFED -UIN_SHADER -DFOO=200 -UUNDEFED hlsl.-D-U.frag >
diff
-b
$BASEDIR
/hlsl.-D-U.frag.out
$TARGETDIR
/hlsl.-D-U.frag.out
||
HASERROR
=
1
#
# Test --client and --target-env
#
$EXE
--client
vulkan100 spv.targetVulkan.vert
||
HASERROR
=
1
$EXE
--client
opengl100 spv.targetOpenGL.vert
||
HASERROR
=
1
$EXE
--target-env
vulkan1.0 spv.targetVulkan.vert
||
HASERROR
=
1
$EXE
--target-env
opengl spv.targetOpenGL.vert
||
HASERROR
=
1
$EXE
-V100
spv.targetVulkan.vert
||
HASERROR
=
1
$EXE
-G100
spv.targetOpenGL.vert
||
HASERROR
=
1
#
# Final checking
#
if
[
$HASERROR
-eq
0
]
...
...
Test/spv.targetOpenGL.vert
0 → 100755
View file @
a8a83204
#version 450
layout
(
constant_id
=
3
)
const
int
a
=
2
;
uniform
float
f
;
void
main
()
{
}
Test/spv.targetVulkan.vert
0 → 100755
View file @
a8a83204
#version 450
layout
(
constant_id
=
3
)
const
int
a
=
2
;
layout
(
push_constant
)
uniform
pc
{
float
f
;
};
void
main
()
{
}
glslang/MachineIndependent/ParseHelper.cpp
View file @
a8a83204
...
...
@@ -50,7 +50,8 @@ namespace glslang {
TParseContext
::
TParseContext
(
TSymbolTable
&
symbolTable
,
TIntermediate
&
interm
,
bool
parsingBuiltins
,
int
version
,
EProfile
profile
,
const
SpvVersion
&
spvVersion
,
EShLanguage
language
,
TInfoSink
&
infoSink
,
bool
forwardCompatible
,
EShMessages
messages
)
:
TParseContextBase
(
symbolTable
,
interm
,
parsingBuiltins
,
version
,
profile
,
spvVersion
,
language
,
infoSink
,
forwardCompatible
,
messages
),
TParseContextBase
(
symbolTable
,
interm
,
parsingBuiltins
,
version
,
profile
,
spvVersion
,
language
,
infoSink
,
forwardCompatible
,
messages
),
inMain
(
false
),
blockName
(
nullptr
),
limits
(
resources
.
limits
),
...
...
glslang/MachineIndependent/ShaderLang.cpp
View file @
a8a83204
...
...
@@ -569,6 +569,73 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
return
correct
;
}
// There are multiple paths in for setting environment stuff.
// TEnvironment takes precedence, for what it sets, so sort all this out.
// Ideally, the internal code could be made to use TEnvironment, but for
// now, translate it to the historically used parameters.
void
TranslateEnvironment
(
const
TEnvironment
*
environment
,
EShMessages
&
messages
,
EShSource
&
source
,
EShLanguage
&
stage
,
SpvVersion
&
spvVersion
)
{
// Set up environmental defaults, first ignoring 'environment'.
if
(
messages
&
EShMsgSpvRules
)
spvVersion
.
spv
=
0x00010000
;
if
(
messages
&
EShMsgVulkanRules
)
{
spvVersion
.
vulkan
=
100
;
spvVersion
.
vulkanGlsl
=
100
;
}
else
if
(
spvVersion
.
spv
!=
0
)
spvVersion
.
openGl
=
100
;
// Now, override, based on any content set in 'environment'.
// 'environment' must be cleared to ESh*None settings when items
// are not being set.
if
(
environment
!=
nullptr
)
{
// input language
if
(
environment
->
input
.
languageFamily
!=
EShSourceNone
)
{
stage
=
environment
->
input
.
stage
;
switch
(
environment
->
input
.
dialect
)
{
case
EShClientNone
:
break
;
case
EShClientVulkan
:
spvVersion
.
vulkanGlsl
=
environment
->
input
.
dialectVersion
;
break
;
case
EShClientOpenGL
:
spvVersion
.
openGl
=
environment
->
input
.
dialectVersion
;
break
;
}
switch
(
environment
->
input
.
languageFamily
)
{
case
EShSourceNone
:
break
;
case
EShSourceGlsl
:
source
=
EShSourceGlsl
;
messages
=
static_cast
<
EShMessages
>
(
messages
&
~
EShMsgReadHlsl
);
break
;
case
EShSourceHlsl
:
source
=
EShSourceHlsl
;
messages
=
static_cast
<
EShMessages
>
(
messages
|
EShMsgReadHlsl
);
break
;
}
}
// client
switch
(
environment
->
client
.
client
)
{
case
EShClientVulkan
:
spvVersion
.
vulkan
=
environment
->
client
.
version
;
break
;
default:
break
;
}
// generated code
switch
(
environment
->
target
.
language
)
{
case
EshTargetSpv
:
spvVersion
.
spv
=
environment
->
target
.
version
;
break
;
default:
break
;
}
}
}
// This is the common setup and cleanup code for PreprocessDeferred and
// CompileDeferred.
// It takes any callable with a signature of
...
...
@@ -599,8 +666,8 @@ bool ProcessDeferred(
ProcessingContext
&
processingContext
,
bool
requireNonempty
,
TShader
::
Includer
&
includer
,
const
std
::
string
sourceEntryPointName
=
""
)
const
std
::
string
sourceEntryPointName
=
""
,
const
TEnvironment
*
environment
=
nullptr
)
// optional way of fully setting all versions, overriding the above
{
if
(
!
InitThread
())
return
false
;
...
...
@@ -641,6 +708,13 @@ bool ProcessDeferred(
names
[
s
+
numPre
]
=
nullptr
;
}
// Get all the stages, languages, clients, and other environment
// stuff sorted out.
EShSource
source
=
(
messages
&
EShMsgReadHlsl
)
!=
0
?
EShSourceHlsl
:
EShSourceGlsl
;
SpvVersion
spvVersion
;
EShLanguage
stage
=
compiler
->
getLanguage
();
TranslateEnvironment
(
environment
,
messages
,
source
,
stage
,
spvVersion
);
// First, without using the preprocessor or parser, find the #version, so we know what
// symbol tables, processing rules, etc. to set up. This does not need the extra strings
// outlined above, just the user shader, after the system and user preambles.
...
...
@@ -648,11 +722,11 @@ bool ProcessDeferred(
int
version
=
0
;
EProfile
profile
=
ENoProfile
;
bool
versionNotFirstToken
=
false
;
bool
versionNotFirst
=
(
messages
&
EShMsgReadHlsl
)
?
true
:
userInput
.
scanVersion
(
version
,
profile
,
versionNotFirstToken
);
bool
versionNotFirst
=
(
source
==
EShSourceHlsl
)
?
true
:
userInput
.
scanVersion
(
version
,
profile
,
versionNotFirstToken
);
bool
versionNotFound
=
version
==
0
;
if
(
forceDefaultVersionAndProfile
&&
(
messages
&
EShMsgReadHlsl
)
==
0
)
{
if
(
forceDefaultVersionAndProfile
&&
source
==
EShSourceGlsl
)
{
if
(
!
(
messages
&
EShMsgSuppressWarnings
)
&&
!
versionNotFound
&&
(
version
!=
defaultVersion
||
profile
!=
defaultProfile
))
{
compiler
->
infoSink
.
info
<<
"Warning, (version, profile) forced to be ("
...
...
@@ -669,15 +743,8 @@ bool ProcessDeferred(
version
=
defaultVersion
;
profile
=
defaultProfile
;
}
SpvVersion
spvVersion
;
if
(
messages
&
EShMsgSpvRules
)
spvVersion
.
spv
=
0x00010000
;
// TODO: eventually have this come from the outside
EShSource
source
=
(
messages
&
EShMsgReadHlsl
)
?
EShSourceHlsl
:
EShSourceGlsl
;
if
(
messages
&
EShMsgVulkanRules
)
spvVersion
.
vulkan
=
100
;
// TODO: eventually have this come from the outside
else
if
(
spvVersion
.
spv
!=
0
)
spvVersion
.
openGl
=
100
;
// TODO: eventually have this come from the outside
bool
goodVersion
=
DeduceVersionProfile
(
compiler
->
infoSink
,
compiler
->
getLanguage
(),
bool
goodVersion
=
DeduceVersionProfile
(
compiler
->
infoSink
,
stage
,
versionNotFirst
,
defaultVersion
,
source
,
version
,
profile
,
spvVersion
);
bool
versionWillBeError
=
(
versionNotFound
||
(
profile
==
EEsProfile
&&
version
>=
300
&&
versionNotFirst
));
bool
warnVersionNotFirst
=
false
;
...
...
@@ -694,7 +761,7 @@ bool ProcessDeferred(
intermediate
.
setSpv
(
spvVersion
);
if
(
spvVersion
.
vulkan
>=
100
)
intermediate
.
setOriginUpperLeft
();
if
((
messages
&
EShMsgHlslOffsets
)
||
(
messages
&
EShMsgReadHlsl
)
)
if
((
messages
&
EShMsgHlslOffsets
)
||
source
==
EShSourceHlsl
)
intermediate
.
setHlslOffsets
();
if
(
messages
&
EShMsgDebugInfo
)
{
intermediate
.
setSourceFile
(
names
[
numPre
]);
...
...
@@ -707,7 +774,7 @@ bool ProcessDeferred(
[
MapSpvVersionToIndex
(
spvVersion
)]
[
MapProfileToIndex
(
profile
)]
[
MapSourceToIndex
(
source
)]
[
compiler
->
getLanguage
()
];
[
stage
];
// Dynamically allocate the symbol table so we can control when it is deallocated WRT the pool.
TSymbolTable
*
symbolTableMemory
=
new
TSymbolTable
;
...
...
@@ -718,7 +785,7 @@ bool ProcessDeferred(
// Add built-in symbols that are potentially context dependent;
// they get popped again further down.
if
(
!
AddContextSpecificSymbols
(
resources
,
compiler
->
infoSink
,
symbolTable
,
version
,
profile
,
spvVersion
,
compiler
->
getLanguage
()
,
source
))
stage
,
source
))
return
false
;
//
...
...
@@ -726,14 +793,14 @@ bool ProcessDeferred(
//
TParseContextBase
*
parseContext
=
CreateParseContext
(
symbolTable
,
intermediate
,
version
,
profile
,
source
,
compiler
->
getLanguage
()
,
compiler
->
infoSink
,
stage
,
compiler
->
infoSink
,
spvVersion
,
forwardCompatible
,
messages
,
false
,
sourceEntryPointName
);
TPpContext
ppContext
(
*
parseContext
,
names
[
numPre
]
?
names
[
numPre
]
:
""
,
includer
);
// only GLSL (bison triggered, really) needs an externally set scan context
glslang
::
TScanContext
scanContext
(
*
parseContext
);
if
(
(
messages
&
EShMsgReadHlsl
)
==
0
)
if
(
source
==
EShSourceGlsl
)
parseContext
->
setScanContext
(
&
scanContext
);
parseContext
->
setPpContext
(
&
ppContext
);
...
...
@@ -1052,14 +1119,15 @@ bool CompileDeferred(
EShMessages
messages
,
// warnings/errors/AST; things to print out
TIntermediate
&
intermediate
,
// returned tree, etc.
TShader
::
Includer
&
includer
,
const
std
::
string
sourceEntryPointName
=
""
)
const
std
::
string
sourceEntryPointName
=
""
,
TEnvironment
*
environment
=
nullptr
)
{
DoFullParse
parser
;
return
ProcessDeferred
(
compiler
,
shaderStrings
,
numStrings
,
inputLengths
,
stringNames
,
preamble
,
optLevel
,
resources
,
defaultVersion
,
defaultProfile
,
forceDefaultVersionAndProfile
,
forwardCompatible
,
messages
,
intermediate
,
parser
,
true
,
includer
,
sourceEntryPointName
);
true
,
includer
,
sourceEntryPointName
,
environment
);
}
}
// end anonymous namespace for local functions
...
...
@@ -1485,6 +1553,12 @@ TShader::TShader(EShLanguage s)
infoSink
=
new
TInfoSink
;
compiler
=
new
TDeferredCompiler
(
stage
,
*
infoSink
);
intermediate
=
new
TIntermediate
(
s
);
// clear environment (avoid constructors in them for use in a C interface)
environment
.
input
.
languageFamily
=
EShSourceNone
;
environment
.
input
.
dialect
=
EShClientNone
;
environment
.
client
.
client
=
EShClientNone
;
environment
.
target
.
language
=
EShTargetNone
;
}
TShader
::~
TShader
()
...
...
@@ -1572,7 +1646,8 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
return
CompileDeferred
(
compiler
,
strings
,
numStrings
,
lengths
,
stringNames
,
preamble
,
EShOptNone
,
builtInResources
,
defaultVersion
,
defaultProfile
,
forceDefaultVersionAndProfile
,
forwardCompatible
,
messages
,
*
intermediate
,
includer
,
sourceEntryPointName
);
forwardCompatible
,
messages
,
*
intermediate
,
includer
,
sourceEntryPointName
,
&
environment
);
}
// Fill in a string with the result of preprocessing ShaderStrings
...
...
glslang/MachineIndependent/Versions.cpp
View file @
a8a83204
...
...
@@ -355,9 +355,9 @@ void TParseVersions::getPreamble(std::string& preamble)
// #define VULKAN XXXX
const
int
numberBufSize
=
12
;
char
numberBuf
[
numberBufSize
];
if
(
spvVersion
.
vulkan
>
0
)
{
if
(
spvVersion
.
vulkan
Glsl
>
0
)
{
preamble
+=
"#define VULKAN "
;
snprintf
(
numberBuf
,
numberBufSize
,
"%d"
,
spvVersion
.
vulkan
);
snprintf
(
numberBuf
,
numberBufSize
,
"%d"
,
spvVersion
.
vulkan
Glsl
);
preamble
+=
numberBuf
;
preamble
+=
"
\n
"
;
}
...
...
glslang/MachineIndependent/Versions.h
View file @
a8a83204
...
...
@@ -72,14 +72,19 @@ inline const char* ProfileName(EProfile profile)
}
//
// SPIR-V has versions for multiple things; tie them together.
// 0 means a target or rule set is not enabled.
// What source rules, validation rules, target language, etc. are needed
// desired for SPIR-V?
//
// 0 means a target or rule set is not enabled (ignore rules from that entity).
// Non-0 means to apply semantic rules arising from that version of its rule set.
// The union of all requested rule sets will be applied.
//
struct
SpvVersion
{
SpvVersion
()
:
spv
(
0
),
vulkan
(
0
),
openGl
(
0
)
{}
unsigned
int
spv
;
// the version of the targeted SPIR-V, as defined by SPIR-V in word 1 of the SPIR-V binary header
int
vulkan
;
// the version of semantics for Vulkan; e.g., for GLSL from KHR_vulkan_glsl "#define VULKAN"
int
openGl
;
// the version of semantics for OpenGL; e.g., for GLSL from KHR_vulkan_glsl "#define GL_SPIRV"
SpvVersion
()
:
spv
(
0
),
vulkanGlsl
(
0
),
vulkan
(
0
),
openGl
(
0
)
{}
unsigned
int
spv
;
// the version of SPIR-V to target, as defined by "word 1" of the SPIR-V binary header
int
vulkanGlsl
;
// the version of GLSL semantics for Vulkan, from GL_KHR_vulkan_glsl, for "#define VULKAN XXX"
int
vulkan
;
// the version of Vulkan, for which SPIR-V execution environment rules to use (100 means 1.0)
int
openGl
;
// the version of GLSL semantics for OpenGL, from GL_ARB_gl_spirv, for "#define GL_SPIRV XXX"
};
//
...
...
glslang/Public/ShaderLang.h
View file @
a8a83204
...
...
@@ -110,7 +110,44 @@ typedef enum {
EShSourceNone
,
EShSourceGlsl
,
EShSourceHlsl
,
}
EShSource
;
// if EShLanguage were EShStage, this could be EShLanguage instead
}
EShSource
;
// if EShLanguage were EShStage, this could be EShLanguage instead
typedef
enum
{
EShClientNone
,
EShClientVulkan
,
EShClientOpenGL
,
}
EShClient
;
typedef
enum
{
EShTargetNone
,
EshTargetSpv
,
}
EShTargetLanguage
;
struct
TInputLanguage
{
EShSource
languageFamily
;
// redundant information with other input, this one overrides when not EShSourceNone
EShLanguage
stage
;
// redundant information with other input, this one overrides when not EShSourceNone
EShClient
dialect
;
int
dialectVersion
;
// version of client's language definition, not the client (when not EShClientNone)
};
struct
TClient
{
EShClient
client
;
int
version
;
// version of client itself (not the client's input dialect)
};
struct
TTarget
{
EShTargetLanguage
language
;
unsigned
int
version
;
// the version to target, if SPIR-V, defined by "word 1" of the SPIR-V binary header
};
// All source/client/target versions and settings.
// Can override previous methods of setting, when items are set here.
// Expected to grow, as more are added, rather than growing parameter lists.
struct
TEnvironment
{
TInputLanguage
input
;
// definition of the input language
TClient
client
;
// what client is the overall compilation being done for?
TTarget
target
;
// what to generate
};
const
char
*
StageName
(
EShLanguage
);
...
...
@@ -324,6 +361,25 @@ public:
void
setNoStorageFormat
(
bool
useUnknownFormat
);
void
setTextureSamplerTransformMode
(
EShTextureSamplerTransformMode
mode
);
// For setting up the environment (initialized in the constructor):
void
setEnvInput
(
EShSource
lang
,
EShLanguage
stage
,
EShClient
client
,
int
version
)
{
environment
.
input
.
languageFamily
=
lang
;
environment
.
input
.
stage
=
stage
;
environment
.
input
.
dialect
=
client
;
environment
.
input
.
dialectVersion
=
version
;
}
void
setEnvClient
(
EShClient
client
,
int
version
)
{
environment
.
client
.
client
=
client
;
environment
.
client
.
version
=
version
;
}
void
setEnvTarget
(
EShTargetLanguage
lang
,
unsigned
int
version
)
{
environment
.
target
.
language
=
lang
;
environment
.
target
.
version
=
version
;
}
// Interface to #include handlers.
//
// To support #include, a client of Glslang does the following:
...
...
@@ -463,6 +519,8 @@ protected:
// a function in the source string can be renamed FROM this TO the name given in setEntryPoint.
std
::
string
sourceEntryPointName
;
TEnvironment
environment
;
friend
class
TProgram
;
private
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment