Jump to content
  • Advertisement
Sign in to follow this  
B_old

DX11 Problem with ConstructGSWithSO (D3DX11 Effect)

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

I'm trying to stream out vertex data to two streams from a geometry shader that looks like this:


cbuffer ChangePerSkinnedObject
{
float4x4 g_bones[256];
}


struct SkinnedVertex
{
float3 pos : Position;
float4 normal : Normal;
};


SkinnedVertex skin(float3 pos, float4 weights, uint4 bones, float4 normal)
{
SkinnedVertex output = (SkinnedVertex)0;

//skinning...

return output;
}


SkinnedVertex vertexShader(float3 pos : Position, float4 weights : Weights, uint4 bones : Bones, float4 normal : Normal)
{
return skin(pos, weights, bones, normal);
}


VertexShader VShader = CompileShader(vs_5_0, vertexShader());


GeometryShader GeoShaderSo = ConstructGSWithSO(VShader, "0:Position.xyz", "1:Normal.xyzw", NULL, NULL, 0);


technique11 Skinning
{
pass P0
{
SetVertexShader(VShader);
SetGeometryShader(GeoShaderSo);
SetPixelShader(0);
}
}


When I compile the effect file I get the following error: D3D11: ERROR: ID3D11Device::CreateGeometryShaderWithStreamOutput: Stream Output Declaration Element[1]'s semantic (Normal 0) not found in output signature of shader.
I don't understand it.
Setting the declaration for the second stream to NULL makes it compile. It even works but obviously the second stream does not receive the data I want to have.
Any idea how to configure ConstructGSWithSO() correctly?

Share this post


Link to post
Share on other sites
Advertisement
Funnily, I can compile that shader with fxc without any problems. Haven't played around with multiple streams yet, but if I get the effect file syntax right from here, maybe this works:


GeometryShader GeoShaderSo = ConstructGSWithSO(VShader, "0:Position.xyz;1:Normal.xyzw", NULL, NULL, NULL, 0);

since you don't have an explicit GS which outputs a second stream.

Share this post


Link to post
Share on other sites
As you say, I don't get a compile error but the error appears later when the effect framework calls CreateGSWithSO(). The variant suggested by you works but than I end up with an interleaved stream, which I don't want.
I tried this:


//...
struct GS_Output_Pos
{
float3 pos : Position;
};

struct GS_Output_Normal
{
float4 normal : Normal;
};

[maxvertexcount(1)]
void geometryShader(point SkinnedVertex input[1], inout PointStream<GS_Output_Pos> positions, inout PointStream<GS_Output_Normal> normals)
{
GS_Output_Pos pos;
pos.pos = input[0].pos;

GS_Output_Normal normal;
normal.normal = input[0].normal;

positions.Append(pos);
normals.Append(normal);
}

VertexShader VShader = CompileShader(vs_5_0, vertexShader());

GeometryShader GsBase = CompileShader(gs_5_0, geometryShader());
GeometryShader GeoShaderSo = ConstructGSWithSO(GsBase, "0:Position.xyz", "1:Normal.xyzw", NULL, NULL, 0xffffffff);


It doesn't give me any errors but it crashes the video driver. :)

BTW, do you happen to know what the fx equivalent of D3D11_SO_NO_RASTERIZED_STREAM is? I tried 0xffffffff, but this still gives me a warning that the rasterizer is activated unless I manually disable depth-writes.

Share this post


Link to post
Share on other sites
I'm currently out of clues. Can you show the buffer creation, draw setup and drawing call code, please ?

Share this post


Link to post
Share on other sites

//buffer creation
D3D11_BUFFER_DESC bd;
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = bytes;
bd.BindFlags = D3D11_BIND_STREAM_OUTPUT | D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;

ID3D11Buffer *buffer;

m_device->CreateBuffer(&bd, nullptr, &buffer);

//drawing
getContext().setRenderTarget(nullptr, nullptr);
getContext().unbindVertexBuffers();
getContext().setDepthStencilState(&m_dsState);
getContext().setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
getContext().setInputLayout(m_inputLayout);

m_effect->setMatrices("g_bones", skeleton->getBones(), skeleton->getNumBones());
getContext().setVertexBuffers(2, skinningData->m_skinningInputs, inputLayoutDescription());
getContext().setStreamOutTargets(2, skinningData->m_streamOutTargets);
m_effect->getTechnique("Skinning").apply(getContext());
getContext().draw(getModel()->m_numVertices);

The second part is pseudo code:ish but I hope you can still see the d3d11 calls beneath it. As I said earlier that stuff actually works as long as I only write to one stream, but I'd rather have two.

Share this post


Link to post
Share on other sites
Hot stuff, literally. Experimenting with your setup - manually though, not through the effect framework - I first got a memory corruption when calling CreateGeometryShaderWithStreamOutput and later a freeze of my apps and suddenly some weird rendering with a blue background and white text. Blue screen of death :(

So I'm of little help now, sorry. I'd double check the strides and experiment with buffers with equal strides. But that's just a real shot in the dark.

Share this post


Link to post
Share on other sites
I managed to get away the errors by specifying [font="Courier New"]uint normal : Normal[/font] as the output for the second stream which matches the stride of my normals, because they are compressed. However whatever I output in the geometry shader it does not seem to end up in the output stream.

EDIT0: I confirmed that the second stream is not being written too, by outputting the same data to both streams. Reading from those streams later the data is not identical.

EDIT1: Had to specify [maxvertexcount(2)]. Now it works! :)

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!