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.
This commit is contained in:
steve-lunarg 2016-09-07 15:20:19 -06:00
parent a1e2d4952e
commit 7f7c2ed780
13 changed files with 1191 additions and 10 deletions

View file

@ -234,6 +234,54 @@ public:
}
}
// Compiles and links the given source |code| of the given shader
// |stage| into the target under the semantics specified via |controls|.
// Returns a GlslangResult instance containing all the information generated
// during the process. If the target includes SPIR-V, also disassembles
// the result and returns disassembly text.
GlslangResult compileLinkIoMap(
const std::string shaderName, const std::string& code,
const std::string& entryPointName, EShMessages controls,
int baseSamplerBinding,
int baseTextureBinding,
int baseUboBinding,
bool autoMapBindings)
{
const EShLanguage kind = GetShaderStage(GetSuffix(shaderName));
glslang::TShader shader(kind);
shader.setShiftSamplerBinding(baseSamplerBinding);
shader.setShiftTextureBinding(baseTextureBinding);
shader.setShiftUboBinding(baseUboBinding);
shader.setAutoMapBindings(autoMapBindings);
bool success = compile(&shader, code, entryPointName, controls);
glslang::TProgram program;
program.addShader(&shader);
success &= program.link(controls);
success &= program.mapIO();
spv::SpvBuildLogger logger;
if (success && (controls & EShMsgSpvRules)) {
std::vector<uint32_t> spirv_binary;
glslang::GlslangToSpv(*program.getIntermediate(kind),
spirv_binary, &logger);
std::ostringstream disassembly_stream;
spv::Parameterize();
spv::Disassemble(disassembly_stream, spirv_binary);
return {{{shaderName, shader.getInfoLog(), shader.getInfoDebugLog()},},
program.getInfoLog(), program.getInfoDebugLog(),
logger.getAllMessages(), disassembly_stream.str()};
} else {
return {{{shaderName, shader.getInfoLog(), shader.getInfoDebugLog()},},
program.getInfoLog(), program.getInfoDebugLog(), "", ""};
}
}
// This is like compileAndLink but with remapping of the SPV binary
// through spirvbin_t::remap(). While technically this could be merged
// with compileAndLink() above (with the remap step optionally being a no-op)
@ -347,6 +395,38 @@ public:
expectedOutputFname);
}
void loadFileCompileIoMapAndCheck(const std::string& testDir,
const std::string& testName,
Source source,
Semantics semantics,
Target target,
const std::string& entryPointName,
int baseSamplerBinding,
int baseTextureBinding,
int baseUboBinding,
bool autoMapBindings)
{
const std::string inputFname = testDir + "/" + testName;
const std::string expectedOutputFname =
testDir + "/baseResults/" + testName + ".out";
std::string input, expectedOutput;
tryLoadFile(inputFname, "input", &input);
tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
const EShMessages controls = DeriveOptions(source, semantics, target);
GlslangResult result = compileLinkIoMap(testName, input, entryPointName, controls,
baseSamplerBinding, baseTextureBinding, baseUboBinding,
autoMapBindings);
// Generate the hybrid output in the way of glslangValidator.
std::ostringstream stream;
outputResultToStream(&stream, result, controls);
checkEqAndUpdateIfRequested(expectedOutput, stream.str(),
expectedOutputFname);
}
void loadFileCompileRemapAndCheck(const std::string& testDir,
const std::string& testName,
Source source,