Texture *DX10Render::loadTextureFromFile(const wchar_t *file) { DX10Texture *result = new DX10Texture(); HRESULT hr = D3DX10CreateShaderResourceViewFromFile(device, file, NULL, NULL, &result->resourceView, NULL); if (FAILED(hr)) { switch (hr) { case D3D10_ERROR_FILE_NOT_FOUND: { //log() << "Texture file \"" << file << "\" does not exists" << std::endl; break; } default: { //log() << "Failed to load texture \"" << file << "\" does not exists" << std::endl; break; } } delete result; return NULL; } // Now when we have pointer to shader resource interface we can get pointer to texture itself ID3D10Resource *resource = NULL; result->resourceView->GetResource(&resource); resource->QueryInterface(__uuidof(ID3D10Texture2D), (void**)&result->texture); resource->Release(); return result; }
Texture3D* Texture3D::FromBuffer(Buffer& buf, Renderer* pRender) { ID3D10Resource* pResource = NULL; HRESULT hr = D3DX10CreateTextureFromMemory( pRender->GetDevice(), //[in] ID3D10Device *pDevice, buf.GetPtr(), //[in] LPCVOID pSrcData, buf.GetSize(), //[in] SIZE_T SrcDataSize, NULL, //[in] D3DX10_IMAGE_LOAD_INFO *pLoadInfo, NULL, //[in] ID3DX10ThreadPump *pPump, &pResource, //[out] ID3D10Resource **ppTexture, NULL //[out] HRESULT *pHResult ); if (SUCCEEDED(hr)) { ID3D10Texture3D* ptr = NULL; hr = pResource->QueryInterface(IID_ID3D10Texture3D, (LPVOID*)&ptr); pResource->Release(); if (SUCCEEDED(hr)) { Texture3D* pTexture3D = new Texture3D(ptr); return pTexture3D; } } return NULL; }
// Loads a texture from a file and creates the resource view Texture::Texture(std::wstring filename, bool srgb) { HRESULT hresult; ID3D10Device *d3d10_device = engine.GetDevice(); ID3D10Resource *resource; if ((hresult = DirectX::CreateDDSTextureFromFileEx(d3d10_device, filename.c_str(), 0, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, 0, 0, srgb, &resource, &resource_view)) != S_OK) throw Exception(L"DirectX::CreateDDSTextureFromFile failed: " + GetD3D10Error(hresult)); D3D10_RESOURCE_DIMENSION dim; resource->GetType(&dim); if (dim != D3D10_RESOURCE_DIMENSION_TEXTURE2D) throw Exception(L"Texture: Only 2D textures are supported currently"); if ((hresult = resource->QueryInterface(__uuidof(ID3D10Texture2D), (LPVOID*)&texture)) != S_OK) throw Exception(L"Texture: QueryInterface failed: " + GetD3D10Error(hresult)); D3D10_TEXTURE2D_DESC desc; texture->GetDesc(&desc); width = desc.Width; height = desc.Height; SafeRelease(resource); }
Texture1D* Texture1D::FromFile(LPCTSTR pFileName, Renderer* pRender) { ID3D10Resource* pResource = NULL; HRESULT hr = D3DX10CreateTextureFromFile( pRender->GetDevice(), //[in] ID3D10Device *pDevice, pFileName, //[in] LPCTSTR pSrcFile, NULL, //[in] D3DX10_IMAGE_LOAD_INFO *pLoadInfo, NULL, //[in] ID3DX10ThreadPump *pPump, &pResource, //[out] ID3D10Resource **ppTexture, NULL //[out] HRESULT *pHResult ); if (SUCCEEDED(hr)) { ID3D10Texture1D* ptr = NULL; hr = pResource->QueryInterface(IID_ID3D10Texture1D, (LPVOID*)&ptr); pResource->Release(); if (SUCCEEDED(hr)) { Texture1D* pTexture1D = new Texture1D(ptr); return pTexture1D; } } return NULL; }
BOOL DXMessD3D10Handler::UpdateTextures() { //call this each time the resolution changes (when the buffer changes) HRESULT hr; ID3D10Resource *test; ID3D10Texture2D *texturex; DXGI_SWAP_CHAIN_DESC desc; int i; int newTextureCount; WaitForSingleObject((HANDLE)(shared->TextureLock), INFINITE); if (shared->textureCount) { ZeroMemory(&desc, sizeof(desc)); hr=swapchain->GetDesc(&desc); if (FAILED(hr)) return hr; newTextureCount=shared->textureCount; if (shared->textureCount > TextureCount) { //update the textures if needed if (textures==NULL) //initial alloc textures=(TextureData10 *)malloc(sizeof(TextureData10)* shared->textureCount); else //realloc textures=(TextureData10 *)realloc(textures, sizeof(TextureData10)* shared->textureCount); //initialize the new entries to NULL for (i=TextureCount; i<shared->textureCount; i++) { textures[i].pTexture=NULL; textures[i].DefinedFontMap=NULL; } } for (i=0; i<newTextureCount; i++) { if (tea[i].AddressOfTexture) { if ((tea[i].hasBeenUpdated) || (textures[i].pTexture==NULL)) { if (textures[i].pTexture) { //already has a texture, so an update. Free the old one first textures[i].pTexture->Release(); textures[i].pTexture=NULL; //should always happen } if (textures[i].DefinedFontMap) { //already has a fontmap. Free the old one free(textures[i].DefinedFontMap); textures[i].DefinedFontMap=NULL; } hr=D3DX10CreateTextureFromMemory(dev, (void *)(tea[i].AddressOfTexture), tea[i].size, NULL, NULL, &test, NULL); if( FAILED( hr ) ) { OutputDebugStringA("Failure creating a texture"); return hr; } hr=test->QueryInterface(__uuidof(ID3D10Texture2D), (void **)(&texturex)); hr=dev->CreateShaderResourceView(test, NULL, &textures[i].pTexture); if( FAILED( hr ) ) return hr; test->Release(); texturex->Release(); if (tea[i].AddressOfFontmap) { int j; float currentOffset=0; textures[i].DefinedFontMap=(PFONTMAP)malloc(sizeof(FONTMAP)); //now parse the fontmap provided by ce and fill in the gaps WORD *cefontmap=(WORD *)(tea[i].AddressOfFontmap); textures[i].DefinedFontMap->charheight=(float)cefontmap[0]; for (j=0; j<96; j++) { textures[i].DefinedFontMap->charinfo[j].offset=currentOffset; textures[i].DefinedFontMap->charinfo[j].charwidth=(float)cefontmap[j+1]; currentOffset+=cefontmap[j+1]; } textures[i].DefinedFontMap->fullwidth=currentOffset; } tea[i].hasBeenUpdated=0; } } else { //It's NULL (cleanup) if (textures[i].pTexture) { textures[i].pTexture->Release(); textures[i].pTexture=NULL; } if (textures[i].DefinedFontMap) { free(textures[i].DefinedFontMap); textures[i].DefinedFontMap=NULL; } } } TextureCount=newTextureCount; } if (shared->texturelistHasUpdate) InterlockedExchange((volatile LONG *)&shared->texturelistHasUpdate,0); SetEvent((HANDLE)(shared->TextureLock)); return TRUE; }
Texture* D3D10Texture::CreateFromSharedHandle(unsigned int width, unsigned int height, HANDLE handle) { HRESULT err; if(!handle) { AppWarning(TEXT("D3D10Texture::CreateFromSharedHandle: NULL handle value.")); return NULL; } ID3D10Resource *tempResource; if(FAILED(err = GetD3D()->OpenSharedResource(handle, __uuidof(ID3D10Resource), (void**)&tempResource))) { AppWarning(TEXT("D3D10Texture::CreateFromSharedHandle: Failed to open shared handle, result = 0x%08lX"), err); return NULL; } ID3D10Texture2D *texVal; if(FAILED(err = tempResource->QueryInterface(__uuidof(ID3D10Texture2D), (void**)&texVal))) { SafeRelease(tempResource); AppWarning(TEXT("D3D10Texture::CreateFromSharedHandle: could not query interface, result = 0x%08lX"), err); return NULL; } tempResource->Release(); //------------------------------------------ D3D10_TEXTURE2D_DESC td; texVal->GetDesc(&td); //------------------------------------------ D3D10_SHADER_RESOURCE_VIEW_DESC resourceDesc; zero(&resourceDesc, sizeof(resourceDesc)); resourceDesc.Format = td.Format; //resourceDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; resourceDesc.Texture2D.MipLevels = 1; //resourceDesc.ViewDimension = D3D10_1_SRV_DIMENSION_TEXTURE2D; resourceDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D; ID3D10ShaderResourceView *resource = NULL; if(FAILED(err = GetD3D()->CreateShaderResourceView(texVal, &resourceDesc, &resource))) { SafeRelease(texVal); AppWarning(TEXT("D3D10Texture::CreateFromSharedHandle: CreateShaderResourceView failed, result = 0x%08lX"), err); return NULL; } //------------------------------------------ D3D10Texture *newTex = new D3D10Texture; newTex->format = GetGSFormatFromDXGIFormat(td.Format);; newTex->resource = resource; newTex->texture = texVal; newTex->bDynamic = false; newTex->width = width; newTex->height = height; return newTex; }
Texture* D3D10Texture::CreateFromFile(CTSTR lpFile, BOOL bBuildMipMaps) { HRESULT err; D3DX10_IMAGE_INFO ii; if(FAILED(D3DX10GetImageInfoFromFile(lpFile, NULL, &ii, NULL))) { AppWarning(TEXT("D3D10Texture::CreateFromFile: Could not get information about texture file '%s'"), lpFile); return NULL; } //------------------------------------------ if(bBuildMipMaps && (!IsPow2(ii.Width) || !IsPow2(ii.Height))) bBuildMipMaps = FALSE; D3DX10_IMAGE_LOAD_INFO ili; ili.Width = D3DX10_DEFAULT; ili.Height = D3DX10_DEFAULT; ili.Depth = D3DX10_DEFAULT; ili.FirstMipLevel = D3DX10_DEFAULT; ili.MipLevels = bBuildMipMaps ? 0 : 1; ili.Usage = (D3D10_USAGE)D3DX10_DEFAULT; ili.BindFlags = D3DX10_DEFAULT; ili.CpuAccessFlags = D3DX10_DEFAULT; ili.MiscFlags = D3DX10_DEFAULT; ili.Format = (DXGI_FORMAT)D3DX10_DEFAULT; ili.Filter = D3DX10_DEFAULT; ili.MipFilter = D3DX10_DEFAULT; ili.pSrcInfo = NULL; ID3D10Resource *texResource; if(FAILED(err = D3DX10CreateTextureFromFile(GetD3D(), lpFile, &ili, NULL, &texResource, NULL))) { AppWarning(TEXT("D3D10Texture::CreateFromFile: failed to load '%s'"), lpFile); return NULL; } //------------------------------------------ D3D10_SHADER_RESOURCE_VIEW_DESC resourceDesc; zero(&resourceDesc, sizeof(resourceDesc)); resourceDesc.Format = ii.Format; resourceDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; resourceDesc.Texture2D.MipLevels = bBuildMipMaps ? -1 : 1; ID3D10ShaderResourceView *resource; if(FAILED(err = GetD3D()->CreateShaderResourceView(texResource, &resourceDesc, &resource))) { SafeRelease(texResource); AppWarning(TEXT("D3D10Texture::CreateFromFile: CreateShaderResourceView failed, result = 0x%08lX"), err); return NULL; } //------------------------------------------ ID3D10Texture2D *tex2D; err = texResource->QueryInterface(__uuidof(ID3D10Texture2D), (void**)&tex2D); if(FAILED(err)) { SafeRelease(texResource); SafeRelease(resource); AppWarning(TEXT("D3D10Texture::CreateFromFile: could not query texture interface")); return NULL; } texResource->Release(); //------------------------------------------ D3D10Texture *newTex = new D3D10Texture; newTex->resource = resource; newTex->texture = tex2D; newTex->width = ii.Width; newTex->height = ii.Height; switch(ii.Format) { case DXGI_FORMAT_R8_UNORM: newTex->format = GS_ALPHA; break; case DXGI_FORMAT_A8_UNORM: newTex->format = GS_GRAYSCALE; break; case DXGI_FORMAT_B8G8R8X8_UNORM: newTex->format = GS_BGR; break; case DXGI_FORMAT_B8G8R8A8_UNORM: newTex->format = GS_BGRA; break; case DXGI_FORMAT_R8G8B8A8_UNORM: newTex->format = GS_RGBA; break; case DXGI_FORMAT_R16G16B16A16_FLOAT: newTex->format = GS_RGBA16F; break; case DXGI_FORMAT_R32G32B32A32_FLOAT: newTex->format = GS_RGBA32F; break; case DXGI_FORMAT_BC1_UNORM: newTex->format = GS_DXT1; break; case DXGI_FORMAT_BC2_UNORM: newTex->format = GS_DXT3; break; case DXGI_FORMAT_BC3_UNORM: newTex->format = GS_DXT5; break; default: newTex->format = GS_UNKNOWNFORMAT; } return newTex; }
Texture* D3D10Texture::CreateFromSharedHandle(unsigned int width, unsigned int height, GSColorFormat colorFormat, HANDLE handle) { HRESULT err; if(colorFormat >= GS_DXT1) { AppWarning(TEXT("D3D10Texture::CreateFromSharedHandle: tried to a blank DXT shared texture.")); return NULL; } if(!handle) { AppWarning(TEXT("D3D10Texture::CreateFromSharedHandle: NULL handle value.")); return NULL; } ID3D10Resource *tempResource; if(FAILED(err = GetD3D()->OpenSharedResource(handle, __uuidof(ID3D10Resource), (void**)&tempResource))) { AppWarning(TEXT("D3D10Texture::CreateFromSharedHandle: Failed to open shared handle, result = 0x%08lX"), err); return NULL; } ID3D10Texture2D *texVal; if(FAILED(err = tempResource->QueryInterface(__uuidof(ID3D10Texture2D), (void**)&texVal))) { SafeRelease(tempResource); AppWarning(TEXT("D3D10Texture::CreateFromSharedHandle: could not query interface, result = 0x%08lX"), err); return NULL; } tempResource->Release(); //------------------------------------------ IDXGIKeyedMutex *km; if(FAILED(err = texVal->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&km))) { //SafeRelease(texVal); AppWarning(TEXT("D3D10Texture::CreateFromSharedHandle: could not query keyed mutex interface, result = 0x%08lX"), err); //return NULL; } //------------------------------------------ DXGI_FORMAT format = convertFormat[(UINT)colorFormat]; D3D10_SHADER_RESOURCE_VIEW_DESC resourceDesc; zero(&resourceDesc, sizeof(resourceDesc)); resourceDesc.Format = format; resourceDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; resourceDesc.Texture2D.MipLevels = 1; ID3D10ShaderResourceView *resource; if(FAILED(err = GetD3D()->CreateShaderResourceView(texVal, &resourceDesc, &resource))) { SafeRelease(texVal); AppWarning(TEXT("D3D10Texture::CreateFromSharedHandle: CreateShaderResourceView failed, result = 0x%08lX"), err); return NULL; } //------------------------------------------ D3D10Texture *newTex = new D3D10Texture; newTex->format = colorFormat; newTex->resource = resource; newTex->texture = texVal; newTex->keyedMutex = km; newTex->bDynamic = false; newTex->width = width; newTex->height = height; return newTex; }
void IDXGISwapChainNew::preUpdateBB(UINT *width, UINT *height) { dbg("dxgi_sc: preUpdateBB"); int rrx = config.main.renderResolution.x; int rry = config.main.renderResolution.y; if(*width == rrx && *height == rry) { dbg("dxgi_sc: Multihead swapchain mode detected"); HEAD *h = config.getPrimaryHead(); *width = h->screenMode.x; *height = h->screenMode.y; // Set mouse hook on application focus window ihGlobal.setHWND(win); SoftTHActive++; h->hwnd = win; // Create new backbuffer dbg("dxgi_sc: Creating new backbuffer"); // TODO: format #if defined(SOFTTHMAIN) || defined(D3D11) if(dev11) { // Create the full backbuffer render texture dbg("dxgi_sc: Creating FULL backbuffer for D3D11 Device"); //CD3D10_TEXTURE2D_DESC d(DXGI_FORMAT_R8G8B8A8_UNORM, rrx, rry, 1, 1, D3D10_BIND_RENDER_TARGET, D3D10_USAGE_DEFAULT, NULL); CD3D11_TEXTURE2D_DESC d(DXGI_FORMAT_R8G8B8A8_UNORM, rrx, rry, 1, 1, D3D11_BIND_RENDER_TARGET, D3D11_USAGE_DEFAULT, NULL); newbbDesc11 = d; if(dev11->CreateTexture2D(&newbbDesc11, NULL, &newbb11) != S_OK) dbg("dxgi_sc: CreateTexture2D failed :("), exit(0); // Initialize outputs numDevs = config.getNumAdditionalHeads(); dbg("dxgi_sc: Initializing %d outputs", numDevs); int logoStopTime = GetTickCount() + 4000; bool fpuPreserve = true; // TODO: does this exist in d3d10? outDevs11 = new OUTDEVICE11[numDevs]; stagingOuts11 = new STAGINGOUT11[numDevs]; for(int i=0;i<numDevs;i++) { OUTDEVICE11 *o = &outDevs11[i]; STAGINGOUT11 *so = &stagingOuts11[i]; so->headID = i+1; so->devID = h->devID; so->stagingSurf = NULL; // Create the output device HEAD *h = config.getHead(i); dbg("dxgi_sc: Initializing Head %d (DevID: %d)",i+1,h->devID); o->output = new outDirect3D11(h->devID, h->screenMode.x, h->screenMode.y, h->transportRes.x, h->transportRes.y, win); o->cfg = h; bool local = h->transportMethod==OUTMETHOD_LOCAL; if (!local) has_nonlocal = true; dbg("dxgi_sc: Head %d is %s", i+1, local?"local":"non-local"); // Create a main staging buffer sized for this head if non-local if (!local) { dbg("dxgi_sc: Creating a main non-local staging buffer for Head %d (DevID %d)", i + 1, h->devID); CD3D11_TEXTURE2D_DESC dss(DXGI_FORMAT_R8G8B8A8_UNORM, h->transportRes.x, h->transportRes.y, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE, 1, 0, 0); /*DWORD32 *fillbuf = new DWORD32[h->transportRes.x*h->transportRes.y]; for (int ii = 0; ii < h->transportRes.y; ii++) for (int jj = 0; jj < h->transportRes.x; jj++) { if ((ii&32)==(jj&32)) fillbuf[ii*h->transportRes.x + jj] = (DWORD32) 0x0000ff00; else fillbuf[ii*h->transportRes.x + jj] = (DWORD32) 0xffffffff; } D3D11_SUBRESOURCE_DATA fillsr; ZeroMemory(&fillsr, sizeof(fillsr)); fillsr.pSysMem = (void *)fillbuf; fillsr.SysMemPitch = h->transportRes.x * 4; fillsr.SysMemSlicePitch = h->transportRes.x * h->transportRes.y * 4; if (dev11->CreateTexture2D(&dss, &fillsr, &so->stagingSurf) != S_OK) {*/ if (dev11->CreateTexture2D(&dss, NULL, &so->stagingSurf) != S_OK) { dbg("dxgi_sc: CreateTexture2D staged for Head %d (DevID %d) failed :(",i+1,h->devID), exit(0); } } // Create shared surfaces HANDLE sha = o->output->GetShareHandle(); if(sha) { o->localSurf = NULL; { // Open surfA share handle ID3D11Resource *tr; if (o->cfg->transportMethod == OUTMETHOD_LOCAL) { // Local output if (dev11->OpenSharedResource(sha, __uuidof(ID3D11Resource), (void**)(&tr)) != S_OK) dbg("dxgi_sc: Local OpenSharedResource A failed!"), exit(0); } else { // Non-local output if (o->output->dev->OpenSharedResource(sha, __uuidof(ID3D11Resource), (void**)(&tr)) != S_OK) dbg("dxgi_sc: Non-local OpenSharedResource A failed!"), exit(0); } if(tr->QueryInterface(__uuidof(ID3D11Texture2D), (void**)(&o->localSurf)) != S_OK) dbg("dxgi_sc: Shared surface QueryInterface failed!"), exit(0); tr->Release(); } dbg("dxgi_sc: Opened share handles"); } else dbg("dxgi_sc: ERROR: Head %d: No share handle!", i+1), exit(0); } // Create the full backbuffer staged texture if we have non-local head /*if (has_nonlocal) { CD3D11_TEXTURE2D_DESC ds(DXGI_FORMAT_R8G8B8A8_UNORM, rrx, rry, 1, 1, NULL, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ, 1, 0, D3D11_RESOURCE_MISC_SHARED); newbbDesc11staged = ds; if(dev11->CreateTexture2D(&newbbDesc11staged, NULL, &newbb11staged) != S_OK) dbg("dxgi_sc: CreateTexture2D staged failed :("), exit(0); }*/ } #endif #ifdef SOFTTHMAIN else #endif #if defined(SOFTTHMAIN) || defined(D3D10_1) if(dev10_1) { dbg("dxgi_sc: Creating backbuffer for D3D10.1 Device"); CD3D10_TEXTURE2D_DESC d(DXGI_FORMAT_R8G8B8A8_UNORM, rrx, rry, 1, 1, D3D10_BIND_RENDER_TARGET, D3D10_USAGE_DEFAULT, NULL); newbbDesc10 = d; if(dev10_1->CreateTexture2D(&newbbDesc10, NULL, &newbb10) != S_OK) dbg("dxgi_sc: CreateTexture2D failed :("), exit(0); // Initialize outputs numDevs = config.getNumAdditionalHeads(); dbg("dxgi_sc: Initializing %d outputs", numDevs); int logoStopTime = GetTickCount() + 4000; bool fpuPreserve = true; // TODO: does this exist in d3d10? outDevs10 = new OUTDEVICE10[numDevs]; for(int i=0;i<numDevs;i++) { OUTDEVICE10 *o = &outDevs10[i]; // Create the output device HEAD *h = config.getHead(i); bool local = h->transportMethod==OUTMETHOD_LOCAL; dbg("dxgi_sc: Initializing head %d (DevID: %d, %s)...", i+1, h->devID, local?"local":"non-local"); o->output = new outDirect3D10(h->devID, h->screenMode.x, h->screenMode.y, h->transportRes.x, h->transportRes.y, win); o->cfg = h; // Create shared surfaces HANDLE sha = o->output->GetShareHandle(); if(sha) { o->localSurf = NULL; { // Open surfA share handle ID3D10Resource *tr; if(dev10_1->OpenSharedResource(sha, __uuidof(ID3D10Resource), (void**)(&tr)) != S_OK) dbg("dxgi_sc: OpenSharedResource A failed!"), exit(0); if(tr->QueryInterface(__uuidof(ID3D10Texture2D), (void**)(&o->localSurf)) != S_OK) dbg("dxgi_sc: Shared surface QueryInterface failed!"), exit(0); tr->Release(); } dbg("dxgi_sc: Opened share handles"); } else dbg("dxgi_sc: ERROR: Head %d: No share handle!", i+1), exit(0); } } #endif #ifdef SOFTTHMAIN else #endif #if defined(SOFTTHMAIN) || defined(D3D10) if(dev10) { dbg("dxgi_sc: Creating backbuffer for D3D10 Device"); CD3D10_TEXTURE2D_DESC d(DXGI_FORMAT_R8G8B8A8_UNORM, rrx, rry, 1, 1, D3D10_BIND_RENDER_TARGET, D3D10_USAGE_DEFAULT, NULL); newbbDesc10 = d; if(dev10->CreateTexture2D(&newbbDesc10, NULL, &newbb10) != S_OK) dbg("dxgi_sc: CreateTexture2D failed :("), exit(0); // Initialize outputs numDevs = config.getNumAdditionalHeads(); dbg("dxgi_sc: Initializing %d outputs", numDevs); int logoStopTime = GetTickCount() + 4000; bool fpuPreserve = true; // TODO: does this exist in d3d10? outDevs10 = new OUTDEVICE10[numDevs]; for(int i=0;i<numDevs;i++) { OUTDEVICE10 *o = &outDevs10[i]; // Create the output device HEAD *h = config.getHead(i); bool local = h->transportMethod==OUTMETHOD_LOCAL; dbg("dxgi_sc: Initializing head %d (DevID: %d, %s)...", i+1, h->devID, local?"local":"non-local"); o->output = new outDirect3D10(h->devID, h->screenMode.x, h->screenMode.y, h->transportRes.x, h->transportRes.y, win); o->cfg = h; // Create shared surfaces HANDLE sha = o->output->GetShareHandle(); if(sha) { o->localSurf = NULL; { // Open surfA share handle ID3D10Resource *tr; if(dev10->OpenSharedResource(sha, __uuidof(ID3D10Resource), (void**)(&tr)) != S_OK) dbg("dxgi_sc: OpenSharedResource A failed!"), exit(0); if(tr->QueryInterface(__uuidof(ID3D10Texture2D), (void**)(&o->localSurf)) != S_OK) dbg("dxgi_sc: Shared surface QueryInterface failed!"), exit(0); tr->Release(); } dbg("dxgi_sc: Opened share handles"); } else dbg("dxgi_sc: ERROR: Head %d: No share handle!", i+1), exit(0); } } #endif } else { dbg("dxgi_sc: Singlehead swapchain mode"); SoftTHActive--; if(dev11) { if(newbb11) SAFE_RELEASE_LAST(newbb11); newbb11 = NULL; } else if(dev10 || dev10_1) { if(newbb10) SAFE_RELEASE_LAST(newbb10); newbb10 = NULL; } } }
void D3D9Hook::gdiCreateSceneObjects() { if(m_sceneObjectsCreated) return; // Already created if(!isCapturable()) return; // Not capturable // Is the back buffer format compatible with DXGI? if(d3d9ToGdiCompatible(m_bbD3D9Format) == DXGI_FORMAT_UNKNOWN) { HookLog2(InterprocessLog::Warning, "Back buffer not compatible with DXGI, falling back to CPU capture"); m_useCpuCopy = true; return; } // Create a dummy DirectX 10 or 10.1 device depending on the system ID3D10Device *m_dx10Device = HookMain::s_instance->refDummyDX10Device(); if(m_dx10Device == NULL) { HookLog2(InterprocessLog::Warning, "Failed to create DirectX 10 device, falling back to CPU capture"); m_useCpuCopy = true; return; } HookLog(stringf("Creating D3D9 scene objects for window of size %d x %d", m_width, m_height)); // Create D3D9 render target surface HRESULT res = m_device->CreateRenderTarget( m_width, m_height, m_bbD3D9Format, D3DMULTISAMPLE_NONE, 0, TRUE, &m_rtSurface, NULL); if(FAILED(res)) { HookLog2(InterprocessLog::Warning, stringf( "Failed to create shared D3D9 render target. Reason = %s", getD3D9ErrorCode(res).data())); goto gdiCreateSceneObjectsFailed1; } // Create shared DX10 textures D3D10_TEXTURE2D_DESC desc; desc.Width = m_width; desc.Height = m_height; desc.MipLevels = 1; desc.ArraySize = 1; desc.Format = d3d9ToGdiCompatible(m_bbD3D9Format); desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D10_USAGE_DEFAULT; desc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET; desc.CPUAccessFlags = 0; desc.MiscFlags = D3D10_RESOURCE_MISC_SHARED | D3D10_RESOURCE_MISC_GDI_COMPATIBLE; for(int i = 0; i < NUM_SHARED_TEXTURES; i++) { res = m_dx10Device->CreateTexture2D(&desc, NULL, &m_dx10Texs[i]); if(FAILED(res)) { HookLog2(InterprocessLog::Warning, stringf( "Failed to create shared DX10 target. Reason = %s", getDX10ErrorCode(res).data())); goto gdiCreateSceneObjectsFailed1; } } m_nextDx10Tex = 0; // Get DXGI shared handles from the textures for(int i = 0; i < NUM_SHARED_TEXTURES; i++) { IDXGIResource *dxgiRes = NULL; res = m_dx10Texs[i]->QueryInterface( __uuidof(IDXGIResource), (void **)&dxgiRes); if(FAILED(res)) { HookLog2(InterprocessLog::Warning, stringf( "Failed to get DXGI resource. Reason = %s", getDX10ErrorCode(res).data())); goto gdiCreateSceneObjectsFailed1; } m_dx10TexHandles[i] = NULL; res = dxgiRes->GetSharedHandle(&m_dx10TexHandles[i]); dxgiRes->Release(); if(FAILED(res)) { HookLog2(InterprocessLog::Warning, stringf( "Failed to get DXGI shared handle. Reason = %s", getDX10ErrorCode(res).data())); goto gdiCreateSceneObjectsFailed1; } } #if 0 // Create D3D9 render target surface HRESULT res = m_device->CreateRenderTarget( m_width, m_height, m_bbD3D9Format, D3DMULTISAMPLE_NONE, 0, FALSE, &m_rtSurface, NULL); if(FAILED(res)) { HookLog2(InterprocessLog::Warning, stringf( "Failed to create shared D3D9 render target. Reason = %s", getD3D9ErrorCode(res).data())); return; // TODO: Not safe to return here } // Create shared D3D9 texture HANDLE sharedHandle = NULL; res = m_device->CreateTexture( m_width, m_height, 1, D3DUSAGE_RENDERTARGET, m_bbD3D9Format, D3DPOOL_DEFAULT, &m_dx9Tex, &sharedHandle); if(FAILED(res)) { HookLog2(InterprocessLog::Warning, stringf( "Failed to create D3D9 texture. Reason = %s", getD3D9ErrorCode(res).data())); return; // TODO: Not safe to return here } // Open shared surface as a DX10 texture ID3D10Resource *resource = NULL; res = m_dx10Device->OpenSharedResource( sharedHandle, __uuidof(ID3D10Resource), (void **)(&resource)); if(FAILED(res)) { HookLog2(InterprocessLog::Warning, stringf( "Failed to open D3D9 surface as a DX10 resource. Reason = %s", getDX10ErrorCode(res).data())); return; // TODO: Not safe to return here } res = resource->QueryInterface( __uuidof(ID3D10Texture2D), (void **)(&m_dx10Tex)); if(FAILED(res)) { HookLog2(InterprocessLog::Warning, stringf( "Failed to query DX10 texture interface. Reason = %s", getDX10ErrorCode(res).data())); return; // TODO: Not safe to return here } resource->Release(); #endif // 0 #if 0 // Create shared DX10 texture D3D10_TEXTURE2D_DESC desc; desc.Width = m_width; desc.Height = m_height; desc.MipLevels = 1; desc.ArraySize = 1; desc.Format = d3d9ToDxgiFormat(m_bbD3D9Format); desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D10_USAGE_DEFAULT; desc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET; desc.CPUAccessFlags = 0; desc.MiscFlags = D3D10_RESOURCE_MISC_SHARED; HRESULT res = m_dx10Device->CreateTexture2D(&desc, NULL, &m_dx10Tex); if(FAILED(res)) { HookLog2(InterprocessLog::Warning, stringf( "Failed to create DX10 target. Reason = %s", getDX10ErrorCode(res).data())); // TODO: Don't continue } // Get DXGI shared handle from the texture IDXGIResource *dxgiRes = NULL; res = m_dx10Tex->QueryInterface( __uuidof(IDXGIResource), (void **)&dxgiRes); if(FAILED(res)) { HookLog2(InterprocessLog::Warning, stringf( "Failed to get DXGI resource. Reason = %s", getDX10ErrorCode(res).data())); // TODO: Don't continue } HANDLE sharedHandle = NULL; res = dxgiRes->GetSharedHandle(&sharedHandle); if(FAILED(res)) { HookLog2(InterprocessLog::Warning, stringf( "Failed to get DXGI shared handle. Reason = %s", getDX10ErrorCode(res).data())); // TODO: Don't continue } dxgiRes->Release(); // Create D3D9 render target surface from the shared handle res = m_device->CreateRenderTarget( m_width, m_height, m_bbD3D9Format, D3DMULTISAMPLE_NONE, 0, TRUE, &m_rtSurface, &sharedHandle); if(FAILED(res)) { HookLog2(InterprocessLog::Warning, stringf( "Failed to create shared D3D9 render target. Reason = %s", getD3D9ErrorCode(res).data())); // TODO: Don't continue } #endif // 0 m_sceneObjectsCreated = true; return; // Error handling gdiCreateSceneObjectsFailed1: // Return everything to the same state as when we started if(m_rtSurface != NULL) m_rtSurface->Release(); for(int i = 0; i < NUM_SHARED_TEXTURES; i++) { m_dx10TexHandles[i] = NULL; if(m_dx10Texs[i] != NULL) { m_dx10Texs[i]->Release(); m_dx10Texs[i] = NULL; } } }