"Attempted to read or write protected memory" on DrawIndexed()

Started by
11 comments, last by Narf the Mouse 11 years, 8 months ago
I've looked at tutorials in Google, examined my buffers and pointers, and I can't find what I'm doing wrong to get this error. I don't even have a clue what's actually causing it. So - Help, please, thanks.

Drawing code:

graphicsDevice.device.ImmediateContext.Rasterizer.State = SlimDX.Direct3D11.RasterizerState.FromDescription(
graphicsDevice.device,
new SlimDX.Direct3D11.RasterizerStateDescription( )
{
CullMode = SlimDX.Direct3D11.CullMode.Back,
DepthBias = 0,
DepthBiasClamp = 0,
FillMode = SlimDX.Direct3D11.FillMode.Solid,
IsAntialiasedLineEnabled = true,
IsDepthClipEnabled = true,
IsFrontCounterclockwise = false,
IsMultisampleEnabled = false,
IsScissorEnabled = false,
SlopeScaledDepthBias = 0
} );
graphicsDevice.device.ImmediateContext.InputAssembler.PrimitiveTopology = SlimDX.Direct3D11.PrimitiveTopology.TriangleList ;
graphicsDevice.device.ImmediateContext.InputAssembler.SetIndexBuffer( indexBuffer.Indices, indexBuffer.Format, indexBuffer.Offset );
SlimDX.Direct3D11.InputLayout layout;
graphicsDevice.device.ImmediateContext.InputAssembler.InputLayout =
layout =
new SlimDX.Direct3D11.InputLayout(
graphicsDevice.device,
graphicsDevice.defaultEffect.Signature,
vertexBuffer.InputElements );
graphicsDevice.device.ImmediateContext.InputAssembler.SetVertexBuffers( 0, vertexBuffer.BufferBinding );
graphicsDevice.device.ImmediateContext.DrawIndexed( indexBuffer.IndexCount, indexBuffer.StartIndexLocation, vertexBuffer.BaseVertexLocation );
layout.Dispose( );
graphicsDevice.defaultEffect.EndPass( );


Vertex buffer class construction:

this.graphicsDevice = graphicsDevice;
var buffer =
new SlimDX.Direct3D11.Buffer(
graphicsDevice.Device,
streamSource,
(int)streamSource.Length,
SlimDX.Direct3D11.ResourceUsage.Default,
SlimDX.Direct3D11.BindFlags.VertexBuffer,
SlimDX.Direct3D11.CpuAccessFlags.None,
SlimDX.Direct3D11.ResourceOptionFlags.None,
0 );
BufferBinding = new SlimDX.Direct3D11.VertexBufferBinding( buffer, vertexStride, 0 );
streamSource.Position = 0;
this.InputElements = GetInputElements( vertexDataInfo );
BaseVertexLocation = 0;


Index buffer class construction:

this.graphicsDeviceDirectX11 = graphicsDeviceDirectX9;
Format = ( indexStride == 2 ? SlimDX.DXGI.Format.R16_UInt : SlimDX.DXGI.Format.R32_UInt );
Offset = 0;
this.Indices = new SlimDX.Direct3D11.Buffer(
graphicsDeviceDirectX9.Device,
streamSource,
(int)streamSource.Length,
SlimDX.Direct3D11.ResourceUsage.Default,
SlimDX.Direct3D11.BindFlags.IndexBuffer,
SlimDX.Direct3D11.CpuAccessFlags.None,
SlimDX.Direct3D11.ResourceOptionFlags.None,
0 );
DisposableManager.Singleton.Register( this.Indices );
streamSource.Position = 0;

IndexCount = (int)streamSource.Length / indexStride;
StartIndexLocation = 0;


Edit: And in further adventures with the forum software, control-V doesn't work with blank spaces, so formatting code for the forum is a lot slower.
Advertisement
Identify where the problem comes from first, does the issue still occur if you use DrawPrimitives instead of DrawIndexedPrimitives without the index buffer? Doesn't matter if it's drawing meaningless crap, but does it crash? If not, the issue comes from the index buffer, if it does, then it comes from either the vertex buffer or your drawing code. It's important to pinpoint where the error comes from exactly.

Then, try and only draw part of the buffer, this might reveal if you are trying to draw more than you have (because of a logic or arithmetic error on your part, perhaps you got primitives and vertices mixed up or something). Etc... Also try listening to what the DirectX debug output has to tell you, it may have some information on why it is crashing (google how to get the debug output into your IDE's console window or just use DebugView otherwise).

[size=2]Also, don't reinitialize your device's input assembler and rasterizer state every frame sad.png

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”


Identify where the problem comes from first, does the issue still occur if you use DrawPrimitives instead of DrawIndexedPrimitives without the index buffer? Doesn't matter if it's drawing meaningless crap, but does it crash? If not, the issue comes from the index buffer, if it does, then it comes from either the vertex buffer or your drawing code. It's important to pinpoint where the error comes from exactly.

Then, try and only draw part of the buffer, this might reveal if you are trying to draw more than you have (because of a logic or arithmetic error on your part, perhaps you got primitives and vertices mixed up or something). Etc... Also try listening to what the DirectX debug output has to tell you, it may have some information on why it is crashing (google how to get the debug output into your IDE's console window or just use DebugView otherwise).

[size=2]Also, don't reinitialize your device's input assembler and rasterizer state every frame sad.png

Good points. Think I was too focused on the immediate, there.

I know about the rasterizer part; this is just a hack until I get the triangles up on the screen, at which point it will be eradicated. Lets me fiddle with it directly.

But...Can you explain the input assembler part?

But...Can you explain the input assembler part?

You're redefining the vertex/index buffers, topology, input layout - they persist across frames, and I think you only have one vertex/index buffer pair at the moment, so it's a waste to reset them every frame (not that it makes much of a performance difference anyway). Anyway that was just a remark. What have you found with more proactive debugging?

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”


[quote name='Narf the Mouse' timestamp='1343085274' post='4962396']
But...Can you explain the input assembler part?

You're redefining the vertex/index buffers, topology, input layout - they persist across frames, and I think you only have one vertex/index buffer pair at the moment, so it's a waste to reset them every frame (not that it makes much of a performance difference anyway). Anyway that was just a remark. What have you found with more proactive debugging?
[/quote]
Well, I just finished the debugging you suggested; Draw( ) gives the exact same error and DebugView ( http://technet.micro...s/bb896647.aspx ) gives no output whatsoever, with or without the DirectX Control Panel set to force the debug layer on for the application, with the default DebugView settings.

Edit: To clarify further, my vertex buffer contains vertices:

[System.Runtime.InteropServices.StructLayout( System.Runtime.InteropServices.LayoutKind.Explicit, Size = 12, Pack = 1 )]
public struct Vertex
{
public Vector3F Position
{
get { return position; }
set { position = value; }
}
public static VertexDataInfo[] VertexDataInfo
{
get
{
return new VertexDataInfo[ ] {
new VertexDataInfo( VertexDataType.Position, VertexDataFrom.Float3 )
};
}
}

[System.Runtime.InteropServices.FieldOffset( 0 )]
private Vector3F position;

public Vertex( Vector3F position )
{
this.position = position;
}
}


and the following draw call: "graphicsDevice.device.ImmediateContext.Draw( 3, 0 );" results in the exact same error message.
DebugView ( http://technet.micro...s/bb896647.aspx ) gives no output whatsoever, with or without the DirectX Control Panel set to force the debug layer on for the application, with the default DebugView settings.[/quote]
No output whatsoever? That's not right, it should at least output some trivial metadata even if it doesn't complain about the crash. For instance this is what I get upon closing one of my unfinished SlimDX projects (with D3D11):

[1860] Object of type SlimDX.Direct3D11.RasterizerState was not disposed. Stack trace of object creation:
[1860] Object of type SlimDX.Direct3D11.Buffer was not disposed. Stack trace of object creation:
[1860] Object of type SlimDX.Direct3D11.Buffer was not disposed. Stack trace of object creation:
[1860] Total of 3 objects still alive.


You want to capture Win32 in DebugView, and have you set the debug verbosity to maximum in the control panel? Also, if you have the 64-bit SDK, the two control panels (x86 and x64) do not actually share their settings, so you want to do it for both if unsure which DLL your program ends up using.

Well, I just finished the debugging you suggested; Draw( ) gives the exact same error[/quote]
Curious. The vertex buffer looks fine from here, so it must be the drawing code that's screwing up. I suspect it has something to do with the input layout being incorrect, but have you confirmed that all your parameters are what they should be (StartIndexLocation, IndexCount, Offset, ...).

I haven't used SlimDX in a while and I have missed a few updates, can you upload the whole project if it isn't too big so people can get a chance to run it and reproduce the error?

EDIT: with your last edit, clearly it is the drawing code or your vertex description as even a trivial vertex buffer doesn't work. I am heavily suspecting some padding issue, since your vertex stride is 12 bytes! Is there a way you can make it a float4 for testing (setting the W-component to 1)? I mean, I can't see anything else wrong.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

Verbose kernal output doesn't help. I wonder if I'm confusing it by using C# destructors to dispose of disposables? Both control panels show the same settings, so it does look like they share them, since I only set one.

indexBuffer.Format is: SlimDX.DXGI.Format.R16_UInt
indexBuffer.Offset is: 0
indexBuffer.IndexCount is: 36
indexBuffer.StartIndexLocation is: 0
vertexBuffer.BaseVertexLocation is: 0

Vertex buffer size: 288. 288 / 12 = 24.
Index buffer size: 72. 72 / 2 = 36.

Mesh box creation function code:

float halfWidth = width * 0.5F,
halfHeight = height * 0.5F,
halfDepth = depth * 0.5F;
Vertex[ ] vertices = new Vertex[ 24 ] {
new Vertex( new Vector3F( -halfWidth, -halfHeight, -halfDepth ) ),
new Vertex( new Vector3F( halfWidth, -halfHeight, -halfDepth ) ),
new Vertex( new Vector3F( halfWidth, halfHeight, -halfDepth ) ),
new Vertex( new Vector3F( -halfWidth, halfHeight, -halfDepth ) ),

new Vertex( new Vector3F( -halfWidth, halfHeight, -halfDepth ) ),
new Vertex( new Vector3F( -halfWidth, halfHeight, halfDepth ) ),
new Vertex( new Vector3F( -halfWidth, -halfHeight, halfDepth ) ),
new Vertex( new Vector3F( -halfWidth, -halfHeight, -halfDepth ) ),

new Vertex( new Vector3F( halfWidth, -halfHeight, -halfDepth ) ),
new Vertex( new Vector3F( halfWidth, -halfHeight, halfDepth ) ),
new Vertex( new Vector3F( halfWidth, halfHeight, halfDepth ) ),
new Vertex( new Vector3F( halfWidth, halfHeight, -halfDepth ) ),

new Vertex( new Vector3F( -halfWidth, -halfHeight, halfDepth ) ),
new Vertex( new Vector3F( halfWidth, -halfHeight, halfDepth ) ),
new Vertex( new Vector3F( halfWidth, -halfHeight, -halfDepth ) ),
new Vertex( new Vector3F( -halfWidth, -halfHeight, -halfDepth ) ),

new Vertex( new Vector3F( -halfWidth, halfHeight, -halfDepth ) ),
new Vertex( new Vector3F( halfWidth, halfHeight, -halfDepth ) ),
new Vertex( new Vector3F( halfWidth, halfHeight, halfDepth ) ),
new Vertex( new Vector3F( -halfWidth, halfHeight, halfDepth ) ),

new Vertex( new Vector3F( -halfWidth, halfHeight, halfDepth ) ),
new Vertex( new Vector3F( halfWidth, halfHeight, halfDepth ) ),
new Vertex( new Vector3F( halfWidth, -halfHeight, halfDepth ) ),
new Vertex( new Vector3F( -halfWidth, -halfHeight, halfDepth ) )
};
short[ ] indices = new short[ 36 ] {
0, 2, 1,
0, 3, 2,
4, 6, 5,
4, 7, 6,
8, 10, 9,
8, 11, 10,
12, 14, 13,
12, 15, 14,
16, 18, 17,
16, 19, 18,
20, 22, 21,
20, 23, 22
};
return new Mesh(
graphicsDevice: graphicsDevice,
vertexBuffer: VertexBuffer.Create( graphicsDevice, vertices, Marshal.SizeOf( typeof( Vertex ) ), Vertex.VertexDataInfo ),
indexBuffer: IndexBuffer.Create( graphicsDevice, indices, sizeof( short ) ) );

Changing the indices to ushort made no difference.

Edit: I get from arrays to SlimDX.DataStreams like so:

using ( var streamSource = new SlimDX.DataStream( vertices.Length * vertexStride, true, true ) )
{
streamSource.WriteRange( vertices );
streamSource.Position = 0;


using ( var streamSource = new SlimDX.DataStream( indices.Length * indexStride, true, true ) )
{
streamSource.WriteRange( indices );
streamSource.Position = 0;

The vertices are correctly written; I've previously tested this...Just did a quick array-readout of the index buffer; data looks valid.

Only thing left might be the "Vector4 versus Vector3" thing.

...It's not Vector4F versus Vector3F. I changed the Vertex struct to use Vector4Fs; same error.

Done the post.
I am out of ideas. Please upload the whole zipped solution (or a minimal sample with the same error) and specify the version of the SlimDX DLL used, and I will take a closer look.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

Hmm:

RenderTarget.Description.FirstDepthSlice for SlimDX SimpleTriangle tutorial is: 2048
RenderTarget.Description.FirstDepthSlice for my code tutorial is: 2.

Now, I'm not sure what that is, but my number doesn't look right.
Isolated the error. It happens when I use my effect. Here's the .fx code:

matrix Projection ;
matrix View ;
matrix World ;

struct VSInput
{
float4 VertexPosition : POSITION ;
};
struct VSOutput
{
float4 ScreenPosition : SV_POSITION ;
float4 WorldPosition : TEXCOORD0 ;
float4 CameraPosition : TEXCOORD1 ;
};

VSOutput VShader( VSInput input )
{
VSOutput output ;
output.WorldPosition = mul( World, input.VertexPosition ) ;
output.CameraPosition = mul( Projection, mul( View, output.WorldPosition ) ) ;
output.ScreenPosition = output.CameraPosition ;
return output ;
}

struct PSInput
{
float4 ScreenPosition : SV_POSITION ;
float4 WorldPosition : TEXCOORD0 ;
float4 CameraPosition : TEXCOORD1 ;
} ;
struct PSOutput
{
float4 Colour : SV_TARGET ;
float Depth : SV_DEPTH ;
} ;

PSOutput PShader( PSInput input )
{
PSOutput output ;
output.Colour = float4( 1.0, 1.0, 1.0, 1.0 ) ;
output.Depth = input.CameraPosition.z / input.CameraPosition.w ;
return output ;
}

technique11 Shader
{
Pass P0
{
SetVertexShader( CompileShader( vs_5_0, VShader( ) ) ) ;
SetComputeShader( NULL ) ;
SetGeometryShader( NULL ) ;
SetDomainShader( NULL ) ;
SetHullShader( NULL ) ;
SetPixelShader( CompileShader( ps_5_0, PShader( ) ) ) ;
}
}

As you can see, it's brilliantly complicated.

And here is how I apply the effect:
effect.GetTechniqueByIndex( 0 ).GetPassByIndex( pass ).Apply( device.ImmediateContext );

...Neither the technique nor the pass is valid. Maybe I was more tired than I thought, because I checked them and was sure they were valid.

Added the technique to the SimpleTriangle triangle.fx file; loaded it into the effect class I'm using for this test - Exact same error.

float4 VShader(float4 position : POSITION) : SV_POSITION
{
return position;
}
float4 PShader(float4 position : SV_POSITION) : SV_Target
{
return float4(1.0f, 1.0f, 0.0f, 1.0f);
}

technique11 Shader
{
Pass P0
{
SetVertexShader( CompileShader( vs_5_0, VShader( ) ) ) ;
SetComputeShader( NULL ) ;
SetGeometryShader( NULL ) ;
SetDomainShader( NULL ) ;
SetHullShader( NULL ) ;
SetPixelShader( CompileShader( ps_5_0, PShader( ) ) ) ;
}
}

Well, I'm not sure how this code is incorrect, but it seems the culprit has been found - Or at least, we've narrowed down the list of suspects.

This topic is closed to new replies.

Advertisement