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));
	}
}
Beispiel #6
0
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;
}
Beispiel #7
0
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();
        }
    }
}
Beispiel #9
0
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);
}
Beispiel #10
0
//----------------------------------------------------------------------------
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);
    }
}
Beispiel #11
0
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;
}
Beispiel #12
0
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();
}
Beispiel #15
0
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);
			}
		}
	}
}
Beispiel #17
0
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);
			}
		}
	}
}
Beispiel #19
0
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
		);
}
Beispiel #20
0
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;
}
Beispiel #21
0
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;
}
Beispiel #22
0
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);
}