D3D11: Simplify MSAA depth texture resolving
This also fixes EFB depth buffer copies when MSAA is enabled.
This commit is contained in:
parent
3ff56aa192
commit
63e4e07683
|
@ -24,7 +24,6 @@ static XFBEncoder s_xfbEncoder;
|
||||||
FramebufferManager::Efb FramebufferManager::m_efb;
|
FramebufferManager::Efb FramebufferManager::m_efb;
|
||||||
unsigned int FramebufferManager::m_target_width;
|
unsigned int FramebufferManager::m_target_width;
|
||||||
unsigned int FramebufferManager::m_target_height;
|
unsigned int FramebufferManager::m_target_height;
|
||||||
ID3D11DepthStencilState* FramebufferManager::m_depth_resolve_depth_state;
|
|
||||||
|
|
||||||
D3DTexture2D* &FramebufferManager::GetEFBColorTexture() { return m_efb.color_tex; }
|
D3DTexture2D* &FramebufferManager::GetEFBColorTexture() { return m_efb.color_tex; }
|
||||||
ID3D11Texture2D* &FramebufferManager::GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; }
|
ID3D11Texture2D* &FramebufferManager::GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; }
|
||||||
|
@ -42,7 +41,9 @@ D3DTexture2D* &FramebufferManager::GetResolvedEFBColorTexture()
|
||||||
return m_efb.resolved_color_tex;
|
return m_efb.resolved_color_tex;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return m_efb.color_tex;
|
return m_efb.color_tex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DTexture2D* &FramebufferManager::GetResolvedEFBDepthTexture()
|
D3DTexture2D* &FramebufferManager::GetResolvedEFBDepthTexture()
|
||||||
|
@ -51,31 +52,26 @@ D3DTexture2D* &FramebufferManager::GetResolvedEFBDepthTexture()
|
||||||
{
|
{
|
||||||
// ResolveSubresource does not work with depth textures.
|
// ResolveSubresource does not work with depth textures.
|
||||||
// Instead, we use a shader that selects the minimum depth from all samples.
|
// Instead, we use a shader that selects the minimum depth from all samples.
|
||||||
|
|
||||||
// Clear render state, and enable depth writes.
|
|
||||||
g_renderer->ResetAPIState();
|
g_renderer->ResetAPIState();
|
||||||
D3D::stateman->PushDepthState(m_depth_resolve_depth_state);
|
|
||||||
|
|
||||||
// Set up to render to resolved depth texture.
|
CD3D11_VIEWPORT viewport(0.f, 0.f, (float)m_target_width, (float)m_target_height);
|
||||||
const D3D11_VIEWPORT viewport = CD3D11_VIEWPORT(0.f, 0.f, (float)m_target_width, (float)m_target_height);
|
|
||||||
D3D::context->RSSetViewports(1, &viewport);
|
D3D::context->RSSetViewports(1, &viewport);
|
||||||
D3D::context->OMSetRenderTargets(0, nullptr, m_efb.resolved_depth_tex->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &m_efb.resolved_depth_tex->GetRTV(), nullptr);
|
||||||
|
|
||||||
// Render a quad covering the entire target, writing SV_Depth.
|
|
||||||
const D3D11_RECT source_rect = CD3D11_RECT(0, 0, m_target_width, m_target_height);
|
const D3D11_RECT source_rect = CD3D11_RECT(0, 0, m_target_width, m_target_height);
|
||||||
D3D::drawShadedTexQuad(m_efb.depth_tex->GetSRV(), &source_rect, m_target_width, m_target_height,
|
D3D::drawShadedTexQuad(m_efb.depth_tex->GetSRV(), &source_rect, m_target_width, m_target_height,
|
||||||
PixelShaderCache::GetDepthResolveProgram(), VertexShaderCache::GetSimpleVertexShader(),
|
PixelShaderCache::GetDepthResolveProgram(), VertexShaderCache::GetSimpleVertexShader(),
|
||||||
VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader());
|
VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader());
|
||||||
|
|
||||||
// Restore render state.
|
|
||||||
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
D3D::stateman->PopDepthState();
|
|
||||||
g_renderer->RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
|
|
||||||
return m_efb.resolved_depth_tex;
|
return m_efb.resolved_depth_tex;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return m_efb.depth_tex;
|
return m_efb.depth_tex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferManager::FramebufferManager()
|
FramebufferManager::FramebufferManager()
|
||||||
|
@ -162,28 +158,18 @@ FramebufferManager::FramebufferManager()
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_color_tex->GetTex(), "EFB color resolve texture");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_color_tex->GetTex(), "EFB color resolve texture");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_color_tex->GetSRV(), "EFB color resolve texture shader resource view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_color_tex->GetSRV(), "EFB color resolve texture shader resource view");
|
||||||
|
|
||||||
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_TYPELESS, m_target_width, m_target_height, m_efb.slices, 1, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL);
|
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, m_target_width, m_target_height, m_efb.slices, 1, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
|
||||||
hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &buf);
|
hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &buf);
|
||||||
CHECK(hr==S_OK, "create EFB depth resolve texture (size: %dx%d; hr=%#x)", m_target_width, m_target_height, hr);
|
CHECK(hr==S_OK, "create EFB depth resolve texture (size: %dx%d; hr=%#x)", m_target_width, m_target_height, hr);
|
||||||
m_efb.resolved_depth_tex = new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL), DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_D32_FLOAT);
|
m_efb.resolved_depth_tex = new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R32_FLOAT);
|
||||||
SAFE_RELEASE(buf);
|
SAFE_RELEASE(buf);
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_depth_tex->GetTex(), "EFB depth resolve texture");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_depth_tex->GetTex(), "EFB depth resolve texture");
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_depth_tex->GetSRV(), "EFB depth resolve texture shader resource view");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.resolved_depth_tex->GetSRV(), "EFB depth resolve texture shader resource view");
|
||||||
|
|
||||||
// Depth state used when writing resolved depth texture
|
|
||||||
D3D11_DEPTH_STENCIL_DESC depth_resolve_depth_state = CD3D11_DEPTH_STENCIL_DESC(CD3D11_DEFAULT());
|
|
||||||
depth_resolve_depth_state.DepthEnable = TRUE;
|
|
||||||
depth_resolve_depth_state.DepthFunc = D3D11_COMPARISON_ALWAYS;
|
|
||||||
depth_resolve_depth_state.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
|
||||||
hr = D3D::device->CreateDepthStencilState(&depth_resolve_depth_state, &m_depth_resolve_depth_state);
|
|
||||||
CHECK(hr == S_OK, "create depth resolve depth stencil state");
|
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_depth_resolve_depth_state, "depth resolve depth stencil state");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_efb.resolved_color_tex = nullptr;
|
m_efb.resolved_color_tex = nullptr;
|
||||||
m_efb.resolved_depth_tex = nullptr;
|
m_efb.resolved_depth_tex = nullptr;
|
||||||
m_depth_resolve_depth_state = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s_xfbEncoder.Init();
|
s_xfbEncoder.Init();
|
||||||
|
@ -201,7 +187,6 @@ FramebufferManager::~FramebufferManager()
|
||||||
SAFE_RELEASE(m_efb.depth_staging_buf);
|
SAFE_RELEASE(m_efb.depth_staging_buf);
|
||||||
SAFE_RELEASE(m_efb.depth_read_texture);
|
SAFE_RELEASE(m_efb.depth_read_texture);
|
||||||
SAFE_RELEASE(m_efb.resolved_depth_tex);
|
SAFE_RELEASE(m_efb.resolved_depth_tex);
|
||||||
SAFE_RELEASE(m_depth_resolve_depth_state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
|
void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
|
||||||
|
|
|
@ -105,7 +105,6 @@ private:
|
||||||
|
|
||||||
static unsigned int m_target_width;
|
static unsigned int m_target_width;
|
||||||
static unsigned int m_target_height;
|
static unsigned int m_target_height;
|
||||||
static ID3D11DepthStencilState* m_depth_resolve_depth_state;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace DX11
|
} // namespace DX11
|
||||||
|
|
|
@ -204,15 +204,15 @@ const char depth_resolve_program[] = {
|
||||||
"#define SAMPLES %d\n"
|
"#define SAMPLES %d\n"
|
||||||
"Texture2DMSArray<float4, SAMPLES> Tex0 : register(t0);\n"
|
"Texture2DMSArray<float4, SAMPLES> Tex0 : register(t0);\n"
|
||||||
"void main(\n"
|
"void main(\n"
|
||||||
" out float depth : SV_Depth,\n"
|
" out float ocol0 : SV_Target,\n"
|
||||||
" in float4 pos : SV_Position,\n"
|
" in float4 pos : SV_Position,\n"
|
||||||
" in float3 uv0 : TEXCOORD0)\n"
|
" in float3 uv0 : TEXCOORD0)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int width, height, slices, samples;\n"
|
" int width, height, slices, samples;\n"
|
||||||
" Tex0.GetDimensions(width, height, slices, samples);\n"
|
" Tex0.GetDimensions(width, height, slices, samples);\n"
|
||||||
" depth = Tex0.Load(int3(uv0.x*(width), uv0.y*(height), uv0.z), 0).x;\n"
|
" ocol0 = Tex0.Load(int3(uv0.x*(width), uv0.y*(height), uv0.z), 0).x;\n"
|
||||||
" for(int i = 1; i < SAMPLES; ++i)\n"
|
" for(int i = 1; i < SAMPLES; ++i)\n"
|
||||||
" depth = min(depth, Tex0.Load(int3(uv0.x*(width), uv0.y*(height), uv0.z), i).x);\n"
|
" ocol0 = min(ocol0, Tex0.Load(int3(uv0.x*(width), uv0.y*(height), uv0.z), i).x);\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue