Jump to content
  • Advertisement
Sign in to follow this  
BlackBrain

Problem with geometry output stream

This topic is 1563 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

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. 

Share this post


Link to post
Share on other sites
Advertisement

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 . 

Share this post


Link to post
Share on other sites

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 ?

Edited by unbird

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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. 

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

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. 

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!