Ejemplo n.º 1
0
        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);
        }