hecomi / uDesktopDuplication

Desktop Duplication API implementation for Unity (only for Windows 8/10)
http://tips.hecomi.com/entry/2016/12/04/125641
MIT License
563 stars 97 forks source link

Desktop Duplication custom output #16

Closed AhmedX6 closed 5 years ago

AhmedX6 commented 7 years ago

Hello hecomi, I try to recreate the project that you did, with the only difference, that I want to send the buffer on the network. I would like to know if it was possible to customize the output of the frame. For example, I have my desktop which is in 1920x1080, I would like to be able to receive the buffer and dirty rect in 1280x720. I saw that there was the SetDisplaySurface function that could be applied before running DuplicateOutput. Here is my code:

HRESULT hr;

 hr = gDevice->QueryInterface(IID_PPV_ARGS(&gDxgiDevice));
        if (FAILED(hr))
            return;
        hr = gDxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&gDxgiAdapter));
        if (FAILED(hr))
            return;
        gDxgiDevice->Release();
        UINT Output = 0;
        IDXGIOutput *lDxgiOutput = nullptr;
        hr = gDxgiAdapter->EnumOutputs(Output, &lDxgiOutput);
        if (FAILED(hr))
            return;
        gDxgiAdapter->Release();
        hr = lDxgiOutput->GetDesc(&gOutputDesc);
        if (FAILED(hr))
            return;
        IDXGIOutput1 *lDxgiOutput1 = nullptr;
        hr = lDxgiOutput->QueryInterface(IID_PPV_ARGS(&lDxgiOutput1));
        if (FAILED(hr))
            return;
        lDxgiOutput->Release();
//Is it possible to customize the output here ? With SetDisplaySurface ?
        hr = lDxgiOutput1->DuplicateOutput(gDevice, &gDeskDupl);
        if (FAILED(hr))
            return;
        lDxgiOutput1->Release();
        gDeskDupl->GetDesc(&gOutputDuplDesc);

Is it possible for you to help me? Thanks a lot

hecomi commented 7 years ago

Sorry, I couldn't understand the situation. I guess there are two pc, the first one wants to send his buffer in a dirty rect, and the other one wants to receive that buffer. Is this matched to your thought? I think in that situation, it's ok for you to just fetch the buffer in a dirty rect from GPU to CPU with IDXGISurface::Map and send it to the other side.

AhmedX6 commented 7 years ago

I mean : is it possible to resize the texture before send it ? I did the IDXGISurface::Map and everything works well. But I would like to map a smaller texture. Here is my code :

if (mRealTexture == nullptr) {
            D3D11_TEXTURE2D_DESC description;
            texture2D->GetDesc(&description);
            description.BindFlags = 0;
            description.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
            description.Usage = D3D11_USAGE_STAGING;
            description.MiscFlags = 0;
            hr = mDevice->CreateTexture2D(&description, NULL, &mRealTexture);
            if (FAILED(hr)) {
                if (mRealTexture) {
                    mRealTexture->Release();
                    mRealTexture = nullptr;
                }
                return NULL;
            }
        }
        mImmediateContext->CopyResource(mRealTexture, texture2D);

        if (mScaledTexture == nullptr) {
            D3D11_TEXTURE2D_DESC description;
            texture2D->GetDesc(&description);
            description.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
            description.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
            description.Width = 1440;
            description.Height = 585;
            description.MipLevels = 4;
            description.ArraySize = 1;
            description.SampleDesc.Count = 1;
            description.SampleDesc.Quality = 0;
            description.Usage = D3D11_USAGE_DEFAULT;
            hr = mDevice->CreateTexture2D(&description, NULL, &mScaledTexture);
            if (FAILED(hr)) {
                if (mScaledTexture) {
                    mScaledTexture->Release();
                    mScaledTexture = nullptr;
                }
                return NULL;
            }
        } 
hecomi commented 7 years ago

Sorry for my late reply...,

If you want to resize the texture in GPU, render the original texture to the smaller one with full screen as described here: https://stackoverflow.com/questions/44265856/directx-11-scale-texture2d