2012-12-12 21:15:54 +00:00
|
|
|
//
|
2017-01-06 19:34:14 +00:00
|
|
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
|
|
|
// Copyright (C) 2013-2016 LunarG, Inc.
|
2020-03-01 11:51:40 +00:00
|
|
|
// Copyright (C) 2016-2020 Google, Inc.
|
2013-02-17 06:01:50 +00:00
|
|
|
//
|
2017-01-06 19:34:14 +00:00
|
|
|
// All rights reserved.
|
2012-12-12 21:15:54 +00:00
|
|
|
//
|
2017-01-06 19:34:14 +00:00
|
|
|
// Redistribution and use in source and binary forms, with or without
|
|
|
|
// modification, are permitted provided that the following conditions
|
|
|
|
// are met:
|
2012-12-12 21:15:54 +00:00
|
|
|
//
|
|
|
|
// Redistributions of source code must retain the above copyright
|
|
|
|
// notice, this list of conditions and the following disclaimer.
|
|
|
|
//
|
|
|
|
// Redistributions in binary form must reproduce the above
|
|
|
|
// copyright notice, this list of conditions and the following
|
|
|
|
// disclaimer in the documentation and/or other materials provided
|
|
|
|
// with the distribution.
|
|
|
|
//
|
|
|
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
|
|
// contributors may be used to endorse or promote products derived
|
|
|
|
// from this software without specific prior written permission.
|
|
|
|
//
|
2017-01-06 19:34:14 +00:00
|
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
|
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
|
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
|
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
2012-12-12 21:15:54 +00:00
|
|
|
//
|
2013-09-17 19:26:08 +00:00
|
|
|
|
|
|
|
// this only applies to the standalone wrapper, not the front end in general
|
2017-05-10 13:52:50 +00:00
|
|
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
2013-09-17 19:26:08 +00:00
|
|
|
#define _CRT_SECURE_NO_WARNINGS
|
2017-05-10 13:52:50 +00:00
|
|
|
#endif
|
2013-09-17 19:26:08 +00:00
|
|
|
|
2016-05-19 17:31:43 +00:00
|
|
|
#include "ResourceLimits.h"
|
2013-07-31 18:44:13 +00:00
|
|
|
#include "Worklist.h"
|
2017-05-22 21:00:42 +00:00
|
|
|
#include "DirStackFileIncluder.h"
|
2012-12-12 21:15:54 +00:00
|
|
|
#include "./../glslang/Include/ShHandle.h"
|
|
|
|
#include "./../glslang/Public/ShaderLang.h"
|
2015-03-03 17:09:43 +00:00
|
|
|
#include "../SPIRV/GlslangToSpv.h"
|
2015-08-07 04:53:06 +00:00
|
|
|
#include "../SPIRV/GLSL.std.450.h"
|
2015-03-04 03:48:38 +00:00
|
|
|
#include "../SPIRV/doc.h"
|
|
|
|
#include "../SPIRV/disassemble.h"
|
2017-05-22 21:00:42 +00:00
|
|
|
|
2016-08-05 20:04:23 +00:00
|
|
|
#include <cstring>
|
|
|
|
#include <cstdlib>
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
#include <cctype>
|
2016-08-05 20:04:23 +00:00
|
|
|
#include <cmath>
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
#include <array>
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
#include <map>
|
2017-04-02 21:04:00 +00:00
|
|
|
#include <memory>
|
|
|
|
#include <thread>
|
2012-12-12 21:15:54 +00:00
|
|
|
|
2015-11-16 17:03:28 +00:00
|
|
|
#include "../glslang/OSDependent/osinclude.h"
|
2012-12-12 21:15:54 +00:00
|
|
|
|
Generate build information from CHANGES.md
This PR significantly reworks the way glslang is versioned.
Instead of committing changes to the `GLSLANG_MINOR_VERSION` define in
`glslang/Public/ShaderLang.h`, and using `make-revision` to generate
`GLSLANG_PATCH_LEVEL` in `glslang/Include/revision.h`, all version
information is now derived from the new `CHANGES.md` file.
`CHANGES.md` acts as the single source of truth for glslang version
information, along with a convenient place to put all release notes for
each notable change made.
`CHANGES.md` is parsed using the new `build_info.py` python script.
This script can read basic template files to produce new source files,
which it does to read the new `build_info.h.tmpl` to generate (at build
time) a glslang private header at
`<build-dir>/include/glslang/build_info.h`.
I've written generators for each of the CMake, Bazel, gn, and
`Android.mk` build scripts.
The new version code conforms to the Semantic Versioning 2.0 spec.
This new version is also used by the CMake rules to produce versioned
shared objects, including a major-versioned SONAME.
New APIs:
---------
* `glslang::GetVersion()` returns a `Version` struct with the version
major, minor, patch and flavor.
Breaking API changes:
---------------------
* The public defines `GLSLANG_MINOR_VERSION` and `GLSLANG_PATCH_LEVEL`
have been entirely removed.
* `glslang/Public/ShaderLang.h` and `glslang/Include/revision.h` have
been deleted.
* Instead, `<build-dir>/include/glslang/build_info.h` is created in
the build directory, and `<build-dir>/include` is a CMake `PUBLIC`
(dependee-inherited) include directory for the glslang targets.
* `<build-dir>/include/glslang/build_info.h` contains the following
new #defines:
`GLSLANG_VERSION_MAJOR`, `GLSLANG_VERSION_MINOR`,
`GLSLANG_VERSION_PATCH`, `GLSLANG_VERSION_FLAVOR`,
`GLSLANG_VERSION_GREATER_THAN(major, minor, patch)`,
`GLSLANG_VERSION_GREATER_OR_EQUAL_TO(major, minor, patch)`,
`GLSLANG_VERSION_LESS_THAN(major, minor, patch)`,
`GLSLANG_VERSION_LESS_OR_EQUAL_TO(major, minor, patch)`
* The CMake install output directory contains a copy of
`build_info.h` at: `include/glslang/build_info.h`
* Python3 is now always required to build glslang (likely always
required for transitive dependency builds).
2020-06-17 10:17:19 +00:00
|
|
|
// Build-time generated includes
|
|
|
|
#include "glslang/build_info.h"
|
|
|
|
|
2012-12-12 21:15:54 +00:00
|
|
|
extern "C" {
|
2020-06-29 13:20:19 +00:00
|
|
|
GLSLANG_EXPORT void ShOutputHtml();
|
2012-12-12 21:15:54 +00:00
|
|
|
}
|
|
|
|
|
2013-08-31 02:41:30 +00:00
|
|
|
// Command-line options
|
|
|
|
enum TOptions {
|
2016-12-10 02:22:20 +00:00
|
|
|
EOptionNone = 0,
|
|
|
|
EOptionIntermediate = (1 << 0),
|
|
|
|
EOptionSuppressInfolog = (1 << 1),
|
|
|
|
EOptionMemoryLeakMode = (1 << 2),
|
|
|
|
EOptionRelaxedErrors = (1 << 3),
|
|
|
|
EOptionGiveWarnings = (1 << 4),
|
|
|
|
EOptionLinkProgram = (1 << 5),
|
|
|
|
EOptionMultiThreaded = (1 << 6),
|
|
|
|
EOptionDumpConfig = (1 << 7),
|
|
|
|
EOptionDumpReflection = (1 << 8),
|
|
|
|
EOptionSuppressWarnings = (1 << 9),
|
|
|
|
EOptionDumpVersions = (1 << 10),
|
|
|
|
EOptionSpv = (1 << 11),
|
|
|
|
EOptionHumanReadableSpv = (1 << 12),
|
|
|
|
EOptionVulkanRules = (1 << 13),
|
|
|
|
EOptionDefaultDesktop = (1 << 14),
|
|
|
|
EOptionOutputPreprocessed = (1 << 15),
|
|
|
|
EOptionOutputHexadecimal = (1 << 16),
|
|
|
|
EOptionReadHlsl = (1 << 17),
|
|
|
|
EOptionCascadingErrors = (1 << 18),
|
|
|
|
EOptionAutoMapBindings = (1 << 19),
|
2016-09-16 19:26:37 +00:00
|
|
|
EOptionFlattenUniformArrays = (1 << 20),
|
2016-12-10 02:22:20 +00:00
|
|
|
EOptionNoStorageFormat = (1 << 21),
|
2016-12-12 18:41:43 +00:00
|
|
|
EOptionKeepUncalled = (1 << 22),
|
2017-04-05 23:38:20 +00:00
|
|
|
EOptionHlslOffsets = (1 << 23),
|
2017-04-18 18:18:01 +00:00
|
|
|
EOptionHlslIoMapping = (1 << 24),
|
2017-05-18 00:28:19 +00:00
|
|
|
EOptionAutoMapLocations = (1 << 25),
|
2017-05-31 23:11:16 +00:00
|
|
|
EOptionDebug = (1 << 26),
|
2017-09-02 17:34:54 +00:00
|
|
|
EOptionStdin = (1 << 27),
|
2017-09-22 00:40:22 +00:00
|
|
|
EOptionOptimizeDisable = (1 << 28),
|
|
|
|
EOptionOptimizeSize = (1 << 29),
|
2017-12-06 23:52:03 +00:00
|
|
|
EOptionInvertY = (1 << 30),
|
2018-03-06 05:23:17 +00:00
|
|
|
EOptionDumpBareVersion = (1 << 31),
|
2013-08-31 02:41:30 +00:00
|
|
|
};
|
2018-03-08 01:05:55 +00:00
|
|
|
bool targetHlslFunctionality1 = false;
|
2018-06-12 00:12:15 +00:00
|
|
|
bool SpvToolsDisassembler = false;
|
2018-08-23 21:29:08 +00:00
|
|
|
bool SpvToolsValidate = false;
|
2019-06-18 05:33:09 +00:00
|
|
|
bool NaNClamp = false;
|
2020-06-17 16:47:44 +00:00
|
|
|
bool stripDebugInfo = false;
|
2020-07-03 12:55:29 +00:00
|
|
|
bool beQuiet = false;
|
2021-03-15 17:26:11 +00:00
|
|
|
bool VulkanRulesRelaxed = false;
|
2013-08-31 02:41:30 +00:00
|
|
|
|
2012-12-12 21:15:54 +00:00
|
|
|
//
|
2015-07-13 01:28:10 +00:00
|
|
|
// Return codes from main/exit().
|
2012-12-12 21:15:54 +00:00
|
|
|
//
|
|
|
|
enum TFailCode {
|
|
|
|
ESuccess = 0,
|
|
|
|
EFailUsage,
|
|
|
|
EFailCompile,
|
|
|
|
EFailLink,
|
|
|
|
EFailCompilerCreate,
|
2013-07-31 18:44:13 +00:00
|
|
|
EFailThreadCreate,
|
2012-12-12 21:15:54 +00:00
|
|
|
EFailLinkerCreate
|
|
|
|
};
|
|
|
|
|
|
|
|
//
|
2015-07-13 01:28:10 +00:00
|
|
|
// Forward declarations.
|
2012-12-12 21:15:54 +00:00
|
|
|
//
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
EShLanguage FindLanguage(const std::string& name, bool parseSuffix=true);
|
2014-02-18 23:37:57 +00:00
|
|
|
void CompileFile(const char* fileName, ShHandle);
|
2012-12-12 21:15:54 +00:00
|
|
|
void usage();
|
2017-06-14 23:36:50 +00:00
|
|
|
char* ReadFileData(const char* fileName);
|
|
|
|
void FreeFileData(char* data);
|
2013-02-11 22:36:01 +00:00
|
|
|
void InfoLogMsg(const char* msg, const char* name, const int num);
|
2013-06-25 18:10:05 +00:00
|
|
|
|
2013-11-07 23:33:24 +00:00
|
|
|
// Globally track if any compile or link failure.
|
|
|
|
bool CompileFailed = false;
|
|
|
|
bool LinkFailed = false;
|
|
|
|
|
2017-11-13 08:32:06 +00:00
|
|
|
// array of unique places to leave the shader names and infologs for the asynchronous compiles
|
|
|
|
std::vector<std::unique_ptr<glslang::TWorkItem>> WorkItems;
|
|
|
|
|
2013-09-17 19:26:08 +00:00
|
|
|
TBuiltInResource Resources;
|
|
|
|
std::string ConfigFile;
|
|
|
|
|
|
|
|
//
|
2016-04-02 19:09:14 +00:00
|
|
|
// Parse either a .conf file provided by the user or the default from glslang::DefaultTBuiltInResource
|
2012-12-12 21:15:54 +00:00
|
|
|
//
|
2013-09-17 19:26:08 +00:00
|
|
|
void ProcessConfigFile()
|
2013-04-11 16:31:09 +00:00
|
|
|
{
|
2017-06-14 23:36:50 +00:00
|
|
|
if (ConfigFile.size() == 0)
|
2016-03-04 21:22:34 +00:00
|
|
|
Resources = glslang::DefaultTBuiltInResource;
|
2019-07-28 08:12:10 +00:00
|
|
|
#ifndef GLSLANG_WEB
|
2017-06-14 23:36:50 +00:00
|
|
|
else {
|
|
|
|
char* configString = ReadFileData(ConfigFile.c_str());
|
|
|
|
glslang::DecodeResourceLimits(&Resources, configString);
|
|
|
|
FreeFileData(configString);
|
2013-09-17 19:26:08 +00:00
|
|
|
}
|
2019-07-28 08:12:10 +00:00
|
|
|
#endif
|
2012-12-12 21:15:54 +00:00
|
|
|
}
|
|
|
|
|
2019-01-29 15:45:56 +00:00
|
|
|
int ReflectOptions = EShReflectionDefault;
|
2013-08-31 02:41:30 +00:00
|
|
|
int Options = 0;
|
2015-07-13 01:28:10 +00:00
|
|
|
const char* ExecutableName = nullptr;
|
|
|
|
const char* binaryFileName = nullptr;
|
2016-03-13 01:17:47 +00:00
|
|
|
const char* entryPointName = nullptr;
|
2016-10-31 21:13:43 +00:00
|
|
|
const char* sourceEntryPointName = nullptr;
|
2016-08-11 18:06:06 +00:00
|
|
|
const char* shaderStageName = nullptr;
|
2017-02-06 19:46:35 +00:00
|
|
|
const char* variableName = nullptr;
|
2018-03-07 05:10:01 +00:00
|
|
|
bool HlslEnable16BitTypes = false;
|
2018-12-08 01:38:26 +00:00
|
|
|
bool HlslDX9compatible = false;
|
2019-04-13 20:18:16 +00:00
|
|
|
bool DumpBuiltinSymbols = false;
|
2017-06-07 21:06:58 +00:00
|
|
|
std::vector<std::string> IncludeDirectoryList;
|
2018-10-26 16:12:32 +00:00
|
|
|
|
|
|
|
// Source environment
|
|
|
|
// (source 'Client' is currently the same as target 'Client')
|
|
|
|
int ClientInputSemanticsVersion = 100;
|
|
|
|
|
|
|
|
// Target environment
|
|
|
|
glslang::EShClient Client = glslang::EShClientNone; // will stay EShClientNone if only validating
|
|
|
|
glslang::EShTargetClientVersion ClientVersion; // not valid until Client is set
|
|
|
|
glslang::EShTargetLanguage TargetLanguage = glslang::EShTargetNone;
|
|
|
|
glslang::EShTargetLanguageVersion TargetVersion; // not valid until TargetLanguage is set
|
|
|
|
|
2018-03-06 23:12:04 +00:00
|
|
|
std::vector<std::string> Processes; // what should be recorded by OpModuleProcessed, or equivalent
|
2015-07-13 01:28:10 +00:00
|
|
|
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
// Per descriptor-set binding base data
|
|
|
|
typedef std::map<unsigned int, unsigned int> TPerSetBaseBinding;
|
|
|
|
|
2018-03-20 16:30:53 +00:00
|
|
|
std::vector<std::pair<std::string, int>> uniformLocationOverrides;
|
2018-03-20 16:41:05 +00:00
|
|
|
int uniformBase = 0;
|
2018-03-20 16:30:53 +00:00
|
|
|
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
std::array<std::array<unsigned int, EShLangCount>, glslang::EResCount> baseBinding;
|
|
|
|
std::array<std::array<TPerSetBaseBinding, EShLangCount>, glslang::EResCount> baseBindingForSet;
|
2017-05-02 07:27:29 +00:00
|
|
|
std::array<std::vector<std::string>, EShLangCount> baseResourceSetBinding;
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
|
2021-03-15 17:26:11 +00:00
|
|
|
std::vector<std::pair<std::string, glslang::TBlockStorageClass>> blockStorageOverrides;
|
|
|
|
|
|
|
|
bool setGlobalUniformBlock = false;
|
|
|
|
std::string globalUniformName;
|
|
|
|
unsigned int globalUniformBinding;
|
|
|
|
unsigned int globalUniformSet;
|
|
|
|
|
|
|
|
bool setGlobalBufferBlock = false;
|
|
|
|
std::string atomicCounterBlockName;
|
|
|
|
unsigned int atomicCounterBlockSet;
|
|
|
|
|
2017-06-15 16:40:49 +00:00
|
|
|
// 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);
|
|
|
|
|
2020-01-07 14:03:11 +00:00
|
|
|
Processes.push_back("define-macro ");
|
2017-07-21 02:00:36 +00:00
|
|
|
Processes.back().append(def);
|
|
|
|
|
2017-06-15 16:40:49 +00:00
|
|
|
// The first "=" needs to turn into a space
|
2017-07-12 15:04:39 +00:00
|
|
|
const size_t equal = def.find_first_of("=");
|
2017-06-15 16:40:49 +00:00
|
|
|
if (equal != def.npos)
|
|
|
|
def[equal] = ' ';
|
|
|
|
|
|
|
|
text.append(def);
|
|
|
|
text.append("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
// #undef...
|
|
|
|
void addUndef(std::string undef)
|
|
|
|
{
|
|
|
|
text.append("#undef ");
|
|
|
|
fixLine(undef);
|
2017-07-21 02:00:36 +00:00
|
|
|
|
2020-01-07 14:03:11 +00:00
|
|
|
Processes.push_back("undef-macro ");
|
2017-07-21 02:00:36 +00:00
|
|
|
Processes.back().append(undef);
|
|
|
|
|
2017-06-15 16:40:49 +00:00
|
|
|
text.append(undef);
|
|
|
|
text.append("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void fixLine(std::string& line)
|
|
|
|
{
|
|
|
|
// Can't go past a newline in the line
|
2017-07-12 15:04:39 +00:00
|
|
|
const size_t end = line.find_first_of("\n");
|
2017-06-15 16:40:49 +00:00
|
|
|
if (end != line.npos)
|
|
|
|
line = line.substr(0, end);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string text; // contents of preamble
|
|
|
|
};
|
|
|
|
|
2020-03-30 06:27:31 +00:00
|
|
|
// Track the user's #define and #undef from the command line.
|
2017-06-15 16:40:49 +00:00
|
|
|
TPreamble UserPreamble;
|
|
|
|
|
2015-07-13 01:28:10 +00:00
|
|
|
//
|
|
|
|
// Create the default name for saving a binary if -o is not provided.
|
|
|
|
//
|
|
|
|
const char* GetBinaryName(EShLanguage stage)
|
|
|
|
{
|
|
|
|
const char* name;
|
|
|
|
if (binaryFileName == nullptr) {
|
|
|
|
switch (stage) {
|
|
|
|
case EShLangVertex: name = "vert.spv"; break;
|
|
|
|
case EShLangTessControl: name = "tesc.spv"; break;
|
|
|
|
case EShLangTessEvaluation: name = "tese.spv"; break;
|
|
|
|
case EShLangGeometry: name = "geom.spv"; break;
|
|
|
|
case EShLangFragment: name = "frag.spv"; break;
|
|
|
|
case EShLangCompute: name = "comp.spv"; break;
|
2020-03-18 00:42:47 +00:00
|
|
|
case EShLangRayGen: name = "rgen.spv"; break;
|
|
|
|
case EShLangIntersect: name = "rint.spv"; break;
|
|
|
|
case EShLangAnyHit: name = "rahit.spv"; break;
|
|
|
|
case EShLangClosestHit: name = "rchit.spv"; break;
|
|
|
|
case EShLangMiss: name = "rmiss.spv"; break;
|
|
|
|
case EShLangCallable: name = "rcall.spv"; break;
|
2018-09-19 18:41:59 +00:00
|
|
|
case EShLangMeshNV: name = "mesh.spv"; break;
|
|
|
|
case EShLangTaskNV: name = "task.spv"; break;
|
2015-07-13 01:28:10 +00:00
|
|
|
default: name = "unknown"; break;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
name = binaryFileName;
|
|
|
|
|
|
|
|
return name;
|
|
|
|
}
|
2012-12-12 21:15:54 +00:00
|
|
|
|
2013-09-17 19:26:08 +00:00
|
|
|
//
|
|
|
|
// *.conf => this is a config file that can set limits/resources
|
|
|
|
//
|
|
|
|
bool SetConfigFile(const std::string& name)
|
|
|
|
{
|
|
|
|
if (name.size() < 5)
|
|
|
|
return false;
|
|
|
|
|
2013-10-11 16:28:43 +00:00
|
|
|
if (name.compare(name.size() - 5, 5, ".conf") == 0) {
|
2013-09-17 19:26:08 +00:00
|
|
|
ConfigFile = name;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-07-13 01:28:10 +00:00
|
|
|
//
|
|
|
|
// Give error and exit with failure code.
|
|
|
|
//
|
2019-12-20 17:33:13 +00:00
|
|
|
void Error(const char* message, const char* detail = nullptr)
|
2015-07-13 01:28:10 +00:00
|
|
|
{
|
2019-12-20 17:33:13 +00:00
|
|
|
fprintf(stderr, "%s: Error: ", ExecutableName);
|
|
|
|
if (detail != nullptr)
|
|
|
|
fprintf(stderr, "%s: ", detail);
|
|
|
|
fprintf(stderr, "%s (use -h for usage)\n", message);
|
2015-07-13 01:28:10 +00:00
|
|
|
exit(EFailUsage);
|
|
|
|
}
|
|
|
|
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
//
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
// Process an optional binding base of one the forms:
|
|
|
|
// --argname [stage] base // base for stage (if given) or all stages (if not)
|
2017-10-21 16:46:39 +00:00
|
|
|
// --argname [stage] [base set]... // set/base pairs: set the base for given binding set.
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
// Where stage is one of the forms accepted by FindLanguage, and base is an integer
|
|
|
|
//
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
void ProcessBindingBase(int& argc, char**& argv, glslang::TResourceType res)
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
{
|
|
|
|
if (argc < 2)
|
|
|
|
usage();
|
|
|
|
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
EShLanguage lang = EShLangCount;
|
|
|
|
int singleBase = 0;
|
|
|
|
TPerSetBaseBinding perSetBase;
|
|
|
|
int arg = 1;
|
|
|
|
|
|
|
|
// Parse stage, if given
|
|
|
|
if (!isdigit(argv[arg][0])) {
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
if (argc < 3) // this form needs one more argument
|
|
|
|
usage();
|
2017-01-06 07:34:48 +00:00
|
|
|
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
lang = FindLanguage(argv[arg++], false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((argc - arg) > 2 && isdigit(argv[arg+0][0]) && isdigit(argv[arg+1][0])) {
|
|
|
|
// Parse a per-set binding base
|
|
|
|
while ((argc - arg) > 2 && isdigit(argv[arg+0][0]) && isdigit(argv[arg+1][0])) {
|
|
|
|
const int baseNum = atoi(argv[arg++]);
|
2017-10-21 16:46:39 +00:00
|
|
|
const int setNum = atoi(argv[arg++]);
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
perSetBase[setNum] = baseNum;
|
|
|
|
}
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
} else {
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
// Parse single binding base
|
|
|
|
singleBase = atoi(argv[arg++]);
|
|
|
|
}
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
argc -= (arg-1);
|
|
|
|
argv += (arg-1);
|
|
|
|
|
|
|
|
// Set one or all languages
|
|
|
|
const int langMin = (lang < EShLangCount) ? lang+0 : 0;
|
|
|
|
const int langMax = (lang < EShLangCount) ? lang+1 : EShLangCount;
|
|
|
|
|
|
|
|
for (int lang = langMin; lang < langMax; ++lang) {
|
|
|
|
if (!perSetBase.empty())
|
2018-08-13 04:05:59 +00:00
|
|
|
baseBindingForSet[res][lang].insert(perSetBase.begin(), perSetBase.end());
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
else
|
|
|
|
baseBinding[res][lang] = singleBase;
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-02 07:27:29 +00:00
|
|
|
void ProcessResourceSetBindingBase(int& argc, char**& argv, std::array<std::vector<std::string>, EShLangCount>& base)
|
|
|
|
{
|
|
|
|
if (argc < 2)
|
|
|
|
usage();
|
|
|
|
|
|
|
|
if (!isdigit(argv[1][0])) {
|
2017-07-14 21:15:47 +00:00
|
|
|
if (argc < 3) // this form needs one more argument
|
2017-05-02 07:27:29 +00:00
|
|
|
usage();
|
|
|
|
|
2017-07-14 21:15:47 +00:00
|
|
|
// Parse form: --argname stage [regname set base...], or:
|
|
|
|
// --argname stage set
|
2017-05-02 07:27:29 +00:00
|
|
|
const EShLanguage lang = FindLanguage(argv[1], false);
|
|
|
|
|
2017-07-14 21:15:47 +00:00
|
|
|
argc--;
|
|
|
|
argv++;
|
|
|
|
|
|
|
|
while (argc > 1 && argv[1] != nullptr && argv[1][0] != '-') {
|
|
|
|
base[lang].push_back(argv[1]);
|
|
|
|
|
|
|
|
argc--;
|
|
|
|
argv++;
|
2017-05-02 07:27:29 +00:00
|
|
|
}
|
2017-07-14 21:15:47 +00:00
|
|
|
|
|
|
|
// Must have one arg, or a multiple of three (for [regname set binding] triples)
|
|
|
|
if (base[lang].size() != 1 && (base[lang].size() % 3) != 0)
|
|
|
|
usage();
|
|
|
|
|
2017-05-02 07:27:29 +00:00
|
|
|
} else {
|
2017-07-14 21:15:47 +00:00
|
|
|
// Parse form: --argname set
|
2017-05-02 07:27:29 +00:00
|
|
|
for (int lang=0; lang<EShLangCount; ++lang)
|
|
|
|
base[lang].push_back(argv[1]);
|
|
|
|
|
|
|
|
argc--;
|
|
|
|
argv++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-15 17:26:11 +00:00
|
|
|
//
|
|
|
|
// Process an optional binding base of one the forms:
|
|
|
|
// --argname name {uniform|buffer|push_constant}
|
|
|
|
void ProcessBlockStorage(int& argc, char**& argv, std::vector<std::pair<std::string, glslang::TBlockStorageClass>>& storage)
|
|
|
|
{
|
|
|
|
if (argc < 3)
|
|
|
|
usage();
|
|
|
|
|
|
|
|
glslang::TBlockStorageClass blockStorage = glslang::EbsNone;
|
|
|
|
|
|
|
|
std::string strBacking(argv[2]);
|
|
|
|
if (strBacking == "uniform")
|
|
|
|
blockStorage = glslang::EbsUniform;
|
|
|
|
else if (strBacking == "buffer")
|
|
|
|
blockStorage = glslang::EbsStorageBuffer;
|
|
|
|
else if (strBacking == "push_constant")
|
|
|
|
blockStorage = glslang::EbsPushConstant;
|
|
|
|
else {
|
|
|
|
printf("%s: invalid block storage\n", strBacking.c_str());
|
|
|
|
usage();
|
|
|
|
}
|
|
|
|
|
|
|
|
storage.push_back(std::make_pair(std::string(argv[1]), blockStorage));
|
|
|
|
|
|
|
|
argc -= 2;
|
|
|
|
argv += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool isNonDigit(char c) {
|
|
|
|
// a non-digit character valid in a glsl identifier
|
|
|
|
return (c == '_') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
|
|
|
|
}
|
|
|
|
|
|
|
|
// whether string isa valid identifier to be used in glsl
|
|
|
|
bool isValidIdentifier(const char* str) {
|
|
|
|
std::string idn(str);
|
|
|
|
|
|
|
|
if (idn.length() == 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (idn.length() >= 3 && idn.substr(0, 3) == "gl_") {
|
|
|
|
// identifiers startin with "gl_" are reserved
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!isNonDigit(idn[0])) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (unsigned int i = 1; i < idn.length(); ++i) {
|
|
|
|
if (!(isdigit(idn[i]) || isNonDigit(idn[i]))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process settings for either the global buffer block or global unfirom block
|
|
|
|
// of the form:
|
|
|
|
// --argname name set binding
|
|
|
|
void ProcessGlobalBlockSettings(int& argc, char**& argv, std::string* name, unsigned int* set, unsigned int* binding)
|
|
|
|
{
|
|
|
|
if (argc < 4)
|
|
|
|
usage();
|
|
|
|
|
|
|
|
unsigned int curArg = 1;
|
|
|
|
|
|
|
|
assert(name || set || binding);
|
|
|
|
|
|
|
|
if (name) {
|
|
|
|
if (!isValidIdentifier(argv[curArg])) {
|
|
|
|
printf("%s: invalid identifier\n", argv[curArg]);
|
|
|
|
usage();
|
|
|
|
}
|
|
|
|
*name = argv[curArg];
|
|
|
|
|
|
|
|
curArg++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (set) {
|
|
|
|
errno = 0;
|
|
|
|
int setVal = ::strtol(argv[curArg], NULL, 10);
|
|
|
|
if (errno || setVal < 0) {
|
|
|
|
printf("%s: invalid set\n", argv[curArg]);
|
|
|
|
usage();
|
|
|
|
}
|
|
|
|
*set = setVal;
|
|
|
|
|
|
|
|
curArg++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (binding) {
|
|
|
|
errno = 0;
|
|
|
|
int bindingVal = ::strtol(argv[curArg], NULL, 10);
|
|
|
|
if (errno || bindingVal < 0) {
|
|
|
|
printf("%s: invalid binding\n", argv[curArg]);
|
|
|
|
usage();
|
|
|
|
}
|
|
|
|
*binding = bindingVal;
|
|
|
|
|
|
|
|
curArg++;
|
|
|
|
}
|
|
|
|
|
|
|
|
argc -= (curArg - 1);
|
|
|
|
argv += (curArg - 1);
|
|
|
|
}
|
|
|
|
|
2015-07-13 01:28:10 +00:00
|
|
|
//
|
|
|
|
// Do all command-line argument parsing. This includes building up the work-items
|
|
|
|
// to be processed later, and saving all the command-line options.
|
|
|
|
//
|
|
|
|
// Does not return (it exits) if command-line is fatally flawed.
|
|
|
|
//
|
2017-04-02 21:04:00 +00:00
|
|
|
void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItems, int argc, char* argv[])
|
2013-07-31 18:44:13 +00:00
|
|
|
{
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
for (int res = 0; res < glslang::EResCount; ++res)
|
|
|
|
baseBinding[res].fill(0);
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
|
2013-09-06 19:52:57 +00:00
|
|
|
ExecutableName = argv[0];
|
2017-04-02 21:04:00 +00:00
|
|
|
workItems.reserve(argc);
|
2013-09-06 19:52:57 +00:00
|
|
|
|
2017-06-23 16:58:31 +00:00
|
|
|
const auto bumpArg = [&]() {
|
|
|
|
if (argc > 0) {
|
|
|
|
argc--;
|
|
|
|
argv++;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// read a string directly attached to a single-letter option
|
2017-06-14 21:52:44 +00:00
|
|
|
const auto getStringOperand = [&](const char* desc) {
|
|
|
|
if (argv[0][2] == 0) {
|
|
|
|
printf("%s must immediately follow option (no spaces)\n", desc);
|
|
|
|
exit(EFailUsage);
|
|
|
|
}
|
|
|
|
return argv[0] + 2;
|
|
|
|
};
|
|
|
|
|
2017-06-23 17:11:09 +00:00
|
|
|
// 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 = []() {
|
2018-10-26 16:12:32 +00:00
|
|
|
if (Client == glslang::EShClientNone)
|
|
|
|
ClientVersion = glslang::EShTargetVulkan_1_0;
|
|
|
|
Client = glslang::EShClientVulkan;
|
2017-06-23 17:11:09 +00:00
|
|
|
Options |= EOptionSpv;
|
|
|
|
Options |= EOptionVulkanRules;
|
|
|
|
Options |= EOptionLinkProgram;
|
|
|
|
};
|
|
|
|
|
|
|
|
// minimum needed (without overriding something else) to target OpenGL SPIR-V
|
|
|
|
const auto setOpenGlSpv = []() {
|
2018-10-26 16:12:32 +00:00
|
|
|
if (Client == glslang::EShClientNone)
|
|
|
|
ClientVersion = glslang::EShTargetOpenGL_450;
|
|
|
|
Client = glslang::EShClientOpenGL;
|
2017-06-23 17:11:09 +00:00
|
|
|
Options |= EOptionSpv;
|
|
|
|
Options |= EOptionLinkProgram;
|
|
|
|
// undo a -H default to Vulkan
|
|
|
|
Options &= ~EOptionVulkanRules;
|
|
|
|
};
|
|
|
|
|
2018-03-20 16:30:53 +00:00
|
|
|
const auto getUniformOverride = [getStringOperand]() {
|
|
|
|
const char *arg = getStringOperand("-u<name>:<location>");
|
|
|
|
const char *split = strchr(arg, ':');
|
|
|
|
if (split == NULL) {
|
|
|
|
printf("%s: missing location\n", arg);
|
|
|
|
exit(EFailUsage);
|
|
|
|
}
|
|
|
|
errno = 0;
|
|
|
|
int location = ::strtol(split + 1, NULL, 10);
|
|
|
|
if (errno) {
|
|
|
|
printf("%s: invalid location\n", arg);
|
|
|
|
exit(EFailUsage);
|
|
|
|
}
|
|
|
|
return std::make_pair(std::string(arg, split - arg), location);
|
|
|
|
};
|
|
|
|
|
2017-06-23 16:58:31 +00:00
|
|
|
for (bumpArg(); argc >= 1; bumpArg()) {
|
2013-07-31 18:44:13 +00:00
|
|
|
if (argv[0][0] == '-') {
|
2015-05-15 16:02:07 +00:00
|
|
|
switch (argv[0][1]) {
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
case '-':
|
|
|
|
{
|
|
|
|
std::string lowerword(argv[0]+2);
|
|
|
|
std::transform(lowerword.begin(), lowerword.end(), lowerword.begin(), ::tolower);
|
|
|
|
|
|
|
|
// handle --word style options
|
2017-06-14 21:52:44 +00:00
|
|
|
if (lowerword == "auto-map-bindings" || // synonyms
|
2017-06-23 17:11:09 +00:00
|
|
|
lowerword == "auto-map-binding" ||
|
|
|
|
lowerword == "amb") {
|
2017-06-14 21:52:44 +00:00
|
|
|
Options |= EOptionAutoMapBindings;
|
|
|
|
} else if (lowerword == "auto-map-locations" || // synonyms
|
|
|
|
lowerword == "aml") {
|
|
|
|
Options |= EOptionAutoMapLocations;
|
2018-03-20 16:41:05 +00:00
|
|
|
} else if (lowerword == "uniform-base") {
|
|
|
|
if (argc <= 1)
|
2019-12-20 17:33:13 +00:00
|
|
|
Error("no <base> provided", lowerword.c_str());
|
2018-03-20 16:41:05 +00:00
|
|
|
uniformBase = ::strtol(argv[1], NULL, 10);
|
|
|
|
bumpArg();
|
|
|
|
break;
|
2017-06-23 17:11:09 +00:00
|
|
|
} else if (lowerword == "client") {
|
|
|
|
if (argc > 1) {
|
|
|
|
if (strcmp(argv[1], "vulkan100") == 0)
|
|
|
|
setVulkanSpv();
|
|
|
|
else if (strcmp(argv[1], "opengl100") == 0)
|
|
|
|
setOpenGlSpv();
|
|
|
|
else
|
2019-12-20 17:33:13 +00:00
|
|
|
Error("expects vulkan100 or opengl100", lowerword.c_str());
|
|
|
|
} else
|
|
|
|
Error("expects vulkan100 or opengl100", lowerword.c_str());
|
2017-06-23 17:11:09 +00:00
|
|
|
bumpArg();
|
2020-01-07 14:03:11 +00:00
|
|
|
} else if (lowerword == "define-macro" ||
|
|
|
|
lowerword == "d") {
|
|
|
|
if (argc > 1)
|
|
|
|
UserPreamble.addDef(argv[1]);
|
|
|
|
else
|
|
|
|
Error("expects <name[=def]>", argv[0]);
|
|
|
|
bumpArg();
|
2019-04-13 20:18:16 +00:00
|
|
|
} else if (lowerword == "dump-builtin-symbols") {
|
|
|
|
DumpBuiltinSymbols = true;
|
2018-08-09 20:15:00 +00:00
|
|
|
} else if (lowerword == "entry-point") {
|
|
|
|
entryPointName = argv[1];
|
|
|
|
if (argc <= 1)
|
2019-12-20 17:33:13 +00:00
|
|
|
Error("no <name> provided", lowerword.c_str());
|
2018-08-09 20:15:00 +00:00
|
|
|
bumpArg();
|
2017-06-14 21:52:44 +00:00
|
|
|
} else if (lowerword == "flatten-uniform-arrays" || // synonyms
|
|
|
|
lowerword == "flatten-uniform-array" ||
|
|
|
|
lowerword == "fua") {
|
|
|
|
Options |= EOptionFlattenUniformArrays;
|
|
|
|
} else if (lowerword == "hlsl-offsets") {
|
|
|
|
Options |= EOptionHlslOffsets;
|
|
|
|
} else if (lowerword == "hlsl-iomap" ||
|
|
|
|
lowerword == "hlsl-iomapper" ||
|
|
|
|
lowerword == "hlsl-iomapping") {
|
|
|
|
Options |= EOptionHlslIoMapping;
|
2018-03-07 05:10:01 +00:00
|
|
|
} else if (lowerword == "hlsl-enable-16bit-types") {
|
|
|
|
HlslEnable16BitTypes = true;
|
2018-12-08 01:38:26 +00:00
|
|
|
} else if (lowerword == "hlsl-dx9-compatible") {
|
|
|
|
HlslDX9compatible = true;
|
2018-03-06 05:23:17 +00:00
|
|
|
} else if (lowerword == "invert-y" || // synonyms
|
|
|
|
lowerword == "iy") {
|
|
|
|
Options |= EOptionInvertY;
|
2017-06-14 21:52:44 +00:00
|
|
|
} else if (lowerword == "keep-uncalled" || // synonyms
|
|
|
|
lowerword == "ku") {
|
|
|
|
Options |= EOptionKeepUncalled;
|
2019-06-18 05:33:09 +00:00
|
|
|
} else if (lowerword == "nan-clamp") {
|
|
|
|
NaNClamp = true;
|
2017-06-14 21:52:44 +00:00
|
|
|
} else if (lowerword == "no-storage-format" || // synonyms
|
|
|
|
lowerword == "nsf") {
|
|
|
|
Options |= EOptionNoStorageFormat;
|
2017-07-21 02:00:36 +00:00
|
|
|
} else if (lowerword == "relaxed-errors") {
|
|
|
|
Options |= EOptionRelaxedErrors;
|
2019-01-29 12:12:59 +00:00
|
|
|
} else if (lowerword == "reflect-strict-array-suffix") {
|
|
|
|
ReflectOptions |= EShReflectionStrictArraySuffix;
|
2019-01-29 15:49:00 +00:00
|
|
|
} else if (lowerword == "reflect-basic-array-suffix") {
|
|
|
|
ReflectOptions |= EShReflectionBasicArraySuffix;
|
2019-01-29 16:04:44 +00:00
|
|
|
} else if (lowerword == "reflect-intermediate-io") {
|
|
|
|
ReflectOptions |= EShReflectionIntermediateIO;
|
2019-01-30 14:18:43 +00:00
|
|
|
} else if (lowerword == "reflect-separate-buffers") {
|
|
|
|
ReflectOptions |= EShReflectionSeparateBuffers;
|
2019-01-30 15:34:02 +00:00
|
|
|
} else if (lowerword == "reflect-all-block-variables") {
|
|
|
|
ReflectOptions |= EShReflectionAllBlockVariables;
|
2019-02-11 11:50:24 +00:00
|
|
|
} else if (lowerword == "reflect-unwrap-io-blocks") {
|
|
|
|
ReflectOptions |= EShReflectionUnwrapIOBlocks;
|
Add Shared/Std140 SSBO process & top-level array elements related (#2231)
* Add Shared/Std140 SSBO process & top-level array elements related
process
1.Add process options for shared/std140 ssbo, following ubo process
2.Add IO Variables reflection option, would keep all input/output
variables in reflection
3.Add Top-level related process, fix top-level array size issues,
following spec
4.Split ssbo/ubo reflection options, merge blowup expanding all into
function blowupActiveAggregate to allow other functions keep same entry
format.
Add options in StandAlone and test symbols.
1. Add options in StandAlone for std140/shared ubo/ssbo and all io variables reflection.
2. Add test for ssbo. When EShReflectionSharedStd140SSBO turns on, generated symbol and output would be different, to remind the difference. Defaultly disabled and nothing would change, nor blocking normal test.
* Add options in runtest script, refresh test results.
Add options in StandAlone:
--reflect-all-io-variables --reflect-shared-std140-ubo --reflect-shared-std140-ssbo
refresh test results.
Now the index, size of unsized array are expected.
2020-06-04 07:47:18 +00:00
|
|
|
} else if (lowerword == "reflect-all-io-variables") {
|
|
|
|
ReflectOptions |= EShReflectionAllIOVariables;
|
|
|
|
} else if (lowerword == "reflect-shared-std140-ubo") {
|
|
|
|
ReflectOptions |= EShReflectionSharedStd140UBO;
|
|
|
|
} else if (lowerword == "reflect-shared-std140-ssbo") {
|
|
|
|
ReflectOptions |= EShReflectionSharedStd140SSBO;
|
2017-06-14 21:52:44 +00:00
|
|
|
} else if (lowerword == "resource-set-bindings" || // synonyms
|
|
|
|
lowerword == "resource-set-binding" ||
|
|
|
|
lowerword == "rsb") {
|
|
|
|
ProcessResourceSetBindingBase(argc, argv, baseResourceSetBinding);
|
2021-03-15 17:26:11 +00:00
|
|
|
} else if (lowerword == "set-block-storage" ||
|
|
|
|
lowerword == "sbs") {
|
|
|
|
ProcessBlockStorage(argc, argv, blockStorageOverrides);
|
|
|
|
} else if (lowerword == "set-atomic-counter-block" ||
|
|
|
|
lowerword == "sacb") {
|
|
|
|
ProcessGlobalBlockSettings(argc, argv, &atomicCounterBlockName, &atomicCounterBlockSet, nullptr);
|
|
|
|
setGlobalBufferBlock = true;
|
|
|
|
} else if (lowerword == "set-default-uniform-block" ||
|
|
|
|
lowerword == "sdub") {
|
|
|
|
ProcessGlobalBlockSettings(argc, argv, &globalUniformName, &globalUniformSet, &globalUniformBinding);
|
|
|
|
setGlobalUniformBlock = true;
|
2017-06-14 21:52:44 +00:00
|
|
|
} else if (lowerword == "shift-image-bindings" || // synonyms
|
|
|
|
lowerword == "shift-image-binding" ||
|
|
|
|
lowerword == "sib") {
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
ProcessBindingBase(argc, argv, glslang::EResImage);
|
2017-06-14 21:52:44 +00:00
|
|
|
} else if (lowerword == "shift-sampler-bindings" || // synonyms
|
2018-08-13 03:24:55 +00:00
|
|
|
lowerword == "shift-sampler-binding" ||
|
|
|
|
lowerword == "ssb") {
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
ProcessBindingBase(argc, argv, glslang::EResSampler);
|
2017-06-14 21:52:44 +00:00
|
|
|
} else if (lowerword == "shift-uav-bindings" || // synonyms
|
|
|
|
lowerword == "shift-uav-binding" ||
|
|
|
|
lowerword == "suavb") {
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
ProcessBindingBase(argc, argv, glslang::EResUav);
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
} else if (lowerword == "shift-texture-bindings" || // synonyms
|
|
|
|
lowerword == "shift-texture-binding" ||
|
|
|
|
lowerword == "stb") {
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
ProcessBindingBase(argc, argv, glslang::EResTexture);
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
} else if (lowerword == "shift-ubo-bindings" || // synonyms
|
|
|
|
lowerword == "shift-ubo-binding" ||
|
2017-04-18 18:18:01 +00:00
|
|
|
lowerword == "shift-cbuffer-bindings" ||
|
|
|
|
lowerword == "shift-cbuffer-binding" ||
|
|
|
|
lowerword == "sub" ||
|
|
|
|
lowerword == "scb") {
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
ProcessBindingBase(argc, argv, glslang::EResUbo);
|
2017-02-22 00:19:08 +00:00
|
|
|
} else if (lowerword == "shift-ssbo-bindings" || // synonyms
|
|
|
|
lowerword == "shift-ssbo-binding" ||
|
|
|
|
lowerword == "sbb") {
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
ProcessBindingBase(argc, argv, glslang::EResSsbo);
|
2017-06-14 21:52:44 +00:00
|
|
|
} else if (lowerword == "source-entrypoint" || // synonyms
|
|
|
|
lowerword == "sep") {
|
2017-06-23 16:58:31 +00:00
|
|
|
if (argc <= 1)
|
2019-12-20 17:33:13 +00:00
|
|
|
Error("no <entry-point> provided", lowerword.c_str());
|
2017-06-23 16:58:31 +00:00
|
|
|
sourceEntryPointName = argv[1];
|
|
|
|
bumpArg();
|
2017-02-15 22:29:33 +00:00
|
|
|
break;
|
2018-06-12 00:12:15 +00:00
|
|
|
} else if (lowerword == "spirv-dis") {
|
|
|
|
SpvToolsDisassembler = true;
|
2018-08-23 21:29:08 +00:00
|
|
|
} else if (lowerword == "spirv-val") {
|
|
|
|
SpvToolsValidate = true;
|
2017-09-02 17:34:54 +00:00
|
|
|
} else if (lowerword == "stdin") {
|
|
|
|
Options |= EOptionStdin;
|
|
|
|
shaderStageName = argv[1];
|
2017-07-21 02:00:36 +00:00
|
|
|
} else if (lowerword == "suppress-warnings") {
|
|
|
|
Options |= EOptionSuppressWarnings;
|
2017-06-23 17:11:09 +00:00
|
|
|
} else if (lowerword == "target-env") {
|
|
|
|
if (argc > 1) {
|
|
|
|
if (strcmp(argv[1], "vulkan1.0") == 0) {
|
|
|
|
setVulkanSpv();
|
2018-10-26 16:12:32 +00:00
|
|
|
ClientVersion = glslang::EShTargetVulkan_1_0;
|
2018-03-06 23:12:04 +00:00
|
|
|
} else if (strcmp(argv[1], "vulkan1.1") == 0) {
|
|
|
|
setVulkanSpv();
|
2018-10-26 16:12:32 +00:00
|
|
|
ClientVersion = glslang::EShTargetVulkan_1_1;
|
2020-01-15 07:10:41 +00:00
|
|
|
} else if (strcmp(argv[1], "vulkan1.2") == 0) {
|
|
|
|
setVulkanSpv();
|
|
|
|
ClientVersion = glslang::EShTargetVulkan_1_2;
|
2017-06-23 17:11:09 +00:00
|
|
|
} else if (strcmp(argv[1], "opengl") == 0) {
|
|
|
|
setOpenGlSpv();
|
2018-10-26 16:12:32 +00:00
|
|
|
ClientVersion = glslang::EShTargetOpenGL_450;
|
|
|
|
} else if (strcmp(argv[1], "spirv1.0") == 0) {
|
|
|
|
TargetLanguage = glslang::EShTargetSpv;
|
|
|
|
TargetVersion = glslang::EShTargetSpv_1_0;
|
|
|
|
} else if (strcmp(argv[1], "spirv1.1") == 0) {
|
|
|
|
TargetLanguage = glslang::EShTargetSpv;
|
|
|
|
TargetVersion = glslang::EShTargetSpv_1_1;
|
|
|
|
} else if (strcmp(argv[1], "spirv1.2") == 0) {
|
|
|
|
TargetLanguage = glslang::EShTargetSpv;
|
|
|
|
TargetVersion = glslang::EShTargetSpv_1_2;
|
|
|
|
} else if (strcmp(argv[1], "spirv1.3") == 0) {
|
|
|
|
TargetLanguage = glslang::EShTargetSpv;
|
|
|
|
TargetVersion = glslang::EShTargetSpv_1_3;
|
|
|
|
} else if (strcmp(argv[1], "spirv1.4") == 0) {
|
|
|
|
TargetLanguage = glslang::EShTargetSpv;
|
|
|
|
TargetVersion = glslang::EShTargetSpv_1_4;
|
2019-08-19 05:58:08 +00:00
|
|
|
} else if (strcmp(argv[1], "spirv1.5") == 0) {
|
|
|
|
TargetLanguage = glslang::EShTargetSpv;
|
|
|
|
TargetVersion = glslang::EShTargetSpv_1_5;
|
2017-06-23 17:11:09 +00:00
|
|
|
} else
|
2020-01-15 07:10:41 +00:00
|
|
|
Error("--target-env expected one of: vulkan1.0, vulkan1.1, vulkan1.2, opengl,\n"
|
2019-08-19 05:58:08 +00:00
|
|
|
"spirv1.0, spirv1.1, spirv1.2, spirv1.3, spirv1.4, or spirv1.5");
|
2017-06-23 17:11:09 +00:00
|
|
|
}
|
|
|
|
bumpArg();
|
2020-01-07 14:03:11 +00:00
|
|
|
} else if (lowerword == "undef-macro" ||
|
|
|
|
lowerword == "u") {
|
|
|
|
if (argc > 1)
|
|
|
|
UserPreamble.addUndef(argv[1]);
|
|
|
|
else
|
|
|
|
Error("expects <name>", argv[0]);
|
|
|
|
bumpArg();
|
2017-06-14 21:52:44 +00:00
|
|
|
} else if (lowerword == "variable-name" || // synonyms
|
2018-03-06 23:12:04 +00:00
|
|
|
lowerword == "vn") {
|
2017-06-14 21:52:44 +00:00
|
|
|
Options |= EOptionOutputHexadecimal;
|
2017-06-23 16:58:31 +00:00
|
|
|
if (argc <= 1)
|
2019-12-20 17:33:13 +00:00
|
|
|
Error("no <C-variable-name> provided", lowerword.c_str());
|
2017-06-23 16:58:31 +00:00
|
|
|
variableName = argv[1];
|
|
|
|
bumpArg();
|
2016-10-31 21:13:43 +00:00
|
|
|
break;
|
2020-07-03 12:55:29 +00:00
|
|
|
} else if (lowerword == "quiet") {
|
|
|
|
beQuiet = true;
|
2018-03-06 05:23:17 +00:00
|
|
|
} else if (lowerword == "version") {
|
|
|
|
Options |= EOptionDumpVersions;
|
2020-01-28 20:18:12 +00:00
|
|
|
} else if (lowerword == "help") {
|
|
|
|
usage();
|
|
|
|
break;
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
} else {
|
2019-12-20 17:33:13 +00:00
|
|
|
Error("unrecognized command-line option", argv[0]);
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2017-06-14 21:52:44 +00:00
|
|
|
case 'C':
|
|
|
|
Options |= EOptionCascadingErrors;
|
|
|
|
break;
|
|
|
|
case 'D':
|
2017-06-15 16:40:49 +00:00
|
|
|
if (argv[0][2] == 0)
|
|
|
|
Options |= EOptionReadHlsl;
|
|
|
|
else
|
2020-01-07 14:03:11 +00:00
|
|
|
UserPreamble.addDef(getStringOperand("-D<name[=def]>"));
|
2017-06-14 21:52:44 +00:00
|
|
|
break;
|
2018-03-20 16:30:53 +00:00
|
|
|
case 'u':
|
|
|
|
uniformLocationOverrides.push_back(getUniformOverride());
|
|
|
|
break;
|
2017-06-14 21:52:44 +00:00
|
|
|
case 'E':
|
|
|
|
Options |= EOptionOutputPreprocessed;
|
|
|
|
break;
|
|
|
|
case 'G':
|
2018-10-26 16:12:32 +00:00
|
|
|
// OpenGL client
|
2017-06-23 17:11:09 +00:00
|
|
|
setOpenGlSpv();
|
|
|
|
if (argv[0][2] != 0)
|
|
|
|
ClientInputSemanticsVersion = getAttachedNumber("-G<num> client input semantics");
|
2020-08-04 13:17:39 +00:00
|
|
|
if (ClientInputSemanticsVersion != 100)
|
|
|
|
Error("unknown client version for -G, should be 100");
|
2017-06-14 21:52:44 +00:00
|
|
|
break;
|
2015-05-15 16:02:07 +00:00
|
|
|
case 'H':
|
|
|
|
Options |= EOptionHumanReadableSpv;
|
2016-07-07 23:46:42 +00:00
|
|
|
if ((Options & EOptionSpv) == 0) {
|
|
|
|
// default to Vulkan
|
2017-06-23 17:11:09 +00:00
|
|
|
setVulkanSpv();
|
2016-07-07 23:46:42 +00:00
|
|
|
}
|
|
|
|
break;
|
2017-06-07 21:06:58 +00:00
|
|
|
case 'I':
|
2017-06-15 16:40:49 +00:00
|
|
|
IncludeDirectoryList.push_back(getStringOperand("-I<dir> include path"));
|
2015-07-13 01:28:10 +00:00
|
|
|
break;
|
2017-09-22 00:40:22 +00:00
|
|
|
case 'O':
|
|
|
|
if (argv[0][2] == 'd')
|
|
|
|
Options |= EOptionOptimizeDisable;
|
|
|
|
else if (argv[0][2] == 's')
|
2018-03-29 17:49:14 +00:00
|
|
|
#if ENABLE_OPT
|
2017-09-22 00:40:22 +00:00
|
|
|
Options |= EOptionOptimizeSize;
|
|
|
|
#else
|
|
|
|
Error("-Os not available; optimizer not linked");
|
|
|
|
#endif
|
|
|
|
else
|
|
|
|
Error("unknown -O option");
|
|
|
|
break;
|
2021-03-15 17:26:11 +00:00
|
|
|
case 'R':
|
|
|
|
VulkanRulesRelaxed = true;
|
|
|
|
break;
|
2016-08-11 21:53:57 +00:00
|
|
|
case 'S':
|
2017-06-23 16:58:31 +00:00
|
|
|
if (argc <= 1)
|
2016-08-11 21:53:57 +00:00
|
|
|
Error("no <stage> specified for -S");
|
2017-06-23 16:58:31 +00:00
|
|
|
shaderStageName = argv[1];
|
|
|
|
bumpArg();
|
2016-08-09 01:43:07 +00:00
|
|
|
break;
|
2017-06-15 16:40:49 +00:00
|
|
|
case 'U':
|
2020-01-07 14:03:11 +00:00
|
|
|
UserPreamble.addUndef(getStringOperand("-U<name>"));
|
2017-06-15 16:40:49 +00:00
|
|
|
break;
|
2017-06-14 21:52:44 +00:00
|
|
|
case 'V':
|
2017-06-23 17:11:09 +00:00
|
|
|
setVulkanSpv();
|
|
|
|
if (argv[0][2] != 0)
|
2018-02-28 02:55:23 +00:00
|
|
|
ClientInputSemanticsVersion = getAttachedNumber("-V<num> client input semantics");
|
2020-08-04 13:17:39 +00:00
|
|
|
if (ClientInputSemanticsVersion != 100)
|
|
|
|
Error("unknown client version for -V, should be 100");
|
2015-06-17 02:38:44 +00:00
|
|
|
break;
|
2013-09-17 19:26:08 +00:00
|
|
|
case 'c':
|
|
|
|
Options |= EOptionDumpConfig;
|
|
|
|
break;
|
2013-07-31 18:44:13 +00:00
|
|
|
case 'd':
|
2018-03-06 05:23:17 +00:00
|
|
|
if (strncmp(&argv[0][1], "dumpversion", strlen(&argv[0][1]) + 1) == 0 ||
|
|
|
|
strncmp(&argv[0][1], "dumpfullversion", strlen(&argv[0][1]) + 1) == 0)
|
|
|
|
Options |= EOptionDumpBareVersion;
|
|
|
|
else
|
|
|
|
Options |= EOptionDefaultDesktop;
|
2013-07-31 18:44:13 +00:00
|
|
|
break;
|
2016-03-13 01:17:47 +00:00
|
|
|
case 'e':
|
|
|
|
entryPointName = argv[1];
|
2017-06-23 16:58:31 +00:00
|
|
|
if (argc <= 1)
|
2017-09-12 02:13:49 +00:00
|
|
|
Error("no <name> provided for -e");
|
2017-06-23 16:58:31 +00:00
|
|
|
bumpArg();
|
2016-03-13 01:17:47 +00:00
|
|
|
break;
|
2018-03-08 01:05:55 +00:00
|
|
|
case 'f':
|
|
|
|
if (strcmp(&argv[0][2], "hlsl_functionality1") == 0)
|
|
|
|
targetHlslFunctionality1 = true;
|
|
|
|
else
|
|
|
|
Error("-f: expected hlsl_functionality1");
|
|
|
|
break;
|
2017-05-31 23:11:16 +00:00
|
|
|
case 'g':
|
2020-06-17 16:47:44 +00:00
|
|
|
// Override previous -g or -g0 argument
|
|
|
|
stripDebugInfo = false;
|
|
|
|
Options &= ~EOptionDebug;
|
|
|
|
if (argv[0][2] == '0')
|
|
|
|
stripDebugInfo = true;
|
|
|
|
else
|
|
|
|
Options |= EOptionDebug;
|
2017-05-31 23:11:16 +00:00
|
|
|
break;
|
2015-07-13 01:28:10 +00:00
|
|
|
case 'h':
|
|
|
|
usage();
|
|
|
|
break;
|
2013-09-17 19:26:08 +00:00
|
|
|
case 'i':
|
2013-08-31 02:41:30 +00:00
|
|
|
Options |= EOptionIntermediate;
|
2013-07-31 18:44:13 +00:00
|
|
|
break;
|
|
|
|
case 'l':
|
2014-08-25 20:07:55 +00:00
|
|
|
Options |= EOptionLinkProgram;
|
2013-08-31 02:41:30 +00:00
|
|
|
break;
|
|
|
|
case 'm':
|
|
|
|
Options |= EOptionMemoryLeakMode;
|
2013-07-31 18:44:13 +00:00
|
|
|
break;
|
2015-07-13 01:28:10 +00:00
|
|
|
case 'o':
|
2017-06-23 16:58:31 +00:00
|
|
|
if (argc <= 1)
|
2015-07-13 01:28:10 +00:00
|
|
|
Error("no <file> provided for -o");
|
2017-06-23 16:58:31 +00:00
|
|
|
binaryFileName = argv[1];
|
|
|
|
bumpArg();
|
2015-07-13 01:28:10 +00:00
|
|
|
break;
|
2013-11-07 01:06:34 +00:00
|
|
|
case 'q':
|
|
|
|
Options |= EOptionDumpReflection;
|
|
|
|
break;
|
2013-07-31 18:44:13 +00:00
|
|
|
case 'r':
|
2013-08-31 02:41:30 +00:00
|
|
|
Options |= EOptionRelaxedErrors;
|
2013-07-31 18:44:13 +00:00
|
|
|
break;
|
|
|
|
case 's':
|
2013-08-31 02:41:30 +00:00
|
|
|
Options |= EOptionSuppressInfolog;
|
2013-07-31 18:44:13 +00:00
|
|
|
break;
|
2013-09-06 19:52:57 +00:00
|
|
|
case 't':
|
2017-04-02 21:04:00 +00:00
|
|
|
Options |= EOptionMultiThreaded;
|
2013-09-06 19:52:57 +00:00
|
|
|
break;
|
2013-12-04 04:43:40 +00:00
|
|
|
case 'v':
|
|
|
|
Options |= EOptionDumpVersions;
|
|
|
|
break;
|
2013-11-07 17:44:20 +00:00
|
|
|
case 'w':
|
|
|
|
Options |= EOptionSuppressWarnings;
|
|
|
|
break;
|
2016-05-27 17:55:53 +00:00
|
|
|
case 'x':
|
|
|
|
Options |= EOptionOutputHexadecimal;
|
|
|
|
break;
|
2013-07-31 18:44:13 +00:00
|
|
|
default:
|
2019-12-20 17:33:13 +00:00
|
|
|
Error("unrecognized command-line option", argv[0]);
|
2015-07-13 01:28:10 +00:00
|
|
|
break;
|
2012-12-12 21:15:54 +00:00
|
|
|
}
|
2013-09-06 19:52:57 +00:00
|
|
|
} else {
|
2013-09-17 19:26:08 +00:00
|
|
|
std::string name(argv[0]);
|
|
|
|
if (! SetConfigFile(name)) {
|
2017-04-02 21:04:00 +00:00
|
|
|
workItems.push_back(std::unique_ptr<glslang::TWorkItem>(new glslang::TWorkItem(name)));
|
2013-09-17 19:26:08 +00:00
|
|
|
}
|
2013-09-06 19:52:57 +00:00
|
|
|
}
|
2013-07-31 18:44:13 +00:00
|
|
|
}
|
2012-12-12 21:15:54 +00:00
|
|
|
|
2017-09-02 17:34:54 +00:00
|
|
|
// Make sure that -S is always specified if --stdin is specified
|
|
|
|
if ((Options & EOptionStdin) && shaderStageName == nullptr)
|
|
|
|
Error("must provide -S when --stdin is given");
|
|
|
|
|
2015-07-13 01:28:10 +00:00
|
|
|
// Make sure that -E is not specified alongside linking (which includes SPV generation)
|
2019-07-02 15:32:48 +00:00
|
|
|
// Or things that require linking
|
|
|
|
if (Options & EOptionOutputPreprocessed) {
|
|
|
|
if (Options & EOptionLinkProgram)
|
|
|
|
Error("can't use -E when linking is selected");
|
|
|
|
if (Options & EOptionDumpReflection)
|
|
|
|
Error("reflection requires linking, which can't be used when -E when is selected");
|
|
|
|
}
|
|
|
|
|
|
|
|
// reflection requires linking
|
|
|
|
if ((Options & EOptionDumpReflection) && !(Options & EOptionLinkProgram))
|
|
|
|
Error("reflection requires -l for linking");
|
2015-06-17 02:38:44 +00:00
|
|
|
|
2016-05-27 17:55:53 +00:00
|
|
|
// -o or -x makes no sense if there is no target binary
|
2015-07-13 01:28:10 +00:00
|
|
|
if (binaryFileName && (Options & EOptionSpv) == 0)
|
|
|
|
Error("no binary generation requested (e.g., -V)");
|
2016-09-16 19:26:37 +00:00
|
|
|
|
|
|
|
if ((Options & EOptionFlattenUniformArrays) != 0 &&
|
|
|
|
(Options & EOptionReadHlsl) == 0)
|
|
|
|
Error("uniform array flattening only valid when compiling HLSL source.");
|
2018-10-26 16:12:32 +00:00
|
|
|
|
2021-01-05 22:54:41 +00:00
|
|
|
if ((Options & EOptionReadHlsl) && (Client == glslang::EShClientOpenGL)) {
|
|
|
|
Error("Using HLSL input under OpenGL semantics is not currently supported.");
|
|
|
|
}
|
|
|
|
|
2018-10-26 16:12:32 +00:00
|
|
|
// rationalize client and target language
|
|
|
|
if (TargetLanguage == glslang::EShTargetNone) {
|
|
|
|
switch (ClientVersion) {
|
|
|
|
case glslang::EShTargetVulkan_1_0:
|
|
|
|
TargetLanguage = glslang::EShTargetSpv;
|
|
|
|
TargetVersion = glslang::EShTargetSpv_1_0;
|
|
|
|
break;
|
|
|
|
case glslang::EShTargetVulkan_1_1:
|
|
|
|
TargetLanguage = glslang::EShTargetSpv;
|
|
|
|
TargetVersion = glslang::EShTargetSpv_1_3;
|
|
|
|
break;
|
2020-01-15 07:10:41 +00:00
|
|
|
case glslang::EShTargetVulkan_1_2:
|
|
|
|
TargetLanguage = glslang::EShTargetSpv;
|
|
|
|
TargetVersion = glslang::EShTargetSpv_1_5;
|
|
|
|
break;
|
2018-10-26 16:12:32 +00:00
|
|
|
case glslang::EShTargetOpenGL_450:
|
|
|
|
TargetLanguage = glslang::EShTargetSpv;
|
|
|
|
TargetVersion = glslang::EShTargetSpv_1_0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (TargetLanguage != glslang::EShTargetNone && Client == glslang::EShClientNone)
|
|
|
|
Error("To generate SPIR-V, also specify client semantics. See -G and -V.");
|
2013-07-31 18:44:13 +00:00
|
|
|
}
|
2012-12-12 21:15:54 +00:00
|
|
|
|
2015-07-13 01:28:10 +00:00
|
|
|
//
|
|
|
|
// Translate the meaningful subset of command-line options to parser-behavior options.
|
|
|
|
//
|
2013-11-07 17:44:20 +00:00
|
|
|
void SetMessageOptions(EShMessages& messages)
|
|
|
|
{
|
|
|
|
if (Options & EOptionRelaxedErrors)
|
|
|
|
messages = (EShMessages)(messages | EShMsgRelaxedErrors);
|
|
|
|
if (Options & EOptionIntermediate)
|
|
|
|
messages = (EShMessages)(messages | EShMsgAST);
|
|
|
|
if (Options & EOptionSuppressWarnings)
|
|
|
|
messages = (EShMessages)(messages | EShMsgSuppressWarnings);
|
2015-07-13 01:28:10 +00:00
|
|
|
if (Options & EOptionSpv)
|
|
|
|
messages = (EShMessages)(messages | EShMsgSpvRules);
|
|
|
|
if (Options & EOptionVulkanRules)
|
|
|
|
messages = (EShMessages)(messages | EShMsgVulkanRules);
|
2015-06-24 21:00:46 +00:00
|
|
|
if (Options & EOptionOutputPreprocessed)
|
|
|
|
messages = (EShMessages)(messages | EShMsgOnlyPreprocessor);
|
2016-03-13 01:34:36 +00:00
|
|
|
if (Options & EOptionReadHlsl)
|
|
|
|
messages = (EShMessages)(messages | EShMsgReadHlsl);
|
2016-07-09 20:50:57 +00:00
|
|
|
if (Options & EOptionCascadingErrors)
|
|
|
|
messages = (EShMessages)(messages | EShMsgCascadingErrors);
|
2016-12-10 02:22:20 +00:00
|
|
|
if (Options & EOptionKeepUncalled)
|
|
|
|
messages = (EShMessages)(messages | EShMsgKeepUncalled);
|
2017-04-05 23:38:20 +00:00
|
|
|
if (Options & EOptionHlslOffsets)
|
|
|
|
messages = (EShMessages)(messages | EShMsgHlslOffsets);
|
2017-05-31 23:11:16 +00:00
|
|
|
if (Options & EOptionDebug)
|
|
|
|
messages = (EShMessages)(messages | EShMsgDebugInfo);
|
2018-03-07 05:10:01 +00:00
|
|
|
if (HlslEnable16BitTypes)
|
|
|
|
messages = (EShMessages)(messages | EShMsgHlslEnable16BitTypes);
|
2018-03-29 17:49:14 +00:00
|
|
|
if ((Options & EOptionOptimizeDisable) || !ENABLE_OPT)
|
|
|
|
messages = (EShMessages)(messages | EShMsgHlslLegalization);
|
2018-12-08 01:38:26 +00:00
|
|
|
if (HlslDX9compatible)
|
|
|
|
messages = (EShMessages)(messages | EShMsgHlslDX9Compatible);
|
2019-04-13 20:18:16 +00:00
|
|
|
if (DumpBuiltinSymbols)
|
|
|
|
messages = (EShMessages)(messages | EShMsgBuiltinSymbolTable);
|
2013-11-07 17:44:20 +00:00
|
|
|
}
|
|
|
|
|
2015-07-13 01:28:10 +00:00
|
|
|
//
|
2013-09-04 21:19:27 +00:00
|
|
|
// Thread entry point, for non-linking asynchronous mode.
|
2013-11-07 23:33:24 +00:00
|
|
|
//
|
2017-04-02 21:04:00 +00:00
|
|
|
void CompileShaders(glslang::TWorklist& worklist)
|
2013-07-31 18:44:13 +00:00
|
|
|
{
|
2018-04-06 01:00:01 +00:00
|
|
|
if (Options & EOptionDebug)
|
|
|
|
Error("cannot generate debug information unless linking to generate code");
|
|
|
|
|
2013-09-06 19:52:57 +00:00
|
|
|
glslang::TWorkItem* workItem;
|
2017-09-02 17:34:54 +00:00
|
|
|
if (Options & EOptionStdin) {
|
2018-07-12 21:11:07 +00:00
|
|
|
if (worklist.remove(workItem)) {
|
|
|
|
ShHandle compiler = ShConstructCompiler(FindLanguage("stdin"), Options);
|
|
|
|
if (compiler == nullptr)
|
|
|
|
return;
|
2012-12-12 21:15:54 +00:00
|
|
|
|
2018-07-12 21:11:07 +00:00
|
|
|
CompileFile("stdin", compiler);
|
2012-12-12 21:15:54 +00:00
|
|
|
|
2017-09-02 17:34:54 +00:00
|
|
|
if (! (Options & EOptionSuppressInfolog))
|
|
|
|
workItem->results = ShGetInfoLog(compiler);
|
2012-12-12 21:15:54 +00:00
|
|
|
|
2018-07-12 21:11:07 +00:00
|
|
|
ShDestruct(compiler);
|
|
|
|
}
|
2017-09-02 17:34:54 +00:00
|
|
|
} else {
|
|
|
|
while (worklist.remove(workItem)) {
|
|
|
|
ShHandle compiler = ShConstructCompiler(FindLanguage(workItem->name), Options);
|
|
|
|
if (compiler == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
CompileFile(workItem->name.c_str(), compiler);
|
|
|
|
|
|
|
|
if (! (Options & EOptionSuppressInfolog))
|
|
|
|
workItem->results = ShGetInfoLog(compiler);
|
|
|
|
|
|
|
|
ShDestruct(compiler);
|
|
|
|
}
|
2013-07-31 18:44:13 +00:00
|
|
|
}
|
|
|
|
}
|
2012-12-12 21:15:54 +00:00
|
|
|
|
2015-06-19 05:14:19 +00:00
|
|
|
// Outputs the given string, but only if it is non-null and non-empty.
|
|
|
|
// This prevents erroneous newlines from appearing.
|
2015-06-24 21:00:46 +00:00
|
|
|
void PutsIfNonEmpty(const char* str)
|
2015-06-19 05:14:19 +00:00
|
|
|
{
|
|
|
|
if (str && str[0]) {
|
|
|
|
puts(str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-24 21:00:46 +00:00
|
|
|
// Outputs the given string to stderr, but only if it is non-null and non-empty.
|
|
|
|
// This prevents erroneous newlines from appearing.
|
|
|
|
void StderrIfNonEmpty(const char* str)
|
|
|
|
{
|
2017-06-14 23:36:50 +00:00
|
|
|
if (str && str[0])
|
|
|
|
fprintf(stderr, "%s\n", str);
|
2015-06-24 21:00:46 +00:00
|
|
|
}
|
|
|
|
|
2016-01-16 22:30:03 +00:00
|
|
|
// Simple bundling of what makes a compilation unit for ease in passing around,
|
|
|
|
// and separation of handling file IO versus API (programmatic) compilation.
|
|
|
|
struct ShaderCompUnit {
|
|
|
|
EShLanguage stage;
|
2017-06-14 23:36:50 +00:00
|
|
|
static const int maxCount = 1;
|
|
|
|
int count; // live number of strings/names
|
2017-06-15 16:40:49 +00:00
|
|
|
const char* text[maxCount]; // memory owned/managed externally
|
2017-06-14 23:36:50 +00:00
|
|
|
std::string fileName[maxCount]; // hold's the memory, but...
|
|
|
|
const char* fileNameList[maxCount]; // downstream interface wants pointers
|
2016-08-21 16:29:08 +00:00
|
|
|
|
2017-06-14 23:36:50 +00:00
|
|
|
ShaderCompUnit(EShLanguage stage) : stage(stage), count(0) { }
|
2016-08-21 16:29:08 +00:00
|
|
|
|
2017-06-14 23:36:50 +00:00
|
|
|
ShaderCompUnit(const ShaderCompUnit& rhs)
|
2016-08-21 16:29:08 +00:00
|
|
|
{
|
|
|
|
stage = rhs.stage;
|
2017-06-14 23:36:50 +00:00
|
|
|
count = rhs.count;
|
|
|
|
for (int i = 0; i < count; ++i) {
|
|
|
|
fileName[i] = rhs.fileName[i];
|
|
|
|
text[i] = rhs.text[i];
|
|
|
|
fileNameList[i] = rhs.fileName[i].c_str();
|
|
|
|
}
|
2016-08-21 16:29:08 +00:00
|
|
|
}
|
|
|
|
|
2017-06-15 16:40:49 +00:00
|
|
|
void addString(std::string& ifileName, const char* itext)
|
2017-06-14 23:36:50 +00:00
|
|
|
{
|
|
|
|
assert(count < maxCount);
|
|
|
|
fileName[count] = ifileName;
|
|
|
|
text[count] = itext;
|
|
|
|
fileNameList[count] = fileName[count].c_str();
|
|
|
|
++count;
|
|
|
|
}
|
2016-01-16 22:30:03 +00:00
|
|
|
};
|
|
|
|
|
2013-09-04 21:19:27 +00:00
|
|
|
//
|
2016-01-16 22:30:03 +00:00
|
|
|
// For linking mode: Will independently parse each compilation unit, but then put them
|
|
|
|
// in the same program and link them together, making at most one linked module per
|
|
|
|
// pipeline stage.
|
2013-09-04 21:19:27 +00:00
|
|
|
//
|
|
|
|
// Uses the new C++ interface instead of the old handle-based interface.
|
|
|
|
//
|
2016-01-16 22:30:03 +00:00
|
|
|
|
|
|
|
void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
2013-09-04 21:19:27 +00:00
|
|
|
{
|
|
|
|
// keep track of what to free
|
|
|
|
std::list<glslang::TShader*> shaders;
|
2016-01-16 22:30:03 +00:00
|
|
|
|
2013-09-04 21:19:27 +00:00
|
|
|
EShMessages messages = EShMsgDefault;
|
2013-11-07 17:44:20 +00:00
|
|
|
SetMessageOptions(messages);
|
2013-09-04 21:19:27 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// Per-shader processing...
|
|
|
|
//
|
|
|
|
|
2013-11-01 03:08:40 +00:00
|
|
|
glslang::TProgram& program = *new glslang::TProgram;
|
2016-02-23 21:17:38 +00:00
|
|
|
for (auto it = compUnits.cbegin(); it != compUnits.cend(); ++it) {
|
|
|
|
const auto &compUnit = *it;
|
2016-01-16 22:30:03 +00:00
|
|
|
glslang::TShader* shader = new glslang::TShader(compUnit.stage);
|
2017-06-14 23:36:50 +00:00
|
|
|
shader->setStringsWithLengthsAndNames(compUnit.text, NULL, compUnit.fileNameList, compUnit.count);
|
2018-08-09 20:15:00 +00:00
|
|
|
if (entryPointName)
|
2016-03-13 01:17:47 +00:00
|
|
|
shader->setEntryPoint(entryPointName);
|
2017-09-29 23:51:52 +00:00
|
|
|
if (sourceEntryPointName) {
|
|
|
|
if (entryPointName == nullptr)
|
|
|
|
printf("Warning: Changing source entry point name without setting an entry-point name.\n"
|
|
|
|
"Use '-e <name>'.\n");
|
2016-10-31 21:13:43 +00:00
|
|
|
shader->setSourceEntryPoint(sourceEntryPointName);
|
2017-09-29 23:51:52 +00:00
|
|
|
}
|
2017-06-15 16:40:49 +00:00
|
|
|
if (UserPreamble.isSet())
|
|
|
|
shader->setPreamble(UserPreamble.get());
|
2017-07-21 02:00:36 +00:00
|
|
|
shader->addProcesses(Processes);
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
|
2019-08-09 05:29:20 +00:00
|
|
|
#ifndef GLSLANG_WEB
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
// Set IO mapper binding shift values
|
|
|
|
for (int r = 0; r < glslang::EResCount; ++r) {
|
|
|
|
const glslang::TResourceType res = glslang::TResourceType(r);
|
|
|
|
|
|
|
|
// Set base bindings
|
|
|
|
shader->setShiftBinding(res, baseBinding[res][compUnit.stage]);
|
2019-10-21 18:50:31 +00:00
|
|
|
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
// Set bindings for particular resource sets
|
|
|
|
// TODO: use a range based for loop here, when available in all environments.
|
|
|
|
for (auto i = baseBindingForSet[res][compUnit.stage].begin();
|
|
|
|
i != baseBindingForSet[res][compUnit.stage].end(); ++i)
|
2017-10-21 16:46:39 +00:00
|
|
|
shader->setShiftBindingForSet(res, i->second, i->first);
|
Add per-descriptor-set IO mapping shift values.
This PR adds the ability to provide per-descriptor-set IO mapping shift
values. If a particular binding does not land into a per-set value,
then it falls back to the prior behavior (global shifts per resource class).
Because there were already 6 copies of many different methods and internal
variables and functions, and this PR would have added 6 more, a new API is
introduced to cut down on replication and present a cleaner interface.
For the global (non-set-specific) API, the old entry points still exist
for backward compatibility, but are phrased internally in terms of the
following.
// Resource type for IO resolver
enum TResourceType {
EResSampler,
EResTexture,
EResImage,
EResUbo,
EResSsbo,
EResUav,
EResCount
};
Methods on TShader:
void setShiftBinding(TResourceType res, unsigned int base);
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
The first method replaces the 6 prior entry points of various spellings, which
exist now in depreciated form. The second provides per-resource-set functionality.
Both accept an enum from the list above.
From the command line, the existing options can accept either a single shift value as
before, or a series of 1 or more [set offset] pairs. Both can be provided, as in:
... --stb 20 --stb 2 25 3 30 ...
which will use the offset 20 for anything except descriptor set 2 (which uses 25) and
3 (which uses 30).
2017-10-18 01:27:14 +00:00
|
|
|
}
|
2016-10-15 00:36:42 +00:00
|
|
|
shader->setNoStorageFormat((Options & EOptionNoStorageFormat) != 0);
|
2017-05-02 07:27:29 +00:00
|
|
|
shader->setResourceSetBinding(baseResourceSetBinding[compUnit.stage]);
|
HLSL: Add location offsets per resource type
This PR adds the ability to offset sampler, texture, and UBO bindings
from provided base bindings, and to auto-number bindings that are not
provided with explicit register numbers. The mechanism works as
follows:
- Offsets may be given on the command line for all stages, or
individually for one or more single stages, in which case the
offset will be auto-selected according to the stage being
compiled. There is also an API to set them. The new command line
options are --shift-sampler-binding, --shift-texture-binding, and
--shift-UBO-binding.
- Uniforms which are not given explicit bindings in the source code
are auto-numbered if and only if they are in live code as
determined by the algorithm used to build the reflection
database, and the --auto-map-bindings option is given. This auto-numbering
avoids using any binding slots which were explicitly provided in
the code, whether or not that explicit use was live. E.g, "uniform
Texture1D foo : register(t3);" with --shift-texture-binding 10 will
reserve binding 13, whether or not foo is used in live code.
- Shorter synonyms for the command line options are available. See
the --help output.
The testing infrastructure is slightly extended to allow use of the
binding offset API, and two new tests spv.register.(no)autoassign.frag are
added for comparing the resulting SPIR-V.
2016-09-07 21:20:19 +00:00
|
|
|
|
|
|
|
if (Options & EOptionAutoMapBindings)
|
|
|
|
shader->setAutoMapBindings(true);
|
2017-01-06 07:34:48 +00:00
|
|
|
|
2017-05-18 00:28:19 +00:00
|
|
|
if (Options & EOptionAutoMapLocations)
|
|
|
|
shader->setAutoMapLocations(true);
|
|
|
|
|
2018-03-20 16:30:53 +00:00
|
|
|
for (auto& uniOverride : uniformLocationOverrides) {
|
|
|
|
shader->addUniformLocationOverride(uniOverride.first.c_str(),
|
|
|
|
uniOverride.second);
|
|
|
|
}
|
|
|
|
|
2018-03-20 16:41:05 +00:00
|
|
|
shader->setUniformLocationBase(uniformBase);
|
2019-08-09 05:29:20 +00:00
|
|
|
#endif
|
|
|
|
|
2021-03-15 17:26:11 +00:00
|
|
|
if (VulkanRulesRelaxed) {
|
|
|
|
for (auto& storageOverride : blockStorageOverrides) {
|
|
|
|
shader->addBlockStorageOverride(storageOverride.first.c_str(),
|
|
|
|
storageOverride.second);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (setGlobalBufferBlock) {
|
|
|
|
shader->setAtomicCounterBlockName(atomicCounterBlockName.c_str());
|
|
|
|
shader->setAtomicCounterBlockSet(atomicCounterBlockSet);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (setGlobalUniformBlock) {
|
|
|
|
shader->setGlobalUniformBlockName(globalUniformName.c_str());
|
|
|
|
shader->setGlobalUniformSet(globalUniformSet);
|
|
|
|
shader->setGlobalUniformBinding(globalUniformBinding);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-09 05:29:20 +00:00
|
|
|
shader->setNanMinMaxClamp(NaNClamp);
|
|
|
|
|
|
|
|
#ifdef ENABLE_HLSL
|
|
|
|
shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0);
|
|
|
|
if (Options & EOptionHlslIoMapping)
|
|
|
|
shader->setHlslIoMapping(true);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (Options & EOptionInvertY)
|
|
|
|
shader->setInvertY(true);
|
2018-03-20 16:41:05 +00:00
|
|
|
|
2017-06-23 16:50:22 +00:00
|
|
|
// Set up the environment, some subsettings take precedence over earlier
|
|
|
|
// ways of setting things.
|
|
|
|
if (Options & EOptionSpv) {
|
2018-10-26 16:12:32 +00:00
|
|
|
shader->setEnvInput((Options & EOptionReadHlsl) ? glslang::EShSourceHlsl
|
|
|
|
: glslang::EShSourceGlsl,
|
|
|
|
compUnit.stage, Client, ClientInputSemanticsVersion);
|
|
|
|
shader->setEnvClient(Client, ClientVersion);
|
|
|
|
shader->setEnvTarget(TargetLanguage, TargetVersion);
|
2019-07-27 11:22:30 +00:00
|
|
|
#ifdef ENABLE_HLSL
|
2018-03-08 01:05:55 +00:00
|
|
|
if (targetHlslFunctionality1)
|
|
|
|
shader->setEnvTargetHlslFunctionality1();
|
2019-07-27 11:22:30 +00:00
|
|
|
#endif
|
2021-03-15 17:26:11 +00:00
|
|
|
if (VulkanRulesRelaxed)
|
|
|
|
shader->setEnvInputVulkanRulesRelaxed();
|
2017-06-23 16:50:22 +00:00
|
|
|
}
|
|
|
|
|
2013-09-04 21:19:27 +00:00
|
|
|
shaders.push_back(shader);
|
2015-07-12 00:01:03 +00:00
|
|
|
|
2017-06-23 16:50:22 +00:00
|
|
|
const int defaultVersion = Options & EOptionDefaultDesktop ? 110 : 100;
|
2013-09-04 21:19:27 +00:00
|
|
|
|
2017-05-22 21:00:42 +00:00
|
|
|
DirStackFileIncluder includer;
|
2017-06-07 21:06:58 +00:00
|
|
|
std::for_each(IncludeDirectoryList.rbegin(), IncludeDirectoryList.rend(), [&includer](const std::string& dir) {
|
|
|
|
includer.pushExternalLocalDirectory(dir); });
|
2019-08-13 14:00:30 +00:00
|
|
|
#ifndef GLSLANG_WEB
|
2015-06-17 02:38:44 +00:00
|
|
|
if (Options & EOptionOutputPreprocessed) {
|
|
|
|
std::string str;
|
2018-10-25 18:43:02 +00:00
|
|
|
if (shader->preprocess(&Resources, defaultVersion, ENoProfile, false, false, messages, &str, includer)) {
|
2015-06-24 21:00:46 +00:00
|
|
|
PutsIfNonEmpty(str.c_str());
|
|
|
|
} else {
|
|
|
|
CompileFailed = true;
|
|
|
|
}
|
|
|
|
StderrIfNonEmpty(shader->getInfoLog());
|
|
|
|
StderrIfNonEmpty(shader->getInfoDebugLog());
|
2015-06-17 02:38:44 +00:00
|
|
|
continue;
|
|
|
|
}
|
2019-08-13 14:00:30 +00:00
|
|
|
#endif
|
2018-10-25 18:43:02 +00:00
|
|
|
|
2017-05-22 21:00:42 +00:00
|
|
|
if (! shader->parse(&Resources, defaultVersion, false, messages, includer))
|
2013-11-07 23:33:24 +00:00
|
|
|
CompileFailed = true;
|
2015-06-17 02:38:44 +00:00
|
|
|
|
2013-09-04 21:19:27 +00:00
|
|
|
program.addShader(shader);
|
|
|
|
|
2016-01-16 22:30:03 +00:00
|
|
|
if (! (Options & EOptionSuppressInfolog) &&
|
|
|
|
! (Options & EOptionMemoryLeakMode)) {
|
2020-07-03 12:55:29 +00:00
|
|
|
if (!beQuiet)
|
|
|
|
PutsIfNonEmpty(compUnit.fileName[0].c_str());
|
2015-06-24 21:00:46 +00:00
|
|
|
PutsIfNonEmpty(shader->getInfoLog());
|
|
|
|
PutsIfNonEmpty(shader->getInfoDebugLog());
|
2013-09-04 21:19:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Program-level processing...
|
|
|
|
//
|
|
|
|
|
2016-03-13 01:17:47 +00:00
|
|
|
// Link
|
2015-07-13 01:28:10 +00:00
|
|
|
if (! (Options & EOptionOutputPreprocessed) && ! program.link(messages))
|
2013-11-07 23:33:24 +00:00
|
|
|
LinkFailed = true;
|
|
|
|
|
2019-08-06 08:20:45 +00:00
|
|
|
#ifndef GLSLANG_WEB
|
2016-10-05 19:40:13 +00:00
|
|
|
// Map IO
|
|
|
|
if (Options & EOptionSpv) {
|
|
|
|
if (!program.mapIO())
|
|
|
|
LinkFailed = true;
|
|
|
|
}
|
2019-08-06 08:20:45 +00:00
|
|
|
#endif
|
2017-01-06 07:34:48 +00:00
|
|
|
|
2016-03-13 01:17:47 +00:00
|
|
|
// Report
|
2016-01-16 22:30:03 +00:00
|
|
|
if (! (Options & EOptionSuppressInfolog) &&
|
|
|
|
! (Options & EOptionMemoryLeakMode)) {
|
2015-06-24 21:00:46 +00:00
|
|
|
PutsIfNonEmpty(program.getInfoLog());
|
|
|
|
PutsIfNonEmpty(program.getInfoDebugLog());
|
2013-09-04 21:19:27 +00:00
|
|
|
}
|
|
|
|
|
2019-08-06 08:20:45 +00:00
|
|
|
#ifndef GLSLANG_WEB
|
2016-03-13 01:17:47 +00:00
|
|
|
// Reflect
|
2013-11-07 01:06:34 +00:00
|
|
|
if (Options & EOptionDumpReflection) {
|
2019-01-29 15:45:56 +00:00
|
|
|
program.buildReflection(ReflectOptions);
|
2013-11-07 01:06:34 +00:00
|
|
|
program.dumpReflection();
|
|
|
|
}
|
2019-08-06 08:20:45 +00:00
|
|
|
#endif
|
2013-11-07 01:06:34 +00:00
|
|
|
|
2016-03-13 01:17:47 +00:00
|
|
|
// Dump SPIR-V
|
2015-03-03 17:09:43 +00:00
|
|
|
if (Options & EOptionSpv) {
|
2014-07-28 04:21:04 +00:00
|
|
|
if (CompileFailed || LinkFailed)
|
2015-07-13 01:28:10 +00:00
|
|
|
printf("SPIR-V is not generated for failed compile or link\n");
|
2014-07-28 04:21:04 +00:00
|
|
|
else {
|
|
|
|
for (int stage = 0; stage < EShLangCount; ++stage) {
|
2014-08-24 18:21:00 +00:00
|
|
|
if (program.getIntermediate((EShLanguage)stage)) {
|
2015-03-03 17:09:43 +00:00
|
|
|
std::vector<unsigned int> spirv;
|
2016-05-04 19:55:59 +00:00
|
|
|
spv::SpvBuildLogger logger;
|
2017-05-31 23:11:16 +00:00
|
|
|
glslang::SpvOptions spvOptions;
|
|
|
|
if (Options & EOptionDebug)
|
|
|
|
spvOptions.generateDebugInfo = true;
|
2020-06-17 16:47:44 +00:00
|
|
|
else if (stripDebugInfo)
|
|
|
|
spvOptions.stripDebugInfo = true;
|
2017-09-28 16:08:32 +00:00
|
|
|
spvOptions.disableOptimizer = (Options & EOptionOptimizeDisable) != 0;
|
|
|
|
spvOptions.optimizeSize = (Options & EOptionOptimizeSize) != 0;
|
2018-08-23 21:17:10 +00:00
|
|
|
spvOptions.disassemble = SpvToolsDisassembler;
|
2018-08-23 21:29:08 +00:00
|
|
|
spvOptions.validate = SpvToolsValidate;
|
2017-05-31 23:11:16 +00:00
|
|
|
glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv, &logger, &spvOptions);
|
2016-01-16 22:30:03 +00:00
|
|
|
|
|
|
|
// Dump the spv to a file or stdout, etc., but only if not doing
|
|
|
|
// memory/perf testing, as it's not internal to programmatic use.
|
|
|
|
if (! (Options & EOptionMemoryLeakMode)) {
|
2016-05-27 17:55:53 +00:00
|
|
|
printf("%s", logger.getAllMessages().c_str());
|
|
|
|
if (Options & EOptionOutputHexadecimal) {
|
2017-02-18 16:45:40 +00:00
|
|
|
glslang::OutputSpvHex(spirv, GetBinaryName((EShLanguage)stage), variableName);
|
2016-05-27 17:55:53 +00:00
|
|
|
} else {
|
|
|
|
glslang::OutputSpvBin(spirv, GetBinaryName((EShLanguage)stage));
|
|
|
|
}
|
2019-07-28 08:12:10 +00:00
|
|
|
#ifndef GLSLANG_WEB
|
2018-06-12 00:12:15 +00:00
|
|
|
if (!SpvToolsDisassembler && (Options & EOptionHumanReadableSpv))
|
2016-01-16 22:30:03 +00:00
|
|
|
spv::Disassemble(std::cout, spirv);
|
2019-07-28 08:12:10 +00:00
|
|
|
#endif
|
2015-03-04 03:48:38 +00:00
|
|
|
}
|
2014-08-24 18:21:00 +00:00
|
|
|
}
|
2014-07-28 04:21:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-01 03:08:40 +00:00
|
|
|
// Free everything up, program has to go before the shaders
|
|
|
|
// because it might have merged stuff from the shaders, and
|
|
|
|
// the stuff from the shaders has to have its destructors called
|
|
|
|
// before the pools holding the memory in the shaders is freed.
|
|
|
|
delete &program;
|
2013-09-04 21:19:27 +00:00
|
|
|
while (shaders.size() > 0) {
|
|
|
|
delete shaders.back();
|
|
|
|
shaders.pop_back();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-16 22:30:03 +00:00
|
|
|
//
|
|
|
|
// Do file IO part of compile and link, handing off the pure
|
|
|
|
// API/programmatic mode to CompileAndLinkShaderUnits(), which can
|
|
|
|
// be put in a loop for testing memory footprint and performance.
|
|
|
|
//
|
|
|
|
// This is just for linking mode: meaning all the shaders will be put into the
|
|
|
|
// the same program linked together.
|
|
|
|
//
|
|
|
|
// This means there are a limited number of work items (not multi-threading mode)
|
|
|
|
// and that the point is testing at the linking level. Hence, to enable
|
|
|
|
// performance and memory testing, the actual compile/link can be put in
|
|
|
|
// a loop, independent of processing the work items and file IO.
|
|
|
|
//
|
2017-04-02 21:04:00 +00:00
|
|
|
void CompileAndLinkShaderFiles(glslang::TWorklist& Worklist)
|
2016-01-16 22:30:03 +00:00
|
|
|
{
|
|
|
|
std::vector<ShaderCompUnit> compUnits;
|
|
|
|
|
2017-09-02 17:34:54 +00:00
|
|
|
// If this is using stdin, we can't really detect multiple different file
|
|
|
|
// units by input type. We need to assume that we're just being given one
|
|
|
|
// file of a certain type.
|
|
|
|
if ((Options & EOptionStdin) != 0) {
|
|
|
|
ShaderCompUnit compUnit(FindLanguage("stdin"));
|
|
|
|
std::istreambuf_iterator<char> begin(std::cin), end;
|
|
|
|
std::string tempString(begin, end);
|
|
|
|
char* fileText = strdup(tempString.c_str());
|
|
|
|
std::string fileName = "stdin";
|
|
|
|
compUnit.addString(fileName, fileText);
|
2016-01-16 22:30:03 +00:00
|
|
|
compUnits.push_back(compUnit);
|
2017-09-02 17:34:54 +00:00
|
|
|
} else {
|
|
|
|
// Transfer all the work items from to a simple list of
|
|
|
|
// of compilation units. (We don't care about the thread
|
|
|
|
// work-item distribution properties in this path, which
|
|
|
|
// is okay due to the limited number of shaders, know since
|
|
|
|
// they are all getting linked together.)
|
|
|
|
glslang::TWorkItem* workItem;
|
|
|
|
while (Worklist.remove(workItem)) {
|
|
|
|
ShaderCompUnit compUnit(FindLanguage(workItem->name));
|
|
|
|
char* fileText = ReadFileData(workItem->name.c_str());
|
|
|
|
if (fileText == nullptr)
|
|
|
|
usage();
|
|
|
|
compUnit.addString(workItem->name, fileText);
|
|
|
|
compUnits.push_back(compUnit);
|
|
|
|
}
|
2016-01-16 22:30:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Actual call to programmatic processing of compile and link,
|
|
|
|
// in a loop for testing memory and performance. This part contains
|
|
|
|
// all the perf/memory that a programmatic consumer will care about.
|
|
|
|
for (int i = 0; i < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++i) {
|
|
|
|
for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j)
|
|
|
|
CompileAndLinkShaderUnits(compUnits);
|
|
|
|
|
|
|
|
if (Options & EOptionMemoryLeakMode)
|
|
|
|
glslang::OS_DumpMemoryCounters();
|
|
|
|
}
|
|
|
|
|
2017-06-15 16:40:49 +00:00
|
|
|
// free memory from ReadFileData, which got stored in a const char*
|
|
|
|
// as the first string above
|
2016-02-23 21:17:38 +00:00
|
|
|
for (auto it = compUnits.begin(); it != compUnits.end(); ++it)
|
2017-06-15 16:40:49 +00:00
|
|
|
FreeFileData(const_cast<char*>(it->text[0]));
|
2016-01-16 22:30:03 +00:00
|
|
|
}
|
|
|
|
|
2017-11-13 08:32:06 +00:00
|
|
|
int singleMain()
|
2013-07-31 18:44:13 +00:00
|
|
|
{
|
2017-04-02 21:04:00 +00:00
|
|
|
glslang::TWorklist workList;
|
2017-11-13 08:32:06 +00:00
|
|
|
std::for_each(WorkItems.begin(), WorkItems.end(), [&workList](std::unique_ptr<glslang::TWorkItem>& item) {
|
2017-04-02 21:04:00 +00:00
|
|
|
assert(item);
|
|
|
|
workList.add(item.get());
|
|
|
|
});
|
2013-07-31 18:44:13 +00:00
|
|
|
|
2019-07-28 08:12:10 +00:00
|
|
|
#ifndef GLSLANG_WEB
|
2013-09-17 19:26:08 +00:00
|
|
|
if (Options & EOptionDumpConfig) {
|
2016-03-04 21:22:34 +00:00
|
|
|
printf("%s", glslang::GetDefaultTBuiltInResourceString().c_str());
|
2017-04-02 21:04:00 +00:00
|
|
|
if (workList.empty())
|
2013-09-17 19:26:08 +00:00
|
|
|
return ESuccess;
|
|
|
|
}
|
2019-07-28 08:12:10 +00:00
|
|
|
#endif
|
2013-09-17 19:26:08 +00:00
|
|
|
|
2018-03-06 05:23:17 +00:00
|
|
|
if (Options & EOptionDumpBareVersion) {
|
Generate build information from CHANGES.md
This PR significantly reworks the way glslang is versioned.
Instead of committing changes to the `GLSLANG_MINOR_VERSION` define in
`glslang/Public/ShaderLang.h`, and using `make-revision` to generate
`GLSLANG_PATCH_LEVEL` in `glslang/Include/revision.h`, all version
information is now derived from the new `CHANGES.md` file.
`CHANGES.md` acts as the single source of truth for glslang version
information, along with a convenient place to put all release notes for
each notable change made.
`CHANGES.md` is parsed using the new `build_info.py` python script.
This script can read basic template files to produce new source files,
which it does to read the new `build_info.h.tmpl` to generate (at build
time) a glslang private header at
`<build-dir>/include/glslang/build_info.h`.
I've written generators for each of the CMake, Bazel, gn, and
`Android.mk` build scripts.
The new version code conforms to the Semantic Versioning 2.0 spec.
This new version is also used by the CMake rules to produce versioned
shared objects, including a major-versioned SONAME.
New APIs:
---------
* `glslang::GetVersion()` returns a `Version` struct with the version
major, minor, patch and flavor.
Breaking API changes:
---------------------
* The public defines `GLSLANG_MINOR_VERSION` and `GLSLANG_PATCH_LEVEL`
have been entirely removed.
* `glslang/Public/ShaderLang.h` and `glslang/Include/revision.h` have
been deleted.
* Instead, `<build-dir>/include/glslang/build_info.h` is created in
the build directory, and `<build-dir>/include` is a CMake `PUBLIC`
(dependee-inherited) include directory for the glslang targets.
* `<build-dir>/include/glslang/build_info.h` contains the following
new #defines:
`GLSLANG_VERSION_MAJOR`, `GLSLANG_VERSION_MINOR`,
`GLSLANG_VERSION_PATCH`, `GLSLANG_VERSION_FLAVOR`,
`GLSLANG_VERSION_GREATER_THAN(major, minor, patch)`,
`GLSLANG_VERSION_GREATER_OR_EQUAL_TO(major, minor, patch)`,
`GLSLANG_VERSION_LESS_THAN(major, minor, patch)`,
`GLSLANG_VERSION_LESS_OR_EQUAL_TO(major, minor, patch)`
* The CMake install output directory contains a copy of
`build_info.h` at: `include/glslang/build_info.h`
* Python3 is now always required to build glslang (likely always
required for transitive dependency builds).
2020-06-17 10:17:19 +00:00
|
|
|
printf("%d:%d.%d.%d%s\n", glslang::GetSpirvGeneratorVersion(), GLSLANG_VERSION_MAJOR, GLSLANG_VERSION_MINOR,
|
|
|
|
GLSLANG_VERSION_PATCH, GLSLANG_VERSION_FLAVOR);
|
2018-03-06 05:23:17 +00:00
|
|
|
if (workList.empty())
|
|
|
|
return ESuccess;
|
|
|
|
} else if (Options & EOptionDumpVersions) {
|
Generate build information from CHANGES.md
This PR significantly reworks the way glslang is versioned.
Instead of committing changes to the `GLSLANG_MINOR_VERSION` define in
`glslang/Public/ShaderLang.h`, and using `make-revision` to generate
`GLSLANG_PATCH_LEVEL` in `glslang/Include/revision.h`, all version
information is now derived from the new `CHANGES.md` file.
`CHANGES.md` acts as the single source of truth for glslang version
information, along with a convenient place to put all release notes for
each notable change made.
`CHANGES.md` is parsed using the new `build_info.py` python script.
This script can read basic template files to produce new source files,
which it does to read the new `build_info.h.tmpl` to generate (at build
time) a glslang private header at
`<build-dir>/include/glslang/build_info.h`.
I've written generators for each of the CMake, Bazel, gn, and
`Android.mk` build scripts.
The new version code conforms to the Semantic Versioning 2.0 spec.
This new version is also used by the CMake rules to produce versioned
shared objects, including a major-versioned SONAME.
New APIs:
---------
* `glslang::GetVersion()` returns a `Version` struct with the version
major, minor, patch and flavor.
Breaking API changes:
---------------------
* The public defines `GLSLANG_MINOR_VERSION` and `GLSLANG_PATCH_LEVEL`
have been entirely removed.
* `glslang/Public/ShaderLang.h` and `glslang/Include/revision.h` have
been deleted.
* Instead, `<build-dir>/include/glslang/build_info.h` is created in
the build directory, and `<build-dir>/include` is a CMake `PUBLIC`
(dependee-inherited) include directory for the glslang targets.
* `<build-dir>/include/glslang/build_info.h` contains the following
new #defines:
`GLSLANG_VERSION_MAJOR`, `GLSLANG_VERSION_MINOR`,
`GLSLANG_VERSION_PATCH`, `GLSLANG_VERSION_FLAVOR`,
`GLSLANG_VERSION_GREATER_THAN(major, minor, patch)`,
`GLSLANG_VERSION_GREATER_OR_EQUAL_TO(major, minor, patch)`,
`GLSLANG_VERSION_LESS_THAN(major, minor, patch)`,
`GLSLANG_VERSION_LESS_OR_EQUAL_TO(major, minor, patch)`
* The CMake install output directory contains a copy of
`build_info.h` at: `include/glslang/build_info.h`
* Python3 is now always required to build glslang (likely always
required for transitive dependency builds).
2020-06-17 10:17:19 +00:00
|
|
|
printf("Glslang Version: %d:%d.%d.%d%s\n", glslang::GetSpirvGeneratorVersion(), GLSLANG_VERSION_MAJOR,
|
|
|
|
GLSLANG_VERSION_MINOR, GLSLANG_VERSION_PATCH, GLSLANG_VERSION_FLAVOR);
|
2013-12-04 04:43:40 +00:00
|
|
|
printf("ESSL Version: %s\n", glslang::GetEsslVersionString());
|
|
|
|
printf("GLSL Version: %s\n", glslang::GetGlslVersionString());
|
2015-07-13 01:28:10 +00:00
|
|
|
std::string spirvVersion;
|
|
|
|
glslang::GetSpirvVersion(spirvVersion);
|
2015-08-01 23:10:02 +00:00
|
|
|
printf("SPIR-V Version %s\n", spirvVersion.c_str());
|
2015-08-07 04:53:06 +00:00
|
|
|
printf("GLSL.std.450 Version %d, Revision %d\n", GLSLstd450Version, GLSLstd450Revision);
|
2015-11-16 04:33:39 +00:00
|
|
|
printf("Khronos Tool ID %d\n", glslang::GetKhronosToolId());
|
2017-11-03 04:32:14 +00:00
|
|
|
printf("SPIR-V Generator Version %d\n", glslang::GetSpirvGeneratorVersion());
|
2016-07-20 22:03:29 +00:00
|
|
|
printf("GL_KHR_vulkan_glsl version %d\n", 100);
|
|
|
|
printf("ARB_GL_gl_spirv version %d\n", 100);
|
2017-04-02 21:04:00 +00:00
|
|
|
if (workList.empty())
|
2013-12-04 04:43:40 +00:00
|
|
|
return ESuccess;
|
|
|
|
}
|
|
|
|
|
2017-09-02 17:34:54 +00:00
|
|
|
if (workList.empty() && ((Options & EOptionStdin) == 0)) {
|
2013-09-17 19:26:08 +00:00
|
|
|
usage();
|
|
|
|
}
|
|
|
|
|
2017-09-02 17:34:54 +00:00
|
|
|
if (Options & EOptionStdin) {
|
2017-11-13 08:32:06 +00:00
|
|
|
WorkItems.push_back(std::unique_ptr<glslang::TWorkItem>{new glslang::TWorkItem("stdin")});
|
|
|
|
workList.add(WorkItems.back().get());
|
2017-09-02 17:34:54 +00:00
|
|
|
}
|
|
|
|
|
2013-09-17 19:26:08 +00:00
|
|
|
ProcessConfigFile();
|
|
|
|
|
2018-10-25 18:43:02 +00:00
|
|
|
if ((Options & EOptionReadHlsl) && !((Options & EOptionOutputPreprocessed) || (Options & EOptionSpv)))
|
2019-12-20 17:33:13 +00:00
|
|
|
Error("HLSL requires SPIR-V code generation (or preprocessing only)");
|
2018-10-25 18:43:02 +00:00
|
|
|
|
2013-09-04 21:19:27 +00:00
|
|
|
//
|
|
|
|
// Two modes:
|
2013-09-06 19:52:57 +00:00
|
|
|
// 1) linking all arguments together, single-threaded, new C++ interface
|
|
|
|
// 2) independent arguments, can be tackled by multiple asynchronous threads, for testing thread safety, using the old handle interface
|
2013-09-04 21:19:27 +00:00
|
|
|
//
|
2018-10-25 18:43:02 +00:00
|
|
|
if (Options & (EOptionLinkProgram | EOptionOutputPreprocessed)) {
|
2013-11-01 17:41:52 +00:00
|
|
|
glslang::InitializeProcess();
|
2017-11-17 05:48:41 +00:00
|
|
|
glslang::InitializeProcess(); // also test reference counting of users
|
|
|
|
glslang::InitializeProcess(); // also test reference counting of users
|
|
|
|
glslang::FinalizeProcess(); // also test reference counting of users
|
|
|
|
glslang::FinalizeProcess(); // also test reference counting of users
|
2017-04-02 21:04:00 +00:00
|
|
|
CompileAndLinkShaderFiles(workList);
|
2013-11-01 17:41:52 +00:00
|
|
|
glslang::FinalizeProcess();
|
|
|
|
} else {
|
|
|
|
ShInitialize();
|
2017-11-17 05:48:41 +00:00
|
|
|
ShInitialize(); // also test reference counting of users
|
|
|
|
ShFinalize(); // also test reference counting of users
|
2013-11-01 17:41:52 +00:00
|
|
|
|
2017-04-02 21:04:00 +00:00
|
|
|
bool printShaderNames = workList.size() > 1;
|
2013-09-06 19:52:57 +00:00
|
|
|
|
2017-11-17 05:48:41 +00:00
|
|
|
if (Options & EOptionMultiThreaded) {
|
2017-04-02 21:04:00 +00:00
|
|
|
std::array<std::thread, 16> threads;
|
2017-11-17 05:48:41 +00:00
|
|
|
for (unsigned int t = 0; t < threads.size(); ++t) {
|
2017-04-02 21:04:00 +00:00
|
|
|
threads[t] = std::thread(CompileShaders, std::ref(workList));
|
2017-11-17 05:48:41 +00:00
|
|
|
if (threads[t].get_id() == std::thread::id()) {
|
2017-11-03 04:48:15 +00:00
|
|
|
fprintf(stderr, "Failed to create thread\n");
|
2013-09-06 19:52:57 +00:00
|
|
|
return EFailThreadCreate;
|
|
|
|
}
|
2013-07-31 18:44:13 +00:00
|
|
|
}
|
2017-04-02 21:04:00 +00:00
|
|
|
|
|
|
|
std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
|
2013-11-07 23:33:24 +00:00
|
|
|
} else
|
2017-04-02 21:04:00 +00:00
|
|
|
CompileShaders(workList);
|
2013-09-06 19:52:57 +00:00
|
|
|
|
|
|
|
// Print out all the resulting infologs
|
2017-11-13 08:32:06 +00:00
|
|
|
for (size_t w = 0; w < WorkItems.size(); ++w) {
|
|
|
|
if (WorkItems[w]) {
|
|
|
|
if (printShaderNames || WorkItems[w]->results.size() > 0)
|
|
|
|
PutsIfNonEmpty(WorkItems[w]->name.c_str());
|
|
|
|
PutsIfNonEmpty(WorkItems[w]->results.c_str());
|
2013-09-06 19:52:57 +00:00
|
|
|
}
|
|
|
|
}
|
2013-11-01 17:41:52 +00:00
|
|
|
|
|
|
|
ShFinalize();
|
2012-12-12 21:15:54 +00:00
|
|
|
}
|
2013-07-31 18:44:13 +00:00
|
|
|
|
2013-11-07 23:33:24 +00:00
|
|
|
if (CompileFailed)
|
2012-12-12 21:15:54 +00:00
|
|
|
return EFailCompile;
|
2013-11-07 23:33:24 +00:00
|
|
|
if (LinkFailed)
|
2012-12-12 21:15:54 +00:00
|
|
|
return EFailLink;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-11-13 08:32:06 +00:00
|
|
|
int C_DECL main(int argc, char* argv[])
|
|
|
|
{
|
|
|
|
ProcessArguments(WorkItems, argc, argv);
|
|
|
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
// Loop over the entire init/finalize cycle to watch memory changes
|
|
|
|
const int iterations = 1;
|
|
|
|
if (iterations > 1)
|
|
|
|
glslang::OS_DumpMemoryCounters();
|
|
|
|
for (int i = 0; i < iterations; ++i) {
|
|
|
|
ret = singleMain();
|
|
|
|
if (iterations > 1)
|
|
|
|
glslang::OS_DumpMemoryCounters();
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-12-12 21:15:54 +00:00
|
|
|
//
|
|
|
|
// Deduce the language from the filename. Files must end in one of the
|
|
|
|
// following extensions:
|
|
|
|
//
|
2013-07-31 18:44:13 +00:00
|
|
|
// .vert = vertex
|
|
|
|
// .tesc = tessellation control
|
|
|
|
// .tese = tessellation evaluation
|
|
|
|
// .geom = geometry
|
|
|
|
// .frag = fragment
|
2013-08-31 02:41:30 +00:00
|
|
|
// .comp = compute
|
2018-09-19 18:42:24 +00:00
|
|
|
// .rgen = ray generation
|
|
|
|
// .rint = ray intersection
|
|
|
|
// .rahit = ray any hit
|
|
|
|
// .rchit = ray closest hit
|
|
|
|
// .rmiss = ray miss
|
|
|
|
// .rcall = ray callable
|
2018-10-04 23:39:18 +00:00
|
|
|
// .mesh = mesh
|
|
|
|
// .task = task
|
2018-04-12 21:35:24 +00:00
|
|
|
// Additionally, the file names may end in .<stage>.glsl and .<stage>.hlsl
|
|
|
|
// where <stage> is one of the stages listed above.
|
|
|
|
//
|
|
|
|
EShLanguage FindLanguage(const std::string& name, bool parseStageName)
|
2012-12-12 21:15:54 +00:00
|
|
|
{
|
2018-04-17 23:24:03 +00:00
|
|
|
std::string stageName;
|
2016-08-11 18:06:06 +00:00
|
|
|
if (shaderStageName)
|
2018-04-17 23:24:03 +00:00
|
|
|
stageName = shaderStageName;
|
|
|
|
else if (parseStageName) {
|
2018-04-12 21:35:24 +00:00
|
|
|
// Note: "first" extension means "first from the end", i.e.
|
|
|
|
// if the file is named foo.vert.glsl, then "glsl" is first,
|
|
|
|
// "vert" is second.
|
2018-04-17 23:24:03 +00:00
|
|
|
size_t firstExtStart = name.find_last_of(".");
|
|
|
|
bool hasFirstExt = firstExtStart != std::string::npos;
|
|
|
|
size_t secondExtStart = hasFirstExt ? name.find_last_of(".", firstExtStart - 1) : std::string::npos;
|
|
|
|
bool hasSecondExt = secondExtStart != std::string::npos;
|
|
|
|
std::string firstExt = name.substr(firstExtStart + 1, std::string::npos);
|
|
|
|
bool usesUnifiedExt = hasFirstExt && (firstExt == "glsl" || firstExt == "hlsl");
|
2018-04-18 03:02:19 +00:00
|
|
|
if (usesUnifiedExt && firstExt == "hlsl")
|
|
|
|
Options |= EOptionReadHlsl;
|
|
|
|
if (hasFirstExt && !usesUnifiedExt)
|
2018-04-17 23:24:03 +00:00
|
|
|
stageName = firstExt;
|
2018-04-18 03:02:19 +00:00
|
|
|
else if (usesUnifiedExt && hasSecondExt)
|
2018-04-17 23:24:03 +00:00
|
|
|
stageName = name.substr(secondExtStart + 1, firstExtStart - secondExtStart - 1);
|
2018-04-18 03:02:19 +00:00
|
|
|
else {
|
2018-04-12 21:35:24 +00:00
|
|
|
usage();
|
|
|
|
return EShLangVertex;
|
2017-03-16 17:20:38 +00:00
|
|
|
}
|
2018-04-17 23:24:03 +00:00
|
|
|
} else
|
|
|
|
stageName = name;
|
2016-08-09 01:43:07 +00:00
|
|
|
|
2018-04-17 23:24:03 +00:00
|
|
|
if (stageName == "vert")
|
2013-07-31 18:44:13 +00:00
|
|
|
return EShLangVertex;
|
2018-04-17 23:24:03 +00:00
|
|
|
else if (stageName == "tesc")
|
2013-07-31 18:44:13 +00:00
|
|
|
return EShLangTessControl;
|
2018-04-17 23:24:03 +00:00
|
|
|
else if (stageName == "tese")
|
2013-07-31 18:44:13 +00:00
|
|
|
return EShLangTessEvaluation;
|
2018-04-17 23:24:03 +00:00
|
|
|
else if (stageName == "geom")
|
2013-07-31 18:44:13 +00:00
|
|
|
return EShLangGeometry;
|
2018-04-17 23:24:03 +00:00
|
|
|
else if (stageName == "frag")
|
2013-07-31 18:44:13 +00:00
|
|
|
return EShLangFragment;
|
2018-04-17 23:24:03 +00:00
|
|
|
else if (stageName == "comp")
|
Put in infrastructure for tessellation, geometry, and compute stages, and partially flesh out with built-in functions.
Added the built-in functions EmitVertex(), EndPrimitive(), barrier(), memoryBarrier(), memoryBarrierAtomicCounter(), memoryBarrierBuffer(), memoryBarrierImage(), memoryBarrierShared(), and groupMemoryBarrier().
Have not added any new built-in variables.
Also changed the linear performance relateToOperator() to a high-performance version.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22659 e7fa87d3-cd2b-0410-9028-fcbf551c1848
2013-08-09 17:14:49 +00:00
|
|
|
return EShLangCompute;
|
2018-09-19 18:42:24 +00:00
|
|
|
else if (stageName == "rgen")
|
2020-03-18 00:42:47 +00:00
|
|
|
return EShLangRayGen;
|
2018-09-19 18:42:24 +00:00
|
|
|
else if (stageName == "rint")
|
2020-03-18 00:42:47 +00:00
|
|
|
return EShLangIntersect;
|
2018-09-19 18:42:24 +00:00
|
|
|
else if (stageName == "rahit")
|
2020-03-18 00:42:47 +00:00
|
|
|
return EShLangAnyHit;
|
2018-09-19 18:42:24 +00:00
|
|
|
else if (stageName == "rchit")
|
2020-03-18 00:42:47 +00:00
|
|
|
return EShLangClosestHit;
|
2018-09-19 18:42:24 +00:00
|
|
|
else if (stageName == "rmiss")
|
2020-03-18 00:42:47 +00:00
|
|
|
return EShLangMiss;
|
2018-09-19 18:42:24 +00:00
|
|
|
else if (stageName == "rcall")
|
2020-03-18 00:42:47 +00:00
|
|
|
return EShLangCallable;
|
2018-09-19 18:41:59 +00:00
|
|
|
else if (stageName == "mesh")
|
|
|
|
return EShLangMeshNV;
|
|
|
|
else if (stageName == "task")
|
|
|
|
return EShLangTaskNV;
|
2013-07-31 18:44:13 +00:00
|
|
|
|
|
|
|
usage();
|
2012-12-12 21:34:14 +00:00
|
|
|
return EShLangVertex;
|
2012-12-12 21:15:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2017-01-06 07:34:48 +00:00
|
|
|
// Read a file's data into a string, and compile it using the old interface ShCompile,
|
2013-09-04 21:19:27 +00:00
|
|
|
// for non-linkable results.
|
2012-12-12 21:15:54 +00:00
|
|
|
//
|
2014-02-18 23:37:57 +00:00
|
|
|
void CompileFile(const char* fileName, ShHandle compiler)
|
2012-12-12 21:15:54 +00:00
|
|
|
{
|
2015-05-18 01:59:45 +00:00
|
|
|
int ret = 0;
|
2017-09-02 17:34:54 +00:00
|
|
|
char* shaderString;
|
|
|
|
if ((Options & EOptionStdin) != 0) {
|
|
|
|
std::istreambuf_iterator<char> begin(std::cin), end;
|
|
|
|
std::string tempString(begin, end);
|
|
|
|
shaderString = strdup(tempString.c_str());
|
|
|
|
} else {
|
|
|
|
shaderString = ReadFileData(fileName);
|
|
|
|
}
|
2013-06-25 18:10:05 +00:00
|
|
|
|
|
|
|
// move to length-based strings, rather than null-terminated strings
|
2017-06-14 23:36:50 +00:00
|
|
|
int* lengths = new int[1];
|
|
|
|
lengths[0] = (int)strlen(shaderString);
|
2012-12-12 21:15:54 +00:00
|
|
|
|
2013-05-05 23:46:22 +00:00
|
|
|
EShMessages messages = EShMsgDefault;
|
2013-11-07 17:44:20 +00:00
|
|
|
SetMessageOptions(messages);
|
2017-01-06 07:34:48 +00:00
|
|
|
|
2017-06-15 16:40:49 +00:00
|
|
|
if (UserPreamble.isSet())
|
|
|
|
Error("-D and -U options require -l (linking)\n");
|
|
|
|
|
2013-08-31 02:41:30 +00:00
|
|
|
for (int i = 0; i < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++i) {
|
|
|
|
for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j) {
|
2017-01-06 19:34:14 +00:00
|
|
|
// ret = ShCompile(compiler, shaderStrings, NumShaderStrings, lengths, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
|
2017-06-14 23:36:50 +00:00
|
|
|
ret = ShCompile(compiler, &shaderString, 1, nullptr, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
|
2017-01-06 19:34:14 +00:00
|
|
|
// const char* multi[12] = { "# ve", "rsion", " 300 e", "s", "\n#err",
|
2017-01-06 07:34:48 +00:00
|
|
|
// "or should be l", "ine 1", "string 5\n", "float glo", "bal",
|
2013-10-28 18:12:06 +00:00
|
|
|
// ";\n#error should be line 2\n void main() {", "global = 2.3;}" };
|
2017-01-06 19:34:14 +00:00
|
|
|
// const char* multi[7] = { "/", "/", "\\", "\n", "\n", "#", "version 300 es" };
|
|
|
|
// ret = ShCompile(compiler, multi, 7, nullptr, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
|
2013-06-25 18:10:05 +00:00
|
|
|
}
|
2012-12-12 21:15:54 +00:00
|
|
|
|
2013-08-31 02:41:30 +00:00
|
|
|
if (Options & EOptionMemoryLeakMode)
|
2013-07-31 18:44:13 +00:00
|
|
|
glslang::OS_DumpMemoryCounters();
|
2012-12-12 21:15:54 +00:00
|
|
|
}
|
|
|
|
|
2013-06-25 18:10:05 +00:00
|
|
|
delete [] lengths;
|
2017-06-14 23:36:50 +00:00
|
|
|
FreeFileData(shaderString);
|
2012-12-12 21:15:54 +00:00
|
|
|
|
2013-11-07 23:33:24 +00:00
|
|
|
if (ret == 0)
|
|
|
|
CompileFailed = true;
|
2012-12-12 21:15:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// print usage to stdout
|
|
|
|
//
|
|
|
|
void usage()
|
|
|
|
{
|
2013-12-04 04:43:40 +00:00
|
|
|
printf("Usage: glslangValidator [option]... [file]...\n"
|
|
|
|
"\n"
|
2017-06-14 21:52:44 +00:00
|
|
|
"'file' can end in .<stage> for auto-stage classification, where <stage> is:\n"
|
|
|
|
" .conf to provide a config file that replaces the default configuration\n"
|
2015-07-13 01:28:10 +00:00
|
|
|
" (see -c option below for generating a template)\n"
|
|
|
|
" .vert for a vertex shader\n"
|
|
|
|
" .tesc for a tessellation control shader\n"
|
|
|
|
" .tese for a tessellation evaluation shader\n"
|
|
|
|
" .geom for a geometry shader\n"
|
|
|
|
" .frag for a fragment shader\n"
|
|
|
|
" .comp for a compute shader\n"
|
2018-09-19 18:41:59 +00:00
|
|
|
" .mesh for a mesh shader\n"
|
|
|
|
" .task for a task shader\n"
|
2018-09-19 18:42:24 +00:00
|
|
|
" .rgen for a ray generation shader\n"
|
|
|
|
" .rint for a ray intersection shader\n"
|
|
|
|
" .rahit for a ray any hit shader\n"
|
|
|
|
" .rchit for a ray closest hit shader\n"
|
|
|
|
" .rmiss for a ray miss shader\n"
|
2018-10-04 23:39:18 +00:00
|
|
|
" .rcall for a ray callable shader\n"
|
2018-04-17 23:44:11 +00:00
|
|
|
" .glsl for .vert.glsl, .tesc.glsl, ..., .comp.glsl compound suffixes\n"
|
|
|
|
" .hlsl for .vert.hlsl, .tesc.hlsl, ..., .comp.hlsl compound suffixes\n"
|
2013-12-04 04:43:40 +00:00
|
|
|
"\n"
|
2017-06-14 21:52:44 +00:00
|
|
|
"Options:\n"
|
|
|
|
" -C cascading errors; risk crash from accumulation of error recoveries\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" -D input is HLSL (this is the default when any suffix is .hlsl)\n"
|
2020-01-07 14:03:11 +00:00
|
|
|
" -D<name[=def]> | --define-macro <name[=def]> | --D <name[=def]>\n"
|
|
|
|
" define a pre-processor macro\n"
|
2017-06-14 21:52:44 +00:00
|
|
|
" -E print pre-processed GLSL; cannot be used with -l;\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" errors will appear on stderr\n"
|
2017-06-23 17:11:09 +00:00
|
|
|
" -G[ver] create SPIR-V binary, under OpenGL semantics; turns on -l;\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" default file name is <stage>.spv (-o overrides this);\n"
|
2017-06-23 17:11:09 +00:00
|
|
|
" 'ver', when present, is the version of the input semantics,\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" which will appear in #define GL_SPIRV ver;\n"
|
|
|
|
" '--client opengl100' is the same as -G100;\n"
|
2021-01-05 22:54:41 +00:00
|
|
|
" a '--target-env' for OpenGL will also imply '-G';\n"
|
|
|
|
" currently only supports GLSL\n"
|
2015-07-13 01:28:10 +00:00
|
|
|
" -H print human readable form of SPIR-V; turns on -V\n"
|
2017-06-07 21:06:58 +00:00
|
|
|
" -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"
|
2018-08-13 03:24:55 +00:00
|
|
|
" -Od disables optimization; may cause illegal SPIR-V for HLSL\n"
|
|
|
|
" -Os optimizes SPIR-V to minimize size\n"
|
2021-03-15 17:26:11 +00:00
|
|
|
" -R use relaxed verification rules for generating Vulkan SPIR-V,\n"
|
|
|
|
" allowing the use of default uniforms, atomic_uints, and\n"
|
|
|
|
" gl_VertexID and gl_InstanceID keywords.\n"
|
2017-03-16 17:20:38 +00:00
|
|
|
" -S <stage> uses specified stage rather than parsing the file extension\n"
|
2017-06-14 21:52:44 +00:00
|
|
|
" choices for <stage> are vert, tesc, tese, geom, frag, or comp\n"
|
2020-01-07 14:03:11 +00:00
|
|
|
" -U<name> | --undef-macro <name> | --U <name>\n"
|
|
|
|
" undefine a pre-processor macro\n"
|
2017-06-23 17:11:09 +00:00
|
|
|
" -V[ver] create SPIR-V binary, under Vulkan semantics; turns on -l;\n"
|
2017-06-14 21:52:44 +00:00
|
|
|
" default file name is <stage>.spv (-o overrides this)\n"
|
2017-06-23 17:11:09 +00:00
|
|
|
" '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"
|
2015-07-13 01:28:10 +00:00
|
|
|
" -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"
|
|
|
|
" (default is ES version 100)\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" -e <name> | --entry-point <name>\n"
|
|
|
|
" specify <name> as the entry-point function name\n"
|
2018-03-08 01:05:55 +00:00
|
|
|
" -f{hlsl_functionality1}\n"
|
|
|
|
" 'hlsl_functionality1' enables use of the\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" SPV_GOOGLE_hlsl_functionality1 extension\n"
|
2017-05-31 23:11:16 +00:00
|
|
|
" -g generate debug information\n"
|
2020-06-17 16:47:44 +00:00
|
|
|
" -g0 strip debug information\n"
|
2015-07-13 01:28:10 +00:00
|
|
|
" -h print this usage message\n"
|
|
|
|
" -i intermediate tree (glslang AST) is printed out\n"
|
|
|
|
" -l link all input files together to form a single module\n"
|
|
|
|
" -m memory leak mode\n"
|
2017-09-12 02:13:49 +00:00
|
|
|
" -o <file> save binary to <file>, requires a binary option (e.g., -V)\n"
|
2019-07-02 15:32:48 +00:00
|
|
|
" -q dump reflection query database; requires -l for linking\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" -r | --relaxed-errors"
|
|
|
|
" relaxed GLSL semantic error-checking mode\n"
|
2017-11-17 05:32:20 +00:00
|
|
|
" -s silence syntax and semantic error reporting\n"
|
2015-07-13 01:28:10 +00:00
|
|
|
" -t multi-threaded mode\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" -v | --version\n"
|
|
|
|
" print version strings\n"
|
|
|
|
" -w | --suppress-warnings\n"
|
|
|
|
" suppress GLSL warnings, except as required by \"#extension : warn\"\n"
|
2017-06-14 21:52:44 +00:00
|
|
|
" -x save binary output as text-based 32-bit hexadecimal numbers\n"
|
2018-03-20 16:30:53 +00:00
|
|
|
" -u<name>:<loc> specify a uniform location override for --aml\n"
|
2018-03-20 16:41:05 +00:00
|
|
|
" --uniform-base <base> set a base to use for generated uniform locations\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" --auto-map-bindings | --amb automatically bind uniform variables\n"
|
|
|
|
" without explicit bindings\n"
|
|
|
|
" --auto-map-locations | --aml automatically locate input/output lacking\n"
|
|
|
|
" 'location' (fragile, not cross stage)\n"
|
|
|
|
" --client {vulkan<ver>|opengl<ver>} see -V and -G\n"
|
2019-04-13 20:57:33 +00:00
|
|
|
" --dump-builtin-symbols prints builtin symbol table prior each compile\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" -dumpfullversion | -dumpversion print bare major.minor.patchlevel\n"
|
|
|
|
" --flatten-uniform-arrays | --fua flatten uniform texture/sampler arrays to\n"
|
|
|
|
" scalars\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"
|
|
|
|
" --hlsl-enable-16bit-types allow 16-bit types in SPIR-V for HLSL\n"
|
2019-06-18 05:33:09 +00:00
|
|
|
" --hlsl-dx9-compatible interprets sampler declarations as a\n"
|
2020-06-02 06:30:50 +00:00
|
|
|
" texture/sampler combo like DirectX9 would,\n"
|
|
|
|
" and recognizes DirectX9-specific semantics\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" --invert-y | --iy invert position.Y output in vertex shader\n"
|
|
|
|
" --keep-uncalled | --ku don't eliminate uncalled functions\n"
|
2019-06-18 05:33:09 +00:00
|
|
|
" --nan-clamp favor non-NaN operand in min, max, and clamp\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" --no-storage-format | --nsf use Unknown image format\n"
|
2020-07-03 12:55:29 +00:00
|
|
|
" --quiet do not print anything to stdout, unless\n"
|
|
|
|
" requested by another option\n"
|
2019-02-08 10:48:48 +00:00
|
|
|
" --reflect-strict-array-suffix use strict array suffix rules when\n"
|
|
|
|
" reflecting\n"
|
2019-01-29 15:49:00 +00:00
|
|
|
" --reflect-basic-array-suffix arrays of basic types will have trailing [0]\n"
|
2019-02-08 10:48:48 +00:00
|
|
|
" --reflect-intermediate-io reflection includes inputs/outputs of linked\n"
|
|
|
|
" shaders rather than just vertex/fragment\n"
|
|
|
|
" --reflect-separate-buffers reflect buffer variables and blocks\n"
|
|
|
|
" separately to uniforms\n"
|
|
|
|
" --reflect-all-block-variables reflect all variables in blocks, whether\n"
|
|
|
|
" inactive or active\n"
|
2019-02-11 11:50:24 +00:00
|
|
|
" --reflect-unwrap-io-blocks unwrap input/output blocks the same as\n"
|
|
|
|
" uniform blocks\n"
|
2017-07-14 21:15:47 +00:00
|
|
|
" --resource-set-binding [stage] name set binding\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" set descriptor set and binding for\n"
|
|
|
|
" individual resources\n"
|
2017-07-14 21:15:47 +00:00
|
|
|
" --resource-set-binding [stage] set\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" set descriptor set for all resources\n"
|
|
|
|
" --rsb synonym for --resource-set-binding\n"
|
2021-03-15 17:26:11 +00:00
|
|
|
" --set-block-backing name {uniform|buffer|push_constant}\n"
|
|
|
|
" changes the backing type of a uniform, buffer,\n"
|
|
|
|
" or push_constant block declared in\n"
|
|
|
|
" in the program, when using -R option.\n"
|
|
|
|
" This can be used to change the backing\n"
|
|
|
|
" for existing blocks as well as implicit ones\n"
|
|
|
|
" such as 'gl_DefaultUniformBlock'.\n"
|
|
|
|
" --sbs synonym for set-block-storage\n"
|
|
|
|
" --set-atomic-counter-block name set\n"
|
|
|
|
" set name, and descriptor set for\n"
|
|
|
|
" atomic counter blocks, with -R opt\n"
|
|
|
|
" --sacb synonym for set-atomic-counter-block\n"
|
|
|
|
" --set-default-uniform-block name set binding\n"
|
|
|
|
" set name, descriptor set, and binding for\n"
|
|
|
|
" global default-uniform-block, with -R opt\n"
|
|
|
|
" --sdub synonym for set-default-uniform-block\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" --shift-image-binding [stage] num\n"
|
|
|
|
" base binding number for images (uav)\n"
|
|
|
|
" --shift-image-binding [stage] [num set]...\n"
|
|
|
|
" per-descriptor-set shift values\n"
|
|
|
|
" --sib synonym for --shift-image-binding\n"
|
|
|
|
" --shift-sampler-binding [stage] num\n"
|
|
|
|
" base binding number for samplers\n"
|
|
|
|
" --shift-sampler-binding [stage] [num set]...\n"
|
|
|
|
" per-descriptor-set shift values\n"
|
|
|
|
" --ssb synonym for --shift-sampler-binding\n"
|
|
|
|
" --shift-ssbo-binding [stage] num base binding number for SSBOs\n"
|
|
|
|
" --shift-ssbo-binding [stage] [num set]...\n"
|
|
|
|
" per-descriptor-set shift values\n"
|
|
|
|
" --sbb synonym for --shift-ssbo-binding\n"
|
|
|
|
" --shift-texture-binding [stage] num\n"
|
|
|
|
" base binding number for textures\n"
|
|
|
|
" --shift-texture-binding [stage] [num set]...\n"
|
|
|
|
" per-descriptor-set shift values\n"
|
|
|
|
" --stb synonym for --shift-texture-binding\n"
|
|
|
|
" --shift-uav-binding [stage] num base binding number for UAVs\n"
|
|
|
|
" --shift-uav-binding [stage] [num set]...\n"
|
|
|
|
" per-descriptor-set shift values\n"
|
|
|
|
" --suavb synonym for --shift-uav-binding\n"
|
|
|
|
" --shift-UBO-binding [stage] num base binding number for UBOs\n"
|
|
|
|
" --shift-UBO-binding [stage] [num set]...\n"
|
|
|
|
" per-descriptor-set shift values\n"
|
|
|
|
" --sub synonym for --shift-UBO-binding\n"
|
|
|
|
" --shift-cbuffer-binding | --scb synonyms for --shift-UBO-binding\n"
|
|
|
|
" --spirv-dis output standard-form disassembly; works only\n"
|
|
|
|
" when a SPIR-V generation option is also used\n"
|
2018-08-23 21:29:08 +00:00
|
|
|
" --spirv-val execute the SPIRV-Tools validator\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" --source-entrypoint <name> the given shader source function is\n"
|
|
|
|
" renamed to be the <name> given in -e\n"
|
|
|
|
" --sep synonym for --source-entrypoint\n"
|
|
|
|
" --stdin read from stdin instead of from a file;\n"
|
|
|
|
" requires providing the shader stage using -S\n"
|
2020-01-15 07:10:41 +00:00
|
|
|
" --target-env {vulkan1.0 | vulkan1.1 | vulkan1.2 | opengl | \n"
|
2019-08-19 05:58:08 +00:00
|
|
|
" spirv1.0 | spirv1.1 | spirv1.2 | spirv1.3 | spirv1.4 | spirv1.5}\n"
|
2020-01-15 07:10:41 +00:00
|
|
|
" Set the execution environment that the\n"
|
|
|
|
" generated code will be executed in.\n"
|
|
|
|
" Defaults to:\n"
|
|
|
|
" * vulkan1.0 under --client vulkan<ver>\n"
|
|
|
|
" * opengl under --client opengl<ver>\n"
|
|
|
|
" * spirv1.0 under --target-env vulkan1.0\n"
|
|
|
|
" * spirv1.3 under --target-env vulkan1.1\n"
|
|
|
|
" * spirv1.5 under --target-env vulkan1.2\n"
|
|
|
|
" Multiple --target-env can be specified.\n"
|
2018-08-13 03:24:55 +00:00
|
|
|
" --variable-name <name>\n"
|
|
|
|
" --vn <name> creates a C header file that contains a\n"
|
|
|
|
" uint32_t array named <name>\n"
|
|
|
|
" initialized with the shader binary code\n"
|
2013-11-07 17:44:20 +00:00
|
|
|
);
|
2015-07-13 01:28:10 +00:00
|
|
|
|
|
|
|
exit(EFailUsage);
|
2012-12-12 21:15:54 +00:00
|
|
|
}
|
|
|
|
|
2014-10-06 19:57:34 +00:00
|
|
|
#if !defined _MSC_VER && !defined MINGW_HAS_SECURE_API
|
2013-03-08 23:14:42 +00:00
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
int fopen_s(
|
|
|
|
FILE** pFile,
|
2014-02-18 23:37:57 +00:00
|
|
|
const char* filename,
|
|
|
|
const char* mode
|
2013-03-08 23:14:42 +00:00
|
|
|
)
|
|
|
|
{
|
|
|
|
if (!pFile || !filename || !mode) {
|
|
|
|
return EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
FILE* f = fopen(filename, mode);
|
|
|
|
if (! f) {
|
|
|
|
if (errno != 0) {
|
|
|
|
return errno;
|
|
|
|
} else {
|
|
|
|
return ENOENT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*pFile = f;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2012-12-12 21:15:54 +00:00
|
|
|
//
|
|
|
|
// Malloc a string of sufficient size and read a string into it.
|
|
|
|
//
|
2017-06-14 23:36:50 +00:00
|
|
|
char* ReadFileData(const char* fileName)
|
2012-12-12 21:15:54 +00:00
|
|
|
{
|
2015-07-12 00:01:03 +00:00
|
|
|
FILE *in = nullptr;
|
2014-10-06 19:57:34 +00:00
|
|
|
int errorCode = fopen_s(&in, fileName, "r");
|
2015-07-13 01:28:10 +00:00
|
|
|
if (errorCode || in == nullptr)
|
|
|
|
Error("unable to open input file");
|
2017-01-06 07:34:48 +00:00
|
|
|
|
2017-06-14 23:36:50 +00:00
|
|
|
int count = 0;
|
2012-12-12 21:15:54 +00:00
|
|
|
while (fgetc(in) != EOF)
|
|
|
|
count++;
|
|
|
|
|
2014-08-18 19:42:35 +00:00
|
|
|
fseek(in, 0, SEEK_SET);
|
2015-05-18 01:59:45 +00:00
|
|
|
|
2017-06-14 23:36:50 +00:00
|
|
|
char* return_data = (char*)malloc(count + 1); // freed in FreeFileData()
|
|
|
|
if ((int)fread(return_data, 1, count, in) != count) {
|
|
|
|
free(return_data);
|
2015-07-13 01:28:10 +00:00
|
|
|
Error("can't read input file");
|
2012-12-12 21:15:54 +00:00
|
|
|
}
|
2015-07-13 01:28:10 +00:00
|
|
|
|
2017-06-14 23:36:50 +00:00
|
|
|
return_data[count] = '\0';
|
2012-12-12 21:15:54 +00:00
|
|
|
fclose(in);
|
2015-07-12 00:01:03 +00:00
|
|
|
|
2012-12-12 21:15:54 +00:00
|
|
|
return return_data;
|
|
|
|
}
|
|
|
|
|
2017-06-14 23:36:50 +00:00
|
|
|
void FreeFileData(char* data)
|
2012-12-12 21:15:54 +00:00
|
|
|
{
|
2015-07-12 00:01:03 +00:00
|
|
|
free(data);
|
2012-12-12 21:15:54 +00:00
|
|
|
}
|
|
|
|
|
2013-02-11 22:36:01 +00:00
|
|
|
void InfoLogMsg(const char* msg, const char* name, const int num)
|
2012-12-12 21:15:54 +00:00
|
|
|
{
|
2015-06-10 23:23:12 +00:00
|
|
|
if (num >= 0 )
|
|
|
|
printf("#### %s %s %d INFO LOG ####\n", msg, name, num);
|
|
|
|
else
|
|
|
|
printf("#### %s %s INFO LOG ####\n", msg, name);
|
2012-12-12 21:15:54 +00:00
|
|
|
}
|