void GFXD3D11TextureManager::_innerCreateTexture( GFXD3D11TextureObject *retTex, 
                                               U32 height, 
                                               U32 width, 
                                               U32 depth,
                                               GFXFormat format, 
                                               GFXTextureProfile *profile, 
                                               U32 numMipLevels,
                                               bool forceMips,
                                               S32 antialiasLevel)
{
   U32 usage = 0;
   U32 bindFlags = 0;
   U32 miscFlags = 0;
   
   if(!retTex->mProfile->isZTarget() && !retTex->mProfile->isSystemMemory())
      bindFlags =  D3D11_BIND_SHADER_RESOURCE;
   
   U32 cpuFlags = 0;

   retTex->mProfile = profile;
   retTex->isManaged = false;
   DXGI_FORMAT d3dTextureFormat = GFXD3D11TextureFormat[format];

   if( retTex->mProfile->isDynamic() )
   {
      usage = D3D11_USAGE_DYNAMIC;
      cpuFlags |= D3D11_CPU_ACCESS_WRITE;
      retTex->isManaged = false;      
   }
   else if ( retTex->mProfile->isSystemMemory() )
   {
      usage |= D3D11_USAGE_STAGING;
      cpuFlags |= D3D11_CPU_ACCESS_READ;
   }
   else
   {
      usage = D3D11_USAGE_DEFAULT;
      retTex->isManaged = true;
   }

   if( retTex->mProfile->isRenderTarget() )
   {
      bindFlags |= D3D11_BIND_RENDER_TARGET;
      //need to check to make sure this format supports render targets
      U32 supportFlag = 0;
      
      D3D11DEVICE->CheckFormatSupport(d3dTextureFormat, &supportFlag);
      //if it doesn't support render targets then default to R8G8B8A8
      if(!(supportFlag & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
         d3dTextureFormat = DXGI_FORMAT_R8G8B8A8_UNORM;

      retTex->isManaged =false;
   }

   if( retTex->mProfile->isZTarget() )
   {
      bindFlags |= D3D11_BIND_DEPTH_STENCIL;
      retTex->isManaged = false;
   }

   if( !forceMips && !retTex->mProfile->isSystemMemory() &&
       numMipLevels == 0 &&
       !(depth > 0) )
   {
      miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
      bindFlags |= D3D11_BIND_RENDER_TARGET; // in order to automatically generate mips. Resource needs to be a rendertarget and shader resource
   }

   if( depth > 0 )
   {
      D3D11_TEXTURE3D_DESC desc;
      ZeroMemory(&desc, sizeof(D3D11_TEXTURE3D_DESC));

		desc.BindFlags = bindFlags;
		desc.CPUAccessFlags = cpuFlags;
		desc.Depth = depth;
		desc.Width = width;
		desc.Height = height;
		desc.Format = d3dTextureFormat;
		desc.Usage = (D3D11_USAGE)usage;
		desc.MipLevels = numMipLevels;

		HRESULT hr = D3D11DEVICE->CreateTexture3D(&desc, NULL, retTex->get3DTexPtr());

      if(FAILED(hr)) 
      {
         AssertFatal(false, "GFXD3D11TextureManager::_createTexture - failed to create volume texture!");
      }

      retTex->mTextureSize.set(width, height, depth);
      retTex->get3DTex()->GetDesc(&desc);
      retTex->mMipLevels = numMipLevels;
      retTex->mFormat = format;
   }
   else
   {
		U32 numQualityLevels = 0;

		switch (antialiasLevel)
		{
			case 0:
			case AA_MATCH_BACKBUFFER:
				antialiasLevel = 1;
				break;

			default:
			{
				antialiasLevel = 0;
				D3D11DEVICE->CheckMultisampleQualityLevels(d3dTextureFormat, antialiasLevel, &numQualityLevels);
				AssertFatal(numQualityLevels, "Invalid AA level!");
				break;
			}
		}

		if(retTex->mProfile->isZTarget())
		{
			D3D11_TEXTURE2D_DESC desc;
		  
			ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
			desc.ArraySize = 1;
			desc.BindFlags = bindFlags;
			desc.CPUAccessFlags = cpuFlags;
			//depth stencil must be a typeless format if it is bound on render target and shader resource simultaneously
			// we'll send the real format for the creation of the views
			desc.Format =  DXGI_FORMAT_R24G8_TYPELESS; 
			desc.MipLevels = numMipLevels;
			desc.SampleDesc.Count = antialiasLevel;
			desc.SampleDesc.Quality = numQualityLevels;
			desc.Height = height;
			desc.Width = width;
			desc.Usage = (D3D11_USAGE)usage;
			HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, retTex->getSurfacePtr());
		   
			if(FAILED(hr)) 
			{
				AssertFatal(false, "Failed to create Zbuffer texture");
			}

			retTex->mFormat = format; // Assigning format like this should be fine.
		}
		else
		{
			D3D11_TEXTURE2D_DESC desc;
		  
			ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
			desc.ArraySize = 1;
			desc.BindFlags = bindFlags;
			desc.CPUAccessFlags = cpuFlags;
			desc.Format = d3dTextureFormat;
			desc.MipLevels = numMipLevels;
			desc.SampleDesc.Count = antialiasLevel;
			desc.SampleDesc.Quality = numQualityLevels;
			desc.Height = height;
			desc.Width = width;
			desc.Usage = (D3D11_USAGE)usage;
			desc.MiscFlags = miscFlags;
			HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, retTex->get2DTexPtr());

			if(FAILED(hr)) 
			{
				AssertFatal(false, "GFXD3D11TextureManager::_createTexture - failed to create texture!");
			}

			retTex->get2DTex()->GetDesc(&desc);
			retTex->mMipLevels = desc.MipLevels;
		}

		// start creating the resource views...
		// don't bother creating views for system memory/staging textures 
		// they are just used for copying

		if (!retTex->mProfile->isSystemMemory())
		{
         createResourceView(height, width, depth, d3dTextureFormat, numMipLevels, bindFlags, retTex);
		}

		// Get the actual size of the texture...
		D3D11_TEXTURE2D_DESC probeDesc;
		ZeroMemory(&probeDesc, sizeof(D3D11_TEXTURE2D_DESC));
	  
		if( retTex->get2DTex() != NULL )
		{
			retTex->get2DTex()->GetDesc(&probeDesc);
		}
		else if( retTex->getSurface() != NULL )
		{
			retTex->getSurface()->GetDesc(&probeDesc);
		}

		retTex->mTextureSize.set(probeDesc.Width, probeDesc.Height, 0);
		S32 fmt = 0;

		if(!profile->isZTarget())
		   fmt = probeDesc.Format;
		else
		   fmt = DXGI_FORMAT_D24_UNORM_S8_UINT; // we need to assign this manually.

		GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, fmt );
		retTex->mFormat = (GFXFormat)fmt;
	}
}
Example #2
0
void ParticleEditor::setDockWidget()
{
	createResourceView();
	createControlView();
	createModelView();
}