Browse Source

More seperate image samplers

Panagiotis Christopoulos Charitos 6 years ago
parent
commit
cb0d3705c3

+ 15 - 8
shaders/ApplyIrradianceToReflection.glslp

@@ -14,27 +14,34 @@ layout(location = 0) in Vec2 in_uv;
 
 
 layout(location = 0) out Vec3 out_color;
 layout(location = 0) out Vec3 out_color;
 
 
-layout(set = 0, binding = 0) uniform sampler2D u_gbufferTex0;
-layout(set = 0, binding = 1) uniform sampler2D u_gbufferTex1;
-layout(set = 0, binding = 2) uniform sampler2D u_gbufferTex2;
+layout(set = 0, binding = 0) uniform sampler u_nearestAnyClampSampler;
+layout(set = 0, binding = 1) uniform sampler u_linearAnyClampSampler;
 
 
-layout(set = 0, binding = 3) uniform samplerCubeArray u_irradianceTex;
+layout(set = 0, binding = 2) uniform texture2D u_gbufferTex0;
+layout(set = 0, binding = 3) uniform texture2D u_gbufferTex1;
+layout(set = 0, binding = 4) uniform texture2D u_gbufferTex2;
 
 
-ANKI_PUSH_CONSTANTS(Vec4, u_faceIdxPad3);
+layout(set = 0, binding = 5) uniform textureCubeArray u_irradianceTex;
+
+layout(push_constant, std430) uniform pc_
+{
+	Vec3 u_padding;
+	F32 u_faceIdx;
+};
 
 
 void main()
 void main()
 {
 {
 	// Compute the UVs to read the gbuffer from
 	// Compute the UVs to read the gbuffer from
 	Vec2 sampleUv = in_uv;
 	Vec2 sampleUv = in_uv;
 	sampleUv.x *= (1.0 / 6.0);
 	sampleUv.x *= (1.0 / 6.0);
-	sampleUv.x += (1.0 / 6.0) * u_faceIdxPad3.x;
+	sampleUv.x += (1.0 / 6.0) * u_faceIdx;
 
 
 	// Read the gbuffer
 	// Read the gbuffer
 	GbufferInfo gbuffer;
 	GbufferInfo gbuffer;
-	readGBuffer(u_gbufferTex0, u_gbufferTex1, u_gbufferTex2, sampleUv, 0.0, gbuffer);
+	readGBuffer(u_gbufferTex0, u_gbufferTex1, u_gbufferTex2, u_nearestAnyClampSampler, sampleUv, 0.0, gbuffer);
 
 
 	// Read the irradiance. Use the layer 0 because C++ will set the appropriate texture view
 	// Read the irradiance. Use the layer 0 because C++ will set the appropriate texture view
-	const Vec3 irradiance = textureLod(u_irradianceTex, Vec4(gbuffer.m_normal, 0.0), 0.0).rgb;
+	const Vec3 irradiance = textureLod(u_irradianceTex, u_linearAnyClampSampler, Vec4(gbuffer.m_normal, 0.0), 0.0).rgb;
 
 
 	// Compute the indirect term
 	// Compute the indirect term
 	const Vec3 indirect = gbuffer.m_diffuse * irradiance;
 	const Vec3 indirect = gbuffer.m_diffuse * irradiance;

+ 5 - 5
shaders/Bloom.glslp

@@ -37,11 +37,11 @@ void main()
 
 
 	const Vec2 uv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(FB_SIZE);
 	const Vec2 uv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(FB_SIZE);
 
 
-	Vec3 color = textureLod(combineImageSampler(u_tex, u_linearAnyClampSampler), uv, 0.0).rgb;
-	color += textureLodOffset(combineImageSampler(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(+1, +1)).rgb;
-	color += textureLodOffset(combineImageSampler(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(-1, -1)).rgb;
-	color += textureLodOffset(combineImageSampler(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(-1, +1)).rgb;
-	color += textureLodOffset(combineImageSampler(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(+1, -1)).rgb;
+	Vec3 color = textureLod(u_tex, u_linearAnyClampSampler, uv, 0.0).rgb;
+	color += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(+1, +1)).rgb;
+	color += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(-1, -1)).rgb;
+	color += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(-1, +1)).rgb;
+	color += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(+1, -1)).rgb;
 
 
 	color *= (1.0 / 5.0);
 	color *= (1.0 / 5.0);
 
 

+ 9 - 9
shaders/BloomUpscale.glslp

@@ -34,9 +34,9 @@ Vec3 textureDistorted(texture2D tex,
 	Vec3 DISTORTION) // per-channel DISTORTION factor
 	Vec3 DISTORTION) // per-channel DISTORTION factor
 {
 {
 #if ENABLE_CHROMATIC_DISTORTION
 #if ENABLE_CHROMATIC_DISTORTION
-	return Vec3(textureLod(combineImageSampler(tex, sampl), uv + direction * DISTORTION.r, 0.0).r,
-		textureLod(combineImageSampler(tex, sampl), uv + direction * DISTORTION.g, 0.0).g,
-		textureLod(combineImageSampler(tex, sampl), uv + direction * DISTORTION.b, 0.0).b);
+	return Vec3(textureLod(tex, sampl, uv + direction * DISTORTION.r, 0.0).r,
+		textureLod(tex, sampl, uv + direction * DISTORTION.g, 0.0).g,
+		textureLod(tex, sampl, uv + direction * DISTORTION.b, 0.0).b);
 #else
 #else
 	return textureLod(tex, uv, 0.0).rgb;
 	return textureLod(tex, uv, 0.0).rgb;
 #endif
 #endif
@@ -76,18 +76,18 @@ Vec3 ssLensFlare(Vec2 uv)
 #endif
 #endif
 
 
 	// Lens dirt
 	// Lens dirt
-	result *= textureLod(combineImageSampler(u_lensDirtTex, u_linearAnyClampSampler), uv, 0.0).rgb;
+	result *= textureLod(u_lensDirtTex, u_linearAnyClampSampler, uv, 0.0).rgb;
 
 
 	return result;
 	return result;
 }
 }
 
 
 Vec3 upscale(Vec2 uv)
 Vec3 upscale(Vec2 uv)
 {
 {
-	Vec3 result = textureLod(combineImageSampler(u_tex, u_linearAnyClampSampler), uv, 0.0).rgb;
-	result += textureLodOffset(combineImageSampler(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(+1, +1)).rgb;
-	result += textureLodOffset(combineImageSampler(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(+1, -1)).rgb;
-	result += textureLodOffset(combineImageSampler(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(-1, -1)).rgb;
-	result += textureLodOffset(combineImageSampler(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(-1, +1)).rgb;
+	Vec3 result = textureLod(u_tex, u_linearAnyClampSampler, uv, 0.0).rgb;
+	result += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(+1, +1)).rgb;
+	result += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(+1, -1)).rgb;
+	result += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(-1, -1)).rgb;
+	result += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), uv, 0.0, ivec2(-1, +1)).rgb;
 
 
 	result *= (1.0 / 5.0);
 	result *= (1.0 / 5.0);
 	return result;
 	return result;

+ 7 - 7
shaders/ClusteredShadingCommon.glsl

@@ -54,7 +54,7 @@ layout(set = LIGHT_SET, binding = LIGHT_LIGHTS_BINDING + 1, std140, row_major) u
 	SpotLight u_spotLights[UBO_MAX_SIZE / SIZEOF_SPOT_LIGHT];
 	SpotLight u_spotLights[UBO_MAX_SIZE / SIZEOF_SPOT_LIGHT];
 };
 };
 
 
-layout(set = LIGHT_SET, binding = LIGHT_LIGHTS_BINDING + 2) uniform highp sampler2D u_shadowTex;
+layout(set = LIGHT_SET, binding = LIGHT_LIGHTS_BINDING + 2) uniform highp texture2D u_shadowTex;
 #endif
 #endif
 
 
 //
 //
@@ -66,13 +66,13 @@ layout(std140, row_major, set = LIGHT_SET, binding = LIGHT_INDIRECT_BINDING) uni
 	ReflectionProbe u_reflectionProbes[UBO_MAX_SIZE / SIZEOF_REFLECTION_PROBE];
 	ReflectionProbe u_reflectionProbes[UBO_MAX_SIZE / SIZEOF_REFLECTION_PROBE];
 };
 };
 
 
-layout(set = LIGHT_SET, binding = LIGHT_INDIRECT_BINDING + 1) uniform samplerCubeArray u_reflectionsTex;
-layout(set = LIGHT_SET, binding = LIGHT_INDIRECT_BINDING + 2) uniform samplerCubeArray u_irradianceTex;
-layout(set = LIGHT_SET, binding = LIGHT_INDIRECT_BINDING + 3) uniform sampler2D u_integrationLut;
+layout(set = LIGHT_SET, binding = LIGHT_INDIRECT_BINDING + 1) uniform textureCubeArray u_reflectionsTex;
+layout(set = LIGHT_SET, binding = LIGHT_INDIRECT_BINDING + 2) uniform textureCubeArray u_irradianceTex;
+layout(set = LIGHT_SET, binding = LIGHT_INDIRECT_BINDING + 3) uniform texture2D u_integrationLut;
 #endif
 #endif
 
 
 //
 //
-// Decal uniforms
+// Decal uniforms (3)
 //
 //
 #if defined(LIGHT_DECALS_BINDING)
 #if defined(LIGHT_DECALS_BINDING)
 layout(std140, row_major, set = LIGHT_SET, binding = LIGHT_DECALS_BINDING) uniform u4_
 layout(std140, row_major, set = LIGHT_SET, binding = LIGHT_DECALS_BINDING) uniform u4_
@@ -80,8 +80,8 @@ layout(std140, row_major, set = LIGHT_SET, binding = LIGHT_DECALS_BINDING) unifo
 	Decal u_decals[UBO_MAX_SIZE / SIZEOF_DECAL];
 	Decal u_decals[UBO_MAX_SIZE / SIZEOF_DECAL];
 };
 };
 
 
-layout(set = LIGHT_SET, binding = LIGHT_DECALS_BINDING + 1) uniform sampler2D u_diffDecalTex;
-layout(set = LIGHT_SET, binding = LIGHT_DECALS_BINDING + 2) uniform sampler2D u_specularRoughnessDecalTex;
+layout(set = LIGHT_SET, binding = LIGHT_DECALS_BINDING + 1) uniform texture2D u_diffDecalTex;
+layout(set = LIGHT_SET, binding = LIGHT_DECALS_BINDING + 2) uniform texture2D u_specularRoughnessDecalTex;
 #endif
 #endif
 
 
 //
 //

+ 2 - 31
shaders/Common.glsl

@@ -7,6 +7,8 @@
 
 
 #pragma once
 #pragma once
 
 
+#include <shaders/TextureFunctions.glsl>
+
 // WORKAROUNDS
 // WORKAROUNDS
 #if defined(ANKI_VENDOR_NVIDIA)
 #if defined(ANKI_VENDOR_NVIDIA)
 #	define NVIDIA_LINK_ERROR_WORKAROUND 1
 #	define NVIDIA_LINK_ERROR_WORKAROUND 1
@@ -73,34 +75,3 @@ const U32 UBO_MAX_SIZE = 16384u;
 #endif
 #endif
 
 
 #define CALC_BITANGENT_IN_VERT 1
 #define CALC_BITANGENT_IN_VERT 1
-
-// Convenience functions to combine image and samplers
-sampler2D combineImageSampler(texture2D tex, sampler sampl)
-{
-	return sampler2D(tex, sampl);
-}
-
-sampler3D combineImageSampler(texture3D tex, sampler sampl)
-{
-	return sampler3D(tex, sampl);
-}
-
-samplerCube combineImageSampler(textureCube tex, sampler sampl)
-{
-	return samplerCube(tex, sampl);
-}
-
-sampler2DArray combineImageSampler(texture2DArray tex, sampler sampl)
-{
-	return sampler2DArray(tex, sampl);
-}
-
-samplerCubeArray combineImageSampler(textureCubeArray tex, sampler sampl)
-{
-	return samplerCubeArray(tex, sampl);
-}
-
-sampler2DShadow combineImageSampler(texture2D tex, samplerShadow sampl)
-{
-	return sampler2DShadow(tex, sampl);
-}

+ 1 - 1
shaders/DepthDownscale.glslp

@@ -59,7 +59,7 @@ void main()
 {
 {
 	// Read depth
 	// Read depth
 	const Vec2 readUv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(u_level0WriteImgSize);
 	const Vec2 readUv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(u_level0WriteImgSize);
-	Vec4 depths = textureGather(combineImageSampler(u_readTex, u_nearestAnyClampSampler), readUv, 0);
+	Vec4 depths = textureGather(sampler2D(u_readTex, u_nearestAnyClampSampler), readUv, 0);
 
 
 	// Resolve & store the 1st level
 	// Resolve & store the 1st level
 	F32 depth = resolveDepths(depths);
 	F32 depth = resolveDepths(depths);

+ 5 - 5
shaders/DownscaleBlur.glsl

@@ -38,11 +38,11 @@ void main()
 	}
 	}
 #endif
 #endif
 
 
-	out_color = textureLod(combineImageSampler(u_tex, u_linearAnyClampSampler), in_uv, 0.0).rgb;
-	out_color += textureLodOffset(combineImageSampler(u_tex, u_linearAnyClampSampler), in_uv, 0.0, IVec2(+1, +1)).rgb;
-	out_color += textureLodOffset(combineImageSampler(u_tex, u_linearAnyClampSampler), in_uv, 0.0, IVec2(-1, -1)).rgb;
-	out_color += textureLodOffset(combineImageSampler(u_tex, u_linearAnyClampSampler), in_uv, 0.0, IVec2(+1, -1)).rgb;
-	out_color += textureLodOffset(combineImageSampler(u_tex, u_linearAnyClampSampler), in_uv, 0.0, IVec2(-1, +1)).rgb;
+	out_color = textureLod(u_tex, u_linearAnyClampSampler, in_uv, 0.0).rgb;
+	out_color += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), in_uv, 0.0, IVec2(+1, +1)).rgb;
+	out_color += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), in_uv, 0.0, IVec2(-1, -1)).rgb;
+	out_color += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), in_uv, 0.0, IVec2(+1, -1)).rgb;
+	out_color += textureLodOffset(sampler2D(u_tex, u_linearAnyClampSampler), in_uv, 0.0, IVec2(-1, +1)).rgb;
 
 
 	out_color *= (1.0 / 5.0);
 	out_color *= (1.0 / 5.0);
 
 

+ 6 - 6
shaders/FinalComposite.glslp

@@ -55,7 +55,7 @@ Vec3 colorGrading(Vec3 color)
 
 
 	color = min(color, Vec3(1.0));
 	color = min(color, Vec3(1.0));
 	const Vec3 lutCoords = color * LUT_SCALE + LUT_OFFSET;
 	const Vec3 lutCoords = color * LUT_SCALE + LUT_OFFSET;
-	return textureLod(combineImageSampler(u_lut, u_trilinearRepeatSampler), lutCoords, 0.0).rgb;
+	return textureLod(u_lut, u_trilinearRepeatSampler, lutCoords, 0.0).rgb;
 }
 }
 
 
 void main()
 void main()
@@ -76,13 +76,13 @@ void main()
 	}
 	}
 	else
 	else
 	{
 	{
-		out_color = textureLod(combineImageSampler(u_lightShadingRt, u_linearAnyClampSampler), uv, 0.0).rgb;
+		out_color = textureLod(u_lightShadingRt, u_linearAnyClampSampler, uv, 0.0).rgb;
 	}
 	}
 
 
 	out_color = tonemap(out_color, u_exposureThreshold0);
 	out_color = tonemap(out_color, u_exposureThreshold0);
 
 
 #if BLOOM_ENABLED
 #if BLOOM_ENABLED
-	const Vec3 bloom = textureLod(combineImageSampler(u_ppsBloomLfRt, u_linearAnyClampSampler), uv, 0.0).rgb;
+	const Vec3 bloom = textureLod(u_ppsBloomLfRt, u_linearAnyClampSampler, uv, 0.0).rgb;
 	out_color += bloom;
 	out_color += bloom;
 #endif
 #endif
 
 
@@ -90,7 +90,7 @@ void main()
 
 
 #if BLUE_NOISE
 #if BLUE_NOISE
 	const Vec3 bnUvw = Vec3(FB_SIZE / Vec2(64.0) * uv, u_blueNoiseLayerPad3.x);
 	const Vec3 bnUvw = Vec3(FB_SIZE / Vec2(64.0) * uv, u_blueNoiseLayerPad3.x);
-	Vec3 blueNoise = textureLod(combineImageSampler(u_blueNoise, u_trilinearRepeatSampler), bnUvw, 0.0).rgb;
+	Vec3 blueNoise = textureLod(u_blueNoise, u_trilinearRepeatSampler, bnUvw, 0.0).rgb;
 	blueNoise = blueNoise * 2.0 - 1.0;
 	blueNoise = blueNoise * 2.0 - 1.0;
 	blueNoise = sign(blueNoise) * (1.0 - sqrt(1.0 - abs(blueNoise)));
 	blueNoise = sign(blueNoise) * (1.0 - sqrt(1.0 - abs(blueNoise)));
 
 
@@ -99,12 +99,12 @@ void main()
 
 
 #if 0
 #if 0
 	{
 	{
-		out_color = textureLod(combineImageSampler(u_lightShadingRt, u_linearAnyClampSampler), uv, 0.0).rgb;
+		out_color = textureLod(u_lightShadingRt, u_linearAnyClampSampler, uv, 0.0).rgb;
 	}
 	}
 #endif
 #endif
 
 
 #if DBG_ENABLED
 #if DBG_ENABLED
-	out_color += textureLod(combineImageSampler(u_dbgRt, u_linearAnyClampSampler), uv, 0.0).rgb;
+	out_color += textureLod(u_dbgRt, u_linearAnyClampSampler, uv, 0.0).rgb;
 #endif
 #endif
 }
 }
 
 

+ 10 - 9
shaders/ForwardShadingCommonFrag.glsl

@@ -10,12 +10,13 @@
 #include <shaders/Functions.glsl>
 #include <shaders/Functions.glsl>
 
 
 // Global resources
 // Global resources
-layout(set = 0, binding = 0) uniform sampler2D u_gbufferDepthRt;
-layout(set = 0, binding = 1) uniform sampler3D u_lightVol;
+layout(set = 0, binding = 0) uniform sampler u_linearAnyClampSampler;
+layout(set = 0, binding = 1) uniform texture2D u_gbufferDepthRt;
+layout(set = 0, binding = 2) uniform texture3D u_lightVol;
 #define LIGHT_SET 0
 #define LIGHT_SET 0
-#define LIGHT_COMMON_UNIS_BINDING 2
-#define LIGHT_LIGHTS_BINDING 3
-#define LIGHT_CLUSTERS_BINDING 6
+#define LIGHT_COMMON_UNIS_BINDING 3
+#define LIGHT_LIGHTS_BINDING 4
+#define LIGHT_CLUSTERS_BINDING 7
 #include <shaders/ClusteredShadingCommon.glsl>
 #include <shaders/ClusteredShadingCommon.glsl>
 
 
 #define anki_u_time u_time
 #define anki_u_time u_time
@@ -64,7 +65,7 @@ Vec3 computeLightColorHigh(Vec3 diffCol, Vec3 worldPos)
 		F32 shadow = 1.0;
 		F32 shadow = 1.0;
 		if(light.m_shadowAtlasTileScale >= 0.0)
 		if(light.m_shadowAtlasTileScale >= 0.0)
 		{
 		{
-			shadow = computeShadowFactorPointLight(light, frag2Light, u_shadowTex);
+			shadow = computeShadowFactorPointLight(light, frag2Light, u_shadowTex, u_linearAnyClampSampler);
 		}
 		}
 #endif
 #endif
 
 
@@ -92,7 +93,7 @@ Vec3 computeLightColorHigh(Vec3 diffCol, Vec3 worldPos)
 		const F32 shadowmapLayerIdx = light.m_shadowmapId;
 		const F32 shadowmapLayerIdx = light.m_shadowmapId;
 		if(shadowmapLayerIdx >= 0.0)
 		if(shadowmapLayerIdx >= 0.0)
 		{
 		{
-			shadow = computeShadowFactorSpotLight(light, worldPos, u_shadowTex);
+			shadow = computeShadowFactorSpotLight(light, worldPos, u_shadowTex, u_linearAnyClampSampler);
 		}
 		}
 #endif
 #endif
 
 
@@ -108,7 +109,7 @@ Vec3 computeLightColorLow(Vec3 diffCol, Vec3 worldPos)
 	const Vec2 uv = gl_FragCoord.xy / RENDERER_SIZE;
 	const Vec2 uv = gl_FragCoord.xy / RENDERER_SIZE;
 	const Vec3 uv3d = computeClustererVolumeTextureUvs(u_clustererMagic, uv, worldPos, u_lightVolumeLastCluster + 1u);
 	const Vec3 uv3d = computeClustererVolumeTextureUvs(u_clustererMagic, uv, worldPos, u_lightVolumeLastCluster + 1u);
 
 
-	const Vec3 light = textureLod(u_lightVol, uv3d, 0.0).rgb;
+	const Vec3 light = textureLod(u_lightVol, u_linearAnyClampSampler, uv3d, 0.0).rgb;
 	return diffuseLambert(diffCol) * light;
 	return diffuseLambert(diffCol) * light;
 }
 }
 
 
@@ -122,7 +123,7 @@ void fog(Vec3 color, F32 fogAlphaScale, F32 fogDistanceOfMaxThikness, F32 zVSpac
 	const Vec2 screenSize = 1.0 / RENDERER_SIZE;
 	const Vec2 screenSize = 1.0 / RENDERER_SIZE;
 
 
 	const Vec2 texCoords = gl_FragCoord.xy * screenSize;
 	const Vec2 texCoords = gl_FragCoord.xy * screenSize;
-	const F32 depth = texture(u_gbufferDepthRt, texCoords).r;
+	const F32 depth = textureLod(u_gbufferDepthRt, u_linearAnyClampSampler, texCoords, 0.0).r;
 	F32 zFeatherFactor;
 	F32 zFeatherFactor;
 
 
 	const Vec4 fragPosVspace4 = u_invProjMat * Vec4(Vec3(UV_TO_NDC(texCoords), depth), 1.0);
 	const Vec4 fragPosVspace4 = u_invProjMat * Vec4(Vec3(UV_TO_NDC(texCoords), depth), 1.0);

+ 3 - 3
shaders/ForwardShadingCommonVert.glsl

@@ -10,9 +10,9 @@
 
 
 // Global resources
 // Global resources
 #define LIGHT_SET 0
 #define LIGHT_SET 0
-#define LIGHT_COMMON_UNIS_BINDING 2
-#define LIGHT_LIGHTS_BINDING 3
-#define LIGHT_CLUSTERS_BINDING 6
+#define LIGHT_COMMON_UNIS_BINDING 3
+#define LIGHT_LIGHTS_BINDING 4
+#define LIGHT_CLUSTERS_BINDING 7
 #include <shaders/ClusteredShadingCommon.glsl>
 #include <shaders/ClusteredShadingCommon.glsl>
 
 
 // In/out
 // In/out

+ 9 - 7
shaders/GBufferPost.glslp

@@ -32,12 +32,14 @@ void main()
 #include <shaders/Pack.glsl>
 #include <shaders/Pack.glsl>
 #include <shaders/Functions.glsl>
 #include <shaders/Functions.glsl>
 
 
-layout(set = 0, binding = 0) uniform sampler2D u_msDepthRt;
+layout(set = 0, binding = 0) uniform sampler u_nearestAnyClampSampler;
+layout(set = 0, binding = 1) uniform texture2D u_msDepthRt;
 
 
+layout(set = 0, binding = 2) uniform sampler u_trilinearRepeatSampler;
 #define LIGHT_SET 0
 #define LIGHT_SET 0
-#define LIGHT_COMMON_UNIS_BINDING 1
-#define LIGHT_DECALS_BINDING 2
-#define LIGHT_CLUSTERS_BINDING 5
+#define LIGHT_COMMON_UNIS_BINDING 3
+#define LIGHT_DECALS_BINDING 4
+#define LIGHT_CLUSTERS_BINDING 7
 #include <shaders/ClusteredShadingCommon.glsl>
 #include <shaders/ClusteredShadingCommon.glsl>
 
 
 layout(location = 0) in Vec2 in_uv;
 layout(location = 0) in Vec2 in_uv;
@@ -59,7 +61,7 @@ void main()
 	Vec4 outSpecular = Vec4(0.0, 0.0, 0.0, 1.0);
 	Vec4 outSpecular = Vec4(0.0, 0.0, 0.0, 1.0);
 
 
 	// Get worldPos
 	// Get worldPos
-	const F32 depth = textureLod(u_msDepthRt, in_uv, 0.0).r;
+	const F32 depth = textureLod(u_msDepthRt, u_nearestAnyClampSampler, in_uv, 0.0).r;
 	const Vec2 ndc = UV_TO_NDC(in_uv);
 	const Vec2 ndc = UV_TO_NDC(in_uv);
 	const Vec4 worldPos4 = u_invViewProjMat * Vec4(ndc, depth, 1.0);
 	const Vec4 worldPos4 = u_invViewProjMat * Vec4(ndc, depth, 1.0);
 	const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
 	const Vec3 worldPos = worldPos4.xyz / worldPos4.w;
@@ -101,11 +103,11 @@ void main()
 
 
 		// Read diffuse
 		// Read diffuse
 		const Vec2 diffUv = mad(texCoords2, decal.m_diffUv.zw, decal.m_diffUv.xy);
 		const Vec2 diffUv = mad(texCoords2, decal.m_diffUv.zw, decal.m_diffUv.xy);
-		const Vec4 decalDiff = texture(u_diffDecalTex, diffUv);
+		const Vec4 decalDiff = texture(u_diffDecalTex, u_trilinearRepeatSampler, diffUv);
 
 
 		// Read roughness
 		// Read roughness
 		const Vec2 specUv = mad(texCoords2, decal.m_normRoughnessUv.zw, decal.m_normRoughnessUv.xy);
 		const Vec2 specUv = mad(texCoords2, decal.m_normRoughnessUv.zw, decal.m_normRoughnessUv.xy);
-		const Vec3 spec = texture(u_specularRoughnessDecalTex, specUv).rgb;
+		const Vec3 spec = texture(u_specularRoughnessDecalTex, u_trilinearRepeatSampler, specUv).rgb;
 
 
 		// Update diffuse
 		// Update diffuse
 		F32 f = decalDiff.a * decal.m_blendFactors[0];
 		F32 f = decalDiff.a * decal.m_blendFactors[0];

+ 12 - 10
shaders/LightFunctions.glsl

@@ -51,11 +51,11 @@ F32 V_Schlick(F32 roughness, F32 NoV, F32 NoL)
 	return 0.25 / (Vis_SchlickV * Vis_SchlickL);
 	return 0.25 / (Vis_SchlickV * Vis_SchlickL);
 }
 }
 
 
-Vec3 envBRDF(Vec3 specular, F32 roughness, sampler2D integrationLut, F32 NoV)
+Vec3 envBRDF(Vec3 specular, F32 roughness, texture2D integrationLut, sampler integrationLutSampler, F32 NoV)
 {
 {
 	const F32 a = roughness * roughness;
 	const F32 a = roughness * roughness;
 	const F32 a2 = a * a;
 	const F32 a2 = a * a;
-	const Vec2 envBRDF = textureLod(integrationLut, Vec2(a2, NoV), 0.0).xy;
+	const Vec2 envBRDF = textureLod(integrationLut, integrationLutSampler, Vec2(a2, NoV), 0.0).xy;
 	return specular * envBRDF.x + /*min(1.0, 50.0 * specular.g) */ envBRDF.y;
 	return specular * envBRDF.x + /*min(1.0, 50.0 * specular.g) */ envBRDF.y;
 }
 }
 
 
@@ -109,7 +109,7 @@ U32 computeShadowSampleCount(const U32 COUNT, F32 zVSpace)
 	return sampleCount;
 	return sampleCount;
 }
 }
 
 
-F32 computeShadowFactorSpotLight(SpotLight light, Vec3 worldPos, sampler2D spotMapArr)
+F32 computeShadowFactorSpotLight(SpotLight light, Vec3 worldPos, texture2D spotMap, sampler spotMapSampler)
 {
 {
 	const Vec4 texCoords4 = light.m_texProjectionMat * Vec4(worldPos, 1.0);
 	const Vec4 texCoords4 = light.m_texProjectionMat * Vec4(worldPos, 1.0);
 	const Vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
 	const Vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
@@ -119,13 +119,13 @@ F32 computeShadowFactorSpotLight(SpotLight light, Vec3 worldPos, sampler2D spotM
 
 
 	const F32 linearDepth = linearizeDepth(texCoords3.z, near, far);
 	const F32 linearDepth = linearizeDepth(texCoords3.z, near, far);
 
 
-	const F32 shadowFactor = textureLod(spotMapArr, texCoords3.xy, 0.0).r;
+	const F32 shadowFactor = textureLod(spotMap, spotMapSampler, texCoords3.xy, 0.0).r;
 
 
 	return saturate(exp(ESM_CONSTANT * (shadowFactor - linearDepth)));
 	return saturate(exp(ESM_CONSTANT * (shadowFactor - linearDepth)));
 }
 }
 
 
 // Compute the shadow factor of point (omni) lights.
 // Compute the shadow factor of point (omni) lights.
-F32 computeShadowFactorPointLight(PointLight light, Vec3 frag2Light, sampler2D shadowMap)
+F32 computeShadowFactorPointLight(PointLight light, Vec3 frag2Light, texture2D shadowMap, sampler shadowMapSampler)
 {
 {
 	const Vec3 dir = -frag2Light;
 	const Vec3 dir = -frag2Light;
 	const Vec3 dirabs = abs(dir);
 	const Vec3 dirabs = abs(dir);
@@ -152,14 +152,15 @@ F32 computeShadowFactorPointLight(PointLight light, Vec3 frag2Light, sampler2D s
 		uv = fma(uv, Vec2(light.m_shadowAtlasTileScale), atlasOffset);
 		uv = fma(uv, Vec2(light.m_shadowAtlasTileScale), atlasOffset);
 
 
 		// Sample
 		// Sample
-		shadowFactor = textureLod(shadowMap, uv, 0.0).r;
+		shadowFactor = textureLod(shadowMap, shadowMapSampler, uv, 0.0).r;
 	}
 	}
 
 
 	return saturate(exp(ESM_CONSTANT * (shadowFactor - linearDepth)));
 	return saturate(exp(ESM_CONSTANT * (shadowFactor - linearDepth)));
 }
 }
 
 
 // Compute the shadow factor of a directional light
 // Compute the shadow factor of a directional light
-F32 computeShadowFactorDirLight(DirectionalLight light, U32 cascadeIdx, Vec3 worldPos, sampler2D shadowMap)
+F32 computeShadowFactorDirLight(
+	DirectionalLight light, U32 cascadeIdx, Vec3 worldPos, texture2D shadowMap, sampler shadowMapSampler)
 {
 {
 	const Mat4 lightProjectionMat = light.m_textureMatrices[cascadeIdx];
 	const Mat4 lightProjectionMat = light.m_textureMatrices[cascadeIdx];
 
 
@@ -168,19 +169,20 @@ F32 computeShadowFactorDirLight(DirectionalLight light, U32 cascadeIdx, Vec3 wor
 
 
 	const F32 cascadeLinearDepth = texCoords3.z;
 	const F32 cascadeLinearDepth = texCoords3.z;
 
 
-	F32 shadowFactor = textureLod(shadowMap, texCoords3.xy, 0.0).r;
+	F32 shadowFactor = textureLod(shadowMap, shadowMapSampler, texCoords3.xy, 0.0).r;
 	shadowFactor = saturate(exp(ESM_CONSTANT * 3.0 * (shadowFactor - cascadeLinearDepth)));
 	shadowFactor = saturate(exp(ESM_CONSTANT * 3.0 * (shadowFactor - cascadeLinearDepth)));
 
 
 	return shadowFactor;
 	return shadowFactor;
 }
 }
 
 
 // Compute the shadow factor of a directional light
 // Compute the shadow factor of a directional light
-F32 computeShadowFactorDirLight(Mat4 lightProjectionMat, Vec3 worldPos, sampler2DShadow shadowMap)
+F32 computeShadowFactorDirLight(
+	Mat4 lightProjectionMat, Vec3 worldPos, texture2D shadowMap, samplerShadow shadowMapSampler)
 {
 {
 	const Vec4 texCoords4 = lightProjectionMat * Vec4(worldPos, 1.0);
 	const Vec4 texCoords4 = lightProjectionMat * Vec4(worldPos, 1.0);
 	const Vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
 	const Vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
 
 
-	const F32 shadowFactor = textureLod(shadowMap, texCoords3, 0.0);
+	const F32 shadowFactor = textureLod(shadowMap, shadowMapSampler, texCoords3, 0.0);
 	return shadowFactor;
 	return shadowFactor;
 }
 }
 
 

+ 24 - 17
shaders/LightShading.glslp

@@ -41,12 +41,15 @@ void main()
 #define LIGHT_CLUSTERS_BINDING 8
 #define LIGHT_CLUSTERS_BINDING 8
 #include <shaders/ClusteredShadingCommon.glsl>
 #include <shaders/ClusteredShadingCommon.glsl>
 
 
-layout(set = 0, binding = 10) uniform sampler2D u_msRt0;
-layout(set = 0, binding = 11) uniform sampler2D u_msRt1;
-layout(set = 0, binding = 12) uniform sampler2D u_msRt2;
-layout(set = 0, binding = 13) uniform sampler2D u_msDepthRt;
-layout(set = 0, binding = 14) uniform sampler2D u_ssrRt;
-layout(set = 0, binding = 15) uniform sampler2D u_ssaoRt;
+layout(set = 0, binding = 10) uniform sampler u_nearestAnyClampSampler;
+layout(set = 0, binding = 11) uniform sampler u_trilinearClampSampler;
+
+layout(set = 0, binding = 12) uniform texture2D u_msRt0;
+layout(set = 0, binding = 13) uniform texture2D u_msRt1;
+layout(set = 0, binding = 14) uniform texture2D u_msRt2;
+layout(set = 0, binding = 15) uniform texture2D u_msDepthRt;
+layout(set = 0, binding = 16) uniform texture2D u_ssrRt;
+layout(set = 0, binding = 17) uniform texture2D u_ssaoRt;
 
 
 layout(location = 0) in Vec2 in_uv;
 layout(location = 0) in Vec2 in_uv;
 layout(location = 1) in Vec2 in_clusterIJ;
 layout(location = 1) in Vec2 in_clusterIJ;
@@ -64,7 +67,7 @@ layout(location = 0) out Vec3 out_color;
 
 
 void main()
 void main()
 {
 {
-	F32 depth = textureLod(u_msDepthRt, in_uv, 0.0).r;
+	F32 depth = textureLod(u_msDepthRt, u_nearestAnyClampSampler, in_uv, 0.0).r;
 	Vec2 ndc = UV_TO_NDC(in_uv);
 	Vec2 ndc = UV_TO_NDC(in_uv);
 
 
 	// Get world position
 	// Get world position
@@ -80,16 +83,16 @@ void main()
 
 
 		idxOffset = u_clusters[clusterIdx];
 		idxOffset = u_clusters[clusterIdx];
 
 
-		// out_color = lightHeatmap(idxOffset, 5, false, false, false, false, true); return;
+		// out_color = lightHeatmap(idxOffset, 5, false, true, false, false, false); return;
 	}
 	}
 
 
 	// Decode GBuffer
 	// Decode GBuffer
 	GbufferInfo gbuffer;
 	GbufferInfo gbuffer;
-	readGBuffer(u_msRt0, u_msRt1, u_msRt2, in_uv, 0.0, gbuffer);
+	readGBuffer(u_msRt0, u_msRt1, u_msRt2, u_nearestAnyClampSampler, in_uv, 0.0, gbuffer);
 	gbuffer.m_subsurface = max(gbuffer.m_subsurface, SUBSURFACE_MIN);
 	gbuffer.m_subsurface = max(gbuffer.m_subsurface, SUBSURFACE_MIN);
 
 
 	// SSAO
 	// SSAO
-	F32 ssao = textureLod(u_ssaoRt, in_uv, 0.0).r;
+	const F32 ssao = textureLod(u_ssaoRt, u_trilinearClampSampler, in_uv, 0.0).r;
 	gbuffer.m_diffuse *= ssao;
 	gbuffer.m_diffuse *= ssao;
 
 
 	// Ambient and emissive color
 	// Ambient and emissive color
@@ -106,7 +109,8 @@ void main()
 			F32 cascadeCountf = F32(u_dirLight.m_cascadeCount);
 			F32 cascadeCountf = F32(u_dirLight.m_cascadeCount);
 			U32 cascadeIdx = min(U32(linearDepth * cascadeCountf), u_dirLight.m_cascadeCount - 1u);
 			U32 cascadeIdx = min(U32(linearDepth * cascadeCountf), u_dirLight.m_cascadeCount - 1u);
 
 
-			shadowFactor = computeShadowFactorDirLight(u_dirLight, cascadeIdx, worldPos, u_shadowTex);
+			shadowFactor =
+				computeShadowFactorDirLight(u_dirLight, cascadeIdx, worldPos, u_shadowTex, u_trilinearClampSampler);
 		}
 		}
 		else
 		else
 		{
 		{
@@ -133,7 +137,7 @@ void main()
 
 
 		ANKI_BRANCH if(light.m_shadowAtlasTileScale >= 0.0)
 		ANKI_BRANCH if(light.m_shadowAtlasTileScale >= 0.0)
 		{
 		{
-			F32 shadow = computeShadowFactorPointLight(light, frag2Light, u_shadowTex);
+			F32 shadow = computeShadowFactorPointLight(light, frag2Light, u_shadowTex, u_trilinearClampSampler);
 			lambert *= shadow;
 			lambert *= shadow;
 		}
 		}
 
 
@@ -152,7 +156,7 @@ void main()
 		F32 shadowmapLayerIdx = light.m_shadowmapId;
 		F32 shadowmapLayerIdx = light.m_shadowmapId;
 		ANKI_BRANCH if(shadowmapLayerIdx >= 0.0)
 		ANKI_BRANCH if(shadowmapLayerIdx >= 0.0)
 		{
 		{
-			F32 shadow = computeShadowFactorSpotLight(light, worldPos, u_shadowTex);
+			F32 shadow = computeShadowFactorSpotLight(light, worldPos, u_shadowTex, u_trilinearClampSampler);
 			lambert *= shadow;
 			lambert *= shadow;
 		}
 		}
 
 
@@ -184,12 +188,14 @@ void main()
 
 
 			// Sample reflections
 			// Sample reflections
 			Vec3 cubeUv = intersectProbe(worldPos, reflDir, aabbMin, aabbMax, probeOrigin);
 			Vec3 cubeUv = intersectProbe(worldPos, reflDir, aabbMin, aabbMax, probeOrigin);
-			Vec3 c = textureLod(u_reflectionsTex, Vec4(cubeUv, cubemapIndex), reflLod).rgb;
+			Vec4 cubeArrUv = Vec4(cubeUv, cubemapIndex);
+			Vec3 c = textureLod(u_reflectionsTex, u_trilinearClampSampler, cubeArrUv, reflLod).rgb;
 			specIndirect += c * blendWeight;
 			specIndirect += c * blendWeight;
 
 
 			// Sample irradiance
 			// Sample irradiance
 			cubeUv = intersectProbe(worldPos, gbuffer.m_normal, aabbMin, aabbMax, probeOrigin);
 			cubeUv = intersectProbe(worldPos, gbuffer.m_normal, aabbMin, aabbMax, probeOrigin);
-			c = textureLod(u_irradianceTex, Vec4(cubeUv, cubemapIndex), 0.0).rgb;
+			cubeArrUv = Vec4(cubeUv, cubemapIndex);
+			c = textureLod(u_irradianceTex, u_trilinearClampSampler, cubeArrUv, 0.0).rgb;
 			diffIndirect += c * blendWeight;
 			diffIndirect += c * blendWeight;
 		}
 		}
 
 
@@ -198,14 +204,15 @@ void main()
 		diffIndirect /= totalBlendWeight;
 		diffIndirect /= totalBlendWeight;
 
 
 		// Read the SSL result
 		// Read the SSL result
-		const Vec4 ssr = textureLod(u_ssrRt, in_uv, 0.0);
+		const Vec4 ssr = textureLod(u_ssrRt, u_trilinearClampSampler, in_uv, 0.0);
 
 
 		// Combine the SSR and probe reflections and write the result
 		// Combine the SSR and probe reflections and write the result
 		const Vec3 finalRefl = specIndirect * ssr.a + ssr.rgb;
 		const Vec3 finalRefl = specIndirect * ssr.a + ssr.rgb;
 
 
 		// Compute env BRDF
 		// Compute env BRDF
 		const F32 NoV = max(EPSILON, dot(gbuffer.m_normal, viewDir));
 		const F32 NoV = max(EPSILON, dot(gbuffer.m_normal, viewDir));
-		const Vec3 env = envBRDF(gbuffer.m_specular, gbuffer.m_roughness, u_integrationLut, NoV);
+		const Vec3 env =
+			envBRDF(gbuffer.m_specular, gbuffer.m_roughness, u_integrationLut, u_trilinearClampSampler, NoV);
 
 
 		out_color += diffIndirect * gbuffer.m_diffuse + finalRefl * env;
 		out_color += diffIndirect * gbuffer.m_diffuse + finalRefl * env;
 	}
 	}

+ 6 - 9
shaders/MotionBlur.glsl

@@ -25,25 +25,22 @@ Vec3 motionBlur(texture2D velocityTex,
 	U32 maxSamples)
 	U32 maxSamples)
 {
 {
 	// Compute previous UV
 	// Compute previous UV
-	Vec2 velocity = textureLod(combineImageSampler(velocityTex, velocityTexSampler), nowUv, 0.0).rg;
+	Vec2 velocity = textureLod(velocityTex, velocityTexSampler, nowUv, 0.0).rg;
 
 
 	// Compute the velocity if it's static geometry
 	// Compute the velocity if it's static geometry
 	ANKI_BRANCH if(velocity.x == -1.0)
 	ANKI_BRANCH if(velocity.x == -1.0)
 	{
 	{
 #if TAA_FIX
 #if TAA_FIX
-		const Vec2 a =
-			textureLodOffset(combineImageSampler(velocityTex, velocityTexSampler), nowUv, 0.0, ivec2(-2, 2)).rg;
-		const Vec2 b =
-			textureLodOffset(combineImageSampler(velocityTex, velocityTexSampler), nowUv, 0.0, ivec2(2, 2)).rg;
-		const Vec2 c =
-			textureLodOffset(combineImageSampler(velocityTex, velocityTexSampler), nowUv, 0.0, ivec2(0, -2)).rg;
+		const Vec2 a = textureLodOffset(sampler2D(velocityTex, velocityTexSampler), nowUv, 0.0, ivec2(-2, 2)).rg;
+		const Vec2 b = textureLodOffset(sampler2D(velocityTex, velocityTexSampler), nowUv, 0.0, ivec2(2, 2)).rg;
+		const Vec2 c = textureLodOffset(sampler2D(velocityTex, velocityTexSampler), nowUv, 0.0, ivec2(0, -2)).rg;
 
 
 		velocity = max(max(a, b), c);
 		velocity = max(max(a, b), c);
 
 
 		ANKI_BRANCH if(velocity.x == -1.0)
 		ANKI_BRANCH if(velocity.x == -1.0)
 #endif
 #endif
 		{
 		{
-			const F32 depth = textureLod(combineImageSampler(depthTex, depthTexSampler), nowUv, 0.0).r;
+			const F32 depth = textureLod(depthTex, depthTexSampler, nowUv, 0.0).r;
 
 
 			const Vec4 v4 = prevViewProjMatMulInvViewProjMat * Vec4(UV_TO_NDC(nowUv), depth, 1.0);
 			const Vec4 v4 = prevViewProjMatMulInvViewProjMat * Vec4(UV_TO_NDC(nowUv), depth, 1.0);
 			velocity = NDC_TO_UV(v4.xy / v4.w) - nowUv;
 			velocity = NDC_TO_UV(v4.xy / v4.w) - nowUv;
@@ -66,7 +63,7 @@ Vec3 motionBlur(texture2D velocityTex,
 		const F32 f = s / sampleCountf;
 		const F32 f = s / sampleCountf;
 		const Vec2 sampleUv = nowUv + velocity * f;
 		const Vec2 sampleUv = nowUv + velocity * f;
 
 
-		outColor += textureLod(combineImageSampler(toBlurTex, toBlurTexSampler), sampleUv, 0.0).rgb;
+		outColor += textureLod(toBlurTex, toBlurTexSampler, sampleUv, 0.0).rgb;
 	}
 	}
 
 
 	outColor /= sampleCountf;
 	outColor /= sampleCountf;

+ 8 - 8
shaders/Pack.glsl

@@ -151,32 +151,32 @@ void writeGBuffer(GbufferInfo g, out Vec4 rt0, out Vec4 rt1, out Vec4 rt2, out V
 }
 }
 
 
 // Read from G-buffer
 // Read from G-buffer
-Vec3 readNormalFromGBuffer(sampler2D rt2, Vec2 uv)
+Vec3 readNormalFromGBuffer(texture2D rt2, sampler sampl, Vec2 uv)
 {
 {
-	return signedOctDecode(texture(rt2, uv).rga);
+	return signedOctDecode(textureLod(rt2, sampl, uv, 0.0).rga);
 }
 }
 
 
 // Read the roughness from G-buffer
 // Read the roughness from G-buffer
-F32 readRoughnessFromGBuffer(sampler2D rt1, Vec2 uv)
+F32 readRoughnessFromGBuffer(texture2D rt1, sampler sampl, Vec2 uv)
 {
 {
-	F32 r = textureLod(rt1, uv, 0.0).r;
+	F32 r = textureLod(rt1, sampl, uv, 0.0).r;
 	r = r * (1.0 - MIN_ROUGHNESS) + MIN_ROUGHNESS;
 	r = r * (1.0 - MIN_ROUGHNESS) + MIN_ROUGHNESS;
 	return r;
 	return r;
 }
 }
 
 
 // Read part of the G-buffer
 // Read part of the G-buffer
-void readGBuffer(sampler2D rt0, sampler2D rt1, sampler2D rt2, Vec2 uv, F32 lod, out GbufferInfo g)
+void readGBuffer(texture2D rt0, texture2D rt1, texture2D rt2, sampler sampl, Vec2 uv, F32 lod, out GbufferInfo g)
 {
 {
-	Vec4 comp = textureLod(rt0, uv, 0.0);
+	Vec4 comp = textureLod(rt0, sampl, uv, 0.0);
 	g.m_diffuse = comp.xyz;
 	g.m_diffuse = comp.xyz;
 	g.m_subsurface = comp.w;
 	g.m_subsurface = comp.w;
 
 
-	comp = textureLod(rt1, uv, 0.0);
+	comp = textureLod(rt1, sampl, uv, 0.0);
 	g.m_roughness = comp.x;
 	g.m_roughness = comp.x;
 	g.m_metallic = comp.y;
 	g.m_metallic = comp.y;
 	g.m_specular = Vec3(comp.z);
 	g.m_specular = Vec3(comp.z);
 
 
-	comp = textureLod(rt2, uv, 0.0);
+	comp = textureLod(rt2, sampl, uv, 0.0);
 	g.m_normal = signedOctDecode(comp.xyw);
 	g.m_normal = signedOctDecode(comp.xyw);
 	g.m_emission = comp.z * MAX_EMISSION;
 	g.m_emission = comp.z * MAX_EMISSION;
 
 

+ 12 - 11
shaders/Ssr.glslp

@@ -25,14 +25,15 @@
 
 
 layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = 1) in;
 layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = 1) in;
 
 
-layout(set = 0, binding = 0) uniform sampler2D u_gbufferRt1;
-layout(set = 0, binding = 1) uniform sampler2D u_gbufferRt2;
-layout(set = 0, binding = 2) uniform sampler2D u_depthRt;
-layout(set = 0, binding = 3) uniform sampler2D u_lightBufferRt;
+layout(set = 0, binding = 0) uniform sampler u_trilinearClampSampler;
+layout(set = 0, binding = 1) uniform texture2D u_gbufferRt1;
+layout(set = 0, binding = 2) uniform texture2D u_gbufferRt2;
+layout(set = 0, binding = 3) uniform texture2D u_depthRt;
+layout(set = 0, binding = 4) uniform texture2D u_lightBufferRt;
 
 
-layout(set = 0, binding = 4, rgba16f) uniform image2D out_img;
+layout(set = 0, binding = 5, rgba16f) uniform image2D out_img;
 
 
-layout(set = 0, binding = 5, row_major) uniform u_
+layout(set = 0, binding = 6, row_major) uniform u_
 {
 {
 	SsrUniforms u_unis;
 	SsrUniforms u_unis;
 };
 };
@@ -100,7 +101,7 @@ Vec3 raymarch(Vec3 r, Vec3 n, Vec3 viewPos, Vec2 uv, F32 depth)
 			break;
 			break;
 		}
 		}
 
 
-		const F32 depth = textureLod(u_depthRt, raySample.xy, 0.0).r;
+		const F32 depth = textureLod(u_depthRt, u_trilinearClampSampler, raySample.xy, 0.0).r;
 
 
 		const Bool hit = raySample.z - depth >= 0.0;
 		const Bool hit = raySample.z - depth >= 0.0;
 		if(!hit)
 		if(!hit)
@@ -156,11 +157,11 @@ void main()
 	const Vec2 uv = (Vec2(fixedInvocationId.xy) + 0.5) / Vec2(FB_SIZE);
 	const Vec2 uv = (Vec2(fixedInvocationId.xy) + 0.5) / Vec2(FB_SIZE);
 
 
 	// Read part of the G-buffer
 	// Read part of the G-buffer
-	const F32 roughness = readRoughnessFromGBuffer(u_gbufferRt1, uv);
-	const Vec3 worldNormal = readNormalFromGBuffer(u_gbufferRt2, uv);
+	const F32 roughness = readRoughnessFromGBuffer(u_gbufferRt1, u_trilinearClampSampler, uv);
+	const Vec3 worldNormal = readNormalFromGBuffer(u_gbufferRt2, u_trilinearClampSampler, uv);
 
 
 	// Get depth
 	// Get depth
-	const F32 depth = textureLod(u_depthRt, uv, 0.0).r;
+	const F32 depth = textureLod(u_depthRt, u_trilinearClampSampler, uv, 0.0).r;
 
 
 	// Get view pos
 	// Get view pos
 	const Vec4 viewPos4 = u_invProjMat * Vec4(UV_TO_NDC(uv), depth, 1.0);
 	const Vec4 viewPos4 = u_invProjMat * Vec4(UV_TO_NDC(uv), depth, 1.0);
@@ -182,7 +183,7 @@ void main()
 	{
 	{
 		// Read the refl
 		// Read the refl
 		const F32 lod = F32(LIGHT_BUFFER_MIP_COUNT - 1u) * roughness;
 		const F32 lod = F32(LIGHT_BUFFER_MIP_COUNT - 1u) * roughness;
-		outColor.rgb = textureLod(u_lightBufferRt, reflUv, lod).rgb;
+		outColor.rgb = textureLod(u_lightBufferRt, u_trilinearClampSampler, reflUv, lod).rgb;
 		outColor.rgb = clamp(outColor.rgb, 0.0, FLT_MAX); // Fix the value just in case
 		outColor.rgb = clamp(outColor.rgb, 0.0, FLT_MAX); // Fix the value just in case
 		outColor.rgb *= factor;
 		outColor.rgb *= factor;
 		outColor.a = 1.0 - factor;
 		outColor.a = 1.0 - factor;

+ 1117 - 0
shaders/TextureFunctions.glsl

@@ -0,0 +1,1117 @@
+// Copyright (C) 2009-2019, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+// WARNING: THIS FILE IS AUTO-GENERATED. DON'T CHANGE IT BY HAND.
+// This file contains some convenience texture functions.
+
+#pragma once
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 texture(texture1D tex, sampler sampl, float P, float bias)
+{
+	return texture(sampler1D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 texture(utexture1D tex, sampler sampl, float P, float bias)
+{
+	return texture(usampler1D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 texture(itexture1D tex, sampler sampl, float P, float bias)
+{
+	return texture(isampler1D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 texture(texture1D tex, sampler sampl, float P)
+{
+	return texture(sampler1D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 texture(utexture1D tex, sampler sampl, float P)
+{
+	return texture(usampler1D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 texture(itexture1D tex, sampler sampl, float P)
+{
+	return texture(isampler1D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 texture(texture2D tex, sampler sampl, vec2 P, float bias)
+{
+	return texture(sampler2D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 texture(utexture2D tex, sampler sampl, vec2 P, float bias)
+{
+	return texture(usampler2D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 texture(itexture2D tex, sampler sampl, vec2 P, float bias)
+{
+	return texture(isampler2D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 texture(texture2D tex, sampler sampl, vec2 P)
+{
+	return texture(sampler2D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 texture(utexture2D tex, sampler sampl, vec2 P)
+{
+	return texture(usampler2D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 texture(itexture2D tex, sampler sampl, vec2 P)
+{
+	return texture(isampler2D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 texture(texture3D tex, sampler sampl, vec3 P, float bias)
+{
+	return texture(sampler3D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 texture(utexture3D tex, sampler sampl, vec3 P, float bias)
+{
+	return texture(usampler3D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 texture(itexture3D tex, sampler sampl, vec3 P, float bias)
+{
+	return texture(isampler3D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 texture(texture3D tex, sampler sampl, vec3 P)
+{
+	return texture(sampler3D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 texture(utexture3D tex, sampler sampl, vec3 P)
+{
+	return texture(usampler3D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 texture(itexture3D tex, sampler sampl, vec3 P)
+{
+	return texture(isampler3D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 texture(textureCube tex, sampler sampl, vec3 P, float bias)
+{
+	return texture(samplerCube(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 texture(utextureCube tex, sampler sampl, vec3 P, float bias)
+{
+	return texture(usamplerCube(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 texture(itextureCube tex, sampler sampl, vec3 P, float bias)
+{
+	return texture(isamplerCube(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 texture(textureCube tex, sampler sampl, vec3 P)
+{
+	return texture(samplerCube(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 texture(utextureCube tex, sampler sampl, vec3 P)
+{
+	return texture(usamplerCube(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 texture(itextureCube tex, sampler sampl, vec3 P)
+{
+	return texture(isamplerCube(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float texture(texture1D tex, samplerShadow sampl, vec3 P, float bias)
+{
+	return texture(sampler1DShadow(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float texture(texture1D tex, samplerShadow sampl, vec3 P)
+{
+	return texture(sampler1DShadow(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float texture(texture2D tex, samplerShadow sampl, vec3 P, float bias)
+{
+	return texture(sampler2DShadow(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float texture(texture2D tex, samplerShadow sampl, vec3 P)
+{
+	return texture(sampler2DShadow(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float texture(textureCube tex, samplerShadow sampl, vec4 P, float bias)
+{
+	return texture(samplerCubeShadow(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float texture(textureCube tex, samplerShadow sampl, vec4 P)
+{
+	return texture(samplerCubeShadow(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 texture(texture2DArray tex, sampler sampl, vec3 P, float bias)
+{
+	return texture(sampler2DArray(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 texture(utexture2DArray tex, sampler sampl, vec3 P, float bias)
+{
+	return texture(usampler2DArray(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 texture(itexture2DArray tex, sampler sampl, vec3 P, float bias)
+{
+	return texture(isampler2DArray(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 texture(texture2DArray tex, sampler sampl, vec3 P)
+{
+	return texture(sampler2DArray(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 texture(utexture2DArray tex, sampler sampl, vec3 P)
+{
+	return texture(usampler2DArray(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 texture(itexture2DArray tex, sampler sampl, vec3 P)
+{
+	return texture(isampler2DArray(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 texture(textureCubeArray tex, sampler sampl, vec4 P, float bias)
+{
+	return texture(samplerCubeArray(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 texture(utextureCubeArray tex, sampler sampl, vec4 P, float bias)
+{
+	return texture(usamplerCubeArray(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 texture(itextureCubeArray tex, sampler sampl, vec4 P, float bias)
+{
+	return texture(isamplerCubeArray(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 texture(textureCubeArray tex, sampler sampl, vec4 P)
+{
+	return texture(samplerCubeArray(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 texture(utextureCubeArray tex, sampler sampl, vec4 P)
+{
+	return texture(usamplerCubeArray(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 texture(itextureCubeArray tex, sampler sampl, vec4 P)
+{
+	return texture(isamplerCubeArray(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 texture(texture1DArray tex, sampler sampl, vec2 P, float bias)
+{
+	return texture(sampler1DArray(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 texture(utexture1DArray tex, sampler sampl, vec2 P, float bias)
+{
+	return texture(usampler1DArray(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 texture(itexture1DArray tex, sampler sampl, vec2 P, float bias)
+{
+	return texture(isampler1DArray(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 texture(texture1DArray tex, sampler sampl, vec2 P)
+{
+	return texture(sampler1DArray(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 texture(utexture1DArray tex, sampler sampl, vec2 P)
+{
+	return texture(usampler1DArray(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 texture(itexture1DArray tex, sampler sampl, vec2 P)
+{
+	return texture(isampler1DArray(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float texture(texture1DArray tex, samplerShadow sampl, vec3 P, float bias)
+{
+	return texture(sampler1DArrayShadow(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float texture(texture1DArray tex, samplerShadow sampl, vec3 P)
+{
+	return texture(sampler1DArrayShadow(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float texture(texture2DArray tex, samplerShadow sampl, vec4 P)
+{
+	return texture(sampler2DArrayShadow(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float texture(textureCubeArray tex, samplerShadow sampl, vec4 P, float compare)
+{
+	return texture(samplerCubeArrayShadow(tex, sampl), P, compare);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProj(texture1D tex, sampler sampl, vec2 P, float bias)
+{
+	return textureProj(sampler1D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProj(utexture1D tex, sampler sampl, vec2 P, float bias)
+{
+	return textureProj(usampler1D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProj(itexture1D tex, sampler sampl, vec2 P, float bias)
+{
+	return textureProj(isampler1D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProj(texture1D tex, sampler sampl, vec2 P)
+{
+	return textureProj(sampler1D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProj(utexture1D tex, sampler sampl, vec2 P)
+{
+	return textureProj(usampler1D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProj(itexture1D tex, sampler sampl, vec2 P)
+{
+	return textureProj(isampler1D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProj(texture1D tex, sampler sampl, vec4 P, float bias)
+{
+	return textureProj(sampler1D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProj(utexture1D tex, sampler sampl, vec4 P, float bias)
+{
+	return textureProj(usampler1D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProj(itexture1D tex, sampler sampl, vec4 P, float bias)
+{
+	return textureProj(isampler1D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProj(texture1D tex, sampler sampl, vec4 P)
+{
+	return textureProj(sampler1D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProj(utexture1D tex, sampler sampl, vec4 P)
+{
+	return textureProj(usampler1D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProj(itexture1D tex, sampler sampl, vec4 P)
+{
+	return textureProj(isampler1D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProj(texture2D tex, sampler sampl, vec3 P, float bias)
+{
+	return textureProj(sampler2D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProj(utexture2D tex, sampler sampl, vec3 P, float bias)
+{
+	return textureProj(usampler2D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProj(itexture2D tex, sampler sampl, vec3 P, float bias)
+{
+	return textureProj(isampler2D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProj(texture2D tex, sampler sampl, vec3 P)
+{
+	return textureProj(sampler2D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProj(utexture2D tex, sampler sampl, vec3 P)
+{
+	return textureProj(usampler2D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProj(itexture2D tex, sampler sampl, vec3 P)
+{
+	return textureProj(isampler2D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProj(texture2D tex, sampler sampl, vec4 P, float bias)
+{
+	return textureProj(sampler2D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProj(utexture2D tex, sampler sampl, vec4 P, float bias)
+{
+	return textureProj(usampler2D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProj(itexture2D tex, sampler sampl, vec4 P, float bias)
+{
+	return textureProj(isampler2D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProj(texture2D tex, sampler sampl, vec4 P)
+{
+	return textureProj(sampler2D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProj(utexture2D tex, sampler sampl, vec4 P)
+{
+	return textureProj(usampler2D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProj(itexture2D tex, sampler sampl, vec4 P)
+{
+	return textureProj(isampler2D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProj(texture3D tex, sampler sampl, vec4 P, float bias)
+{
+	return textureProj(sampler3D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProj(utexture3D tex, sampler sampl, vec4 P, float bias)
+{
+	return textureProj(usampler3D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProj(itexture3D tex, sampler sampl, vec4 P, float bias)
+{
+	return textureProj(isampler3D(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProj(texture3D tex, sampler sampl, vec4 P)
+{
+	return textureProj(sampler3D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProj(utexture3D tex, sampler sampl, vec4 P)
+{
+	return textureProj(usampler3D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProj(itexture3D tex, sampler sampl, vec4 P)
+{
+	return textureProj(isampler3D(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float textureProj(texture1D tex, samplerShadow sampl, vec4 P, float bias)
+{
+	return textureProj(sampler1DShadow(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float textureProj(texture1D tex, samplerShadow sampl, vec4 P)
+{
+	return textureProj(sampler1DShadow(tex, sampl), P);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float textureProj(texture2D tex, samplerShadow sampl, vec4 P, float bias)
+{
+	return textureProj(sampler2DShadow(tex, sampl), P, bias);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float textureProj(texture2D tex, samplerShadow sampl, vec4 P)
+{
+	return textureProj(sampler2DShadow(tex, sampl), P);
+}
+#endif
+
+vec4 textureLod(texture1D tex, sampler sampl, float P, float lod)
+{
+	return textureLod(sampler1D(tex, sampl), P, lod);
+}
+
+uvec4 textureLod(utexture1D tex, sampler sampl, float P, float lod)
+{
+	return textureLod(usampler1D(tex, sampl), P, lod);
+}
+
+ivec4 textureLod(itexture1D tex, sampler sampl, float P, float lod)
+{
+	return textureLod(isampler1D(tex, sampl), P, lod);
+}
+
+vec4 textureLod(texture2D tex, sampler sampl, vec2 P, float lod)
+{
+	return textureLod(sampler2D(tex, sampl), P, lod);
+}
+
+uvec4 textureLod(utexture2D tex, sampler sampl, vec2 P, float lod)
+{
+	return textureLod(usampler2D(tex, sampl), P, lod);
+}
+
+ivec4 textureLod(itexture2D tex, sampler sampl, vec2 P, float lod)
+{
+	return textureLod(isampler2D(tex, sampl), P, lod);
+}
+
+vec4 textureLod(texture3D tex, sampler sampl, vec3 P, float lod)
+{
+	return textureLod(sampler3D(tex, sampl), P, lod);
+}
+
+uvec4 textureLod(utexture3D tex, sampler sampl, vec3 P, float lod)
+{
+	return textureLod(usampler3D(tex, sampl), P, lod);
+}
+
+ivec4 textureLod(itexture3D tex, sampler sampl, vec3 P, float lod)
+{
+	return textureLod(isampler3D(tex, sampl), P, lod);
+}
+
+vec4 textureLod(textureCube tex, sampler sampl, vec3 P, float lod)
+{
+	return textureLod(samplerCube(tex, sampl), P, lod);
+}
+
+uvec4 textureLod(utextureCube tex, sampler sampl, vec3 P, float lod)
+{
+	return textureLod(usamplerCube(tex, sampl), P, lod);
+}
+
+ivec4 textureLod(itextureCube tex, sampler sampl, vec3 P, float lod)
+{
+	return textureLod(isamplerCube(tex, sampl), P, lod);
+}
+
+float textureLod(texture2D tex, samplerShadow sampl, vec3 P, float lod)
+{
+	return textureLod(sampler2DShadow(tex, sampl), P, lod);
+}
+
+float textureLod(texture1D tex, samplerShadow sampl, vec3 P, float lod)
+{
+	return textureLod(sampler1DShadow(tex, sampl), P, lod);
+}
+
+vec4 textureLod(texture1DArray tex, sampler sampl, vec2 P, float lod)
+{
+	return textureLod(sampler1DArray(tex, sampl), P, lod);
+}
+
+uvec4 textureLod(utexture1DArray tex, sampler sampl, vec2 P, float lod)
+{
+	return textureLod(usampler1DArray(tex, sampl), P, lod);
+}
+
+ivec4 textureLod(itexture1DArray tex, sampler sampl, vec2 P, float lod)
+{
+	return textureLod(isampler1DArray(tex, sampl), P, lod);
+}
+
+float textureLod(texture1DArray tex, samplerShadow sampl, vec3 P, float lod)
+{
+	return textureLod(sampler1DArrayShadow(tex, sampl), P, lod);
+}
+
+vec4 textureLod(texture2DArray tex, sampler sampl, vec3 P, float lod)
+{
+	return textureLod(sampler2DArray(tex, sampl), P, lod);
+}
+
+uvec4 textureLod(utexture2DArray tex, sampler sampl, vec3 P, float lod)
+{
+	return textureLod(usampler2DArray(tex, sampl), P, lod);
+}
+
+ivec4 textureLod(itexture2DArray tex, sampler sampl, vec3 P, float lod)
+{
+	return textureLod(isampler2DArray(tex, sampl), P, lod);
+}
+
+vec4 textureLod(textureCubeArray tex, sampler sampl, vec4 P, float lod)
+{
+	return textureLod(samplerCubeArray(tex, sampl), P, lod);
+}
+
+uvec4 textureLod(utextureCubeArray tex, sampler sampl, vec4 P, float lod)
+{
+	return textureLod(usamplerCubeArray(tex, sampl), P, lod);
+}
+
+ivec4 textureLod(itextureCubeArray tex, sampler sampl, vec4 P, float lod)
+{
+	return textureLod(isamplerCubeArray(tex, sampl), P, lod);
+}
+
+vec4 textureProjLod(texture1D tex, sampler sampl, vec2 P, float lod)
+{
+	return textureProjLod(sampler1D(tex, sampl), P, lod);
+}
+
+uvec4 textureProjLod(utexture1D tex, sampler sampl, vec2 P, float lod)
+{
+	return textureProjLod(usampler1D(tex, sampl), P, lod);
+}
+
+ivec4 textureProjLod(itexture1D tex, sampler sampl, vec2 P, float lod)
+{
+	return textureProjLod(isampler1D(tex, sampl), P, lod);
+}
+
+vec4 textureProjLod(texture1D tex, sampler sampl, vec4 P, float lod)
+{
+	return textureProjLod(sampler1D(tex, sampl), P, lod);
+}
+
+uvec4 textureProjLod(utexture1D tex, sampler sampl, vec4 P, float lod)
+{
+	return textureProjLod(usampler1D(tex, sampl), P, lod);
+}
+
+ivec4 textureProjLod(itexture1D tex, sampler sampl, vec4 P, float lod)
+{
+	return textureProjLod(isampler1D(tex, sampl), P, lod);
+}
+
+vec4 textureProjLod(texture2D tex, sampler sampl, vec3 P, float lod)
+{
+	return textureProjLod(sampler2D(tex, sampl), P, lod);
+}
+
+uvec4 textureProjLod(utexture2D tex, sampler sampl, vec3 P, float lod)
+{
+	return textureProjLod(usampler2D(tex, sampl), P, lod);
+}
+
+ivec4 textureProjLod(itexture2D tex, sampler sampl, vec3 P, float lod)
+{
+	return textureProjLod(isampler2D(tex, sampl), P, lod);
+}
+
+vec4 textureProjLod(texture2D tex, sampler sampl, vec4 P, float lod)
+{
+	return textureProjLod(sampler2D(tex, sampl), P, lod);
+}
+
+uvec4 textureProjLod(utexture2D tex, sampler sampl, vec4 P, float lod)
+{
+	return textureProjLod(usampler2D(tex, sampl), P, lod);
+}
+
+ivec4 textureProjLod(itexture2D tex, sampler sampl, vec4 P, float lod)
+{
+	return textureProjLod(isampler2D(tex, sampl), P, lod);
+}
+
+vec4 textureProjLod(texture3D tex, sampler sampl, vec4 P, float lod)
+{
+	return textureProjLod(sampler3D(tex, sampl), P, lod);
+}
+
+uvec4 textureProjLod(utexture3D tex, sampler sampl, vec4 P, float lod)
+{
+	return textureProjLod(usampler3D(tex, sampl), P, lod);
+}
+
+ivec4 textureProjLod(itexture3D tex, sampler sampl, vec4 P, float lod)
+{
+	return textureProjLod(isampler3D(tex, sampl), P, lod);
+}
+
+float textureProjLod(texture1D tex, samplerShadow sampl, vec4 P, float lod)
+{
+	return textureProjLod(sampler1DShadow(tex, sampl), P, lod);
+}
+
+float textureProjLod(texture2D tex, samplerShadow sampl, vec4 P, float lod)
+{
+	return textureProjLod(sampler2DShadow(tex, sampl), P, lod);
+}
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureGrad(texture1D tex, sampler sampl, float P, float dPdx, float dPdy)
+{
+	return textureGrad(sampler1D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureGrad(utexture1D tex, sampler sampl, float P, float dPdx, float dPdy)
+{
+	return textureGrad(usampler1D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureGrad(itexture1D tex, sampler sampl, float P, float dPdx, float dPdy)
+{
+	return textureGrad(isampler1D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureGrad(texture2D tex, sampler sampl, vec2 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureGrad(sampler2D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureGrad(utexture2D tex, sampler sampl, vec2 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureGrad(usampler2D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureGrad(itexture2D tex, sampler sampl, vec2 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureGrad(isampler2D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureGrad(texture3D tex, sampler sampl, vec3 P, vec3 dPdx, vec3 dPdy)
+{
+	return textureGrad(sampler3D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureGrad(utexture3D tex, sampler sampl, vec3 P, vec3 dPdx, vec3 dPdy)
+{
+	return textureGrad(usampler3D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureGrad(itexture3D tex, sampler sampl, vec3 P, vec3 dPdx, vec3 dPdy)
+{
+	return textureGrad(isampler3D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureGrad(textureCube tex, sampler sampl, vec3 P, vec3 dPdx, vec3 dPdy)
+{
+	return textureGrad(samplerCube(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureGrad(utextureCube tex, sampler sampl, vec3 P, vec3 dPdx, vec3 dPdy)
+{
+	return textureGrad(usamplerCube(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureGrad(itextureCube tex, sampler sampl, vec3 P, vec3 dPdx, vec3 dPdy)
+{
+	return textureGrad(isamplerCube(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float textureGrad(texture1D tex, samplerShadow sampl, vec3 P, float dPdx, float dPdy)
+{
+	return textureGrad(sampler1DShadow(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureGrad(texture1DArray tex, sampler sampl, vec2 P, float dPdx, float dPdy)
+{
+	return textureGrad(sampler1DArray(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureGrad(utexture1DArray tex, sampler sampl, vec2 P, float dPdx, float dPdy)
+{
+	return textureGrad(usampler1DArray(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureGrad(itexture1DArray tex, sampler sampl, vec2 P, float dPdx, float dPdy)
+{
+	return textureGrad(isampler1DArray(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureGrad(texture2DArray tex, sampler sampl, vec3 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureGrad(sampler2DArray(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureGrad(utexture2DArray tex, sampler sampl, vec3 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureGrad(usampler2DArray(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureGrad(itexture2DArray tex, sampler sampl, vec3 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureGrad(isampler2DArray(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float textureGrad(texture1DArray tex, samplerShadow sampl, vec3 P, float dPdx, float dPdy)
+{
+	return textureGrad(sampler1DArrayShadow(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float textureGrad(texture2D tex, samplerShadow sampl, vec3 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureGrad(sampler2DShadow(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float textureGrad(textureCube tex, samplerShadow sampl, vec4 P, vec3 dPdx, vec3 dPdy)
+{
+	return textureGrad(samplerCubeShadow(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float textureGrad(texture2DArray tex, samplerShadow sampl, vec4 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureGrad(sampler2DArrayShadow(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureGrad(textureCubeArray tex, sampler sampl, vec4 P, vec3 dPdx, vec3 dPdy)
+{
+	return textureGrad(samplerCubeArray(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureGrad(utextureCubeArray tex, sampler sampl, vec4 P, vec3 dPdx, vec3 dPdy)
+{
+	return textureGrad(usamplerCubeArray(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureGrad(itextureCubeArray tex, sampler sampl, vec4 P, vec3 dPdx, vec3 dPdy)
+{
+	return textureGrad(isamplerCubeArray(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProjGrad(texture1D tex, sampler sampl, vec2 P, float dPdx, float dPdy)
+{
+	return textureProjGrad(sampler1D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProjGrad(utexture1D tex, sampler sampl, vec2 P, float dPdx, float dPdy)
+{
+	return textureProjGrad(usampler1D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProjGrad(itexture1D tex, sampler sampl, vec2 P, float dPdx, float dPdy)
+{
+	return textureProjGrad(isampler1D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProjGrad(texture1D tex, sampler sampl, vec4 P, float dPdx, float dPdy)
+{
+	return textureProjGrad(sampler1D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProjGrad(utexture1D tex, sampler sampl, vec4 P, float dPdx, float dPdy)
+{
+	return textureProjGrad(usampler1D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProjGrad(itexture1D tex, sampler sampl, vec4 P, float dPdx, float dPdy)
+{
+	return textureProjGrad(isampler1D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProjGrad(texture2D tex, sampler sampl, vec3 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureProjGrad(sampler2D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProjGrad(utexture2D tex, sampler sampl, vec3 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureProjGrad(usampler2D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProjGrad(itexture2D tex, sampler sampl, vec3 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureProjGrad(isampler2D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProjGrad(texture2D tex, sampler sampl, vec4 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureProjGrad(sampler2D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProjGrad(utexture2D tex, sampler sampl, vec4 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureProjGrad(usampler2D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProjGrad(itexture2D tex, sampler sampl, vec4 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureProjGrad(isampler2D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+vec4 textureProjGrad(texture3D tex, sampler sampl, vec4 P, vec3 dPdx, vec3 dPdy)
+{
+	return textureProjGrad(sampler3D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+uvec4 textureProjGrad(utexture3D tex, sampler sampl, vec4 P, vec3 dPdx, vec3 dPdy)
+{
+	return textureProjGrad(usampler3D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+ivec4 textureProjGrad(itexture3D tex, sampler sampl, vec4 P, vec3 dPdx, vec3 dPdy)
+{
+	return textureProjGrad(isampler3D(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float textureProjGrad(texture1D tex, samplerShadow sampl, vec4 P, float dPdx, float dPdy)
+{
+	return textureProjGrad(sampler1DShadow(tex, sampl), P, dPdx, dPdy);
+}
+#endif
+
+#if defined(ANKI_FRAGMENT_SHADER)
+float textureProjGrad(texture2D tex, samplerShadow sampl, vec4 P, vec2 dPdx, vec2 dPdy)
+{
+	return textureProjGrad(sampler2DShadow(tex, sampl), P, dPdx, dPdy);
+}
+#endif

+ 10 - 8
shaders/TraditionalDeferredShading.glslp

@@ -63,13 +63,15 @@ layout(set = 0, binding = 1, row_major) uniform u1_
 #endif
 #endif
 };
 };
 
 
-layout(set = 0, binding = 2) uniform sampler2D u_msRt0;
-layout(set = 0, binding = 3) uniform sampler2D u_msRt1;
-layout(set = 0, binding = 4) uniform sampler2D u_msRt2;
-layout(set = 0, binding = 5) uniform sampler2D u_msDepthRt;
+layout(set = 0, binding = 2) uniform sampler u_msSampler;
+layout(set = 0, binding = 3) uniform texture2D u_msRt0;
+layout(set = 0, binding = 4) uniform texture2D u_msRt1;
+layout(set = 0, binding = 5) uniform texture2D u_msRt2;
+layout(set = 0, binding = 6) uniform texture2D u_msDepthRt;
 
 
 #if LIGHT_TYPE == DIR_LIGHT_TYPE
 #if LIGHT_TYPE == DIR_LIGHT_TYPE
-layout(set = 0, binding = 6) uniform sampler2DShadow u_shadowMap;
+layout(set = 0, binding = 7) uniform samplerShadow u_shadowMapSampler;
+layout(set = 0, binding = 8) uniform texture2D u_shadowMap;
 #endif
 #endif
 
 
 void main()
 void main()
@@ -78,7 +80,7 @@ void main()
 	const Vec2 uv = Vec2(gl_FragCoord.xy) / u_unis.m_fbSize;
 	const Vec2 uv = Vec2(gl_FragCoord.xy) / u_unis.m_fbSize;
 	const Vec2 uvToRead = fma(uv, u_unis.m_inputTexUvScale, u_unis.m_inputTexUvOffset);
 	const Vec2 uvToRead = fma(uv, u_unis.m_inputTexUvScale, u_unis.m_inputTexUvOffset);
 
 
-	const F32 depth = texture(u_msDepthRt, uvToRead).r;
+	const F32 depth = textureLod(u_msDepthRt, u_msSampler, uvToRead, 0.0).r;
 
 
 #if LIGHT_TYPE != DIR_LIGHT_TYPE
 #if LIGHT_TYPE != DIR_LIGHT_TYPE
 	// Do manual depth test
 	// Do manual depth test
@@ -90,7 +92,7 @@ void main()
 
 
 	// Decode and process gbuffer
 	// Decode and process gbuffer
 	GbufferInfo gbuffer;
 	GbufferInfo gbuffer;
-	readGBuffer(u_msRt0, u_msRt1, u_msRt2, uvToRead, 0.0, gbuffer);
+	readGBuffer(u_msRt0, u_msRt1, u_msRt2, u_msSampler, uvToRead, 0.0, gbuffer);
 	gbuffer.m_subsurface = max(gbuffer.m_subsurface, SUBSURFACE_MIN * 8.0);
 	gbuffer.m_subsurface = max(gbuffer.m_subsurface, SUBSURFACE_MIN * 8.0);
 
 
 	const Vec4 worldPos4 = u_unis.m_invViewProjMat * Vec4(UV_TO_NDC(uv), depth, 1.0);
 	const Vec4 worldPos4 = u_unis.m_invViewProjMat * Vec4(UV_TO_NDC(uv), depth, 1.0);
@@ -127,7 +129,7 @@ void main()
 	{
 	{
 		// Acceptable distance
 		// Acceptable distance
 
 
-		shadowFactor = computeShadowFactorDirLight(u_unis.m_lightMatrix, worldPos, u_shadowMap);
+		shadowFactor = computeShadowFactorDirLight(u_unis.m_lightMatrix, worldPos, u_shadowMap, u_shadowMapSampler);
 	}
 	}
 	else
 	else
 	{
 	{

+ 21 - 19
shaders/VolumetricLightingAccumulation.glslp

@@ -23,24 +23,25 @@ const F32 PHASE_FUNCTION_ANISOTROPY = 0.3;
 
 
 layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = WORKGROUP_SIZE.z) in;
 layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = WORKGROUP_SIZE.z) in;
 
 
-layout(set = 0, binding = 0) writeonly uniform image3D u_volume;
-layout(set = 0, binding = 1) uniform sampler3D u_noiseTex;
-layout(set = 0, binding = 2) uniform sampler3D u_prevVolume;
+layout(set = 0, binding = 0) uniform sampler u_linearAnyRepeatSampler;
+layout(set = 0, binding = 1) uniform sampler u_linearAnyClampSampler;
 
 
-struct PushConsts
+layout(set = 0, binding = 2) writeonly uniform image3D u_volume;
+layout(set = 0, binding = 3) uniform texture3D u_noiseTex;
+layout(set = 0, binding = 4) uniform texture3D u_prevVolume;
+
+layout(push_constant, std430) uniform pc_
 {
 {
-	Vec4 m_noiseOffsetPad3;
+	Vec3 u_padding;
+	F32 u_noiseOffset;
 };
 };
-ANKI_PUSH_CONSTANTS(PushConsts, u_regs);
-
-#define u_noiseOffset u_regs.m_noiseOffsetPad3.x
 
 
 #define LIGHT_SET 0
 #define LIGHT_SET 0
-#define LIGHT_COMMON_UNIS_BINDING 3
-#define LIGHT_LIGHTS_BINDING 4
-#define LIGHT_INDIRECT_BINDING 7
-#define LIGHT_FOG_DENSITY_VOLUMES_BINDING 11
-#define LIGHT_CLUSTERS_BINDING 12
+#define LIGHT_COMMON_UNIS_BINDING 5
+#define LIGHT_LIGHTS_BINDING 6
+#define LIGHT_INDIRECT_BINDING 9
+#define LIGHT_FOG_DENSITY_VOLUMES_BINDING 13
+#define LIGHT_CLUSTERS_BINDING 14
 #include <shaders/ClusteredShadingCommon.glsl>
 #include <shaders/ClusteredShadingCommon.glsl>
 
 
 Vec3 g_globalInvocationID = Vec3(gl_GlobalInvocationID);
 Vec3 g_globalInvocationID = Vec3(gl_GlobalInvocationID);
@@ -49,7 +50,7 @@ Vec3 readRand()
 {
 {
 	Vec3 uv = (g_globalInvocationID + 0.5) / Vec3(NOISE_TEX_SIZE);
 	Vec3 uv = (g_globalInvocationID + 0.5) / Vec3(NOISE_TEX_SIZE);
 	uv.z += u_noiseOffset;
 	uv.z += u_noiseOffset;
-	return textureLod(u_noiseTex, uv, 0.0).rgb;
+	return textureLod(u_noiseTex, u_linearAnyRepeatSampler, uv, 0.0).rgb;
 }
 }
 
 
 Vec3 worldPosInsideClusterAndZViewSpace(Vec3 relativePos, out F32 negativeZViewSpace)
 Vec3 worldPosInsideClusterAndZViewSpace(Vec3 relativePos, out F32 negativeZViewSpace)
@@ -114,7 +115,8 @@ Vec4 accumulateLightsAndFog(U32 clusterIdx, Vec3 worldPos, F32 linearDepth)
 		{
 		{
 			const F32 cascadeCountf = F32(u_dirLight.m_cascadeCount);
 			const F32 cascadeCountf = F32(u_dirLight.m_cascadeCount);
 			const U32 cascadeIdx = min(U32(linearDepth * cascadeCountf), u_dirLight.m_cascadeCount - 1u);
 			const U32 cascadeIdx = min(U32(linearDepth * cascadeCountf), u_dirLight.m_cascadeCount - 1u);
-			factor *= computeShadowFactorDirLight(u_dirLight, cascadeIdx, worldPos, u_shadowTex);
+			factor *=
+				computeShadowFactorDirLight(u_dirLight, cascadeIdx, worldPos, u_shadowTex, u_linearAnyClampSampler);
 		}
 		}
 #endif
 #endif
 
 
@@ -135,7 +137,7 @@ Vec4 accumulateLightsAndFog(U32 clusterIdx, Vec3 worldPos, F32 linearDepth)
 #if ENABLE_SHADOWS
 #if ENABLE_SHADOWS
 		if(light.m_shadowAtlasTileScale >= 0.0)
 		if(light.m_shadowAtlasTileScale >= 0.0)
 		{
 		{
-			factor *= computeShadowFactorPointLight(light, frag2Light, u_shadowTex);
+			factor *= computeShadowFactorPointLight(light, frag2Light, u_shadowTex, u_linearAnyClampSampler);
 		}
 		}
 #endif
 #endif
 
 
@@ -160,7 +162,7 @@ Vec4 accumulateLightsAndFog(U32 clusterIdx, Vec3 worldPos, F32 linearDepth)
 		const F32 shadowmapLayerIdx = light.m_shadowmapId;
 		const F32 shadowmapLayerIdx = light.m_shadowmapId;
 		if(shadowmapLayerIdx >= 0.0)
 		if(shadowmapLayerIdx >= 0.0)
 		{
 		{
-			factor *= computeShadowFactorSpotLight(light, worldPos, u_shadowTex);
+			factor *= computeShadowFactorSpotLight(light, worldPos, u_shadowTex, u_linearAnyClampSampler);
 		}
 		}
 #endif
 #endif
 
 
@@ -181,7 +183,7 @@ Vec4 accumulateLightsAndFog(U32 clusterIdx, Vec3 worldPos, F32 linearDepth)
 		const F32 blendWeight = computeProbeBlendWeight(worldPos, aabbMin, aabbMax, 0.2);
 		const F32 blendWeight = computeProbeBlendWeight(worldPos, aabbMin, aabbMax, 0.2);
 		totalBlendWeight += blendWeight;
 		totalBlendWeight += blendWeight;
 
 
-		Vec3 c = textureLod(u_irradianceTex, Vec4(viewDir, cubemapIndex), 0.0).rgb;
+		Vec3 c = textureLod(u_irradianceTex, u_linearAnyClampSampler, Vec4(viewDir, cubemapIndex), 0.0).rgb;
 		c *= PI; // Irradiance is pre-divided with PI so fix it
 		c *= PI; // Irradiance is pre-divided with PI so fix it
 		diffIndirect += c * blendWeight;
 		diffIndirect += c * blendWeight;
 	}
 	}
@@ -254,7 +256,7 @@ void main()
 		const Vec3 uvw = Vec3(prevUv, k);
 		const Vec3 uvw = Vec3(prevUv, k);
 		if(all(lessThan(abs(uvw), Vec3(1.0))))
 		if(all(lessThan(abs(uvw), Vec3(1.0))))
 		{
 		{
-			const Vec4 prev = textureLod(u_prevVolume, uvw, 0.0);
+			const Vec4 prev = textureLod(u_prevVolume, u_linearAnyClampSampler, uvw, 0.0);
 
 
 			// Modulate
 			// Modulate
 			lightAndFog = mix(prev, lightAndFog, 1.0 / 16.0);
 			lightAndFog = mix(prev, lightAndFog, 1.0 / 16.0);

+ 444 - 0
shaders/gen_texture_funcs.py

@@ -0,0 +1,444 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2009-2019, Panagiotis Christopoulos Charitos and contributors.
+# All rights reserved.
+# Code licensed under the BSD License.
+# http://www.anki3d.org/LICENSE
+
+import enum
+import copy
+
+signatures = """
+gvec4 texture(gsampler1D sampler, float P [,float bias] )
+gvec4 texture(gsampler2D sampler, vec2 P [,float bias] )
+gvec4 texture(gsampler3D sampler, vec3 P [, float bias] )
+gvec4 texture(gsamplerCube sampler, vec3 P[, float bias] )
+float texture(sampler1DShadow sampler, vec3 P [, float bias])
+float texture(sampler2DShadow sampler, vec3 P [, float bias])
+float texture(samplerCubeShadow sampler, vec4 P [, float bias] )
+gvec4 texture(gsampler2DArray sampler, vec3 P [, float bias] )
+gvec4 texture(gsamplerCubeArray sampler, vec4 P [, float bias] )
+gvec4 texture(gsampler1DArray sampler, vec2 P [, float bias] )
+float texture(sampler1DArrayShadow sampler, vec3 P [, float bias] )
+float texture(sampler2DArrayShadow sampler, vec4 P)
+float texture(samplerCubeArrayShadow sampler, vec4 P, float compare)
+
+gvec4 textureProj(gsampler1D sampler, vec2 P [, float bias] )
+gvec4 textureProj(gsampler1D sampler, vec4 P [, float bias] )
+gvec4 textureProj(gsampler2D sampler, vec3 P [, float bias] )
+gvec4 textureProj(gsampler2D sampler, vec4 P [, float bias] )
+gvec4 textureProj(gsampler3D sampler, vec4 P [, float bias] )
+float textureProj(sampler1DShadow sampler, vec4 P [, float bias] )
+float textureProj(sampler2DShadow sampler, vec4 P [, float bias] )
+
+gvec4 textureLod(gsampler1D sampler, float P, float lod)
+gvec4 textureLod(gsampler2D sampler, vec2 P, float lod)
+gvec4 textureLod(gsampler3D sampler, vec3 P, float lod)
+gvec4 textureLod(gsamplerCube sampler, vec3 P, float lod)
+float textureLod(sampler2DShadow sampler, vec3 P, float lod)
+float textureLod(sampler1DShadow sampler, vec3 P, float lod)
+gvec4 textureLod(gsampler1DArray sampler, vec2 P, float lod)
+float textureLod(sampler1DArrayShadow sampler, vec3 P, float lod)
+gvec4 textureLod(gsampler2DArray sampler, vec3 P, float lod)
+gvec4 textureLod(gsamplerCubeArray sampler, vec4 P, float lod)
+
+gvec4 textureProjLod(gsampler1D sampler, vec2 P, float lod)
+gvec4 textureProjLod(gsampler1D sampler, vec4 P, float lod)
+gvec4 textureProjLod(gsampler2D sampler, vec3 P, float lod)
+gvec4 textureProjLod(gsampler2D sampler, vec4 P, float lod)
+gvec4 textureProjLod(gsampler3D sampler, vec4 P, float lod)
+float textureProjLod(sampler1DShadow sampler, vec4 P, float lod)
+float textureProjLod(sampler2DShadow sampler, vec4 P, float lod)
+
+gvec4 textureGrad(gsampler1D sampler, float P, float dPdx, float dPdy)
+gvec4 textureGrad(gsampler2D sampler, vec2 P, vec2 dPdx, vec2 dPdy)
+gvec4 textureGrad(gsampler3D sampler, vec3 P, vec3 dPdx, vec3 dPdy)
+gvec4 textureGrad(gsamplerCube sampler, vec3 P, vec3 dPdx, vec3 dPdy)
+float textureGrad(sampler1DShadow sampler, vec3 P, float dPdx, float dPdy)
+gvec4 textureGrad(gsampler1DArray sampler, vec2 P, float dPdx, float dPdy)
+gvec4 textureGrad(gsampler2DArray sampler, vec3 P, vec2 dPdx, vec2 dPdy)
+float textureGrad(sampler1DArrayShadow sampler, vec3 P, float dPdx, float dPdy)
+float textureGrad(sampler2DShadow sampler, vec3 P, vec2 dPdx, vec2 dPdy)
+float textureGrad(samplerCubeShadow sampler, vec4 P, vec3 dPdx, vec3 dPdy)
+float textureGrad(sampler2DArrayShadow sampler, vec4 P, vec2 dPdx, vec2 dPdy)
+gvec4 textureGrad(gsamplerCubeArray sampler, vec4 P, vec3 dPdx, vec3 dPdy)
+
+gvec4 textureProjGrad(gsampler1D sampler, vec2 P, float dPdx, float dPdy)
+gvec4 textureProjGrad(gsampler1D sampler, vec4 P, float dPdx, float dPdy)
+gvec4 textureProjGrad(gsampler2D sampler, vec3 P, vec2 dPdx, vec2 dPdy)
+gvec4 textureProjGrad(gsampler2D sampler, vec4 P, vec2 dPdx, vec2 dPdy)
+gvec4 textureProjGrad(gsampler3D sampler, vec4 P, vec3 dPdx, vec3 dPdy)
+float textureProjGrad(sampler1DShadow sampler, vec4 P, float dPdx, float dPdy)
+float textureProjGrad(sampler2DShadow sampler, vec4 P, vec2 dPdx, vec2 dPdy)
+"""
+
+
+class Type(enum.Enum):
+    NONE = 0
+    BASIC = 1
+    VEC = 2
+    COMBINED_IMAGE_SAMPLER = 3
+    SAMPLER = 4
+    TEXTURE = 5
+
+
+class TypeFlag(enum.IntEnum):
+    NONE = 0
+    FLOAT = 1 << 0
+    INT = 1 << 1
+    UINT = 1 << 2
+    GENERIC = 1 << 3
+    ARRAY = 1 << 4
+    SHADOW = 1 << 5
+    OPTIONAL_ARG = 1 << 6
+
+
+class TypeInfo:
+    def __init__(self):
+        self.type = Type.NONE
+        self.type_flags = TypeFlag.NONE
+        self.dim = 0
+
+    def __str__(self):
+        return str(self.__class__) + ": " + str(self.__dict__)
+
+
+class Arg:
+    def __init__(self):
+        self.type = TypeInfo()
+        self.name = None
+
+
+class Function:
+    def __init__(self):
+        self.return_type = TypeInfo()
+        self.func_name = None
+        self.args = []
+        self.is_generic = False
+        self.has_optional_arg = False
+        self.all_shader_stages = False
+
+    def __str__(self):
+        return str(self.__class__) + ": " + str(self.__dict__)
+
+
+def tokenize(line):
+    out = []
+    line = line.replace("(", " ")
+    line = line.replace(")", " ")
+    line = line.replace(",", " ")
+    line = line.replace("[", " ")
+    line = line.replace("]", " ")
+    tokens = line.split(" ")
+    for token in tokens:
+        token = token.strip()
+        if len(token) == 0:
+            continue
+        out.append(token)
+    return out
+
+
+def parse_type(s):
+    type = TypeInfo()
+    if s.find("sampler") >= 0:
+        type.type = Type.COMBINED_IMAGE_SAMPLER
+
+        if s[0] == "g":
+            type.type_flags |= TypeFlag.GENERIC
+        elif s[0] == "s":
+            type.type_flags |= TypeFlag.FLOAT
+        elif s[0] == "u":
+            type.type_flags |= TypeFlag.UINT
+        elif s[0] == "i":
+            type.type_flags |= TypeFlag.INT
+        else:
+            assert (False)
+
+        if s.find("1D") >= 0:
+            type.dim = 1
+        elif s.find("2D") >= 0:
+            type.dim = 2
+        elif s.find("3D") >= 0:
+            type.dim = 3
+        elif s.find("Cube") >= 0:
+            type.dim = 6
+
+        if s.find("Array") >= 0:
+            type.type_flags |= TypeFlag.ARRAY
+
+        if s.find("Shadow") >= 0:
+            type.type_flags |= TypeFlag.SHADOW
+
+    elif s.find("vec") >= 0:
+        type.type = Type.VEC
+
+        if s[0] == "g":
+            type.type_flags |= TypeFlag.GENERIC
+        elif s[0] == "u":
+            type.type_flags |= TypeFlag.UINT
+        elif s[0] == "i":
+            type.type_flags |= TypeFlag.INT
+        elif s[0] == "v":
+            type.type_flags |= TypeFlag.FLOAT
+        else:
+            assert (False)
+
+        if s[-1] == "4":
+            type.dim = 4
+        elif s[-1] == "3":
+            type.dim = 3
+        elif s[-1] == "2":
+            type.dim = 2
+        else:
+            assert (False)
+    elif s == "float":
+        type.dim = 1
+        type.type_flags |= TypeFlag.FLOAT
+        type.type = Type.BASIC
+    elif s == "int":
+        type.dim = 1
+        type.type_flags |= TypeFlag.INT
+        type.type = Type.BASIC
+    else:
+        assert (False)
+
+    return type
+
+
+def parse_func(tokens):
+    func = Function()
+
+    func.return_type = parse_type(tokens[0])
+    func.is_generic = func.is_generic or (
+        func.return_type.type_flags & TypeFlag.GENERIC)
+
+    func.func_name = tokens[1]
+
+    if func.func_name.find("Lod") >= 0:
+        func.all_shader_stages = True
+    else:
+        func.all_shader_stages = False
+
+    size = len(tokens)
+    for i in range(2, size, 2):
+        arg = Arg()
+
+        arg.type = parse_type(tokens[i])
+        arg.name = tokens[i + 1]
+
+        if arg.name == "bias":
+            arg.type.type_flags |= TypeFlag.OPTIONAL_ARG
+            func.has_optional_arg = True
+
+        func.is_generic = func.is_generic or (
+            arg.type.type_flags & TypeFlag.GENERIC)
+
+        func.args.append(arg)
+
+    return func
+
+
+def write_type(type):
+    out = ""
+    if type.type == Type.BASIC and type.type_flags & TypeFlag.FLOAT:
+        out += "float"
+    elif type.type == Type.BASIC and type.type_flags & TypeFlag.UINT:
+        out += "uint"
+    elif type.type == Type.BASIC and type.type_flags & TypeFlag.INT:
+        out += "int"
+    elif type.type == Type.VEC and type.type_flags & TypeFlag.FLOAT:
+        out += "vec" + str(type.dim)
+    elif type.type == Type.VEC and type.type_flags & TypeFlag.UINT:
+        out += "uvec" + str(type.dim)
+    elif type.type == Type.VEC and type.type_flags & TypeFlag.INT:
+        out += "ivec" + str(type.dim)
+    elif type.type == Type.COMBINED_IMAGE_SAMPLER:
+        if type.type_flags & TypeFlag.UINT:
+            out += "u"
+        elif type.type_flags & TypeFlag.INT:
+            out += "i"
+
+        out += "sampler"
+
+        if type.dim == 1:
+            out += "1D"
+        elif type.dim == 2:
+            out += "2D"
+        elif type.dim == 3:
+            out += "3D"
+        elif type.dim == 6:
+            out += "Cube"
+
+        if type.type_flags & TypeFlag.ARRAY:
+            out += "Array"
+
+        if type.type_flags & TypeFlag.SHADOW:
+            out += "Shadow"
+    elif type.type == Type.TEXTURE:
+        if type.type_flags & TypeFlag.UINT:
+            out += "u"
+        elif type.type_flags & TypeFlag.INT:
+            out += "i"
+
+        out += "texture"
+
+        if type.dim == 1:
+            out += "1D"
+        elif type.dim == 2:
+            out += "2D"
+        elif type.dim == 3:
+            out += "3D"
+        elif type.dim == 6:
+            out += "Cube"
+
+        if type.type_flags & TypeFlag.ARRAY:
+            out += "Array"
+    elif type.type == Type.SAMPLER:
+        out += "sampler"
+        if type.type_flags & TypeFlag.SHADOW:
+            out += "Shadow"
+    else:
+        assert False
+
+    return out
+
+
+def gen_split_sampler_tex_func(func):
+    out = ""
+
+    # Generate new function signatures
+    func_instances = []
+    if func.is_generic:
+        for generic_type in [TypeFlag.FLOAT, TypeFlag.UINT, TypeFlag.INT]:
+            new_func = copy.deepcopy(func)
+
+            # Return
+            if new_func.return_type.type_flags & TypeFlag.GENERIC:
+                new_func.return_type.type_flags &= ~TypeFlag.GENERIC
+                new_func.return_type.type_flags |= generic_type
+
+            # Args
+            for arg in new_func.args:
+                if arg.type.type_flags & TypeFlag.GENERIC:
+                    arg.type.type_flags &= ~TypeFlag.GENERIC
+                    arg.type.type_flags |= generic_type
+
+            func_instances.append(new_func)
+    else:
+        func_instances.append(copy.deepcopy(func))
+
+    # Populate optional arg version
+    if func.has_optional_arg:
+        extra_func_instances = []
+        for func in func_instances:
+            new_func = copy.deepcopy(func)
+
+            assert new_func.args[-1].type.type_flags & TypeFlag.OPTIONAL_ARG
+            new_func.args.pop()
+            extra_func_instances.append(new_func)
+
+        func_instances.extend(extra_func_instances)
+
+    for func in func_instances:
+        # Shader guard
+        if not func.all_shader_stages:
+            out += "#if defined(ANKI_FRAGMENT_SHADER)\n"
+
+        # Return type
+        out += write_type(func.return_type) + " "
+
+        # Func name
+        out += func.func_name
+        out += "("
+
+        # Args
+        for i in range(len(func.args)):
+            arg = func.args[i]
+
+            if arg.type.type == Type.COMBINED_IMAGE_SAMPLER:
+                # Write texture
+                tex_type = copy.deepcopy(arg.type)
+                tex_type.type = Type.TEXTURE
+                out += write_type(tex_type)
+                out += " tex, "
+
+                # Write sampler
+                sampler_type = copy.deepcopy(arg.type)
+                sampler_type.type = Type.SAMPLER
+                out += write_type(sampler_type)
+                out += " sampl"
+            else:
+                out += write_type(arg.type)
+                out += " " + arg.name
+
+            if i < len(func.args) - 1:
+                out += ", "
+
+        out += ")\n"
+
+        # Body
+        out += "{\n"
+
+        out += "\treturn " + func.func_name + "("
+
+        for i in range(len(func.args)):
+            arg = func.args[i]
+
+            if arg.type.type == Type.COMBINED_IMAGE_SAMPLER:
+                out += write_type(arg.type) + "(tex, sampl)"
+            else:
+                out += arg.name
+
+            if i < len(func.args) - 1:
+                out += ", "
+            else:
+                out += ");\n"
+
+        out += "}\n"
+
+        # Shader guard
+        if not func.all_shader_stages:
+            out += "#endif\n"
+
+        out += "\n"
+
+    return out
+
+
+def main():
+    print(
+        """// Copyright (C) 2009-2019, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+// WARNING: THIS FILE IS AUTO-GENERATED. DON'T CHANGE IT BY HAND.
+// This file contains some convenience texture functions.
+
+#pragma once
+""")
+    lines = signatures.splitlines()
+
+    for line in lines:
+        line = line.strip()
+
+        # Skip empty
+        if len(line) == 0:
+            continue
+
+        # Parse the func signature
+        func = parse_func(tokenize(line))
+
+        # Write the alternative func
+        func_code = gen_split_sampler_tex_func(func)
+        print(func_code)
+
+
+#    print("""layout(location = 0) out vec4 out_color;
+#void main()
+#{
+#	out_color = vec4(0);
+#}""")
+
+if __name__ == "__main__":
+    main()

+ 1 - 1
src/anki/gr/ShaderCompiler.cpp

@@ -430,7 +430,7 @@ Error ShaderCompiler::compile(CString source, const ShaderCompilerOptions& optio
 		ANKI_CHECK(
 		ANKI_CHECK(
 			file.open(StringAuto(m_alloc).sprintf("%s/.anki/cache/%d.dump.glsl", homeDir.cstr(), id++).toCString(),
 			file.open(StringAuto(m_alloc).sprintf("%s/.anki/cache/%d.dump.glsl", homeDir.cstr(), id++).toCString(),
 				FileOpenFlag::WRITE));
 				FileOpenFlag::WRITE));
-		ANKI_CHECK(file.write(&fullSrc[0], fullSrc.getLength() + 1));
+		ANKI_CHECK(file.write(finalSrc.cstr(), finalSrc.getLength() + 1));
 
 
 		homeDir.destroy(m_alloc);
 		homeDir.destroy(m_alloc);
 	}
 	}

+ 10 - 10
src/anki/renderer/ForwardShading.cpp

@@ -41,17 +41,17 @@ void ForwardShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgr
 		cmdb->setBlendFactors(0, BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA);
 		cmdb->setBlendFactors(0, BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA);
 
 
 		const ClusterBinOut& rsrc = ctx.m_clusterBinOut;
 		const ClusterBinOut& rsrc = ctx.m_clusterBinOut;
-		rgraphCtx.bindTextureAndSampler(
-			0, 0, m_r->getDepthDownscale().getHiZRt(), HIZ_HALF_DEPTH, m_r->getLinearSampler());
-		rgraphCtx.bindColorTextureAndSampler(
-			0, 1, m_r->getVolumetricLightingAccumulation().getRt(), m_r->getLinearSampler());
+		cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
 
 
-		bindUniforms(cmdb, 0, 2, ctx.m_lightShadingUniformsToken);
-		bindUniforms(cmdb, 0, 3, rsrc.m_pointLightsToken);
-		bindUniforms(cmdb, 0, 4, rsrc.m_spotLightsToken);
-		rgraphCtx.bindColorTextureAndSampler(0, 5, m_r->getShadowMapping().getShadowmapRt(), m_r->getLinearSampler());
-		bindStorage(cmdb, 0, 6, rsrc.m_clustersToken);
-		bindStorage(cmdb, 0, 7, rsrc.m_indicesToken);
+		rgraphCtx.bindTexture(0, 1, m_r->getDepthDownscale().getHiZRt(), HIZ_HALF_DEPTH);
+		rgraphCtx.bindColorTexture(0, 2, m_r->getVolumetricLightingAccumulation().getRt());
+
+		bindUniforms(cmdb, 0, 3, ctx.m_lightShadingUniformsToken);
+		bindUniforms(cmdb, 0, 4, rsrc.m_pointLightsToken);
+		bindUniforms(cmdb, 0, 5, rsrc.m_spotLightsToken);
+		rgraphCtx.bindColorTexture(0, 6, m_r->getShadowMapping().getShadowmapRt());
+		bindStorage(cmdb, 0, 7, rsrc.m_clustersToken);
+		bindStorage(cmdb, 0, 8, rsrc.m_indicesToken);
 
 
 		// Start drawing
 		// Start drawing
 		m_r->getSceneDrawer().drawRange(Pass::FS,
 		m_r->getSceneDrawer().drawRange(Pass::FS,

+ 13 - 15
src/anki/renderer/GBufferPost.cpp

@@ -85,28 +85,26 @@ void GBufferPost::run(RenderPassWorkContext& rgraphCtx)
 	cmdb->setBlendFactors(1, BlendFactor::ONE, BlendFactor::SRC_ALPHA, BlendFactor::ZERO, BlendFactor::ONE);
 	cmdb->setBlendFactors(1, BlendFactor::ONE, BlendFactor::SRC_ALPHA, BlendFactor::ZERO, BlendFactor::ONE);
 
 
 	// Bind all
 	// Bind all
-	rgraphCtx.bindTextureAndSampler(0,
-		0,
-		m_r->getGBuffer().getDepthRt(),
-		TextureSubresourceInfo(DepthStencilAspectBit::DEPTH),
-		m_r->getNearestSampler());
+	cmdb->bindSampler(0, 0, m_r->getSamplers().m_nearestNearestClamp);
 
 
-	bindUniforms(cmdb, 0, 1, ctx.m_lightShadingUniformsToken);
-	bindUniforms(cmdb, 0, 2, rsrc.m_decalsToken);
+	rgraphCtx.bindTexture(0, 1, m_r->getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
 
 
-	cmdb->bindTextureAndSampler(0,
-		3,
+	cmdb->bindSampler(0, 2, m_r->getSamplers().m_trilinearRepeat);
+
+	bindUniforms(cmdb, 0, 3, ctx.m_lightShadingUniformsToken);
+	bindUniforms(cmdb, 0, 4, rsrc.m_decalsToken);
+
+	cmdb->bindTexture(0,
+		5,
 		(rsrc.m_diffDecalTexView) ? rsrc.m_diffDecalTexView : m_r->getDummyTextureView(),
 		(rsrc.m_diffDecalTexView) ? rsrc.m_diffDecalTexView : m_r->getDummyTextureView(),
-		m_r->getTrilinearRepeatSampler(),
 		TextureUsageBit::SAMPLED_FRAGMENT);
 		TextureUsageBit::SAMPLED_FRAGMENT);
-	cmdb->bindTextureAndSampler(0,
-		4,
+	cmdb->bindTexture(0,
+		6,
 		(rsrc.m_specularRoughnessDecalTexView) ? rsrc.m_specularRoughnessDecalTexView : m_r->getDummyTextureView(),
 		(rsrc.m_specularRoughnessDecalTexView) ? rsrc.m_specularRoughnessDecalTexView : m_r->getDummyTextureView(),
-		m_r->getTrilinearRepeatSampler(),
 		TextureUsageBit::SAMPLED_FRAGMENT);
 		TextureUsageBit::SAMPLED_FRAGMENT);
 
 
-	bindStorage(cmdb, 0, 5, rsrc.m_clustersToken);
-	bindStorage(cmdb, 0, 6, rsrc.m_indicesToken);
+	bindStorage(cmdb, 0, 7, rsrc.m_clustersToken);
+	bindStorage(cmdb, 0, 8, rsrc.m_indicesToken);
 
 
 	// Draw
 	// Draw
 	cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3);
 	cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3);

+ 17 - 14
src/anki/renderer/Indirect.cpp

@@ -405,12 +405,13 @@ void Indirect::runLightShading(U32 faceIdx, RenderPassWorkContext& rgraphCtx)
 
 
 	// Set common state for all lights
 	// Set common state for all lights
 	// NOTE: Use nearest sampler because we don't want the result to sample the near tiles
 	// NOTE: Use nearest sampler because we don't want the result to sample the near tiles
-	rgraphCtx.bindColorTextureAndSampler(0, 2, m_ctx.m_gbufferColorRts[0], m_r->getNearestSampler());
-	rgraphCtx.bindColorTextureAndSampler(0, 3, m_ctx.m_gbufferColorRts[1], m_r->getNearestSampler());
-	rgraphCtx.bindColorTextureAndSampler(0, 4, m_ctx.m_gbufferColorRts[2], m_r->getNearestSampler());
+	cmdb->bindSampler(0, 2, m_r->getSamplers().m_nearestNearestClamp);
 
 
-	rgraphCtx.bindTextureAndSampler(
-		0, 5, m_ctx.m_gbufferDepthRt, TextureSubresourceInfo(DepthStencilAspectBit::DEPTH), m_r->getNearestSampler());
+	rgraphCtx.bindColorTexture(0, 3, m_ctx.m_gbufferColorRts[0]);
+	rgraphCtx.bindColorTexture(0, 4, m_ctx.m_gbufferColorRts[1]);
+	rgraphCtx.bindColorTexture(0, 5, m_ctx.m_gbufferColorRts[2]);
+
+	rgraphCtx.bindTexture(0, 6, m_ctx.m_gbufferDepthRt, TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
 
 
 	// Get shadowmap info
 	// Get shadowmap info
 	const Bool hasDirLight = probe.m_renderQueues[0]->m_directionalLight.m_uuid;
 	const Bool hasDirLight = probe.m_renderQueues[0]->m_directionalLight.m_uuid;
@@ -418,11 +419,9 @@ void Indirect::runLightShading(U32 faceIdx, RenderPassWorkContext& rgraphCtx)
 	{
 	{
 		ANKI_ASSERT(m_ctx.m_shadowMapRt.isValid());
 		ANKI_ASSERT(m_ctx.m_shadowMapRt.isValid());
 
 
-		rgraphCtx.bindTextureAndSampler(0,
-			6,
-			m_ctx.m_shadowMapRt,
-			TextureSubresourceInfo(DepthStencilAspectBit::DEPTH),
-			m_shadowMapping.m_shadowSampler);
+		cmdb->bindSampler(0, 7, m_shadowMapping.m_shadowSampler);
+
+		rgraphCtx.bindTexture(0, 8, m_ctx.m_shadowMapRt, TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
 	}
 	}
 
 
 	m_lightShading.m_deferred.drawLights(rqueue.m_viewProjectionMatrix,
 	m_lightShading.m_deferred.drawLights(rqueue.m_viewProjectionMatrix,
@@ -499,14 +498,18 @@ void Indirect::runIrradianceToRefl(U32 faceIdx, RenderPassWorkContext& rgraphCtx
 
 
 	cmdb->bindShaderProgram(m_irradianceToRefl.m_grProg);
 	cmdb->bindShaderProgram(m_irradianceToRefl.m_grProg);
 
 
-	rgraphCtx.bindColorTextureAndSampler(0, 0, m_ctx.m_gbufferColorRts[0], m_r->getNearestSampler());
-	rgraphCtx.bindColorTextureAndSampler(0, 1, m_ctx.m_gbufferColorRts[1], m_r->getNearestSampler());
-	rgraphCtx.bindColorTextureAndSampler(0, 2, m_ctx.m_gbufferColorRts[2], m_r->getNearestSampler());
+	// Bind resources
+	cmdb->bindSampler(0, 0, m_r->getSamplers().m_nearestNearestClamp);
+	cmdb->bindSampler(0, 1, m_r->getSamplers().m_trilinearClamp);
+
+	rgraphCtx.bindColorTexture(0, 2, m_ctx.m_gbufferColorRts[0]);
+	rgraphCtx.bindColorTexture(0, 3, m_ctx.m_gbufferColorRts[1]);
+	rgraphCtx.bindColorTexture(0, 4, m_ctx.m_gbufferColorRts[2]);
 
 
 	TextureSubresourceInfo subresource;
 	TextureSubresourceInfo subresource;
 	subresource.m_faceCount = 6;
 	subresource.m_faceCount = 6;
 	subresource.m_firstLayer = cacheEntryIdx;
 	subresource.m_firstLayer = cacheEntryIdx;
-	rgraphCtx.bindTextureAndSampler(0, 3, m_ctx.m_irradianceRt, subresource, m_r->getLinearSampler());
+	rgraphCtx.bindTexture(0, 5, m_ctx.m_irradianceRt, subresource);
 
 
 	Vec4 pushConsts(faceIdx);
 	Vec4 pushConsts(faceIdx);
 	cmdb->setPushConstants(&pushConsts, sizeof(pushConsts));
 	cmdb->setPushConstants(&pushConsts, sizeof(pushConsts));

+ 13 - 20
src/anki/renderer/LightShading.cpp

@@ -112,32 +112,25 @@ void LightShading::run(RenderPassWorkContext& rgraphCtx)
 
 
 		bindUniforms(cmdb, 0, 1, rsrc.m_pointLightsToken);
 		bindUniforms(cmdb, 0, 1, rsrc.m_pointLightsToken);
 		bindUniforms(cmdb, 0, 2, rsrc.m_spotLightsToken);
 		bindUniforms(cmdb, 0, 2, rsrc.m_spotLightsToken);
-		rgraphCtx.bindColorTextureAndSampler(0, 3, m_r->getShadowMapping().getShadowmapRt(), m_r->getLinearSampler());
+		rgraphCtx.bindColorTexture(0, 3, m_r->getShadowMapping().getShadowmapRt());
 
 
 		bindUniforms(cmdb, 0, 4, rsrc.m_probesToken);
 		bindUniforms(cmdb, 0, 4, rsrc.m_probesToken);
-		rgraphCtx.bindColorTextureAndSampler(
-			0, 5, m_r->getIndirect().getReflectionRt(), m_r->getTrilinearRepeatSampler());
-		rgraphCtx.bindColorTextureAndSampler(
-			0, 6, m_r->getIndirect().getIrradianceRt(), m_r->getTrilinearRepeatSampler());
-		cmdb->bindTextureAndSampler(0,
-			7,
-			m_r->getIndirect().getIntegrationLut(),
-			m_r->getIndirect().getIntegrationLutSampler(),
-			TextureUsageBit::SAMPLED_FRAGMENT);
+		rgraphCtx.bindColorTexture(0, 5, m_r->getIndirect().getReflectionRt());
+		rgraphCtx.bindColorTexture(0, 6, m_r->getIndirect().getIrradianceRt());
+		cmdb->bindTexture(0, 7, m_r->getIndirect().getIntegrationLut(), TextureUsageBit::SAMPLED_FRAGMENT);
 
 
 		bindStorage(cmdb, 0, 8, rsrc.m_clustersToken);
 		bindStorage(cmdb, 0, 8, rsrc.m_clustersToken);
 		bindStorage(cmdb, 0, 9, rsrc.m_indicesToken);
 		bindStorage(cmdb, 0, 9, rsrc.m_indicesToken);
 
 
-		rgraphCtx.bindColorTextureAndSampler(0, 10, m_r->getGBuffer().getColorRt(0), m_r->getNearestSampler());
-		rgraphCtx.bindColorTextureAndSampler(0, 11, m_r->getGBuffer().getColorRt(1), m_r->getNearestSampler());
-		rgraphCtx.bindColorTextureAndSampler(0, 12, m_r->getGBuffer().getColorRt(2), m_r->getNearestSampler());
-		rgraphCtx.bindTextureAndSampler(0,
-			13,
-			m_r->getGBuffer().getDepthRt(),
-			TextureSubresourceInfo(DepthStencilAspectBit::DEPTH),
-			m_r->getNearestSampler());
-		rgraphCtx.bindColorTextureAndSampler(0, 14, m_r->getSsr().getRt(), m_r->getLinearSampler());
-		rgraphCtx.bindColorTextureAndSampler(0, 15, m_r->getSsao().getRt(), m_r->getLinearSampler());
+		cmdb->bindSampler(0, 10, m_r->getSamplers().m_nearestNearestClamp);
+		cmdb->bindSampler(0, 11, m_r->getSamplers().m_trilinearRepeat);
+		rgraphCtx.bindColorTexture(0, 12, m_r->getGBuffer().getColorRt(0));
+		rgraphCtx.bindColorTexture(0, 13, m_r->getGBuffer().getColorRt(1));
+		rgraphCtx.bindColorTexture(0, 14, m_r->getGBuffer().getColorRt(2));
+		rgraphCtx.bindTexture(
+			0, 15, m_r->getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
+		rgraphCtx.bindColorTexture(0, 16, m_r->getSsr().getRt());
+		rgraphCtx.bindColorTexture(0, 17, m_r->getSsao().getRt());
 
 
 		// Draw
 		// Draw
 		drawQuad(cmdb);
 		drawQuad(cmdb);

+ 8 - 6
src/anki/renderer/Ssr.cpp

@@ -98,18 +98,20 @@ void Ssr::run(RenderPassWorkContext& rgraphCtx)
 	cmdb->bindShaderProgram(m_grProg[m_r->getFrameCount() & 1u]);
 	cmdb->bindShaderProgram(m_grProg[m_r->getFrameCount() & 1u]);
 
 
 	// Bind all
 	// Bind all
-	rgraphCtx.bindColorTextureAndSampler(0, 0, m_r->getGBuffer().getColorRt(1), m_r->getLinearSampler());
-	rgraphCtx.bindColorTextureAndSampler(0, 1, m_r->getGBuffer().getColorRt(2), m_r->getLinearSampler());
+	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
+
+	rgraphCtx.bindColorTexture(0, 1, m_r->getGBuffer().getColorRt(1));
+	rgraphCtx.bindColorTexture(0, 2, m_r->getGBuffer().getColorRt(2));
 
 
 	TextureSubresourceInfo hizSubresource; // Only first mip
 	TextureSubresourceInfo hizSubresource; // Only first mip
-	rgraphCtx.bindTextureAndSampler(0, 2, m_r->getDepthDownscale().getHiZRt(), hizSubresource, m_r->getLinearSampler());
+	rgraphCtx.bindTexture(0, 3, m_r->getDepthDownscale().getHiZRt(), hizSubresource);
 
 
-	rgraphCtx.bindColorTextureAndSampler(0, 3, m_r->getDownscaleBlur().getRt(), m_r->getTrilinearRepeatSampler());
+	rgraphCtx.bindColorTexture(0, 4, m_r->getDownscaleBlur().getRt());
 
 
-	rgraphCtx.bindImage(0, 4, m_runCtx.m_rt, TextureSubresourceInfo());
+	rgraphCtx.bindImage(0, 5, m_runCtx.m_rt, TextureSubresourceInfo());
 
 
 	// Bind uniforms
 	// Bind uniforms
-	SsrUniforms* unis = allocateAndBindUniforms<SsrUniforms*>(sizeof(SsrUniforms), cmdb, 0, 5);
+	SsrUniforms* unis = allocateAndBindUniforms<SsrUniforms*>(sizeof(SsrUniforms), cmdb, 0, 6);
 	unis->m_nearPad3 = Vec4(ctx.m_renderQueue->m_cameraNear);
 	unis->m_nearPad3 = Vec4(ctx.m_renderQueue->m_cameraNear);
 	unis->m_prevViewProjMatMulInvViewProjMat =
 	unis->m_prevViewProjMatMulInvViewProjMat =
 		ctx.m_prevMatrices.m_viewProjection * ctx.m_matrices.m_viewProjectionJitter.getInverse();
 		ctx.m_prevMatrices.m_viewProjection * ctx.m_matrices.m_viewProjectionJitter.getInverse();

+ 20 - 20
src/anki/renderer/VolumetricLightingAccumulation.cpp

@@ -108,36 +108,36 @@ void VolumetricLightingAccumulation::run(RenderPassWorkContext& rgraphCtx)
 	cmdb->bindShaderProgram(m_grProg);
 	cmdb->bindShaderProgram(m_grProg);
 
 
 	// Bind all
 	// Bind all
-	rgraphCtx.bindImage(0, 0, m_runCtx.m_rts[1], TextureSubresourceInfo());
+	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearRepeat);
+	cmdb->bindSampler(0, 1, m_r->getSamplers().m_trilinearClamp);
 
 
-	cmdb->bindTextureAndSampler(
-		0, 1, m_noiseTex->getGrTextureView(), m_r->getTrilinearRepeatSampler(), TextureUsageBit::SAMPLED_COMPUTE);
+	rgraphCtx.bindImage(0, 2, m_runCtx.m_rts[1], TextureSubresourceInfo());
 
 
-	rgraphCtx.bindColorTextureAndSampler(0, 2, m_runCtx.m_rts[0], m_r->getLinearSampler());
+	cmdb->bindTexture(0, 3, m_noiseTex->getGrTextureView(), TextureUsageBit::SAMPLED_COMPUTE);
 
 
-	bindUniforms(cmdb, 0, 3, ctx.m_lightShadingUniformsToken);
-	bindUniforms(cmdb, 0, 4, rsrc.m_pointLightsToken);
-	bindUniforms(cmdb, 0, 5, rsrc.m_spotLightsToken);
-	rgraphCtx.bindColorTextureAndSampler(0, 6, m_r->getShadowMapping().getShadowmapRt(), m_r->getLinearSampler());
+	rgraphCtx.bindColorTexture(0, 4, m_runCtx.m_rts[0]);
 
 
-	bindUniforms(cmdb, 0, 7, rsrc.m_probesToken);
-	cmdb->bindTextureAndSampler(
-		0, 8, m_r->getDummyTextureView(), m_r->getNearestSampler(), TextureUsageBit::SAMPLED_COMPUTE);
-	rgraphCtx.bindColorTextureAndSampler(0, 9, m_r->getIndirect().getIrradianceRt(), m_r->getTrilinearRepeatSampler());
-	cmdb->bindTextureAndSampler(
-		0, 10, m_r->getDummyTextureView(), m_r->getNearestSampler(), TextureUsageBit::SAMPLED_COMPUTE);
+	bindUniforms(cmdb, 0, 5, ctx.m_lightShadingUniformsToken);
+	bindUniforms(cmdb, 0, 6, rsrc.m_pointLightsToken);
+	bindUniforms(cmdb, 0, 7, rsrc.m_spotLightsToken);
+	rgraphCtx.bindColorTexture(0, 8, m_r->getShadowMapping().getShadowmapRt());
 
 
-	bindUniforms(cmdb, 0, 11, rsrc.m_fogDensityVolumesToken);
-	bindStorage(cmdb, 0, 12, rsrc.m_clustersToken);
-	bindStorage(cmdb, 0, 13, rsrc.m_indicesToken);
+	bindUniforms(cmdb, 0, 9, rsrc.m_probesToken);
+	cmdb->bindTexture(0, 10, m_r->getDummyTextureView(), TextureUsageBit::SAMPLED_COMPUTE);
+	rgraphCtx.bindColorTexture(0, 11, m_r->getIndirect().getIrradianceRt());
+	cmdb->bindTexture(0, 12, m_r->getDummyTextureView(), TextureUsageBit::SAMPLED_COMPUTE);
+
+	bindUniforms(cmdb, 0, 13, rsrc.m_fogDensityVolumesToken);
+	bindStorage(cmdb, 0, 14, rsrc.m_clustersToken);
+	bindStorage(cmdb, 0, 15, rsrc.m_indicesToken);
 
 
 	struct PushConsts
 	struct PushConsts
 	{
 	{
-		Vec4 m_noiseOffsetPad3;
+		Vec3 m_padding;
+		F32 m_noiseOffset;
 	} regs;
 	} regs;
-	regs.m_noiseOffsetPad3 = Vec4(0.0f);
 	const F32 texelSize = 1.0f / m_noiseTex->getDepth();
 	const F32 texelSize = 1.0f / m_noiseTex->getDepth();
-	regs.m_noiseOffsetPad3.x() = texelSize * F32(m_r->getFrameCount() % m_noiseTex->getDepth()) + texelSize / 2.0f;
+	regs.m_noiseOffset = texelSize * F32(m_r->getFrameCount() % m_noiseTex->getDepth()) + texelSize / 2.0f;
 
 
 	cmdb->setPushConstants(&regs, sizeof(regs));
 	cmdb->setPushConstants(&regs, sizeof(regs));