Page 1 of 1

[Bug or Feature] Override of D3D9 render states

Posted: Sat Aug 02, 2014 22:51
by Zorsz
Hi,

Not restoring states caused a lot of artifacts.
I fixed Direct3D9Renderer to restore the state and now it is better.

Maybe someone will find it useful.

Code: Select all

03/08/2014 00:12:54 (Std)    ********************************************************************************
03/08/2014 00:12:54 (Std)    ---- Version: 0.8.4 (Build: Aug  3 2014 Microsoft Windows MSVC++ Great Scott! 32 bit) ----
03/08/2014 00:12:54 (Std)    ---- Renderer module is: CEGUI::Direct3D9Renderer - Official Direct3D 9 based 2nd generation renderer module. ----
03/08/2014 00:12:54 (Std)    ---- XML Parser module is: CEGUI::ExpatParser - Official expat based parser module for CEGUI ----
03/08/2014 00:12:54 (Std)    ---- Image Codec module is: SILLYImageCodec - Official SILLY based image codec ----
03/08/2014 00:12:54 (Std)    ---- Scripting module is: None ----
03/08/2014 00:12:54 (Std)    ********************************************************************************


Code: Select all


#define SAVE_D3D_STATE(Flag, What)do{DWORD val = 0; if(SUCCEEDED(dev->Get##What##State(Flag, &val))) What##States[Flag] = val;}while(0)
#define SAVE_D3D_STATE1(Flag, Count, What)do{DWORD val = 0; if(SUCCEEDED(dev->Get##What##State(0, Flag, &val))) What##Count##States[Flag] = val;}while(0)
#define SAVE_D3D_RENDER(Flag) SAVE_D3D_STATE(Flag, Render)
#define SAVE_D3D_SAMPLER1(Flag) SAVE_D3D_STATE1(Flag,0, Sampler)
#define SAVE_D3D_TEXTURESTAGE0(Flag) SAVE_D3D_STATE1(Flag, 0, TextureStage)
#define SAVE_D3D_TEXTURESTAGE1(Flag) SAVE_D3D_STATE1(Flag, 1, TextureStage)

#define RESTORE_STATE(flag, what) do { dev->Set##what##State(flag, what##States[flag]);}while(0)
#define RESTORE_RENDER(flag) RESTORE_STATE(flag, Render)
#define RESTORE_STATE1(flag, count, what) do{dev->Set##what##State(count, flag, what##count##States[flag]);}while(0)
#define RESTORE_SAMPLER0(flag) RESTORE_STATE1(flag, 0, Sampler)
#define RESTORE_TEXTURE0(flag) RESTORE_STATE1(flag, 0, TextureStage)
#define RESTORE_TEXTURE1(flag) RESTORE_STATE1(flag, 1, TextureStage)
struct D3d9DevState
{
   typedef std::unordered_map<int, DWORD> option_map;
   DWORD FVF;
   IDirect3DVertexShader9* vertexShader;
   IDirect3DPixelShader9* pixelShader;
   option_map RenderStates;
   option_map Sampler0States;
   option_map TextureStage0States;
   option_map TextureStage1States;
   D3DMATRIX transform;
   LPDIRECT3DDEVICE9 dev;

   D3d9DevState(LPDIRECT3DDEVICE9 _dev)
      :dev(_dev)
   {
      //   d_device->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
      dev->GetFVF(&FVF);
      //// no shaders initially
      //d_device->SetVertexShader(0);
      dev->GetVertexShader(&vertexShader);
      //d_device->SetPixelShader(0);
      dev->GetPixelShader(&pixelShader);
      //// set device states
      //d_device->SetRenderState(D3DRS_LIGHTING, FALSE);
      SAVE_D3D_RENDER(D3DRS_LIGHTING);
      //d_device->SetRenderState(D3DRS_FOGENABLE, FALSE);
      SAVE_D3D_RENDER(D3DRS_FOGENABLE);
      //d_device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
      SAVE_D3D_RENDER(D3DRS_ZENABLE);
      //d_device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
      SAVE_D3D_RENDER(D3DRS_ALPHATESTENABLE);
      //d_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
      SAVE_D3D_RENDER(D3DRS_CULLMODE);
      //d_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
      SAVE_D3D_RENDER(D3DRS_FILLMODE);
      //d_device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
      SAVE_D3D_RENDER(D3DRS_SCISSORTESTENABLE);
      //d_device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
      SAVE_D3D_RENDER(D3DRS_ZWRITEENABLE);
      //// setup texture addressing settings
      //d_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
      SAVE_D3D_SAMPLER1(D3DSAMP_ADDRESSU);
      //d_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
      SAVE_D3D_SAMPLER1(D3DSAMP_ADDRESSV);
      //// setup colour calculations
      //d_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
      SAVE_D3D_TEXTURESTAGE0(D3DTSS_COLORARG1);
      //d_device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
      SAVE_D3D_TEXTURESTAGE0(D3DTSS_COLORARG2);
      //d_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
      SAVE_D3D_TEXTURESTAGE0(D3DTSS_COLOROP);
      //// setup alpha calculations
      //d_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
      SAVE_D3D_TEXTURESTAGE0(D3DTSS_ALPHAARG1);
      //d_device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
      SAVE_D3D_TEXTURESTAGE0(D3DTSS_ALPHAARG2);
      //d_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
      SAVE_D3D_TEXTURESTAGE0(D3DTSS_ALPHAOP);
      //// setup filtering
      //d_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
      SAVE_D3D_SAMPLER1(D3DSAMP_MINFILTER);
      //d_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
      SAVE_D3D_SAMPLER1(D3DSAMP_MAGFILTER);
      //// disable texture stages we do not need.
      //d_device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
      SAVE_D3D_TEXTURESTAGE1(D3DTSS_COLOROP);
      //// setup scene alpha blending
      //d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
      SAVE_D3D_RENDER(D3DRS_ALPHABLENDENABLE);

      //// put alpha blend operations into a known state
      //setupRenderingBlendMode(BM_NORMAL, true);

      //// set view matrix back to identity.
      //d_device->SetTransform(D3DTS_VIEW, &s_identityMatrix);
      dev->GetTransform(D3DTS_VIEW, &transform);
   }
   ~D3d9DevState()
   {
      //d_device->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
      dev->SetFVF(FVF);
      //// no shaders initially
      //d_device->SetVertexShader(0);
      dev->SetVertexShader(vertexShader);
      //d_device->SetPixelShader(0);
      dev->SetPixelShader(pixelShader);

      //// set device states
      //d_device->SetRenderState(D3DRS_LIGHTING, FALSE);
      RESTORE_RENDER(D3DRS_LIGHTING);
      //d_device->SetRenderState(D3DRS_FOGENABLE, FALSE);
      RESTORE_RENDER(D3DRS_FOGENABLE);
      //d_device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
      RESTORE_RENDER(D3DRS_ZENABLE);
      //d_device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
      RESTORE_RENDER(D3DRS_ALPHATESTENABLE);
      //d_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
      RESTORE_RENDER(D3DRS_CULLMODE);
      //d_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
      RESTORE_RENDER(D3DRS_FILLMODE);
      //d_device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
      RESTORE_RENDER(D3DRS_SCISSORTESTENABLE);
      //d_device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
      RESTORE_RENDER(D3DRS_ZWRITEENABLE);

      //// setup texture addressing settings
      //d_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
      RESTORE_SAMPLER0(D3DSAMP_ADDRESSU);
      //d_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
      RESTORE_SAMPLER0(D3DSAMP_ADDRESSV);
      //// setup colour calculations
      //d_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
      RESTORE_TEXTURE0(D3DTSS_COLORARG1);
      //d_device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
      RESTORE_TEXTURE0(D3DTSS_COLORARG2);
      //d_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
      RESTORE_TEXTURE0(D3DTSS_COLOROP);

      //// setup alpha calculations
      //d_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
      RESTORE_TEXTURE0(D3DTSS_ALPHAARG1);
      //d_device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
      RESTORE_TEXTURE0(D3DTSS_ALPHAARG2);
      //d_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
      RESTORE_TEXTURE0(D3DTSS_ALPHAOP);
      //// setup filtering
      //d_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
      RESTORE_SAMPLER0(D3DSAMP_MINFILTER);
      //d_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
      RESTORE_SAMPLER0(D3DSAMP_MAGFILTER);
      //// disable texture stages we do not need.
      //d_device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
      RESTORE_TEXTURE1(D3DTSS_COLOROP);
      //// setup scene alpha blending
      //d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);

      //// put alpha blend operations into a known state
      //setupRenderingBlendMode(BM_NORMAL, true);

      //// set view matrix back to identity.
      //d_device->SetTransform(D3DTS_VIEW, &s_identityMatrix);
      dev->SetTransform(D3DTS_VIEW, &transform);
   }

};

D3d9DevState* d3dstate = nullptr;
void Direct3D9Renderer::beginRendering()
{
   if (!d3dstate)
      d3dstate = new D3d9DevState(d_device);
    d_device->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);

    // no shaders initially
    d_device->SetVertexShader(0);
    d_device->SetPixelShader(0);

    // set device states
    d_device->SetRenderState(D3DRS_LIGHTING, FALSE);
    d_device->SetRenderState(D3DRS_FOGENABLE, FALSE);
    d_device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
    d_device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
    d_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    d_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
    d_device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
    d_device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);

    // setup texture addressing settings
    d_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
    d_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);

    // setup colour calculations
    d_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    d_device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    d_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);

    // setup alpha calculations
    d_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    d_device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
    d_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);

    // setup filtering
    d_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    d_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

    // disable texture stages we do not need.
    d_device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);

    // setup scene alpha blending
    d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);

    // put alpha blend operations into a known state
    setupRenderingBlendMode(BM_NORMAL, true);

    // set view matrix back to identity.
    d_device->SetTransform(D3DTS_VIEW, &s_identityMatrix);
}

//----------------------------------------------------------------------------//
void Direct3D9Renderer::endRendering()
{
   if (d3dstate)
   {
      delete d3dstate;
      d3dstate = nullptr;
   }
}


Re: [Bug or Feature] Override of D3D9 render states

Posted: Sun Aug 03, 2014 09:45
by lucebac
Hi Zorsz,
please create a pull request on bitbucket. This makes it easier to review your patch and to discuss specific changes. Also, please look into default branch and check, if your artifacts are still in there. Ident made a lot of changes to the D3D renderer. It could already be fixed there.

Re: [Bug or Feature] Override of D3D9 render states

Posted: Sun Aug 03, 2014 11:21
by Ident
If this will be fixed in D3D9 Renderer of the 0.8 version I will also fix it in the default branch Renderer. A pull request would be nice so that we can inspect the changes better.