void LightingParser_ResolveGBuffer( Metal::DeviceContext& context, LightingParserContext& parserContext, MainTargetsBox& mainTargets, LightingResolveTextureBox& lightingResTargets) { Metal::GPUProfiler::DebugAnnotation anno(context, L"ResolveGBuffer"); const bool doSampleFrequencyOptimisation = Tweakable("SampleFrequencyOptimisation", true); LightingResolveContext lightingResolveContext(mainTargets); const unsigned samplingCount = lightingResolveContext.GetSamplingCount(); const bool useMsaaSamplers = lightingResolveContext.UseMsaaSamplers(); auto& resolveRes = Techniques::FindCachedBoxDep2<LightingResolveResources>(samplingCount); // // Our inputs is the prepared gbuffer // -- we resolve the lighting and write out a "lighting resolve texture" // if (doSampleFrequencyOptimisation && samplingCount>1) { context.Bind(resolveRes._alwaysWriteToStencil, 0xff); // todo -- instead of clearing the stencil every time, how // about doing a progressive walk through all of the bits! context.ClearStencil(mainTargets._secondaryDepthBuffer, 0); context.Bind(ResourceList<Metal::RenderTargetView, 0>(), &mainTargets._secondaryDepthBuffer); context.BindPS(MakeResourceList(mainTargets._msaaDepthBufferSRV, mainTargets._gbufferRTVsSRV[1])); SetupVertexGeneratorShader(context); CATCH_ASSETS_BEGIN context.Bind(*resolveRes._perSampleMask); context.Draw(4); CATCH_ASSETS_END(parserContext) }
unsigned LightingParser_BindLightResolveResources( Metal::DeviceContext& context, LightingParserContext& parserContext) { // bind resources and constants that are required for lighting resolve operations // these are needed in both deferred and forward shading modes... But they are // bound at different times in different modes CATCH_ASSETS_BEGIN unsigned skyTextureProjection = SkyTextureParts(parserContext.GetSceneParser()->GetGlobalLightingDesc()).BindPS(context, 11); context.BindPS(MakeResourceList(10, ::Assets::GetAssetDep<RenderCore::Assets::DeferredShaderResource>("game/xleres/DefaultResources/balanced_noise.dds:LT").GetShaderResource())); context.BindPS(MakeResourceList(16, ::Assets::GetAssetDep<RenderCore::Assets::DeferredShaderResource>("game/xleres/DefaultResources/GGXTable.dds:LT").GetShaderResource())); context.BindPS(MakeResourceList(9, Metal::ConstantBuffer(&GlobalMaterialOverride, sizeof(GlobalMaterialOverride)))); return skyTextureProjection; CATCH_ASSETS_END(parserContext) return 0; }
} CATCH(...) { savedTargets.ResetToOldTargets(metalContext); throw; } CATCH_END savedTargets.ResetToOldTargets(metalContext); } // // Now we have to read-back the results from the cube map, // and weight by the solid angle. Let's do this with a // compute shader. We'll split each face into 16 squares, and // assign a separate thread to each. The output will be a 4x4x5 // texture of floats // metalContext.BindCS(MakeResourceList(_pimpl->_cubeSRV)); metalContext.BindCS(MakeResourceList(_pimpl->_miniUAV)); // metalContext.Bind(*_pimpl->_stepDownShader); metalContext.Bind( ::Assets::GetAssetDep<Metal::ComputeShader>( "game/xleres/toolshelper/aogenprocess.sh:CubeMapStepDown:cs_*")); metalContext.Dispatch(1u); metalContext.UnbindCS<Metal::ShaderResourceView>(0, 1); metalContext.UnbindCS<Metal::UnorderedAccessView>(0, 1); auto& bufferUploads = RenderCore::Assets::Services::GetBufferUploads(); auto readback = bufferUploads.Resource_ReadBack(*_pimpl->_miniLocator); #if defined(GEN_AO_DEBUG)