/** * @fn Resize (int w, int h) * * @brief Resizes the render target, creates new textures and views * * @param w - New resource width * * @param h - New resource height */ void CDXRenderTarget::Resize(int resW, int resH) { HRESULT hr; SAFE_RELEASE(m_pSRV); SAFE_RELEASE(m_pRTV); SAFE_RELEASE(m_pTexture); SAFE_RELEASE(m_pTextureCPU); // Save the new values m_width = resW; m_height = resH; // Get the device ID3D10Device *pDev = DXUTGetD3D10Device(); // Create the texture here CD3D10_TEXTURE2D_DESC desc(m_fmt, resW, resH, 1, 1); desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE; desc.Usage = D3D10_USAGE_DEFAULT; hr = pDev->CreateTexture2D(&desc, NULL, &m_pTexture); assert(hr == S_OK); // Create the CPU version of the texture here CD3D10_TEXTURE2D_DESC descCPU(m_fmt, resW, resH, 1, 1); descCPU.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; descCPU.Usage = D3D10_USAGE_DYNAMIC; hr = pDev->CreateTexture2D(&descCPU, NULL, &m_pTextureCPU); assert(hr == S_OK); // Create the shader resource view D3D10_SHADER_RESOURCE_VIEW_DESC resDesc; resDesc.Format = m_fmt; resDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; resDesc.Texture2D.MipLevels = 1; resDesc.Texture2D.MostDetailedMip = 0; hr = pDev->CreateShaderResourceView(m_pTexture, &resDesc, &m_pSRV); assert(hr == S_OK); // Create the render target view D3D10_RENDER_TARGET_VIEW_DESC rtDesc; rtDesc.Format = m_fmt; rtDesc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D; rtDesc.Texture2D.MipSlice = 0; hr = pDev->CreateRenderTargetView(m_pTexture, &rtDesc, &m_pRTV); assert(hr == S_OK); } // End of resize()
bool TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags) { mSize = aSize; ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device(); CD3D10_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1, D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE); newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX; HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture)); if (FAILED(hr)) { LOGD3D11("Error creating texture for client!"); return false; } // Defer clearing to the next time we lock to avoid an extra (expensive) lock. mNeedsClear = aFlags & ALLOC_CLEAR_BUFFER; mNeedsClearWhite = aFlags & ALLOC_CLEAR_BUFFER_WHITE; return true; }
static bool grabFrameD3D10(IDXGISwapChain *swap) { ID3D10Device *device = 0; ID3D10Texture2D *tex = 0, *captureTex = 0; if (FAILED(swap->GetBuffer(0, IID_ID3D10Texture2D, (void**)&tex))) return false; D3D10_TEXTURE2D_DESC desc; tex->GetDevice(&device); tex->GetDesc(&desc); // re-creating the capture staging texture each frame is definitely not the most efficient // way to handle things, but it frees me of all kind of resource management trouble, so // here goes... desc.MipLevels = 1; desc.ArraySize = 1; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D10_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ; desc.MiscFlags = 0; if(FAILED(device->CreateTexture2D(&desc,0,&captureTex))) printLog("video/d3d10: couldn't create staging texture for gpu->cpu download!\n"); else setCaptureResolution(desc.Width,desc.Height); if(device) device->CopySubresourceRegion(captureTex,0,0,0,0,tex,0,0); D3D10_MAPPED_TEXTURE2D mapped; bool grabOk = false; if(captureTex && SUCCEEDED(captureTex->Map(0,D3D10_MAP_READ,0,&mapped))) { switch(desc.Format) { case DXGI_FORMAT_R8G8B8A8_UNORM: blitAndFlipRGBAToCaptureData((unsigned char *) mapped.pData,mapped.RowPitch); grabOk = true; break; default: printLog("video/d3d10: unsupported backbuffer format, can't grab pixels!\n"); break; } captureTex->Unmap(0); } tex->Release(); if(captureTex) captureTex->Release(); if(device) device->Release(); return grabOk; }
void TextureClientD3D11::Unlock() { MOZ_ASSERT(mIsLocked, "Unlocked called while the texture is not locked!"); if (!mIsLocked) { return; } if (mDrawTarget) { // see the comment on TextureClient::BorrowDrawTarget. // This DrawTarget is internal to the TextureClient and is only exposed to the // outside world between Lock() and Unlock(). This assertion checks that no outside // reference remains by the time Unlock() is called. MOZ_ASSERT(mDrawTarget->refCount() == 1); mDrawTarget->Flush(); } if (mReadbackSink && mTexture10) { ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device(); D3D10_TEXTURE2D_DESC desc; mTexture10->GetDesc(&desc); desc.BindFlags = 0; desc.Usage = D3D10_USAGE_STAGING; desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ; desc.MiscFlags = 0; RefPtr<ID3D10Texture2D> tex; HRESULT hr = device->CreateTexture2D(&desc, nullptr, byRef(tex)); if (FAILED(hr)) { gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(mSize))) << "[D3D11] CreateTexture2D failure " << mSize << " Code: " << gfx::hexa(hr); return; } if (SUCCEEDED(hr)) { device->CopyResource(tex, mTexture10); gfxWindowsPlatform::GetPlatform()->GetReadbackManager()->PostTask(tex, mReadbackSink); } else { mReadbackSink->ProcessReadback(nullptr); } } // The DrawTarget is created only once, and is only usable between calls // to Lock and Unlock. if (mTexture) { UnlockD3DTexture(mTexture.get()); } else { UnlockD3DTexture(mTexture10.get()); } mIsLocked = false; }
bool DeprecatedTextureClientD3D11::EnsureAllocated(gfx::IntSize aSize, gfxContentType aType) { D3D10_TEXTURE2D_DESC desc; if (mTexture) { mTexture->GetDesc(&desc); if (desc.Width == aSize.width && desc.Height == aSize.height) { return true; } mTexture = nullptr; mSurface = nullptr; ClearDT(); } mSize = aSize; ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device(); CD3D10_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1, D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE); newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX; HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture)); if (FAILED(hr)) { LOGD3D11("Error creating texture for client!"); return false; } RefPtr<IDXGIResource> resource; mTexture->QueryInterface((IDXGIResource**)byRef(resource)); HANDLE sharedHandle; hr = resource->GetSharedHandle(&sharedHandle); if (FAILED(hr)) { LOGD3D11("Error getting shared handle for texture."); return false; } mDescriptor = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle, aType == GFX_CONTENT_COLOR_ALPHA); mContentType = aType; return true; }
void D10State::newTexture(unsigned int w, unsigned int h) { HRESULT hr; ods("D3D10: newTexture %d %d", w, h); if (pTexture) { pTexture->Release(); pTexture = NULL; } if (pSRView) { pSRView->Release(); pSRView = NULL; } D3D10_TEXTURE2D_DESC desc; ZeroMemory(&desc, sizeof(desc)); desc.Width = w; desc.Height = h; desc.MipLevels = desc.ArraySize = 1; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.SampleDesc.Count = 1; desc.Usage = D3D10_USAGE_DYNAMIC; desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; hr = pDevice->CreateTexture2D(&desc, NULL, &pTexture); if (FAILED(hr)) { pTexture = NULL; ods("D3D10: Failed to create texture."); return; } D3D10_SHADER_RESOURCE_VIEW_DESC srvDesc; ZeroMemory(&srvDesc, sizeof(srvDesc)); srvDesc.Format = desc.Format; srvDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = desc.MipLevels; hr = pDevice->CreateShaderResourceView(pTexture, &srvDesc, &pSRView); if (FAILED(hr)) { pSRView = NULL; pTexture->Release(); pTexture = NULL; ods("D3D10: Failed to create resource view."); return; } }
void D3D10Texture::Allocate(UINT Width, UINT Height, bool ConstructMipmaps, DXGI_FORMAT Format, const Bitmap &Bmp) { FreeMemory(); PersistentAssert(_GD != NULL, "D3D10Texture::Allocate on unassociated texture"); ID3D10Device* Device = _GD->CastD3D10().GetDevice(); D3D10_TEXTURE2D_DESC TextureDesc; TextureDesc.Width = Width; TextureDesc.Height = Height; TextureDesc.MipLevels = 0; if(!ConstructMipmaps) { TextureDesc.MipLevels = 1; } TextureDesc.ArraySize = 1; TextureDesc.Format = Format; TextureDesc.SampleDesc.Count = 1; TextureDesc.SampleDesc.Quality = 0; TextureDesc.Usage = D3D10_USAGE_DEFAULT; TextureDesc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET; TextureDesc.CPUAccessFlags = 0; TextureDesc.MiscFlags = D3D10_RESOURCE_MISC_GENERATE_MIPS; D3D10_SUBRESOURCE_DATA Data[12]; for(UINT Index = 0; Index < 12; Index++) { Data[Index].pSysMem = &(Bmp[0][0]); Data[Index].SysMemPitch = Bmp.Width() * sizeof(RGBColor); } HRESULT hr = Device->CreateTexture2D(&TextureDesc, Data, &_Texture); PersistentAssert(SUCCEEDED(hr), "CreateTexture2D failed"); _Texture->GetDesc(&TextureDesc); D3D10_SHADER_RESOURCE_VIEW_DESC ViewDesc; ViewDesc.Format = Format; ViewDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; ViewDesc.Texture2D.MostDetailedMip = 0; ViewDesc.Texture2D.MipLevels = TextureDesc.MipLevels; hr = Device->CreateShaderResourceView(_Texture, &ViewDesc, &_View); PersistentAssert(SUCCEEDED(hr), "CreateShaderResourceView failed"); Device->GenerateMips(_View); }
Texture2D::Texture2D(Texture2D_Desc& desc, Renderer* pRender) { HRESULT hr; ID3D10Device* pDevice = pRender->GetDevice(); V(pDevice->CreateTexture2D( &desc, //[in] const D3D10_TEXTURE2D_DESC *pDesc, NULL, //[in] const D3D10_SUBRESOURCE_DATA *pInitialData, &_ptr //[out] ID3D10Texture2D **ppTexture2D )); if (SUCCEEDED(hr)) { _width = (float)desc.Width; _height = (float)desc.Height; _invW = 1.0f / _width; _invH = 1.0f / _height; D3D10_SHADER_RESOURCE_VIEW_DESC resourceViewDesc; resourceViewDesc.Format = desc.Format; resourceViewDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; resourceViewDesc.Texture2D.MostDetailedMip = 0; resourceViewDesc.Texture2D.MipLevels = desc.MipLevels; ID3D10ShaderResourceView* pResourceView; V(pDevice->CreateShaderResourceView( (ID3D10Resource *)_ptr, //[in] ID3D10Resource *pResource, &resourceViewDesc, //[in] const D3D10_SHADER_RESOURCE_VIEW_DESC *pDesc, &pResourceView //[out] ID3D10ShaderResourceView **ppSRView )); if (SUCCEEDED(hr)) { _ResourceView = pResourceView; } } else { _ptr = NULL; _width = 0; _height = 0; _invW = 0; _invH = 0; } }
bool CGutFontUniCodeDX10::CreateTexture(int w, int h) { m_iTextureW = w; m_iTextureH = h; ID3D10Device *pDevice = GutGetGraphicsDeviceDX10(); // { D3D10_TEXTURE2D_DESC desc; ZeroMemory( &desc, sizeof(desc) ); desc.Width = w; desc.Height = h; desc.MipLevels = 1; desc.ArraySize = 1; desc.SampleDesc.Count = 1; desc.Format = DXGI_FORMAT_A8_UNORM; desc.Usage = D3D10_USAGE_DEFAULT; desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; pDevice->CreateTexture2D( &desc, NULL, &m_pFontTexture2D ); } // { D3D10_SHADER_RESOURCE_VIEW_DESC desc; ZeroMemory(&desc, sizeof(desc)); desc.Format = DXGI_FORMAT_A8_UNORM; desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; desc.Texture2D.MostDetailedMip = 0; desc.Texture2D.MipLevels = 1; pDevice->CreateShaderResourceView(m_pFontTexture2D, &desc, &m_pFontTexture); } return true; }
// Detour function that replaces the IDXGISwapChain::Present() API DllExport HRESULT __stdcall hook_DXGISwapChainPresent( IDXGISwapChain * This, UINT SyncInterval, UINT Flags ) { static int frame_interval; static LARGE_INTEGER initialTv, captureTv, freq; static int capture_initialized = 0; // int i; struct pooldata *data; struct vsource_frame *frame; // DXGI_SWAP_CHAIN_DESC pDESC; HRESULT hr = pDXGISwapChainPresent(This, SyncInterval, Flags); if(resolution_retrieved == 0) { if(DXGI_get_resolution(This) >= 0) { resolution_retrieved = 1; } return hr; } if(vsource_initialized == 0) { ga_error("video source not initialized.\n"); return hr; } This->GetDesc(&pDESC); pDXGI_FORMAT = pDESC.BufferDesc.Format; // extract screen format for sws_scale if(pDESC.BufferDesc.Width != game_width || pDESC.BufferDesc.Height != game_height) { ga_error("game width/height mismatched (%dx%d) != (%dx%d)\n", pDESC.BufferDesc.Width, pDESC.BufferDesc.Height, game_width, game_height); return hr; } // if (enable_server_rate_control && ga_hook_video_rate_control() < 0) return hr; if (dx_version == dx_none) { //bool check_result = FALSE; if (check_dx_device_version(This, IID_ID3D10Device)) { dx_version = dx_10; ga_error("[DXGISwapChain] DirectX 10\n"); } else if (check_dx_device_version(This, IID_ID3D10Device1)) { dx_version = dx_10_1; ga_error("[DXGISwapChain] DirectX 10.1\n"); } else if (check_dx_device_version(This, IID_ID3D11Device)) { dx_version = dx_11; ga_error("[DXGISwapChain] DirectX 11\n"); } } if (capture_initialized == 0) { frame_interval = 1000000/video_fps; // in the unif of us frame_interval++; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&initialTv); capture_initialized = 1; } else { QueryPerformanceCounter(&captureTv); } hr = 0; // d3d10 / d3d10.1 if (dx_version == dx_10 || dx_version == dx_10_1) { void *ppDevice; ID3D10Device *pDevice; //IUnknown *pDevice; if (dx_version == dx_10) { This->GetDevice(IID_ID3D10Device, &ppDevice); pDevice = (ID3D10Device *)ppDevice; } else if (dx_version == dx_10_1) { This->GetDevice(IID_ID3D10Device1, &ppDevice); pDevice = (ID3D10Device1 *)ppDevice; } else { OutputDebugString("Invalid DirectX version in IDXGISwapChain::Present"); return hr; } ID3D10RenderTargetView *pRTV = NULL; ID3D10Resource *pSrcResource = NULL; pDevice->OMGetRenderTargets(1, &pRTV, NULL); pRTV->GetResource(&pSrcResource); ID3D10Texture2D* pSrcBuffer = (ID3D10Texture2D *)pSrcResource; ID3D10Texture2D* pDstBuffer = NULL; D3D10_TEXTURE2D_DESC desc; pSrcBuffer->GetDesc(&desc); desc.BindFlags = 0; desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ; desc.Usage = D3D10_USAGE_STAGING; hr = pDevice->CreateTexture2D(&desc, NULL, &pDstBuffer); if (FAILED(hr)) { OutputDebugString("Failed to create texture2D"); //assert(exp_state == exp_none); } pDevice->CopyResource(pDstBuffer, pSrcBuffer); D3D10_MAPPED_TEXTURE2D mapped_screen; hr = pDstBuffer->Map(0, D3D10_MAP_READ, 0, &mapped_screen); if (FAILED(hr)) { OutputDebugString("Failed to map from DstBuffer"); //assert(exp_state == exp_none); } // copy image do { unsigned char *src, *dst; data = g_pipe[0]->allocate_data(); frame = (struct vsource_frame*) data->ptr; frame->pixelformat = PIX_FMT_BGRA; frame->realwidth = desc.Width; frame->realheight = desc.Height; frame->realstride = desc.Width<<2; frame->realsize = frame->realwidth * frame->realstride; frame->linesize[0] = frame->realstride;//frame->stride; // src = (unsigned char*) mapped_screen.pData; dst = (unsigned char*) frame->imgbuf; for (i = 0; i < encoder_height; i++) { CopyMemory(dst, src, frame->realstride/*frame->stride*/); src += mapped_screen.RowPitch; dst += frame->realstride;//frame->stride; } frame->imgpts = pcdiff_us(captureTv, initialTv, freq)/frame_interval; } while(0); // duplicate from channel 0 to other channels for(i = 1; i < SOURCES; i++) { int j; struct pooldata *dupdata; struct vsource_frame *dupframe; dupdata = g_pipe[i]->allocate_data(); dupframe = (struct vsource_frame*) dupdata->ptr; // vsource_dup_frame(frame, dupframe); // g_pipe[i]->store_data(dupdata); g_pipe[i]->notify_all(); } g_pipe[0]->store_data(data); g_pipe[0]->notify_all(); pDstBuffer->Unmap(0); pDevice->Release(); pSrcResource->Release(); pSrcBuffer->Release(); pRTV->Release(); pDstBuffer->Release(); // d11 } else if (dx_version == dx_11) { void *ppDevice; This->GetDevice(IID_ID3D11Device, &ppDevice); ID3D11Device *pDevice = (ID3D11Device*) ppDevice; This->GetDevice(IID_ID3D11DeviceContext, &ppDevice); ID3D11DeviceContext *pDeviceContext = (ID3D11DeviceContext *) ppDevice; ID3D11RenderTargetView *pRTV = NULL; ID3D11Resource *pSrcResource = NULL; pDeviceContext->OMGetRenderTargets(1, &pRTV, NULL); pRTV->GetResource(&pSrcResource); ID3D11Texture2D *pSrcBuffer = (ID3D11Texture2D *)pSrcResource; ID3D11Texture2D *pDstBuffer = NULL; D3D11_TEXTURE2D_DESC desc; pSrcBuffer->GetDesc(&desc); desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.Usage = D3D11_USAGE_STAGING; hr = pDevice->CreateTexture2D(&desc, NULL, &pDstBuffer); if (FAILED(hr)) { OutputDebugString("Failed to create buffer"); //assert(exp_state == exp_none); } pDeviceContext->CopyResource(pDstBuffer, pSrcBuffer); D3D11_MAPPED_SUBRESOURCE mapped_screen; hr = pDeviceContext->Map(pDstBuffer, 0, D3D11_MAP_READ, 0, &mapped_screen); if (FAILED(hr)) { OutputDebugString("Failed to map from DeviceContext"); //assert(exp_state == exp_none); } // copy image do { unsigned char *src, *dst; data = g_pipe[0]->allocate_data(); frame = (struct vsource_frame*) data->ptr; frame->pixelformat = PIX_FMT_BGRA; frame->realwidth = desc.Width; frame->realheight = desc.Height; frame->realstride = desc.Width<<2; frame->realsize = frame->realwidth * frame->realstride; frame->linesize[0] = frame->realstride;//frame->stride; // src = (unsigned char*) mapped_screen.pData; dst = (unsigned char*) frame->imgbuf; for (i = 0; i < encoder_height; i++) { CopyMemory(dst, src, frame->realstride/*frame->stride*/); src += mapped_screen.RowPitch; dst += frame->realstride;//frame->stride; } frame->imgpts = pcdiff_us(captureTv, initialTv, freq)/frame_interval; } while(0); // duplicate from channel 0 to other channels for(i = 1; i < SOURCES; i++) { int j; struct pooldata *dupdata; struct vsource_frame *dupframe; dupdata = g_pipe[i]->allocate_data(); dupframe = (struct vsource_frame*) dupdata->ptr; // vsource_dup_frame(frame, dupframe); // g_pipe[i]->store_data(dupdata); g_pipe[i]->notify_all(); } g_pipe[0]->store_data(data); g_pipe[0]->notify_all(); pDeviceContext->Unmap(pDstBuffer, 0); pDevice->Release(); pDeviceContext->Release(); pSrcResource->Release(); pSrcBuffer->Release(); pRTV->Release(); pDstBuffer->Release(); } return hr; }
void D3D10Grab(ID3D10Texture2D* pBackBuffer) { D3D10_TEXTURE2D_DESC tex_desc; pBackBuffer->GetDesc(&tex_desc); ID3D10Device *pDev; pBackBuffer->GetDevice(&pDev); ID3D10Texture2D * pTexture; D3D10_MAPPED_TEXTURE2D mappedTexture; tex_desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ; tex_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; tex_desc.ArraySize = 1; tex_desc.MipLevels = 1; tex_desc.BindFlags = 0; tex_desc.SampleDesc.Count = 1; tex_desc.SampleDesc.Quality = 0; tex_desc.Usage = D3D10_USAGE_STAGING; tex_desc.MiscFlags = 0; HRESULT hr = pDev->CreateTexture2D(&tex_desc, NULL, &pTexture); #ifdef DEBUG reportLog(EVENTLOG_INFORMATION_TYPE, L"pDev->CreateTexture2D 0x%x", hr); #endif pDev->CopyResource(pTexture, pBackBuffer); D3D10_BOX box = {0, 0, tex_desc.Width, tex_desc.Height, 0, 1}; pDev->CopySubresourceRegion(pTexture, 0, 0, 0, 0, pBackBuffer, 0, &box); DxgiFrameGrabber *dxgiFrameGrabber = DxgiFrameGrabber::getInstance(); IPCContext *ipcContext = dxgiFrameGrabber->m_ipcContext; Logger *logger = dxgiFrameGrabber->m_logger; if (S_OK != (hr = pTexture->Map(D3D10CalcSubresource(0, 0, 1), D3D10_MAP_READ, 0, &mappedTexture))) { logger->reportLogError(L"d3d10 couldn't map texture, hresult = 0x%x", hr); goto end; } ipcContext->m_memDesc.width = tex_desc.Width; ipcContext->m_memDesc.height = tex_desc.Height; ipcContext->m_memDesc.rowPitch = mappedTexture.RowPitch; ipcContext->m_memDesc.format = BufferFormatAbgr; ipcContext->m_memDesc.frameId++; // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d10 texture description. width: %u, height: %u, pitch: %u", tex_desc.Width, tex_desc.Height, mappedTexture.RowPitch); DWORD errorcode; if (WAIT_OBJECT_0 == (errorcode = WaitForSingleObject(ipcContext->m_hMutex, 0))) { // __asm__("int $3"); // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d10 writing description to mem mapped file"); memcpy(ipcContext->m_pMemMap, &ipcContext->m_memDesc, sizeof (ipcContext->m_memDesc)); // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d10 writing data to mem mapped file"); PVOID pMemDataMap = incPtr(ipcContext->m_pMemMap, sizeof (ipcContext->m_memDesc)); if (mappedTexture.RowPitch == tex_desc.Width * 4) { memcpy(pMemDataMap, mappedTexture.pData, tex_desc.Width * tex_desc.Height * 4); } else { UINT cleanOffset = 0, pitchOffset = 0, i = 0; while (i < tex_desc.Height) { memcpy(incPtr(pMemDataMap, cleanOffset), incPtr(mappedTexture.pData, pitchOffset), tex_desc.Width * 4); cleanOffset += tex_desc.Width * 4; pitchOffset += mappedTexture.RowPitch; i++; } } ReleaseMutex(ipcContext->m_hMutex); SetEvent(ipcContext->m_hFrameGrabbedEvent); } else { logger->reportLogError(L"d3d10 couldn't wait mutex. errocode = 0x%x", errorcode); } pTexture->Unmap(D3D10CalcSubresource(0, 0, 1)); end: pTexture->Release(); pDev->Release(); }