Просмотр исходного кода

Move some shaders to separate image samplers

Panagiotis Christopoulos Charitos 6 лет назад
Родитель
Сommit
b5329d7109

+ 9 - 8
shaders/Bloom.glslp

@@ -13,16 +13,17 @@
 layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = 1) in;
 
 // Vars
-layout(set = 0, binding = 0) uniform sampler2D u_tex; ///< Its the IS RT
+layout(set = 0, binding = 0) uniform sampler u_linearAnyClampSampler;
+layout(set = 0, binding = 1) uniform texture2D u_tex; ///< Its the IS RT
 
 ANKI_PUSH_CONSTANTS(Vec4, u_thresholdScalePad2);
 
-layout(set = 0, binding = 1, std140) readonly buffer ss0_
+layout(set = 0, binding = 2, std140) readonly buffer ss0_
 {
 	Vec4 u_averageLuminancePad3;
 };
 
-layout(set = 0, binding = 2) writeonly uniform image2D out_img;
+layout(set = 0, binding = 3) writeonly uniform image2D out_img;
 
 void main()
 {
@@ -36,11 +37,11 @@ void main()
 
 	const Vec2 uv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(FB_SIZE);
 
-	Vec3 color = textureLod(u_tex, uv, 0.0).rgb;
-	color += textureLodOffset(u_tex, uv, 0.0, ivec2(+1, +1)).rgb;
-	color += textureLodOffset(u_tex, uv, 0.0, ivec2(-1, -1)).rgb;
-	color += textureLodOffset(u_tex, uv, 0.0, ivec2(-1, +1)).rgb;
-	color += textureLodOffset(u_tex, uv, 0.0, ivec2(+1, -1)).rgb;
+	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;
 
 	color *= (1.0 / 5.0);
 

+ 18 - 15
shaders/BloomUpscale.glslp

@@ -12,10 +12,11 @@
 
 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_tex;
-layout(set = 0, binding = 1) uniform sampler2D u_lensDirtTex;
+layout(set = 0, binding = 0) uniform sampler u_linearAnyClampSampler;
+layout(set = 0, binding = 1) uniform texture2D u_tex;
+layout(set = 0, binding = 2) uniform texture2D u_lensDirtTex;
 
-layout(set = 0, binding = 2) writeonly uniform image2D out_img;
+layout(set = 0, binding = 3) writeonly uniform image2D out_img;
 
 // Constants
 const U32 MAX_GHOSTS = 4u;
@@ -26,15 +27,16 @@ const F32 CHROMATIC_DISTORTION = 3.0;
 #define ENABLE_HALO 1
 const F32 HALO_OPACITY = 0.5;
 
-Vec3 textureDistorted(sampler2D tex,
+Vec3 textureDistorted(texture2D tex,
+	sampler sampl,
 	Vec2 uv,
 	Vec2 direction, // direction of DISTORTION
 	Vec3 DISTORTION) // per-channel DISTORTION factor
 {
 #if ENABLE_CHROMATIC_DISTORTION
-	return Vec3(textureLod(tex, uv + direction * DISTORTION.r, 0.0).r,
-		textureLod(tex, uv + direction * DISTORTION.g, 0.0).g,
-		textureLod(tex, uv + direction * DISTORTION.b, 0.0).b);
+	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);
 #else
 	return textureLod(tex, uv, 0.0).rgb;
 #endif
@@ -61,7 +63,7 @@ Vec3 ssLensFlare(Vec2 uv)
 		F32 weight = length(Vec2(0.5) - offset) / LEN_OF_HALF;
 		weight = pow(1.0 - weight, 10.0);
 
-		result += textureDistorted(u_tex, offset, direction, DISTORTION) * weight;
+		result += textureDistorted(u_tex, u_linearAnyClampSampler, offset, direction, DISTORTION) * weight;
 	}
 
 	// Sample halo
@@ -69,22 +71,23 @@ Vec3 ssLensFlare(Vec2 uv)
 	const Vec2 haloVec = normalize(ghostVec) * HALO_WIDTH;
 	F32 weight = length(Vec2(0.5) - fract(flipUv + haloVec)) / LEN_OF_HALF;
 	weight = pow(1.0 - weight, 20.0);
-	result += textureDistorted(u_tex, flipUv + haloVec, direction, DISTORTION) * (weight * HALO_OPACITY);
+	result += textureDistorted(u_tex, u_linearAnyClampSampler, flipUv + haloVec, direction, DISTORTION)
+			  * (weight * HALO_OPACITY);
 #endif
 
 	// Lens dirt
-	result *= textureLod(u_lensDirtTex, uv, 0.0).rgb;
+	result *= textureLod(combineImageSampler(u_lensDirtTex, u_linearAnyClampSampler), uv, 0.0).rgb;
 
 	return result;
 }
 
 Vec3 upscale(Vec2 uv)
 {
-	Vec3 result = textureLod(u_tex, uv, 0.0).rgb;
-	result += textureLodOffset(u_tex, uv, 0.0, ivec2(+1, +1)).rgb;
-	result += textureLodOffset(u_tex, uv, 0.0, ivec2(+1, -1)).rgb;
-	result += textureLodOffset(u_tex, uv, 0.0, ivec2(-1, -1)).rgb;
-	result += textureLodOffset(u_tex, uv, 0.0, ivec2(-1, +1)).rgb;
+	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;
 
 	result *= (1.0 / 5.0);
 	return result;

+ 6 - 5
shaders/DepthDownscale.glslp

@@ -25,11 +25,12 @@ ANKI_PUSH_CONSTANTS(PushConsts, u_regs);
 #define u_copyToClientLevel u_regs.m_copyToClientLevelWriteLevel1Pad2.x
 #define u_writeLevel1 (u_regs.m_copyToClientLevelWriteLevel1Pad2.y == 1u)
 
-layout(set = 0, binding = 0) uniform sampler2D u_readTex;
-layout(set = 0, binding = 1) writeonly uniform image2D u_level0WriteImg;
-layout(set = 0, binding = 2) writeonly uniform image2D u_level1WriteImg;
+layout(set = 0, binding = 0) uniform sampler u_nearestAnyClampSampler;
+layout(set = 0, binding = 1) uniform texture2D u_readTex;
+layout(set = 0, binding = 2) writeonly uniform image2D u_level0WriteImg;
+layout(set = 0, binding = 3) writeonly uniform image2D u_level1WriteImg;
 
-layout(std430, set = 0, binding = 3) writeonly buffer s1_
+layout(std430, set = 0, binding = 4) writeonly buffer s1_
 {
 	F32 u_clientBuf[];
 };
@@ -58,7 +59,7 @@ void main()
 {
 	// Read depth
 	const Vec2 readUv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(u_level0WriteImgSize);
-	Vec4 depths = textureGather(u_readTex, readUv, 0);
+	Vec4 depths = textureGather(combineImageSampler(u_readTex, u_nearestAnyClampSampler), readUv, 0);
 
 	// Resolve & store the 1st level
 	F32 depth = resolveDepths(depths);

+ 11 - 11
shaders/DownscaleBlur.glsl

@@ -7,21 +7,21 @@
 
 #include <shaders/Common.glsl>
 
-layout(set = 0, binding = 0) uniform sampler2D u_tex;
+layout(set = 0, binding = 0) uniform sampler u_linearAnyClampSampler;
+layout(set = 0, binding = 1) uniform texture2D u_tex;
 
 #if defined(ANKI_COMPUTE_SHADER)
 layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = 1) in;
 
 // Push constants hold the size of the output image
-struct PushConsts
+layout(push_constant, row_major, std430) uniform pc_
 {
-	UVec4 m_outImageSizePad2;
+	UVec2 u_fbSize;
+	UVec2 u_padding;
 };
-ANKI_PUSH_CONSTANTS(PushConsts, u_regs);
-#	define u_fbSize (u_regs.m_outImageSizePad2.xy)
 
 Vec2 in_uv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(u_fbSize);
-layout(set = 0, binding = 1) writeonly uniform image2D out_img;
+layout(set = 0, binding = 2) writeonly uniform image2D out_img;
 Vec3 out_color;
 #else
 layout(location = 0) in Vec2 in_uv;
@@ -38,11 +38,11 @@ void main()
 	}
 #endif
 
-	out_color = textureLod(u_tex, in_uv, 0.0).rgb;
-	out_color += textureLodOffset(u_tex, in_uv, 0.0, IVec2(+1, +1)).rgb;
-	out_color += textureLodOffset(u_tex, in_uv, 0.0, IVec2(-1, -1)).rgb;
-	out_color += textureLodOffset(u_tex, in_uv, 0.0, IVec2(+1, -1)).rgb;
-	out_color += textureLodOffset(u_tex, in_uv, 0.0, IVec2(-1, +1)).rgb;
+	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 *= (1.0 / 5.0);
 

+ 30 - 24
shaders/FinalComposite.glslp

@@ -21,28 +21,30 @@
 #include <shaders/Functions.glsl>
 #include <shaders/MotionBlur.glsl>
 
-layout(set = 0, binding = 1) uniform sampler2D u_lightShadingRt;
-layout(set = 0, binding = 2) uniform sampler2D u_ppsBloomLfRt;
-layout(set = 0, binding = 3) uniform sampler3D u_lut;
-layout(set = 0, binding = 4) uniform sampler2DArray u_blueNoise;
-layout(set = 0, binding = 5) uniform sampler2D u_velocityRt;
-layout(set = 0, binding = 6) uniform sampler2D u_depthRt;
+#define TONEMAPPING_BINDING 0
+#define TONEMAPPING_SET 0
+#include <shaders/TonemappingResources.glsl>
+
+layout(set = 0, binding = 1) uniform sampler u_nearestAnyClampSampler;
+layout(set = 0, binding = 2) uniform sampler u_linearAnyClampSampler;
+layout(set = 0, binding = 3) uniform sampler u_trilinearRepeatSampler;
+
+layout(set = 0, binding = 4) uniform texture2D u_lightShadingRt;
+layout(set = 0, binding = 5) uniform texture2D u_ppsBloomLfRt;
+layout(set = 0, binding = 6) uniform texture3D u_lut;
+layout(set = 0, binding = 7) uniform texture2DArray u_blueNoise;
+layout(set = 0, binding = 8) uniform texture2D u_velocityRt;
+layout(set = 0, binding = 9) uniform texture2D u_depthRt;
 #if DBG_ENABLED
-layout(set = 0, binding = 7) uniform sampler2D u_dbgRt;
+layout(set = 0, binding = 10) uniform texture2D u_dbgRt;
 #endif
 
-struct PushConsts
+layout(push_constant, row_major, std430) uniform pc_
 {
-	Vec4 m_blueNoiseLayerPad3;
-	Mat4 m_prevViewProjMatMulInvViewProjMat;
+	Vec4 u_blueNoiseLayerPad3;
+	Mat4 u_prevViewProjMatMulInvViewProjMat;
 };
 
-ANKI_PUSH_CONSTANTS(PushConsts, u_regs);
-
-#define TONEMAPPING_BINDING 0
-#define TONEMAPPING_SET 0
-#include <shaders/TonemappingResources.glsl>
-
 layout(location = 0) in Vec2 in_uv;
 layout(location = 0) out Vec3 out_color;
 
@@ -53,7 +55,7 @@ Vec3 colorGrading(Vec3 color)
 
 	color = min(color, Vec3(1.0));
 	const Vec3 lutCoords = color * LUT_SCALE + LUT_OFFSET;
-	return textureLod(u_lut, lutCoords, 0.0).rgb;
+	return textureLod(combineImageSampler(u_lut, u_trilinearRepeatSampler), lutCoords, 0.0).rgb;
 }
 
 void main()
@@ -63,28 +65,32 @@ void main()
 	if(MOTION_BLUR_SAMPLES > 0u)
 	{
 		out_color = motionBlur(u_velocityRt,
+			u_nearestAnyClampSampler,
 			u_lightShadingRt,
+			u_linearAnyClampSampler,
 			u_depthRt,
+			u_nearestAnyClampSampler,
 			uv,
-			u_regs.m_prevViewProjMatMulInvViewProjMat,
+			u_prevViewProjMatMulInvViewProjMat,
 			MOTION_BLUR_SAMPLES);
 	}
 	else
 	{
-		out_color = textureLod(u_lightShadingRt, uv, 0.0).rgb;
+		out_color = textureLod(combineImageSampler(u_lightShadingRt, u_linearAnyClampSampler), uv, 0.0).rgb;
 	}
 
-	out_color = tonemap(out_color, UNIFORM(u_exposureThreshold0));
+	out_color = tonemap(out_color, u_exposureThreshold0);
 
 #if BLOOM_ENABLED
-	const Vec3 bloom = textureLod(u_ppsBloomLfRt, uv, 0.0).rgb;
+	const Vec3 bloom = textureLod(combineImageSampler(u_ppsBloomLfRt, u_linearAnyClampSampler), uv, 0.0).rgb;
 	out_color += bloom;
 #endif
 
 	out_color = colorGrading(out_color);
 
 #if BLUE_NOISE
-	Vec3 blueNoise = textureLod(u_blueNoise, Vec3(FB_SIZE / Vec2(64.0) * uv, u_regs.m_blueNoiseLayerPad3.x), 0.0).rgb;
+	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;
 	blueNoise = blueNoise * 2.0 - 1.0;
 	blueNoise = sign(blueNoise) * (1.0 - sqrt(1.0 - abs(blueNoise)));
 
@@ -93,12 +99,12 @@ void main()
 
 #if 0
 	{
-		out_color = textureLod(u_lightShadingRt, uv, 0.0).rgb;
+		out_color = textureLod(combineImageSampler(u_lightShadingRt, u_linearAnyClampSampler), uv, 0.0).rgb;
 	}
 #endif
 
 #if DBG_ENABLED
-	out_color += textureLod(u_dbgRt, uv, 0.0).rgb;
+	out_color += textureLod(combineImageSampler(u_dbgRt, u_linearAnyClampSampler), uv, 0.0).rgb;
 #endif
 }
 

+ 15 - 9
shaders/MotionBlur.glsl

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

+ 16 - 2
src/anki/gr/vulkan/DescriptorSet.cpp

@@ -511,18 +511,32 @@ void DescriptorSetState::flush(
 			switch(entry.m_bindingType[i])
 			{
 			case DescriptorType::COMBINED_TEXTURE_SAMPLER:
+				ANKI_ASSERT(
+					m_bindings[i].m_type == DescriptorType::COMBINED_TEXTURE_SAMPLER && "Have bound the wrong type");
 				toHash[toHashCount++] = m_bindings[i].m_uuids[1];
 				toHash[toHashCount++] = U64(m_bindings[i].m_texAndSampler.m_layout);
 				break;
+			case DescriptorType::TEXTURE:
+				ANKI_ASSERT(m_bindings[i].m_type == DescriptorType::TEXTURE && "Have bound the wrong type");
+				toHash[toHashCount] = U64(m_bindings[i].m_tex.m_layout);
+				break;
+			case DescriptorType::SAMPLER:
+				ANKI_ASSERT(m_bindings[i].m_type == DescriptorType::SAMPLER && "Have bound the wrong type");
+				break;
 			case DescriptorType::UNIFORM_BUFFER:
+				ANKI_ASSERT(m_bindings[i].m_type == DescriptorType::UNIFORM_BUFFER && "Have bound the wrong type");
+				toHash[toHashCount++] = m_bindings[i].m_buff.m_range;
+				dynamicOffsets[dynamicOffsetCount++] = m_bindings[i].m_buff.m_offset;
+				dynamicOffsetsDirty = dynamicOffsetsDirty || m_dynamicOffsetDirty.get(i);
+				break;
 			case DescriptorType::STORAGE_BUFFER:
+				ANKI_ASSERT(m_bindings[i].m_type == DescriptorType::STORAGE_BUFFER && "Have bound the wrong type");
 				toHash[toHashCount++] = m_bindings[i].m_buff.m_range;
-
 				dynamicOffsets[dynamicOffsetCount++] = m_bindings[i].m_buff.m_offset;
 				dynamicOffsetsDirty = dynamicOffsetsDirty || m_dynamicOffsetDirty.get(i);
 				break;
 			case DescriptorType::IMAGE:
-				// Nothing
+				ANKI_ASSERT(m_bindings[i].m_type == DescriptorType::IMAGE && "Have bound the wrong type");
 				break;
 			default:
 				ANKI_ASSERT(0);

+ 9 - 11
src/anki/renderer/Bloom.cpp

@@ -126,15 +126,16 @@ void Bloom::runExposure(RenderPassWorkContext& rgraphCtx)
 
 	TextureSubresourceInfo inputTexSubresource;
 	inputTexSubresource.m_firstMipmap = m_r->getDownscaleBlur().getMipmapCount() - 1;
-	rgraphCtx.bindTextureAndSampler(
-		0, 0, m_r->getDownscaleBlur().getRt(), inputTexSubresource, m_r->getLinearSampler());
+
+	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
+	rgraphCtx.bindTexture(0, 1, m_r->getDownscaleBlur().getRt(), inputTexSubresource);
 
 	Vec4 uniforms(m_exposure.m_threshold, m_exposure.m_scale, 0.0f, 0.0f);
 	cmdb->setPushConstants(&uniforms, sizeof(uniforms));
 
-	rgraphCtx.bindStorageBuffer(0, 1, m_r->getTonemapping().getAverageLuminanceBuffer());
+	rgraphCtx.bindStorageBuffer(0, 2, m_r->getTonemapping().getAverageLuminanceBuffer());
 
-	rgraphCtx.bindImage(0, 2, m_runCtx.m_exposureRt, TextureSubresourceInfo());
+	rgraphCtx.bindImage(0, 3, m_runCtx.m_exposureRt, TextureSubresourceInfo());
 
 	dispatchPPCompute(cmdb, m_workgroupSize[0], m_workgroupSize[1], m_exposure.m_width, m_exposure.m_height);
 }
@@ -145,14 +146,11 @@ void Bloom::runUpscaleAndSslf(RenderPassWorkContext& rgraphCtx)
 
 	cmdb->bindShaderProgram(m_upscale.m_grProg);
 
-	rgraphCtx.bindColorTextureAndSampler(0, 0, m_runCtx.m_exposureRt, m_r->getLinearSampler());
-	cmdb->bindTextureAndSampler(0,
-		1,
-		m_upscale.m_lensDirtTex->getGrTextureView(),
-		m_upscale.m_lensDirtTex->getSampler(),
-		TextureUsageBit::SAMPLED_COMPUTE);
+	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
+	rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_exposureRt);
+	cmdb->bindTexture(0, 2, m_upscale.m_lensDirtTex->getGrTextureView(), TextureUsageBit::SAMPLED_COMPUTE);
 
-	rgraphCtx.bindImage(0, 2, m_runCtx.m_upscaleRt, TextureSubresourceInfo());
+	rgraphCtx.bindImage(0, 3, m_runCtx.m_upscaleRt, TextureSubresourceInfo());
 
 	dispatchPPCompute(cmdb, m_workgroupSize[0], m_workgroupSize[1], m_upscale.m_width, m_upscale.m_height);
 }

+ 8 - 9
src/anki/renderer/DepthDownscale.cpp

@@ -156,33 +156,32 @@ void DepthDownscale::run(RenderPassWorkContext& rgraphCtx)
 	regs.m_copyToClientLevelWriteLevel1Pad2.y() = mipsToFill == MIPS_WRITTEN_PER_PASS;
 	cmdb->setPushConstants(&regs, sizeof(regs));
 
+	cmdb->bindSampler(0, 0, m_r->getSamplers().m_nearestNearestClamp);
+
 	// Bind input texure
 	if(level == 0)
 	{
-		rgraphCtx.bindTextureAndSampler(0,
-			0,
-			m_r->getGBuffer().getDepthRt(),
-			TextureSubresourceInfo(DepthStencilAspectBit::DEPTH),
-			m_r->getNearestSampler());
+		rgraphCtx.bindTexture(
+			0, 1, m_r->getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
 	}
 	else
 	{
 		TextureSubresourceInfo subresource;
 		subresource.m_firstMipmap = level - 1;
-		rgraphCtx.bindTextureAndSampler(0, 0, m_runCtx.m_hizRt, subresource, m_r->getNearestSampler());
+		rgraphCtx.bindTexture(0, 1, m_runCtx.m_hizRt, subresource);
 	}
 
 	// 1st level
 	TextureSubresourceInfo subresource;
 	subresource.m_firstMipmap = level;
-	rgraphCtx.bindImage(0, 1, m_runCtx.m_hizRt, subresource);
+	rgraphCtx.bindImage(0, 2, m_runCtx.m_hizRt, subresource);
 
 	// 2nd level
 	subresource.m_firstMipmap = (mipsToFill == MIPS_WRITTEN_PER_PASS) ? level + 1 : level; // Bind the next or the same
-	rgraphCtx.bindImage(0, 2, m_runCtx.m_hizRt, subresource);
+	rgraphCtx.bindImage(0, 3, m_runCtx.m_hizRt, subresource);
 
 	// Client buffer
-	cmdb->bindStorageBuffer(0, 3, m_copyToBuff.m_buff, 0, m_copyToBuff.m_buff->getSize());
+	cmdb->bindStorageBuffer(0, 4, m_copyToBuff.m_buff, 0, m_copyToBuff.m_buff->getSize());
 
 	// Done
 	dispatchPPCompute(cmdb, 8, 8, level0Width, level0Height);

+ 5 - 3
src/anki/renderer/DownscaleBlur.cpp

@@ -178,22 +178,24 @@ void DownscaleBlur::run(RenderPassWorkContext& rgraphCtx)
 	const U vpWidth = m_rtTex->getWidth() >> passIdx;
 	const U vpHeight = m_rtTex->getHeight() >> passIdx;
 
+	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
+
 	if(passIdx > 0)
 	{
 		TextureSubresourceInfo sampleSubresource;
 		sampleSubresource.m_firstMipmap = passIdx - 1;
-		rgraphCtx.bindTextureAndSampler(0, 0, m_runCtx.m_rt, sampleSubresource, m_r->getLinearSampler());
+		rgraphCtx.bindTexture(0, 1, m_runCtx.m_rt, sampleSubresource);
 	}
 	else
 	{
-		rgraphCtx.bindColorTextureAndSampler(0, 0, m_r->getTemporalAA().getRt(), m_r->getLinearSampler());
+		rgraphCtx.bindColorTexture(0, 1, m_r->getTemporalAA().getRt());
 	}
 
 	if(m_useCompute)
 	{
 		TextureSubresourceInfo sampleSubresource;
 		sampleSubresource.m_firstMipmap = passIdx;
-		rgraphCtx.bindImage(0, 1, m_runCtx.m_rt, sampleSubresource);
+		rgraphCtx.bindImage(0, 2, m_runCtx.m_rt, sampleSubresource);
 
 		UVec4 fbSize(vpWidth, vpHeight, 0, 0);
 		cmdb->setPushConstants(&fbSize, sizeof(fbSize));

+ 14 - 16
src/anki/renderer/FinalComposite.cpp

@@ -94,27 +94,25 @@ void FinalComposite::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx
 	cmdb->bindShaderProgram(m_grProgs[dbgEnabled]);
 
 	// Bind stuff
-	rgraphCtx.bindColorTextureAndSampler(0, 1, m_r->getTemporalAA().getRt(), m_r->getLinearSampler());
-
-	rgraphCtx.bindColorTextureAndSampler(0, 2, m_r->getBloom().getRt(), m_r->getLinearSampler());
-	cmdb->bindTextureAndSampler(
-		0, 3, m_lut->getGrTextureView(), m_r->getLinearSampler(), TextureUsageBit::SAMPLED_FRAGMENT);
-	cmdb->bindTextureAndSampler(
-		0, 4, m_blueNoise->getGrTextureView(), m_blueNoise->getSampler(), TextureUsageBit::SAMPLED_FRAGMENT);
-	rgraphCtx.bindColorTextureAndSampler(0, 5, m_r->getGBuffer().getColorRt(3), m_r->getNearestSampler());
-	rgraphCtx.bindTextureAndSampler(0,
-		6,
-		m_r->getGBuffer().getDepthRt(),
-		TextureSubresourceInfo(DepthStencilAspectBit::DEPTH),
-		m_r->getNearestSampler());
+	rgraphCtx.bindUniformBuffer(0, 0, m_r->getTonemapping().getAverageLuminanceBuffer());
+
+	cmdb->bindSampler(0, 1, m_r->getSamplers().m_nearestNearestClamp);
+	cmdb->bindSampler(0, 2, m_r->getSamplers().m_trilinearClamp);
+	cmdb->bindSampler(0, 3, m_r->getSamplers().m_trilinearRepeat);
+
+	rgraphCtx.bindColorTexture(0, 4, m_r->getTemporalAA().getRt());
+
+	rgraphCtx.bindColorTexture(0, 5, m_r->getBloom().getRt());
+	cmdb->bindTexture(0, 6, m_lut->getGrTextureView(), TextureUsageBit::SAMPLED_FRAGMENT);
+	cmdb->bindTexture(0, 7, m_blueNoise->getGrTextureView(), TextureUsageBit::SAMPLED_FRAGMENT);
+	rgraphCtx.bindColorTexture(0, 8, m_r->getGBuffer().getColorRt(3));
+	rgraphCtx.bindTexture(0, 9, m_r->getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
 
 	if(dbgEnabled)
 	{
-		rgraphCtx.bindColorTextureAndSampler(0, 7, m_r->getDbg().getRt(), m_r->getLinearSampler());
+		rgraphCtx.bindColorTexture(0, 10, m_r->getDbg().getRt());
 	}
 
-	rgraphCtx.bindUniformBuffer(0, 0, m_r->getTonemapping().getAverageLuminanceBuffer());
-
 	struct PushConsts
 	{
 		Vec4 m_blueNoiseLayerPad3;

+ 16 - 0
src/anki/renderer/Renderer.cpp

@@ -188,6 +188,22 @@ Error Renderer::initInternal(const ConfigSet& config)
 	sinit.m_minMagFilter = SamplingFilter::NEAREST;
 	m_nearesetNearestSampler = m_gr->newSampler(sinit);
 
+	// Init samplers
+	{
+		SamplerInitInfo sinit("Renderer");
+		sinit.m_addressing = SamplingAddressing::CLAMP;
+		sinit.m_mipmapFilter = SamplingFilter::NEAREST;
+		sinit.m_minMagFilter = SamplingFilter::NEAREST;
+		m_samplers.m_nearestNearestClamp = m_gr->newSampler(sinit);
+
+		sinit.m_minMagFilter = SamplingFilter::LINEAR;
+		sinit.m_mipmapFilter = SamplingFilter::LINEAR;
+		m_samplers.m_trilinearClamp = m_gr->newSampler(sinit);
+
+		sinit.m_addressing = SamplingAddressing::REPEAT;
+		m_samplers.m_trilinearRepeat = m_gr->newSampler(sinit);
+	}
+
 	initJitteredMats();
 
 	return Error::NONE;

+ 14 - 0
src/anki/renderer/Renderer.h

@@ -79,6 +79,14 @@ public:
 	Second m_lightBinTime ANKI_DBG_NULLIFY;
 };
 
+class RendererPrecreatedSamplers
+{
+public:
+	SamplerPtr m_nearestNearestClamp;
+	SamplerPtr m_trilinearClamp;
+	SamplerPtr m_trilinearRepeat;
+};
+
 /// Offscreen renderer.
 class Renderer
 {
@@ -318,6 +326,11 @@ anki_internal:
 		return m_dummyBuff;
 	}
 
+	const RendererPrecreatedSamplers& getSamplers() const
+	{
+		return m_samplers;
+	}
+
 	SamplerPtr getNearestSampler() const
 	{
 		return m_nearestSampler;
@@ -422,6 +435,7 @@ private:
 	SamplerPtr m_linearSampler;
 	SamplerPtr m_trilinearRepeatSampler;
 	SamplerPtr m_nearesetNearestSampler;
+	RendererPrecreatedSamplers m_samplers;
 
 	ShaderProgramResourcePtr m_clearTexComputeProg;