IDXGISurface::Map: этот объект не был создан с флагами CPUAccess, разрешающими доступ к процессору.
Я пытаюсь создать новый ID3D11Texture2D
для сопоставления с DXGI_MAPPED_RECT
в дальнейшем. Я получаю немногоID3D11Texture2D
что у меня нет питания (не могу изменить способ создания).
Вот часть кода:
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
является входным ID3D11Texture2D. Я получаю сообщение об ошибке ниже, покаMap()
:
RET_HR(cpDXGISurface->Map(&bitmap2Dmap, DXGI_MAP_READ));
ОШИБКА DXGI: IDXGISurface::Map: этот объект не был создан с флагами CPUAccess, разрешающими доступ к процессору. [ПРОЧАЯ ОШИБКА № 42: ] Исключение по адресу 0x76734192 в testhost.x86.exe: исключение Microsoft C++: _com_error в ячейке памяти 0x0716E134. Поток 0x26bc завершился с кодом 0 (0x0).
НО! на самом деле у меня естьD3D11_CPU_ACCESS_READ
установить на cpNewTexture
. См. Вывод ntd и sd ниже:
Вот содержание ntd
а также 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 ответ
Хорошо, в основном вопросе Roman R. объяснил следующее:
Хорошо, теперь я, кажется, понимаю... Я думал, вы отображаете текстуру вывода (для чтения!), Но вы отображаете текстуру ввода. Почему? В свою защиту поток выполнения трудно прочитать из фрагментов. Я также не понимаю, почему вы используете
IDXGISurface::Map()
вообще? Кажется, тебе это не нужно. Возможно, вам стоит объяснить себе, чего вы пытаетесь достичь. У вас уже есть текстура, которую вы используете в качестве входных данных. Совместимо ли это сD2D
? Если да, просто используйте его в дальнейшем. В нем нет, создайте совместимую и скопируйте туда текстуру ввода. Вам не нужна карта ни для одного из двух.Даже если вам нужна карта, почему
IDXGISurface::Map()
? У тебя естьID3D11DeviceContext::Map()
что подходит для доступа к данным текстуры с текстурами, которые это предполагают. Я бы сказал, что ты не должен делатьIDXGISurface::Map()
вообще. Тогда еслиMap()
для чтения вывода предполагается, что вы заканчиваете рисование, затем вы либо сопоставляете текстуру, либо копируете ее в сопоставимую и сопоставляете ту вторую.
После всего
Тебе не нужно
Map()
тем не мение. Хотя это возможно, этот путь сMap()
а такжеCreateBitmap()
очевидный удар по производительности. Вместо этого вы можете и должны использовать другой API. Используя CreateSharedBitmap для создания ID2D1Bitmap из IDXGISurface, вы можете записать сцену Direct3D в растровое изображение и отрендерить ее с помощью Direct2D.