Jump to content
  • Advertisement
Sign in to follow this  
CarlML

Strange slowdown when model(s) goes off screen

This topic is 579 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Got a pretty strange issue, perhaps someone recognizes it.

 

I have a model that I created the vertex and index buffers for and that I render using DrawIndexedPrimitive, after that I render a bunch of models that are loaded from .x files. Whatever I render after the first model gets really slow when all the models goes off screen, the fps goes from 150 to 20. What could be causing this?

 

If I render the first model after the "bunch of other models" the issue goes away but if I render another bunch of models after that the issue is seen again.

 

 

Share this post


Link to post
Share on other sites
Advertisement

What does your debugger and graphics debugger tell you?

I'm figuring out how to use PIX directx debugging tool now (I'm using directx 9), comparing the calls of different frames, but have not found anything useful so far. Any tips on what to look for?

Share this post


Link to post
Share on other sites

Any tips on what to look for?
 

 

It should show some amount of timing information indicating whether the slowdown is on the GPU/shader or in the driver. You'll possibly have to use a CPU-side profiler as well and correlate date to see some types of problems.

 

If you have DX warning levels turned up, you should also see anything about misuse of the APIs that could lead to issues.

 

I'm not sure I fully understand your problem; it sounds super weird. At this point I'd just be digging for every piece of information I could get my hands on and looking for anything that seems remotely abnormal. 

Share this post


Link to post
Share on other sites

According to PIX, in the frames where it is slow there are thousands of more calls to:

 

IDirect3DQuery9::GetData(NULL, 0x00000000, 0x00000001)

 

The rest seems to be the same between the fast and slow frames.

 

 

Edit: This was because I was flushing commands between each render call for profiling purposes. When I remove all such calls all the GetData commands go away but the slowdown issue remains. The search continues...

Edited by CarlML

Share this post


Link to post
Share on other sites

How are you storing and updating your objects?

The object that seems to be causing the issue is setup like this:

 

A model is loaded form an .x file, then x number of instances of that model is stored in a batch model.

 

The class basically looks like this:

class Model
{
public:
    LPDIRECT3DVERTEXBUFFER9 vertexBuffer;
    LPDIRECT3DINDEXBUFFER9 indexBuffer;
    DWORD numBytesPerVertex;
    int numVerts;
    int numFaces;

    LPDIRECT3DTEXTURE9 diffuseTexture;
    LPDIRECT3DTEXTURE9 normalTexture;

    //Some functions here
};

The .x model mesh is loaded like this:

LPD3DXBUFFER materialBuffer;
D3DXLoadMeshFromX(meshFileName, D3DXMESH_SYSTEMMEM, d3d.device, NULL, &materialBuffer, NULL, &numSubsets, &mesh);

The vertex and index buffers are intitialized like this:

numBytesPerVertex = mesh->GetNumBytesPerVertex();
int numModelVerts = mesh->GetNumVertices();
int numModelFaces = mesh->GetNumFaces();
numVerts = numModelVerts * numInstances;
numFaces = numModelFaces * numInstances;

//Create vertex buffer
d3d.device->CreateVertexBuffer(numVerts * numBytesPerVertex, D3DUSAGE_WRITEONLY, FVF_MESHVERTEX, D3DPOOL_DEFAULT, &vertexBuffer, NULL));

//Fill vertex buffer
MeshVertex* vertBuf = NULL;
vertexBuffer->Lock(0, 0, (void**)&vertBuf, 0);

MeshVertex* modelVertBuf = NULL;
mesh->LockVertexBuffer(0, (VOID**)&modelVertBuf);

int currentVertex = 0;
for(int i=0; i < numInstances; i++)
{
    for(int d=0; d < numModelVerts; d++)
    {
        vertBuf[currentVertex] = modelVertBuf[d];
        currentVertex++;
    }
}
mesh->UnlockVertexBuffer();
vertexBuffer->Unlock();


//Create index buffer
d3d.device->CreateIndexBuffer(numFaces * 3 * sizeof(short), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &indexBuffer, NULL);


//Fill in index buffer
int currentStartIndex = 0;
int currentIndexIndex = 0;
int numIndices = numModelFaces * 3;

short* indexBuf = NULL;
indexBuffer->Lock(0, 0, (void**)&indexBuf, 0);

short* modelIndeXBuf = NULL;
mesh->LockIndexBuffer(0, (void**)&modelIndeXBuf);
for(int i=0; i < numInstances; i++)
{
    for(int d=0; d < numIndices; d++)
    {
        indexBuf[currentIndexIndex] = modelIndeXBuf[d] + currentStartIndex;
        currentIndexIndex++;
    }
    currentStartIndex += numModelVerts;
}

mesh->UnlockIndexBuffer();
indexBuffer->Unlock();

The vertex declaration looks like this:

#define FVF_MESHVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEXCOORDSIZE3(2) | D3DFVF_TEXCOORDSIZE2(3))

struct MeshVertex
{
    D3DXVECTOR3 pos;
    D3DXVECTOR3 normal;
    D3DXVECTOR3 tangent;
    D3DXVECTOR3 binormal;
    D3DXVECTOR2 tex;
};

const D3DVERTEXELEMENT9 vertexDecl[] =
{
    { 0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
    { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0 },
    { 0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0 },
    { 0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 },
    { 0, 48, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
    D3DDECL_END()
};

The model is rendered like this:

d3d.effectScene->SetTexture( "diffuseMap", diffuseTexture );
d3d.effectScene->SetTexture( "normalMap", normalTexture );

D3DXMATRIX worldMat;
D3DXMatrixIdentity(&worldMat);

d3d.effectScene->SetMatrix( "worldMatrix", &worldMat);
D3DXMATRIX worldViewProjMatrix = worldMat * camera.viewMatrix * camera.projMatrix;
d3d.effectScene->SetMatrix( "worldViewProjMatrix", &worldViewProjMatrix);
d3d.effectScene->CommitChanges();

d3d.device->SetVertexDeclaration(d3d.vertDecl);
d3d.device->SetStreamSource(0, vertexBuffer, 0, numBytesPerVertex);
d3d.device->SetIndices(indexBuffer);

d3d.device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, numVerts, 0, numFaces);

 

Edited by CarlML

Share this post


Link to post
Share on other sites

It has something to do with clipping because if I move the camera back until part of an object (or sometimes all of the objects) goes outside the view frustum the slowdown happens (as well as if I move to the side). I'm guessing the vertex buffer is not setup correctly for clipping or something like that. If you see an issue with how it is setup above let me know.

 

 

The slowdown happens in the GPU during the Present() call. My vertex and pixel shaders for testing are pretty simple though.

 

 

PIX shows the same function calls for the fast and slow frames, although as I pointed out, if I use:

 

pEvent->Issue(D3DISSUE_END); while(S_FALSE == pEvent->GetData( NULL, 0, D3DGETDATA_FLUSH ));

 

...before the Present() PIX shows that a lot more of GetData calls are made in the slow frames than in the fast frames.

Edited by CarlML

Share this post


Link to post
Share on other sites

The issue goes away if I set:

device->SetRenderState(D3DRS_CLIPPING, FALSE);

That is probably not the solution I want since it probably just hides the bug. It at least shows that the issue is related to clipping.

Share this post


Link to post
Share on other sites

I doubt it has to do with clipping for many reasons including if it was clipping the order of draws wouldn't matter.  Stick with profiling to give you hints as to what is happening.

 

edit - also what videocard are you running on?

Edited by Infinisearch

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!