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 TBasicType getBasicType() const { return basicType; }
|
||||||
virtual const TSampler& getSampler() const { return sampler; }
|
virtual const TSampler& getSampler() const { return sampler; }
|
||||||
|
virtual TSampler& getSampler() { return sampler; }
|
||||||
|
|
||||||
virtual TQualifier& getQualifier() { return qualifier; }
|
virtual TQualifier& getQualifier() { return qualifier; }
|
||||||
virtual const TQualifier& getQualifier() const { 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.
|
// Propagate 'noContraction' label in backward from 'precise' variables.
|
||||||
glslang::PropagateNoContraction(*this);
|
glslang::PropagateNoContraction(*this);
|
||||||
|
|
||||||
|
switch (textureSamplerTransformMode) {
|
||||||
|
case EShTexSampTransKeep:
|
||||||
|
break;
|
||||||
|
case EShTexSampTransUpgradeTextureRemoveSampler:
|
||||||
|
performTextureUpgradeAndSamplerRemovalTransformation(root);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2943,4 +2951,41 @@ bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TInt
|
|||||||
(node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant());
|
(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
|
} // end namespace glslang
|
||||||
|
@ -1578,6 +1578,7 @@ void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslI
|
|||||||
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
|
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
|
||||||
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
|
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
|
||||||
void TShader::setResourceSetBinding(const std::vector<std::string>& base) { intermediate->setResourceSetBinding(base); }
|
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.
|
// Turn the shader strings into a parse tree in the TIntermediate.
|
||||||
|
@ -182,7 +182,8 @@ public:
|
|||||||
useUnknownFormat(false),
|
useUnknownFormat(false),
|
||||||
hlslOffsets(false),
|
hlslOffsets(false),
|
||||||
useStorageBuffer(false),
|
useStorageBuffer(false),
|
||||||
hlslIoMapping(false)
|
hlslIoMapping(false),
|
||||||
|
textureSamplerTransformMode(EShTexSampTransKeep)
|
||||||
{
|
{
|
||||||
localSize[0] = 1;
|
localSize[0] = 1;
|
||||||
localSize[1] = 1;
|
localSize[1] = 1;
|
||||||
@ -233,6 +234,7 @@ public:
|
|||||||
bool usingStorageBuffer() const { return useStorageBuffer; }
|
bool usingStorageBuffer() const { return useStorageBuffer; }
|
||||||
void setHlslIoMapping(bool b) { hlslIoMapping = b; }
|
void setHlslIoMapping(bool b) { hlslIoMapping = b; }
|
||||||
bool usingHlslIoMapping() { return hlslIoMapping; }
|
bool usingHlslIoMapping() { return hlslIoMapping; }
|
||||||
|
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
|
||||||
|
|
||||||
void setVersion(int v) { version = v; }
|
void setVersion(int v) { version = v; }
|
||||||
int getVersion() const { return version; }
|
int getVersion() const { return version; }
|
||||||
@ -472,6 +474,7 @@ protected:
|
|||||||
void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
|
void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
|
||||||
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);
|
||||||
|
|
||||||
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
|
||||||
@ -536,6 +539,8 @@ protected:
|
|||||||
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
||||||
std::set<TString> semanticNameSet;
|
std::set<TString> semanticNameSet;
|
||||||
|
|
||||||
|
EShTextureSamplerTransformMode textureSamplerTransformMode;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void operator=(TIntermediate&); // prevent assignments
|
void operator=(TIntermediate&); // prevent assignments
|
||||||
};
|
};
|
||||||
|
@ -134,6 +134,14 @@ typedef enum {
|
|||||||
EShOptFull, // Optimizations that will take more time
|
EShOptFull, // Optimizations that will take more time
|
||||||
} EShOptimizationLevel;
|
} 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.
|
// Message choices for what errors and warnings are given.
|
||||||
//
|
//
|
||||||
@ -313,6 +321,7 @@ public:
|
|||||||
void setHlslIoMapping(bool hlslIoMap);
|
void setHlslIoMapping(bool hlslIoMap);
|
||||||
void setFlattenUniformArrays(bool flatten);
|
void setFlattenUniformArrays(bool flatten);
|
||||||
void setNoStorageFormat(bool useUnknownFormat);
|
void setNoStorageFormat(bool useUnknownFormat);
|
||||||
|
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
|
||||||
|
|
||||||
// Interface to #include handlers.
|
// Interface to #include handlers.
|
||||||
//
|
//
|
||||||
|
@ -75,6 +75,7 @@ using CompileVulkanToSpirvTestAMD = GlslangTest<::testing::TestWithParam<std::st
|
|||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
using CompileVulkanToSpirvTestNV = GlslangTest<::testing::TestWithParam<std::string>>;
|
using CompileVulkanToSpirvTestNV = GlslangTest<::testing::TestWithParam<std::string>>;
|
||||||
#endif
|
#endif
|
||||||
|
using CompileUpgradeTextureToSampledTextureAndDropSamplersTest = GlslangTest<::testing::TestWithParam<std::string>>;
|
||||||
|
|
||||||
// Compiling GLSL to SPIR-V under Vulkan semantics. Expected to successfully
|
// Compiling GLSL to SPIR-V under Vulkan semantics. Expected to successfully
|
||||||
// generate SPIR-V.
|
// generate SPIR-V.
|
||||||
@ -172,6 +173,15 @@ TEST_P(CompileVulkanToSpirvTestNV, FromFile)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
TEST_P(CompileUpgradeTextureToSampledTextureAndDropSamplersTest, FromFile)
|
||||||
|
{
|
||||||
|
loadCompileUpgradeTextureToSampledTextureAndDropSamplersAndCheck(GlobalTestSettings.testRoot,
|
||||||
|
GetParam(),
|
||||||
|
Source::GLSL,
|
||||||
|
Semantics::Vulkan,
|
||||||
|
Target::Spv);
|
||||||
|
}
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
Glsl, CompileVulkanToSpirvTest,
|
Glsl, CompileVulkanToSpirvTest,
|
||||||
@ -407,6 +417,14 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
FileNameAsCustomTestSuffix
|
FileNameAsCustomTestSuffix
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
Glsl, CompileUpgradeTextureToSampledTextureAndDropSamplersTest,
|
||||||
|
::testing::ValuesIn(std::vector<std::string>({
|
||||||
|
"spv.texture.sampler.transform.frag",
|
||||||
|
})),
|
||||||
|
FileNameAsCustomTestSuffix
|
||||||
|
);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
@ -197,12 +197,14 @@ public:
|
|||||||
GlslangResult compileAndLink(
|
GlslangResult compileAndLink(
|
||||||
const std::string shaderName, const std::string& code,
|
const std::string shaderName, const std::string& code,
|
||||||
const std::string& entryPointName, EShMessages controls,
|
const std::string& entryPointName, EShMessages controls,
|
||||||
bool flattenUniformArrays = false)
|
bool flattenUniformArrays = false,
|
||||||
|
EShTextureSamplerTransformMode texSampTransMode = EShTexSampTransKeep)
|
||||||
{
|
{
|
||||||
const EShLanguage kind = GetShaderStage(GetSuffix(shaderName));
|
const EShLanguage kind = GetShaderStage(GetSuffix(shaderName));
|
||||||
|
|
||||||
glslang::TShader shader(kind);
|
glslang::TShader shader(kind);
|
||||||
shader.setAutoMapLocations(true);
|
shader.setAutoMapLocations(true);
|
||||||
|
shader.setTextureSamplerTransformMode(texSampTransMode);
|
||||||
shader.setFlattenUniformArrays(flattenUniformArrays);
|
shader.setFlattenUniformArrays(flattenUniformArrays);
|
||||||
|
|
||||||
bool success = compile(&shader, code, entryPointName, controls);
|
bool success = compile(&shader, code, entryPointName, controls);
|
||||||
@ -570,6 +572,31 @@ public:
|
|||||||
expectedErrorFname);
|
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:
|
private:
|
||||||
const int defaultVersion;
|
const int defaultVersion;
|
||||||
const EProfile defaultProfile;
|
const EProfile defaultProfile;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user