void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXCubemap *tex, U32 face, U32 mipLevel/*=0*/ ) { GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_attachTexture_Cubemap, ColorI::RED ); AssertFatal(slot < MaxRenderSlotId, "GFXD3D11TextureTarget::attachTexture - out of range slot."); // Mark state as dirty so device can know to update. invalidateState(); // Release what we had, it's definitely going to change. SAFE_RELEASE(mTargetViews[slot]); SAFE_RELEASE(mTargets[slot]); SAFE_RELEASE(mTargetSRViews[slot]); mResolveTargets[slot] = NULL; // Cast the texture object to D3D... AssertFatal(!tex || static_cast<GFXD3D11Cubemap*>(tex), "GFXD3DTextureTarget::attachTexture - invalid cubemap object."); if(slot == Color0) { mTargetSize = Point2I::Zero; mTargetFormat = GFXFormatR8G8B8A8; } // Are we clearing? if(!tex) { // Yup - just exit, it'll stay NULL. return; } GFXD3D11Cubemap *cube = static_cast<GFXD3D11Cubemap*>(tex); mTargets[slot] = cube->get2DTex(); mTargets[slot]->AddRef(); mTargetViews[slot] = cube->getRTView(face); mTargetViews[slot]->AddRef(); mTargetSRViews[slot] = cube->getSRView(); mTargetSRViews[slot]->AddRef(); // Update surface size if(slot == Color0) { ID3D11Texture2D *surface = mTargets[Color0]; if ( surface ) { D3D11_TEXTURE2D_DESC sd; surface->GetDesc(&sd); mTargetSize = Point2I(sd.Width, sd.Height); S32 format = sd.Format; GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, format ); mTargetFormat = (GFXFormat)format; } } }
void GFXPCD3D9TextureTarget::attachTexture( RenderSlot slot, GFXCubemap *tex, U32 face, U32 mipLevel/*=0*/ ) { GFXDEBUGEVENT_SCOPE( GFXPCD3D9TextureTarget_attachTexture_Cubemap, ColorI::RED ); AssertFatal(slot < MaxRenderSlotId, "GFXPCD3D9TextureTarget::attachTexture - out of range slot."); // Mark state as dirty so device can know to update. invalidateState(); // Release what we had, it's definitely going to change. mDevice->destroyD3DResource( mTargets[slot] ); // SAFE_RELEASE mTargets[slot] = NULL; mResolveTargets[slot] = NULL; // Cast the texture object to D3D... AssertFatal(!tex || dynamic_cast<GFXD3D9Cubemap*>(tex), "GFXD3DTextureTarget::attachTexture - invalid cubemap object."); GFXD3D9Cubemap *cube = static_cast<GFXD3D9Cubemap*>(tex); if(slot == Color0) { mTargetSize = Point2I::Zero; mTargetFormat = GFXFormatR8G8B8A8; } // Are we clearing? if(!tex) { // Yup - just exit, it'll stay NULL. return; } D3D9Assert(cube->mCubeTex->GetCubeMapSurface( (D3DCUBEMAP_FACES)face, mipLevel, &mTargets[slot] ), "GFXD3DTextureTarget::attachTexture - could not get surface level for the passed texture!"); // Update surface size if(slot == Color0) { IDirect3DSurface9 *surface = mTargets[Color0]; if ( surface ) { D3DSURFACE_DESC sd; surface->GetDesc(&sd); mTargetSize = Point2I(sd.Width, sd.Height); S32 format = sd.Format; GFXREVERSE_LOOKUP( GFXD3D9TextureFormat, GFXFormat, format ); mTargetFormat = (GFXFormat)format; } } }
//----------------------------------------------------------------------------- // _innerCreateTexture //----------------------------------------------------------------------------- void GFXD3D9TextureManager::_innerCreateTexture( GFXD3D9TextureObject *retTex, U32 height, U32 width, U32 depth, GFXFormat format, GFXTextureProfile *profile, U32 numMipLevels, bool forceMips, S32 antialiasLevel) { GFXD3D9Device* d3d = static_cast<GFXD3D9Device*>(GFX); // Some relevant helper information... bool supportsAutoMips = GFX->getCardProfiler()->queryProfile("autoMipMapLevel", true); DWORD usage = 0; // 0, D3DUSAGE_RENDERTARGET, or D3DUSAGE_DYNAMIC D3DPOOL pool = D3DPOOL_DEFAULT; retTex->mProfile = profile; D3DFORMAT d3dTextureFormat = GFXD3D9TextureFormat[format]; #ifndef TORQUE_OS_XENON if( retTex->mProfile->isDynamic() ) { usage = D3DUSAGE_DYNAMIC; } else { usage = 0; pool = d3d->isD3D9Ex() ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED; } if( retTex->mProfile->isRenderTarget() ) { pool = D3DPOOL_DEFAULT; usage |= D3DUSAGE_RENDERTARGET; } if(retTex->mProfile->isZTarget()) { usage |= D3DUSAGE_DEPTHSTENCIL; pool = D3DPOOL_DEFAULT; } if( retTex->mProfile->isSystemMemory() ) { pool = D3DPOOL_SYSTEMMEM; } if( supportsAutoMips && !forceMips && !retTex->mProfile->isSystemMemory() && numMipLevels == 0 && !(depth > 0) ) { usage |= D3DUSAGE_AUTOGENMIPMAP; } #else if(retTex->mProfile->isRenderTarget()) { d3dTextureFormat = (D3DFORMAT)MAKELEFMT(d3dTextureFormat); } #endif // Set the managed flag... retTex->isManaged = (pool == D3DPOOL_MANAGED) || d3d->isD3D9Ex(); if( depth > 0 ) { #ifdef TORQUE_OS_XENON D3D9Assert( mD3DDevice->CreateVolumeTexture( width, height, depth, numMipLevels, 0 /* usage ignored on the 360 */, d3dTextureFormat, pool, retTex->get3DTexPtr(), NULL), "Failed to create volume texture" ); #else D3D9Assert( GFXD3DX.D3DXCreateVolumeTexture( mD3DDevice, width, height, depth, numMipLevels, usage, d3dTextureFormat, pool, retTex->get3DTexPtr() ), "GFXD3D9TextureManager::_createTexture - failed to create volume texture!" ); #endif retTex->mTextureSize.set( width, height, depth ); retTex->mMipLevels = retTex->get3DTex()->GetLevelCount(); // required for 3D texture support - John Kabus retTex->mFormat = format; } else { #ifdef TORQUE_OS_XENON D3D9Assert( mD3DDevice->CreateTexture(width, height, numMipLevels, usage, d3dTextureFormat, pool, retTex->get2DTexPtr(), NULL), "Failed to create texture" ); retTex->mMipLevels = retTex->get2DTex()->GetLevelCount(); #else // Figure out AA settings for depth and render targets D3DMULTISAMPLE_TYPE mstype; DWORD mslevel; switch (antialiasLevel) { case 0 : mstype = D3DMULTISAMPLE_NONE; mslevel = 0; break; case AA_MATCH_BACKBUFFER : mstype = d3d->getMultisampleType(); mslevel = d3d->getMultisampleLevel(); break; default : { mstype = D3DMULTISAMPLE_NONMASKABLE; mslevel = antialiasLevel; #ifdef TORQUE_DEBUG DWORD MaxSampleQualities; d3d->getD3D()->CheckDeviceMultiSampleType(mAdapterIndex, D3DDEVTYPE_HAL, d3dTextureFormat, FALSE, D3DMULTISAMPLE_NONMASKABLE, &MaxSampleQualities); AssertFatal(mslevel < MaxSampleQualities, "Invalid AA level!"); #endif } break; } bool fastCreate = true; // Check for power of 2 textures - this is a problem with FX 5xxx cards // with current drivers - 3/2/05 if( !isPow2(width) || !isPow2(height) ) { fastCreate = false; } if(retTex->mProfile->isZTarget()) { D3D9Assert(mD3DDevice->CreateDepthStencilSurface(width, height, d3dTextureFormat, mstype, mslevel, retTex->mProfile->canDiscard(), retTex->getSurfacePtr(), NULL), "Failed to create Z surface" ); retTex->mFormat = format; // Assigning format like this should be fine. } else { // Try to create the texture directly - should gain us a bit in high // performance cases where we know we're creating good stuff and we // don't want to bother with D3DX - slow function. HRESULT res = D3DERR_INVALIDCALL; if( fastCreate ) { res = mD3DDevice->CreateTexture(width, height, numMipLevels, usage, d3dTextureFormat, pool, retTex->get2DTexPtr(), NULL); } if( !fastCreate || (res != D3D_OK) ) { D3D9Assert( GFXD3DX.D3DXCreateTexture( mD3DDevice, width, height, numMipLevels, usage, d3dTextureFormat, pool, retTex->get2DTexPtr() ), "GFXD3D9TextureManager::_createTexture - failed to create texture!" ); } // If this is a render target, and it wants AA or wants to match the backbuffer (for example, to share the z) // Check the caps though, if we can't stretchrect between textures, use the old RT method. (Which hopefully means // that they can't force AA on us as well.) if (retTex->mProfile->isRenderTarget() && mslevel != 0 && (mDeviceCaps.Caps2 && D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES)) { D3D9Assert(mD3DDevice->CreateRenderTarget(width, height, d3dTextureFormat, mstype, mslevel, false, retTex->getSurfacePtr(), NULL), "GFXD3D9TextureManager::_createTexture - unable to create render target"); } // All done! retTex->mMipLevels = retTex->get2DTex()->GetLevelCount(); } #endif // Get the actual size of the texture... D3DSURFACE_DESC probeDesc; ZeroMemory(&probeDesc, sizeof probeDesc); if( retTex->get2DTex() != NULL ) D3D9Assert( retTex->get2DTex()->GetLevelDesc( 0, &probeDesc ), "Failed to get surface description"); else if( retTex->getSurface() != NULL ) D3D9Assert( retTex->getSurface()->GetDesc( &probeDesc ), "Failed to get surface description"); retTex->mTextureSize.set(probeDesc.Width, probeDesc.Height, 0); int fmt = probeDesc.Format; #if !defined(TORQUE_OS_XENON) GFXREVERSE_LOOKUP( GFXD3D9TextureFormat, GFXFormat, fmt ); retTex->mFormat = (GFXFormat)fmt; #else retTex->mFormat = format; #endif } }
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; } }
void GFXPCD3D9TextureTarget::attachTexture( RenderSlot slot, GFXTextureObject *tex, U32 mipLevel/*=0*/, U32 zOffset /*= 0*/ ) { GFXDEBUGEVENT_SCOPE( GFXPCD3D9TextureTarget_attachTexture, ColorI::RED ); AssertFatal(slot < MaxRenderSlotId, "GFXPCD3D9TextureTarget::attachTexture - out of range slot."); // TODO: The way this is implemented... you can attach a texture // object multiple times and it will release and reset it. // // We should rework this to detect when no change has occured // and skip out early. // Mark state as dirty so device can know to update. invalidateState(); // Release what we had, it's definitely going to change. mDevice->destroyD3DResource( mTargets[slot] ); // SAFE_RELEASE mTargets[slot] = NULL; mResolveTargets[slot] = NULL; if(slot == Color0) { mTargetSize = Point2I::Zero; mTargetFormat = GFXFormatR8G8B8A8; } // Are we clearing? if(!tex) { // Yup - just exit, it'll stay NULL. return; } // Take care of default targets if( tex == GFXTextureTarget::sDefaultDepthStencil ) { mTargets[slot] = mDevice->mDeviceDepthStencil; mTargets[slot]->AddRef(); } else { // Cast the texture object to D3D... AssertFatal(dynamic_cast<GFXD3D9TextureObject*>(tex), "GFXPCD3D9TextureTarget::attachTexture - invalid texture object."); GFXD3D9TextureObject *d3dto = static_cast<GFXD3D9TextureObject*>(tex); // Grab the surface level. if( slot == DepthStencil ) { mTargets[slot] = d3dto->getSurface(); if ( mTargets[slot] ) mTargets[slot]->AddRef(); } else { // getSurface will almost always return NULL. It will only return non-NULL // if the surface that it needs to render to is different than the mip level // in the actual texture. This will happen with MSAA. if( d3dto->getSurface() == NULL ) { D3D9Assert(d3dto->get2DTex()->GetSurfaceLevel(mipLevel, &mTargets[slot]), "GFXPCD3D9TextureTarget::attachTexture - could not get surface level for the passed texture!"); } else { mTargets[slot] = d3dto->getSurface(); mTargets[slot]->AddRef(); // Only assign resolve target if d3dto has a surface to give us. // // That usually means there is an MSAA target involved, which is why // the resolve is needed to get the data out of the target. mResolveTargets[slot] = d3dto; if ( tex && slot == Color0 ) { mTargetSize.set( tex->getSize().x, tex->getSize().y ); mTargetFormat = tex->getFormat(); } } } // Update surface size if(slot == Color0) { IDirect3DSurface9 *surface = mTargets[Color0]; if ( surface ) { D3DSURFACE_DESC sd; surface->GetDesc(&sd); mTargetSize = Point2I(sd.Width, sd.Height); S32 format = sd.Format; GFXREVERSE_LOOKUP( GFXD3D9TextureFormat, GFXFormat, format ); mTargetFormat = (GFXFormat)format; } } } }
GFXFormat GFXPCD3D9WindowTarget::getFormat() { S32 format = mPresentationParams.BackBufferFormat; GFXREVERSE_LOOKUP( GFXD3D9TextureFormat, GFXFormat, format ); return (GFXFormat)format; }
GFXFormat GFXD3D11WindowTarget::getFormat() { S32 format = mPresentationParams.BufferDesc.Format; GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, format ); return (GFXFormat)format; }