1
\$\begingroup\$

I'm using 3 different shaders:

  • a tessellation shader to use the tessellation feature of DirectX11 :)
  • a regular shader to show how it would look without tessellation
  • and a text shader to display debug-info such as FPS, model count etc.

All of these shaders are initialized at the beginning.

Using the keyboard, I can switch between the tessellation shader and regular shader to render the scene. Additionally, I also want to be able toggle the display of debug-info using the text shader.

Since implementing the tessellation shader the text shader doesn't work anymore. When I activate the DebugText (rendered using the text-shader) my screens go black for a while, and Windows displays the following message:

Display Driver stopped responding and has recovered

Display driver stopped

This happens with either of the two shaders used to render the scene.

Additionally: I can start the application using the regular shader to render the scene and then switch to the tessellation shader. If I try to switch back to the regular shader I get the same error as with the text shader.

What am I doing wrong when switching between shaders? What am I doing wrong when displaying text at the same time?

What file can I post to help you help me? :) thx

P.S. I already checked if my keyinputs interrupt at the wrong time (during render or so..), but that seems to be ok

Testing Procedure

  1. Regular Shader without text shader Regular Shader
  2. Add text shader to Regular Shader by keyinput (works now, I built the text shader back to only vertex and pixel shader) (somthing with the z buffer is stil wrong...) Regular Shader and Font Shader
  3. Remove text shader, then change shader to Tessellation Shader by key input Tessellation Shader without Font Shader
  4. Then if I add the Text Shader or switch back to the Regular Shader Display driver stopped

Switching/Render Shader

Here the code snipet from the Renderer.cpp where I choose the Shader according to the boolean "m_useTessellationShader":

if(m_useTessellationShader) 
{
    // Render the model using the tesselation shader
    ecResult = m_ShaderManager->renderTessellationShader(m_D3D->getDeviceContext(), meshes[lod_level]->getIndexCount(), 
        worldMatrix, viewMatrix, projectionMatrix, textures, texturecount, 
        m_Light->getDirection(), m_Light->getAmbientColor(), m_Light->getDiffuseColor(), 
        (D3DXVECTOR3)m_Camera->getPosition(), TESSELLATION_AMOUNT);
} else { 
    // todo: loaded model depends on distance to camera
    // Render the model using the light shader.
    ecResult = m_ShaderManager->renderShader(m_D3D->getDeviceContext(), 
        meshes[lod_level]->getIndexCount(), lod_level, textures, texturecount,
        m_Light->getDirection(), m_Light->getAmbientColor(), m_Light->getDiffuseColor(),
        worldMatrix, viewMatrix, projectionMatrix);
}

And here the code snipet from the Mesh.cpp where I choose the Typology according to the boolean "useTessellationShader":

// RenderBuffers is called from the Render function. The purpose of this function is to set the vertex buffer and index buffer as active on the input assembler in the GPU. Once the GPU has an active vertex buffer it can then use the shader to render that buffer.
void Mesh::renderBuffers(ID3D11DeviceContext* deviceContext, bool useTessellationShader)
{
    unsigned int stride;
    unsigned int offset;

    // Set vertex buffer stride and offset.
    stride = sizeof(VertexType); 
    offset = 0;

    // Set the vertex buffer to active in the input assembler so it can be rendered.
    deviceContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset);

    // Set the index buffer to active in the input assembler so it can be rendered.
    deviceContext->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);

    // Check which Shader is used to set the appropriate Topology
    // Set the type of primitive that should be rendered from this vertex buffer, in this case triangles.
    if(useTessellationShader)
    {       
        deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST);
    }else{
        deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    }

    return;
}

RenderShader

Could there be a problem using sometimes only vertex and pixel shader and after switching using vertex, hull, domain and pixel shader? Here a little overview of my architecture:

  • TextClass: uses font.vs and font.ps

    deviceContext->VSSetShader(m_vertexShader, NULL, 0); deviceContext->PSSetShader(m_pixelShader, NULL, 0); deviceContext->PSSetSamplers(0, 1, &m_sampleState);

  • RegularShader: uses vertex.vs and pixel.ps

    deviceContext->VSSetShader(m_vertexShader, NULL, 0); deviceContext->PSSetShader(m_pixelShader, NULL, 0); deviceContext->PSSetSamplers(0, 1, &m_sampleState);

  • TessellationShader: uses tessellation.vs, tessellation.hs, tessellation.ds, tessellation.ps

    deviceContext->VSSetShader(m_vertexShader, NULL, 0); deviceContext->HSSetShader(m_hullShader, NULL, 0); deviceContext->DSSetShader(m_domainShader, NULL, 0); deviceContext->PSSetShader(m_pixelShader, NULL, 0); deviceContext->PSSetSamplers(0, 1, &m_sampleState);

ClearState

I'd like to switch between 2 shaders and it seems they have different context parameters, right? In clearstate methode it says it resets following params to NULL:

I found following in my Direct3D Class:

  • depth-stencil state -> m_deviceContext->OMSetDepthStencilState
  • rasterizer state -> m_deviceContext->RSSetState(m_rasterState);
  • blend state -> m_device->CreateBlendState
  • viewports -> m_deviceContext->RSSetViewports(1, &viewport);

I found following in every Shader Class:

  • input/output resource slots -> deviceContext->PSSetShaderResources
  • shaders -> deviceContext->VSSetShader to - deviceContext->PSSetShader
  • input layouts -> device->CreateInputLayout
  • sampler state -> device->CreateSamplerState

These two I didn't understand, where can I find them?

  • predications -> ?
  • scissor rectangles -> ?

Do I need to store them all localy so I can switch between them, because it doesn't feel right to reinitialize the Direct3d and the Shaders by every switch (key input)?!

\$\endgroup\$
7
  • 1
    \$\begingroup\$ We'd have to know how you're switching shaders. The most concise code snippet you can provide. Also, does each shader work independently? Or is it only when switching that the issue arises? \$\endgroup\$
    – House
    Mar 27, 2013 at 18:31
  • 2
    \$\begingroup\$ Have you tried enabling the D3D11 debug layer to see if it gives any interesting errors/warnings? \$\endgroup\$ Mar 27, 2013 at 18:37
  • \$\begingroup\$ @Byte56 The Tessellation Shader and the Text Shader never worked together, but seperatly they all work fine. \$\endgroup\$
    – Jinxi
    Apr 2, 2013 at 14:07
  • 1
    \$\begingroup\$ @NathanReed thats a cool "tool" it sais maybe a 1000 times D3D11: ERROR: ID3D11DeviceContext::DrawIndexed: Mismatched topology. Current Hull Shader expects input Control Point count of 3, but Input Assembler topology is not set to the matching PATCHLIST topology. [ EXECUTION ERROR #2097222: DEVICE_DRAW_HULL_SHADER_INPUT_TOPOLOGY_MISMATCH ] I was woundering if when I use vertex and pixel shader for the regular shader and then switch to tessellation shader with vertex, hull domain and pixel shader it makes problems? \$\endgroup\$
    – Jinxi
    Apr 2, 2013 at 14:34
  • 2
    \$\begingroup\$ This API debugging question is only really solvable by using D3D11 debug info messages. \$\endgroup\$
    – bobobobo
    Aug 31, 2013 at 15:22

1 Answer 1

1
\$\begingroup\$

Based on the debug layer error message you posted in your comment, it appears you are not setting the primitive topology correctly. When switching between shaders, be sure to issue an IASetPrimitiveTopology call with the correct topology for the new shader.

\$\endgroup\$
5
  • \$\begingroup\$ I think I did, look at the renderBuffers function. But where and how can I clear/restore the context? \$\endgroup\$
    – Jinxi
    Apr 2, 2013 at 18:20
  • \$\begingroup\$ @Jinxi I don't quite follow, but if you're asking about how to reset a context to the default state, you can do that with ID3D11DeviceContext::ClearState. This doesn't destroy any shaders or other resources you may have created, but after doing this you will have to re-bind them to the pipeline (VSSetShader etc.) \$\endgroup\$ Apr 2, 2013 at 18:48
  • \$\begingroup\$ I added the comment to the question. It is found at Heading ClearState \$\endgroup\$
    – Jinxi
    Apr 3, 2013 at 11:24
  • \$\begingroup\$ maybe this is more usefull than my sometimes not understandable english explenation :) jinxi.ch/diverses/jinxi-wa-tessellation.rar \$\endgroup\$
    – Jinxi
    Apr 3, 2013 at 14:41
  • \$\begingroup\$ @Jinxi Also make sure you're setting the HS and DS to NULL after you're finished using the tessellation shader. Otherwise they'll continue to be active while using the text shader, which is probably not what you want. \$\endgroup\$ Jul 2, 2013 at 17:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .