Переглянути джерело

Add the ability to show various render targets in FinalComposite

Panagiotis Christopoulos Charitos 5 роки тому
батько
коміт
a41184c515

+ 8 - 6
shaders/FinalComposite.ankiprog

@@ -6,6 +6,7 @@
 #pragma anki mutator BLUE_NOISE 0 1
 #pragma anki mutator BLOOM_ENABLED 0 1
 #pragma anki mutator DBG_ENABLED 0 1
+#pragma anki mutator DBG_RENDER_TARGET_ENABLED 0 1
 
 ANKI_SPECIALIZATION_CONSTANT_U32(LUT_SIZE, 0, 1);
 ANKI_SPECIALIZATION_CONSTANT_UVEC2(FB_SIZE, 1, UVec2(1, 1));
@@ -36,7 +37,10 @@ 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 = 10) uniform texture2D u_dbgRt;
+layout(set = 0, binding = 10) uniform texture2D u_dbgOutlineRt;
+#endif
+#if DBG_RENDER_TARGET_ENABLED
+layout(set = 0, binding = 11) uniform texture2D u_dbgRt;
 #endif
 
 layout(push_constant, row_major, std430) uniform pc_
@@ -97,14 +101,12 @@ void main()
 	out_color += blueNoise / 255.0;
 #endif
 
-#if 0
-	{
-		out_color = textureLod(u_lightShadingRt, u_linearAnyClampSampler, uv, 0.0).rgb;
-	}
+#if DBG_RENDER_TARGET_ENABLED
+	out_color = textureLod(u_dbgRt, u_linearAnyClampSampler, uv, 0.0).rgb;
 #endif
 
 #if DBG_ENABLED
-	const Vec4 dbg = textureLod(u_dbgRt, u_linearAnyClampSampler, uv, 0.0);
+	const Vec4 dbg = textureLod(u_dbgOutlineRt, u_linearAnyClampSampler, uv, 0.0);
 	out_color = mix(out_color, dbg.rgb, dbg.a);
 #endif
 }

+ 1 - 0
src/anki/renderer/Common.h

@@ -20,6 +20,7 @@ namespace anki
 
 // Forward
 class Renderer;
+class RendererObject;
 class GBuffer;
 class GBufferPost;
 class ShadowMapping;

+ 28 - 9
src/anki/renderer/FinalComposite.cpp

@@ -48,19 +48,22 @@ Error FinalComposite::initInternal(const ConfigSet& config)
 	ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
 	variantInitInfo.addMutation("BLUE_NOISE", 1);
 	variantInitInfo.addMutation("BLOOM_ENABLED", 1);
-	variantInitInfo.addMutation("DBG_ENABLED", 0);
 	variantInitInfo.addConstant("LUT_SIZE", U32(LUT_SIZE));
 	variantInitInfo.addConstant("LUT_SIZE", U32(LUT_SIZE));
 	variantInitInfo.addConstant("FB_SIZE", UVec2(m_r->getWidth(), m_r->getHeight()));
 	variantInitInfo.addConstant("MOTION_BLUR_SAMPLES", config.getNumberU32("r_motionBlurSamples"));
 
-	const ShaderProgramResourceVariant* variant;
-	m_prog->getOrCreateVariant(variantInitInfo, variant);
-	m_grProgs[0] = variant->getProgram();
-
-	variantInitInfo.addMutation("DBG_ENABLED", 1);
-	m_prog->getOrCreateVariant(variantInitInfo, variant);
-	m_grProgs[1] = variant->getProgram();
+	for(U32 dbg = 0; dbg < 2; ++dbg)
+	{
+		for(U32 dbgRt = 0; dbgRt < 2; ++dbgRt)
+		{
+			const ShaderProgramResourceVariant* variant;
+			variantInitInfo.addMutation("DBG_ENABLED", dbg);
+			variantInitInfo.addMutation("DBG_RENDER_TARGET_ENABLED", dbgRt);
+			m_prog->getOrCreateVariant(variantInitInfo, variant);
+			m_grProgs[dbg][dbgRt] = variant->getProgram();
+		}
+	}
 
 	return Error::NONE;
 }
@@ -91,8 +94,11 @@ void FinalComposite::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	const Bool dbgEnabled = m_r->getDbg().getEnabled();
+	RenderTargetHandle dbgRt;
+	Bool dbgRtValid;
+	m_r->getCurrentDebugRenderTarget(dbgRt, dbgRtValid);
 
-	cmdb->bindShaderProgram(m_grProgs[dbgEnabled]);
+	cmdb->bindShaderProgram(m_grProgs[dbgEnabled][dbgRtValid]);
 
 	// Bind stuff
 	rgraphCtx.bindUniformBuffer(0, 0, m_r->getTonemapping().getAverageLuminanceBuffer());
@@ -114,6 +120,11 @@ void FinalComposite::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx
 		rgraphCtx.bindColorTexture(0, 10, m_r->getDbg().getRt());
 	}
 
+	if(dbgRtValid)
+	{
+		rgraphCtx.bindColorTexture(0, 11, dbgRt);
+	}
+
 	struct PushConsts
 	{
 		Vec4 m_blueNoiseLayerPad3;
@@ -161,6 +172,14 @@ void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 
 	pass.newDependency({m_r->getGBuffer().getColorRt(3), TextureUsageBit::SAMPLED_FRAGMENT});
 	pass.newDependency({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+
+	RenderTargetHandle dbgRt;
+	Bool dbgRtValid;
+	m_r->getCurrentDebugRenderTarget(dbgRt, dbgRtValid);
+	if(dbgRtValid)
+	{
+		pass.newDependency({dbgRt, TextureUsageBit::SAMPLED_FRAGMENT});
+	}
 }
 
 } // end namespace anki

+ 1 - 1
src/anki/renderer/FinalComposite.h

@@ -35,7 +35,7 @@ private:
 	FramebufferDescription m_fbDescr;
 
 	ShaderProgramResourcePtr m_prog;
-	Array<ShaderProgramPtr, 2> m_grProgs; ///< One with Dbg and one without
+	Array2d<ShaderProgramPtr, 2, 2> m_grProgs; ///< [Debug on or off][Dbg render target on or off]
 
 	TextureResourcePtr m_lut; ///< Color grading lookup texture.
 	TextureResourcePtr m_blueNoise;

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

@@ -44,6 +44,12 @@ Renderer::Renderer()
 
 Renderer::~Renderer()
 {
+	for(DebugRtInfo& info : m_debugRts)
+	{
+		info.m_rtName.destroy(getAllocator());
+	}
+	m_debugRts.destroy(getAllocator());
+	m_currentDebugRtName.destroy(getAllocator());
 }
 
 Error Renderer::init(ThreadHive* hive,
@@ -599,4 +605,53 @@ void Renderer::updateLightShadingUniforms(RenderingContext& ctx) const
 	}
 }
 
+void Renderer::registerDebugRenderTarget(RendererObject* obj, CString rtName)
+{
+#if ANKI_ASSERTS_ENABLED
+	for(const DebugRtInfo& inf : m_debugRts)
+	{
+		ANKI_ASSERT(inf.m_rtName != rtName && "Choose different name");
+	}
+#endif
+
+	ANKI_ASSERT(obj);
+	DebugRtInfo inf;
+	inf.m_obj = obj;
+	inf.m_rtName.create(getAllocator(), rtName);
+
+	m_debugRts.emplaceBack(getAllocator(), std::move(inf));
+}
+
+void Renderer::getCurrentDebugRenderTarget(RenderTargetHandle& handle, Bool& handleValid)
+{
+	if(ANKI_LIKELY(m_currentDebugRtName.isEmpty()))
+	{
+		handleValid = false;
+		return;
+	}
+
+	RendererObject* obj = nullptr;
+	for(const DebugRtInfo& inf : m_debugRts)
+	{
+		if(inf.m_rtName == m_currentDebugRtName)
+		{
+			obj = inf.m_obj;
+		}
+	}
+	ANKI_ASSERT(obj);
+
+	obj->getDebugRenderTarget(m_currentDebugRtName, handle);
+	handleValid = true;
+}
+
+void Renderer::setCurrentDebugRenderTarget(CString rtName)
+{
+	m_currentDebugRtName.destroy(getAllocator());
+
+	if(!rtName.isEmpty() && rtName.getLength() > 0)
+	{
+		m_currentDebugRtName.create(getAllocator(), rtName);
+	}
+}
+
 } // end namespace anki

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

@@ -364,6 +364,19 @@ public:
 		return *m_threadHive;
 	}
 
+	/// @name Debug render targets
+	/// @{
+
+	/// Register a debug render target.
+	void registerDebugRenderTarget(RendererObject* obj, CString rtName);
+
+	/// Set the render target you want to show.
+	void setCurrentDebugRenderTarget(CString rtName);
+
+	// Need to call it after the handle is set by the RenderGraph.
+	void getCurrentDebugRenderTarget(RenderTargetHandle& handle, Bool& handleValid);
+	/// @}
+
 private:
 	ResourceManager* m_resources = nullptr;
 	ThreadHive* m_threadHive = nullptr;
@@ -432,6 +445,15 @@ private:
 	RendererStats m_stats;
 	Bool m_statsEnabled = false;
 
+	class DebugRtInfo
+	{
+	public:
+		RendererObject* m_obj;
+		String m_rtName;
+	};
+	DynamicArray<DebugRtInfo> m_debugRts;
+	String m_currentDebugRtName;
+
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
 
 	void initJitteredMats();

+ 5 - 0
src/anki/renderer/RendererObject.cpp

@@ -77,4 +77,9 @@ U32 RendererObject::computeNumberOfSecondLevelCommandBuffers(U32 drawcallCount)
 	return secondLevelCmdbCount;
 }
 
+void RendererObject::registerDebugRenderTarget(CString rtName)
+{
+	m_r->registerDebugRenderTarget(this, rtName);
+}
+
 } // end namespace anki

+ 7 - 0
src/anki/renderer/RendererObject.h

@@ -38,6 +38,11 @@ public:
 
 	HeapAllocator<U8> getAllocator() const;
 
+	virtual void getDebugRenderTarget(CString rtName, RenderTargetHandle& handle) const
+	{
+		ANKI_ASSERT(!"Object doesn't support that");
+	}
+
 protected:
 	Renderer* m_r; ///< Know your father
 
@@ -112,6 +117,8 @@ protected:
 		bindStorage(cmdb, set, binding, token);
 		return ptr;
 	}
+
+	void registerDebugRenderTarget(CString rtName);
 };
 /// @}
 

+ 7 - 0
src/anki/renderer/Ssgi.h

@@ -22,6 +22,7 @@ public:
 	Ssgi(Renderer* r)
 		: RendererObject(r)
 	{
+		registerDebugRenderTarget("SSGI");
 	}
 
 	~Ssgi();
@@ -36,6 +37,12 @@ public:
 		return m_runCtx.m_rt;
 	}
 
+	void getDebugRenderTarget(CString rtName, RenderTargetHandle& handle) const override
+	{
+		ANKI_ASSERT(rtName == "SSGI");
+		handle = m_runCtx.m_rt;
+	}
+
 private:
 	class
 	{

+ 7 - 0
src/anki/renderer/Ssr.h

@@ -20,6 +20,7 @@ public:
 	Ssr(Renderer* r)
 		: RendererObject(r)
 	{
+		registerDebugRenderTarget("SSR");
 	}
 
 	~Ssr();
@@ -54,6 +55,12 @@ private:
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
 
 	void run(RenderPassWorkContext& rgraphCtx);
+
+	void getDebugRenderTarget(CString rtName, RenderTargetHandle& handle) const override
+	{
+		ANKI_ASSERT(rtName == "SSR");
+		handle = m_runCtx.m_rt;
+	}
 };
 /// @}
 

+ 57 - 4
src/anki/script/Renderer.cpp

@@ -23,7 +23,7 @@ static MainRenderer* getMainRenderer(lua_State* l)
 }
 
 LuaUserDataTypeInfo luaUserDataTypeInfoDbg = {
-	-2784798555522127122, "Dbg", LuaUserData::computeSizeForGarbageCollected<Dbg>(), nullptr, nullptr};
+	6963341295180544814, "Dbg", LuaUserData::computeSizeForGarbageCollected<Dbg>(), nullptr, nullptr};
 
 template<>
 const LuaUserDataTypeInfo& LuaUserData::getDataTypeInfoFor<Dbg>()
@@ -134,8 +134,11 @@ static inline void wrapDbg(lua_State* l)
 	lua_settop(l, 0);
 }
 
-LuaUserDataTypeInfo luaUserDataTypeInfoMainRenderer = {
-	919289102518575326, "MainRenderer", LuaUserData::computeSizeForGarbageCollected<MainRenderer>(), nullptr, nullptr};
+LuaUserDataTypeInfo luaUserDataTypeInfoMainRenderer = {-2700850970637484325,
+	"MainRenderer",
+	LuaUserData::computeSizeForGarbageCollected<MainRenderer>(),
+	nullptr,
+	nullptr};
 
 template<>
 const LuaUserDataTypeInfo& LuaUserData::getDataTypeInfoFor<MainRenderer>()
@@ -170,7 +173,7 @@ static inline int pwrapMainRenderergetAspectRatio(lua_State* l)
 	F32 ret = self->getAspectRatio();
 
 	// Push return value
-	lua_pushnumber(l, ret);
+	lua_pushnumber(l, lua_Number(ret));
 
 	return 1;
 }
@@ -188,11 +191,61 @@ static int wrapMainRenderergetAspectRatio(lua_State* l)
 	return 0;
 }
 
+/// Pre-wrap method MainRenderer::setCurrentDebugRenderTarget.
+static inline int pwrapMainRenderersetCurrentDebugRenderTarget(lua_State* l)
+{
+	LuaUserData* ud;
+	(void)ud;
+	void* voidp;
+	(void)voidp;
+	PtrSize size;
+	(void)size;
+
+	if(ANKI_UNLIKELY(LuaBinder::checkArgsCount(l, 2)))
+	{
+		return -1;
+	}
+
+	// Get "this" as "self"
+	if(LuaBinder::checkUserData(l, 1, luaUserDataTypeInfoMainRenderer, ud))
+	{
+		return -1;
+	}
+
+	MainRenderer* self = ud->getData<MainRenderer>();
+
+	// Pop arguments
+	const char* arg0;
+	if(ANKI_UNLIKELY(LuaBinder::checkString(l, 2, arg0)))
+	{
+		return -1;
+	}
+
+	// Call the method
+	self->getOffscreenRenderer().setCurrentDebugRenderTarget(arg0);
+
+	return 0;
+}
+
+/// Wrap method MainRenderer::setCurrentDebugRenderTarget.
+static int wrapMainRenderersetCurrentDebugRenderTarget(lua_State* l)
+{
+	int res = pwrapMainRenderersetCurrentDebugRenderTarget(l);
+	if(res >= 0)
+	{
+		return res;
+	}
+
+	lua_error(l);
+	return 0;
+}
+
 /// Wrap class MainRenderer.
 static inline void wrapMainRenderer(lua_State* l)
 {
 	LuaBinder::createClass(l, &luaUserDataTypeInfoMainRenderer);
 	LuaBinder::pushLuaCFuncMethod(l, "getAspectRatio", wrapMainRenderergetAspectRatio);
+	LuaBinder::pushLuaCFuncMethod(l, "setCurrentDebugRenderTarget", wrapMainRenderersetCurrentDebugRenderTarget);
 	lua_settop(l, 0);
 }
 

+ 8 - 2
src/anki/script/Renderer.xml

@@ -11,7 +11,7 @@
 #include <anki/Renderer.h>
 
 namespace anki {
-	
+
 static MainRenderer* getMainRenderer(lua_State* l)
 {
 	LuaBinder* binder = nullptr;
@@ -20,7 +20,7 @@ static MainRenderer* getMainRenderer(lua_State* l)
 	MainRenderer* r = binder->getOtherSystems().m_renderer;
 	ANKI_ASSERT(r);
 	return r;
-}	
+}
 ]]></head>
 
 	<classes>
@@ -41,6 +41,12 @@ static MainRenderer* getMainRenderer(lua_State* l)
 				<method name="getAspectRatio">
 					<return>F32</return>
 				</method>
+				<method name="setCurrentDebugRenderTarget">
+					<overrideCall>self->getOffscreenRenderer().setCurrentDebugRenderTarget(arg0);</overrideCall>
+					<args>
+						<arg>CString</arg>
+					</args>
+				</method>
 			</methods>
 		</class>
 	</classes>