Skip to main content
GameDev.net gamedev.net
🔒 Locked

Problem with geometry output stream

Started by BlackBrain Jul 11, 2014 at 1:41 PM 6 replies 2.7k views
Original Post
BlackBrain
BlackBrain

Hello.

I'm trying to create human animation by skinning. I would like to use geometry output stream so that I don't have to alter vertex shaders for this.

But I get an error with this description :

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

My Code :


 internal void FillStreamOut()
        {
            if (StreamOutBuffer == null) // Initialize stream out buffer if it hasn't been already
            {
                int stride = Marshal.SizeOf(typeof(VertexPositionNormalTexture));
                int size = stride * indexCount;
                StreamOutBuffer = new Buffer(GraphicsRenderer.device, size, ResourceUsage.Default, BindFlags.VertexBuffer | BindFlags.StreamOutput, CpuAccessFlags.None, ResourceOptionFlags.None, stride);
            }

            //Binding to stream output
            GraphicsRenderer.contex.StreamOutput.SetTarget(StreamOutBuffer, 0);

            Draw();

            StreamOutputBufferBinding[] bindings = new StreamOutputBufferBinding[1]{new StreamOutputBufferBinding()};

            //unbingind from stream output
            GraphicsRenderer.contex.StreamOutput.SetTargets(bindings);
        }

public void Draw()
        {

            int stride = Marshal.SizeOf(typeof(T));

            GraphicsRenderer.contex.InputAssembler.SetVertexBuffers(0,VertBinding);
            GraphicsRenderer.contex.InputAssembler.SetIndexBuffer(IndBuf, SharpDX.DXGI.Format.R32_UInt, 0);

            GraphicsRenderer.contex.DrawIndexed(indexCount, 0, 0); //this line gives the error
        }

What do u think is causing this ?

My Draw Method works OK when there is no stream output binded.

BlackBrain
BlackBrain

Well I figured it out myself , I had forgotten to apply the effect . Now this problem is gone but there is nothing in the screen now ! Even Not skinned meshes disappear after a frame .

unbird
unbird

Just guessing: Probably need to explicitly reset the geometry shader to null (Edit: after your stream out drawing, of course). What does the debug layer say ?

BlackBrain
BlackBrain

Well I think I got from where this is not working . Consider the following code


 void SetSkinEffectAndSkinVertices()
        {

            if (SkinEffect == null || SkinEffect.IsDisposed)
            {
                SkinEffect = Scene.Content.Load<Effect>("VertexSkinEffect.fx",true);
            }
            GraphicsRenderer.contex.InputAssembler.InputLayout = GraphicsRenderer.SignatureManager.GetLayout(SkinEffect.GetTechniqueByIndex(0).GetPassByIndex(0), meshes[0].GetVertexLayout());

            for (int i = 0; i < meshes.Length; i++)
            {
                SkinEffect.GetVariableByName("SkinTransforms").AsMatrix().SetMatrix(meshes[i].VerticesFinalTransform);
                SkinEffect.GetTechniqueByIndex(0).GetPassByIndex(0).Apply(GraphicsRenderer.contex); //  *<THIS LINE>*
              //  meshes[i].FillStreamOut();
            }

        }

The Effect: 


cbuffer cPerCall
{
	float4x4 SkinTransforms[256];
};


struct VertexInput
{
	float4 pos:POSITION;
	float2 uv:TEXCOORD;
	float3 normal:NORMAL;
	float4 weights:BLENDWEIGHTS;
	int4 indices:BLENDINDICES;
};

struct VertexOutput
{
	float4 position:POSITION;
	float3 normal:NORMAL;
	float2 uv:TEXCOORD;
};

void SkinVertex(float4 weights,int4 indices ,inout float4 pos, inout float3 normal)
{
	if (weights.x == 0)//No skinnig when having no skinning information
		return;
	float4x4 TransformMatrix = SkinTransforms[indices.x] * weights.x + SkinTransforms[indices.y] * weights.y + SkinTransforms[indices.z] * weights.z + SkinTransforms[indices.w] * weights.w;
	pos = mul(pos, TransformMatrix);
	normal = mul(normal, (float3x3)TransformMatrix);//Assuming non-uniform scaling
}

VertexOutput VS(VertexInput input)
{
	VertexOutput output;

	float3 normal = input.normal;

	SkinVertex(input.weights, input.indices, input.pos, normal);

	output.position = input.pos;

	output.normal = normal;


	output.uv = input.uv;

	return output;
}

//Geometry Shaders

struct GeoOut
{
	float4 position:POSITION;
	float3 normal:NORMAL;
	float2 uv:TEXCOORD;
};

[maxvertexcount(3)]
void GS(triangle VertexOutput outs[3], inout TriangleStream<GeoOut> stream)
{
	
	for (int i = 0; i < 3; i++)
	{
		GeoOut p;
		p.position = outs[i].position;
		p.normal = outs[i].normal;
		p.uv = outs[i].uv;
		stream.Append(p);
	}
	stream.RestartStrip();
}

DepthStencilState DisableDepth
{
	DepthEnable = FALSE;
	DepthWriteMask = ZERO;
};

GeometryShader gsStreamOut = ConstructGSWithSO(
	CompileShader(gs_5_0, GS()),
	"POSITION.xyzw; NORMAL.xyz; TEXCOORD.xy");

technique11 DefaultTech
{
	pass pass0
	{
		SetVertexShader( CompileShader(vs_5_0, VS() ) );
		SetGeometryShader(gsStreamOut);

		// disable pixel shader for stream-out only
		SetPixelShader(NULL);
		//Also disabling depth-Stencil for stream-out only
		SetDepthStencilState(DisableDepth, 0);
	}
}

Only by applying this effect in the line that I have showned in the code . Everything is gone and I think rasterization is disabled after it. I thought setting states in an effect file is temporary and only when drawing with the effect .It seems I was wrong . How should I enable rasterization again?

unbird
unbird
By enabling a pixel shader again tongue.png

Which should happen if you use effects like before. But the reason I mentioned explicit resetting the geo shader (manually, i.e. with an ID3D11DeviceContext::GSSetShader call) because I sometimes have troubles with the effect framework. If e.g. your pass does not use SetGeometryShader(NULL), the geo shader from before is still active. Mismatching input/output signatures (VS-GS, GS->PS) will result in failing draw calls, nothing gets rasterized. You really should have a look at the debug output, such pipeline screw-ups get reported. Always.

PS: The debug layer is enabled if you create the device with the D3D11_CREATE_DEVICE_DEBUG flag.
BlackBrain
BlackBrain

I got it working finally biggrin.png

Thanks for all the help unbird.

I do set pixel shader but it wasn't enough , I should have set DepthStencilState again to work as usuall.

unbird
unbird
Glad you got it.

Now that it works, a final note. I see you use DrawIndexed and a triangle topology. This will duplicate a lot of vertices in you stream output buffer. You might want to consider drawing points if you got performance problems
BlackBrain
BlackBrain

So you mean I can just transform the vertices , then I use DrawIndexed to draw the stream-out buffer ? That's a really better idea . Thanks.

Now I use DrawAuto which is not necessary for this case.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.