Hy; Yeah, I'm still pushing the limits ... :smile:
Okay, we need a depth-buffer "resolve" in the middle of a render-pass, no z-prepass possible in the moment. This is what I tried:
- Using INTZ depth-buffer texture [CreateTexture,GetSurfaceLevel]
- render first part of the scene
- EndScene()
- create a clone-surface (same parameters as for the initial allocation, incl. DEPTH_STENCIL-USAGE)
- StretchRect()
- BeginScene()
Seems not to work, reason: "The source and destination surfaces must be plain depth stencil surfaces (not textures)".
Then I was reading up really anything what was written, and ATI supposely allows me to copy-"resolve" the INTZ-buffer via the RESZ-hack (it doesn't need to be multisampled). That's too hackish and restricted (some specific cards).
So I'm back at thinking about shader-copying the depth-buffer. The problem is I must not change any renderstate basically. Which makes it necessary to fake a full-screen pass in projection-space. I'm not quite sure how to do that.
- read the world & projection transform
- position a quad at the z-near frustum-corners and multiply it by the inverse world-transform as well as inverse projection-transform? does this give me the correct full-screen quad?
- make a backup of the current vertex- and pixel-shader, the first bound texture, the rendertarget and the z-write/check states
- set pass-through vertex- and pixel-shader, bind depth-buffer to sampler 0, bind depth-buffer target-copy to rendertarget, disable z-fail and disable z-write
- DrawPrimitive of my calculated quad
- push back the backup-values
- continue as usual
Is that a sound concept? It works by applying minimal state-changes. All DX9. I know it's horrible, thanks to nVidia ...
Thanks
Edit: I think it's more performant to do the quad in the vertex-shader isn't it?
Quad-VertexArray with index:
matrix FullScreenQuad[] = {
{1,1,0,0},
{-1,1,1,0},
{-1,-1,2,0},
{1,-1,3,0}
};
In case DX9 doesn't support vertex-id it can be done with vertex-colors-as-index.
Okay, we need a depth-buffer "resolve" in the middle of a render-pass, no z-prepass possible in the moment. This is what I tried:
- Using INTZ depth-buffer texture [CreateTexture,GetSurfaceLevel]
- render first part of the scene
- EndScene()
- create a clone-surface (same parameters as for the initial allocation, incl. DEPTH_STENCIL-USAGE)
- StretchRect()
- BeginScene()
Seems not to work, reason: "The source and destination surfaces must be plain depth stencil surfaces (not textures)".
Then I was reading up really anything what was written, and ATI supposely allows me to copy-"resolve" the INTZ-buffer via the RESZ-hack (it doesn't need to be multisampled). That's too hackish and restricted (some specific cards).
So I'm back at thinking about shader-copying the depth-buffer. The problem is I must not change any renderstate basically. Which makes it necessary to fake a full-screen pass in projection-space. I'm not quite sure how to do that.
- read the world & projection transform
- position a quad at the z-near frustum-corners and multiply it by the inverse world-transform as well as inverse projection-transform? does this give me the correct full-screen quad?
- make a backup of the current vertex- and pixel-shader, the first bound texture, the rendertarget and the z-write/check states
- set pass-through vertex- and pixel-shader, bind depth-buffer to sampler 0, bind depth-buffer target-copy to rendertarget, disable z-fail and disable z-write
- DrawPrimitive of my calculated quad
- push back the backup-values
- continue as usual
Is that a sound concept? It works by applying minimal state-changes. All DX9. I know it's horrible, thanks to nVidia ...
Thanks
Edit: I think it's more performant to do the quad in the vertex-shader isn't it?
Quad-VertexArray with index:
matrix FullScreenQuad[] = {
{1,1,0,0},
{-1,1,1,0},
{-1,-1,2,0},
{1,-1,3,0}
};
Code:
matrix FullScreenQuad;
struct VSInput
{
float4 Position : POSITION;
float2 TexCoord : TEXCOORD;
uint VertexID : SV_VertexID;
};
float4 VSMain(in VSInput input) : POSITION
{
return float4(FullScreenQuad[VertexID].xy, 0, 1);
}
sampler2D DepthTexture;
float4 PSMain(in VSOutput input) : COLOR0
{
return tex2D(DepthTexture, input.position.xy * 0.5);
}
Last edited by a moderator: