Пример #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;
}
		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;
		}
Пример #3
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);
	}
		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;
		}
Пример #5
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;	

}
Пример #6
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;
}
Пример #7
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;
}
Пример #8
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;
}
Пример #9
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;
    }

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