/// 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; }
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 *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; }
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); }