зеркало из https://github.com/stride3d/xkslang.git
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).
This commit is contained in:
Родитель
7d67c6cbc2
Коммит
08a14422c1
|
@ -55,6 +55,7 @@
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
@ -157,12 +158,11 @@ int OpenGLClientVersion = 450; // doesn't influence anything yet, but
|
||||||
unsigned int TargetVersion = 0x00001000; // maps to, say, SPIR-V 1.0
|
unsigned int TargetVersion = 0x00001000; // maps to, say, SPIR-V 1.0
|
||||||
std::vector<std::string> Processes; // what should be recorded by OpModuleProcessed, or equivalent
|
std::vector<std::string> Processes; // what should be recorded by OpModuleProcessed, or equivalent
|
||||||
|
|
||||||
std::array<unsigned int, EShLangCount> baseSamplerBinding;
|
// Per descriptor-set binding base data
|
||||||
std::array<unsigned int, EShLangCount> baseTextureBinding;
|
typedef std::map<unsigned int, unsigned int> TPerSetBaseBinding;
|
||||||
std::array<unsigned int, EShLangCount> baseImageBinding;
|
|
||||||
std::array<unsigned int, EShLangCount> baseUboBinding;
|
std::array<std::array<unsigned int, EShLangCount>, glslang::EResCount> baseBinding;
|
||||||
std::array<unsigned int, EShLangCount> baseSsboBinding;
|
std::array<std::array<TPerSetBaseBinding, EShLangCount>, glslang::EResCount> baseBindingForSet;
|
||||||
std::array<unsigned int, EShLangCount> baseUavBinding;
|
|
||||||
std::array<std::vector<std::string>, EShLangCount> baseResourceSetBinding;
|
std::array<std::vector<std::string>, EShLangCount> baseResourceSetBinding;
|
||||||
|
|
||||||
// Add things like "#define ..." to a preamble to use in the beginning of the shader.
|
// Add things like "#define ..." to a preamble to use in the beginning of the shader.
|
||||||
|
@ -266,31 +266,54 @@ void Error(const char* message)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Process an optional binding base of the form:
|
// Process an optional binding base of one the forms:
|
||||||
// --argname [stage] base
|
// --argname [stage] base // base for stage (if given) or all stages (if not)
|
||||||
|
// --argname [stage] [set base]... // set/base pairs: set the base for given binding set.
|
||||||
|
|
||||||
// Where stage is one of the forms accepted by FindLanguage, and base is an integer
|
// Where stage is one of the forms accepted by FindLanguage, and base is an integer
|
||||||
//
|
//
|
||||||
void ProcessBindingBase(int& argc, char**& argv, std::array<unsigned int, EShLangCount>& base)
|
void ProcessBindingBase(int& argc, char**& argv, glslang::TResourceType res)
|
||||||
{
|
{
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
if (!isdigit(argv[1][0])) {
|
EShLanguage lang = EShLangCount;
|
||||||
|
int singleBase = 0;
|
||||||
|
TPerSetBaseBinding perSetBase;
|
||||||
|
int arg = 1;
|
||||||
|
|
||||||
|
// Parse stage, if given
|
||||||
|
if (!isdigit(argv[arg][0])) {
|
||||||
if (argc < 3) // this form needs one more argument
|
if (argc < 3) // this form needs one more argument
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
// Parse form: --argname stage base
|
lang = FindLanguage(argv[arg++], false);
|
||||||
const EShLanguage lang = FindLanguage(argv[1], false);
|
}
|
||||||
base[lang] = atoi(argv[2]);
|
|
||||||
argc-= 2;
|
|
||||||
argv+= 2;
|
|
||||||
} else {
|
|
||||||
// Parse form: --argname base
|
|
||||||
for (int lang=0; lang<EShLangCount; ++lang)
|
|
||||||
base[lang] = atoi(argv[1]);
|
|
||||||
|
|
||||||
argc--;
|
if ((argc - arg) > 2 && isdigit(argv[arg+0][0]) && isdigit(argv[arg+1][0])) {
|
||||||
argv++;
|
// Parse a per-set binding base
|
||||||
|
while ((argc - arg) > 2 && isdigit(argv[arg+0][0]) && isdigit(argv[arg+1][0])) {
|
||||||
|
const int setNum = atoi(argv[arg++]);
|
||||||
|
const int baseNum = atoi(argv[arg++]);
|
||||||
|
perSetBase[setNum] = baseNum;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Parse single binding base
|
||||||
|
singleBase = atoi(argv[arg++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
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())
|
||||||
|
baseBindingForSet[res][lang] = perSetBase;
|
||||||
|
else
|
||||||
|
baseBinding[res][lang] = singleBase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,12 +362,8 @@ void ProcessResourceSetBindingBase(int& argc, char**& argv, std::array<std::vect
|
||||||
//
|
//
|
||||||
void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItems, int argc, char* argv[])
|
void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItems, int argc, char* argv[])
|
||||||
{
|
{
|
||||||
baseSamplerBinding.fill(0);
|
for (int res = 0; res < glslang::EResCount; ++res)
|
||||||
baseTextureBinding.fill(0);
|
baseBinding[res].fill(0);
|
||||||
baseImageBinding.fill(0);
|
|
||||||
baseUboBinding.fill(0);
|
|
||||||
baseSsboBinding.fill(0);
|
|
||||||
baseUavBinding.fill(0);
|
|
||||||
|
|
||||||
ExecutableName = argv[0];
|
ExecutableName = argv[0];
|
||||||
workItems.reserve(argc);
|
workItems.reserve(argc);
|
||||||
|
@ -441,30 +460,30 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
||||||
} else if (lowerword == "shift-image-bindings" || // synonyms
|
} else if (lowerword == "shift-image-bindings" || // synonyms
|
||||||
lowerword == "shift-image-binding" ||
|
lowerword == "shift-image-binding" ||
|
||||||
lowerword == "sib") {
|
lowerword == "sib") {
|
||||||
ProcessBindingBase(argc, argv, baseImageBinding);
|
ProcessBindingBase(argc, argv, glslang::EResImage);
|
||||||
} else if (lowerword == "shift-sampler-bindings" || // synonyms
|
} else if (lowerword == "shift-sampler-bindings" || // synonyms
|
||||||
lowerword == "shift-sampler-binding" ||
|
lowerword == "shift-sampler-binding" ||
|
||||||
lowerword == "ssb") {
|
lowerword == "ssb") {
|
||||||
ProcessBindingBase(argc, argv, baseSamplerBinding);
|
ProcessBindingBase(argc, argv, glslang::EResSampler);
|
||||||
} else if (lowerword == "shift-uav-bindings" || // synonyms
|
} else if (lowerword == "shift-uav-bindings" || // synonyms
|
||||||
lowerword == "shift-uav-binding" ||
|
lowerword == "shift-uav-binding" ||
|
||||||
lowerword == "suavb") {
|
lowerword == "suavb") {
|
||||||
ProcessBindingBase(argc, argv, baseUavBinding);
|
ProcessBindingBase(argc, argv, glslang::EResUav);
|
||||||
} else if (lowerword == "shift-texture-bindings" || // synonyms
|
} else if (lowerword == "shift-texture-bindings" || // synonyms
|
||||||
lowerword == "shift-texture-binding" ||
|
lowerword == "shift-texture-binding" ||
|
||||||
lowerword == "stb") {
|
lowerword == "stb") {
|
||||||
ProcessBindingBase(argc, argv, baseTextureBinding);
|
ProcessBindingBase(argc, argv, glslang::EResTexture);
|
||||||
} else if (lowerword == "shift-ubo-bindings" || // synonyms
|
} else if (lowerword == "shift-ubo-bindings" || // synonyms
|
||||||
lowerword == "shift-ubo-binding" ||
|
lowerword == "shift-ubo-binding" ||
|
||||||
lowerword == "shift-cbuffer-bindings" ||
|
lowerword == "shift-cbuffer-bindings" ||
|
||||||
lowerword == "shift-cbuffer-binding" ||
|
lowerword == "shift-cbuffer-binding" ||
|
||||||
lowerword == "sub" ||
|
lowerword == "sub" ||
|
||||||
lowerword == "scb") {
|
lowerword == "scb") {
|
||||||
ProcessBindingBase(argc, argv, baseUboBinding);
|
ProcessBindingBase(argc, argv, glslang::EResUbo);
|
||||||
} else if (lowerword == "shift-ssbo-bindings" || // synonyms
|
} else if (lowerword == "shift-ssbo-bindings" || // synonyms
|
||||||
lowerword == "shift-ssbo-binding" ||
|
lowerword == "shift-ssbo-binding" ||
|
||||||
lowerword == "sbb") {
|
lowerword == "sbb") {
|
||||||
ProcessBindingBase(argc, argv, baseSsboBinding);
|
ProcessBindingBase(argc, argv, glslang::EResSsbo);
|
||||||
} else if (lowerword == "source-entrypoint" || // synonyms
|
} else if (lowerword == "source-entrypoint" || // synonyms
|
||||||
lowerword == "sep") {
|
lowerword == "sep") {
|
||||||
if (argc <= 1)
|
if (argc <= 1)
|
||||||
|
@ -791,12 +810,20 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
||||||
shader->setPreamble(UserPreamble.get());
|
shader->setPreamble(UserPreamble.get());
|
||||||
shader->addProcesses(Processes);
|
shader->addProcesses(Processes);
|
||||||
|
|
||||||
shader->setShiftSamplerBinding(baseSamplerBinding[compUnit.stage]);
|
// Set IO mapper binding shift values
|
||||||
shader->setShiftTextureBinding(baseTextureBinding[compUnit.stage]);
|
for (int r = 0; r < glslang::EResCount; ++r) {
|
||||||
shader->setShiftImageBinding(baseImageBinding[compUnit.stage]);
|
const glslang::TResourceType res = glslang::TResourceType(r);
|
||||||
shader->setShiftUboBinding(baseUboBinding[compUnit.stage]);
|
|
||||||
shader->setShiftSsboBinding(baseSsboBinding[compUnit.stage]);
|
// Set base bindings
|
||||||
shader->setShiftUavBinding(baseUavBinding[compUnit.stage]);
|
shader->setShiftBinding(res, baseBinding[res][compUnit.stage]);
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
shader->setShiftBindingForSet(res, i->first, i->second);
|
||||||
|
}
|
||||||
|
|
||||||
shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0);
|
shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0);
|
||||||
shader->setNoStorageFormat((Options & EOptionNoStorageFormat) != 0);
|
shader->setNoStorageFormat((Options & EOptionNoStorageFormat) != 0);
|
||||||
shader->setResourceSetBinding(baseResourceSetBinding[compUnit.stage]);
|
shader->setResourceSetBinding(baseResourceSetBinding[compUnit.stage]);
|
||||||
|
@ -1274,17 +1301,24 @@ void usage()
|
||||||
" Set descriptor set for all resources\n"
|
" Set descriptor set for all resources\n"
|
||||||
" --rsb [stage] type set binding synonym for --resource-set-binding\n"
|
" --rsb [stage] type set binding synonym for --resource-set-binding\n"
|
||||||
" --shift-image-binding [stage] num base binding number for images (uav)\n"
|
" --shift-image-binding [stage] num base binding number for images (uav)\n"
|
||||||
|
" --shift-image-binding [stage] [set num]... per-descriptor-set shift values\n"
|
||||||
" --sib [stage] num synonym for --shift-image-binding\n"
|
" --sib [stage] num synonym for --shift-image-binding\n"
|
||||||
" --shift-sampler-binding [stage] num base binding number for samplers\n"
|
" --shift-sampler-binding [stage] num base binding number for samplers\n"
|
||||||
|
" --shift-sampler-binding [stage] [set num]... per-descriptor-set shift values\n"
|
||||||
" --ssb [stage] num synonym for --shift-sampler-binding\n"
|
" --ssb [stage] num synonym for --shift-sampler-binding\n"
|
||||||
" --shift-ssbo-binding [stage] num base binding number for SSBOs\n"
|
" --shift-ssbo-binding [stage] num base binding number for SSBOs\n"
|
||||||
|
" --shift-ssbo-binding [stage] [set num]... per-descriptor-set shift values\n"
|
||||||
" --sbb [stage] num synonym for --shift-ssbo-binding\n"
|
" --sbb [stage] num synonym for --shift-ssbo-binding\n"
|
||||||
" --shift-texture-binding [stage] num base binding number for textures\n"
|
" --shift-texture-binding [stage] num base binding number for textures\n"
|
||||||
|
" --shift-texture-binding [stage] [set num]... per-descriptor-set shift values\n"
|
||||||
" --stb [stage] num synonym for --shift-texture-binding\n"
|
" --stb [stage] num synonym for --shift-texture-binding\n"
|
||||||
" --shift-uav-binding [stage] num base binding number for UAVs\n"
|
" --shift-uav-binding [stage] num base binding number for UAVs\n"
|
||||||
|
" --shift-uav-binding [stage] [set num]... per-descriptor-set shift values\n"
|
||||||
" --suavb [stage] num synonym for --shift-uav-binding\n"
|
" --suavb [stage] num synonym for --shift-uav-binding\n"
|
||||||
" --shift-UBO-binding [stage] num base binding number for UBOs\n"
|
" --shift-UBO-binding [stage] num base binding number for UBOs\n"
|
||||||
|
" --shift-UBO-binding [stage] [set num]... per-descriptor-set shift values\n"
|
||||||
" --shift-cbuffer-binding [stage] num synonym for --shift-UBO-binding\n"
|
" --shift-cbuffer-binding [stage] num synonym for --shift-UBO-binding\n"
|
||||||
|
" --shift-cbuffer-binding [stage] [set num]... per-descriptor-set shift values\n"
|
||||||
" --sub [stage] num synonym for --shift-UBO-binding\n"
|
" --sub [stage] num synonym for --shift-UBO-binding\n"
|
||||||
" --source-entrypoint <name> the given shader source function is\n"
|
" --source-entrypoint <name> the given shader source function is\n"
|
||||||
" renamed to be the <name> given in -e\n"
|
" renamed to be the <name> given in -e\n"
|
||||||
|
|
|
@ -0,0 +1,225 @@
|
||||||
|
hlsl.shift.per-set.frag
|
||||||
|
Shader version: 500
|
||||||
|
gl_FragCoord origin is upper left
|
||||||
|
0:? Sequence
|
||||||
|
0:34 Function Definition: @main( ( temp 4-component vector of float)
|
||||||
|
0:34 Function Parameters:
|
||||||
|
0:? Sequence
|
||||||
|
0:35 't1' (layout( set=1 binding=1) uniform texture1D)
|
||||||
|
0:36 't2' (layout( set=1 binding=2) uniform texture2D)
|
||||||
|
0:37 't3' (layout( set=2 binding=1) uniform texture3D)
|
||||||
|
0:38 direct index (layout( row_major std430) buffer 4-component vector of float)
|
||||||
|
0:38 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of 4-component vector of float)
|
||||||
|
0:38 't4' (layout( set=3 binding=1 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data})
|
||||||
|
0:38 Constant:
|
||||||
|
0:38 0 (const uint)
|
||||||
|
0:38 Constant:
|
||||||
|
0:38 0 (const int)
|
||||||
|
0:39 indirect index (layout( row_major std430) buffer uint)
|
||||||
|
0:39 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of uint)
|
||||||
|
0:39 't5' (layout( set=3 binding=2 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
|
||||||
|
0:39 Constant:
|
||||||
|
0:39 0 (const uint)
|
||||||
|
0:39 right-shift ( temp int)
|
||||||
|
0:39 Constant:
|
||||||
|
0:39 0 (const int)
|
||||||
|
0:39 Constant:
|
||||||
|
0:39 2 (const int)
|
||||||
|
0:40 't6' (layout( set=3 binding=3 rgba32f) uniform textureBuffer)
|
||||||
|
0:42 's1' (layout( set=1 binding=1) uniform sampler)
|
||||||
|
0:43 's2' (layout( set=2 binding=2) uniform sampler)
|
||||||
|
0:45 'u1' (layout( set=1 binding=1 rgba32f) uniform image1D)
|
||||||
|
0:46 'u2' (layout( set=2 binding=2 rgba32f) uniform image2D)
|
||||||
|
0:47 'u3' (layout( set=2 binding=3 rgba32f) uniform image3D)
|
||||||
|
0:49 imageLoad ( temp float)
|
||||||
|
0:49 'u4' (layout( set=1 binding=4 r32f) uniform imageBuffer)
|
||||||
|
0:49 Constant:
|
||||||
|
0:49 0 (const int)
|
||||||
|
0:50 indirect index (layout( row_major std430) buffer uint)
|
||||||
|
0:50 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of uint)
|
||||||
|
0:50 'u5' (layout( set=2 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
|
||||||
|
0:50 Constant:
|
||||||
|
0:50 0 (const uint)
|
||||||
|
0:50 right-shift ( temp int)
|
||||||
|
0:50 Constant:
|
||||||
|
0:50 0 (const int)
|
||||||
|
0:50 Constant:
|
||||||
|
0:50 2 (const int)
|
||||||
|
0:51 direct index (layout( row_major std430) buffer float)
|
||||||
|
0:51 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of float)
|
||||||
|
0:51 'u6' (layout( set=3 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
|
||||||
|
0:51 Constant:
|
||||||
|
0:51 0 (const uint)
|
||||||
|
0:51 Constant:
|
||||||
|
0:51 0 (const int)
|
||||||
|
0:52 'u7' (layout( set=4 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
|
||||||
|
0:53 'u8' (layout( set=5 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
|
||||||
|
0:55 cb1: direct index for structure (layout( row_major std140) uniform int)
|
||||||
|
0:55 'anon@0' (layout( set=6 binding=1 row_major std140) uniform block{layout( row_major std140) uniform int cb1})
|
||||||
|
0:55 Constant:
|
||||||
|
0:55 0 (const uint)
|
||||||
|
0:56 tb1: direct index for structure (layout( row_major std430) buffer int)
|
||||||
|
0:56 'anon@1' (layout( binding=7 row_major std430) readonly buffer block{layout( row_major std430) buffer int tb1})
|
||||||
|
0:56 Constant:
|
||||||
|
0:56 0 (const uint)
|
||||||
|
0:58 Branch: Return with expression
|
||||||
|
0:58 Constant:
|
||||||
|
0:58 0.000000
|
||||||
|
0:58 0.000000
|
||||||
|
0:58 0.000000
|
||||||
|
0:58 0.000000
|
||||||
|
0:34 Function Definition: main( ( temp void)
|
||||||
|
0:34 Function Parameters:
|
||||||
|
0:? Sequence
|
||||||
|
0:34 move second child to first child ( temp 4-component vector of float)
|
||||||
|
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||||
|
0:34 Function Call: @main( ( temp 4-component vector of float)
|
||||||
|
0:? Linker Objects
|
||||||
|
0:? 's1' (layout( set=1 binding=1) uniform sampler)
|
||||||
|
0:? 's2' (layout( set=2 binding=2) uniform sampler)
|
||||||
|
0:? 't1' (layout( set=1 binding=1) uniform texture1D)
|
||||||
|
0:? 't2' (layout( set=1 binding=2) uniform texture2D)
|
||||||
|
0:? 't3' (layout( set=2 binding=1) uniform texture3D)
|
||||||
|
0:? 't4' (layout( set=3 binding=1 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data})
|
||||||
|
0:? 't5' (layout( set=3 binding=2 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
|
||||||
|
0:? 't6' (layout( set=3 binding=3 rgba32f) uniform textureBuffer)
|
||||||
|
0:? 'u1' (layout( set=1 binding=1 rgba32f) uniform image1D)
|
||||||
|
0:? 'u2' (layout( set=2 binding=2 rgba32f) uniform image2D)
|
||||||
|
0:? 'u3' (layout( set=2 binding=3 rgba32f) uniform image3D)
|
||||||
|
0:? 'u4' (layout( set=1 binding=4 r32f) uniform imageBuffer)
|
||||||
|
0:? 'u5' (layout( set=2 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
|
||||||
|
0:? 'u6' (layout( set=3 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
|
||||||
|
0:? 'u7' (layout( set=4 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
|
||||||
|
0:? 'u8' (layout( set=5 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
|
||||||
|
0:? 'anon@0' (layout( set=6 binding=1 row_major std140) uniform block{layout( row_major std140) uniform int cb1})
|
||||||
|
0:? 'anon@1' (layout( binding=7 row_major std430) readonly buffer block{layout( row_major std430) buffer int tb1})
|
||||||
|
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||||
|
|
||||||
|
|
||||||
|
Linked fragment stage:
|
||||||
|
|
||||||
|
|
||||||
|
Shader version: 500
|
||||||
|
gl_FragCoord origin is upper left
|
||||||
|
0:? Sequence
|
||||||
|
0:34 Function Definition: @main( ( temp 4-component vector of float)
|
||||||
|
0:34 Function Parameters:
|
||||||
|
0:? Sequence
|
||||||
|
0:35 't1' (layout( set=1 binding=1) uniform texture1D)
|
||||||
|
0:36 't2' (layout( set=1 binding=2) uniform texture2D)
|
||||||
|
0:37 't3' (layout( set=2 binding=1) uniform texture3D)
|
||||||
|
0:38 direct index (layout( row_major std430) buffer 4-component vector of float)
|
||||||
|
0:38 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of 4-component vector of float)
|
||||||
|
0:38 't4' (layout( set=3 binding=1 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data})
|
||||||
|
0:38 Constant:
|
||||||
|
0:38 0 (const uint)
|
||||||
|
0:38 Constant:
|
||||||
|
0:38 0 (const int)
|
||||||
|
0:39 indirect index (layout( row_major std430) buffer uint)
|
||||||
|
0:39 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of uint)
|
||||||
|
0:39 't5' (layout( set=3 binding=2 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
|
||||||
|
0:39 Constant:
|
||||||
|
0:39 0 (const uint)
|
||||||
|
0:39 right-shift ( temp int)
|
||||||
|
0:39 Constant:
|
||||||
|
0:39 0 (const int)
|
||||||
|
0:39 Constant:
|
||||||
|
0:39 2 (const int)
|
||||||
|
0:40 't6' (layout( set=3 binding=3 rgba32f) uniform textureBuffer)
|
||||||
|
0:42 's1' (layout( set=1 binding=1) uniform sampler)
|
||||||
|
0:43 's2' (layout( set=2 binding=2) uniform sampler)
|
||||||
|
0:45 'u1' (layout( set=1 binding=1 rgba32f) uniform image1D)
|
||||||
|
0:46 'u2' (layout( set=2 binding=2 rgba32f) uniform image2D)
|
||||||
|
0:47 'u3' (layout( set=2 binding=3 rgba32f) uniform image3D)
|
||||||
|
0:49 imageLoad ( temp float)
|
||||||
|
0:49 'u4' (layout( set=1 binding=4 r32f) uniform imageBuffer)
|
||||||
|
0:49 Constant:
|
||||||
|
0:49 0 (const int)
|
||||||
|
0:50 indirect index (layout( row_major std430) buffer uint)
|
||||||
|
0:50 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of uint)
|
||||||
|
0:50 'u5' (layout( set=2 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
|
||||||
|
0:50 Constant:
|
||||||
|
0:50 0 (const uint)
|
||||||
|
0:50 right-shift ( temp int)
|
||||||
|
0:50 Constant:
|
||||||
|
0:50 0 (const int)
|
||||||
|
0:50 Constant:
|
||||||
|
0:50 2 (const int)
|
||||||
|
0:51 direct index (layout( row_major std430) buffer float)
|
||||||
|
0:51 @data: direct index for structure (layout( row_major std430) buffer implicitly-sized array of float)
|
||||||
|
0:51 'u6' (layout( set=3 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
|
||||||
|
0:51 Constant:
|
||||||
|
0:51 0 (const uint)
|
||||||
|
0:51 Constant:
|
||||||
|
0:51 0 (const int)
|
||||||
|
0:52 'u7' (layout( set=4 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
|
||||||
|
0:53 'u8' (layout( set=5 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
|
||||||
|
0:55 cb1: direct index for structure (layout( row_major std140) uniform int)
|
||||||
|
0:55 'anon@0' (layout( set=6 binding=1 row_major std140) uniform block{layout( row_major std140) uniform int cb1})
|
||||||
|
0:55 Constant:
|
||||||
|
0:55 0 (const uint)
|
||||||
|
0:56 tb1: direct index for structure (layout( row_major std430) buffer int)
|
||||||
|
0:56 'anon@1' (layout( binding=7 row_major std430) readonly buffer block{layout( row_major std430) buffer int tb1})
|
||||||
|
0:56 Constant:
|
||||||
|
0:56 0 (const uint)
|
||||||
|
0:58 Branch: Return with expression
|
||||||
|
0:58 Constant:
|
||||||
|
0:58 0.000000
|
||||||
|
0:58 0.000000
|
||||||
|
0:58 0.000000
|
||||||
|
0:58 0.000000
|
||||||
|
0:34 Function Definition: main( ( temp void)
|
||||||
|
0:34 Function Parameters:
|
||||||
|
0:? Sequence
|
||||||
|
0:34 move second child to first child ( temp 4-component vector of float)
|
||||||
|
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||||
|
0:34 Function Call: @main( ( temp 4-component vector of float)
|
||||||
|
0:? Linker Objects
|
||||||
|
0:? 's1' (layout( set=1 binding=1) uniform sampler)
|
||||||
|
0:? 's2' (layout( set=2 binding=2) uniform sampler)
|
||||||
|
0:? 't1' (layout( set=1 binding=1) uniform texture1D)
|
||||||
|
0:? 't2' (layout( set=1 binding=2) uniform texture2D)
|
||||||
|
0:? 't3' (layout( set=2 binding=1) uniform texture3D)
|
||||||
|
0:? 't4' (layout( set=3 binding=1 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of 4-component vector of float @data})
|
||||||
|
0:? 't5' (layout( set=3 binding=2 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
|
||||||
|
0:? 't6' (layout( set=3 binding=3 rgba32f) uniform textureBuffer)
|
||||||
|
0:? 'u1' (layout( set=1 binding=1 rgba32f) uniform image1D)
|
||||||
|
0:? 'u2' (layout( set=2 binding=2 rgba32f) uniform image2D)
|
||||||
|
0:? 'u3' (layout( set=2 binding=3 rgba32f) uniform image3D)
|
||||||
|
0:? 'u4' (layout( set=1 binding=4 r32f) uniform imageBuffer)
|
||||||
|
0:? 'u5' (layout( set=2 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of uint @data})
|
||||||
|
0:? 'u6' (layout( set=3 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
|
||||||
|
0:? 'u7' (layout( set=4 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
|
||||||
|
0:? 'u8' (layout( set=5 binding=4 row_major std430) buffer block{layout( row_major std430) buffer implicitly-sized array of float @data})
|
||||||
|
0:? 'anon@0' (layout( set=6 binding=1 row_major std140) uniform block{layout( row_major std140) uniform int cb1})
|
||||||
|
0:? 'anon@1' (layout( binding=7 row_major std430) readonly buffer block{layout( row_major std430) buffer int tb1})
|
||||||
|
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
|
||||||
|
|
||||||
|
Uniform reflection:
|
||||||
|
t1: offset -1, type 8b5d, size 1, index -1, binding 21
|
||||||
|
t2: offset -1, type 8b5e, size 1, index -1, binding 22
|
||||||
|
t3: offset -1, type 8b5f, size 1, index -1, binding 26
|
||||||
|
t4.@data: offset 0, type 8b52, size 1, index 0, binding -1
|
||||||
|
t5.@data: offset 0, type 1405, size 0, index 1, binding -1
|
||||||
|
t6: offset -1, type 8dc2, size 1, index -1, binding 23
|
||||||
|
s1: offset -1, type 0, size 1, index -1, binding 11
|
||||||
|
s2: offset -1, type 0, size 1, index -1, binding 17
|
||||||
|
u1: offset -1, type 904c, size 1, index -1, binding 31
|
||||||
|
u2: offset -1, type 904d, size 1, index -1, binding 42
|
||||||
|
u3: offset -1, type 904e, size 1, index -1, binding 43
|
||||||
|
u4: offset -1, type 9051, size 1, index -1, binding 34
|
||||||
|
u5.@data: offset 0, type 1405, size 0, index 2, binding -1
|
||||||
|
u6.@data: offset 0, type 1406, size 1, index 3, binding -1
|
||||||
|
cb1: offset 0, type 1404, size 1, index 4, binding -1
|
||||||
|
tb1: offset 0, type 1404, size 1, index 5, binding -1
|
||||||
|
|
||||||
|
Uniform block reflection:
|
||||||
|
t4: offset -1, type ffffffff, size 0, index -1, binding 21
|
||||||
|
t5: offset -1, type ffffffff, size 0, index -1, binding 22
|
||||||
|
u5: offset -1, type ffffffff, size 0, index -1, binding 44
|
||||||
|
u6: offset -1, type ffffffff, size 0, index -1, binding 34
|
||||||
|
cb: offset -1, type ffffffff, size 4, index -1, binding 51
|
||||||
|
tb: offset -1, type ffffffff, size 4, index -1, binding 27
|
||||||
|
|
||||||
|
Vertex attribute reflection:
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
// Test register class offsets for different resource types
|
||||||
|
|
||||||
|
SamplerState s1 : register(s1, space1);
|
||||||
|
SamplerComparisonState s2 : register(s2, space2);
|
||||||
|
|
||||||
|
Texture1D <float4> t1 : register(t1, space1);
|
||||||
|
Texture2D <float4> t2 : register(t2, space1);
|
||||||
|
Texture3D <float4> t3 : register(t1, space2);
|
||||||
|
|
||||||
|
StructuredBuffer<float4> t4 : register(t1, space3);
|
||||||
|
|
||||||
|
ByteAddressBuffer t5 : register(t2, space3);
|
||||||
|
Buffer<float4> t6 : register(t3, space3);
|
||||||
|
|
||||||
|
RWTexture1D <float4> u1 : register(u1, space1);
|
||||||
|
RWTexture2D <float4> u2 : register(u2, space2);
|
||||||
|
RWTexture3D <float4> u3 : register(u3, space2);
|
||||||
|
|
||||||
|
RWBuffer <float> u4 : register(u4, space1);
|
||||||
|
RWByteAddressBuffer u5 : register(u4, space2);
|
||||||
|
RWStructuredBuffer<float> u6 : register(u4, space3);
|
||||||
|
AppendStructuredBuffer<float> u7 : register(u4, space4);
|
||||||
|
ConsumeStructuredBuffer<float> u8 : register(u4, space5);
|
||||||
|
|
||||||
|
cbuffer cb : register(b1, space6) {
|
||||||
|
int cb1;
|
||||||
|
};
|
||||||
|
|
||||||
|
tbuffer tb : register(t7) {
|
||||||
|
int tb1;
|
||||||
|
};
|
||||||
|
|
||||||
|
float4 main() : SV_Target0
|
||||||
|
{
|
||||||
|
t1;
|
||||||
|
t2;
|
||||||
|
t3;
|
||||||
|
t4[0];
|
||||||
|
t5.Load(0);
|
||||||
|
t6;
|
||||||
|
|
||||||
|
s1;
|
||||||
|
s2;
|
||||||
|
|
||||||
|
u1;
|
||||||
|
u2;
|
||||||
|
u3;
|
||||||
|
|
||||||
|
u4[0];
|
||||||
|
u5.Load(0);
|
||||||
|
u6[0];
|
||||||
|
u7;
|
||||||
|
u8;
|
||||||
|
|
||||||
|
cb1;
|
||||||
|
tb1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -104,6 +104,13 @@ diff -b $BASEDIR/hlsl.explicitDescriptorSet.frag.out $TARGETDIR/hlsl.explicitDes
|
||||||
$EXE -V -D -e main -H -Od hlsl.explicitDescriptorSet.frag --hlsl-iomap --amb --ssb 10 --stb 20 --rsb frag 3 > $TARGETDIR/hlsl.explicitDescriptorSet-2.frag.out
|
$EXE -V -D -e main -H -Od hlsl.explicitDescriptorSet.frag --hlsl-iomap --amb --ssb 10 --stb 20 --rsb frag 3 > $TARGETDIR/hlsl.explicitDescriptorSet-2.frag.out
|
||||||
diff -b $BASEDIR/hlsl.explicitDescriptorSet-2.frag.out $TARGETDIR/hlsl.explicitDescriptorSet-2.frag.out || HASERROR=1
|
diff -b $BASEDIR/hlsl.explicitDescriptorSet-2.frag.out $TARGETDIR/hlsl.explicitDescriptorSet-2.frag.out || HASERROR=1
|
||||||
|
|
||||||
|
#
|
||||||
|
# Testing per-descriptor-set IO map shift
|
||||||
|
#
|
||||||
|
echo 'Testing per-descriptor-set IO map shift'
|
||||||
|
$EXE -e main --hlsl-iomap --ssb 1 10 2 15 --stb 20 --stb 2 25 --suavb 30 --suavb 2 40 --sub 6 50 -i -q -D -V hlsl.shift.per-set.frag > $TARGETDIR/hlsl.shift.per-set.frag.out || HASERROR=1
|
||||||
|
diff -b $BASEDIR/hlsl.shift.per-set.frag.out $TARGETDIR/hlsl.shift.per-set.frag.out || HASERROR=1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Testing location error
|
# Testing location error
|
||||||
#
|
#
|
||||||
|
|
|
@ -3222,4 +3222,20 @@ void TIntermediate::performTextureUpgradeAndSamplerRemovalTransformation(TInterm
|
||||||
root->traverse(&transform);
|
root->traverse(&transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* TIntermediate::getResourceName(TResourceType res)
|
||||||
|
{
|
||||||
|
switch (res) {
|
||||||
|
case EResSampler: return "shift-sampler-binding";
|
||||||
|
case EResTexture: return "shift-texture-binding";
|
||||||
|
case EResImage: return "shift-image-binding";
|
||||||
|
case EResUbo: return "shift-UBO-binding";
|
||||||
|
case EResSsbo: return "shift-ssbo-binding";
|
||||||
|
case EResUav: return "shift-uav-binding";
|
||||||
|
default:
|
||||||
|
assert(0); // internal error: should only be called with valid resource types.
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
|
@ -1661,20 +1661,30 @@ void TShader::addProcesses(const std::vector<std::string>& p)
|
||||||
intermediate->addProcesses(p);
|
intermediate->addProcesses(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set binding base for given resource type
|
||||||
|
void TShader::setShiftBinding(TResourceType res, unsigned int base) {
|
||||||
|
intermediate->setShiftBinding(res, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set binding base for given resource type for a given binding set.
|
||||||
|
void TShader::setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base) {
|
||||||
|
intermediate->setShiftBindingForSet(res, set, base);
|
||||||
|
}
|
||||||
|
|
||||||
// Set binding base for sampler types
|
// Set binding base for sampler types
|
||||||
void TShader::setShiftSamplerBinding(unsigned int base) { intermediate->setShiftSamplerBinding(base); }
|
void TShader::setShiftSamplerBinding(unsigned int base) { setShiftBinding(EResSampler, base); }
|
||||||
// Set binding base for texture types (SRV)
|
// Set binding base for texture types (SRV)
|
||||||
void TShader::setShiftTextureBinding(unsigned int base) { intermediate->setShiftTextureBinding(base); }
|
void TShader::setShiftTextureBinding(unsigned int base) { setShiftBinding(EResTexture, base); }
|
||||||
// Set binding base for image types
|
// Set binding base for image types
|
||||||
void TShader::setShiftImageBinding(unsigned int base) { intermediate->setShiftImageBinding(base); }
|
void TShader::setShiftImageBinding(unsigned int base) { setShiftBinding(EResImage, base); }
|
||||||
// Set binding base for uniform buffer objects (CBV)
|
// Set binding base for uniform buffer objects (CBV)
|
||||||
void TShader::setShiftUboBinding(unsigned int base) { intermediate->setShiftUboBinding(base); }
|
void TShader::setShiftUboBinding(unsigned int base) { setShiftBinding(EResUbo, base); }
|
||||||
// Synonym for setShiftUboBinding, to match HLSL language.
|
// Synonym for setShiftUboBinding, to match HLSL language.
|
||||||
void TShader::setShiftCbufferBinding(unsigned int base) { intermediate->setShiftUboBinding(base); }
|
void TShader::setShiftCbufferBinding(unsigned int base) { setShiftBinding(EResUbo, base); }
|
||||||
// Set binding base for UAV (unordered access view)
|
// Set binding base for UAV (unordered access view)
|
||||||
void TShader::setShiftUavBinding(unsigned int base) { intermediate->setShiftUavBinding(base); }
|
void TShader::setShiftUavBinding(unsigned int base) { setShiftBinding(EResUav, base); }
|
||||||
// Set binding base for SSBOs
|
// Set binding base for SSBOs
|
||||||
void TShader::setShiftSsboBinding(unsigned int base) { intermediate->setShiftSsboBinding(base); }
|
void TShader::setShiftSsboBinding(unsigned int base) { setShiftBinding(EResSsbo, base); }
|
||||||
// Enables binding automapping using TIoMapper
|
// Enables binding automapping using TIoMapper
|
||||||
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
|
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
|
||||||
// Fragile: currently within one stage: simple auto-assignment of location
|
// Fragile: currently within one stage: simple auto-assignment of location
|
||||||
|
|
|
@ -351,16 +351,21 @@ private:
|
||||||
// Base class for shared TIoMapResolver services, used by several derivations.
|
// Base class for shared TIoMapResolver services, used by several derivations.
|
||||||
struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
||||||
{
|
{
|
||||||
int baseSamplerBinding;
|
TDefaultIoResolverBase(const TIntermediate &intermediate) :
|
||||||
int baseTextureBinding;
|
intermediate(intermediate),
|
||||||
int baseImageBinding;
|
nextUniformLocation(0)
|
||||||
int baseUboBinding;
|
{ }
|
||||||
int baseSsboBinding;
|
|
||||||
int baseUavBinding;
|
int getBaseBinding(TResourceType res, unsigned int set) const {
|
||||||
std::vector<std::string> baseResourceSetBinding;
|
return selectBaseBinding(intermediate.getShiftBinding(res),
|
||||||
bool doAutoBindingMapping;
|
intermediate.getShiftBindingForSet(res, set));
|
||||||
bool doAutoLocationMapping;
|
}
|
||||||
int nextUniformLocation;
|
|
||||||
|
const std::vector<std::string>& getResourceSetBinding() const { return intermediate.getResourceSetBinding(); }
|
||||||
|
|
||||||
|
bool doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); }
|
||||||
|
bool doAutoLocationMapping() const { return intermediate.getAutoMapLocations(); }
|
||||||
|
|
||||||
typedef std::vector<int> TSlotSet;
|
typedef std::vector<int> TSlotSet;
|
||||||
typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
|
typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
|
||||||
TSlotSetMap slots;
|
TSlotSetMap slots;
|
||||||
|
@ -411,15 +416,15 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
||||||
return type.getQualifier().layoutSet;
|
return type.getQualifier().layoutSet;
|
||||||
|
|
||||||
// If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN)
|
// If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN)
|
||||||
if (baseResourceSetBinding.size() == 1)
|
if (getResourceSetBinding().size() == 1)
|
||||||
return atoi(baseResourceSetBinding[0].c_str());
|
return atoi(getResourceSetBinding()[0].c_str());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int resolveUniformLocation(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
int resolveUniformLocation(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
||||||
{
|
{
|
||||||
// kick out of not doing this
|
// kick out of not doing this
|
||||||
if (!doAutoLocationMapping)
|
if (!doAutoLocationMapping())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// no locations added if already present, a built-in variable, a block, or an opaque
|
// no locations added if already present, a built-in variable, a block, or an opaque
|
||||||
|
@ -444,7 +449,7 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
||||||
int resolveInOutLocation(EShLanguage /*stage*/, const char* /*name*/, const TType& type, bool /*is_live*/) override
|
int resolveInOutLocation(EShLanguage /*stage*/, const char* /*name*/, const TType& type, bool /*is_live*/) override
|
||||||
{
|
{
|
||||||
// kick out of not doing this
|
// kick out of not doing this
|
||||||
if (!doAutoLocationMapping)
|
if (!doAutoLocationMapping())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// no locations added if already present, or a built-in variable
|
// no locations added if already present, or a built-in variable
|
||||||
|
@ -485,6 +490,14 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
||||||
void endResolve(EShLanguage) override {}
|
void endResolve(EShLanguage) override {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
const TIntermediate &intermediate;
|
||||||
|
int nextUniformLocation;
|
||||||
|
|
||||||
|
// Return descriptor set specific base if there is one, and the generic base otherwise.
|
||||||
|
int selectBaseBinding(int base, int descriptorSetBase) const {
|
||||||
|
return descriptorSetBase != -1 ? descriptorSetBase : base;
|
||||||
|
}
|
||||||
|
|
||||||
static int getLayoutSet(const glslang::TType& type) {
|
static int getLayoutSet(const glslang::TType& type) {
|
||||||
if (type.getQualifier().hasSet())
|
if (type.getQualifier().hasSet())
|
||||||
return type.getQualifier().layoutSet;
|
return type.getQualifier().layoutSet;
|
||||||
|
@ -518,6 +531,8 @@ protected:
|
||||||
*/
|
*/
|
||||||
struct TDefaultIoResolver : public TDefaultIoResolverBase
|
struct TDefaultIoResolver : public TDefaultIoResolverBase
|
||||||
{
|
{
|
||||||
|
TDefaultIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { }
|
||||||
|
|
||||||
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override
|
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -529,37 +544,37 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase
|
||||||
|
|
||||||
if (type.getQualifier().hasBinding()) {
|
if (type.getQualifier().hasBinding()) {
|
||||||
if (isImageType(type))
|
if (isImageType(type))
|
||||||
return reserveSlot(set, baseImageBinding + type.getQualifier().layoutBinding);
|
return reserveSlot(set, getBaseBinding(EResImage, set) + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
if (isTextureType(type))
|
if (isTextureType(type))
|
||||||
return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
if (isSsboType(type))
|
if (isSsboType(type))
|
||||||
return reserveSlot(set, baseSsboBinding + type.getQualifier().layoutBinding);
|
return reserveSlot(set, getBaseBinding(EResSsbo, set) + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
if (isSamplerType(type))
|
if (isSamplerType(type))
|
||||||
return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
if (isUboType(type))
|
if (isUboType(type))
|
||||||
return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
|
return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding);
|
||||||
} else if (is_live && doAutoBindingMapping) {
|
} else if (is_live && doAutoBindingMapping()) {
|
||||||
// find free slot, the caller did make sure it passes all vars with binding
|
// find free slot, the caller did make sure it passes all vars with binding
|
||||||
// first and now all are passed that do not have a binding and needs one
|
// first and now all are passed that do not have a binding and needs one
|
||||||
|
|
||||||
if (isImageType(type))
|
if (isImageType(type))
|
||||||
return getFreeSlot(set, baseImageBinding);
|
return getFreeSlot(set, getBaseBinding(EResImage, set));
|
||||||
|
|
||||||
if (isTextureType(type))
|
if (isTextureType(type))
|
||||||
return getFreeSlot(set, baseTextureBinding);
|
return getFreeSlot(set, getBaseBinding(EResTexture, set));
|
||||||
|
|
||||||
if (isSsboType(type))
|
if (isSsboType(type))
|
||||||
return getFreeSlot(set, baseSsboBinding);
|
return getFreeSlot(set, getBaseBinding(EResSsbo, set));
|
||||||
|
|
||||||
if (isSamplerType(type))
|
if (isSamplerType(type))
|
||||||
return getFreeSlot(set, baseSamplerBinding);
|
return getFreeSlot(set, getBaseBinding(EResSampler, set));
|
||||||
|
|
||||||
if (isUboType(type))
|
if (isUboType(type))
|
||||||
return getFreeSlot(set, baseUboBinding);
|
return getFreeSlot(set, getBaseBinding(EResUbo, set));
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -620,6 +635,8 @@ b – for constant buffer views (CBV)
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
|
struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
|
||||||
{
|
{
|
||||||
|
TDefaultHlslIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { }
|
||||||
|
|
||||||
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override
|
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -631,31 +648,31 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
|
||||||
|
|
||||||
if (type.getQualifier().hasBinding()) {
|
if (type.getQualifier().hasBinding()) {
|
||||||
if (isUavType(type))
|
if (isUavType(type))
|
||||||
return reserveSlot(set, baseUavBinding + type.getQualifier().layoutBinding);
|
return reserveSlot(set, getBaseBinding(EResUav, set) + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
if (isSrvType(type))
|
if (isSrvType(type))
|
||||||
return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
if (isSamplerType(type))
|
if (isSamplerType(type))
|
||||||
return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
if (isUboType(type))
|
if (isUboType(type))
|
||||||
return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
|
return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding);
|
||||||
} else if (is_live && doAutoBindingMapping) {
|
} else if (is_live && doAutoBindingMapping()) {
|
||||||
// find free slot, the caller did make sure it passes all vars with binding
|
// find free slot, the caller did make sure it passes all vars with binding
|
||||||
// first and now all are passed that do not have a binding and needs one
|
// first and now all are passed that do not have a binding and needs one
|
||||||
|
|
||||||
if (isUavType(type))
|
if (isUavType(type))
|
||||||
return getFreeSlot(set, baseUavBinding);
|
return getFreeSlot(set, getBaseBinding(EResUav, set));
|
||||||
|
|
||||||
if (isSrvType(type))
|
if (isSrvType(type))
|
||||||
return getFreeSlot(set, baseTextureBinding);
|
return getFreeSlot(set, getBaseBinding(EResTexture, set));
|
||||||
|
|
||||||
if (isSamplerType(type))
|
if (isSamplerType(type))
|
||||||
return getFreeSlot(set, baseSamplerBinding);
|
return getFreeSlot(set, getBaseBinding(EResSampler, set));
|
||||||
|
|
||||||
if (isUboType(type))
|
if (isUboType(type))
|
||||||
return getFreeSlot(set, baseUboBinding);
|
return getFreeSlot(set, getBaseBinding(EResUbo, set));
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -684,17 +701,17 @@ protected:
|
||||||
// Returns false if the input is too malformed to do this.
|
// Returns false if the input is too malformed to do this.
|
||||||
bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSink &infoSink, TIoMapResolver *resolver)
|
bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSink &infoSink, TIoMapResolver *resolver)
|
||||||
{
|
{
|
||||||
// Trivial return if there is nothing to do.
|
bool somethingToDo = !intermediate.getResourceSetBinding().empty() ||
|
||||||
if (intermediate.getShiftSamplerBinding() == 0 &&
|
intermediate.getAutoMapBindings() ||
|
||||||
intermediate.getShiftTextureBinding() == 0 &&
|
intermediate.getAutoMapLocations();
|
||||||
intermediate.getShiftImageBinding() == 0 &&
|
|
||||||
intermediate.getShiftUboBinding() == 0 &&
|
for (int res = 0; res < EResCount; ++res) {
|
||||||
intermediate.getShiftSsboBinding() == 0 &&
|
somethingToDo = somethingToDo ||
|
||||||
intermediate.getShiftUavBinding() == 0 &&
|
(intermediate.getShiftBinding(TResourceType(res)) != 0) ||
|
||||||
intermediate.getResourceSetBinding().empty() &&
|
intermediate.hasShiftBindingForSet(TResourceType(res));
|
||||||
intermediate.getAutoMapBindings() == false &&
|
}
|
||||||
intermediate.getAutoMapLocations() == false &&
|
|
||||||
resolver == nullptr)
|
if (!somethingToDo && resolver == nullptr)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive())
|
if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive())
|
||||||
|
@ -705,30 +722,15 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// if no resolver is provided, use the default resolver with the given shifts and auto map settings
|
// if no resolver is provided, use the default resolver with the given shifts and auto map settings
|
||||||
TDefaultIoResolver defaultResolver;
|
TDefaultIoResolver defaultResolver(intermediate);
|
||||||
TDefaultHlslIoResolver defaultHlslResolver;
|
TDefaultHlslIoResolver defaultHlslResolver(intermediate);
|
||||||
|
|
||||||
if (resolver == nullptr) {
|
if (resolver == nullptr) {
|
||||||
TDefaultIoResolverBase* resolverBase;
|
|
||||||
|
|
||||||
// TODO: use a passed in IO mapper for this
|
// TODO: use a passed in IO mapper for this
|
||||||
if (intermediate.usingHlslIoMapping())
|
if (intermediate.usingHlslIoMapping())
|
||||||
resolverBase = &defaultHlslResolver;
|
resolver = &defaultHlslResolver;
|
||||||
else
|
else
|
||||||
resolverBase = &defaultResolver;
|
resolver = &defaultResolver;
|
||||||
|
|
||||||
resolverBase->baseSamplerBinding = intermediate.getShiftSamplerBinding();
|
|
||||||
resolverBase->baseTextureBinding = intermediate.getShiftTextureBinding();
|
|
||||||
resolverBase->baseImageBinding = intermediate.getShiftImageBinding();
|
|
||||||
resolverBase->baseUboBinding = intermediate.getShiftUboBinding();
|
|
||||||
resolverBase->baseSsboBinding = intermediate.getShiftSsboBinding();
|
|
||||||
resolverBase->baseUavBinding = intermediate.getShiftUavBinding();
|
|
||||||
resolverBase->baseResourceSetBinding = intermediate.getResourceSetBinding();
|
|
||||||
resolverBase->doAutoBindingMapping = intermediate.getAutoMapBindings();
|
|
||||||
resolverBase->doAutoLocationMapping = intermediate.getAutoMapLocations();
|
|
||||||
resolverBase->nextUniformLocation = 0;
|
|
||||||
|
|
||||||
resolver = resolverBase;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TVarLiveMap inVarMap, outVarMap, uniformVarMap;
|
TVarLiveMap inVarMap, outVarMap, uniformVarMap;
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
class TInfoSink;
|
class TInfoSink;
|
||||||
|
|
||||||
|
@ -221,12 +222,6 @@ public:
|
||||||
layoutOverrideCoverage(false),
|
layoutOverrideCoverage(false),
|
||||||
geoPassthroughEXT(false),
|
geoPassthroughEXT(false),
|
||||||
#endif
|
#endif
|
||||||
shiftSamplerBinding(0),
|
|
||||||
shiftTextureBinding(0),
|
|
||||||
shiftImageBinding(0),
|
|
||||||
shiftUboBinding(0),
|
|
||||||
shiftSsboBinding(0),
|
|
||||||
shiftUavBinding(0),
|
|
||||||
autoMapBindings(false),
|
autoMapBindings(false),
|
||||||
autoMapLocations(false),
|
autoMapLocations(false),
|
||||||
flattenUniformArrays(false),
|
flattenUniformArrays(false),
|
||||||
|
@ -244,6 +239,8 @@ public:
|
||||||
localSizeSpecId[1] = TQualifier::layoutNotSet;
|
localSizeSpecId[1] = TQualifier::layoutNotSet;
|
||||||
localSizeSpecId[2] = TQualifier::layoutNotSet;
|
localSizeSpecId[2] = TQualifier::layoutNotSet;
|
||||||
xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
|
xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
|
||||||
|
|
||||||
|
shiftBinding.fill(0);
|
||||||
}
|
}
|
||||||
void setLimits(const TBuiltInResource& r) { resources = r; }
|
void setLimits(const TBuiltInResource& r) { resources = r; }
|
||||||
|
|
||||||
|
@ -263,42 +260,39 @@ public:
|
||||||
const std::string& getEntryPointName() const { return entryPointName; }
|
const std::string& getEntryPointName() const { return entryPointName; }
|
||||||
const std::string& getEntryPointMangledName() const { return entryPointMangledName; }
|
const std::string& getEntryPointMangledName() const { return entryPointMangledName; }
|
||||||
|
|
||||||
void setShiftSamplerBinding(unsigned int shift)
|
void setShiftBinding(TResourceType res, unsigned int shift)
|
||||||
{
|
{
|
||||||
shiftSamplerBinding = shift;
|
shiftBinding[res] = shift;
|
||||||
processes.addIfNonZero("shift-sampler-binding", shift);
|
|
||||||
|
const char* name = getResourceName(res);
|
||||||
|
if (name != nullptr)
|
||||||
|
processes.addIfNonZero(name, shift);
|
||||||
}
|
}
|
||||||
unsigned int getShiftSamplerBinding() const { return shiftSamplerBinding; }
|
|
||||||
void setShiftTextureBinding(unsigned int shift)
|
unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; }
|
||||||
|
|
||||||
|
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int shift)
|
||||||
{
|
{
|
||||||
shiftTextureBinding = shift;
|
if (shift == 0) // ignore if there's no shift: it's a no-op.
|
||||||
processes.addIfNonZero("shift-texture-binding", shift);
|
return;
|
||||||
|
|
||||||
|
shiftBindingForSet[res][set] = shift;
|
||||||
|
|
||||||
|
const char* name = getResourceName(res);
|
||||||
|
if (name != nullptr) {
|
||||||
|
processes.addProcess(name);
|
||||||
|
processes.addArgument(set);
|
||||||
|
processes.addArgument(shift);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
unsigned int getShiftTextureBinding() const { return shiftTextureBinding; }
|
|
||||||
void setShiftImageBinding(unsigned int shift)
|
int getShiftBindingForSet(TResourceType res, unsigned int set) const
|
||||||
{
|
{
|
||||||
shiftImageBinding = shift;
|
const auto shift = shiftBindingForSet[res].find(set);
|
||||||
processes.addIfNonZero("shift-image-binding", shift);
|
return shift == shiftBindingForSet[res].end() ? -1 : shift->second;
|
||||||
}
|
}
|
||||||
unsigned int getShiftImageBinding() const { return shiftImageBinding; }
|
bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); }
|
||||||
void setShiftUboBinding(unsigned int shift)
|
|
||||||
{
|
|
||||||
shiftUboBinding = shift;
|
|
||||||
processes.addIfNonZero("shift-UBO-binding", shift);
|
|
||||||
}
|
|
||||||
unsigned int getShiftUboBinding() const { return shiftUboBinding; }
|
|
||||||
void setShiftSsboBinding(unsigned int shift)
|
|
||||||
{
|
|
||||||
shiftSsboBinding = shift;
|
|
||||||
processes.addIfNonZero("shift-ssbo-binding", shift);
|
|
||||||
}
|
|
||||||
unsigned int getShiftSsboBinding() const { return shiftSsboBinding; }
|
|
||||||
void setShiftUavBinding(unsigned int shift)
|
|
||||||
{
|
|
||||||
shiftUavBinding = shift;
|
|
||||||
processes.addIfNonZero("shift-uav-binding", shift);
|
|
||||||
}
|
|
||||||
unsigned int getShiftUavBinding() const { return shiftUavBinding; }
|
|
||||||
void setResourceSetBinding(const std::vector<std::string>& shift)
|
void setResourceSetBinding(const std::vector<std::string>& shift)
|
||||||
{
|
{
|
||||||
resourceSetBinding = shift;
|
resourceSetBinding = shift;
|
||||||
|
@ -638,6 +632,7 @@ protected:
|
||||||
void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
|
void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
|
||||||
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
|
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
|
||||||
void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
|
void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
|
||||||
|
static const char* getResourceName(TResourceType);
|
||||||
|
|
||||||
const EShLanguage language; // stage, known at construction time
|
const EShLanguage language; // stage, known at construction time
|
||||||
EShSource source; // source language, known a bit later
|
EShSource source; // source language, known a bit later
|
||||||
|
@ -678,12 +673,13 @@ protected:
|
||||||
bool geoPassthroughEXT;
|
bool geoPassthroughEXT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned int shiftSamplerBinding;
|
// Base shift values
|
||||||
unsigned int shiftTextureBinding;
|
std::array<unsigned int, EResCount> shiftBinding;
|
||||||
unsigned int shiftImageBinding;
|
|
||||||
unsigned int shiftUboBinding;
|
// Per-descriptor-set shift values
|
||||||
unsigned int shiftSsboBinding;
|
typedef std::map<int, int> TDescriptorSetShift;
|
||||||
unsigned int shiftUavBinding;
|
TDescriptorSetShift shiftBindingForSet[EResCount];
|
||||||
|
|
||||||
std::vector<std::string> resourceSetBinding;
|
std::vector<std::string> resourceSetBinding;
|
||||||
bool autoMapBindings;
|
bool autoMapBindings;
|
||||||
bool autoMapLocations;
|
bool autoMapLocations;
|
||||||
|
|
|
@ -324,6 +324,17 @@ bool InitializeProcess();
|
||||||
// Call once per process to tear down everything
|
// Call once per process to tear down everything
|
||||||
void FinalizeProcess();
|
void FinalizeProcess();
|
||||||
|
|
||||||
|
// Resource type for IO resolver
|
||||||
|
enum TResourceType {
|
||||||
|
EResSampler,
|
||||||
|
EResTexture,
|
||||||
|
EResImage,
|
||||||
|
EResUbo,
|
||||||
|
EResSsbo,
|
||||||
|
EResUav,
|
||||||
|
EResCount
|
||||||
|
};
|
||||||
|
|
||||||
// Make one TShader per shader that you will link into a program. Then provide
|
// Make one TShader per shader that you will link into a program. Then provide
|
||||||
// the shader through setStrings() or setStringsWithLengths(), then call parse(),
|
// the shader through setStrings() or setStringsWithLengths(), then call parse(),
|
||||||
// then query the info logs.
|
// then query the info logs.
|
||||||
|
@ -347,13 +358,17 @@ public:
|
||||||
void setEntryPoint(const char* entryPoint);
|
void setEntryPoint(const char* entryPoint);
|
||||||
void setSourceEntryPoint(const char* sourceEntryPointName);
|
void setSourceEntryPoint(const char* sourceEntryPointName);
|
||||||
void addProcesses(const std::vector<std::string>&);
|
void addProcesses(const std::vector<std::string>&);
|
||||||
void setShiftSamplerBinding(unsigned int base);
|
|
||||||
void setShiftTextureBinding(unsigned int base);
|
// IO resolver binding data: see comments in ShaderLang.cpp
|
||||||
void setShiftImageBinding(unsigned int base);
|
void setShiftBinding(TResourceType res, unsigned int base);
|
||||||
void setShiftUboBinding(unsigned int base);
|
void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftUavBinding(unsigned int base);
|
void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
|
void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
void setShiftSsboBinding(unsigned int base);
|
void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
|
void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
|
void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
|
||||||
|
void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
|
||||||
|
void setShiftBindingForSet(TResourceType res, unsigned int set, unsigned int base);
|
||||||
void setResourceSetBinding(const std::vector<std::string>& base);
|
void setResourceSetBinding(const std::vector<std::string>& base);
|
||||||
void setAutoMapBindings(bool map);
|
void setAutoMapBindings(bool map);
|
||||||
void setAutoMapLocations(bool map);
|
void setAutoMapLocations(bool map);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче