Пример #1
0
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;
}
Пример #2
0
	// 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);
	}
		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;
		}
Пример #4
0
//----------------------------------------------------------------------------//
void Direct3D10Texture::initialiseShaderResourceView()
{
    if (!d_texture)
        return;

    D3D10_TEXTURE2D_DESC tex_desc;
    d_texture->GetDesc(&tex_desc);

    ID3D10Resource* resource = 0;
    d_texture->QueryInterface(__uuidof(ID3D10Resource),
                              reinterpret_cast<LPVOID*>(&resource));

    D3D10_SHADER_RESOURCE_VIEW_DESC srvd;
    srvd.Format = tex_desc.Format;
    srvd.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
    srvd.Texture2D.MostDetailedMip = 0;
    srvd.Texture2D.MipLevels = tex_desc.MipLevels;
    d_device.CreateShaderResourceView(resource, &srvd, &d_resourceView);
    resource->Release();
}
Пример #5
0
TextureID Texture_Create( const char* filename )
{
	unsigned handle = 0;

	// Create from the free list if we can
	if( Texture_freelist_count > 0 )
	{
		handle = Texture_freelist[ Texture_freelist_count - 1 ];
		Texture_freelist_count--;
	}
	else // And only expand the range if free list is empty
	{
		assert( Texture_Count < MAX_TEXTURES );
		handle = Texture_Count;
		Texture_Count++;
	}

	//load the texture

	Texture* Texture = &Textures[ handle ];
	 
	HRESULT load_texture = D3DX10CreateShaderResourceViewFromFile( dx_device, filename, NULL, NULL, &Texture->texture, NULL );
	assert( SUCCEEDED( load_texture ) );

	ID3D10Resource* res;
	Texture->texture->GetResource( &res ); 
	D3D10_TEXTURE2D_DESC desc2D;
    ((ID3D10Texture2D*)res)->GetDesc(&desc2D);

	/*Texture->transform.position[0] = x / GAME_RESOLUTION_X;
	Texture->transform.position[1] = y / GAME_RESOLUTION_Y;
	Texture->transform.position[2] = 0;
	Texture->transform.scale[0] = (float)(desc2D.Width/(float)GAME_RESOLUTION_X);
	Texture->transform.scale[1] = (float)(desc2D.Height/(float)GAME_RESOLUTION_Y);
	Texture->transform.rotation = 180;*/

	res->Release();

	return handle;
}
Пример #6
0
HRESULT CSurfaceQueueDeviceD3D10::CopySurface(IUnknown* pDst, IUnknown* pSrc, UINT width, UINT height)
{
    HRESULT hr;
    
    D3D10_BOX UnitBox = {0, 0, 0, width, height, 1};
    
    ID3D10Resource* pSrcRes = NULL;
    ID3D10Resource* pDstRes = NULL;

    if (FAILED(hr = pDst->QueryInterface(__uuidof(ID3D10Resource), (void**)&pDstRes)))
    {
        goto end;
    }
    
    if (FAILED(hr = pSrc->QueryInterface(__uuidof(ID3D10Resource), (void**)&pSrcRes)))
    {
        goto end;
    }

    m_pDevice->CopySubresourceRegion(
            pDstRes, 
            0, 
            0, 0, 0, //(x, y, z)
            pSrcRes,
            0, 
            &UnitBox);
end:
    if (pSrcRes)
    {
        pSrcRes->Release();
    }
    if (pDstRes)
    {
        pDstRes->Release();
    }

    return hr;
}
		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;
		}
// 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;
}
Пример #9
0
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;	

}
Пример #10
0
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;
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
0
void DoD3D10Capture(IDXGISwapChain *swap)
{
    ID3D10Device *device = NULL;
    if(SUCCEEDED(swap->GetDevice(__uuidof(ID3D10Device), (void**)&device)))
    {
        if(!lpCurrentDevice)
        {
            lpCurrentDevice = device;

            /*FARPROC oldRelease = GetVTable(device, (8/4));
            if(oldRelease != newD3D10Release)
            {
                oldD3D10Release = oldRelease;
                newD3D10Release = ConvertClassProcToFarproc((CLASSPROC)&D3D10Override::DeviceReleaseHook);
                SetVTable(device, (8/4), newD3D10Release);
            }*/
        }

        if(bCapturing && bStopRequested)
        {
            ClearD3D10Data();
            bCapturing = false;
            bStopRequested = false;
        }

        if(!bCapturing && WaitForSingleObject(hSignalRestart, 0) == WAIT_OBJECT_0)
        {
            hwndOBS = FindWindow(OBS_WINDOW_CLASS, NULL);
            if(hwndOBS)
                bCapturing = true;
        }

        if(!bHasTextures && bCapturing)
        {
            if(dxgiFormat && hwndOBS)
            {
                BOOL bSuccess = DoD3D10Hook(device);

                if(bSuccess)
                {
                    d3d10CaptureInfo.mapID = InitializeSharedMemoryGPUCapture(&texData);
                    if(!d3d10CaptureInfo.mapID)
                        bSuccess = false;
                }

                if(bSuccess)
                {
                    bHasTextures = true;
                    d3d10CaptureInfo.captureType = CAPTURETYPE_SHAREDTEX;
                    d3d10CaptureInfo.bFlip = FALSE;
                    texData->texHandle = (DWORD)sharedHandle;

                    memcpy(infoMem, &d3d10CaptureInfo, sizeof(CaptureInfo));
                    SetEvent(hSignalReady);

                    logOutput << "DoD3D10Hook: success" << endl;
                }
                else
                {
                    ClearD3D10Data();
                }
            }
        }

        if(bHasTextures)
        {
            LONGLONG timeVal = OSGetTimeMicroseconds();

            //check keep alive state, dumb but effective
            if(bCapturing)
            {
                if((timeVal-keepAliveTime) > 3000000)
                {
                    HANDLE hKeepAlive = OpenEvent(EVENT_ALL_ACCESS, FALSE, strKeepAlive.c_str());
                    if (hKeepAlive) {
                        CloseHandle(hKeepAlive);
                    } else {
                        ClearD3D10Data();
                        bCapturing = false;
                    }

                    keepAliveTime = timeVal;
                }
            }

            LONGLONG frameTime;
            if(bCapturing)
            {
                if(texData)
                {
                    if(frameTime = texData->frameTime)
                    {
                        LONGLONG timeElapsed = timeVal-lastTime;

                        if(timeElapsed >= frameTime)
                        {
                            if(!IsWindow(hwndOBS))
                            {
                                hwndOBS = NULL;
                                bStopRequested = true;
                            }

                            if(WaitForSingleObject(hSignalEnd, 0) == WAIT_OBJECT_0)
                                bStopRequested = true;

                            lastTime += frameTime;
                            if(timeElapsed > frameTime*2)
                                lastTime = timeVal;

                            DWORD nextCapture = curCapture == 0 ? 1 : 0;

                            ID3D10Resource *backBuffer = NULL;
                            if(SUCCEEDED(swap->GetBuffer(0, IID_ID3D10Resource, (void**)&backBuffer)))
                            {
                                if(bIsMultisampled)
                                    device->ResolveSubresource(copyD3D10TextureGame, 0, backBuffer, 0, dxgiFormat);
                                else
                                    device->CopyResource(copyD3D10TextureGame, backBuffer);

                                backBuffer->Release();
                            }

                            curCapture = nextCapture;
                        }
                    }
                }
            }
            else
                ClearD3D10Data();
        }
    }

    device->Release();
}
Пример #14
0
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;
    }

  }
}
Пример #15
0
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;
		}
	}
}