[glslang][EXT] Support extension ARB_bindless_texture.

Add missing callgraph clean for bindless status flag.

Add test cases. Add support to check special extensions not be available for Vulkan when using GLSL.
This commit is contained in:
Zhou 2022-11-16 00:04:55 +08:00 committed by ShchchowAMD
parent 2b2523fb95
commit 16526fd9d2
19 changed files with 608 additions and 35 deletions

View file

@ -225,6 +225,16 @@ enum ComputeDerivativeMode {
LayoutDerivativeGroupLinear, // derivative_group_linearNV
};
//
// Status type on AST level. Some uncalled status or functions would be reset in call graph.
// Currently we will keep status set by explicitly declared layout or variable decl.
//
enum AstRefType {
AstRefTypeVar, // Status set by variable decl
AstRefTypeFunc, // Status set by function decl
AstRefTypeLayout, // Status set by layout decl
};
class TIdMaps {
public:
TMap<TString, long long>& operator[](long long i) { return maps[i]; }
@ -744,6 +754,65 @@ public:
useVariablePointers = true;
processes.addProcess("use-variable-pointers");
}
// Set the global flag for bindless texture
void setBindlessTextureMode(const TString& currentCaller, AstRefType type)
{
// When type is not func, currentCaller should be "" (empty string)
bindlessTextureModeCaller[currentCaller] = type;
}
// Get the global flag for bindless texture
bool getBindlessTextureMode() const
{
return (bindlessTextureModeCaller.size() > 0);
}
// Set the global flag for bindless image
void setBindlessImageMode(const TString& currentCaller, AstRefType type)
{
// When type is not func, currentCaller should be "" (empty string)
bindlessImageModeCaller[currentCaller] = type;
}
// Get the global flag for bindless image
bool getBindlessImageMode() const
{
return (bindlessImageModeCaller.size() > 0);
}
// Get the global flag for bindless texture
bool resetTopLevelUncalledStatus(const TString& deadCaller)
{
// For reflection collection purpose, currently uniform layout setting and some
// flags introduced by variables (IO, global, etc,.) won't be reset here.
// Remove each global status (AST top level) introduced by uncalled functions.
// If a status is set by several functions, keep those which in call graph.
bool result = false;
// For two types of bindless mode flag, we would only reset which is set by an uncalled function.
// If one status flag's key in caller vec is empty, it should be come from a non-function setting.
if (!bindlessTextureModeCaller.empty()) {
auto caller = bindlessTextureModeCaller.find(deadCaller);
if (caller != bindlessTextureModeCaller.end() && bindlessTextureModeCaller[deadCaller] == AstRefTypeFunc) {
bindlessTextureModeCaller.erase(caller);
result = true;
}
}
if (!bindlessImageModeCaller.empty()) {
auto caller = bindlessImageModeCaller.find(deadCaller);
if (caller != bindlessImageModeCaller.end() && bindlessImageModeCaller[deadCaller] == AstRefTypeFunc) {
bindlessImageModeCaller.erase(caller);
result = true;
}
}
return result;
}
bool getBindlessMode() const
{
return getBindlessTextureMode() || getBindlessImageMode();
}
bool usingVariablePointers() const { return useVariablePointers; }
#ifdef ENABLE_HLSL
@ -1188,7 +1257,8 @@ protected:
TSpirvRequirement* spirvRequirement;
TSpirvExecutionMode* spirvExecutionMode;
std::map<TString, AstRefType> bindlessTextureModeCaller;
std::map<TString, AstRefType> bindlessImageModeCaller;
std::unordered_map<std::string, int> uniformLocationOverrides;
int uniformLocationBase;
TNumericFeatures numericFeatures;