Exemple #1
0
        internal static void Run(MyBindableResource destination, MyBindableResource source)
        {
            var context = MyRender11.DeviceContext;

            context.OutputMerger.BlendState = null;

            RC.SetIL(null);
            context.PixelShader.Set(m_ps);

            RC.BindDepthRT(null, DepthStencilAccess.ReadWrite, destination);
            RC.BindSRV(0, source);

            MyScreenPass.DrawFullscreenQuad(new MyViewport(destination.GetSize().X, destination.GetSize().Y));
        }
        internal static void ClearAlpha(MyBindableResource destination)
        {
            var context = MyRender11.DeviceContext;

            context.OutputMerger.BlendState = MyRender11.BlendAdditive;

            context.InputAssembler.InputLayout = null;
            context.PixelShader.Set(m_clearAlphaPs);

            RC.BindDepthRT(null, DepthStencilAccess.ReadWrite, destination);

            MyScreenPass.DrawFullscreenQuad(new MyViewport(destination.GetSize().X, destination.GetSize().Y));

            context.OutputMerger.BlendState = null;
        }
Exemple #3
0
        internal static void ClearAlpha(MyBindableResource destination)
        {
            var context = MyRender11.DeviceContext;

            context.OutputMerger.BlendState = MyRender11.BlendAdditive;

            context.InputAssembler.InputLayout = null;
            context.PixelShader.Set(m_clearAlphaPs);

            RC.BindDepthRT(null, DepthStencilAccess.ReadWrite, destination);

            MyScreenPass.DrawFullscreenQuad(new MyViewport(destination.GetSize().X, destination.GetSize().Y));

            context.OutputMerger.BlendState = null;
        }
        internal static void Run(MyBindableResource dst, MyBindableResource src, MyBindableResource avgLum, MyBindableResource bloom, bool enableTonemapping = true)
        {
            //Debug.Assert(src.GetSize() == dst.GetSize());

            var mapping = MyMapping.MapDiscard(MyCommon.GetObjectCB(16));
            mapping.stream.Write(MyRender11.Settings.MiddleGrey);
            mapping.stream.Write(MyRender11.Settings.LuminanceExposure);
            mapping.stream.Write(MyRender11.Settings.BloomExposure);
            mapping.stream.Write(MyRender11.Settings.BloomMult);
            mapping.Unmap();

            RC.CSSetCB(0, MyCommon.FrameConstants);
            RC.CSSetCB(1, MyCommon.GetObjectCB(16));

            RC.BindUAV(0, dst);
            RC.BindSRV(0, src, avgLum, bloom);

            RC.Context.ComputeShader.SetSampler(0, MyRender11.m_defaultSamplerState);

            if (enableTonemapping)
            {
                RC.SetCS(m_cs);
            }
            else
            {
                RC.SetCS(m_csSkip);
            }

            var size = dst.GetSize();
            RC.Context.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1);
            RC.SetCS(null);
        }
Exemple #5
0
        internal static void Run(MyBindableResource dst, MyBindableResource src, MyBindableResource avgLum, MyBindableResource bloom, bool enableTonemapping = true)
        {
            //Debug.Assert(src.GetSize() == dst.GetSize());

            var mapping = MyMapping.MapDiscard(MyCommon.GetObjectCB(16));

            mapping.stream.Write(MyRender11.Settings.MiddleGrey);
            mapping.stream.Write(MyRender11.Settings.LuminanceExposure);
            mapping.stream.Write(MyRender11.Settings.BloomExposure);
            mapping.stream.Write(MyRender11.Settings.BloomMult);
            mapping.Unmap();

            RC.CSSetCB(0, MyCommon.FrameConstants);
            RC.CSSetCB(1, MyCommon.GetObjectCB(16));

            RC.BindUAV(0, dst);
            RC.BindSRV(0, src, avgLum, bloom);

            RC.Context.ComputeShader.SetSampler(0, MyRender11.m_defaultSamplerState);

            if (enableTonemapping)
            {
                RC.SetCS(m_cs);
            }
            else
            {
                RC.SetCS(m_csSkip);
            }

            var size = dst.GetSize();

            RC.Context.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1);
            RC.SetCS(null);
        }
        internal static void Run(MyBindableResource destination, MyBindableResource source, MyViewport? customViewport = null)
        {
            var context = MyRender11.DeviceContext;
        
            context.OutputMerger.BlendState = null;
            //context.Rasterizer.SetViewport(0, 0, MyRender.ViewportResolution.X, MyRender.ViewportResolution.Y);

            RC.SetIL(null);
            context.PixelShader.Set(m_copyPs);
        
            //context.OutputMerger.SetTargets(null as DepthStencilView, target);
            //context.PixelShader.SetShaderResource(0, resource);
        
            RC.BindDepthRT(null, DepthStencilAccess.ReadWrite, destination);
            RC.BindSRV(0, source);

            MyScreenPass.DrawFullscreenQuad(customViewport ?? new MyViewport(destination.GetSize().X, destination.GetSize().Y));
        }
Exemple #7
0
        internal static void Run(MyBindableResource destination, MyBindableResource source)
        {
            var context = MyRender11.Context;

            context.OutputMerger.BlendState = null;
            //context.Rasterizer.SetViewport(0, 0, MyRender.ViewportResolution.X, MyRender.ViewportResolution.Y);

            context.InputAssembler.InputLayout = null;
            context.PixelShader.Set(m_copyPs);

            //context.OutputMerger.SetTargets(null as DepthStencilView, target);
            //context.PixelShader.SetShaderResource(0, resource);

            RC.BindDepthRT(null, DepthStencilAccess.ReadWrite, destination);
            RC.BindSRV(0, source);

            MyScreenPass.DrawFullscreenQuad(new MyViewport(destination.GetSize().X, destination.GetSize().Y));
        }
Exemple #8
0
        private static void TakeCustomSizedScreenshot(Vector2 rescale)
        {
            var resCpy = m_resolution;

            m_resolution = new Vector2I(resCpy * rescale);
            CreateScreenResources();

            m_finalImage         = DrawGameScene(null);
            m_resetEyeAdaptation = true;

            var surface = new MyRenderTarget(m_finalImage.GetSize().X, m_finalImage.GetSize().Y, SharpDX.DXGI.Format.R8G8B8A8_UNorm_SRgb, 1, 0);

            MyCopyToRT.Run(surface, m_finalImage);
            MyCopyToRT.ClearAlpha(surface);
            SaveScreenshotFromResource(surface.m_resource);
            surface.Release();

            m_resolution = resCpy;
            CreateScreenResources();
        }
        internal static void Run(MyBindableResource dst, MyBindableResource src, MyBindableResource stencil)
        {
            RC.BindUAV(0, dst);
            RC.BindSRV(0, src, stencil);

            RC.SetCS(m_cs);

            var size = dst.GetSize();
            RC.Context.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1);
            RC.SetCS(null);
        }
        internal static void Run(MyBindableResource dst, MyBindableResource src, MyBindableResource stencil)
        {
            RC.BindUAV(0, dst);
            RC.BindSRV(0, src, stencil);

            RC.SetCS(m_cs);

            var size = dst.GetSize();

            RC.Context.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1);
            RC.SetCS(null);
        }
        internal static void Run(MyBindableResource dst, MyBindableResource src, MyBindableResource avgLum, MyBindableResource bloom, bool enableTonemapping = true)
        {
            //Debug.Assert(src.GetSize() == dst.GetSize());

            var buffer  = MyCommon.GetObjectCB(16);
            var mapping = MyMapping.MapDiscard(buffer);

            mapping.WriteAndPosition(ref MyRender11.Settings.MiddleGrey);
            mapping.WriteAndPosition(ref MyRender11.Settings.LuminanceExposure);
            mapping.WriteAndPosition(ref MyRender11.Settings.BloomExposure);
            mapping.WriteAndPosition(ref MyRender11.Settings.BloomMult);
            mapping.Unmap();

            RC.CSSetCB(0, MyCommon.FrameConstants);
            RC.CSSetCB(1, MyCommon.GetObjectCB(16));

            RC.BindUAV(0, dst);
            RC.BindSRVs(0, src, avgLum, bloom);

            RC.DeviceContext.ComputeShader.SetSampler(0, SamplerStates.m_default);

            if (enableTonemapping)
            {
                RC.SetCS(m_cs);
            }
            else
            {
                RC.SetCS(m_csSkip);
            }

            var size = dst.GetSize();

            RC.DeviceContext.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1);

            ComputeShaderId.TmpUav[0] = null;
            RC.DeviceContext.ComputeShader.SetUnorderedAccessViews(0, ComputeShaderId.TmpUav, ComputeShaderId.TmpCount);
            RC.SetCS(null);
        }
        internal static void Run(MyBindableResource dst, MyBindableResource src, MyBindableResource avgLum, MyBindableResource bloom, bool enableTonemapping = true)
        {
            //Debug.Assert(src.GetSize() == dst.GetSize());

            var buffer = MyCommon.GetObjectCB(16);
            var mapping = MyMapping.MapDiscard(buffer);
            mapping.WriteAndPosition(ref MyRender11.Settings.MiddleGrey);
            mapping.WriteAndPosition(ref MyRender11.Settings.LuminanceExposure);
            mapping.WriteAndPosition(ref MyRender11.Settings.BloomExposure);
            mapping.WriteAndPosition(ref MyRender11.Settings.BloomMult);
            mapping.Unmap();

            RC.CSSetCB(0, MyCommon.FrameConstants);
            RC.CSSetCB(1, MyCommon.GetObjectCB(16));

            RC.BindUAV(0, dst);
            RC.BindSRVs(0, src, avgLum, bloom);

            RC.DeviceContext.ComputeShader.SetSampler(0, SamplerStates.m_default);

            if (enableTonemapping)
            {
                RC.SetCS(m_cs);
            }
            else
            {
                RC.SetCS(m_csSkip);
            }

            var size = dst.GetSize();
            RC.DeviceContext.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1);

            ComputeShaderId.TmpUav[0] = null;
            RC.DeviceContext.ComputeShader.SetUnorderedAccessViews(0, ComputeShaderId.TmpUav, ComputeShaderId.TmpCount);
            RC.SetCS(null);
        }
Exemple #13
0
        private unsafe static byte[] GetScreenData(Vector2I resolution, byte[] screenData = null)
        {
            const uint headerPadding    = 256; // Need to allocate some space for the bitmap headers
            const uint bytesPerPixel    = 4;
            uint       imageSizeInBytes = (uint)(resolution.Size() * bytesPerPixel);
            uint       dataSizeInBytes  = imageSizeInBytes + headerPadding;

            byte[] returnData = null;
            if (screenData == null)
            {
                screenData = new byte[imageSizeInBytes];
            }
            else if (screenData.Length != imageSizeInBytes)
            {
                Debug.Fail("Preallocated buffer for GetScreenData incorrect size: " + imageSizeInBytes.ToString() + " expected, " + screenData.Length + " received");
                return(returnData);
            }

            MyBindableResource imageSource             = Backbuffer;
            MyBindableResource imageSourceResourceView = null;

            if (imageSource != null && (resolution.X != imageSource.GetSize().X || resolution.Y != imageSource.GetSize().Y))
            {
                MyViewKey viewKey = new MyViewKey {
                    View = MyViewEnum.SrvView, Fmt = MyRender11Constants.DX11_BACKBUFFER_FORMAT
                };
                if (m_backbufferCopyResource == null)
                {
                    m_backbufferCopyResource = new MyCustomTexture(m_resolution.X, m_resolution.Y, BindFlags.ShaderResource, MyRender11Constants.DX11_BACKBUFFER_FORMAT);
                    m_backbufferCopyResource.AddView(viewKey);
                }
                MyRenderContext.Immediate.DeviceContext.CopyResource(imageSource.m_resource, m_backbufferCopyResource.m_resource);
                imageSource             = m_backbufferCopyResource;
                imageSourceResourceView = m_backbufferCopyResource.GetView(viewKey);
            }

            if (imageSource == null)
            {
                return(returnData);
            }

            if (imageSizeInBytes > int.MaxValue)
            {
                Debug.Fail("Image size too large to read!");
                return(returnData);
            }

            MyBindableResource imageResource = imageSource;
            bool shouldResize = imageSourceResourceView != null;

            if (shouldResize)
            {
                imageResource = m_lastScreenDataResource;
                if (imageResource == null || (imageResource.GetSize().X != resolution.X || imageResource.GetSize().Y != resolution.Y))
                {
                    if (m_lastScreenDataResource != null && (m_lastScreenDataResource != m_backbufferCopyResource && m_lastScreenDataResource != Backbuffer))
                    {
                        m_lastScreenDataResource.Release();
                    }
                    m_lastScreenDataResource = null;

                    imageResource = new MyRenderTarget(resolution.X, resolution.Y, MyRender11Constants.DX11_BACKBUFFER_FORMAT, 1, 0);
                }
                var RC            = MyRenderContext.Immediate;
                var deviceContext = RC.DeviceContext;
                deviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
                deviceContext.Rasterizer.SetViewport(0, 0, resolution.X, resolution.Y);
                deviceContext.PixelShader.Set(MyDebugRenderer.BlitTextureShader);
                deviceContext.PixelShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants);

                RC.BindDepthRT(null, DepthStencilAccess.ReadWrite, imageResource);
                RC.BindSRV(0, imageSourceResourceView);
                MyDebugRenderer.DrawQuad(0, 0, resolution.X, resolution.Y, MyScreenPass.QuadVS);
                //MyCopyToRT.Run(imageResource, imageSourceResourceView, new MyViewport(resolution));
            }

            m_lastScreenDataResource = imageResource;

            Stream dataStream = m_lastDataStream;

            if (m_lastDataStream == null || m_lastDataStream.Length != dataSizeInBytes)
            {
                if (m_lastDataStream != null)
                {
                    m_lastDataStream.Dispose();
                    m_lastDataStream = null;
                }
                dataStream = new DataStream((int)dataSizeInBytes, true, true);
                dataStream.Seek(0, SeekOrigin.Begin);
            }

            m_lastDataStream = dataStream;

            Resource.ToStream(MyRenderContext.Immediate.DeviceContext, imageResource.m_resource, ImageFileFormat.Bmp, dataStream);

            if (!(dataStream.CanRead && dataStream.CanSeek))
            {
                Debug.Fail("Screen data stream does not support the necessary operations to get the data");
                return(returnData);
            }

            fixed(byte *dataPointer = screenData)
            {
                GetBmpDataFromStream(dataStream, dataPointer, imageSizeInBytes);
            }

            returnData = screenData;

            if (m_lastDataStream != null)
            {
                m_lastDataStream.Seek(0, SeekOrigin.Begin);
            }

            return(returnData);
        }
        internal static MyBindableResource Run(MyBindableResource uav0, MyBindableResource uav1, MyBindableResource src,
            MyBindableResource prevLum, MyBindableResource localAvgLum)
        {
            var size = src.GetSize();
            var texelsNum = size.X * size.Y;
            var mapping = MyMapping.MapDiscard(MyCommon.GetObjectCB(16));
            mapping.stream.Write((uint)size.X);
            mapping.stream.Write((uint)size.Y);
            mapping.stream.Write(texelsNum);
            mapping.Unmap();

            RC.CSSetCB(0, MyCommon.FrameConstants);
            RC.CSSetCB(1, MyCommon.GetObjectCB(16));

            RC.BindUAV(0, uav0);
            RC.BindSRV(0, src);
            RC.SetCS(m_initialShader);

            RC.Context.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1);

            RC.SetCS(m_sumShader);
            int i = 0;
            while (true)
            {
                size.X = (size.X + m_numthreads - 1) / m_numthreads;
                size.Y = (size.Y + m_numthreads - 1) / m_numthreads;

                if (size.X <= 8 && size.Y <= 8)
                    break;

                //mapping = MyMapping.MapDiscard(MyCommon.GetObjectBuffer(16).Buffer);
                //mapping.stream.Write(new Vector2I(size.X, size.Y));
                //mapping.Unmap();

                RC.BindUAV(0, (i % 2 == 0) ? uav1 : uav0);
                RC.BindSRV(0, (i % 2 == 0) ? uav0 : uav1);

                RC.Context.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1);

                //might not be exactly correct if we skip this
                var dirty = (i % 2 == 0) ? uav0 : uav1;
                RC.Context.ClearUnorderedAccessView((dirty as IUnorderedAccessBindable).UAV, new SharpDX.Int4(0, 0, 0, 0));

                i++;
            }

            RC.SetCS(m_finalShader);

            //mapping = MyMapping.MapDiscard(MyCommon.GetObjectBuffer(16).Buffer);
            //mapping.stream.Write(new Vector2I(size.X, size.Y));
            //mapping.stream.Write(texelsNum);
            //mapping.Unmap();

            RC.BindUAV(0, (i % 2 == 0) ? uav1 : uav0);
            RC.BindSRV(0, (i % 2 == 0) ? uav0 : uav1, prevLum);

            RC.Context.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1);

            RC.SetCS(null);

            var output = (i % 2 == 0) ? uav1 : uav0;

            RC.Context.CopySubresourceRegion(output.m_resource, 0, new ResourceRegion(0, 0, 0, 1, 1, 1), prevLum.m_resource, 0);

            return output;
        }
        private static void TakeCustomSizedScreenshot(Vector2 rescale)
        {
            var resCpy = m_resolution;

            m_resolution = new Vector2I(resCpy * rescale);
            CreateScreenResources();

            m_finalImage = DrawGameScene(null);
            m_resetEyeAdaptation = true;

            var surface = new MyRenderTarget(m_finalImage.GetSize().X, m_finalImage.GetSize().Y, SharpDX.DXGI.Format.R8G8B8A8_UNorm_SRgb, 1, 0);
            MyCopyToRT.Run(surface, m_finalImage);
            MyCopyToRT.ClearAlpha(surface);
            SaveScreenshotFromResource(surface.m_resource);
            surface.Release();

            m_resolution = resCpy;
            CreateScreenResources();
        }
 internal override Vector3I GetSize()
 {
     return(m_owner.GetSize());
 }
Exemple #17
0
        internal static MyBindableResource Run(MyBindableResource uav0, MyBindableResource uav1, MyBindableResource src,
                                               MyBindableResource prevLum, MyBindableResource localAvgLum)
        {
            var size      = src.GetSize();
            var texelsNum = size.X * size.Y;
            var mapping   = MyMapping.MapDiscard(MyCommon.GetObjectCB(16));

            mapping.stream.Write((uint)size.X);
            mapping.stream.Write((uint)size.Y);
            mapping.stream.Write(texelsNum);
            mapping.stream.Write(MyRender11.Postprocess.EnableEyeAdaptation ? -1.0f : MyRender11.Postprocess.ConstantLuminance);

            mapping.Unmap();

            RC.CSSetCB(0, MyCommon.FrameConstants);
            RC.CSSetCB(1, MyCommon.GetObjectCB(16));

            RC.BindUAV(0, uav0);
            RC.BindSRV(0, src);
            RC.SetCS(m_initialShader);

            RC.Context.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1);

            RC.SetCS(m_sumShader);
            int i = 0;

            while (true)
            {
                size.X = (size.X + m_numthreads - 1) / m_numthreads;
                size.Y = (size.Y + m_numthreads - 1) / m_numthreads;

                if (size.X <= 8 && size.Y <= 8)
                {
                    break;
                }

                //mapping = MyMapping.MapDiscard(MyCommon.GetObjectBuffer(16).Buffer);
                //mapping.stream.Write(new Vector2I(size.X, size.Y));
                //mapping.Unmap();

                RC.BindUAV(0, (i % 2 == 0) ? uav1 : uav0);
                RC.BindSRV(0, (i % 2 == 0) ? uav0 : uav1);

                RC.Context.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1);

                //might not be exactly correct if we skip this
                var dirty = (i % 2 == 0) ? uav0 : uav1;
                RC.Context.ClearUnorderedAccessView((dirty as IUnorderedAccessBindable).UAV, new SharpDX.Int4(0, 0, 0, 0));

                i++;
            }

            RC.SetCS(m_finalShader);

            //mapping = MyMapping.MapDiscard(MyCommon.GetObjectBuffer(16).Buffer);
            //mapping.stream.Write(new Vector2I(size.X, size.Y));
            //mapping.stream.Write(texelsNum);
            //mapping.Unmap();

            RC.BindUAV(0, (i % 2 == 0) ? uav1 : uav0);
            RC.BindSRV(0, (i % 2 == 0) ? uav0 : uav1, prevLum);

            RC.Context.Dispatch((size.X + m_numthreads - 1) / m_numthreads, (size.Y + m_numthreads - 1) / m_numthreads, 1);

            RC.SetCS(null);

            var output = (i % 2 == 0) ? uav1 : uav0;

            RC.Context.CopySubresourceRegion(output.m_resource, 0, new ResourceRegion(0, 0, 0, 1, 1, 1), prevLum.m_resource, 0);

            return(output);
        }
Exemple #18
0
        internal static MyBindableResource Run(MyBindableResource uav0, MyBindableResource uav1, MyBindableResource src,
                                               MyBindableResource prevLum)
        {
            Vector3I size             = src.GetSize();
            int      texelsNum        = size.X * size.Y;
            uint     sizeX            = (uint)size.X;
            uint     sizeY            = (uint)size.Y;
            float    adaptationFactor = MyRender11.Postprocess.EnableEyeAdaptation ? -1.0f : MyRender11.Postprocess.ConstantLuminance;
            var      buffer           = MyCommon.GetObjectCB(16);
            var      mapping          = MyMapping.MapDiscard(buffer);

            mapping.WriteAndPosition(ref sizeX);
            mapping.WriteAndPosition(ref sizeY);
            mapping.WriteAndPosition(ref texelsNum);
            mapping.WriteAndPosition(ref adaptationFactor);
            mapping.Unmap();

            RC.CSSetCB(0, MyCommon.FrameConstants);
            RC.CSSetCB(1, MyCommon.GetObjectCB(16));

            RC.SetCS(m_initialShader);

            MyBindableResource output = uav0;
            MyBindableResource input  = src;

            RC.BindUAV(0, output);
            RC.BindSRV(0, input);

            int threadGroupCountX = ComputeGroupCount(size.X);
            int threadGroupCountY = ComputeGroupCount(size.Y);

            RC.DeviceContext.Dispatch(threadGroupCountX, threadGroupCountY, 1);

            RC.SetCS(m_sumShader);

            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.BindUAV(0, output);
                RC.BindSRV(0, input);

                threadGroupCountX = ComputeGroupCount(size.X);
                threadGroupCountY = ComputeGroupCount(size.Y);
                RC.DeviceContext.Dispatch(threadGroupCountX, threadGroupCountY, 1);

                i++;
            }

            RC.SetCS(m_finalShader);

            output = (i % 2 == 0) ? uav1 : uav0;
            input  = (i % 2 == 0) ? uav0 : uav1;
            RC.BindUAV(0, output);
            RC.BindSRVs(0, input, prevLum);

            threadGroupCountX = ComputeGroupCount(size.X);
            threadGroupCountY = ComputeGroupCount(size.Y);
            RC.DeviceContext.Dispatch(threadGroupCountX, threadGroupCountY, 1);

            RC.SetCS(null);

            // Backup the result for later process
            RC.DeviceContext.CopySubresourceRegion(output.m_resource, 0, new ResourceRegion(0, 0, 0, 1, 1, 1), prevLum.m_resource, 0);

            return(output);
        }
        internal static MyBindableResource Run(MyBindableResource uav0, MyBindableResource uav1, MyBindableResource src,
            MyBindableResource prevLum)
        {
            Vector3I size = src.GetSize();
            int texelsNum = size.X * size.Y;
            uint sizeX = (uint)size.X;
            uint sizeY = (uint)size.Y;
            float adaptationFactor = MyRender11.Postprocess.EnableEyeAdaptation ? -1.0f : MyRender11.Postprocess.ConstantLuminance;
            var buffer = MyCommon.GetObjectCB(16);
            var mapping = MyMapping.MapDiscard(buffer);
            mapping.WriteAndPosition(ref sizeX);
            mapping.WriteAndPosition(ref sizeY);
            mapping.WriteAndPosition(ref texelsNum);
            mapping.WriteAndPosition(ref adaptationFactor);
            mapping.Unmap();

            RC.CSSetCB(0, MyCommon.FrameConstants);
            RC.CSSetCB(1, MyCommon.GetObjectCB(16));

            RC.SetCS(m_initialShader);

            MyBindableResource output = uav0;
            MyBindableResource input = src;
            RC.BindUAV(0, output);
            RC.BindSRV(0, input);

            int threadGroupCountX = ComputeGroupCount(size.X);
            int threadGroupCountY = ComputeGroupCount(size.Y);
            RC.DeviceContext.Dispatch(threadGroupCountX, threadGroupCountY, 1);

            RC.SetCS(m_sumShader);

            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.BindUAV(0, output);
                RC.BindSRV(0, input);

                threadGroupCountX = ComputeGroupCount(size.X);
                threadGroupCountY = ComputeGroupCount(size.Y);
                RC.DeviceContext.Dispatch(threadGroupCountX, threadGroupCountY, 1);

                i++;
            }

            RC.SetCS(m_finalShader);

            output = (i % 2 == 0) ? uav1 : uav0;
            input = (i % 2 == 0) ? uav0 : uav1;
            RC.BindUAV(0, output);
            RC.BindSRVs(0, input, prevLum);

            threadGroupCountX = ComputeGroupCount(size.X);
            threadGroupCountY = ComputeGroupCount(size.Y);
            RC.DeviceContext.Dispatch(threadGroupCountX, threadGroupCountY, 1);

            RC.SetCS(null);

            // Backup the result for later process
            RC.DeviceContext.CopySubresourceRegion(output.m_resource, 0, new ResourceRegion(0, 0, 0, 1, 1, 1), prevLum.m_resource, 0);

            return output;
        }
        private unsafe static byte[] GetScreenData(Vector2I resolution, byte[] screenData = null)
        {
            const uint headerPadding    = 256; // Need to allocate some space for the bitmap headers
            const uint bytesPerPixel    = 4;
            uint       imageSizeInBytes = (uint)(resolution.Size() * bytesPerPixel);
            uint       dataSizeInBytes  = imageSizeInBytes + headerPadding;

            byte[] returnData = null;
            if (screenData == null)
            {
                screenData = new byte[imageSizeInBytes];
            }
            else if (screenData.Length != imageSizeInBytes)
            {
                Debug.Fail("Preallocated buffer for GetScreenData incorrect size: " + imageSizeInBytes.ToString() + " expected, " + screenData.Length * bytesPerPixel + " received");
                return(returnData);
            }

            MyBindableResource imageSource = Backbuffer;

            if (imageSource == null)
            {
                return(returnData);
            }

            if (imageSizeInBytes > int.MaxValue)
            {
                Debug.Fail("Image size too large to read!");
                return(returnData);
            }

            MyBindableResource imageResource = imageSource;

            if (resolution.X != imageResource.GetSize().X || resolution.Y != imageResource.GetSize().Y)
            {
                imageResource = m_lastScreenDataResource;
                if (imageResource == null || (imageResource.GetSize().X != resolution.X || imageResource.GetSize().Y != resolution.Y))
                {
                    if (m_lastScreenDataResource != null && m_lastScreenDataResource != Backbuffer)
                    {
                        m_lastScreenDataResource.Release();
                    }
                    m_lastScreenDataResource = null;

                    imageResource = new MyRenderTarget(resolution.X, resolution.Y, MyRender11Constants.DX11_BACKBUFFER_FORMAT, 0, 0);
                }

                MyCopyToRT.Run(imageResource, imageSource, new MyViewport(resolution));
            }

            m_lastScreenDataResource = imageResource;

            Stream dataStream = m_lastDataStream;

            if (m_lastDataStream == null || m_lastDataStream.Length != dataSizeInBytes)
            {
                if (m_lastDataStream != null)
                {
                    m_lastDataStream.Dispose();
                    m_lastDataStream = null;
                }
                dataStream = new DataStream((int)dataSizeInBytes, true, true);
            }

            m_lastDataStream = dataStream;

            Resource.ToStream(MyRenderContext.Immediate.DeviceContext, imageResource.m_resource, ImageFileFormat.Bmp, dataStream);

            if (!(dataStream.CanRead && dataStream.CanSeek))
            {
                Debug.Fail("Screen data stream does not support the necessary operations to get the data");
                return(returnData);
            }

            fixed(byte *dataPointer = screenData)
            {
                GetBmpDataFromStream(dataStream, dataPointer, imageSizeInBytes);
            }

            returnData = screenData;

            if (m_lastDataStream != null)
            {
                m_lastDataStream.Seek(0, SeekOrigin.Begin);
            }

            return(returnData);
        }