Windows has triggered a breakpoint,error at SetFVF()

Started by
13 comments, last by 21st Century Moose 11 years, 11 months ago
I get the message




Windows has triggered a breakpoint in D3D.exe.

This may be due to a corruption of the heap, which indicates a bug in D3D.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while D3D.exe has focus.

The output window may have more diagnostic information.[/quote]

it says the error is right here at the bold line:



void Terrain::Render()
{
m_d3dDevice->SetMaterial( &m_material );
m_d3dDevice->SetTexture(0,NULL);
m_d3dDevice->SetStreamSource( 0, m_vb,0, sizeof(CUSTOMVERTEX) );
m_d3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
m_d3dDevice->SetIndices( m_ib );

m_d3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,0,0,CHUNK_VERTICES,0,CHUNK_PRIMITIVES);
}


I've been banging my head and I can't seem to understand what the problem could be.Here are the other methods,but as far as I know they work without errors:



void Terrain::CreateMaterial(float r,float g,float b,float a)
{
ZeroMemory( &m_material, sizeof(D3DMATERIAL9) );
m_material.Diffuse.r = m_material.Ambient.r = r;
m_material.Diffuse.g = m_material.Ambient.g = g;
m_material.Diffuse.b = m_material.Ambient.b = b;
m_material.Diffuse.a = m_material.Ambient.a = a;
}

void Terrain::Update()
{
int count=0;
int vIndex=0;
HRESULT hr=m_d3dDevice->CreateVertexBuffer( CHUNK_VERTICES*sizeof(CUSTOMVERTEX),D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX,D3DPOOL_MANAGED, &m_vb, NULL );

hr=m_d3dDevice->CreateIndexBuffer(sizeof(short)*CHUNK_PRIMITIVES*3,D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_ib, NULL);

hr=m_vb->Lock( 0, 0, (void**)&pVertices, 0 );
hr=m_ib->Lock( 0, 0, (void**)&indices, 0 );

for(int i=0;i<CHUNK_HEIGHT+1;i++)
{
for(int n=0;n<CHUNK_WIDTH+1;n++)
{
pVertices->p.x = n;
pVertices->p.y = i;
pVertices->p.z = 0;
pVertices->n.x = n;
pVertices->n.y = i;
pVertices->n.z = 0;
pVertices->tu = 0;
pVertices->tv = 0;

indices[count++]=vIndex;
indices[count++]=vIndex+n;
indices[count++]=vIndex+n+1;

indices[count++]=vIndex;
indices[count++]=vIndex+n+1;
indices[count++]=vIndex+1;

vIndex++;
}
vIndex++;
}

m_vb->Unlock();
m_ib->Unlock();

}



and as for the custom vertex:



#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 )
#define CHUNK_HEIGHT 64
#define CHUNK_WIDTH 64

#define CHUNK_VERTICES 4225
#define CHUNK_PRIMITIVES 8192

struct CUSTOMVERTEX
{
D3DXVECTOR3 p;
D3DXVECTOR3 n;
float tu,tv;
};
at the top of my code,and I don't think any of them are faulty either
Advertisement
That error message means that at some point previous to that line of code the heap has been trashed.

Firstly, you appear to be writing data to the same vertex over and over again, which shouldn't cause any harm but it looks like a bug.

What I'd suggest doing is adding assert( _CrtCheckMemory( ) ); tests backwards from the point of the crash. That should let you work out which line of code makes that assert trigger.

That error message means that at some point previous to that line of code the heap has been trashed.

Firstly, you appear to be writing data to the same vertex over and over again, which shouldn't cause any harm but it looks like a bug.

What I'd suggest doing is adding assert( _CrtCheckMemory( ) ); tests backwards from the point of the crash. That should let you work out which line of code makes that assert trigger.

That error message means that at some point previous to that line of code the heap has been trashed.

Firstly, you appear to be writing data to the same vertex over and over again, which shouldn't cause any harm but it looks like a bug.

What I'd suggest doing is adding assert( _CrtCheckMemory( ) ); tests backwards from the point of the crash. That should let you work out which line of code makes that assert trigger.


yeah,it's the m_d3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); that's giving an error,any idea why this might happen?I passed a proper FVF argument that matches my CUSTOMVERTEX struct
Your problem lies in this

#define D3DFVF_CUSTOMVERTEX(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 )

This is not a properly defined FVF.

SetFVF takes a DWORD as it's parameter not a define.

//From the DX SDK documentation
HRESULT SetFVF(
[in] DWORD FVF
);

And if you would look at the examples they use in the documentation you see that they all use "const DWORD" variables to define the custom vertex format.
The better way of doing this is to use a vertexdeclaration, which will allow you to use shaders properly as well and will make the switch from DX9 to higher much easier to achieve as the fixed function pipeline is dead.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

What happens if you put assert( _CrtCheckMemory( ) ); right before the SetFVF() call?

You'll need to #include <crtdbg.h> and #include <assert.h> to get that to compile.

Your problem lies in this

#define D3DFVF_CUSTOMVERTEX(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 )

This is not a properly defined FVF.

SetFVF takes a DWORD as it's parameter not a define.

//From the DX SDK documentation
HRESULT SetFVF(
[in] DWORD FVF
);

And if you would look at the examples they use in the documentation you see that they all use "const DWORD" variables to define the custom vertex format.
The better way of doing this is to use a vertexdeclaration, which will allow you to use shaders properly as well and will make the switch from DX9 to higher much easier to achieve as the fixed function pipeline is dead.


I changed it to const DWORD D3DFVF_CUSTOMVERTEX = (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1);
but it still gives the same error.I actualy used #define before,because that's how I saw it in msdn.( http://msdn.microsof...9(v=vs.85).aspx )My CUSTOMVERTEX pretty much matches the FVF,doesn't it?



struct CUSTOMVERTEX
{
D3DXVECTOR3 p; //D3DFVF_XYZ
D3DXVECTOR3 n; //D3DFVF_NORMAL
float tu,tv; //D3DFVF_TEX1
};



[background=rgb(250, 251, 252)]What happens if you put assert( [/background]


_CrtCheckMemory( )



[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

[background=rgb(250, 251, 252)]); right before the SetFVF() call?[/background][/font]




I attached an image of the result.

The second square of code(where the error occurs in the green code) is in mlock.c
[attachment=8553:error.png]
I also used windows symbols to get a more detailed stack heap,but I can't really figure out why setting a new vertex declaration corrupts the heap.
[attachment=8558:Call Stack.png]
You need to use another macro in your FVF as well that tells the DX9 runtime how many tex coords to expect. You have to use this macro(texcoordSizeN) as well I think

#define Description D3DFVF_TEX0 - D3DFVF_TEX8 Number of texture coordinate sets for this vertex. The actual values for these flags are not sequential. D3DFVF_TEXCOORDSIZEN(coordIndex) Define a texture coordinate data set. n indicates the dimension of the texture coordinates. coordIndex indicates texture coordinate index number. See D3DFVF_TEXCOORDSIZEN and Texture coordinates and Texture Stages.
[/quote]
It's been a really long time since I have done anyting with the FF.

Basically the D3DFVF_TEXn flags only define how many texture cooridnate sets the runtime expects, the TexcoordSizeN flag tells the runtime the size of these texture coordinate streams. And it might be that you need to tell the runtime about this as well.

With VertexDeclarations, which you can mix with FF, this is a bit more explicit and clearer to the reader that you specify the size of the things as well. See this for a translation between FVF->VertexDecalaration and this for an explanation of how the shader engine sees the FVF codes.

And seeing that callstack your runtime is converting to the shader pipeline in D3D9 anyways and probably because the TexCoordSizeN flag isn't present it is failing to create the correct VertexDeclaration. If you run the D3D9 runtime on a DX10 or greater card the runtime will convert all Fixed Function calls to shader calls on the fly, and thats exactly what that callstack is telling you with the line "CFVFToDecl::GetDeclaration" and "CVertexDeclaration::Create" this must be reading from some address it isn't allowed to and hence the crash.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

Have you tried enabling the D3D Debug Runtime? It usually gives a lot of clues when something fails with D3D.

You need to use another macro in your FVF as well that tells the DX9 runtime how many tex coords to expect.[/quote]

The default number of texcoords in FVF is 2 so this is not the problem here. But I agree that vertex declarations are the way to go.

Have you tried enabling the D3D Debug Runtime? It usually gives a lot of clues when something fails with D3D.

You need to use another macro in your FVF as well that tells the DX9 runtime how many tex coords to expect.


The default number of texcoords in FVF is 2 so this is not the problem here. But I agree that vertex declarations are the way to go.
[/quote]

Have you tried enabling the D3D Debug Runtime? It usually gives a lot of clues when something fails with D3D.

You need to use another macro in your FVF as well that tells the DX9 runtime how many tex coords to expect.


The default number of texcoords in FVF is 2 so this is not the problem here. But I agree that vertex declarations are the way to go.
[/quote]

Yeah I still haven't implemented shaders in my engine,just working on models and terrain right now,so for now I'm using just SetFVF(),could the problem be in some DLL?I checked everything in the source,the D3DDevice is initialized,the FVF is properly declared and the vertex/index buffers create and lock/unlock without a problem.
Could you provide us with the output window error when this happens, even if it is just a access violation. These errors can tell you quite a bit of whats gone wrong. And as Froop suggests turn the debug runtime on.
The error is happening on a memory allocation from just looking at your callstack, the address of that location would be interesting to see as that could be pointing at 0 or some other memory location thats not allowed. So please could you give us the output window text as well, which shows the error.

Also nearly every D3D call returns a HRESULT, inspect what that result is on all calls that return one, if it is not D3D_OK use the error tool in the SDK folder to figure out wha the error means. When running with the debug runtime the information it spits out and the return codes should point you into the direction of the problem.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

This topic is closed to new replies.

Advertisement