Click here to Skip to main content
15,896,455 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
GeneralRe: linkage error Pin
«_Superman_»18-Aug-09 0:13
professional«_Superman_»18-Aug-09 0:13 
GeneralRe: linkage error [modified] Pin
MozhdehQeraati18-Aug-09 0:29
MozhdehQeraati18-Aug-09 0:29 
AnswerRe: linkage error Pin
KarstenK18-Aug-09 3:47
mveKarstenK18-Aug-09 3:47 
GeneralRe: linkage error Pin
MozhdehQeraati19-Aug-09 3:07
MozhdehQeraati19-Aug-09 3:07 
GeneralRe: linkage error Pin
KarstenK19-Aug-09 3:21
mveKarstenK19-Aug-09 3:21 
QuestionExchange server news groups on Microsoft Pin
tom groezer17-Aug-09 23:13
tom groezer17-Aug-09 23:13 
AnswerRe: Exchange server news groups on Microsoft Pin
Rajesh R Subramanian17-Aug-09 23:22
professionalRajesh R Subramanian17-Aug-09 23:22 
Question[D3DM] Memory & textures [modified] Pin
MMoi17-Aug-09 21:57
MMoi17-Aug-09 21:57 
Hi all,

this is my first post on the Code Project forums, since I'm using one of the tool posted here, I thought I should ask where the knowledge lies in order to solve my problem Wink | ;)

the problem
In my 3d engine, each texture creation reserves 3 times the space it should need in memory.

Hypotheses
- 3d engine based on Loulou's YesEngine (here, in French)
- Runs on Windows Mobile 6.1 with Direct 3d Mobile (D3D subset)
- Windows Mobile is much restrictive concerning virtual memory (32MB against desktop's 2GB), so the heap is full pretty fast.

1st step: texture creation
IRscTextureBase* GDirect3DMRenderer::CreateTexture(const TVector2I& Size, TPixelFormat Format, unsigned long Flags) const
{
    // mip level detection and auto creation detection
    bool HasMipmaps  = (Flags & TEX_NOMIPMAP) != 0;

    bool AutoMipmaps = false;       // no auto mipmaping on D3DM
    unsigned long Usage = m_SurfCaps_Texture;       // let the texture be locked

    // create texture
    LPDIRECT3DMOBILETEXTURE Texture = NULL;
    HRESULT hr;
    if ( FAILED ( hr = D3DMXCreateTexture(m_Device, Size.x, Size.y, 0, Usage, CD3DMEnum::Get(Format), m_SurfCaps_Pool, &Texture) ) )
        throw CD3DMException(_T("D3DXCreateTexture"), _T("CreateTexture"));

    return new CD3DMTexture(Size, Format, HasMipmaps, AutoMipmaps, Usage, Texture);
}


D3DMXCreateTexture reserves memory space (ok), but new CD3DMTexture (simple object to encapsulate my D3DM texture) does the same ! We exit the function with 2 spaces reserved in memory instead of one.

reference :
class CD3DMTexture : public IRscTextureBase
    {
    public :
        CD3DMTexture(const TVector2I& Size, TPixelFormat Format, bool HasMipmaps, bool AutoMipmaps, unsigned long Usage, IDirect3DMobileTexture* Texture);

		// GET D3D TEXTURE
		IDirect3DMobileTexture* GetDxTexture() const;

    private :
		// UPDATE PIXELS
        virtual void Update(const CRectangle& Rect);

        // COPY PIXELS TO LOCKED SURFACE
        void UpdateSurface(const D3DMLOCKED_RECT& LockedRect, const CRectangle& Rect);

        // DATA
		CSmartPtr<IDirect3DMobileTexture , CResourceCOM > m_Texture;		// D3D texture pointer
		unsigned long m_Usage;
    };


2d step : texture update

A lot of devices (let's say Omnia) don't allow texture locking, thus we're forced to use surface locking, and then copy pixels from one surface to another... as follows :

void CD3DMTexture::Update(const CRectangle& Rect)
{
    Assert(CRectangle(0, 0, m_Size.x, m_Size.y).Intersects(Rect) == INT_IN);

	if (m_Format == m_Data.GetFormat() && (m_Usage & D3DMUSAGE_LOCKABLE) )		// if pixel format is the same, simple copy (if texture lockable)
    {
        // lock texture
        D3DMLOCKED_RECT LockedRect;
        RECT Lock = {Rect.Left(), Rect.Top(), Rect.Right(), Rect.Bottom()};
        m_Texture->LockRect(0, &LockedRect, &Lock, 0);	

        // copy pixels
        UpdateSurface(LockedRect, Rect);

        // unlock texture
        m_Texture->UnlockRect(0);
    }
    else
    {
        // get device
		CSmartPtr<IDirect3DMobileDevice, CResourceCOM> Device;
        m_Texture->GetDevice(&GetPtr(Device));

        // create texture in memory
		CSmartPtr<IDirect3DMobileSurface, CResourceCOM> Src;
		HRESULT res = Device->CreateImageSurface(Rect.Width(), Rect.Height(), CD3DMEnum::Get(m_Data.GetFormat()), &GetPtr(Src));		
		if (FAILED(res))		// CreateOffscreenPlainSurface not available in D3DM 
		{
            throw CD3DMException(_T("CreateImageSurface"), _T("CD3DMTexture::Update"));
		}

        // lock temp texture
        D3DMLOCKED_RECT LockedRect;
        Src->LockRect(&LockedRect, NULL, 0);

        // copy pixels
        UpdateSurface(LockedRect, Rect);

        // unlock texture
        Src->UnlockRect();
        // get 0 level surface of the texture
		CSmartPtr<IDirect3DMobileSurface, CResourceCOM> Dest;
        m_Texture->GetSurfaceLevel(0, &GetPtr(Dest));
		
        // copy to destination surface
        RECT DestRect = {Rect.Left(), Rect.Top(), Rect.Right(), Rect.Bottom()};
        if (FAILED(D3DMXLoadSurfaceFromSurface(Dest, NULL, &DestRect, Src, NULL, NULL, D3DMX_DEFAULT, 0)))
            throw CD3DMException(_T("D3DXLoadSurfaceFromSurface"), _T("CD3DMTexture::Update"));			

		m_Texture->GetSurfaceLevel(0, &GetPtr(Dest));
		IDirect3DMobileSurface_Release(GetPtr(Dest));
    }
}


Src surface reserves the space needed during CreateImageSurface, then free it when we exit the brackets where it's defined (thanks smart pointer).
However, Dest does also a reservation about the same size during D3DMXLoadSurfaceFromSurface... but doesn't release it when the smart pointer is freed !

Conclusion
We have 3 times the needed space reserved by a texture, that other components of the program won't be able to use. With 32MB of virtual memory, I guess you already figured how painful it may be !

There shall be some stuff I messed up, or maybe is it due to the implementation of the YesEngine (encapsulating the D3D texture for instance ?) creating some conflict with D3DM data types... anyway...

Help !

Thanks for your help, may you be WM developer or not (it's after all only a subset of Windows API and DirectX Wink | ;) )


ps: see here for more information about the well named "WM virtual memory monster" (and thanks a lot to it's author)
http://www.codeproject.com/KB/mobile/VirtualMemory.aspx

modified on Tuesday, August 18, 2009 4:46 AM

AnswerRe: [D3DM] Memory & textures Pin
Cedric Moonen17-Aug-09 22:56
Cedric Moonen17-Aug-09 22:56 
GeneralRe: [D3DM] Memory & textures Pin
MMoi17-Aug-09 23:14
MMoi17-Aug-09 23:14 
AnswerRe: [D3DM] Memory & textures Pin
MMoi19-Aug-09 15:10
MMoi19-Aug-09 15:10 
Questionthumbnails are not displayed if another window is opened on Dialog box. Pin
VCProgrammer17-Aug-09 19:26
VCProgrammer17-Aug-09 19:26 
QuestionOther option in place of Sleep. Pin
Le@rner17-Aug-09 18:16
Le@rner17-Aug-09 18:16 
AnswerRe: Other option in place of Sleep. Pin
Adam Roderick J17-Aug-09 19:44
Adam Roderick J17-Aug-09 19:44 
AnswerRe: Other option in place of Sleep. Pin
«_Superman_»17-Aug-09 20:08
professional«_Superman_»17-Aug-09 20:08 
AnswerRe: Other option in place of Sleep. Pin
Rajesh R Subramanian17-Aug-09 20:08
professionalRajesh R Subramanian17-Aug-09 20:08 
AnswerRe: Other option in place of Sleep. Pin
CPallini18-Aug-09 0:01
mveCPallini18-Aug-09 0:01 
AnswerRe: Other option in place of Sleep. Pin
David Crow18-Aug-09 3:15
David Crow18-Aug-09 3:15 
AnswerRe: Other option in place of Sleep. Pin
Joe Woodbury18-Aug-09 11:20
professionalJoe Woodbury18-Aug-09 11:20 
AnswerRe: Other option in place of Sleep. Pin
KarstenK19-Aug-09 3:23
mveKarstenK19-Aug-09 3:23 
QuestionWhen press enter over ListCtrl OK button click event called. Pin
Le@rner17-Aug-09 18:14
Le@rner17-Aug-09 18:14 
AnswerRe: When press enter over ListCtrl OK button click event called. Pin
Code-o-mat17-Aug-09 21:54
Code-o-mat17-Aug-09 21:54 
QuestionAccess to Locigal Drives under Vista Pin
Bram van Kampen17-Aug-09 13:56
Bram van Kampen17-Aug-09 13:56 
AnswerRe: Access to Locigal Drives under Vista Pin
Michael Dunn17-Aug-09 15:06
sitebuilderMichael Dunn17-Aug-09 15:06 
GeneralRe: Access to Locigal Drives under Vista Pin
Bram van Kampen18-Aug-09 11:01
Bram van Kampen18-Aug-09 11:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.