IDXGISurface::Map: This object was not created with CPUAccess flags that allow CPU access

578 views Asked by At

I try to create new ID3D11Texture2D for map it to DXGI_MAPPED_RECT further. I receive some ID3D11Texture2D that I have no power on (can not change way of creation of).

Here is the part of the code:

CComPtr<IDXGIResource> cpDXGIResource;
RET_HR_NULL(_pTexIn->QueryInterface(__uuidof(IDXGIResource), (void**)&cpDXGIResource), cpDXGIResource);

HANDLE sharedHandle;
cpDXGIResource->GetSharedHandle(&sharedHandle);

CComPtr<ID3D11Texture2D> cpTexIn;
cpD3D11Device->OpenSharedResource(sharedHandle, __uuidof(ID3D11Resource), (void**)(&cpTexIn));

D3D11_TEXTURE2D_DESC td;
cpTexIn->GetDesc(&td);
td.Usage = D3D11_USAGE_STAGING;
td.BindFlags = D3D11_BIND_SHADER_RESOURCE;
td.CPUAccessFlags = D3D11_CPU_ACCESS_READ;

CComPtr<ID3D11Texture2D> cpNewTexture;
RET_HR_NULL(cpD3D11Device->CreateTexture2D(&td, NULL, &cpNewTexture), cpNewTexture);

cpD3D11DeviceContext->CopyResource(cpNewTexture, cpTexIn);

CComPtr<IDXGISurface> cpDXGISurface;
RET_HR_NULL(cpNewTexture->QueryInterface(&cpDXGISurface), cpDXGISurface);

D3D11_TEXTURE2D_DESC ntd;
cpNewTexture->GetDesc(&ntd);

DXGI_SURFACE_DESC sd;
cpDXGISurface->GetDesc(&sd);

DXGI_MAPPED_RECT bitmap2Dmap;
RET_HR(cpDXGISurface->Map(&bitmap2Dmap, DXGI_MAP_READ));

_pTexIn is an input ID3D11Texture2D. I get the error below while Map():

RET_HR(cpDXGISurface->Map(&bitmap2Dmap, DXGI_MAP_READ));

DXGI ERROR: IDXGISurface::Map: This object was not created with CPUAccess flags that allow CPU access. [ MISCELLANEOUS ERROR #42: ] Exception thrown at 0x76734192 in testhost.x86.exe: Microsoft C++ exception: _com_error at memory location 0x0716E134. The thread 0x26bc has exited with code 0 (0x0).

BUT!, actually I have D3D11_CPU_ACCESS_READ set on the cpNewTexture. See output of ntd and sd below:

Here is content of ntd and sd:

ntd {Width=0x00000354 Height=0x000001e0 MipLevels=0x00000001 ...}   D3D11_TEXTURE2D_DESC
    Width   0x00000354  unsigned int
    Height  0x000001e0  unsigned int
    MipLevels   0x00000001  unsigned int
    ArraySize   0x00000001  unsigned int
    Format  DXGI_FORMAT_B8G8R8A8_UNORM (0x00000057) DXGI_FORMAT
    SampleDesc  {Count=0x00000001 Quality=0x00000000 }  DXGI_SAMPLE_DESC
    Usage   D3D11_USAGE_DEFAULT (0x00000000)    D3D11_USAGE
    BindFlags   0x00000008  unsigned int
    CPUAccessFlags  0x00020000  unsigned int
    MiscFlags   0x00000002  unsigned int


sd  {Width=0x00000354 Height=0x000001e0 Format=DXGI_FORMAT_B8G8R8A8_UNORM (0x00000057) ...} DXGI_SURFACE_DESC
    Width   0x00000354  unsigned int
    Height  0x000001e0  unsigned int
    Format  DXGI_FORMAT_B8G8R8A8_UNORM (0x00000057) DXGI_FORMAT
    SampleDesc  {Count=0x00000001 Quality=0x00000000 }  DXGI_SAMPLE_DESC
1

There are 1 answers

0
Olga Pshenichnikova On

OK, in the main question Roma gave follow explonation:

OK, I seem to understand now... I thought you're mapping output texture (for reading!) but you are mapping input texture. Why? In my defense the execution flow is hard to read from the snippets. I am also confused why you are using IDXGISurface::Map() at all? You don't seem to need it. Perhaps you should explain yourself what you are trying to achieve. You already have a texture you use as input. Is it compatible with D2D? If yes, just use it first further. In it's not, create a compatible and copy input texture there. You don't need Map for either of the two.

Even if you do want Map, why IDXGISurface::Map()? You have ID3D11DeviceContext::Map() which is appropriate for accessing texture data with textures that assume this. I would say you are not supposed to do IDXGISurface::Map() at all. Then if Map() for reading output is intended you end drawing, then you either map the texture or copy it to mappable and map that second one.

After all

You don't need Map() anyway. Even though it is possible, this path with Map() and CreateBitmap() is an apparent performance hit. You could and should use other API instead. By using CreateSharedBitmap to create an ID2D1Bitmap from an IDXGISurface, you can write a Direct3D scene to a bitmap and render it with Direct2D.