0

I'm trying to get, basically, screenshot (each 1 second, without saving) of Direct3D11 application. Code works fine on my PC(Intel CPU, Radeon GPU) but crashes after few iterations on 2 others (Intel CPU + Intel integrated GPU, Intel CPU + Nvidia GPU).

void extractBitmap(void* texture) {

    if (texture) {
        ID3D11Texture2D* d3dtex = (ID3D11Texture2D*)texture;
        ID3D11Texture2D* pNewTexture = NULL;

        D3D11_TEXTURE2D_DESC desc;
        d3dtex->GetDesc(&desc);

        desc.BindFlags = 0;
        desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
        desc.Usage = D3D11_USAGE_STAGING;
        desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;

        HRESULT hRes = D3D11Device->CreateTexture2D(&desc, NULL, &pNewTexture);

        if (FAILED(hRes)) {
            printCon(std::string("CreateTexture2D FAILED:" + format_error(hRes)).c_str());
            if (hRes == DXGI_ERROR_DEVICE_REMOVED)
                printCon(std::string("DXGI_ERROR_DEVICE_REMOVED -- " + format_error(D3D11Device->GetDeviceRemovedReason())).c_str());
        }
        else {
            if (pNewTexture) {
                D3D11DeviceContext->CopyResource(pNewTexture, d3dtex);

                // Wokring with texture

                pNewTexture->Release();
            }
        }
    }
    return;
}


D3D11SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast< void** >(&pBackBuffer));
extractBitmap(pBackBuffer);
pBackBuffer->Release();

Crash log:

CreateTexture2D FAILED:887a0005
DXGI_ERROR_DEVICE_REMOVED -- 887a0020

Once I comment out D3D11DeviceContext->CopyResource(pNewTexture, d3dtex); code works fine on all 3 PC's.

Alex Hide
  • 555
  • 5
  • 18
  • You can try two things: use DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8X8_UNORM, DXGI_FORMAT_B8G8R8X8_UNORM or even better use the format from the D3D11SwapChain->GetBuffer(0... texture; AND/OR replace CopyResource with CopySubresource: https://stackoverflow.com/a/10624205/2440728 – VuVirt Sep 13 '17 at 15:50
  • @VuVirt Thanks, I'll try it. Original texture is DXGI_FORMAT_R8G8B8A8_UNORM_SRGB aswell. – Alex Hide Sep 13 '17 at 16:03
  • is it always DXGI_FORMAT_R8G8B8A8_UNORM_SRGB when running on other GPUs? – VuVirt Sep 13 '17 at 16:16
  • @VuVirt Yes, it is – Alex Hide Sep 13 '17 at 16:23
  • the reason for the crash could be wrong or not up-to-date video drivers – VuVirt Sep 13 '17 at 16:28
  • Are you still calling ``Present`` every frame? – Chuck Walbourn Sep 13 '17 at 17:48
  • BTW, you should take a look at the [ScreenGrab](https://github.com/Microsoft/DirectXTK/blob/master/Src/ScreenGrab.cpp) source code in the _DirectX Tool Kit_. – Chuck Walbourn Sep 13 '17 at 17:49
  • @ChuckWalbourn As I'm injecting to another application, I don't know, but it's the same every time. Thanks for the link. – Alex Hide Sep 13 '17 at 18:00
  • https://msdn.microsoft.com/en-us/library/windows/desktop/ff476392(v=vs.85).aspx CopyResource might fail if the source and destination dimensions/formats are different; or when the source texture is Map'ed; or when the backbuffer is multisampled (in this case you should call ResolveSubResource first). – VuVirt Sep 14 '17 at 08:43
  • @VuVirt desc.SampleDesc.Count is 1 always. As I mentioned above, I use format and dimensions from original texture (GetDesc and then applied it to create my texture). I've tried to check if texture is _STAGING, but it never was. Is there any way to check whether texture is already mapped? – Alex Hide Sep 14 '17 at 09:21
  • 1
    Not that I know of, but you can try to call your extract function in a different moment from your hook, to see if it changes anything. – VuVirt Sep 14 '17 at 09:23

1 Answers1

0

Got it wokring. I was running my code in separate thread. After I moved it to hooked Present(), application did not crash.

Alex Hide
  • 555
  • 5
  • 18