bool GFXD3D11TextureManager::_refreshTexture(GFXTextureObject *texture)
{
   U32 usedStrategies = 0;
   GFXD3D11TextureObject *realTex = static_cast<GFXD3D11TextureObject *>(texture);

   if(texture->mProfile->doStoreBitmap())
   {
      if(texture->mBitmap)
         _loadTexture(texture, texture->mBitmap);

      if(texture->mDDS)
         _loadTexture(texture, texture->mDDS);

      usedStrategies++;
   }

   if(texture->mProfile->isRenderTarget() || texture->mProfile->isDynamic() || texture->mProfile->isZTarget())
   {
      realTex->release();
      _innerCreateTexture(realTex, texture->getHeight(), texture->getWidth(), texture->getDepth(), texture->mFormat, texture->mProfile, texture->mMipLevels, false, texture->mAntialiasLevel);
      usedStrategies++;
   }

   AssertFatal(usedStrategies < 2, "GFXD3D11TextureManager::_refreshTexture - Inconsistent profile flags!");

   return true;
}
/// Load a texture from a proper DDSFile instance.
bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, DDSFile *dds)
{
   PROFILE_SCOPE(GFXD3D11TextureManager_loadTextureDDS);

   GFXD3D11TextureObject *texture = static_cast<GFXD3D11TextureObject*>(aTexture);
   GFXD3D11Device* dev = static_cast<GFXD3D11Device *>(GFX);
   // Fill the texture...
   for( U32 i = 0; i < aTexture->mMipLevels; i++ )
   {
      PROFILE_SCOPE(GFXD3DTexMan_loadSurface);

		AssertFatal( dds->mSurfaces.size() > 0, "Assumption failed. DDSFile has no surfaces." );

		U32 subresource = D3D11CalcSubresource(i, 0, aTexture->mMipLevels);
		dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subresource, 0, dds->mSurfaces[0]->mMips[i], dds->getSurfacePitch(i), 0);
   }

   D3D11_TEXTURE2D_DESC desc;
   // if the texture asked for mip generation. lets generate it.
   texture->get2DTex()->GetDesc(&desc);
   if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)
      dev->getDeviceContext()->GenerateMips(texture->getSRView());

   return true;
}
//-----------------------------------------------------------------------------
// createTexture
//-----------------------------------------------------------------------------
GFXTextureObject *GFXD3D11TextureManager::_createTextureObject( U32 height, 
                                                               U32 width,
                                                               U32 depth,
                                                               GFXFormat format, 
                                                               GFXTextureProfile *profile, 
                                                               U32 numMipLevels,
                                                               bool forceMips, 
                                                               S32 antialiasLevel,
                                                               GFXTextureObject *inTex )
{
   GFXD3D11TextureObject *retTex;
   if ( inTex )
   {
      AssertFatal(static_cast<GFXD3D11TextureObject*>( inTex ), "GFXD3D11TextureManager::_createTexture() - Bad inTex type!");
      retTex = static_cast<GFXD3D11TextureObject*>( inTex );
      retTex->release();
   }      
   else
   {
      retTex = new GFXD3D11TextureObject(GFX, profile);
      retTex->registerResourceWithDevice(GFX);
   }

   _innerCreateTexture(retTex, height, width, depth, format, profile, numMipLevels, forceMips, antialiasLevel);

   return retTex;
}
bool GFXD3D11TextureManager::_freeTexture(GFXTextureObject *texture, bool zombify)
{
   AssertFatal(dynamic_cast<GFXD3D11TextureObject *>(texture),"Not an actual d3d texture object!");
   GFXD3D11TextureObject *tex = static_cast<GFXD3D11TextureObject *>( texture );

   // If it's a managed texture and we're zombifying, don't blast it, D3D allows
   // us to keep it.
   if(zombify && tex->isManaged)
     return true;

   tex->release();

   return true;
}
void GFXD3D11TextureManager::createResourceView(U32 height, U32 width, U32 depth, DXGI_FORMAT format, U32 numMipLevels,U32 usageFlags, GFXTextureObject *inTex)
{
	GFXD3D11TextureObject *tex = static_cast<GFXD3D11TextureObject*>(inTex);
	ID3D11Resource* resource = NULL;
	
	if(tex->get2DTex())
		resource = tex->get2DTex();
	else if(tex->getSurface())
		resource = tex->getSurface();
	else
		resource = tex->get3DTex();

	HRESULT hr;
	//TODO: add MSAA support later.
	if(usageFlags & D3D11_BIND_SHADER_RESOURCE)
	{
      D3D11_SHADER_RESOURCE_VIEW_DESC desc;

      if(usageFlags & D3D11_BIND_DEPTH_STENCIL)
         desc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; // reads the depth
      else
         desc.Format = format;
	
		if(depth > 0)
		{
			desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
			desc.Texture3D.MipLevels = -1;
			desc.Texture3D.MostDetailedMip = 0;
		}
		else
		{
			desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
			desc.Texture2D.MipLevels = -1;
			desc.Texture2D.MostDetailedMip = 0;
		}
		
		hr = D3D11DEVICE->CreateShaderResourceView(resource,&desc, tex->getSRViewPtr());
		AssertFatal(SUCCEEDED(hr), "CreateShaderResourceView:: failed to create view!");
	}

	if(usageFlags & D3D11_BIND_RENDER_TARGET)
	{
		D3D11_RENDER_TARGET_VIEW_DESC desc;
		desc.Format = format;
		desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
		desc.Texture2D.MipSlice = 0;
		hr = D3D11DEVICE->CreateRenderTargetView(resource, &desc, tex->getRTViewPtr());
		AssertFatal(SUCCEEDED(hr), "CreateRenderTargetView:: failed to create view!");
	}

	if(usageFlags & D3D11_BIND_DEPTH_STENCIL)
	{
		D3D11_DEPTH_STENCIL_VIEW_DESC desc;
		desc.Format = format;
		desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
		desc.Texture2D.MipSlice = 0;
		desc.Flags = 0;
		hr = D3D11DEVICE->CreateDepthStencilView(resource,&desc, tex->getDSViewPtr());
		AssertFatal(SUCCEEDED(hr), "CreateDepthStencilView:: failed to create view!");
	}
}
bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *inTex, void *raw)
{
   PROFILE_SCOPE(GFXD3D11TextureManager_loadTextureRaw);

   GFXD3D11TextureObject *texture = (GFXD3D11TextureObject *) inTex;
   GFXD3D11Device* dev = static_cast<GFXD3D11Device *>(GFX);
   // currently only for volume textures...
   if(texture->getDepth() < 1) return false;

   U8* Bits = NULL;
  
   if(texture->mFormat == GFXFormatR8G8B8 || texture->mFormat == GFXFormatR8G8B8_SRGB)
   {
	   // convert 24 bit to 32 bit
	   Bits = new U8[texture->getWidth() * texture->getHeight() * texture->getDepth() * 4];
	   dMemcpy(Bits, raw, texture->getWidth() * texture->getHeight() * texture->getDepth() * 3);
	   bitmapConvertRGB_to_RGBX(&Bits, texture->getWidth() * texture->getHeight() * texture->getDepth());      
   }

   U32 bytesPerPix = 1;

   switch(texture->mFormat)
   {
      case GFXFormatR8G8B8:
      case GFXFormatR8G8B8_SRGB:
      case GFXFormatR8G8B8A8:
      case GFXFormatR8G8B8X8:
      case GFXFormatR8G8B8A8_SRGB:
         bytesPerPix = 4;
         break;
   }

   D3D11_BOX box;
   box.left    = 0;
   box.right   = texture->getWidth();
   box.front   = 0;
   box.back    = texture->getDepth();
   box.top     = 0;
   box.bottom  = texture->getHeight();

   if(texture->mFormat == GFXFormatR8G8B8 || texture->mFormat == GFXFormatR8G8B8_SRGB) // converted format also for volume textures
		dev->getDeviceContext()->UpdateSubresource(texture->get3DTex(), 0, &box, Bits, texture->getWidth() * bytesPerPix, texture->getHeight() * bytesPerPix);
   else
		dev->getDeviceContext()->UpdateSubresource(texture->get3DTex(), 0, &box, raw, texture->getWidth() * bytesPerPix, texture->getHeight() * bytesPerPix);

   SAFE_DELETE_ARRAY(Bits);

   return true;
}
bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *pDL)
{
   PROFILE_SCOPE(GFXD3D11TextureManager_loadTexture);

   GFXD3D11TextureObject *texture = static_cast<GFXD3D11TextureObject*>(aTexture);

   // Check with profiler to see if we can do automatic mipmap generation.
   const bool supportsAutoMips = GFX->getCardProfiler()->queryProfile("autoMipMapLevel", true);

   // Helper bool
   const bool isCompressedTexFmt = ImageUtil::isCompressedFormat(aTexture->mFormat);

   // Settings for mipmap generation
   U32 maxDownloadMip = pDL->getNumMipLevels();
   U32 nbMipMapLevel  = pDL->getNumMipLevels();

   if( supportsAutoMips && !isCompressedTexFmt )
   {
      maxDownloadMip = 1;
      nbMipMapLevel  = aTexture->mMipLevels;
   }
   GFXD3D11Device* dev = D3D11;

   bool isDynamic = texture->mProfile->isDynamic();
   // Fill the texture...
   for( U32 i = 0; i < maxDownloadMip; i++ )
   {
	   U32 subResource = D3D11CalcSubresource(i, 0, aTexture->mMipLevels);

	   if(!isDynamic)
	   {
		   U8* copyBuffer = NULL;

		   switch(texture->mFormat)
			{
            case GFXFormatR8G8B8:
            case GFXFormatR8G8B8_SRGB:
				{
					PROFILE_SCOPE(Swizzle24_Upload);

					U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
					dMemcpy(Bits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * 3);
					bitmapConvertRGB_to_RGBX(&Bits, pDL->getWidth(i) * pDL->getHeight(i));
					copyBuffer = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
					
					dev->getDeviceSwizzle32()->ToBuffer(copyBuffer, Bits, pDL->getWidth(i) * pDL->getHeight(i) * 4);
					dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subResource, NULL, copyBuffer, pDL->getWidth() * 4, pDL->getHeight() *4);
               SAFE_DELETE_ARRAY(Bits);
					break;
				}

				case GFXFormatR8G8B8A8:
				case GFXFormatR8G8B8X8:
            case GFXFormatR8G8B8A8_SRGB:
				{
               PROFILE_SCOPE(Swizzle32_Upload);
               copyBuffer = new U8[pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel()];
               dev->getDeviceSwizzle32()->ToBuffer(copyBuffer, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel());
               dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subResource, NULL, copyBuffer, pDL->getWidth() * pDL->getBytesPerPixel(), pDL->getHeight() *pDL->getBytesPerPixel());
					break;
				}

				default:
				{
               // Just copy the bits in no swizzle or padding
               PROFILE_SCOPE(SwizzleNull_Upload);
               AssertFatal( pDL->getFormat() == texture->mFormat, "Format mismatch");
               dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subResource, NULL, pDL->getBits(i), pDL->getWidth() *pDL->getBytesPerPixel(), pDL->getHeight() *pDL->getBytesPerPixel());
				}
			}

         SAFE_DELETE_ARRAY(copyBuffer);
	    }
	  
	   else
	   {
			D3D11_MAPPED_SUBRESOURCE mapping;
			HRESULT res =  dev->getDeviceContext()->Map(texture->get2DTex(), subResource, D3D11_MAP_WRITE, 0, &mapping);

			AssertFatal(res, "tex2d map call failure");

			switch( texture->mFormat )
			{
				case GFXFormatR8G8B8:
            case GFXFormatR8G8B8_SRGB:
				{
					PROFILE_SCOPE(Swizzle24_Upload);

					U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
					dMemcpy(Bits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * 3);
					bitmapConvertRGB_to_RGBX(&Bits, pDL->getWidth(i) * pDL->getHeight(i));					

					dev->getDeviceSwizzle32()->ToBuffer(mapping.pData, Bits, pDL->getWidth(i) * pDL->getHeight(i) * 4);
               SAFE_DELETE_ARRAY(Bits);
				}
				break;

            case GFXFormatR8G8B8A8:
            case GFXFormatR8G8B8X8:
            case GFXFormatR8G8B8A8_SRGB:
            {
               PROFILE_SCOPE(Swizzle32_Upload);
               dev->getDeviceSwizzle32()->ToBuffer(mapping.pData, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel());
            }
				break;

				default:
				{
               // Just copy the bits in no swizzle or padding
               PROFILE_SCOPE(SwizzleNull_Upload);
               AssertFatal( pDL->getFormat() == texture->mFormat, "Format mismatch");
               dMemcpy(mapping.pData, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel());
				}
			}

			dev->getDeviceContext()->Unmap(texture->get2DTex(), subResource);
	   }
   }

   D3D11_TEXTURE2D_DESC desc;
   // if the texture asked for mip generation. lets generate it.
   texture->get2DTex()->GetDesc(&desc);
   if (desc.MiscFlags &D3D11_RESOURCE_MISC_GENERATE_MIPS)
   {
      dev->getDeviceContext()->GenerateMips(texture->getSRView());
      //texture->mMipLevels = desc.MipLevels;
   }

   return true;          
}
Beispiel #8
0
void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
{
   AssertFatal( faces, "GFXD3D11Cubemap::initStatic - Got null GFXTexHandle!" );
	AssertFatal( *faces, "empty texture passed to CubeMap::create" );
  
	// NOTE - check tex sizes on all faces - they MUST be all same size
	mTexSize = faces->getWidth();
	mFaceFormat = faces->getFormat();
   bool compressed = isCompressed(mFaceFormat);

   UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
   UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
   if (!compressed)
   {
      bindFlags |= D3D11_BIND_RENDER_TARGET;
      miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
   }

   U32 mipLevels = faces->getPointer()->getMipLevels();
   if (mipLevels > 1)
      mAutoGenMips = true;

	D3D11_TEXTURE2D_DESC desc;
	ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
	desc.Width = mTexSize;
	desc.Height = mTexSize;
   desc.MipLevels = mAutoGenMips ? 0 : mipLevels;
	desc.ArraySize = 6;
	desc.Format = GFXD3D11TextureFormat[mFaceFormat];
	desc.SampleDesc.Count = 1;
	desc.SampleDesc.Quality = 0;
	desc.Usage = D3D11_USAGE_DEFAULT;
	desc.BindFlags = bindFlags;
	desc.MiscFlags = miscFlags;
	desc.CPUAccessFlags = 0;

	HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mTexture);

	if (FAILED(hr))
	{
		AssertFatal(false, "GFXD3D11Cubemap:initStatic(GFXTexhandle *faces) - failed to create texcube texture");
	}

   for (U32 i = 0; i < CubeFaces; i++)
   {
      GFXD3D11TextureObject *texObj = static_cast<GFXD3D11TextureObject*>((GFXTextureObject*)faces[i]);
      U32 subResource = D3D11CalcSubresource(0, i, mipLevels);
      D3D11DEVICECONTEXT->CopySubresourceRegion(mTexture, subResource, 0, 0, 0, texObj->get2DTex(), 0, NULL);
   }
   
	D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
	SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
	SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
   SMViewDesc.TextureCube.MipLevels = mAutoGenMips ? -1 : mipLevels;
	SMViewDesc.TextureCube.MostDetailedMip = 0;

	hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
	if (FAILED(hr))
	{
		AssertFatal(false, "GFXD3D11Cubemap::initStatic(GFXTexHandle *faces) - texcube shader resource view  creation failure");
	} 

   if (mAutoGenMips && !compressed)
      D3D11DEVICECONTEXT->GenerateMips(mSRView);
}