Skip to content

Commit

Permalink
Add Support for depth data inside blit shader
Browse files Browse the repository at this point in the history
  • Loading branch information
Tinob committed Jan 9, 2016
1 parent 8b7624b commit 3982da0
Show file tree
Hide file tree
Showing 13 changed files with 100 additions and 33 deletions.
27 changes: 27 additions & 0 deletions Source/Core/VideoBackends/DX11/FramebufferManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,13 @@ void XFBSource::DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight)

void XFBSource::CopyEFB(float Gamma)
{
bool depth_copy_required = g_renderer->GetPostProcessor()->GetBlitShaderConfig()->RequiresDepthBuffer();
if (depth_copy_required && !depthtex)
{
depthtex = D3DTexture2D::Create(texWidth, texHeight,
(D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE),
D3D11_USAGE_DEFAULT, DXGI_FORMAT_R32_FLOAT, 1, m_slices);
}
g_renderer->GetPostProcessor()->OnEndFrame();
if (g_ActiveConfig.bPostProcessingEnable &&
g_ActiveConfig.iPostProcessingTrigger == POST_PROCESSING_TRIGGER_ON_SWAP &&
Expand All @@ -245,10 +252,30 @@ void XFBSource::CopyEFB(float Gamma)
FramebufferManager::GetEFBColorTexture()->GetTex(),
resource_idx, DXGI_FORMAT_R8G8B8A8_UNORM);
}
if (depth_copy_required)
{
g_renderer->ResetAPIState();
const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)texWidth, (float)texHeight);
D3D::context->OMSetRenderTargets(1, &depthtex->GetRTV(), nullptr);
D3D::context->RSSetViewports(1, &vp);
D3D::SetPointCopySampler();
D3D::drawShadedTexQuad(FramebufferManager::GetEFBDepthTexture()->GetSRV(), nullptr,
Renderer::GetTargetWidth(), Renderer::GetTargetHeight(),
PixelShaderCache::GetColorCopyProgram(true), VertexShaderCache::GetSimpleVertexShader(),
VertexShaderCache::GetSimpleInputLayout(), GeometryShaderCache::GetCopyGeometryShader(), 1.0, 0, texWidth, texHeight);
D3D::context->OMSetRenderTargets(1,
&FramebufferManager::GetEFBColorTexture()->GetRTV(),
FramebufferManager::GetEFBDepthTexture()->GetDSV());
g_renderer->RestoreAPIState();
}
}
else
{
D3D::context->CopyResource(tex->GetTex(), FramebufferManager::GetEFBColorTexture()->GetTex());
if (depth_copy_required)
{
D3D::context->CopyResource(depthtex->GetTex(), FramebufferManager::GetEFBDepthTexture()->GetTex());
}
}
}

Expand Down
8 changes: 7 additions & 1 deletion Source/Core/VideoBackends/DX11/FramebufferManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,20 @@ struct XFBSource : public XFBSourceBase
{
XFBSource(D3DTexture2D *_tex, int slices) :
tex(_tex),
m_slices(slices){}
m_slices(slices),
depthtex(nullptr) {}
~XFBSource() {
tex->Release();
if (depthtex)
{
depthtex->Release();
}
}

void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
void CopyEFB(float Gamma);
D3DTexture2D* const tex;
D3DTexture2D* depthtex;
const int m_slices;
};

Expand Down
7 changes: 4 additions & 3 deletions Source/Core/VideoBackends/DX11/PostProcessing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,11 +495,12 @@ void D3DPostProcessor::PostProcessEFB()
}

void D3DPostProcessor::BlitToFramebuffer(const TargetRectangle& dst, uintptr_t dst_texture,
const TargetRectangle& src, uintptr_t src_texture,
const TargetRectangle& src, uintptr_t src_texture, uintptr_t src_depth_texture,
int src_width, int src_height, int src_layer, float gamma)
{
D3DTexture2D* real_dst_texture = reinterpret_cast<D3DTexture2D*>(dst_texture);
D3DTexture2D* real_dst_texture = reinterpret_cast<D3DTexture2D*>(dst_texture);
D3DTexture2D* real_src_texture = reinterpret_cast<D3DTexture2D*>(src_texture);
D3DTexture2D* real_src_depth_texture = reinterpret_cast<D3DTexture2D*>(src_depth_texture);
_dbg_assert_msg_(VIDEO, src_layer >= 0, "BlitToFramebuffer should always be called with a single source layer");

// Options changed?
Expand All @@ -522,7 +523,7 @@ void D3DPostProcessor::BlitToFramebuffer(const TargetRectangle& dst, uintptr_t d
if (m_blit_shader)
{
D3D::stateman->SetPixelConstants(m_uniform_buffer.get());
m_blit_shader->Draw(this, dst, real_dst_texture, src, src_width, src_height, real_src_texture, nullptr, src_layer);
m_blit_shader->Draw(this, dst, real_dst_texture, src, src_width, src_height, real_src_texture, real_src_depth_texture, src_layer);
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoBackends/DX11/PostProcessing.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class D3DPostProcessor final : public PostProcessor
void PostProcessEFB() override;

void BlitToFramebuffer(const TargetRectangle& dst, uintptr_t dst_texture,
const TargetRectangle& src, uintptr_t src_texture,
const TargetRectangle& src, uintptr_t src_texture, uintptr_t src_depth_texture,
int src_width, int src_height, int src_layer, float gamma) override;

void PostProcess(const TargetRectangle& visible_rect, int tex_width, int tex_height, int tex_layers,
Expand Down
23 changes: 13 additions & 10 deletions Source/Core/VideoBackends/DX11/Render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co

sourceRc.right -= Renderer::EFBToScaledX(fbStride - fbWidth);

BlitScreen(drawRc, sourceRc, xfbSource->tex, xfbSource->texWidth, xfbSource->texHeight, Gamma);
BlitScreen(drawRc, sourceRc, xfbSource->tex, xfbSource->depthtex, xfbSource->texWidth, xfbSource->texHeight, Gamma);
}
}
else
Expand All @@ -834,13 +834,13 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
D3DTexture2D* read_texture = FramebufferManager::GetResolvedEFBColorTexture();
int src_width = s_target_width;
int src_height = s_target_height;
D3DTexture2D* depth_texture = nullptr;
m_post_processor->OnEndFrame();
// Post processing active?
if (g_ActiveConfig.bPostProcessingEnable &&
g_ActiveConfig.iPostProcessingTrigger == POST_PROCESSING_TRIGGER_ON_SWAP &&
m_post_processor->IsActive())
{
D3DTexture2D* depth_texture = nullptr;
if (m_post_processor->RequiresDepthBuffer())
depth_texture = FramebufferManager::GetResolvedEFBDepthTexture();

Expand All @@ -851,8 +851,11 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), nullptr);
D3D::SetLinearCopySampler();
}

BlitScreen(targetRc, sourceRc, read_texture, src_width, src_height, Gamma);
if (depth_texture == nullptr && m_post_processor->GetBlitShaderConfig()->RequiresDepthBuffer())
{
depth_texture = FramebufferManager::GetResolvedEFBDepthTexture();
}
BlitScreen(targetRc, sourceRc, read_texture, depth_texture, src_width, src_height, Gamma);
}
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)targetRc.left, (float)targetRc.top, (float)targetRc.GetWidth(), (float)targetRc.GetHeight());
D3D::context->RSSetViewports(1, &vp);
Expand Down Expand Up @@ -1323,18 +1326,18 @@ void Renderer::BBoxWrite(int index, u16 _value)
BBox::Set(index, value);
}

void Renderer::BlitScreen(TargetRectangle dst, TargetRectangle src, D3DTexture2D* src_texture, u32 src_width, u32 src_height, float gamma)
void Renderer::BlitScreen(TargetRectangle dst, TargetRectangle src, D3DTexture2D* src_texture, D3DTexture2D* depth_texture, u32 src_width, u32 src_height, float gamma)
{
if (g_ActiveConfig.iStereoMode == STEREO_SBS || g_ActiveConfig.iStereoMode == STEREO_TAB)
{
TargetRectangle leftRc, rightRc;
ConvertStereoRectangle(dst, leftRc, rightRc);

m_post_processor->BlitToFramebuffer(leftRc, reinterpret_cast<uintptr_t>(D3D::GetBackBuffer()),
src, reinterpret_cast<uintptr_t>(src_texture), src_width, src_height, 0, gamma);
src, reinterpret_cast<uintptr_t>(src_texture), reinterpret_cast<uintptr_t>(depth_texture), src_width, src_height, 0, gamma);

m_post_processor->BlitToFramebuffer(rightRc, reinterpret_cast<uintptr_t>(D3D::GetBackBuffer()),
src, reinterpret_cast<uintptr_t>(src_texture), src_width, src_height, 1, gamma);
src, reinterpret_cast<uintptr_t>(src_texture), reinterpret_cast<uintptr_t>(depth_texture), src_width, src_height, 1, gamma);
}
else if (g_ActiveConfig.iStereoMode == STEREO_3DVISION)
{
Expand All @@ -1355,10 +1358,10 @@ void Renderer::BlitScreen(TargetRectangle dst, TargetRectangle src, D3DTexture2D

// Render to staging texture which is double the width of the backbuffer
m_post_processor->BlitToFramebuffer(leftRc, reinterpret_cast<uintptr_t>(s_3d_vision_texture),
src, reinterpret_cast<uintptr_t>(src_texture), src_width, src_height, 0, gamma);
src, reinterpret_cast<uintptr_t>(src_texture), reinterpret_cast<uintptr_t>(depth_texture), src_width, src_height, 0, gamma);

m_post_processor->BlitToFramebuffer(rightRc, reinterpret_cast<uintptr_t>(s_3d_vision_texture),
src, reinterpret_cast<uintptr_t>(src_texture), src_width, src_height, 1, gamma);
src, reinterpret_cast<uintptr_t>(src_texture), reinterpret_cast<uintptr_t>(depth_texture), src_width, src_height, 1, gamma);

// Copy the left eye to the backbuffer, if Nvidia 3D Vision is enabled it should
// recognize the signature and automatically include the right eye frame.
Expand All @@ -1371,7 +1374,7 @@ void Renderer::BlitScreen(TargetRectangle dst, TargetRectangle src, D3DTexture2D
else
{
m_post_processor->BlitToFramebuffer(dst, reinterpret_cast<uintptr_t>(D3D::GetBackBuffer()),
src, reinterpret_cast<uintptr_t>(src_texture), src_width, src_height, 0, gamma);
src, reinterpret_cast<uintptr_t>(src_texture), reinterpret_cast<uintptr_t>(depth_texture), src_width, src_height, 0, gamma);
}
}

Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoBackends/DX11/Render.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace DX11
class Renderer : public ::Renderer
{
private:
void BlitScreen(TargetRectangle dst, TargetRectangle src, D3DTexture2D* src_texture, u32 src_width, u32 src_height, float gamma = 1.0f);
void BlitScreen(TargetRectangle dst, TargetRectangle src, D3DTexture2D* src_texture, D3DTexture2D* depth_texture, u32 src_width, u32 src_height, float gamma = 1.0f);
public:
Renderer(void *&window_handle);
~Renderer();
Expand Down
29 changes: 27 additions & 2 deletions Source/Core/VideoBackends/OGL/FramebufferManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,10 @@ void FramebufferManager::ReinterpretPixelData(unsigned int convtype)
XFBSource::~XFBSource()
{
glDeleteTextures(1, &texture);
if (depthtexture)
{
glDeleteTextures(1, &depthtexture);
}
}

void XFBSource::DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
Expand All @@ -598,6 +602,16 @@ void XFBSource::DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight)

void XFBSource::CopyEFB(float Gamma)
{
bool depth_copy_required = g_renderer->GetPostProcessor()->GetBlitShaderConfig()->RequiresDepthBuffer();
if (depth_copy_required && !depthtexture)
{
glGenTextures(1, &depthtexture);

glActiveTexture(GL_TEXTURE9);
glBindTexture(GL_TEXTURE_2D_ARRAY, depthtexture);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32F, m_target_width, m_target_height, m_layers, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
}
g_renderer->GetPostProcessor()->OnEndFrame();
if (g_ActiveConfig.bPostProcessingEnable &&
g_ActiveConfig.iPostProcessingTrigger == POST_PROCESSING_TRIGGER_ON_SWAP &&
Expand All @@ -610,7 +624,7 @@ void XFBSource::CopyEFB(float Gamma)
// Copy EFB data to XFB and restore render target again
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferManager::GetXFBFramebuffer());

for (int i = 0; i < m_layers; i++)
for (unsigned int i = 0; i < m_layers; i++)
{
// Bind EFB and texture layer
glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetEFBFramebuffer(i));
Expand All @@ -621,6 +635,17 @@ void XFBSource::CopyEFB(float Gamma)
0, 0, texWidth, texHeight,
GL_COLOR_BUFFER_BIT, GL_NEAREST
);
if (depth_copy_required)
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetEFBFramebuffer(i));
glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthtexture, 0, i);

glBlitFramebuffer(
0, 0, texWidth, texHeight,
0, 0, texWidth, texHeight,
GL_DEPTH_BUFFER_BIT, GL_NEAREST
);
}
}

// Return to EFB.
Expand All @@ -641,7 +666,7 @@ std::unique_ptr<XFBSourceBase> FramebufferManager::CreateXFBSource(unsigned int
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, target_width, target_height, layers, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

return std::make_unique<XFBSource>(texture, layers);
return std::make_unique<XFBSource>(texture, target_width, target_height, layers);
}

void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height)
Expand Down
7 changes: 4 additions & 3 deletions Source/Core/VideoBackends/OGL/FramebufferManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ namespace OGL

struct XFBSource : public XFBSourceBase
{
XFBSource(GLuint tex, int layers) :
XFBSource(GLuint tex, unsigned int target_width, unsigned int target_height, unsigned int layers) :
texture(tex),
m_layers(layers){}
depthtexture(0),
m_layers(layers), m_target_width(target_width), m_target_height(target_height){}

~XFBSource();

Expand All @@ -61,7 +62,7 @@ struct XFBSource : public XFBSourceBase

const GLuint texture;
GLuint depthtexture;
const int m_layers;
const unsigned int m_layers, m_target_width, m_target_height;
};

class FramebufferManager : public FramebufferManagerBase
Expand Down
5 changes: 3 additions & 2 deletions Source/Core/VideoBackends/OGL/PostProcessing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,11 +602,12 @@ void OGLPostProcessor::PostProcessEFB()
}

void OGLPostProcessor::BlitToFramebuffer(const TargetRectangle& dst, uintptr_t dst_texture,
const TargetRectangle& src, uintptr_t src_texture,
const TargetRectangle& src, uintptr_t src_texture, uintptr_t src_depth_texture,
int src_width, int src_height, int src_layer, float gamma)
{
GLuint real_dst_texture = static_cast<GLuint>(dst_texture);
GLuint real_src_texture = static_cast<GLuint>(src_texture);
GLuint real_src_depth_texture = static_cast<GLuint>(src_depth_texture);
_dbg_assert_msg_(VIDEO, src_layer >= 0, "BlitToFramebuffer should always be called with a single source layer");

// Options changed?
Expand All @@ -628,7 +629,7 @@ void OGLPostProcessor::BlitToFramebuffer(const TargetRectangle& dst, uintptr_t d

// Use blit shader if one is set-up. Should only be a single pass in almost all cases.
if (m_blit_shader)
m_blit_shader->Draw(this, dst, real_dst_texture, src, src_width, src_height, real_src_texture, 0, src_layer, gamma);
m_blit_shader->Draw(this, dst, real_dst_texture, src, src_width, src_height, real_src_texture, real_src_depth_texture, src_layer, gamma);
else
CopyTexture(dst, real_dst_texture, src, real_src_texture, src_layer, false);
}
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoBackends/OGL/PostProcessing.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class OGLPostProcessor final : public PostProcessor
void PostProcessEFB() override;

void BlitToFramebuffer(const TargetRectangle& dst, uintptr_t dst_texture,
const TargetRectangle& src, uintptr_t src_texture,
const TargetRectangle& src, uintptr_t src_texture, uintptr_t src_depth_texture,
int src_width, int src_height, int src_layer, float gamma) override;

void PostProcess(const TargetRectangle& visible_rect, int tex_width, int tex_height, int tex_layers,
Expand Down
17 changes: 10 additions & 7 deletions Source/Core/VideoBackends/OGL/Render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1058,7 +1058,7 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
ClearEFBCache();
}

void Renderer::BlitScreen(TargetRectangle dst, TargetRectangle src, GLuint src_texture, int src_width, int src_height, float gamma)
void Renderer::BlitScreen(TargetRectangle dst, TargetRectangle src, GLuint src_texture, GLuint src_depth_texture, int src_width, int src_height, float gamma)
{
if (g_ActiveConfig.iStereoMode == STEREO_SBS || g_ActiveConfig.iStereoMode == STEREO_TAB)
{
Expand All @@ -1070,12 +1070,12 @@ void Renderer::BlitScreen(TargetRectangle dst, TargetRectangle src, GLuint src_t
else
ConvertStereoRectangle(dst, leftRc, rightRc);

m_post_processor->BlitToFramebuffer(leftRc, 0, src, src_texture, src_width, src_height, 0, gamma);
m_post_processor->BlitToFramebuffer(rightRc, 0, src, src_texture, src_width, src_height, 1, gamma);
m_post_processor->BlitToFramebuffer(leftRc, 0, src, src_texture, src_depth_texture, src_width, src_height, 0, gamma);
m_post_processor->BlitToFramebuffer(rightRc, 0, src, src_texture, src_depth_texture, src_width, src_height, 1, gamma);
}
else
{
m_post_processor->BlitToFramebuffer(dst, 0, src, src_texture, src_width, src_height, 0, gamma);
m_post_processor->BlitToFramebuffer(dst, 0, src, src_texture, src_depth_texture, src_width, src_height, 0, gamma);
}
}

Expand Down Expand Up @@ -1293,7 +1293,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
// Tell the OSD Menu about the current internal resolution
OSDInternalW = xfbSource->sourceRc.GetWidth(); OSDInternalH = xfbSource->sourceRc.GetHeight();

BlitScreen(drawRc, sourceRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight);
BlitScreen(drawRc, sourceRc, xfbSource->texture, xfbSource->depthtexture, xfbSource->texWidth, xfbSource->texHeight);
}
}
else
Expand All @@ -1306,20 +1306,23 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
int src_width = s_target_width;
int src_height = s_target_height;

GLuint depth_tex = 0;
// Post processing active?
if (g_ActiveConfig.bPostProcessingEnable &&
g_ActiveConfig.iPostProcessingTrigger == POST_PROCESSING_TRIGGER_ON_SWAP &&
m_post_processor->IsActive())
{
GLuint depth_tex = 0;
if (m_post_processor->RequiresDepthBuffer())
depth_tex = FramebufferManager::ResolveAndGetDepthTarget(rc);

m_post_processor->PostProcess(target_rc, s_target_width, s_target_height,
FramebufferManager::GetEFBLayers(), tex, depth_tex);
}

BlitScreen(flipped_trc, target_rc, tex, src_width, src_height, Gamma);
if (!depth_tex && m_post_processor->GetBlitShaderConfig()->RequiresDepthBuffer())
depth_tex = FramebufferManager::ResolveAndGetDepthTarget(rc);

BlitScreen(flipped_trc, target_rc, tex, depth_tex, src_width, src_height, Gamma);
}

glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoBackends/OGL/Render.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class Renderer : public ::Renderer
private:
void UpdateEFBCache(EFBAccessType type, u32 cacheRectIdx, const EFBRectangle& efbPixelRc, const TargetRectangle& targetPixelRc, const void* data);

void BlitScreen(TargetRectangle dst, TargetRectangle src, GLuint src_texture, int src_width, int src_height, float gamma = 1.0f);
void BlitScreen(TargetRectangle dst, TargetRectangle src, GLuint src_texture, GLuint src_depth_texture, int src_width, int src_height, float gamma = 1.0f);
};

}
2 changes: 1 addition & 1 deletion Source/Core/VideoCommon/PostProcessing.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ class PostProcessor

// Copy/resize src_texture to dst_texture (0 means backbuffer), using the resize/blit shader.
virtual void BlitToFramebuffer(const TargetRectangle& dst, uintptr_t dst_texture,
const TargetRectangle& src, uintptr_t src_texture, int src_width, int src_height, int src_layer, float gamma = 1.0f) = 0;
const TargetRectangle& src, uintptr_t src_texture, uintptr_t src_depth_texture, int src_width, int src_height, int src_layer, float gamma = 1.0f) = 0;

// Post-process an image.
virtual void PostProcess(const TargetRectangle& visible_rect, int target_width, int target_height,
Expand Down

0 comments on commit 3982da0

Please sign in to comment.