I have been trying to solve the problem for a month with googling.
But Now I have to ask for help here.
I want to render using ffmpeg decoded frame.
and using frame(it converted to RGB32 format), I try to render frame with DX2D texture.
ZeroMemory(&TextureDesc, sizeof(TextureDesc));
TextureDesc.Height = pFrame->height;
TextureDesc.Width = pFrame->width;
TextureDesc.MipLevels = 1;
TextureDesc.ArraySize = 1;
TextureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; //size 16
TextureDesc.SampleDesc.Count = 1;
TextureDesc.SampleDesc.Quality = 0;
TextureDesc.Usage = D3D11_USAGE_DYNAMIC;
TextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
TextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
TextureDesc.MiscFlags = 0;
result = m_device->CreateTexture2D(&TextureDesc, NULL, &m_2DTex);
if (FAILED(result)) return false;
ShaderResourceViewDesc.Format = TextureDesc.Format;
ShaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
ShaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
ShaderResourceViewDesc.Texture2D.MipLevels = 1;
D3D11_MAPPED_SUBRESOURCE S_mappedResource_tt = { 0, };
ZeroMemory(&S_mappedResource_tt, sizeof(D3D11_MAPPED_SUBRESOURCE));
result = m_deviceContext->Map(m_2DTex, 0, D3D11_MAP_WRITE_DISCARD, 0, &S_mappedResource_tt);
if (FAILED(result)) return false;
BYTE* mappedData = reinterpret_cast<BYTE *>(S_mappedResource_tt.pData);
for (auto i = 0; i < pFrame->height; ++i) {
memcpy(mappedData, pFrame->data, pFrame->linesize[0]);
mappedData += S_mappedResource_tt.RowPitch;
pFrame->data[0] += pFrame->linesize[0];
}
m_deviceContext->Unmap(m_2DTex, 0);
result = m_device->CreateShaderResourceView(m_2DTex, &ShaderResourceViewDesc, &m_ShaderResourceView);
if (FAILED(result)) return false;
m_deviceContext->PSSetShaderResources(0, 1, &m_ShaderResourceView);
but it shows me just black screen(nothing render).
I guess it's wrong memcpy size.
The biggest problem is that I don't know what is the problem.
Question 1 :
It has any problem creating 2D texture for mapping?
Question 2 :
What size of the memcpy parameters should I enter (related to formatting)?
I based on the link below.
[1]https://www.gamedev.net/forums/topic/667097-copy-2d-array-into-texture2d/
[2]https://www.gamedev.net/forums/topic/645514-directx-11-maping-id3d11texture2d/
[3]https://www.gamedev.net/forums/topic/606100-solved-dx11-updating-texture-data/
Thank U for watching, Please reply.
Nobody reply. I solved my issue.
I have modified some code and I'm not sure if it solves the problem. The problem with the black screen Reason is my matrix.
D3D11_TEXTURE2D_DESC TextureDesc;
D3D11_RENDER_TARGET_VIEW_DESC RenderTargetViewDesc;
D3D11_SHADER_RESOURCE_VIEW_DESC ShaderResourceViewDesc;
ZeroMemory(&TextureDesc, sizeof(TextureDesc));
TextureDesc.Height = pFrame->height;
TextureDesc.Width = pFrame->width;
TextureDesc.MipLevels = 1;
TextureDesc.ArraySize = 1;
TextureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;/*DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;*/ //size 32bit
TextureDesc.SampleDesc.Count = 1;
TextureDesc.SampleDesc.Quality = 0;
TextureDesc.Usage = D3D11_USAGE_DYNAMIC;
TextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
TextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
TextureDesc.MiscFlags = 0;
DWORD* pInitImage = new DWORD[pFrame->width*pFrame->height];
memset(pInitImage, 0, sizeof(DWORD)*pFrame->width*pFrame->height);
D3D11_SUBRESOURCE_DATA InitData;
InitData.pSysMem = pInitImage;
InitData.SysMemPitch = pFrame->width*sizeof(DWORD);
InitData.SysMemSlicePitch = 0;
result = m_device->CreateTexture2D(&TextureDesc, &InitData, &m_2DTex);
if (FAILED(result)) return false;
ShaderResourceViewDesc.Format = TextureDesc.Format;
ShaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
ShaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
ShaderResourceViewDesc.Texture2D.MipLevels = 1;
result = m_device->CreateShaderResourceView(m_2DTex, &ShaderResourceViewDesc, &m_ShaderResourceView);
if (FAILED(result)) return false;
D3D11_MAPPED_SUBRESOURCE S_mappedResource_tt;
ZeroMemory(&S_mappedResource_tt, sizeof(S_mappedResource_tt));
DWORD Stride = pFrame->linesize[0];
result = m_deviceContext->Map(m_2DTex, 0, D3D11_MAP_WRITE_DISCARD, 0, &S_mappedResource_tt);
if (FAILED(result)) return false;
BYTE * pFrameData = pFrame->data[0]; // now we have a pointer that points to begin of the destination buffer
BYTE* mappedData = (BYTE *)S_mappedResource_tt.pData;// +S_mappedResource_tt.RowPitch;
for (auto i = 0; i < pFrame->height; i++) {
memcpy(mappedData, pFrameData, Stride);
mappedData += S_mappedResource_tt.RowPitch;
pFrameData += Stride;
}
m_deviceContext->Unmap(m_2DTex, 0);
It works vell. I hope that it will be helpful to those who are doing the same thing with me.
Related
The problem is that if you do not use these methods, then the FPS differs by about 2 times in a big way. For example, I had about 5000 fps in a 3d scene. And it became about 2500. I know that the problem is that the application is waiting for the copy to wait. But it's only 4 bytes... If you use the D3D11_MAP_FLAG_DO_NOT_WAIT flag, Map() will always return DXGI_ERROR_WAS_STILL_DRAWING. What can be done so that I can use this method without losing fps? Here is my code:
Init
D3D11_BUFFER_DESC outputDesc;
outputDesc.Usage = D3D11_USAGE_DEFAULT;
outputDesc.ByteWidth = sizeof(float);
outputDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS;
outputDesc.CPUAccessFlags = 0;
outputDesc.StructureByteStride = sizeof(float);
outputDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
FOG_TRACE(mDevice->CreateBuffer(&outputDesc, nullptr, &outputBuffer));
outputDesc.Usage = D3D11_USAGE_STAGING;
outputDesc.BindFlags = 0;
outputDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
FOG_TRACE(mDevice->CreateBuffer(&outputDesc, nullptr, &outputResultBuffer));
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc{};
uavDesc.Buffer.FirstElement = 0;
uavDesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_APPEND;
uavDesc.Buffer.NumElements = 1;
uavDesc.Format = DXGI_FORMAT_UNKNOWN;
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
FOG_TRACE(mDevice->CreateUnorderedAccessView(outputBuffer, &uavDesc, &unorderedAccessView));
Update
const UINT offset = 0;
mDeviceContext->OMSetRenderTargetsAndUnorderedAccessViews(1, &mRenderTargetView, mDepthStencilView, 1, 1, &unorderedAccessView, &offset);
mDeviceContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
ObjectManager::Draw();
mDeviceContext->CopyResource(outputResultBuffer, outputBuffer);
D3D11_MAPPED_SUBRESOURCE mappedBuffer;
HRESULT hr;
FOG_TRACE(hr = mDeviceContext->Map(outputResultBuffer, 0, D3D11_MAP_READ, 0/*D3D11_MAP_FLAG_DO_NOT_WAIT*/, &mappedBuffer));
if (SUCCEEDED(hr))
{
float* copy = (float*)(mappedBuffer.pData);
OutputDebugString(String::ToStr(*copy) + L"\n");
}
mDeviceContext->Unmap(outputResultBuffer, 0);
const UINT var[4]{};
mDeviceContext->ClearUnorderedAccessViewUint(unorderedAccessView, var);
I've already profiled and checked everything possible, the problem is exactly in pending. I would be very grateful if someone could explain everything in detail :)
The problem was solved very simply but for a long time! I just didn't make copy calls until I had read past data. Here is a small crutch:
static bool isWait = false;
if (!isWait)
{
mDeviceContext->CopyResource(outputResultBuffer, outputBuffer);
}
D3D11_MAPPED_SUBRESOURCE mappedBuffer;
HRESULT hr;
FOG_TRACE(hr = mDeviceContext->Map(outputResultBuffer, 0, D3D11_MAP_READ, D3D11_MAP_FLAG_DO_NOT_WAIT, &mappedBuffer));
if (SUCCEEDED(hr))
{
float* copy = (float*)(mappedBuffer.pData);
OutputDebugString(String::ToStr(*copy) + L"\n");
mDeviceContext->Unmap(outputResultBuffer, 0);
const UINT var[4]{};
mDeviceContext->ClearUnorderedAccessViewUint(unorderedAccessView, var);
isWait = false;
}
else
{
isWait = true;
}
I want to load in a skysphere, I know how to do it using a dds file, but I want to try and do it from 6 separate texture files.
The problem I have is that when I load in the texturecube, only 3 separate textures are visible, the other 3 are not. I'll show you my code and how it looks in Nsight. I am right now using just 6 different uniform colored png files, they are all 512x512 in size.
std::vector<std::string> paths = { "../Resources/Textures/posX.png", "../Resources/Textures/negX.png",
"../Resources/Textures/posY.png",
"../Resources/Textures/negY.png",
"../Resources/Textures/posZ.png", "../Resources/Textures/negZ.png" };
ID3D11Texture2D* cubeTexture = NULL;
WRL::ComPtr<ID3D11ShaderResourceView> shaderResourceView = NULL;
//Description of each face
D3D11_TEXTURE2D_DESC texDesc = {};
texDesc.Width = 512;
texDesc.Height = 512;
texDesc.MipLevels = 1;
texDesc.ArraySize = 6;
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texDesc.CPUAccessFlags = 0;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DEFAULT;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = 0;
texDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
//The Shader Resource view description
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc = {};
SMViewDesc.Format = texDesc.Format;
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SMViewDesc.TextureCube.MipLevels = texDesc.MipLevels;
SMViewDesc.TextureCube.MostDetailedMip = 0;
D3D11_SUBRESOURCE_DATA pData[6] = {};
for (int i = 0; i < 6; i++)
{
ID3D11Resource* res = nullptr;
std::wstring pathWString(paths[j].begin(), paths[j].end());
HRESULT hr = DirectX::CreateWICTextureFromFileEx(Renderer::getDevice(), pathWString.c_str(), 0, D3D11_USAGE_STAGING, 0, D3D11_CPU_ACCESS_READ, 0,
WIC_LOADER_FLAGS::WIC_LOADER_DEFAULT,
&res, 0);
assert(SUCCEEDED(hr));
D3D11_MAPPED_SUBRESOURCE destRes = {};
Renderer::getContext()->Map(res, 0, D3D11_MAP_READ, 0, &destRes);
pData[i].pSysMem = destRes.pData;
pData[i].SysMemPitch = destRes.RowPitch;
pData[i].SysMemSlicePitch = destRes.DepthPitch;
Renderer::getContext()->Unmap(res, 0);
RELEASE_COM(res);
}
Renderer::getDevice()->CreateTexture2D(&texDesc, &pData[0], &cubeTexture);
Renderer::getDevice()->CreateShaderResourceView(cubeTexture, &SMViewDesc, shaderResourceView.GetAddressOf());
When graphics debugging, this is what the cubemap looks like, 3 textures are loaded in twice, overwriting the other 3.
When reading the documentation it says subresource should be relating to mip levels.
If I loop 9 times instead of 6, the other 3 images are shown instead of these current 3. All 6 should have unique colors.
What I'm doing in the code is creating a Texture2D Description, a Shader Resource View Descriptuion, then I try to fetch data from imported images using WIC, I put it in a resource then map that to a subresource struct.
When looking at the addresses of the subresource, all 6 are always unique so it seems they load in the textures correctly, I have tried moving around the rowpitch, changing the size of the image but it only seems to affect the single images inside the textureCube, it doesn't seem to move around the duplicates if you understand what I mean.
Any help is greatly appreciated.
So I found some code from a Frank D Luna example doing something else.
Here is the code I use that works, mip levels had to be taken into account.
I hope this helps if someone in the future has a similar issue.
ID3D11Texture2D* cubeTexture = NULL;
WRL::ComPtr<ID3D11ShaderResourceView> shaderResourceView = NULL;
//Description of each face
D3D11_TEXTURE2D_DESC texDesc = {};
D3D11_TEXTURE2D_DESC texDesc1 = {};
//The Shader Resource view description
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc = {};
ID3D11Texture2D* tex[6] = { nullptr, nullptr, nullptr,nullptr, nullptr, nullptr };
for (int i = 0; i < 6; i++)
{
std::wstring pathWString(paths[i].begin(), paths[i].end());
HRESULT hr = DirectX::CreateWICTextureFromFileEx(Renderer::getDevice(), pathWString.c_str(), 0, D3D11_USAGE_STAGING, 0, D3D11_CPU_ACCESS_READ| D3D11_CPU_ACCESS_WRITE, 0,
WIC_LOADER_FLAGS::WIC_LOADER_DEFAULT,
(ID3D11Resource**)&tex[i], 0);
assert(SUCCEEDED(hr));
}
tex[0]->GetDesc(&texDesc1);
texDesc.Width = texDesc1.Width;
texDesc.Height = texDesc1.Height;
texDesc.MipLevels = texDesc1.MipLevels;
texDesc.ArraySize = 6;
texDesc.Format = texDesc1.Format;
texDesc.CPUAccessFlags = 0;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DEFAULT;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = 0;
texDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
SMViewDesc.Format = texDesc.Format;
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SMViewDesc.TextureCube.MipLevels = texDesc.MipLevels;
SMViewDesc.TextureCube.MostDetailedMip = 0;
Renderer::getDevice()->CreateTexture2D(&texDesc, NULL, &cubeTexture);
for (int i = 0; i < 6; i++)
{
for (UINT mipLevel = 0; mipLevel < texDesc.MipLevels; ++mipLevel)
{
D3D11_MAPPED_SUBRESOURCE mappedTex2D;
HRESULT hr = (Renderer::getContext()->Map(tex[i], mipLevel, D3D11_MAP_READ, 0, &mappedTex2D));
assert(SUCCEEDED(hr));
Renderer::getContext()->UpdateSubresource(cubeTexture,
D3D11CalcSubresource(mipLevel, i, texDesc.MipLevels),
0, mappedTex2D.pData, mappedTex2D.RowPitch, mappedTex2D.DepthPitch);
Renderer::getContext()->Unmap(tex[i], mipLevel);
}
}
for (int i = 0; i < 6; i++)
{
RELEASE_COM(tex[i]);
}
Renderer::getDevice()->CreateShaderResourceView(cubeTexture, &SMViewDesc, shaderResourceView.GetAddressOf());
i'm working on an old project based on AVR, that controls a led stripe using 1 pin with SPI high frequency in DMA. (42 leds)
I'm converting the code to esp-idf, but i'm facing some problem, probably base on bus/config parameters.
These are the code:
AVR:
USART_SPI_RGB_OPTIONS.baudrate = USART_SPI_RGB_BAUDRATE;
USART_SPI_RGB_OPTIONS.spimode = USART_SPI_RGB_CHMODE;
USART_SPI_RGB_OPTIONS.data_order = USART_SPI_RGB_DATA_ORDER;
usart_init_spi(USART_SPI_RGB_PORT, &USART_SPI_RGB_OPTIONS);
void dma_init(void){
struct dma_channel_config dmach_conf;
memset(&dmach_conf, 0, sizeof(dmach_conf));
dma_channel_set_burst_length(&dmach_conf, DMA_CH_BURSTLEN_1BYTE_gc);
dma_channel_set_transfer_count(&dmach_conf, DMA_BUFFER_SIZE);
dma_channel_set_src_reload_mode(&dmach_conf, DMA_CH_SRCRELOAD_TRANSACTION_gc);
dma_channel_set_dest_reload_mode(&dmach_conf, DMA_CH_DESTRELOAD_NONE_gc);
dma_channel_set_src_dir_mode(&dmach_conf, DMA_CH_SRCDIR_INC_gc);
dma_channel_set_source_address(&dmach_conf, (uint16_t)(uintptr_t)RGBMemoryMap);
dma_channel_set_dest_dir_mode(&dmach_conf, DMA_CH_DESTDIR_FIXED_gc);
dma_channel_set_destination_address(&dmach_conf, (uint16_t)(uintptr_t)USART_SPI_RGB_PORT.DATA);
dma_channel_set_trigger_source(&dmach_conf, DMA_CH_TRIGSRC_USARTD0_DRE_gc);
dma_channel_set_single_shot(&dmach_conf);
dma_enable();
dma_channel_write_config(DMA_CHANNEL, &dmach_conf);
dma_channel_enable(DMA_CHANNEL);
}
ESP-IDF:
void initSPISettings()
{
//memset(&SPI_settings, 0, sizeof(SPI_settings));
SPI_settings.host = HSPI_HOST,
SPI_settings.dma_chan = SPI_DMA_CH2;
// buscfg
SPI_settings.buscfg.flags = 0;
SPI_settings.buscfg.miso_io_num = -1;
SPI_settings.buscfg.mosi_io_num = GPIO_NUM_32;
SPI_settings.buscfg.sclk_io_num = -1;
SPI_settings.buscfg.quadwp_io_num = -1;
SPI_settings.buscfg.quadhd_io_num = -1;
SPI_settings.buscfg.max_transfer_sz = LED_DMA_BUFFER_SIZE;
// devcfg
SPI_settings.devcfg.clock_speed_hz = DMA_SPEED;
SPI_settings.devcfg.dummy_bits = 0;
SPI_settings.devcfg.mode = 0;
SPI_settings.devcfg.flags = SPI_DEVICE_NO_DUMMY;
SPI_settings.devcfg.spics_io_num = -1;
SPI_settings.devcfg.queue_size = 1;
SPI_settings.devcfg.command_bits = 0;
SPI_settings.devcfg.address_bits = 0;
}
void initSPI()
{
esp_err_t err;
initSPISettings();
err = spi_bus_initialize(SPI_settings.host, &SPI_settings.buscfg, SPI_settings.dma_chan);
ESP_ERROR_CHECK(err);
//Attach the Accel to the SPI bus
err = spi_bus_add_device(SPI_settings.host, &SPI_settings.devcfg, &SPI_settings.spi);
ESP_ERROR_CHECK(err);
}
void updateRGB()
{
spi_transaction_t t;
esp_err_t err;
printf("Start transaction to DMA...\r\n");
// for (int i = (LED_DMA_BUFFER_SIZE - LED_RESET_COUNT); i < LED_DMA_BUFFER_SIZE; i++) {
// //Setting more bytes to 0x00 at the end of memory map to assure correct RGB init
// ledDMAbuffer[i] = 0x00;
// }
t.flags = 0;
t.length = LED_DMA_BUFFER_SIZE * 8; //length is in bits
t.tx_buffer = ledDMAbuffer;
t.rx_buffer = NULL;
t.rxlength = 0;
err = spi_device_transmit(SPI_settings.spi, &t);
ESP_ERROR_CHECK(err);
}
ledDMAbuffer = heap_caps_malloc(LED_DMA_BUFFER_SIZE, MALLOC_CAP_DMA); // Critical to be DMA memory.
Do you have any ideas what i'm missing?
I fill data in the right way (i'm sure of that). If i try to control 1 led no problem at all, while increasing the number of leds controlled i have strange behaviour (for example with 2 led blinking red/green, first one works properly while second one just red)
Thanks to all
I use dxgi to capture window, since the windows maybe resized, so I use IDXGISwapChain1 and recreate framepool, but now I can't get the surface since GetRestrictToOutput always return null.
void OnFrameArrived(winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool const &sender,winrt::Windows::Foundation::IInspectable const &)
{
const winrt::Windows::Graphics::Capture::Direct3D11CaptureFrame frame = sender.TryGetNextFrame();
auto swapChainResizedToFrame = TryResizeSwapChain(frame);
winrt::com_ptr<ID3D11Texture2D> backBuffer;
winrt::check_hresult(m_swapChain->GetBuffer(0, winrt::guid_of<ID3D11Texture2D>(), backBuffer.put_void()));
winrt::com_ptr<ID3D11Texture2D> frameSurface = GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
m_d3dContext->CopyResource(backBuffer.get(), frameSurface.get());
DXGI_PRESENT_PARAMETERS presentParameters{};
m_swapChain->Present1(1, 0, &presentParameters);
//winrt::com_ptr<IDXGIOutput> dxgiOutput = nullptr;
IDXGIOutput* dxgiOutput = nullptr;
BOOL full;
m_swapChain->GetRestrictToOutput(&dxgiOutput);
if(dxgiOutput!=nullptr){
std::cerr <<"33333333333333"<<std::endl;
...
}
m_framePool.Recreate(m_device, m_pixelFormat, 2, m_lastSize);
If I use getbuffer to get the image data, if the window size is changed, then the image is black, the code is as below:
winrt::com_ptr<ID3D11Texture2D> renderBuffer;
winrt::check_hresult(m_swapChain->GetBuffer(0, winrt::guid_of<ID3D11Texture2D>(), renderBuffer.put_void()));
if(renderBuffer != nullptr){
D3D11_TEXTURE2D_DESC desc;
renderBuffer->GetDesc(&desc);
desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
winrt::com_ptr<ID3D11Texture2D> textureCopy;
auto d3dDevice = GetDXGIInterfaceFromObject<ID3D11Device>(m_device);
winrt::check_hresult(d3dDevice->CreateTexture2D(&desc, nullptr, textureCopy.put()));
m_d3dContext->CopyResource(textureCopy.get(), renderBuffer.get());
winrt::com_ptr<IDXGISurface> dxgi_surface = nullptr;
HRESULT hr = textureCopy->QueryInterface(__uuidof(IDXGISurface), (void **)(&dxgi_surface));
DXGI_MAPPED_RECT mapped_rect;
hr = dxgi_surface->Map(&mapped_rect, DXGI_MAP_READ);
unsigned int imgSize = desc.Width * desc.Height * 4;
uint8_t* buffer = new uint8_t[imgSize];
int dst_rowpitch = desc.Width * 4;
for (unsigned int h = 0; h < desc.Height; h++) {
memcpy_s(buffer + h * dst_rowpitch, dst_rowpitch, (BYTE*)mapped_rect.pBits + h * mapped_rect.Pitch, min(mapped_rect.Pitch, dst_rowpitch));
}
dxgi_surface->Unmap();
I'm try to communicate with \Windows\SbApiPort port .
The problem is that I get an error from NtRequestPort (0xc000000d - status invalid parameter).
The parameters of PORT_MESSAGE are not documented so I don't know where is my problem...
I tried to change the length, CallbackId, but the same problem...
Thanks for the help !
Here is the code:
HANDLE hSection=0;
LARGE_INTEGER SecSize;
SecSize.LowPart=0x10000;
SecSize.HighPart=0x0;
if(NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, &SecSize, PAGE_READWRITE,SEC_COMMIT ,NULL))
{
printf("couldn't create a section");
}
HANDLE hPort;
PORT_VIEW sectionInfo;
REMOTE_PORT_VIEW mapInfo;
byte ConnectDataBuffer[0x100];
DWORD Size = sizeof(ConnectDataBuffer);
UNICODE_STRING uStr;
WCHAR * uString=L"\\Windows\\SbApiPort";
DWORD maxSize;
SECURITY_QUALITY_OF_SERVICE qos;
for (int i=0 ; i < 0x100 ; i++)
{
ConnectDataBuffer[i]=0xcc;
}
memset(§ionInfo, 0, sizeof(sectionInfo));
memset(&mapInfo, 0, sizeof(mapInfo));
memset(&mapInfo, 0, sizeof(mapInfo));
memset(&qos, 0, sizeof(qos));
qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
qos.ImpersonationLevel = SecurityImpersonation;
qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
qos.EffectiveOnly = TRUE;
sectionInfo.Length = sizeof(LPC_SECTION_OWNER_MEMORY);
sectionInfo.SectionHandle = hSection;
sectionInfo.SectionOffset = 0;
sectionInfo.ViewSize = 0x10000;
sectionInfo.ViewBase = NULL;
sectionInfo.ViewRemoteBase = NULL;
mapInfo.Length = sizeof(LPC_SECTION_MEMORY);
mapInfo.ViewSize = 0;
mapInfo.ViewBase = NULL;
uStr.Length = wcslen(uString)*2;
uStr.MaximumLength = wcslen(uString)*2+2;
uStr.Buffer =uString;
NTSTATUS res = NtConnectPort(&hPort,&uStr,&qos,§ionInfo,&mapInfo,&maxSize,(DWORD*)&ConnectDataBuffer,&Size);
if (res)
{
printf("Could not connect to LPC port.\n -%x", res);
return 1;
}
PORT_MESSAGE PortMessage;
ZeroMemory(&PortMessage,sizeof(PORT_MESSAGE));
PortMessage.u1.Length = 0x20;
PortMessage.u2.s2.DataInfoOffset = 15;
PortMessage.u2.ZeroInit = 0x20;
PortMessage.MessageId = LPC_REQUEST;
PortMessage.ClientViewSize = 0x20;
PortMessage.ClientId.UniqueProcess = GetCurrentProcess();
PortMessage.ClientId.UniqueThread = GetCurrentThread();
PortMessage.CallbackId = 0;
res = NtRequestPort(hPort, &PortMessage);
if (res)
{
printf("Could not request LPC port.\n -%x", res);
return 1;
}
printf("End\n", res);