RESZ unsuccessfull

Ethatron

Regular
Supporter
Hey;

I could use some help, I'm trying to do the RESZ-resolve of a depth-buffer (AutoDepthStencil D24S8), but I can do the resolve exactly one time, then the surface remains static:

RESZ.jpg

The context is:
Code:
  // Sets up the viewport.
  float test[4] = { 0.0, 1.0, 1.0, 0.0 };
  Renderer->SetupScreenSpaceCamera(test);

  // Set up world/view/proj matrices to identity in case there's no vertex effect.
  D3DXMATRIX mIdent;
  D3DXMatrixIdentity(&mIdent);

  D3DDevice->SetTransform(D3DTS_PROJECTION, &mIdent);
  D3DDevice->SetTransform(D3DTS_VIEW, &mIdent);
  D3DDevice->SetTransform(D3DTS_WORLD, &mIdent);

  UpdateFrameConstants(Renderer);

  /* is multi-sampled? this has to be done before everything else
   * as a geometry-call will be done to resolve the depth-target
   */
  bool resz;
  D3DDevice->SetRenderTarget(0, RenderTo);
  if ((resz = ResolveDepthBuffer(D3DDevice))) {
    OrigDS.Initialise(GetDepthBufferTexture());
//  FXMan->OrigDS.SetTexture("oblv_CurrDepthStencilZ_MAINPASS", pEffect);
  }

  Renderer->RenderStateManager->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED, false);
  Renderer->RenderStateManager->SetRenderState(D3DRS_ALPHATESTENABLE, false, false);
  Renderer->RenderStateManager->SetRenderState(D3DRS_ALPHABLENDENABLE, false, false);
  Renderer->RenderStateManager->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE, false);
  Renderer->RenderStateManager->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE, false);

  /* full-screen quad */
  D3DDevice->SetStreamSource(0, EffectVertex, 0, sizeof(EffectQuad));
  Renderer->RenderStateManager->SetFVF(EFFECTQUADFORMAT, false);

The code to resolve (ResolveDepthBuffer) is:
Code:
bool ResolveDepthBuffer(IDirect3DDevice9 *Device) {
  if (DoResolve) { 
    IDirect3DSurface9 *pSurface = NULL;
    Device->GetDepthStencilSurface(&pSurface);
    if (pSurface != pOldSurface)
      Device->SetDepthStencilSurface(pOldSurface);

    Device->EndScene();
    Device->BeginScene();

    // Bind depth stencil texture to texture sampler 0
    Device->SetTexture(0, pDepthTexture);

    // Perform a dummy draw call to ensure texture sampler 0 is set before the
    // resolve is triggered
    // Vertex declaration and shaders may need to be adjusted to ensure no debug
    // error message is produced
    D3DXVECTOR3 vDummyPoint(0.0f, 0.0f, 0.0f);

    Device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
    Device->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_FALSE);
    Device->SetRenderState(D3DRS_COLORWRITEENABLE, 0);

    Device->SetVertexShader(NULL);
    Device->SetPixelShader(NULL);

    Device->SetFVF(D3DFVF_XYZ);
    Device->DrawPrimitiveUP(D3DPT_POINTLIST, 1, vDummyPoint, sizeof(D3DXVECTOR3));

    Device->SetRenderState(D3DRS_COLORWRITEENABLE, 0x0F);
//  Device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
//  Device->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_TRUE);

#define RESZ_MAGIC 0x7fa05000
    // Trigger the depth buffer resolve; after this call texture sampler 0
    // will contain the contents of the resolve operation
    Device->SetRenderState(D3DRS_POINTSIZE, RESZ_MAGIC);

    Device->EndScene();
    Device->BeginScene();

    Device->SetDepthStencilSurface(pSurface);
    return true;
  }

  return false;
};

I've thrown a lot of stupid stuff into the code to see if it changes anything, the Begin/End are not necessary, I don't even think the GetDepthStencilSurface is necessary, the SetRenderTarget may not be necessary. Despite being an official feature there is nothing to be found in the net (no code, no explanation, nada). I can provide links to the entire code-base if necessary.

Please, help ... :cry:
It's the remaining piece to enable MSAA in Oblivion, while having the depthbuffer for effects.
 
Very tough to debug someone else's (incomplete) code.

In any event, I haven't heard about any regressions with the RESZ extension. When I wrote the extension, I provided a test program that should be used to verify correct functionality before releasing drivers. We also have some games that use the extension, so if there were a regression, I'm sure that would have been found.

Is it possible that "DoResolve" isn't always true?
 
You were what? ... writing the part in the driver? :oops:

I can point you to the GIT code:
http://codaset.com/ethatron/oblivion-graphics-extender/
http://codaset.com/ethatron/oblivion-graphics-extender/source/master/blob/DepthBufferHook.cpp
Just look for ResolveDepthBuffer in these two:
http://codaset.com/ethatron/oblivion-graphics-extender/source/master/blob/EffectManager.cpp
http://codaset.com/ethatron/oblivion-graphics-extender/source/master/blob/ShaderManager.cpp

Very tough to debug someone else's (incomplete) code.

In any event, I haven't heard about any regressions with the RESZ extension. When I wrote the extension, I provided a test program that should be used to verify correct functionality before releasing drivers. We also have some games that use the extension, so if there were a regression, I'm sure that would have been found.

Is it possible that "DoResolve" isn't always true?

No, it's a global set after allocating D3D. I am debugging thoroughly, it's not wrong code, maybe some DX-state that breaks, some condition which is wrong.

If the resolve results in 1.0s you think it's working, just not right?

The first time I hit the MAGIC-line the resolve happens, but the SetRenderState takes very long (0.5-1.0 sec line-stepping in Debug-Session), if I could hear something I probably would hear it crack. That's my impression. I know it's not RESZ which is broken, the problem is it doesn't run under the conditions, and I am a bit sad it seems a hit-and-run feature, no error-reporting, and no discussions in the net either.

If I go back to the minimal version, the least amount of state changes, the "resolve" fills the texture with 1.0, but I'm not sure if it's because DX optimizes the state-change and thus the resolve away, or because of something related to the depth-buffer, or just because the resolve does not resolve. The depth buffer is automanaged, I didn't allocate it.
 
could it be related to this ?
the
GL spec states that "the color sample values are resolved to a
single, displayable color each time a pixel is updated." There are,
however, several modern hardware implementations that do not
actually resolve for each sample update, but instead postpones the
resolve operation to a later time and resolve a batch of sample
updates at a time. This is OK as long as the implementation behaves
"as if" it had resolved a sample-at-a-time. Unfortunately, however,
honoring the "as if" rule can sometimes degrade performance.

ps: you tried it on a differed vendors gfx card ?
pps: maybe humus would know
ppps: any help (especially page 7)
http://www.google.com/url?sa=t&sour...hpjeDw&usg=AFQjCNE1aA7KVuNjzQaCaHxlnGrz93eEtg
 
could it be related to this ?

Well I don't think so, but it really could be related to anything, it's a blackbox. It's possible it's so robust it's impossible to break, but then ... I managed it.
- The depth-texture I resolve to, is permanently bound to an effect without being rebound. I don't know if that matters, why should it?
- It's possible there is no rendertarget bound the moment the resolve happens for the effects (I'm very positive there is), but there is definitly one bound for the shaders, and they behave identical (either 0.0s [resolve doesn't happen] or 1.0s [I don't know what that means], but not depth). Of course just one of both can have the first stab at the resolve, so they are not exposing identical results.
- There is the possibility the depth-buffer is cleared before the effects (I'm very positive it is not because if I replace the depth-surface I can access depth just fine and we disabled the depth-clear), but the depth-buffer is definitly not cleared in the middle of the render, as in the case when a shader requests a depth-buffer copy.
- There may be subtitle differences between a AutoDepthStencil-surface and a manually CreateTexture-surface, though I can't say with my limited knowledge.

ps: you tried it on a differed vendors gfx card ?

A 5770 and a 5870 expose the same behaviour. I don't know about others. The 5870 is a XFX, I don't know about the 5770.

pps: maybe humus would know

Why? Did he do it in some game?


Yeah, I copied that code! :cry: It is in fact the only text on the planet which says something concrete about RESZ.
 
Hm, D3D Debug spit out this:
"MultiSampleType between DepthStencil Buffer and RenderTarget must match."

Do I have to use a "NULL" Rendertarget, or can I unbind the rendertarget?
Edit: I suppose it need to be "NULL" as we want D3D to actually to the Draw-call, right? Can I allocate a "NULL" RT with matching multisampling? CheckDeviceMultiSampleType says yes. CreateRendertarget says yes.

The result of fixing a few things, lala:

RESZ2.jpg


I now got the initial strange depth-content copied in the middle of the frame by the water-shader. Though the content is still strange and static from there on.

GIT has been updated.

------

Uh, Debug mode is really great. Too bad the Oblivion shaders are bugged ...:

Direct3D9: (ERROR) :Vertex shader function usage (D3DDECLUSAGE_TEXCOORD,1) does not have corresponding usage in the current vertex declaration
 
Last edited by a moderator:
This functionality is not part of DX9, Oblivion is DX9. I think NV exposes something similar through NV API but that's beyond the point. Etathron, it's probably best if you ping someone from ATI devrel directly, since it might, in the least, give you access to some more decent documentation.
 
This functionality is not part of DX9, Oblivion is DX9. I think NV exposes something similar through NV API but that's beyond the point. Etathron, it's probably best if you ping someone from ATI devrel directly, since it might, in the least, give you access to some more decent documentation.

But I don't know who those people are. They don't have a team-page, or a telephone number. I know there is catalyst-maker, I don't know anymore what Dave is doing ...
And (to follow the self-pity line of thoughts :p) what do they care in which way I abuse a "perfectly working and successfull AAA title who's time is long gone"? I don't have anything to give back in return ... I could put the AMD-logo ingame (bad) ... I could say OBGE is now AMD-sponsored/supported (okayish) ... I'm not even a proficient DX9-programmer (well, I start to become one ...), amateurish.

I just got good intentions. :oops: And I'm really thankfull for you guys, doesn't matter the outcome.
 
Back
Top