最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

windows - Usage of OnAcceleratedPaint in OSR - Stack Overflow

programmeradmin3浏览0评论

I'm trying to develop an application that renders the cef texture in offscreen-rendering. I don't want to render it to a form or any window. I'd like to create a texture which I'm then sharing to other processes, for now I would simply be fine in saving it to disk to see if I'm getting anything.

Below is the code I'm using, I have little to no experience in D3D11, I've tried using SharpDX to create a Device to open the shared pointer I'm getting with OnAcceleratedPaint (which gets called correctly from the RenderHandler class).

using System.Runtime.InteropServices;
using SharpDX;
using SharpDX.D3DCompiler;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using Buffer = SharpDX.Direct3D11.Buffer;
using Device = SharpDX.Direct3D11.Device;
using Device1 = SharpDX.Direct3D11.Device1;
using Device2 = SharpDX.Direct3D11.Device2;
using Device3 = SharpDX.Direct3D11.Device3;
using Device4 = SharpDX.Direct3D11.Device4;

namespace Browser.HardwareAcceleration;

public class D3DRenderer
{
    private Lock _lock = new ();
    private Texture2D _texture;
    private Device _device;
    private int _width = 1280;
    private int _height = 720;
    private VertexShader _vs;
    private PixelShader _ps;
    private InputLayout _layout;
    private const string ShaderSrc = "Texture2D tex;   \n" +
                                     "   \n" +
                                     "SamplerState texSampler   \n" +
                                     "{   \n" +
                                     "   Texture = <tex>;   \n" +
                                     "   Filter = MIN_MAG_MIP_POINT; \n" +
                                     "};   \n" +
                                     "   \n" +
                                     "struct PS_IN   \n" +
                                     "{  \n" +
                                     "   float4 pos : SV_POSITION; \n" +
                                     "   float2 Tex : TEXCOORD;  \n" +
                                     "};   \n" +
                                     "   \n" +
                                     "PS_IN vertex( PS_IN input )    \n" +
                                     "{  \n" +
                                     "   return input;   \n" +
                                     "}  \n" +
                                     "   \n" +
                                     "float4 pixel( PS_IN input ) : SV_Target  \n" +
                                     "{  \n" +
                                     "   return tex.Sample( texSampler, input.Tex );   \n" +
                                     "}  \n" +
                                     "   \n";

    [StructLayout(LayoutKind.Sequential)]
    private struct VertexDX11
    {
        public Vector4 Position;
        public Vector2 TexCoord0;

        public static InputElement[] GetInputElements()
        {
            InputElement[] inputElements = [new("SV_POSITION", 0, Format.R32G32B32A32_Float, 0, 0), new("TEXCOORD", 0, Format.R32G32_Float, 16, 0)];
            return inputElements;
        }
    }

    public D3DRenderer()
    {
        _device = new Device(DriverType.Hardware, DeviceCreationFlags.None);

        UpgradeDevice();
        
        var viewPort = new Viewport(0, 0, _width, _height);
        _device.ImmediateContext.Rasterizer.SetViewport(viewPort);
        
        //testing
        if (_texture == null)
        {
            var desc = new Texture2DDescription();
            desc.Format = Format.R8G8B8A8_UInt;
            desc.ArraySize = 1;
            desc.Width = _width;
            desc.Height = _height;
            desc.SampleDescription = new SampleDescription(1, 0);
            desc.Usage = ResourceUsage.Default;
            desc.BindFlags = BindFlags.None;
            desc.CpuAccessFlags = CpuAccessFlags.Read;
            _texture = new Texture2D(_device, desc);
        }
        
        var renderTarget = new RenderTargetView(_device, _texture);
        _device.ImmediateContext.ClearRenderTargetView(renderTarget, Color4.Black);
        _device.ImmediateContext.OutputMerger.SetRenderTargets(renderTarget);
        //
        
        CreateShaders();
        
        _device.ImmediateContext.VertexShader.Set(_vs);
        _device.ImmediateContext.PixelShader.Set(_ps);
        _device.ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;
        _device.ImmediateContext.InputAssembler.InputLayout = _layout;
    }

    private void UpgradeDevice()
    {
        var device5 = _device.QueryInterfaceOrNull<Device5>();
        if (device5 != null)
        {
            _device.Dispose();
            _device = device5;
            return;
        }

        var device4 = _device.QueryInterfaceOrNull<Device4>();
        if (device4 != null)
        {
            _device.Dispose();
            _device = device4;
            return;
        }

        var device3 = _device.QueryInterfaceOrNull<Device3>();
        if (device3 != null)
        {
            _device = device3;
            return;
        }

        var device2 = _device.QueryInterfaceOrNull<Device2>();
        if (device2 != null)
        {
            _device = device2;
            return;
        }

        var device1 = _device.QueryInterfaceOrNull<Device1>();
        if (device1 != null)
        {
            _device.Dispose();
            _device = device1;
        }
    }
    
    private void CreateShaders()
    {
        using (ShaderBytecode byteCode = ShaderBytecode.Compile(ShaderSrc, "vertex", "vs_4_0_level_9_1"))
        {
            _vs = new VertexShader(_device, byteCode);
            var signature = ShaderSignature.GetInputSignature(byteCode);
            _layout = new InputLayout(_device, signature, VertexDX11.GetInputElements());
        }

        using (ShaderBytecode byteCode = ShaderBytecode.Compile(ShaderSrc, "pixel", "ps_4_0_level_9_1"))
        {
            _ps = new PixelShader(_device, byteCode);
        }
    }

    public void OnAcceleratedPaint(IntPtr sharedTextureHandle)
    {
        lock (_lock)
        {
            var dev1 = _device as Device1;
            using (var cefTex = dev1.OpenSharedResource1<Texture2D>(sharedTextureHandle))
            {
                _device.ImmediateContext.CopyResource(cefTex, _texture);
                //do stuff with texture, like save to png or share it with other processes
            }
        }
    }
}

I've tried many things but to no avail, from what I understood I don't need a swap chain to render in osr because I won't display it on a window/form (I don't know if this is correct). I've tried to create a texture to use as a render target but if I do it like the code above I'm getting an exception SharpDX.SharpDXException: HRESULT: [0x80070057], Module: [General], ApiCode: [E_INVALIDARG/Invalid Arguments], Message: The parameter is incorrect. at the line var renderTarget = new RenderTargetView(_device, _texture); if I don't do that I'm getting the same exception when opening the shared resource in the OnAcceleratedPaint. I'm guessing I'm creating the device in the wrong way. What do I need to do?

I'm on .NET Core 9 and Windows 10 with a Nvidia 2070

发布评论

评论列表(0)

  1. 暂无评论