internal static IBorrowedUavTexture Run(ISrvBindable src) { IBorrowedUavTexture uav0 = MyManagers.RwTexturesPool.BorrowUav("MyLuminanceAverage.Uav0", Format.R32G32_Float); IBorrowedUavTexture uav1 = MyManagers.RwTexturesPool.BorrowUav("MyLuminanceAverage.Uav1", Format.R32G32_Float); Vector2I size = src.Size; int texelsNum = size.X * size.Y; uint sizeX = (uint)size.X; uint sizeY = (uint)size.Y; var buffer = MyCommon.GetObjectCB(16); var mapping = MyMapping.MapDiscard(buffer); mapping.WriteAndPosition(ref sizeX); mapping.WriteAndPosition(ref sizeY); mapping.WriteAndPosition(ref texelsNum); mapping.Unmap(); RC.ComputeShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.ComputeShader.SetConstantBuffer(1, MyCommon.GetObjectCB(16)); RC.ComputeShader.Set(m_initialShader); IBorrowedUavTexture output = uav0; ISrvBindable inputSrc = src; RC.ComputeShader.SetUav(0, output); RC.ComputeShader.SetSrv(0, inputSrc); int threadGroupCountX = ComputeGroupCount(size.X); int threadGroupCountY = ComputeGroupCount(size.Y); RC.Dispatch(threadGroupCountX, threadGroupCountY, 1); RC.ComputeShader.Set(m_sumShader); IBorrowedUavTexture input; int i = 0; while (true) { size.X = threadGroupCountX; size.Y = threadGroupCountY; if (size.X <= NUM_THREADS && size.Y <= NUM_THREADS) { break; } output = (i % 2 == 0) ? uav1 : uav0; input = (i % 2 == 0) ? uav0 : uav1; RC.ComputeShader.SetSrv(0, null); RC.ComputeShader.SetUav(0, output); RC.ComputeShader.SetSrv(0, input); threadGroupCountX = ComputeGroupCount(size.X); threadGroupCountY = ComputeGroupCount(size.Y); RC.Dispatch(threadGroupCountX, threadGroupCountY, 1); i++; } RC.ComputeShader.Set(m_finalShader); output = (i % 2 == 0) ? uav1 : uav0; input = (i % 2 == 0) ? uav0 : uav1; RC.ComputeShader.SetSrv(0, null); RC.ComputeShader.SetUav(0, output); RC.ComputeShader.SetSrvs(0, input, m_prevLum); threadGroupCountX = ComputeGroupCount(size.X); threadGroupCountY = ComputeGroupCount(size.Y); RC.Dispatch(threadGroupCountX, threadGroupCountY, 1); RC.ComputeShader.Set(null); RC.ComputeShader.SetUav(0, null); // Backup the result for later process RC.CopySubresourceRegion(output.Resource, 0, new ResourceRegion(0, 0, 0, 1, 1, 1), m_prevLum.Resource, 0); input.Release(); return(output); }