mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-30 01:29:42 -06:00
VideoCommon: Add support for Abstract Framebuffers
This commit is contained in:
@ -344,4 +344,88 @@ void DXStagingTexture::Flush()
|
||||
m_needs_flush = false;
|
||||
}
|
||||
|
||||
DXFramebuffer::DXFramebuffer(AbstractTextureFormat color_format, AbstractTextureFormat depth_format,
|
||||
u32 width, u32 height, u32 layers, u32 samples,
|
||||
ID3D11RenderTargetView* rtv, ID3D11DepthStencilView* dsv)
|
||||
: AbstractFramebuffer(color_format, depth_format, width, height, layers, samples), m_rtv(rtv),
|
||||
m_dsv(dsv)
|
||||
{
|
||||
}
|
||||
|
||||
DXFramebuffer::~DXFramebuffer()
|
||||
{
|
||||
if (m_rtv)
|
||||
m_rtv->Release();
|
||||
if (m_dsv)
|
||||
m_dsv->Release();
|
||||
}
|
||||
|
||||
std::unique_ptr<DXFramebuffer> DXFramebuffer::Create(const DXTexture* color_attachment,
|
||||
const DXTexture* depth_attachment)
|
||||
{
|
||||
if (!ValidateConfig(color_attachment, depth_attachment))
|
||||
return nullptr;
|
||||
|
||||
const AbstractTextureFormat color_format =
|
||||
color_attachment ? color_attachment->GetFormat() : AbstractTextureFormat::Undefined;
|
||||
const AbstractTextureFormat depth_format =
|
||||
depth_attachment ? depth_attachment->GetFormat() : AbstractTextureFormat::Undefined;
|
||||
const DXTexture* either_attachment = color_attachment ? color_attachment : depth_attachment;
|
||||
const u32 width = either_attachment->GetWidth();
|
||||
const u32 height = either_attachment->GetHeight();
|
||||
const u32 layers = either_attachment->GetLayers();
|
||||
const u32 samples = either_attachment->GetSamples();
|
||||
|
||||
ID3D11RenderTargetView* rtv = nullptr;
|
||||
if (color_attachment)
|
||||
{
|
||||
D3D11_RENDER_TARGET_VIEW_DESC desc;
|
||||
desc.Format = GetDXGIFormatForHostFormat(color_attachment->GetConfig().format);
|
||||
if (color_attachment->GetConfig().IsMultisampled())
|
||||
{
|
||||
desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
|
||||
desc.Texture2DMSArray.ArraySize = color_attachment->GetConfig().layers;
|
||||
desc.Texture2DMSArray.FirstArraySlice = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
|
||||
desc.Texture2DArray.ArraySize = color_attachment->GetConfig().layers;
|
||||
desc.Texture2DArray.FirstArraySlice = 0;
|
||||
desc.Texture2DArray.MipSlice = 0;
|
||||
}
|
||||
|
||||
HRESULT hr = D3D::device->CreateRenderTargetView(
|
||||
color_attachment->GetRawTexIdentifier()->GetTex(), &desc, &rtv);
|
||||
CHECK(SUCCEEDED(hr), "Create render target view for framebuffer");
|
||||
}
|
||||
|
||||
ID3D11DepthStencilView* dsv = nullptr;
|
||||
if (depth_attachment)
|
||||
{
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC desc;
|
||||
desc.Format = GetDXGIFormatForHostFormat(depth_attachment->GetConfig().format);
|
||||
if (depth_attachment->GetConfig().IsMultisampled())
|
||||
{
|
||||
desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;
|
||||
desc.Texture2DMSArray.ArraySize = depth_attachment->GetConfig().layers;
|
||||
desc.Texture2DMSArray.FirstArraySlice = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
|
||||
desc.Texture2DArray.ArraySize = depth_attachment->GetConfig().layers;
|
||||
desc.Texture2DArray.FirstArraySlice = 0;
|
||||
desc.Texture2DArray.MipSlice = 0;
|
||||
}
|
||||
|
||||
HRESULT hr = D3D::device->CreateDepthStencilView(
|
||||
depth_attachment->GetRawTexIdentifier()->GetTex(), &desc, &dsv);
|
||||
CHECK(SUCCEEDED(hr), "Create depth stencil view for framebuffer");
|
||||
}
|
||||
|
||||
return std::make_unique<DXFramebuffer>(color_format, depth_format, width, height, layers, samples,
|
||||
rtv, dsv);
|
||||
}
|
||||
|
||||
} // namespace DX11
|
||||
|
@ -4,8 +4,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
#include "VideoCommon/AbstractFramebuffer.h"
|
||||
#include "VideoCommon/AbstractStagingTexture.h"
|
||||
#include "VideoCommon/AbstractTexture.h"
|
||||
|
||||
@ -63,4 +65,23 @@ private:
|
||||
ID3D11Texture2D* m_tex = nullptr;
|
||||
};
|
||||
|
||||
class DXFramebuffer final : public AbstractFramebuffer
|
||||
{
|
||||
public:
|
||||
DXFramebuffer(AbstractTextureFormat color_format, AbstractTextureFormat depth_format, u32 width,
|
||||
u32 height, u32 layers, u32 samples, ID3D11RenderTargetView* rtv,
|
||||
ID3D11DepthStencilView* dsv);
|
||||
~DXFramebuffer() override;
|
||||
|
||||
ID3D11RenderTargetView* const* GetRTVArray() const { return &m_rtv; }
|
||||
UINT GetNumRTVs() const { return m_rtv ? 1 : 0; }
|
||||
ID3D11DepthStencilView* GetDSV() const { return m_dsv; }
|
||||
static std::unique_ptr<DXFramebuffer> Create(const DXTexture* color_attachment,
|
||||
const DXTexture* depth_attachment);
|
||||
|
||||
protected:
|
||||
ID3D11RenderTargetView* m_rtv;
|
||||
ID3D11DepthStencilView* m_dsv;
|
||||
};
|
||||
|
||||
} // namespace DX11
|
||||
|
@ -90,6 +90,8 @@ Renderer::Renderer(int backbuffer_width, int backbuffer_height)
|
||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)m_target_width, (float)m_target_height);
|
||||
D3D::context->RSSetViewports(1, &vp);
|
||||
FramebufferManager::BindEFBRenderTarget();
|
||||
m_current_framebuffer_width = m_target_width;
|
||||
m_current_framebuffer_height = m_target_height;
|
||||
}
|
||||
|
||||
Renderer::~Renderer()
|
||||
@ -243,6 +245,14 @@ std::unique_ptr<AbstractStagingTexture> Renderer::CreateStagingTexture(StagingTe
|
||||
return DXStagingTexture::Create(type, config);
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractFramebuffer>
|
||||
Renderer::CreateFramebuffer(const AbstractTexture* color_attachment,
|
||||
const AbstractTexture* depth_attachment)
|
||||
{
|
||||
return DXFramebuffer::Create(static_cast<const DXTexture*>(color_attachment),
|
||||
static_cast<const DXTexture*>(depth_attachment));
|
||||
}
|
||||
|
||||
void Renderer::RenderText(const std::string& text, int left, int top, u32 color)
|
||||
{
|
||||
D3D::DrawTextScaled(static_cast<float>(left + 1), static_cast<float>(top + 1), 20.f, 0.0f,
|
||||
@ -648,6 +658,9 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region
|
||||
static constexpr std::array<float, 4> clear_color{{0.f, 0.f, 0.f, 1.f}};
|
||||
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), nullptr);
|
||||
D3D::context->ClearRenderTargetView(D3D::GetBackBuffer()->GetRTV(), clear_color.data());
|
||||
m_current_framebuffer = nullptr;
|
||||
m_current_framebuffer_width = m_backbuffer_width;
|
||||
m_current_framebuffer_height = m_backbuffer_height;
|
||||
|
||||
// activate linear filtering for the buffer copies
|
||||
D3D::SetLinearCopySampler();
|
||||
@ -763,6 +776,9 @@ void Renderer::ResetAPIState()
|
||||
void Renderer::RestoreAPIState()
|
||||
{
|
||||
// Gets us back into a more game-like state.
|
||||
m_current_framebuffer = nullptr;
|
||||
m_current_framebuffer_width = m_target_width;
|
||||
m_current_framebuffer_height = m_target_height;
|
||||
FramebufferManager::BindEFBRenderTarget();
|
||||
BPFunctions::SetViewport();
|
||||
BPFunctions::SetScissor();
|
||||
@ -792,6 +808,36 @@ void Renderer::RestoreState()
|
||||
{
|
||||
}
|
||||
|
||||
void Renderer::SetFramebuffer(const AbstractFramebuffer* framebuffer)
|
||||
{
|
||||
const DXFramebuffer* fb = static_cast<const DXFramebuffer*>(framebuffer);
|
||||
D3D::context->OMSetRenderTargets(fb->GetNumRTVs(), fb->GetRTVArray(), fb->GetDSV());
|
||||
m_current_framebuffer = fb;
|
||||
m_current_framebuffer_width = fb->GetWidth();
|
||||
m_current_framebuffer_height = fb->GetHeight();
|
||||
}
|
||||
|
||||
void Renderer::SetAndDiscardFramebuffer(const AbstractFramebuffer* framebuffer)
|
||||
{
|
||||
SetFramebuffer(framebuffer);
|
||||
}
|
||||
|
||||
void Renderer::SetAndClearFramebuffer(const AbstractFramebuffer* framebuffer,
|
||||
const ClearColor& color_value, float depth_value)
|
||||
{
|
||||
SetFramebuffer(framebuffer);
|
||||
if (framebuffer->GetColorFormat() != AbstractTextureFormat::Undefined)
|
||||
{
|
||||
D3D::context->ClearRenderTargetView(
|
||||
static_cast<const DXFramebuffer*>(framebuffer)->GetRTVArray()[0], color_value.data());
|
||||
}
|
||||
if (framebuffer->GetDepthFormat() != AbstractTextureFormat::Undefined)
|
||||
{
|
||||
D3D::context->ClearDepthStencilView(static_cast<const DXFramebuffer*>(framebuffer)->GetDSV(),
|
||||
D3D11_CLEAR_DEPTH, depth_value, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::SetRasterizationState(const RasterizationState& state)
|
||||
{
|
||||
m_gx_state.raster.hex = state.hex;
|
||||
|
@ -31,8 +31,16 @@ public:
|
||||
std::unique_ptr<AbstractShader> CreateShaderFromBinary(ShaderStage stage, const void* data,
|
||||
size_t length) override;
|
||||
std::unique_ptr<AbstractPipeline> CreatePipeline(const AbstractPipelineConfig& config) override;
|
||||
std::unique_ptr<AbstractFramebuffer>
|
||||
CreateFramebuffer(const AbstractTexture* color_attachment,
|
||||
const AbstractTexture* depth_attachment) override;
|
||||
|
||||
void SetPipeline(const AbstractPipeline* pipeline) override;
|
||||
void SetFramebuffer(const AbstractFramebuffer* framebuffer) override;
|
||||
void SetAndDiscardFramebuffer(const AbstractFramebuffer* framebuffer) override;
|
||||
void SetAndClearFramebuffer(const AbstractFramebuffer* framebuffer,
|
||||
const ClearColor& color_value = {},
|
||||
float depth_value = 0.0f) override;
|
||||
void SetBlendingState(const BlendingState& state) override;
|
||||
void SetScissorRect(const MathUtil::Rectangle<int>& rc) override;
|
||||
void SetRasterizationState(const RasterizationState& state) override;
|
||||
|
Reference in New Issue
Block a user