mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-08 11:30:06 +00:00
Pure Texture to Sampled Texture Transform
Adds a transformation step to the post processing step. Two modes are available: 1) keep - Keeps samplers, textures and sampled textures as is 2) transform pure texture into sampled texture and remove pure samplers - removes all pure samplers - transforms all pure textures into its sampled counter part Change-Id: If54972e8052961db66c23f4b7e719d363cf6edbd
This commit is contained in:
parent
d6af18f621
commit
baf570efa5
38
Test/baseResults/spv.texture.sampler.transform.frag.out
Normal file
38
Test/baseResults/spv.texture.sampler.transform.frag.out
Normal file
@ -0,0 +1,38 @@
|
||||
spv.texture.sampler.transform.frag
|
||||
Warning, version 440 is not yet complete; most version-specific features are present, but some are missing.
|
||||
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80001
|
||||
// Id's are bound by 19
|
||||
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Fragment 4 "main" 9 16
|
||||
ExecutionMode 4 OriginUpperLeft
|
||||
Source GLSL 440
|
||||
Name 4 "main"
|
||||
Name 9 "color"
|
||||
Name 12 "tex"
|
||||
Name 16 "coord"
|
||||
Decorate 12(tex) DescriptorSet 0
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeFloat 32
|
||||
7: TypeVector 6(float) 4
|
||||
8: TypePointer Output 7(fvec4)
|
||||
9(color): 8(ptr) Variable Output
|
||||
10: TypeImage 6(float) 2D sampled format:Unknown
|
||||
11: TypePointer UniformConstant 10
|
||||
12(tex): 11(ptr) Variable UniformConstant
|
||||
14: TypeVector 6(float) 2
|
||||
15: TypePointer Input 14(fvec2)
|
||||
16(coord): 15(ptr) Variable Input
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
13: 10 Load 12(tex)
|
||||
17: 14(fvec2) Load 16(coord)
|
||||
18: 7(fvec4) ImageSampleImplicitLod 13 17
|
||||
Store 9(color) 18
|
||||
Return
|
||||
FunctionEnd
|
13
Test/spv.texture.sampler.transform.frag
Normal file
13
Test/spv.texture.sampler.transform.frag
Normal file
@ -0,0 +1,13 @@
|
||||
#version 440
|
||||
|
||||
uniform sampler smp;
|
||||
uniform texture2D tex;
|
||||
|
||||
in vec2 coord;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = texture(sampler2D(tex, smp), coord);
|
||||
}
|
@ -1310,6 +1310,7 @@ public:
|
||||
|
||||
virtual TBasicType getBasicType() const { return basicType; }
|
||||
virtual const TSampler& getSampler() const { return sampler; }
|
||||
virtual TSampler& getSampler() { return sampler; }
|
||||
|
||||
virtual TQualifier& getQualifier() { return qualifier; }
|
||||
virtual const TQualifier& getQualifier() const { return qualifier; }
|
||||
|
@ -1776,6 +1776,14 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/)
|
||||
// Propagate 'noContraction' label in backward from 'precise' variables.
|
||||
glslang::PropagateNoContraction(*this);
|
||||
|
||||
switch (textureSamplerTransformMode) {
|
||||
case EShTexSampTransKeep:
|
||||
break;
|
||||
case EShTexSampTransUpgradeTextureRemoveSampler:
|
||||
performTextureUpgradeAndSamplerRemovalTransformation(root);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2943,4 +2951,41 @@ bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TInt
|
||||
(node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant());
|
||||
}
|
||||
|
||||
struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser {
|
||||
bool visitAggregate(TVisit, TIntermAggregate* ag) override {
|
||||
using namespace std;
|
||||
TIntermSequence& seq = ag->getSequence();
|
||||
// remove pure sampler variables
|
||||
TIntermSequence::iterator newEnd = remove_if(seq.begin(), seq.end(), [](TIntermNode* node) {
|
||||
TIntermSymbol* symbol = node->getAsSymbolNode();
|
||||
if (!symbol)
|
||||
return false;
|
||||
|
||||
return (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler());
|
||||
});
|
||||
seq.erase(newEnd, seq.end());
|
||||
// replace constructors with sampler/textures
|
||||
// update textures into sampled textures
|
||||
for_each(seq.begin(), seq.end(), [](TIntermNode*& node) {
|
||||
TIntermSymbol* symbol = node->getAsSymbolNode();
|
||||
if (!symbol) {
|
||||
TIntermAggregate *constructor = node->getAsAggregate();
|
||||
if (constructor && constructor->getOp() == EOpConstructTextureSampler) {
|
||||
if (!constructor->getSequence().empty())
|
||||
node = constructor->getSequence()[0];
|
||||
}
|
||||
} else if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) {
|
||||
symbol->getWritableType().getSampler().combined = true;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void TIntermediate::performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root)
|
||||
{
|
||||
TextureUpgradeAndSamplerRemovalTransform transform;
|
||||
root->traverse(&transform);
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
||||
|
@ -1578,6 +1578,7 @@ void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslI
|
||||
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
|
||||
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
|
||||
void TShader::setResourceSetBinding(const std::vector<std::string>& base) { intermediate->setResourceSetBinding(base); }
|
||||
void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
|
||||
|
||||
//
|
||||
// Turn the shader strings into a parse tree in the TIntermediate.
|
||||
|
@ -182,7 +182,8 @@ public:
|
||||
useUnknownFormat(false),
|
||||
hlslOffsets(false),
|
||||
useStorageBuffer(false),
|
||||
hlslIoMapping(false)
|
||||
hlslIoMapping(false),
|
||||
textureSamplerTransformMode(EShTexSampTransKeep)
|
||||
{
|
||||
localSize[0] = 1;
|
||||
localSize[1] = 1;
|
||||
@ -233,6 +234,7 @@ public:
|
||||
bool usingStorageBuffer() const { return useStorageBuffer; }
|
||||
void setHlslIoMapping(bool b) { hlslIoMapping = b; }
|
||||
bool usingHlslIoMapping() { return hlslIoMapping; }
|
||||
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
|
||||
|
||||
void setVersion(int v) { version = v; }
|
||||
int getVersion() const { return version; }
|
||||
@ -472,6 +474,7 @@ protected:
|
||||
void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
|
||||
void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
|
||||
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
|
||||
void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
|
||||
|
||||
const EShLanguage language; // stage, known at construction time
|
||||
EShSource source; // source language, known a bit later
|
||||
@ -536,6 +539,8 @@ protected:
|
||||
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
||||
std::set<TString> semanticNameSet;
|
||||
|
||||
EShTextureSamplerTransformMode textureSamplerTransformMode;
|
||||
|
||||
private:
|
||||
void operator=(TIntermediate&); // prevent assignments
|
||||
};
|
||||
|
@ -134,6 +134,14 @@ typedef enum {
|
||||
EShOptFull, // Optimizations that will take more time
|
||||
} EShOptimizationLevel;
|
||||
|
||||
//
|
||||
// Texture and Sampler transformation mode.
|
||||
//
|
||||
typedef enum {
|
||||
EShTexSampTransKeep, // keep textures and samplers as is (default)
|
||||
EShTexSampTransUpgradeTextureRemoveSampler, // change texture w/o embeded sampler into sampled texture and throw away all samplers
|
||||
} EShTextureSamplerTransformMode;
|
||||
|
||||
//
|
||||
// Message choices for what errors and warnings are given.
|
||||
//
|
||||
@ -313,6 +321,7 @@ public:
|
||||
void setHlslIoMapping(bool hlslIoMap);
|
||||
void setFlattenUniformArrays(bool flatten);
|
||||
void setNoStorageFormat(bool useUnknownFormat);
|
||||
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
|
||||
|
||||
// Interface to #include handlers.
|
||||
//
|
||||
|
@ -75,6 +75,7 @@ using CompileVulkanToSpirvTestAMD = GlslangTest<::testing::TestWithParam<std::st
|
||||
#ifdef NV_EXTENSIONS
|
||||
using CompileVulkanToSpirvTestNV = GlslangTest<::testing::TestWithParam<std::string>>;
|
||||
#endif
|
||||
using CompileUpgradeTextureToSampledTextureAndDropSamplersTest = GlslangTest<::testing::TestWithParam<std::string>>;
|
||||
|
||||
// Compiling GLSL to SPIR-V under Vulkan semantics. Expected to successfully
|
||||
// generate SPIR-V.
|
||||
@ -172,6 +173,15 @@ TEST_P(CompileVulkanToSpirvTestNV, FromFile)
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_P(CompileUpgradeTextureToSampledTextureAndDropSamplersTest, FromFile)
|
||||
{
|
||||
loadCompileUpgradeTextureToSampledTextureAndDropSamplersAndCheck(GlobalTestSettings.testRoot,
|
||||
GetParam(),
|
||||
Source::GLSL,
|
||||
Semantics::Vulkan,
|
||||
Target::Spv);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
Glsl, CompileVulkanToSpirvTest,
|
||||
@ -407,6 +417,14 @@ INSTANTIATE_TEST_CASE_P(
|
||||
FileNameAsCustomTestSuffix
|
||||
);
|
||||
#endif
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
Glsl, CompileUpgradeTextureToSampledTextureAndDropSamplersTest,
|
||||
::testing::ValuesIn(std::vector<std::string>({
|
||||
"spv.texture.sampler.transform.frag",
|
||||
})),
|
||||
FileNameAsCustomTestSuffix
|
||||
);
|
||||
// clang-format on
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -197,12 +197,14 @@ public:
|
||||
GlslangResult compileAndLink(
|
||||
const std::string shaderName, const std::string& code,
|
||||
const std::string& entryPointName, EShMessages controls,
|
||||
bool flattenUniformArrays = false)
|
||||
bool flattenUniformArrays = false,
|
||||
EShTextureSamplerTransformMode texSampTransMode = EShTexSampTransKeep)
|
||||
{
|
||||
const EShLanguage kind = GetShaderStage(GetSuffix(shaderName));
|
||||
|
||||
glslang::TShader shader(kind);
|
||||
shader.setAutoMapLocations(true);
|
||||
shader.setTextureSamplerTransformMode(texSampTransMode);
|
||||
shader.setFlattenUniformArrays(flattenUniformArrays);
|
||||
|
||||
bool success = compile(&shader, code, entryPointName, controls);
|
||||
@ -570,6 +572,31 @@ public:
|
||||
expectedErrorFname);
|
||||
}
|
||||
|
||||
void loadCompileUpgradeTextureToSampledTextureAndDropSamplersAndCheck(const std::string& testDir,
|
||||
const std::string& testName,
|
||||
Source source,
|
||||
Semantics semantics,
|
||||
Target target,
|
||||
const std::string& entryPointName = "")
|
||||
{
|
||||
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 = compileAndLink(testName, input, entryPointName, controls, false, EShTexSampTransUpgradeTextureRemoveSampler);
|
||||
|
||||
// Generate the hybrid output in the way of glslangValidator.
|
||||
std::ostringstream stream;
|
||||
outputResultToStream(&stream, result, controls);
|
||||
|
||||
checkEqAndUpdateIfRequested(expectedOutput, stream.str(),
|
||||
expectedOutputFname);
|
||||
}
|
||||
|
||||
private:
|
||||
const int defaultVersion;
|
||||
const EProfile defaultProfile;
|
||||
|
Loading…
Reference in New Issue
Block a user