HLSL: split textures used for both shadow and non-shadow modes
A single texture can statically appear in code mixed with a shadow sampler and a non-shadow sampler. This would be create invalid SPIR-V, unless one of them is provably dead. The previous detection of this happened before DCE, so some shaders would trigger the error even though they wouldn't after DCE. To handle that case, this PR splits the texture into two: one with each mode. It sets "needsLegalization" (if that happens for any texture) to warn that this shader will need post-compilation legalization. If the texture is only used with one of the two modes, behavior is as it was before.
This commit is contained in:
@@ -457,10 +457,29 @@ protected:
|
||||
|
||||
TVector<tMipsOperatorData> mipsOperatorMipArg;
|
||||
|
||||
// This can be removed if and when the texture shadow workarounnd in
|
||||
// HlslParseContext::handleSamplerTextureCombine is removed. It maps
|
||||
// texture symbol IDs to the shadow modes of samplers they were combined with.
|
||||
TMap<int, bool> textureShadowMode;
|
||||
// A texture object may be used with shadow and non-shadow samplers, but both may not be
|
||||
// alive post-DCE in the same shader. We do not know at compilation time which are alive: that's
|
||||
// only known post-DCE. If a texture is used both ways, we create two textures, and
|
||||
// leave the elimiation of one to the optimizer. This maps the shader variant to
|
||||
// the shadow variant.
|
||||
//
|
||||
// This can be removed if and when the texture shadow code in
|
||||
// HlslParseContext::handleSamplerTextureCombine is removed.
|
||||
struct tShadowTextureSymbols {
|
||||
tShadowTextureSymbols() { symId.fill(-1); }
|
||||
|
||||
void set(bool shadow, int id) { symId[int(shadow)] = id; }
|
||||
int get(bool shadow) const { return symId[int(shadow)]; }
|
||||
|
||||
// True if this texture has been seen with both shadow and non-shadow modes
|
||||
bool overloaded() const { return symId[0] != -1 && symId[1] != -1; }
|
||||
bool isShadowId(int id) const { return symId[1] == id; }
|
||||
|
||||
private:
|
||||
std::array<int, 2> symId;
|
||||
};
|
||||
|
||||
TMap<int, tShadowTextureSymbols*> textureShadowVariant;
|
||||
};
|
||||
|
||||
// This is the prefix we use for built-in methods to avoid namespace collisions with
|
||||
|
||||
Reference in New Issue
Block a user