Пример #1
0
        // the code below failing due to GC

        /*public static SharpDX.WIC.BitmapSource LoadBitmap(DirectXContext directXContext, Stream stream)
         * {
         *  var bitmapDecoder = new SharpDX.WIC.BitmapDecoder(
         *      directXContext.ImagingFactory2,
         *      stream,
         *      SharpDX.WIC.DecodeOptions.CacheOnLoad);
         *
         *  var formatConverter = new SharpDX.WIC.FormatConverter(directXContext.ImagingFactory2);
         *
         *  formatConverter.Initialize(
         *      bitmapDecoder.GetFrame(0),
         *      SharpDX.WIC.PixelFormat.Format32bppPRGBA,
         *      SharpDX.WIC.BitmapDitherType.None,
         *      null,
         *      0.0,
         *      SharpDX.WIC.BitmapPaletteType.Custom);
         *
         *  return formatConverter;
         * }*/

        public static DirectXResource CreateTexture2DFromBitmap(DirectXContext directXContext, SharpDX.WIC.BitmapSource bitmapSource)
        {
            // Allocate DataStream to receive the WIC image pixels
            int stride = bitmapSource.Size.Width * 4;

            using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true))
            {
                try
                {
                    // Copy the content of the WIC to the buffer
                    bitmapSource.CopyPixels(stride, buffer);
                }
                catch (Exception e)
                {
                    Core.LogError(e, "Failed to load image into Dx");
                }

                return(directXContext.Pool.Get("loadbitmap", DirectXResource.Desc(bitmapSource.Size.Width,
                                                                                  bitmapSource.Size.Height,
                                                                                  SharpDX.DXGI.Format.R8G8B8A8_UNorm,
                                                                                  SharpDX.Direct3D11.BindFlags.ShaderResource,
                                                                                  SharpDX.Direct3D11.ResourceUsage.Immutable),
                                               new SharpDX.DataRectangle(buffer.DataPointer, stride)));
            }
        }
        public virtual DirectXResource Render(DeviceContext ctx, DirectXResource source)
        {
            var target = Dx.Pool.Get("FilterStage", DirectXResource.Desc(source.Texture2D.Description.Width, source.Texture2D.Description.Height));

            using var rtv = target.GetRenderTargetView();
            using var srv = source.GetShaderResourceView();

            Pipeline.SetPosition(DirectXPipelineConfig.FullRectangle, new Viewport(0, 0, source.Texture2D.Description.Width, source.Texture2D.Description.Height));
            Render(ctx, rtv, srv, source.Texture2D.Description.Width, source.Texture2D.Description.Height);

            return(target);
        }
 public int Write(Frame frame, int inputNo)
 {
     _currentFramePts = frame.Properties.Pts;
     _currentFrame?.Dispose();
     _currentFrame = _dx.Pool.Get("passthru2", DirectXResource.Desc(_width,
                                                                    _height,
                                                                    SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                                                                    SharpDX.Direct3D11.BindFlags.ShaderResource,
                                                                    SharpDX.Direct3D11.ResourceUsage.Immutable),
                                  new SharpDX.DataRectangle(frame.Properties.DataPtr0, _width * 4));
     return(0);
 }
        public DirectXResource Process(Frame input)
        {
            var texOut = _dx.Pool.Get("transfer out", DirectXResource.Desc(_width, _height, Format.NV12,
                                                                           BindFlags.RenderTarget, ResourceUsage.Default, ResourceOptionFlags.Shared, CpuAccessFlags.None));

            _dx.RunOnContext(ctx =>
            {
                for (int q = 0; q < _planes.Count; q++)
                {
                    Render(input.DirectXResourceRef.Instance, texOut, _planes[q], ctx);
                }
            }, "Transfer Render");

            return(texOut);
        }
        private static DirectXDownloaderPlaneData CreatePlane(DirectXContext dx, int width, int height, DirectXDownloaderFormatPlane plane)
        {
            var config = new DirectXPipelineConfig
            {
                VertexShaderFile     = "format_conversion.hlsl",
                VertexShaderFunction = plane.VS,
                PixelShaderFile      = "format_conversion.hlsl",
                PixelShaderFunction  = plane.PS,
            };

            var pipeline = new DirectXPipeline <ConverterFilterConstantBuffer>(config, dx);

            pipeline.SetDebugColor(0, 0, 0, 1);
            pipeline.SetPosition(DirectXPipelineConfig.FullRectangle, new Viewport(0, 0, width / plane.WidthFactor, height / plane.HeightFactor));
            var colorMatrix = ColorMatrices.GetInverted(ColorMatrices.Full709);
            var cm          = colorMatrix.Values;
            var cb          = new ConverterFilterConstantBuffer
            {
                width      = width,
                height     = height,
                width_i    = 1.0f / width,
                width_d2   = width / 2,
                height_d2  = height / 2,
                width_x2_i = 0.5f / width,

                color_vec0      = new Vector4(cm[0], cm[1], cm[2], cm[3]),
                color_vec1      = new Vector4(cm[4], cm[5], cm[6], cm[7]),
                color_vec2      = new Vector4(cm[8], cm[9], cm[10], cm[11]),
                color_range_min = new Vector3(0.0f, 0.0f, 0.0f),
                color_range_max = new Vector3(1.0f, 1.0f, 1.0f),
            };

            pipeline.SetConstantBuffer(cb, false);

            return(new DirectXDownloaderPlaneData
            {
                Format = plane,
                Pipeline = pipeline,
                GpuTexture = dx.Pool.Get("downloadGpu", DirectXResource.Desc(width / plane.WidthFactor, height / plane.HeightFactor, plane.Format)),
                CpuTexture = dx.Pool.Get("downloadCpu", DirectXResource.Desc(width / plane.WidthFactor, height / plane.HeightFactor, plane.Format, BindFlags.None, ResourceUsage.Staging, ResourceOptionFlags.None, CpuAccessFlags.Read))
            });
        }
        private void DownloadAndDisplayAsBitmap(DirectXResource res)
        {
            int width  = res.Texture2D.Description.Width;
            int height = res.Texture2D.Description.Height;
            var dx     = res.GetDx();

            PrepareSoftwareImage(width, height, PixelFormats.Bgra32);

            if (_cpuTexture == null ||
                _cpuTexture.Texture2D == null ||
                _cpuTexture.Texture2D.Description.Width != width ||
                _cpuTexture.Texture2D.Description.Height != height ||
                _cpuTextureOwner != dx)
            {
                _cpuTexture?.Dispose();
                _cpuTextureOwner = dx;
                _cpuTexture      = dx.Pool.Get("uiCpu", DirectXResource.Desc(width, height, SharpDX.DXGI.Format.B8G8R8A8_UNorm, BindFlags.None, ResourceUsage.Staging, ResourceOptionFlags.None, CpuAccessFlags.Read));
            }

            DataBox db = new DataBox();

            dx.RunOnContext(ctx =>
            {
                ctx.CopyResource(res.Texture2D, _cpuTexture.Texture2D);
                ctx.Flush();
                db = ctx.MapSubresource(_cpuTexture.Texture2D, 0, MapMode.Read, MapFlags.None);
            }, "Download for ui");

            if (db.SlicePitch > 0)
            {
                _softwareImage.WritePixels(new Int32Rect(0, 0, width, height), db.DataPointer, db.SlicePitch, db.RowPitch);
            }
            dx.RunOnContext(ctx => ctx.UnmapSubresource(_cpuTexture.Texture2D, 0), "Unmap for ui");

            if (Source != _softwareImage)
            {
                Source = _softwareImage;
            }
        }
        public void Enqueue(IntPtr buffer, int size)
        {
            lock (_queueLock)
            {
                if (_queue.Count == _maxPackets)
                {
                    _streamer.PacketPool.Back(_queue.Dequeue());
                    Core.LogWarning($"Queue '{_name}' reached maximum");
                }

                var packet = _streamer.PacketPool.Rent();
                var now    = Core.GetCurrentTime();

                if (_dx == null)
                {
                    packet.InitFromBuffer(buffer, size, now);
                }
                else
                {
                    var dx = _dx.Pool.Get("WebBrowserQueue", DirectXResource.Desc(_width,
                                                                                  _height,
                                                                                  SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                                                                                  SharpDX.Direct3D11.BindFlags.ShaderResource,
                                                                                  SharpDX.Direct3D11.ResourceUsage.Immutable),
                                          new SharpDX.DataRectangle(buffer, _width * 4));
                    packet.InitFromDirectX(dx, now);
                }
                _queue.Enqueue(packet);

                // update last
                _streamer.PacketPool.Back(_last);
                _last = _streamer.PacketPool.Rent();
                _last.CopyContentFrom(packet);
                _lastEnqueueTime = now;

                Monitor.PulseAll(_queueLock);
            }
        }
        private bool RenderDirectX(Frame resultPayload, out PayloadTrace trace)
        {
            trace = null;
            bool hasAnyContent = false;
            var  dx            = _setup.Dx;

            try
            {
                if (dx.IsBrokenAndLog("Blender"))
                {
                    return(false);
                }

                var texture = dx.Pool.Get("Blender", DirectXResource.Desc(_setup.Width, _setup.Height, SharpDX.DXGI.Format.B8G8R8A8_UNorm, BindFlags.ShaderResource | BindFlags.RenderTarget, ResourceUsage.Default, ResourceOptionFlags.None));

                _defferedContext = _defferedContext ?? new DeviceContext(dx.Device);
                //using
                using (var rtv = texture.GetRenderTargetView())
                {
                    int counter = 0;

                    foreach (var runtime in _inputRuntimesSorted)
                    {
                        var frameData = GetRuntimeOrFixedFrame(runtime);
                        if (frameData != null && runtime.Description.Visible)
                        {
                            hasAnyContent = true;

                            UpdateTrace(frameData, ref trace);

                            var xResource = frameData.Payload.DirectXResourceRef.Instance;

                            if (xResource.CommandList != null)
                            {
                                _defferedContext.ExecuteCommandList(xResource.CommandList, false);
                                xResource.CommandList.Dispose();
                                xResource.CommandList = null;
                            }

                            var pipeline = GetPipeline(runtime, texture, xResource);
                            SetDebugColor(pipeline, counter++);
                            UpdatePositionInDxPipeline(runtime, pipeline, xResource.Texture2D.Description.Width, xResource.Texture2D.Description.Height);

                            var filteredResource = runtime.DirectXFilterRuntime.Render(dx, runtime.Description.FilterChain, _defferedContext, xResource);
                            if (ReferenceEquals(filteredResource, xResource))
                            {
                                using (var srv = filteredResource.GetShaderResourceView())
                                    pipeline.Render(_defferedContext, rtv, srv);
                                dx.Flush(_defferedContext, "Blender Flush All");
                            }
                            else
                            {
                                dx.Flush(_defferedContext, "Blender Flush All");
                                using (var srvFiltered = filteredResource.GetShaderResourceView())
                                    pipeline.Render(_defferedContext, rtv, srvFiltered);
                                dx.Flush(_defferedContext, "Blender Flush All");
                                filteredResource.Dispose();
                            }
                        }
                    }
                }

                if (hasAnyContent)
                {
                    if (trace != null)
                    {
                        trace = PayloadTrace.Create(_name, trace);
                    }

                    dx.Flush(_defferedContext, "Blender Flush All");
                    var allFilteredResource = _dxFilterRuntime.Render(dx, _setup.WeakOptions.FilterChain, _defferedContext, texture);
                    dx.Flush(_defferedContext, "Blender Flush All");

                    resultPayload.InitFromDirectX(allFilteredResource, _currentFpsTicks);

                    if (allFilteredResource != texture)
                    {
                        dx.Pool.Back(texture);
                    }
                }
            }
            catch (Exception e)
            {
                dx.Broken(e);
            }

            return(hasAnyContent);
        }
        public int Write(Packet packet)
        {
            RemoveCurrent();

            _currentFramePts = packet.Properties.Pts;

            if (_dx != null)
            {
                _currentResource = new RefCounted <DirectXResource>(_dx.Pool.Get("passthru", DirectXResource.Desc(_width,
                                                                                                                  _height,
                                                                                                                  SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                                                                                                                  SharpDX.Direct3D11.BindFlags.ShaderResource,
                                                                                                                  SharpDX.Direct3D11.ResourceUsage.Immutable),
                                                                                 new SharpDX.DataRectangle(packet.Properties.DataPtr, _width * 4)));
            }
            else
            {
                _currentResource = packet.DirectXResourceRef.AddRef();
            }
            return(0);
        }