TextureDX9::TextureDX9( const PixelFormat texFormat, const TexType texType, const unsigned int sizeX, const unsigned int sizeY, const unsigned int sizeZ, const unsigned int mipmapLevelCount, const BufferUsage usage) : Texture(texFormat, texType, sizeX, sizeY, sizeZ, mipmapLevelCount, usage) , m_pTexture(nullptr) , m_pTempBuffer(nullptr) , m_nRowPitch(0) , m_nDepthPitch(0) { IDirect3DDevice9* device = RendererDX9::GetInstance()->GetDevice(); D3DPOOL pool; if (GetUsage() == BU_TEXTURE) pool = D3DPOOL_MANAGED; else pool = D3DPOOL_DEFAULT; HRESULT hr; DWORD usageFlags; switch (GetTextureType()) { case TT_1D: hr = device->CreateTexture( GetWidth(), 1u, GetMipmapLevelCount(), BufferUsageDX9[m_eBufferUsage], TextureFormatDX9[m_eTexFormat], pool, (IDirect3DTexture9**)&m_pTexture, 0); break; case TT_2D: usageFlags = BufferUsageDX9[m_eBufferUsage]; if (m_eBufferUsage == BU_RENDERTAGET && mipmapLevelCount == 0) { // automatic mipmap generation for RTs usageFlags |= D3DUSAGE_AUTOGENMIPMAP; m_bAutogenMipmaps = true; } hr = device->CreateTexture( GetWidth(), GetHeight(), m_bAutogenMipmaps ? 0 : GetMipmapLevelCount(), usageFlags, TextureFormatDX9[m_eTexFormat], pool, (IDirect3DTexture9**)&m_pTexture, 0); break; case TT_3D: hr = device->CreateVolumeTexture( GetWidth(), GetHeight(), GetDepth(), GetMipmapLevelCount(), BufferUsageDX9[m_eBufferUsage], TextureFormatDX9[m_eTexFormat], pool, (IDirect3DVolumeTexture9**)&m_pTexture, 0); break; case TT_CUBE: hr = device->CreateCubeTexture( GetWidth(), GetMipmapLevelCount(), BufferUsageDX9[m_eBufferUsage], TextureFormatDX9[m_eTexFormat], pool, (IDirect3DCubeTexture9**)&m_pTexture, 0); } assert(SUCCEEDED(hr)); }
Coherent::UI::CoherentHandle CCoherentUISystem::CreateSharedTextureDX9( const CreateSurfaceTask& task, TexturePair* outTexturePair ) { IDirect3DTexture9* pD3DTex = nullptr; // Create a shared texture HANDLE result = 0; IDirect3DDevice9* pDevice = static_cast<IDirect3DDevice9*>( gD3DDevice ); HRESULT hr = pDevice->CreateTexture( task.Width, task.Height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pD3DTex, &result ); if ( FAILED( hr ) ) { CryLogAlways( "Unable to create shared texture with DirectX9 renderer!" ); } ITexture* pCryTex = gD3DSystem->InjectTexture( pD3DTex, task.Width, task.Height, eTF_A8R8G8B8, 0 ); // The native texture has one more reference after InjectTexture if ( outTexturePair ) { outTexturePair->CryTextureID = pCryTex->GetTextureID(); outTexturePair->NativeTexture.pTexDX9 = pD3DTex; } SAFE_RELEASE( pD3DTex ); return Coherent::UI::CoherentHandle( result ); }
void D3D9Texture::createHardwareResource() { IDirect3DDevice9* dev = mFatherManager->getAs<D3D9TextureManager>() ->getD3DResourceFactory()->getMainDevice(); // release created resources. releaseHardwareResource(); D3DFORMAT texFormat = (mFormat == PF_Unknown) ? D3DFMT_A8R8G8B8 : D3D9Translator::getD3DFormat(mFormat); uint32 mipmap = mMipMapCount == MIPMAP_MAXCOUNT ? 0 : mMipMapCount + 1; if (mType == TT_1D || mType == TT_2D) { dev->CreateTexture(mWidth, mHeight, mipmap, 0, texFormat, D3DPOOL_MANAGED, &mTexture.p2DTexture, NULL); mTexture.pBaseTexture = mTexture.p2DTexture; } else if (mType == TT_3D) { dev->CreateVolumeTexture(mWidth, mHeight, mDepth, mipmap, 0, texFormat, D3DPOOL_MANAGED, &mTexture.p3DTexture, NULL); mTexture.pBaseTexture = mTexture.p3DTexture; } else { dev-> CreateCubeTexture(mWidth, mipmap, 0, texFormat, D3DPOOL_MANAGED, &mTexture.pCubeTexture, NULL); mTexture.pBaseTexture = mTexture.pCubeTexture; } createSurfaceList(); mTextureConstant = DGpuTextureConstantPtr(new D3D9GpuTextureConstant(mTexture.pBaseTexture)); }
TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) : TextureStorage9(renderer, GetTextureUsage(internalformat, Renderer9::makeRenderer9(renderer), renderTarget)) { mTexture = NULL; mRenderTarget = NULL; // if the width or height is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation if (width > 0 && height > 0) { IDirect3DDevice9 *device = mRenderer->getDevice(); D3DFORMAT format = gl_d3d9::GetTextureFormat(internalformat, mRenderer); d3d9::MakeValidSize(false, format, &width, &height, &mTopLevel); UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels; HRESULT result = device->CreateTexture(width, height, creationLevels, getUsage(), format, getPool(), &mTexture, NULL); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); gl::error(GL_OUT_OF_MEMORY); } } initializeRenderTarget(); }
//---------------------------------------------------------------------------- PdrTexture2D::PdrTexture2D (Renderer* renderer, bool isColorTexture, const Texture2D* texture, bool autoGenMipMap) { IDirect3DDevice9* device = renderer->mData->mDevice; HRESULT hr; PX2_UNUSED(hr); if (isColorTexture) { UINT levels = 1; DWORD usage = gDX9BufferUsage[texture->GetUsage()]; if (autoGenMipMap) { levels = 0; usage |= D3DUSAGE_AUTOGENMIPMAP; } hr = device->CreateTexture((UINT)texture->GetWidth(), (UINT)texture->GetHeight(), levels, usage, gDX9TextureFormat[texture->GetFormat()], D3DPOOL_DEFAULT, &mTexture, 0); assertion(hr == D3D_OK, "Failed to create render target color texture: %s\n", DXGetErrorString(hr)); } else { hr = device->CreateTexture((UINT)texture->GetWidth(), (UINT)texture->GetHeight(), 1, gDX9BufferUsage[texture->GetUsage()], gDX9TextureFormat[texture->GetFormat()], D3DPOOL_DEFAULT, &mTexture, 0); assertion(hr == D3D_OK, "Failed to create render target depthstencil texture: %s\n", DXGetErrorString(hr)); } }
IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect) { egl::Display *display = getDisplay(); IDirect3DDevice9 *device = getDevice(); D3DSURFACE_DESC sourceDesc; surface->GetDesc(&sourceDesc); // Copy the render target into a texture IDirect3DTexture9 *texture; HRESULT result = device->CreateTexture(sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1, D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, NULL); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); } IDirect3DSurface9 *textureSurface; result = texture->GetSurfaceLevel(0, &textureSurface); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); texture->Release(); return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); } RECT d3dSourceRect; d3dSourceRect.left = sourceRect.left; d3dSourceRect.right = sourceRect.right; d3dSourceRect.top = sourceRect.top; d3dSourceRect.bottom = sourceRect.bottom; display->endScene(); result = device->StretchRect(surface, &d3dSourceRect, textureSurface, NULL, D3DTEXF_NONE); textureSurface->Release(); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); texture->Release(); return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); } return texture; }
void DevState::newTexture(unsigned int width, unsigned int height) { ods("D3D9: New texture %d x %d", width, height); if (texTexture) { texTexture->Release(); texTexture = NULL; } dev->CreateTexture(uiWidth, uiHeight, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texTexture, NULL); for (int i = 0; i < 4; ++i) { vertices[i].x = vertices[i].y = vertices[i].z = 0.0f; vertices[i].tu = vertices[i].tv = 0.0f; vertices[i].rhw = 1.0f; } }
/// @copydoc D3D9DeviceResetListener::OnPostReset() void D3D9DynamicTexture2d::OnPostReset( D3D9Renderer* pRenderer ) { HELIUM_ASSERT( pRenderer ); IDirect3DDevice9* pDevice = pRenderer->GetD3DDevice(); HELIUM_ASSERT( pDevice ); // Recreate the texture. static const DWORD d3dUsages[] = { 0, // RENDERER_BUFFER_USAGE_STATIC D3DUSAGE_DYNAMIC, // RENDERER_BUFFER_USAGE_DYNAMIC D3DUSAGE_RENDERTARGET, // RENDERER_BUFFER_USAGE_RENDER_TARGET D3DUSAGE_DEPTHSTENCIL // RENDERER_BUFFER_USAGE_DEPTH_STENCIL }; HELIUM_ASSERT( !m_pTexture ); HELIUM_D3D9_VERIFY( pDevice->CreateTexture( m_width, m_height, m_mipLevelCountMinusOne + 1, d3dUsages[ m_usage ], m_format, D3DPOOL_DEFAULT, &m_pTexture, NULL ) ); // Reassign surface references to any D3D9Surface objects cached during OnPreReset(). uint_fast32_t mipLevelCount = m_mipLevelCountMinusOne + 1; for( uint_fast32_t levelIndex = 0; levelIndex < mipLevelCount; ++levelIndex ) { D3D9Surface* pSurface = m_surfaces[ levelIndex ]; if( pSurface ) { IDirect3DSurface9* pD3DSurface = NULL; HELIUM_D3D9_VERIFY( m_pTexture->GetSurfaceLevel( static_cast< UINT >( levelIndex ), &pD3DSurface ) ); HELIUM_ASSERT( pD3DSurface ); pSurface->SetD3DSurface( pD3DSurface ); m_surfaces[ levelIndex ].Release(); pD3DSurface->Release(); } } }
gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect, IDirect3DTexture9 **outTexture) { ASSERT(surface); IDirect3DDevice9 *device = mRenderer->getDevice(); D3DSURFACE_DESC sourceDesc; surface->GetDesc(&sourceDesc); // Copy the render target into a texture IDirect3DTexture9 *texture; HRESULT result = device->CreateTexture(sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1, D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, NULL); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal texture for blit, result: 0x%X.", result); } IDirect3DSurface9 *textureSurface; result = texture->GetSurfaceLevel(0, &textureSurface); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); SafeRelease(texture); return gl::Error(GL_OUT_OF_MEMORY, "Failed to query surface of internal blit texture, result: 0x%X.", result); } mRenderer->endScene(); result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE); SafeRelease(textureSurface); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); SafeRelease(texture); return gl::Error(GL_OUT_OF_MEMORY, "Failed to copy between internal blit textures, result: 0x%X.", result); } *outTexture = texture; return gl::Error(GL_NO_ERROR); }
//---------------------------------------------------------------------------- PdrTexture1D::PdrTexture1D (Renderer* renderer, const Texture1D* texture) { IDirect3DDevice9* device = renderer->mData->mDevice; int numLevels = texture->GetNumLevels(); HRESULT hr = device->CreateTexture((UINT)texture->GetLength(), 1u, (UINT)numLevels, gDX9BufferUsage[texture->GetUsage()], gDX9TextureFormat[texture->GetFormat()], D3DPOOL_MANAGED, &mTexture, 0); WM5_UNUSED(hr); assertion(hr == D3D_OK, "Failed to create 1D texture: %s\n", DXGetErrorString(hr)); for (int level = 0; level < numLevels; ++level) { void* data = Lock(level, Buffer::BL_WRITE_ONLY); memcpy(data, texture->GetData(level), texture->GetNumLevelBytes(level)); Unlock(level); } }
IDirect3DTexture9* MythRenderD3D9::CreateTexture(const QSize &size) { D3D9Locker locker(this); IDirect3DDevice9* dev = locker.Acquire(); if (!dev) return NULL; IDirect3DTexture9* temp_texture = NULL; HRESULT hr = dev->CreateTexture( size.width(), size.height(), 1, D3DUSAGE_RENDERTARGET, m_texture_fmt, D3DPOOL_DEFAULT, &temp_texture, NULL); if (FAILED(hr) || !temp_texture) { VERBOSE(VB_IMPORTANT, D3DERR + "Failed to create texture."); return NULL; } m_textures[temp_texture] = size;; return temp_texture; }
gl::Error TextureStorage9_2D::getBaseTexture(IDirect3DBaseTexture9 **outTexture) { // if the width or height is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0) { ASSERT(mMipLevels > 0); IDirect3DDevice9 *device = mRenderer->getDevice(); HRESULT result = device->CreateTexture(mTextureWidth, mTextureHeight, mMipLevels, getUsage(), mTextureFormat, getPool(), &mTexture, NULL); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D storage texture, result: 0x%X.", result); } } *outTexture = mTexture; return gl::Error(GL_NO_ERROR); }
void DX9Texture::createFallbackTexture(HDResourceMgr *pMgr) { ASSERT(pMgr); DX9ResourceMgr* pDX9Mgr = (DX9ResourceMgr*)pMgr; IDirect3DDevice9* pDev = pDX9Mgr->getDX9Device(); HRESULT hr; const int SIZE = 128; hr = pDev->CreateTexture(SIZE, SIZE, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &s_fallbackTexture, NULL); if(FAILED(hr)) { LOG("fallback texture create failed"); return; } D3DLOCKED_RECT lockRect; hr = s_fallbackTexture->LockRect(0, &lockRect, NULL, 0); if(SUCCEEDED(hr)) { D3DCOLOR fallColor[2]; fallColor[0] = D3DCOLOR_ARGB(255,5,250,250); fallColor[1] = D3DCOLOR_ARGB(255,5,0,5); D3DCOLOR *pPixel = (D3DCOLOR *)lockRect.pBits; for(int y=0; y<SIZE; y++) { for(int x=0; x<SIZE; x++) { int sel = (x/16)%2+(y/16+1)%2; pPixel[y*SIZE+x] = fallColor[sel%2]; } } hr = s_fallbackTexture->UnlockRect(0); }//endof if }
TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable)) { mTexture = NULL; mRenderTarget = NULL; // if the width or height is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation if (width > 0 && height > 0) { IDirect3DDevice9 *device = mRenderer->getDevice(); gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset); HRESULT result = device->CreateTexture(width, height, levels ? levels + mLodOffset : 0, getUsage(), mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); gl::error(GL_OUT_OF_MEMORY); } } initializeRenderTarget(); }
LXTextureRef LXTextureCreateWithData(uint32_t w, uint32_t h, LXPixelFormat pxFormat, uint8_t *buffer, size_t rowBytes, LXUInteger storageHint, LXError *outError) { const LXBool useClientStorage = (storageHint & kLXStorageHint_ClientStorage) ? YES : NO; const LXBool useAGPTexturing = (storageHint & kLXStorageHint_PreferDMAToCaching) ? YES : NO; if ( !buffer || rowBytes < 1) return NULL; HRESULT hRes; D3DFORMAT texFormat = LXD3DFormatFromLXPixelFormat(pxFormat); if (texFormat == 0) { LXPrintf("** %s -- invalid texture format (%i)\n", __func__, pxFormat); LXErrorSet(outError, 4802, "invalid texture format"); return NULL; } IDirect3DDevice9 *dxDev = LXPlatformGetSharedD3D9Device(); if ( !dxDev) { LXPrintf("** %s -- no d3d device set, can't create texture\n", __func__); LXErrorSet(outError, 4803, "no d3d device"); return NULL; } IDirect3DTexture9 *newTexture = NULL; hRes = dxDev->CreateTexture(w, h, 1, ((useClientStorage || useAGPTexturing) ? D3DUSAGE_DYNAMIC : D3DUSAGE_WRITEONLY), texFormat, (useClientStorage || useAGPTexturing) ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED, &newTexture, NULL); const char *errStr = NULL; switch (hRes) { case D3D_OK: break; case D3DERR_INVALIDCALL: errStr = "Invalid call"; break; case D3DERR_OUTOFVIDEOMEMORY: errStr = "Out of video memory"; break; case E_OUTOFMEMORY: errStr = "Out of system memory"; break; default: errStr = "unknown"; break; } if (errStr) { LXPrintf("** %s -- D3D error '%s' (%i * %i, pf %lu, cs %i, agp %i)\n", __func__, errStr, w, h, pxFormat, useClientStorage, useAGPTexturing); LXErrorSet(outError, 4810, "D3D error"); return NULL; } writeTextureData(newTexture, w, h, pxFormat, buffer, rowBytes); LXTextureRef newRef = LXTextureCreateWithD3DTextureAndLXSurface_(newTexture, w, h, pxFormat, NULL); if (newRef) { LXTextureDXImpl *imp = (LXTextureDXImpl *)newRef; imp->storageHint = storageHint; // it's safe to store the data pointer only if client storage was specified if (useClientStorage) { imp->buffer = buffer; imp->rowBytes = rowBytes; } } newTexture->Release(); return newRef; }
void TextureDX9::Bind() { IDirect3DDevice9* device = RendererDX9::GetInstance()->GetDevice(); D3DPOOL pool; if (GetUsage() == BU_TEXTURE) pool = D3DPOOL_MANAGED; else pool = D3DPOOL_DEFAULT; HRESULT hr; DWORD usageFlags; switch (GetTextureType()) { case TT_1D: hr = device->CreateTexture( GetWidth(), 1u, GetMipmapLevelCount(), BufferUsageDX9[m_eBufferUsage], TextureFormatDX9[m_eTexFormat], pool, (IDirect3DTexture9**)&m_pTexture, 0); break; case TT_2D: usageFlags = BufferUsageDX9[m_eBufferUsage]; if (m_eBufferUsage == BU_RENDERTAGET && m_bAutogenMipmaps == true) { // automatic mipmap generation for RTs usageFlags |= D3DUSAGE_AUTOGENMIPMAP; } hr = device->CreateTexture( GetWidth(), GetHeight(), m_bAutogenMipmaps ? 0 : GetMipmapLevelCount(), usageFlags, TextureFormatDX9[m_eTexFormat], pool, (IDirect3DTexture9**)&m_pTexture, 0); break; case TT_3D: hr = device->CreateVolumeTexture( GetWidth(), GetHeight(), GetDepth(), GetMipmapLevelCount(), BufferUsageDX9[m_eBufferUsage], TextureFormatDX9[m_eTexFormat], pool, (IDirect3DVolumeTexture9**)&m_pTexture, 0); break; case TT_CUBE: hr = device->CreateCubeTexture( GetWidth(), GetMipmapLevelCount(), BufferUsageDX9[m_eBufferUsage], TextureFormatDX9[m_eTexFormat], pool, (IDirect3DCubeTexture9**)&m_pTexture, 0); } assert(SUCCEEDED(hr)); switch (GetTextureType()) { case TT_1D: case TT_2D: case TT_3D: for (unsigned int mip = 0; mip < GetMipmapLevelCount(); mip++) { if (Lock(mip, BL_WRITE_ONLY)) { Update(); Unlock(); } else if (m_eBufferUsage != BU_RENDERTAGET && m_eBufferUsage != BU_DEPTHSTENCIL) assert(false); } break; case TT_CUBE: for (unsigned int face = 0; face < 6; face++) { for (unsigned int mip = 0; mip < GetMipmapLevelCount(); mip++) { if (Lock(face, mip, BL_WRITE_ONLY)) { Update(); Unlock(); } else assert(false); } } } }
void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) { IDirect3DDevice9 *device = mDisplay->getDevice(); if (device == NULL) { return; } // Evict all non-render target textures to system memory and release all resources // before reallocating them to free up as much video memory as possible. device->EvictManagedResources(); release(); D3DPRESENT_PARAMETERS presentParameters = {0}; HRESULT result; presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat; presentParameters.BackBufferCount = 1; presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat; presentParameters.EnableAutoDepthStencil = FALSE; presentParameters.Flags = 0; presentParameters.hDeviceWindow = getWindowHandle(); presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented presentParameters.PresentationInterval = mPresentInterval; presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; presentParameters.Windowed = TRUE; presentParameters.BackBufferWidth = backbufferWidth; presentParameters.BackBufferHeight = backbufferHeight; if (mWindow) { result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); } else { HANDLE *pShareHandle = NULL; if (mDisplay->isD3d9exDevice()) { pShareHandle = &mShareHandle; } result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET, presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); } if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); release(); return error(EGL_BAD_ALLOC); } result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType, presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); ERR("Could not create depthstencil surface for new swap chain: %08lX", result); release(); return error(EGL_BAD_ALLOC); } if (mWindow) { mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mRenderTarget); InvalidateRect(mWindow, NULL, FALSE); } else { mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget); } mWidth = presentParameters.BackBufferWidth; mHeight = presentParameters.BackBufferHeight; mPresentIntervalDirty = false; }
//---------------------------------------------------------------------------- PdrTexture2D::PdrTexture2D (Renderer* renderer, const Texture2D* texture) { IDirect3DDevice9* device = renderer->mData->mDevice; Texture::Format tdFormat = texture->GetFormat(); int numBytes = texture->GetNumTotalBytes(); int numLevels = texture->GetNumLevels(); char *srcData = texture->GetData(0); int numElement = 0; unsigned char* newSrc = 0; int newNumBytes = 0; D3DPOOL pool = D3DPOOL_MANAGED; int SrcBase = 0, newSrcBase = 0; D3DFORMAT format; if (texture->GetUsage() == Buffer::BU_TEXTURE) { pool = D3DPOOL_MANAGED; } else { pool = D3DPOOL_DEFAULT; } int charMax = 255; switch (tdFormat) { case Texture::TF_R8G8B8: numElement = numBytes/3; newNumBytes = numBytes + numElement; newSrc = new1<unsigned char>(newNumBytes); assertion(newSrc!=0, "new failed."); for (int i = 0; i < numElement; i++) { newSrc[newSrcBase ] = srcData[SrcBase ]; // B newSrc[newSrcBase + 1] = srcData[SrcBase + 1]; // G newSrc[newSrcBase + 2] = srcData[SrcBase + 2]; // R newSrc[newSrcBase + 3] = (unsigned char)charMax;// A newSrcBase += 4; SrcBase += 3; } format = D3DFMT_X8R8G8B8; break; default: format = gDX9TextureFormat[texture->GetFormat()]; break; } UINT texWidth = (UINT)texture->GetWidth(); UINT texHeight = (UINT)texture->GetHeight(); HRESULT hr = device->CreateTexture(texWidth, texHeight, (UINT)numLevels, gDX9BufferUsage[texture->GetUsage()], format, pool, &mTexture, 0); PX2_UNUSED(hr); assertion(hr == D3D_OK, "Failed to create 2D texture: %s\n", DXGetErrorString(hr)); if (pool == D3DPOOL_MANAGED) { if (tdFormat == Texture::TF_R8G8B8) { unsigned char *src1 = newSrc; int levelByte = 0; int lastWidth = 0; int lastHegiht = 0; for (int level = 0; level < numLevels; ++level) { int curWidth = texture->GetDimension(0, level); int curHegiht = texture->GetDimension(1, level); levelByte = 4*curWidth*curHegiht; char* data = (char*)Lock(level, Buffer::BL_WRITE_ONLY); memcpy(data, src1, levelByte); Unlock(level); src1 += levelByte; } delete1(newSrc); } else { for (int level = 0; level < numLevels; ++level) { void* data = Lock(level, Buffer::BL_WRITE_ONLY); memcpy(data, texture->GetData(level), texture->GetNumLevelBytes(level)); Unlock(level); } } } }
sge::d3d9::texture::d3d_texture_unique_ptr sge::d3d9::devicefuncs::create_texture( IDirect3DDevice9 &_device, sge::renderer::texture::planar_parameters const &_params, D3DFORMAT const _color_format, D3DPOOL const _pool, sge::d3d9::usage const _usage ) { IDirect3DTexture9 *ret( nullptr ); if( _device.CreateTexture( static_cast< UINT >( _params.size().w() ), static_cast< UINT >( _params.size().h() ), sge::d3d9::texture::mipmap::level_count( _params.mipmap() ), _usage.get() | sge::d3d9::texture::mipmap::usage( _params.mipmap() ).get(), _color_format, _pool, &ret, 0 ) != D3D_OK ) throw sge::renderer::exception( FCPPT_TEXT("CreateTexture() with size ") + fcppt::insert_to_fcppt_string( _params.size() ) + FCPPT_TEXT(" and color format ") + sge::image::color::format_to_string( _params.format().format() ) + FCPPT_TEXT(" failed!") ); return sge::d3d9::texture::d3d_texture_unique_ptr( ret ); }
bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) { IDirect3DDevice9 *device = mDisplay->getDevice(); if (device == NULL) { return false; } // Evict all non-render target textures to system memory and release all resources // before reallocating them to free up as much video memory as possible. device->EvictManagedResources(); release(); D3DPRESENT_PARAMETERS presentParameters = {0}; HRESULT result; bool useFlipEx = (LOWORD(GetVersion()) >= 0x61) && mDisplay->isD3d9ExDevice(); // FlipEx causes unseemly stretching when resizing windows AND when one // draws outside of the WM_PAINT callback. While this is seldom a problem in // single process applications, it is particuarly noticeable in multiprocess // applications. Therefore, if the creator process of our window is not in // the current process, disable use of FlipEx. DWORD windowPID; GetWindowThreadProcessId(mWindow, &windowPID); if(windowPID != GetCurrentProcessId()) useFlipEx = false; presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat; // We set BackBufferCount = 1 even when we use D3DSWAPEFFECT_FLIPEX. // We do this because DirectX docs are a bit vague whether to set this to 1 // or 2. The runtime seems to accept 1, so we speculate that either it is // forcing it to 2 without telling us, or better, doing something smart // behind the scenes knowing that we don't need more. presentParameters.BackBufferCount = 1; presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat; presentParameters.EnableAutoDepthStencil = FALSE; presentParameters.Flags = 0; presentParameters.hDeviceWindow = getWindowHandle(); presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented presentParameters.PresentationInterval = mPresentInterval; // Use flipEx on Win7 or greater. if(useFlipEx) presentParameters.SwapEffect = D3DSWAPEFFECT_FLIPEX; else presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; presentParameters.Windowed = TRUE; presentParameters.BackBufferWidth = backbufferWidth; presentParameters.BackBufferHeight = backbufferHeight; if (mWindow) { result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); } else { HANDLE *pShareHandle = NULL; if (mDisplay->isD3d9ExDevice()) { pShareHandle = &mShareHandle; } result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET, presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); } if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); release(); return error(EGL_BAD_ALLOC, false); } if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN) { result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType, presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL); } if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); ERR("Could not create depthstencil surface for new swap chain: %08lX", result); release(); return error(EGL_BAD_ALLOC, false); } if (mWindow) { mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mRenderTarget); InvalidateRect(mWindow, NULL, FALSE); } else { mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget); } mWidth = presentParameters.BackBufferWidth; mHeight = presentParameters.BackBufferHeight; mPresentIntervalDirty = false; return true; }
EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval) { IDirect3DDevice9 *device = mRenderer->getDevice(); if (device == NULL) { return EGL_BAD_ACCESS; } // Evict all non-render target textures to system memory and release all resources // before reallocating them to free up as much video memory as possible. device->EvictManagedResources(); HRESULT result; // Release specific resources to free up memory for the new render target, while the // old render target still exists for the purpose of preserving its contents. if (mSwapChain) { mSwapChain->Release(); mSwapChain = NULL; } if (mBackBuffer) { mBackBuffer->Release(); mBackBuffer = NULL; } if (mOffscreenTexture) { mOffscreenTexture->Release(); mOffscreenTexture = NULL; } if (mDepthStencil) { mDepthStencil->Release(); mDepthStencil = NULL; } HANDLE *pShareHandle = NULL; if (!mWindow && mRenderer->getShareHandleSupport()) { pShareHandle = &mShareHandle; } result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat), D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); if (FAILED(result)) { ERR("Could not create offscreen texture: %08lX", result); release(); if (d3d9::isDeviceLostError(result)) { return EGL_CONTEXT_LOST; } else { return EGL_BAD_ALLOC; } } IDirect3DSurface9 *oldRenderTarget = mRenderTarget; result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget); ASSERT(SUCCEEDED(result)); if (oldRenderTarget) { RECT rect = { 0, 0, mWidth, mHeight }; if (rect.right > static_cast<LONG>(backbufferWidth)) { rect.right = backbufferWidth; } if (rect.bottom > static_cast<LONG>(backbufferHeight)) { rect.bottom = backbufferHeight; } mRenderer->endScene(); result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE); ASSERT(SUCCEEDED(result)); oldRenderTarget->Release(); } if (mWindow) { D3DPRESENT_PARAMETERS presentParameters = {0}; presentParameters.AutoDepthStencilFormat = gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat); presentParameters.BackBufferCount = 1; presentParameters.BackBufferFormat = gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat); presentParameters.EnableAutoDepthStencil = FALSE; presentParameters.Flags = 0; presentParameters.hDeviceWindow = mWindow; presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented presentParameters.PresentationInterval = convertInterval(swapInterval); presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; presentParameters.Windowed = TRUE; presentParameters.BackBufferWidth = backbufferWidth; presentParameters.BackBufferHeight = backbufferHeight; // http://crbug.com/140239 // http://crbug.com/143434 // // Some AMD/Intel switchable systems / drivers appear to round swap chain surfaces to a multiple of 64 pixels in width // when using the integrated Intel. This rounds the width up rather than down. // // Some non-switchable AMD GPUs / drivers do not respect the source rectangle to Present. Therefore, when the vendor ID // is not Intel, the back buffer width must be exactly the same width as the window or horizontal scaling will occur. if (mRenderer->getAdapterVendor() == VENDOR_ID_INTEL) { presentParameters.BackBufferWidth = (presentParameters.BackBufferWidth + 63) / 64 * 64; } result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST); ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); release(); if (d3d9::isDeviceLostError(result)) { return EGL_CONTEXT_LOST; } else { return EGL_BAD_ALLOC; } } result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); ASSERT(SUCCEEDED(result)); InvalidateRect(mWindow, NULL, FALSE); } if (mDepthBufferFormat != GL_NONE) { result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight, gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat), D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL); ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); release(); if (d3d9::isDeviceLostError(result)) { return EGL_CONTEXT_LOST; } else { return EGL_BAD_ALLOC; } } } mWidth = backbufferWidth; mHeight = backbufferHeight; mSwapInterval = swapInterval; return EGL_SUCCESS; }
void Surface::resetSwapChain() { IDirect3DDevice9 *device = mDisplay->getDevice(); D3DPRESENT_PARAMETERS presentParameters = {0}; presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat; presentParameters.BackBufferCount = 1; presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat; presentParameters.EnableAutoDepthStencil = FALSE; presentParameters.Flags = 0; presentParameters.hDeviceWindow = getWindowHandle(); presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented presentParameters.PresentationInterval = Display::convertInterval(mConfig->mMinSwapInterval); presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; presentParameters.Windowed = TRUE; RECT windowRect; if (!GetClientRect(getWindowHandle(), &windowRect)) { ASSERT(false); return; } presentParameters.BackBufferWidth = windowRect.right - windowRect.left; presentParameters.BackBufferHeight = windowRect.bottom - windowRect.top; IDirect3DSwapChain9 *swapChain = NULL; HRESULT result = device->CreateAdditionalSwapChain(&presentParameters, &swapChain); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); ERR("Could not create additional swap chains: %08lX", result); return error(EGL_BAD_ALLOC); } IDirect3DSurface9 *depthStencilSurface = NULL; result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType, presentParameters.MultiSampleQuality, FALSE, &depthStencilSurface, NULL); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); swapChain->Release(); ERR("Could not create depthstencil surface for new swap chain: %08lX", result); return error(EGL_BAD_ALLOC); } IDirect3DSurface9 *renderTarget = NULL; result = device->CreateRenderTarget(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, presentParameters.BackBufferFormat, presentParameters.MultiSampleType, presentParameters.MultiSampleQuality, FALSE, &renderTarget, NULL); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); swapChain->Release(); depthStencilSurface->Release(); ERR("Could not create render target surface for new swap chain: %08lX", result); return error(EGL_BAD_ALLOC); } ASSERT(SUCCEEDED(result)); IDirect3DTexture9 *flipTexture = NULL; result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET, presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &flipTexture, NULL); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); swapChain->Release(); depthStencilSurface->Release(); renderTarget->Release(); ERR("Could not create flip texture for new swap chain: %08lX", result); return error(EGL_BAD_ALLOC); } IDirect3DSurface9 *backBuffer = NULL; swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backBuffer); if (mSwapChain) mSwapChain->Release(); if (mDepthStencil) mDepthStencil->Release(); if (mBackBuffer) mBackBuffer->Release(); if (mRenderTarget) mRenderTarget->Release(); if (mFlipTexture) mFlipTexture->Release(); mWidth = presentParameters.BackBufferWidth; mHeight = presentParameters.BackBufferHeight; mSwapChain = swapChain; mDepthStencil = depthStencilSurface; mBackBuffer = backBuffer; mRenderTarget = renderTarget; mFlipTexture = flipTexture; // The flip state block recorded mFlipTexture so it is now invalid. releaseRecordedState(device); }