Move FB to GPU_HW
This commit is contained in:
parent
12fbeb9280
commit
9b967e3751
|
@ -132,6 +132,46 @@ bool D3D11Device::SupportsTextureFormat(GPUTexture::Format format) const
|
|||
return (SUCCEEDED(m_device->CheckFormatSupport(dfmt, &support)) && ((support & required) == required));
|
||||
}
|
||||
|
||||
void D3D11Device::CopyTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 dst_layer, u32 dst_level,
|
||||
GPUTexture* src, u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width,
|
||||
u32 height)
|
||||
{
|
||||
DebugAssert(src_level < src->GetLevels() && src_layer < src->GetLayers());
|
||||
DebugAssert((src_x + width) <= src->GetMipWidth(src_level));
|
||||
DebugAssert((src_y + height) <= src->GetMipWidth(src_level));
|
||||
DebugAssert(dst_level < dst->GetLevels() && dst_layer < dst->GetLayers());
|
||||
DebugAssert((dst_x + width) <= dst->GetMipWidth(dst_level));
|
||||
DebugAssert((dst_y + height) <= dst->GetMipWidth(dst_level));
|
||||
|
||||
const CD3D11_BOX src_box(static_cast<LONG>(src_x), static_cast<LONG>(src_y), 0, static_cast<LONG>(src_x + width),
|
||||
static_cast<LONG>(src_y + height), 1);
|
||||
m_context->CopySubresourceRegion(static_cast<D3D11Texture*>(dst)->GetD3DTexture(),
|
||||
D3D11CalcSubresource(dst_level, dst_layer, dst->GetLevels()), dst_x, dst_y, 0,
|
||||
static_cast<D3D11Texture*>(src)->GetD3DTexture(),
|
||||
D3D11CalcSubresource(src_level, src_layer, src->GetLevels()), &src_box);
|
||||
}
|
||||
|
||||
void D3D11Device::ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 dst_layer, u32 dst_level,
|
||||
GPUTexture* src, u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width,
|
||||
u32 height)
|
||||
{
|
||||
DebugAssert(src_level < src->GetLevels() && src_layer < src->GetLayers());
|
||||
DebugAssert((src_x + width) <= src->GetMipWidth(src_level));
|
||||
DebugAssert((src_y + height) <= src->GetMipWidth(src_level));
|
||||
DebugAssert(dst_level < dst->GetLevels() && dst_layer < dst->GetLayers());
|
||||
DebugAssert((dst_x + width) <= dst->GetMipWidth(dst_level));
|
||||
DebugAssert((dst_y + height) <= dst->GetMipWidth(dst_level));
|
||||
DebugAssert(!dst->IsMultisampled() && src->IsMultisampled());
|
||||
|
||||
// DX11 can't resolve partial rects.
|
||||
Assert(src_x == dst_x && src_y == dst_y);
|
||||
|
||||
m_context->ResolveSubresource(
|
||||
static_cast<D3D11Texture*>(dst)->GetD3DTexture(), D3D11CalcSubresource(dst_level, dst_layer, dst->GetLevels()),
|
||||
static_cast<D3D11Texture*>(src)->GetD3DTexture(), D3D11CalcSubresource(src_level, src_layer, src->GetLevels()),
|
||||
static_cast<D3D11Texture*>(dst)->GetDXGIFormat());
|
||||
}
|
||||
|
||||
bool D3D11Device::GetHostRefreshRate(float* refresh_rate)
|
||||
{
|
||||
if (m_swap_chain && IsFullscreen())
|
||||
|
@ -751,9 +791,7 @@ bool D3D11Device::Render(bool skip_present)
|
|||
{
|
||||
if (skip_present || !m_swap_chain)
|
||||
{
|
||||
if (ImGui::GetCurrentContext())
|
||||
ImGui::Render();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -771,7 +809,6 @@ bool D3D11Device::Render(bool skip_present)
|
|||
static_cast<float>(m_window_info.surface_height), 0.0f, 1.0f);
|
||||
m_context->RSSetViewports(1, &vp);
|
||||
|
||||
if (ImGui::GetCurrentContext())
|
||||
RenderImGui();
|
||||
|
||||
RenderSoftwareCursor();
|
||||
|
|
|
@ -54,11 +54,16 @@ public:
|
|||
bool SetPostProcessingChain(const std::string_view& config) override;
|
||||
|
||||
std::unique_ptr<GPUTexture> CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples,
|
||||
GPUTexture::Type type, GPUTexture::Format format, const void* data,
|
||||
u32 data_stride, bool dynamic = false) override;
|
||||
GPUTexture::Type type, GPUTexture::Format format,
|
||||
const void* data = nullptr, u32 data_stride = 0,
|
||||
bool dynamic = false) override;
|
||||
bool DownloadTexture(GPUTexture* texture, u32 x, u32 y, u32 width, u32 height, void* out_data,
|
||||
u32 out_data_stride) override;
|
||||
bool SupportsTextureFormat(GPUTexture::Format format) const override;
|
||||
void CopyTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 dst_layer, u32 dst_level, GPUTexture* src,
|
||||
u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width, u32 height) override;
|
||||
void ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 dst_layer, u32 dst_level, GPUTexture* src,
|
||||
u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width, u32 height) override;
|
||||
|
||||
bool GetHostRefreshRate(float* refresh_rate) override;
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@ static constexpr std::array<DXGI_FORMAT, static_cast<u32>(GPUTexture::Format::Co
|
|||
D3D11Texture::D3D11Texture() = default;
|
||||
|
||||
D3D11Texture::D3D11Texture(ComPtr<ID3D11Texture2D> texture, ComPtr<ID3D11ShaderResourceView> srv,
|
||||
ComPtr<ID3D11RenderTargetView> rtv)
|
||||
: m_texture(std::move(texture)), m_srv(std::move(srv)), m_rtv(std::move(rtv))
|
||||
ComPtr<ID3D11View> rtv)
|
||||
: m_texture(std::move(texture)), m_srv(std::move(srv)), m_rtv_dsv(std::move(rtv))
|
||||
{
|
||||
const D3D11_TEXTURE2D_DESC desc = GetDesc();
|
||||
m_width = static_cast<u16>(desc.Width);
|
||||
|
@ -179,23 +179,41 @@ bool D3D11Texture::Create(ID3D11Device* device, u32 width, u32 height, u32 layer
|
|||
}
|
||||
}
|
||||
|
||||
ComPtr<ID3D11RenderTargetView> rtv;
|
||||
ComPtr<ID3D11View> rtv_dsv;
|
||||
if (bind_flags & D3D11_BIND_RENDER_TARGET)
|
||||
{
|
||||
const D3D11_RTV_DIMENSION rtv_dimension =
|
||||
(desc.SampleDesc.Count > 1) ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
const CD3D11_RENDER_TARGET_VIEW_DESC rtv_desc(rtv_dimension, desc.Format, 0, 0, desc.ArraySize);
|
||||
ComPtr<ID3D11RenderTargetView> rtv;
|
||||
const HRESULT hr = device->CreateRenderTargetView(texture.Get(), &rtv_desc, rtv.GetAddressOf());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Create RTV for texture failed: 0x%08X", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
rtv_dsv = std::move(rtv);
|
||||
}
|
||||
else if (bind_flags & D3D11_BIND_DEPTH_STENCIL)
|
||||
{
|
||||
const D3D11_DSV_DIMENSION dsv_dimension =
|
||||
(desc.SampleDesc.Count > 1) ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;
|
||||
const CD3D11_DEPTH_STENCIL_VIEW_DESC dsv_desc(dsv_dimension, desc.Format, 0, 0, desc.ArraySize);
|
||||
ComPtr<ID3D11DepthStencilView> dsv;
|
||||
const HRESULT hr = device->CreateDepthStencilView(texture.Get(), &dsv_desc, dsv.GetAddressOf());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Create DSV for texture failed: 0x%08X", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
rtv_dsv = std::move(dsv);
|
||||
}
|
||||
|
||||
m_texture = std::move(texture);
|
||||
m_srv = std::move(srv);
|
||||
m_rtv = std::move(rtv);
|
||||
m_rtv_dsv = std::move(rtv_dsv);
|
||||
m_width = static_cast<u16>(width);
|
||||
m_height = static_cast<u16>(height);
|
||||
m_layers = static_cast<u8>(layers);
|
||||
|
@ -225,23 +243,41 @@ bool D3D11Texture::Adopt(ID3D11Device* device, ComPtr<ID3D11Texture2D> texture)
|
|||
}
|
||||
}
|
||||
|
||||
ComPtr<ID3D11RenderTargetView> rtv;
|
||||
ComPtr<ID3D11View> rtv_dsv;
|
||||
if (desc.BindFlags & D3D11_BIND_RENDER_TARGET)
|
||||
{
|
||||
const D3D11_RTV_DIMENSION rtv_dimension =
|
||||
(desc.SampleDesc.Count > 1) ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
const CD3D11_RENDER_TARGET_VIEW_DESC rtv_desc(rtv_dimension, desc.Format, 0, 0, desc.ArraySize);
|
||||
const HRESULT hr = device->CreateRenderTargetView(texture.Get(), &rtv_desc, rtv.ReleaseAndGetAddressOf());
|
||||
ComPtr<ID3D11RenderTargetView> rtv;
|
||||
const HRESULT hr = device->CreateRenderTargetView(texture.Get(), &rtv_desc, rtv.GetAddressOf());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Create RTV for adopted texture failed: 0x%08X", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
rtv_dsv = std::move(rtv);
|
||||
}
|
||||
else if (desc.BindFlags & D3D11_BIND_DEPTH_STENCIL)
|
||||
{
|
||||
const D3D11_DSV_DIMENSION dsv_dimension =
|
||||
(desc.SampleDesc.Count > 1) ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;
|
||||
const CD3D11_DEPTH_STENCIL_VIEW_DESC dsv_desc(dsv_dimension, desc.Format, 0, 0, desc.ArraySize);
|
||||
ComPtr<ID3D11DepthStencilView> dsv;
|
||||
const HRESULT hr = device->CreateDepthStencilView(texture.Get(), &dsv_desc, dsv.GetAddressOf());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Create DSV for adopted texture failed: 0x%08X", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
rtv_dsv = std::move(dsv);
|
||||
}
|
||||
|
||||
m_texture = std::move(texture);
|
||||
m_srv = std::move(srv);
|
||||
m_rtv = std::move(rtv);
|
||||
m_rtv_dsv = std::move(rtv_dsv);
|
||||
m_width = static_cast<u16>(desc.Width);
|
||||
m_height = static_cast<u16>(desc.Height);
|
||||
m_layers = static_cast<u8>(desc.ArraySize);
|
||||
|
@ -253,7 +289,7 @@ bool D3D11Texture::Adopt(ID3D11Device* device, ComPtr<ID3D11Texture2D> texture)
|
|||
|
||||
void D3D11Texture::Destroy()
|
||||
{
|
||||
m_rtv.Reset();
|
||||
m_rtv_dsv.Reset();
|
||||
m_srv.Reset();
|
||||
m_texture.Reset();
|
||||
m_dynamic = false;
|
||||
|
|
|
@ -14,8 +14,7 @@ public:
|
|||
using ComPtr = Microsoft::WRL::ComPtr<T>;
|
||||
|
||||
D3D11Texture();
|
||||
D3D11Texture(ComPtr<ID3D11Texture2D> texture, ComPtr<ID3D11ShaderResourceView> srv,
|
||||
ComPtr<ID3D11RenderTargetView> rtv);
|
||||
D3D11Texture(ComPtr<ID3D11Texture2D> texture, ComPtr<ID3D11ShaderResourceView> srv, ComPtr<ID3D11View> rtv);
|
||||
~D3D11Texture();
|
||||
|
||||
static DXGI_FORMAT GetDXGIFormat(Format format);
|
||||
|
@ -23,15 +22,32 @@ public:
|
|||
|
||||
ALWAYS_INLINE ID3D11Texture2D* GetD3DTexture() const { return m_texture.Get(); }
|
||||
ALWAYS_INLINE ID3D11ShaderResourceView* GetD3DSRV() const { return m_srv.Get(); }
|
||||
ALWAYS_INLINE ID3D11RenderTargetView* GetD3DRTV() const { return m_rtv.Get(); }
|
||||
ALWAYS_INLINE ID3D11RenderTargetView* GetD3DRTV() const
|
||||
{
|
||||
return static_cast<ID3D11RenderTargetView*>(m_rtv_dsv.Get());
|
||||
}
|
||||
ALWAYS_INLINE ID3D11DepthStencilView* GetD3DDSV() const
|
||||
{
|
||||
return static_cast<ID3D11DepthStencilView*>(m_rtv_dsv.Get());
|
||||
}
|
||||
ALWAYS_INLINE ID3D11ShaderResourceView* const* GetD3DSRVArray() const { return m_srv.GetAddressOf(); }
|
||||
ALWAYS_INLINE ID3D11RenderTargetView* const* GetD3DRTVArray() const { return m_rtv.GetAddressOf(); }
|
||||
ALWAYS_INLINE ID3D11RenderTargetView* const* GetD3DRTVArray() const
|
||||
{
|
||||
return reinterpret_cast<ID3D11RenderTargetView* const*>(m_rtv_dsv.GetAddressOf());
|
||||
}
|
||||
ALWAYS_INLINE DXGI_FORMAT GetDXGIFormat() const { return GetDXGIFormat(m_format); }
|
||||
ALWAYS_INLINE bool IsDynamic() const { return m_dynamic; }
|
||||
|
||||
ALWAYS_INLINE operator ID3D11Texture2D*() const { return m_texture.Get(); }
|
||||
ALWAYS_INLINE operator ID3D11ShaderResourceView*() const { return m_srv.Get(); }
|
||||
ALWAYS_INLINE operator ID3D11RenderTargetView*() const { return m_rtv.Get(); }
|
||||
ALWAYS_INLINE operator ID3D11RenderTargetView*() const
|
||||
{
|
||||
return static_cast<ID3D11RenderTargetView*>(m_rtv_dsv.Get());
|
||||
}
|
||||
ALWAYS_INLINE operator ID3D11DepthStencilView*() const
|
||||
{
|
||||
return static_cast<ID3D11DepthStencilView*>(m_rtv_dsv.Get());
|
||||
}
|
||||
ALWAYS_INLINE operator bool() const { return static_cast<bool>(m_texture); }
|
||||
|
||||
bool Create(ID3D11Device* device, u32 width, u32 height, u32 layers, u32 levels, u32 samples, Type type,
|
||||
|
@ -51,7 +67,7 @@ public:
|
|||
private:
|
||||
ComPtr<ID3D11Texture2D> m_texture;
|
||||
ComPtr<ID3D11ShaderResourceView> m_srv;
|
||||
ComPtr<ID3D11RenderTargetView> m_rtv;
|
||||
ComPtr<ID3D11View> m_rtv_dsv;
|
||||
u32 m_mapped_subresource = 0;
|
||||
bool m_dynamic = false;
|
||||
};
|
||||
|
|
|
@ -39,6 +39,21 @@ void GPUDevice::DestroyResources()
|
|||
m_imgui_font_texture.reset();
|
||||
}
|
||||
|
||||
void GPUDevice::CopyTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 dst_layer, u32 dst_level, GPUTexture* src,
|
||||
u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width, u32 height)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
void GPUDevice::ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 dst_layer, u32 dst_level,
|
||||
GPUTexture* src, u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width,
|
||||
u32 height)
|
||||
{
|
||||
// TODO: REMOVE ME
|
||||
UnreachableCode();
|
||||
}
|
||||
|
||||
bool GPUDevice::ParseFullscreenMode(const std::string_view& mode, u32* width, u32* height, float* refresh_rate)
|
||||
{
|
||||
if (!mode.empty())
|
||||
|
|
|
@ -90,10 +90,16 @@ public:
|
|||
|
||||
/// Creates an abstracted RGBA8 texture. If dynamic, the texture can be updated with UpdateTexture() below.
|
||||
virtual std::unique_ptr<GPUTexture> CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples,
|
||||
GPUTexture::Type type, GPUTexture::Format format, const void* data,
|
||||
u32 data_stride, bool dynamic = false) = 0;
|
||||
GPUTexture::Type type, GPUTexture::Format format,
|
||||
const void* data = nullptr, u32 data_stride = 0,
|
||||
bool dynamic = false) = 0;
|
||||
virtual bool DownloadTexture(GPUTexture* texture, u32 x, u32 y, u32 width, u32 height, void* out_data,
|
||||
u32 out_data_stride) = 0;
|
||||
virtual void CopyTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 dst_layer, u32 dst_level, GPUTexture* src,
|
||||
u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width, u32 height);
|
||||
virtual void ResolveTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 dst_layer, u32 dst_level,
|
||||
GPUTexture* src, u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width,
|
||||
u32 height);
|
||||
|
||||
/// Returns false if the window was completely occluded.
|
||||
virtual bool Render(bool skip_present) = 0;
|
||||
|
|
|
@ -133,6 +133,42 @@ bool GPU_HW::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_di
|
|||
if (!GPU::DoState(sw, host_texture, update_display))
|
||||
return false;
|
||||
|
||||
if (host_texture)
|
||||
{
|
||||
GPUTexture* tex = *host_texture;
|
||||
if (sw.IsReading())
|
||||
{
|
||||
if (tex->GetWidth() != m_vram_texture->GetWidth() || tex->GetHeight() != m_vram_texture->GetHeight() ||
|
||||
tex->GetSamples() != m_vram_texture->GetSamples())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
g_host_display->CopyTextureRegion(m_vram_texture.get(), 0, 0, 0, 0, tex, 0, 0, 0, 0, tex->GetWidth(),
|
||||
tex->GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!tex || tex->GetWidth() != m_vram_texture->GetWidth() || tex->GetHeight() != m_vram_texture->GetHeight() ||
|
||||
tex->GetSamples() != m_vram_texture->GetSamples())
|
||||
{
|
||||
delete tex;
|
||||
|
||||
tex =
|
||||
g_host_display
|
||||
->CreateTexture(m_vram_texture->GetWidth(), m_vram_texture->GetHeight(), 1, 1, m_vram_texture->GetSamples(),
|
||||
GPUTexture::Type::RenderTarget, GPUTexture::Format::RGBA8, nullptr, 0, false)
|
||||
.release();
|
||||
*host_texture = tex;
|
||||
if (!tex)
|
||||
return false;
|
||||
}
|
||||
|
||||
g_host_display->CopyTextureRegion(tex, 0, 0, 0, 0, m_vram_texture.get(), 0, 0, 0, 0, tex->GetWidth(),
|
||||
tex->GetHeight());
|
||||
}
|
||||
}
|
||||
|
||||
// invalidate the whole VRAM read texture when loading state
|
||||
if (sw.IsReading())
|
||||
{
|
||||
|
@ -303,8 +339,64 @@ void GPU_HW::PrintSettingsToLog()
|
|||
Log_InfoPrintf("Using software renderer for readbacks: %s", m_sw_renderer ? "YES" : "NO");
|
||||
}
|
||||
|
||||
bool GPU_HW::CreateFramebuffer()
|
||||
{
|
||||
DestroyFramebuffer();
|
||||
|
||||
// scale vram size to internal resolution
|
||||
const u32 texture_width = VRAM_WIDTH * m_resolution_scale;
|
||||
const u32 texture_height = VRAM_HEIGHT * m_resolution_scale;
|
||||
const u8 samples = static_cast<u8>(m_multisamples);
|
||||
const GPUTexture::Format texture_format = GPUTexture::Format::RGBA8;
|
||||
const GPUTexture::Format depth_format = GPUTexture::Format::D16;
|
||||
|
||||
if (!(m_vram_texture = g_host_display->CreateTexture(texture_width, texture_height, 1, 1, samples,
|
||||
GPUTexture::Type::RenderTarget, texture_format)) ||
|
||||
!(m_vram_depth_texture = g_host_display->CreateTexture(texture_width, texture_height, 1, 1, samples,
|
||||
GPUTexture::Type::DepthStencil, depth_format)) ||
|
||||
!(m_vram_read_texture = g_host_display->CreateTexture(texture_width, texture_height, 1, 1, 1,
|
||||
GPUTexture::Type::Texture, texture_format)) ||
|
||||
!(m_display_texture = g_host_display->CreateTexture(
|
||||
((m_downsample_mode == GPUDownsampleMode::Adaptive) ? VRAM_WIDTH : GPU_MAX_DISPLAY_WIDTH) *
|
||||
m_resolution_scale,
|
||||
GPU_MAX_DISPLAY_HEIGHT * m_resolution_scale, 1, 1, 1, GPUTexture::Type::RenderTarget, texture_format)) ||
|
||||
!(m_vram_encoding_texture = g_host_display->CreateTexture(VRAM_WIDTH / 2, VRAM_HEIGHT, 1, 1, 1,
|
||||
GPUTexture::Type::RenderTarget, texture_format)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Log_InfoPrintf("Created HW framebuffer of %ux%u", texture_width, texture_height);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GPU_HW::DestroyFramebuffer()
|
||||
{
|
||||
m_vram_read_texture.reset();
|
||||
m_vram_depth_view.reset();
|
||||
m_vram_depth_texture.reset();
|
||||
m_vram_texture.reset();
|
||||
m_vram_encoding_texture.reset();
|
||||
m_display_texture.reset();
|
||||
}
|
||||
|
||||
void GPU_HW::UpdateVRAMReadTexture()
|
||||
{
|
||||
const auto scaled_rect = m_vram_dirty_rect * m_resolution_scale;
|
||||
|
||||
if (m_vram_texture->IsMultisampled())
|
||||
{
|
||||
g_host_display->ResolveTextureRegion(m_vram_read_texture.get(), scaled_rect.left, scaled_rect.top, 0, 0,
|
||||
m_vram_texture.get(), scaled_rect.left, scaled_rect.top, 0, 0,
|
||||
scaled_rect.GetWidth(), scaled_rect.GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
g_host_display->CopyTextureRegion(m_vram_read_texture.get(), scaled_rect.left, scaled_rect.top, 0, 0,
|
||||
m_vram_texture.get(), scaled_rect.left, scaled_rect.top, 0, 0,
|
||||
scaled_rect.GetWidth(), scaled_rect.GetHeight());
|
||||
}
|
||||
|
||||
m_renderer_stats.num_vram_read_texture_updates++;
|
||||
ClearVRAMDirtyRectangle();
|
||||
}
|
||||
|
|
|
@ -200,7 +200,9 @@ protected:
|
|||
|
||||
void UpdateHWSettings(bool* framebuffer_changed, bool* shaders_changed);
|
||||
|
||||
virtual void UpdateVRAMReadTexture();
|
||||
virtual bool CreateFramebuffer();
|
||||
virtual void DestroyFramebuffer();
|
||||
void UpdateVRAMReadTexture();
|
||||
virtual void UpdateDepthBufferFromMaskBit() = 0;
|
||||
virtual void ClearDepthBuffer() = 0;
|
||||
virtual void SetScissorFromDrawingArea() = 0;
|
||||
|
@ -355,7 +357,14 @@ protected:
|
|||
SmoothingUBOData GetSmoothingUBO(u32 level, u32 left, u32 top, u32 width, u32 height, u32 tex_width,
|
||||
u32 tex_height) const;
|
||||
|
||||
std::unique_ptr<GPUTexture> m_vram_texture;
|
||||
std::unique_ptr<GPUTexture> m_vram_depth_texture;
|
||||
std::unique_ptr<GPUTexture> m_vram_depth_view;
|
||||
std::unique_ptr<GPUTexture> m_vram_read_texture;
|
||||
std::unique_ptr<GPUTexture> m_vram_encoding_texture;
|
||||
std::unique_ptr<GPUTexture> m_display_texture;
|
||||
HeapArray<u16, VRAM_WIDTH * VRAM_HEIGHT> m_vram_shadow;
|
||||
|
||||
std::unique_ptr<GPU_SW_Backend> m_sw_renderer;
|
||||
|
||||
BatchVertex* m_batch_start_vertex_ptr = nullptr;
|
||||
|
|
|
@ -84,53 +84,10 @@ void GPU_HW_D3D11::Reset(bool clear_vram)
|
|||
ClearFramebuffer();
|
||||
}
|
||||
|
||||
bool GPU_HW_D3D11::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display)
|
||||
{
|
||||
if (host_texture)
|
||||
{
|
||||
ComPtr<ID3D11Resource> resource;
|
||||
|
||||
D3D11Texture* tex = static_cast<D3D11Texture*>(*host_texture);
|
||||
if (sw.IsReading())
|
||||
{
|
||||
if (tex->GetWidth() != m_vram_texture.GetWidth() || tex->GetHeight() != m_vram_texture.GetHeight() ||
|
||||
tex->GetSamples() != m_vram_texture.GetSamples())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_context->CopySubresourceRegion(m_vram_texture.GetD3DTexture(), 0, 0, 0, 0, tex->GetD3DTexture(), 0, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!tex || tex->GetWidth() != m_vram_texture.GetWidth() || tex->GetHeight() != m_vram_texture.GetHeight() ||
|
||||
tex->GetSamples() != m_vram_texture.GetSamples())
|
||||
{
|
||||
delete tex;
|
||||
|
||||
tex = static_cast<D3D11Texture*>(g_host_display
|
||||
->CreateTexture(m_vram_texture.GetWidth(), m_vram_texture.GetHeight(), 1, 1,
|
||||
m_vram_texture.GetSamples(), GPUTexture::Type::RenderTarget,
|
||||
GPUTexture::Format::RGBA8, nullptr, 0, false)
|
||||
.release());
|
||||
*host_texture = tex;
|
||||
if (!tex)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_context->CopySubresourceRegion(tex->GetD3DTexture(), 0, 0, 0, 0, m_vram_texture.GetD3DTexture(), 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
return GPU_HW::DoState(sw, host_texture, update_display);
|
||||
}
|
||||
|
||||
void GPU_HW_D3D11::ResetGraphicsAPIState()
|
||||
{
|
||||
GPU_HW::ResetGraphicsAPIState();
|
||||
|
||||
m_context->GSSetShader(nullptr, nullptr, 0);
|
||||
|
||||
// In D3D11 we can't leave a buffer mapped across a Present() call.
|
||||
FlushRender();
|
||||
}
|
||||
|
@ -142,12 +99,11 @@ void GPU_HW_D3D11::RestoreGraphicsAPIState()
|
|||
m_context->IASetVertexBuffers(0, 1, m_vertex_stream_buffer.GetD3DBufferArray(), &stride, &offset);
|
||||
m_context->IASetInputLayout(m_batch_input_layout.Get());
|
||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
m_context->GSSetShader(nullptr, nullptr, 0);
|
||||
m_context->PSSetShaderResources(0, 1, m_vram_read_texture.GetD3DSRVArray());
|
||||
m_context->PSSetShaderResources(0, 1, GetVRAMReadTexture()->GetD3DSRVArray());
|
||||
m_context->PSSetSamplers(0, 1, m_point_sampler_state.GetAddressOf());
|
||||
m_context->OMSetRenderTargets(1, m_vram_texture.GetD3DRTVArray(), m_vram_depth_view.Get());
|
||||
m_context->OMSetRenderTargets(1, GetVRAMTexture()->GetD3DRTVArray(), GetVRAMDepthTexture()->GetD3DDSV());
|
||||
m_context->RSSetState(m_cull_none_rasterizer_state.Get());
|
||||
SetViewport(0, 0, m_vram_texture.GetWidth(), m_vram_texture.GetHeight());
|
||||
SetViewport(0, 0, GetVRAMTexture()->GetWidth(), GetVRAMTexture()->GetHeight());
|
||||
SetScissorFromDrawingArea();
|
||||
m_batch_ubo_dirty = true;
|
||||
}
|
||||
|
@ -234,38 +190,12 @@ void GPU_HW_D3D11::SetCapabilities()
|
|||
|
||||
bool GPU_HW_D3D11::CreateFramebuffer()
|
||||
{
|
||||
DestroyFramebuffer();
|
||||
|
||||
// scale vram size to internal resolution
|
||||
const u32 texture_width = VRAM_WIDTH * m_resolution_scale;
|
||||
const u32 texture_height = VRAM_HEIGHT * m_resolution_scale;
|
||||
const u8 samples = static_cast<u8>(m_multisamples);
|
||||
const GPUTexture::Format texture_format = GPUTexture::Format::RGBA8;
|
||||
const GPUTexture::Format depth_format = GPUTexture::Format::D16;
|
||||
|
||||
if (!m_vram_texture.Create(m_device.Get(), texture_width, texture_height, 1, 1, samples,
|
||||
GPUTexture::Type::RenderTarget, texture_format) ||
|
||||
!m_vram_depth_texture.Create(m_device.Get(), texture_width, texture_height, 1, 1, samples,
|
||||
GPUTexture::Type::DepthStencil, depth_format) ||
|
||||
!m_vram_read_texture.Create(m_device.Get(), texture_width, texture_height, 1, 1, 1, GPUTexture::Type::Texture,
|
||||
texture_format) ||
|
||||
!m_display_texture.Create(
|
||||
m_device.Get(),
|
||||
((m_downsample_mode == GPUDownsampleMode::Adaptive) ? VRAM_WIDTH : GPU_MAX_DISPLAY_WIDTH) * m_resolution_scale,
|
||||
GPU_MAX_DISPLAY_HEIGHT * m_resolution_scale, 1, 1, 1, GPUTexture::Type::RenderTarget, texture_format) ||
|
||||
!m_vram_encoding_texture.Create(m_device.Get(), VRAM_WIDTH / 2, VRAM_HEIGHT, 1, 1, 1,
|
||||
GPUTexture::Type::RenderTarget, texture_format))
|
||||
{
|
||||
if (!GPU_HW::CreateFramebuffer())
|
||||
return false;
|
||||
}
|
||||
|
||||
const CD3D11_DEPTH_STENCIL_VIEW_DESC depth_view_desc(samples > 1 ? D3D11_DSV_DIMENSION_TEXTURE2DMS :
|
||||
D3D11_DSV_DIMENSION_TEXTURE2D,
|
||||
D3D11Texture::GetDXGIFormat(depth_format));
|
||||
HRESULT hr =
|
||||
m_device->CreateDepthStencilView(m_vram_depth_texture, &depth_view_desc, m_vram_depth_view.GetAddressOf());
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
const u32 texture_width = m_vram_texture->GetWidth();
|
||||
const u32 texture_height = m_vram_texture->GetHeight();
|
||||
const GPUTexture::Format texture_format = m_vram_texture->GetFormat();
|
||||
|
||||
if (m_downsample_mode == GPUDownsampleMode::Adaptive)
|
||||
{
|
||||
|
@ -288,7 +218,7 @@ bool GPU_HW_D3D11::CreateFramebuffer()
|
|||
const CD3D11_RENDER_TARGET_VIEW_DESC rtv_desc(m_downsample_texture, D3D11_RTV_DIMENSION_TEXTURE2D,
|
||||
m_downsample_texture.GetDXGIFormat(), i, 1);
|
||||
|
||||
hr = m_device->CreateShaderResourceView(m_downsample_texture, &srv_desc,
|
||||
HRESULT hr = m_device->CreateShaderResourceView(m_downsample_texture, &srv_desc,
|
||||
m_downsample_mip_views[i].first.GetAddressOf());
|
||||
if (FAILED(hr))
|
||||
return false;
|
||||
|
@ -308,7 +238,7 @@ bool GPU_HW_D3D11::CreateFramebuffer()
|
|||
}
|
||||
}
|
||||
|
||||
m_context->OMSetRenderTargets(1, m_vram_texture.GetD3DRTVArray(), nullptr);
|
||||
m_context->OMSetRenderTargets(1, GetVRAMTexture()->GetD3DRTVArray(), nullptr);
|
||||
SetFullVRAMDirtyRectangle();
|
||||
return true;
|
||||
}
|
||||
|
@ -316,9 +246,10 @@ bool GPU_HW_D3D11::CreateFramebuffer()
|
|||
void GPU_HW_D3D11::ClearFramebuffer()
|
||||
{
|
||||
static constexpr std::array<float, 4> color = {};
|
||||
m_context->ClearRenderTargetView(m_vram_texture.GetD3DRTV(), color.data());
|
||||
m_context->ClearDepthStencilView(m_vram_depth_view.Get(), D3D11_CLEAR_DEPTH, m_pgxp_depth_buffer ? 1.0f : 0.0f, 0);
|
||||
m_context->ClearRenderTargetView(m_display_texture, color.data());
|
||||
m_context->ClearRenderTargetView(GetVRAMTexture()->GetD3DRTV(), color.data());
|
||||
m_context->ClearDepthStencilView(GetVRAMDepthTexture()->GetD3DDSV(), D3D11_CLEAR_DEPTH,
|
||||
m_pgxp_depth_buffer ? 1.0f : 0.0f, 0);
|
||||
m_context->ClearRenderTargetView(GetDisplayTexture()->GetD3DRTV(), color.data());
|
||||
SetFullVRAMDirtyRectangle();
|
||||
m_last_depth_z = 1.0f;
|
||||
}
|
||||
|
@ -329,12 +260,7 @@ void GPU_HW_D3D11::DestroyFramebuffer()
|
|||
m_downsample_weight_texture.Destroy();
|
||||
m_downsample_texture.Destroy();
|
||||
|
||||
m_vram_read_texture.Destroy();
|
||||
m_vram_depth_view.Reset();
|
||||
m_vram_depth_texture.Destroy();
|
||||
m_vram_texture.Destroy();
|
||||
m_vram_encoding_texture.Destroy();
|
||||
m_display_texture.Destroy();
|
||||
GPU_HW::DestroyFramebuffer();
|
||||
}
|
||||
|
||||
bool GPU_HW_D3D11::CreateVertexBuffer()
|
||||
|
@ -720,7 +646,6 @@ void GPU_HW_D3D11::DrawUtilityShader(ID3D11PixelShader* shader, const void* unif
|
|||
}
|
||||
|
||||
m_context->VSSetShader(m_screen_quad_vertex_shader.Get(), nullptr, 0);
|
||||
m_context->GSSetShader(nullptr, nullptr, 0);
|
||||
m_context->PSSetShader(shader, nullptr, 0);
|
||||
m_context->OMSetBlendState(m_blend_disabled_state.Get(), nullptr, 0xFFFFFFFFu);
|
||||
|
||||
|
@ -814,7 +739,7 @@ void GPU_HW_D3D11::ClearDisplay()
|
|||
g_host_display->ClearDisplayTexture();
|
||||
|
||||
static constexpr std::array<float, 4> clear_color = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
m_context->ClearRenderTargetView(m_display_texture.GetD3DRTV(), clear_color.data());
|
||||
m_context->ClearRenderTargetView(GetDisplayTexture()->GetD3DRTV(), clear_color.data());
|
||||
}
|
||||
|
||||
void GPU_HW_D3D11::UpdateDisplay()
|
||||
|
@ -826,12 +751,13 @@ void GPU_HW_D3D11::UpdateDisplay()
|
|||
if (IsUsingMultisampling())
|
||||
{
|
||||
UpdateVRAMReadTexture();
|
||||
g_host_display->SetDisplayTexture(&m_vram_read_texture, 0, 0, m_vram_read_texture.GetWidth(),
|
||||
m_vram_read_texture.GetHeight());
|
||||
g_host_display->SetDisplayTexture(m_vram_read_texture.get(), 0, 0, GetVRAMReadTexture()->GetWidth(),
|
||||
GetVRAMReadTexture()->GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
g_host_display->SetDisplayTexture(&m_vram_texture, 0, 0, m_vram_texture.GetWidth(), m_vram_texture.GetHeight());
|
||||
g_host_display->SetDisplayTexture(m_vram_texture.get(), 0, 0, GetVRAMTexture()->GetWidth(),
|
||||
GetVRAMTexture()->GetHeight());
|
||||
}
|
||||
|
||||
g_host_display->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
|
||||
|
@ -860,27 +786,27 @@ void GPU_HW_D3D11::UpdateDisplay()
|
|||
g_host_display->ClearDisplayTexture();
|
||||
}
|
||||
else if (!m_GPUSTAT.display_area_color_depth_24 && interlaced == InterlacedRenderMode::None &&
|
||||
!IsUsingMultisampling() && (scaled_vram_offset_x + scaled_display_width) <= m_vram_texture.GetWidth() &&
|
||||
(scaled_vram_offset_y + scaled_display_height) <= m_vram_texture.GetHeight())
|
||||
!IsUsingMultisampling() && (scaled_vram_offset_x + scaled_display_width) <= GetVRAMTexture()->GetWidth() &&
|
||||
(scaled_vram_offset_y + scaled_display_height) <= GetVRAMTexture()->GetHeight())
|
||||
{
|
||||
|
||||
if (IsUsingDownsampling())
|
||||
{
|
||||
DownsampleFramebuffer(m_vram_texture, scaled_vram_offset_x, scaled_vram_offset_y, scaled_display_width,
|
||||
DownsampleFramebuffer(GetVRAMTexture(), scaled_vram_offset_x, scaled_vram_offset_y, scaled_display_width,
|
||||
scaled_display_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_host_display->SetDisplayTexture(&m_vram_texture, scaled_vram_offset_x, scaled_vram_offset_y,
|
||||
g_host_display->SetDisplayTexture(m_vram_texture.get(), scaled_vram_offset_x, scaled_vram_offset_y,
|
||||
scaled_display_width, scaled_display_height);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_context->RSSetState(m_cull_none_rasterizer_state_no_msaa.Get());
|
||||
m_context->OMSetRenderTargets(1, m_display_texture.GetD3DRTVArray(), nullptr);
|
||||
m_context->OMSetRenderTargets(1, GetDisplayTexture()->GetD3DRTVArray(), nullptr);
|
||||
m_context->OMSetDepthStencilState(m_depth_disabled_state.Get(), 0);
|
||||
m_context->PSSetShaderResources(0, 1, m_vram_texture.GetD3DSRVArray());
|
||||
m_context->PSSetShaderResources(0, 1, GetVRAMTexture()->GetD3DSRVArray());
|
||||
|
||||
const u32 reinterpret_field_offset = (interlaced != InterlacedRenderMode::None) ? GetInterlacedDisplayField() : 0;
|
||||
const u32 reinterpret_start_x = m_crtc_state.regs.X * resolution_scale;
|
||||
|
@ -890,16 +816,16 @@ void GPU_HW_D3D11::UpdateDisplay()
|
|||
ID3D11PixelShader* display_pixel_shader =
|
||||
m_display_pixel_shaders[BoolToUInt8(m_GPUSTAT.display_area_color_depth_24)][static_cast<u8>(interlaced)].Get();
|
||||
|
||||
Assert(scaled_display_width <= m_display_texture.GetWidth() &&
|
||||
scaled_display_height <= m_display_texture.GetHeight());
|
||||
Assert(scaled_display_width <= m_display_texture->GetWidth() &&
|
||||
scaled_display_height <= m_display_texture->GetHeight());
|
||||
|
||||
SetViewportAndScissor(0, 0, scaled_display_width, scaled_display_height);
|
||||
DrawUtilityShader(display_pixel_shader, uniforms, sizeof(uniforms));
|
||||
|
||||
if (IsUsingDownsampling())
|
||||
DownsampleFramebuffer(m_display_texture, 0, 0, scaled_display_width, scaled_display_height);
|
||||
DownsampleFramebuffer(GetDisplayTexture(), 0, 0, scaled_display_width, scaled_display_height);
|
||||
else
|
||||
g_host_display->SetDisplayTexture(&m_display_texture, 0, 0, scaled_display_width, scaled_display_height);
|
||||
g_host_display->SetDisplayTexture(m_display_texture.get(), 0, 0, scaled_display_width, scaled_display_height);
|
||||
|
||||
RestoreGraphicsAPIState();
|
||||
}
|
||||
|
@ -922,14 +848,14 @@ void GPU_HW_D3D11::ReadVRAM(u32 x, u32 y, u32 width, u32 height)
|
|||
// Encode the 24-bit texture as 16-bit.
|
||||
const u32 uniforms[4] = {copy_rect.left, copy_rect.top, copy_rect.GetWidth(), copy_rect.GetHeight()};
|
||||
m_context->RSSetState(m_cull_none_rasterizer_state_no_msaa.Get());
|
||||
m_context->OMSetRenderTargets(1, m_vram_encoding_texture.GetD3DRTVArray(), nullptr);
|
||||
m_context->OMSetRenderTargets(1, GetVRAMEncodingTexture()->GetD3DRTVArray(), nullptr);
|
||||
m_context->OMSetDepthStencilState(m_depth_disabled_state.Get(), 0);
|
||||
m_context->PSSetShaderResources(0, 1, m_vram_texture.GetD3DSRVArray());
|
||||
m_context->PSSetShaderResources(0, 1, GetVRAMTexture()->GetD3DSRVArray());
|
||||
SetViewportAndScissor(0, 0, encoded_width, encoded_height);
|
||||
DrawUtilityShader(m_vram_read_pixel_shader.Get(), uniforms, sizeof(uniforms));
|
||||
|
||||
// Stage the readback and copy it into our shadow buffer.
|
||||
g_host_display->DownloadTexture(&m_vram_encoding_texture, 0, 0, encoded_width, encoded_height,
|
||||
g_host_display->DownloadTexture(m_vram_encoding_texture.get(), 0, 0, encoded_width, encoded_height,
|
||||
reinterpret_cast<u32*>(&m_vram_shadow[copy_rect.top * VRAM_WIDTH + copy_rect.left]),
|
||||
VRAM_WIDTH * sizeof(u16));
|
||||
|
||||
|
@ -1018,7 +944,7 @@ void GPU_HW_D3D11::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 widt
|
|||
m_depth_test_greater_state.Get() :
|
||||
m_depth_test_always_state.Get(),
|
||||
0);
|
||||
m_context->PSSetShaderResources(0, 1, m_vram_read_texture.GetD3DSRVArray());
|
||||
m_context->PSSetShaderResources(0, 1, GetVRAMReadTexture()->GetD3DSRVArray());
|
||||
DrawUtilityShader(m_vram_copy_pixel_shader.Get(), &uniforms, sizeof(uniforms));
|
||||
RestoreGraphicsAPIState();
|
||||
|
||||
|
@ -1044,26 +970,8 @@ void GPU_HW_D3D11::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 widt
|
|||
height *= m_resolution_scale;
|
||||
|
||||
const CD3D11_BOX src_box(src_x, src_y, 0, src_x + width, src_y + height, 1);
|
||||
m_context->CopySubresourceRegion(m_vram_texture, 0, dst_x, dst_y, 0, m_vram_read_texture, 0, &src_box);
|
||||
}
|
||||
|
||||
void GPU_HW_D3D11::UpdateVRAMReadTexture()
|
||||
{
|
||||
const auto scaled_rect = m_vram_dirty_rect * m_resolution_scale;
|
||||
const CD3D11_BOX src_box(scaled_rect.left, scaled_rect.top, 0, scaled_rect.right, scaled_rect.bottom, 1);
|
||||
|
||||
if (m_vram_texture.IsMultisampled())
|
||||
{
|
||||
m_context->ResolveSubresource(m_vram_read_texture.GetD3DTexture(), 0, m_vram_texture.GetD3DTexture(), 0,
|
||||
m_vram_texture.GetDXGIFormat());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_context->CopySubresourceRegion(m_vram_read_texture, 0, scaled_rect.left, scaled_rect.top, 0, m_vram_texture, 0,
|
||||
&src_box);
|
||||
}
|
||||
|
||||
GPU_HW::UpdateVRAMReadTexture();
|
||||
m_context->CopySubresourceRegion(GetVRAMTexture()->GetD3DTexture(), 0, dst_x, dst_y, 0,
|
||||
GetVRAMReadTexture()->GetD3DTexture(), 0, &src_box);
|
||||
}
|
||||
|
||||
void GPU_HW_D3D11::UpdateDepthBufferFromMaskBit()
|
||||
|
@ -1071,16 +979,16 @@ void GPU_HW_D3D11::UpdateDepthBufferFromMaskBit()
|
|||
if (m_pgxp_depth_buffer)
|
||||
return;
|
||||
|
||||
SetViewportAndScissor(0, 0, m_vram_texture.GetWidth(), m_vram_texture.GetHeight());
|
||||
SetViewportAndScissor(0, 0, GetVRAMTexture()->GetWidth(), GetVRAMTexture()->GetHeight());
|
||||
|
||||
m_context->OMSetRenderTargets(0, nullptr, m_vram_depth_view.Get());
|
||||
m_context->OMSetRenderTargets(0, nullptr, GetVRAMDepthTexture()->GetD3DDSV());
|
||||
m_context->OMSetDepthStencilState(m_depth_test_always_state.Get(), 0);
|
||||
m_context->OMSetBlendState(m_blend_no_color_writes_state.Get(), nullptr, 0xFFFFFFFFu);
|
||||
|
||||
m_context->PSSetShaderResources(0, 1, m_vram_texture.GetD3DSRVArray());
|
||||
m_context->PSSetShaderResources(0, 1, GetVRAMTexture()->GetD3DSRVArray());
|
||||
DrawUtilityShader(m_vram_update_depth_pixel_shader.Get(), nullptr, 0);
|
||||
|
||||
m_context->PSSetShaderResources(0, 1, m_vram_read_texture.GetD3DSRVArray());
|
||||
m_context->PSSetShaderResources(0, 1, GetVRAMReadTexture()->GetD3DSRVArray());
|
||||
RestoreGraphicsAPIState();
|
||||
}
|
||||
|
||||
|
@ -1088,11 +996,11 @@ void GPU_HW_D3D11::ClearDepthBuffer()
|
|||
{
|
||||
DebugAssert(m_pgxp_depth_buffer);
|
||||
|
||||
m_context->ClearDepthStencilView(m_vram_depth_view.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0);
|
||||
m_context->ClearDepthStencilView(GetVRAMDepthTexture()->GetD3DDSV(), D3D11_CLEAR_DEPTH, 1.0f, 0);
|
||||
m_last_depth_z = 1.0f;
|
||||
}
|
||||
|
||||
void GPU_HW_D3D11::DownsampleFramebuffer(D3D11Texture& source, u32 left, u32 top, u32 width, u32 height)
|
||||
void GPU_HW_D3D11::DownsampleFramebuffer(const D3D11Texture* source, u32 left, u32 top, u32 width, u32 height)
|
||||
{
|
||||
if (m_downsample_mode == GPUDownsampleMode::Adaptive)
|
||||
DownsampleFramebufferAdaptive(source, left, top, width, height);
|
||||
|
@ -1100,12 +1008,12 @@ void GPU_HW_D3D11::DownsampleFramebuffer(D3D11Texture& source, u32 left, u32 top
|
|||
DownsampleFramebufferBoxFilter(source, left, top, width, height);
|
||||
}
|
||||
|
||||
void GPU_HW_D3D11::DownsampleFramebufferAdaptive(D3D11Texture& source, u32 left, u32 top, u32 width, u32 height)
|
||||
void GPU_HW_D3D11::DownsampleFramebufferAdaptive(const D3D11Texture* source, u32 left, u32 top, u32 width, u32 height)
|
||||
{
|
||||
CD3D11_BOX src_box(left, top, 0, left + width, top + height, 1);
|
||||
m_context->OMSetDepthStencilState(m_depth_disabled_state.Get(), 0);
|
||||
m_context->OMSetBlendState(m_blend_disabled_state.Get(), nullptr, 0xFFFFFFFFu);
|
||||
m_context->CopySubresourceRegion(m_downsample_texture, 0, left, top, 0, source, 0, &src_box);
|
||||
m_context->CopySubresourceRegion(m_downsample_texture, 0, left, top, 0, source->GetD3DTexture(), 0, &src_box);
|
||||
m_context->PSSetSamplers(0, 1, m_point_sampler_state.GetAddressOf());
|
||||
m_context->VSSetShader(m_uv_quad_vertex_shader.Get(), nullptr, 0);
|
||||
|
||||
|
@ -1149,7 +1057,7 @@ void GPU_HW_D3D11::DownsampleFramebufferAdaptive(D3D11Texture& source, u32 left,
|
|||
// composite downsampled and upsampled images together
|
||||
{
|
||||
SetViewportAndScissor(left, top, width, height);
|
||||
m_context->OMSetRenderTargets(1, m_display_texture.GetD3DRTVArray(), nullptr);
|
||||
m_context->OMSetRenderTargets(1, GetDisplayTexture()->GetD3DRTVArray(), nullptr);
|
||||
|
||||
ID3D11ShaderResourceView* const srvs[2] = {m_downsample_texture.GetD3DSRV(),
|
||||
m_downsample_weight_texture.GetD3DSRV()};
|
||||
|
@ -1166,10 +1074,10 @@ void GPU_HW_D3D11::DownsampleFramebufferAdaptive(D3D11Texture& source, u32 left,
|
|||
|
||||
RestoreGraphicsAPIState();
|
||||
|
||||
g_host_display->SetDisplayTexture(&m_display_texture, left, top, width, height);
|
||||
g_host_display->SetDisplayTexture(m_display_texture.get(), left, top, width, height);
|
||||
}
|
||||
|
||||
void GPU_HW_D3D11::DownsampleFramebufferBoxFilter(D3D11Texture& source, u32 left, u32 top, u32 width, u32 height)
|
||||
void GPU_HW_D3D11::DownsampleFramebufferBoxFilter(const D3D11Texture* source, u32 left, u32 top, u32 width, u32 height)
|
||||
{
|
||||
const u32 ds_left = left / m_resolution_scale;
|
||||
const u32 ds_top = top / m_resolution_scale;
|
||||
|
@ -1183,7 +1091,7 @@ void GPU_HW_D3D11::DownsampleFramebufferBoxFilter(D3D11Texture& source, u32 left
|
|||
m_context->OMSetBlendState(m_blend_disabled_state.Get(), nullptr, 0xFFFFFFFFu);
|
||||
m_context->VSSetShader(m_screen_quad_vertex_shader.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(m_downsample_first_pass_pixel_shader.Get(), nullptr, 0);
|
||||
m_context->PSSetShaderResources(0, 1, source.GetD3DSRVArray());
|
||||
m_context->PSSetShaderResources(0, 1, source->GetD3DSRVArray());
|
||||
SetViewportAndScissor(ds_left, ds_top, ds_width, ds_height);
|
||||
m_context->Draw(3, 0);
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ public:
|
|||
|
||||
bool Initialize() override;
|
||||
void Reset(bool clear_vram) override;
|
||||
bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override;
|
||||
|
||||
void ResetGraphicsAPIState() override;
|
||||
void RestoreGraphicsAPIState() override;
|
||||
|
@ -39,7 +38,6 @@ protected:
|
|||
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
|
||||
void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) override;
|
||||
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
|
||||
void UpdateVRAMReadTexture() override;
|
||||
void UpdateDepthBufferFromMaskBit() override;
|
||||
void ClearDepthBuffer() override;
|
||||
void SetScissorFromDrawingArea() override;
|
||||
|
@ -55,10 +53,28 @@ private:
|
|||
MAX_UNIFORM_BUFFER_SIZE = 64
|
||||
};
|
||||
|
||||
ALWAYS_INLINE D3D11Texture* GetVRAMTexture() const { return static_cast<D3D11Texture*>(m_vram_texture.get()); }
|
||||
ALWAYS_INLINE D3D11Texture* GetVRAMDepthTexture() const
|
||||
{
|
||||
return static_cast<D3D11Texture*>(m_vram_depth_texture.get());
|
||||
}
|
||||
ALWAYS_INLINE D3D11Texture* GetVRAMReadTexture() const
|
||||
{
|
||||
return static_cast<D3D11Texture*>(m_vram_read_texture.get());
|
||||
}
|
||||
ALWAYS_INLINE D3D11Texture* GetVRAMEncodingTexture() const
|
||||
{
|
||||
return static_cast<D3D11Texture*>(m_vram_encoding_texture.get());
|
||||
}
|
||||
ALWAYS_INLINE D3D11Texture* GetDisplayTexture() const
|
||||
{
|
||||
return static_cast<D3D11Texture*>(m_display_texture.get());
|
||||
}
|
||||
|
||||
void SetCapabilities();
|
||||
bool CreateFramebuffer();
|
||||
bool CreateFramebuffer() override;
|
||||
void ClearFramebuffer();
|
||||
void DestroyFramebuffer();
|
||||
void DestroyFramebuffer() override;
|
||||
|
||||
bool CreateVertexBuffer();
|
||||
bool CreateUniformBuffer();
|
||||
|
@ -76,21 +92,13 @@ private:
|
|||
|
||||
bool BlitVRAMReplacementTexture(const TextureReplacementTexture* tex, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
||||
|
||||
void DownsampleFramebuffer(D3D11Texture& source, u32 left, u32 top, u32 width, u32 height);
|
||||
void DownsampleFramebufferAdaptive(D3D11Texture& source, u32 left, u32 top, u32 width, u32 height);
|
||||
void DownsampleFramebufferBoxFilter(D3D11Texture& source, u32 left, u32 top, u32 width, u32 height);
|
||||
void DownsampleFramebuffer(const D3D11Texture* source, u32 left, u32 top, u32 width, u32 height);
|
||||
void DownsampleFramebufferAdaptive(const D3D11Texture* source, u32 left, u32 top, u32 width, u32 height);
|
||||
void DownsampleFramebufferBoxFilter(const D3D11Texture* source, u32 left, u32 top, u32 width, u32 height);
|
||||
|
||||
ComPtr<ID3D11Device> m_device;
|
||||
ComPtr<ID3D11DeviceContext> m_context;
|
||||
|
||||
// downsample texture - used for readbacks at >1xIR.
|
||||
D3D11Texture m_vram_texture;
|
||||
D3D11Texture m_vram_depth_texture;
|
||||
ComPtr<ID3D11DepthStencilView> m_vram_depth_view;
|
||||
D3D11Texture m_vram_read_texture;
|
||||
D3D11Texture m_vram_encoding_texture;
|
||||
D3D11Texture m_display_texture;
|
||||
|
||||
D3D11::StreamBuffer m_vertex_stream_buffer;
|
||||
|
||||
D3D11::StreamBuffer m_uniform_stream_buffer;
|
||||
|
|
|
@ -1128,6 +1128,8 @@ void GPU_HW_D3D12::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 widt
|
|||
m_vram_texture.TransitionToState(D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
void GPU_HW_D3D12::UpdateVRAMReadTexture()
|
||||
{
|
||||
ID3D12GraphicsCommandList* cmdlist = g_d3d12_context->GetCommandList();
|
||||
|
@ -1157,6 +1159,8 @@ void GPU_HW_D3D12::UpdateVRAMReadTexture()
|
|||
GPU_HW::UpdateVRAMReadTexture();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void GPU_HW_D3D12::UpdateDepthBufferFromMaskBit()
|
||||
{
|
||||
ID3D12GraphicsCommandList* cmdlist = g_d3d12_context->GetCommandList();
|
||||
|
|
|
@ -37,7 +37,6 @@ protected:
|
|||
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
|
||||
void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) override;
|
||||
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
|
||||
void UpdateVRAMReadTexture() override;
|
||||
void UpdateDepthBufferFromMaskBit() override;
|
||||
void ClearDepthBuffer() override;
|
||||
void SetScissorFromDrawingArea() override;
|
||||
|
|
|
@ -89,49 +89,7 @@ void GPU_HW_OpenGL::Reset(bool clear_vram)
|
|||
ClearFramebuffer();
|
||||
}
|
||||
|
||||
bool GPU_HW_OpenGL::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display)
|
||||
{
|
||||
if (host_texture)
|
||||
{
|
||||
GPUTexture* tex = *host_texture;
|
||||
if (sw.IsReading())
|
||||
{
|
||||
if (tex->GetWidth() != m_vram_texture.GetWidth() || tex->GetHeight() != m_vram_texture.GetHeight() ||
|
||||
tex->GetSamples() != m_vram_texture.GetSamples())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CopyFramebufferForState(m_vram_texture.GetGLTarget(), static_cast<GL::Texture*>(tex)->GetGLId(), 0, 0, 0,
|
||||
m_vram_texture.GetGLId(), m_vram_fbo_id, 0, 0, m_vram_texture.GetWidth(),
|
||||
m_vram_texture.GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!tex || tex->GetWidth() != m_vram_texture.GetWidth() || tex->GetHeight() != m_vram_texture.GetHeight() ||
|
||||
tex->GetSamples() != m_vram_texture.GetSamples())
|
||||
{
|
||||
delete tex;
|
||||
|
||||
tex =
|
||||
g_host_display
|
||||
->CreateTexture(m_vram_texture.GetWidth(), m_vram_texture.GetHeight(), 1, 1, m_vram_texture.GetSamples(),
|
||||
GPUTexture::Type::RenderTarget, GPUTexture::Format::RGBA8, nullptr, 0, false)
|
||||
.release();
|
||||
*host_texture = tex;
|
||||
if (!tex)
|
||||
return false;
|
||||
}
|
||||
|
||||
CopyFramebufferForState(m_vram_texture.GetGLTarget(), m_vram_texture.GetGLId(), m_vram_fbo_id, 0, 0,
|
||||
static_cast<GL::Texture*>(tex)->GetGLId(), 0, 0, 0, m_vram_texture.GetWidth(),
|
||||
m_vram_texture.GetHeight());
|
||||
}
|
||||
}
|
||||
|
||||
return GPU_HW::DoState(sw, host_texture, update_display);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void GPU_HW_OpenGL::CopyFramebufferForState(GLenum target, GLuint src_texture, u32 src_fbo, u32 src_x, u32 src_y,
|
||||
GLuint dst_texture, u32 dst_fbo, u32 dst_x, u32 dst_y, u32 width,
|
||||
u32 height)
|
||||
|
@ -190,6 +148,7 @@ void GPU_HW_OpenGL::CopyFramebufferForState(GLenum target, GLuint src_texture, u
|
|||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_vram_fbo_id);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void GPU_HW_OpenGL::ResetGraphicsAPIState()
|
||||
{
|
||||
|
@ -1209,6 +1168,7 @@ void GPU_HW_OpenGL::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 wid
|
|||
IncludeVRAMDirtyRectangle(dst_bounds);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void GPU_HW_OpenGL::UpdateVRAMReadTexture()
|
||||
{
|
||||
const auto scaled_rect = m_vram_dirty_rect * m_resolution_scale;
|
||||
|
@ -1245,6 +1205,7 @@ void GPU_HW_OpenGL::UpdateVRAMReadTexture()
|
|||
|
||||
GPU_HW::UpdateVRAMReadTexture();
|
||||
}
|
||||
#endif
|
||||
|
||||
void GPU_HW_OpenGL::UpdateDepthBufferFromMaskBit()
|
||||
{
|
||||
|
|
|
@ -23,7 +23,6 @@ public:
|
|||
|
||||
bool Initialize() override;
|
||||
void Reset(bool clear_vram) override;
|
||||
bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override;
|
||||
|
||||
void ResetGraphicsAPIState() override;
|
||||
void RestoreGraphicsAPIState() override;
|
||||
|
@ -36,7 +35,6 @@ protected:
|
|||
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
|
||||
void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) override;
|
||||
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
|
||||
void UpdateVRAMReadTexture() override;
|
||||
void UpdateDepthBufferFromMaskBit() override;
|
||||
void ClearDepthBuffer() override;
|
||||
void SetScissorFromDrawingArea() override;
|
||||
|
@ -61,8 +59,6 @@ private:
|
|||
void SetCapabilities();
|
||||
bool CreateFramebuffer();
|
||||
void ClearFramebuffer();
|
||||
void CopyFramebufferForState(GLenum target, GLuint src_texture, u32 src_fbo, u32 src_x, u32 src_y, GLuint dst_texture,
|
||||
u32 dst_fbo, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
||||
|
||||
bool CreateVertexBuffer();
|
||||
bool CreateUniformBuffer();
|
||||
|
|
|
@ -93,76 +93,6 @@ void GPU_HW_Vulkan::Reset(bool clear_vram)
|
|||
ClearFramebuffer();
|
||||
}
|
||||
|
||||
bool GPU_HW_Vulkan::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display)
|
||||
{
|
||||
if (host_texture)
|
||||
{
|
||||
EndRenderPass();
|
||||
|
||||
const VkImageCopy ic{{VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u},
|
||||
{0, 0, 0},
|
||||
{VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u},
|
||||
{0, 0, 0},
|
||||
{m_vram_texture.GetWidth(), m_vram_texture.GetHeight(), 1u}};
|
||||
|
||||
VkCommandBuffer buf = g_vulkan_context->GetCurrentCommandBuffer();
|
||||
const Vulkan::Util::DebugScope debugScope(buf, "GPU_HW_Vulkan::DoState");
|
||||
|
||||
if (sw.IsReading())
|
||||
{
|
||||
Vulkan::Texture* tex = static_cast<Vulkan::Texture*>(*host_texture);
|
||||
if (tex->GetWidth() != m_vram_texture.GetWidth() || tex->GetHeight() != m_vram_texture.GetHeight() ||
|
||||
tex->GetSamples() != m_vram_texture.GetSamples())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const VkImageLayout old_tex_layout = tex->GetLayout();
|
||||
const VkImageLayout old_vram_layout = m_vram_texture.GetLayout();
|
||||
tex->TransitionToLayout(buf, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
m_vram_texture.TransitionToLayout(buf, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
vkCmdCopyImage(g_vulkan_context->GetCurrentCommandBuffer(), tex->GetImage(), tex->GetLayout(),
|
||||
m_vram_texture.GetImage(), m_vram_texture.GetLayout(), 1, &ic);
|
||||
m_vram_texture.TransitionToLayout(buf, old_vram_layout);
|
||||
tex->TransitionToLayout(buf, old_tex_layout);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vulkan::Texture* tex = static_cast<Vulkan::Texture*>(*host_texture);
|
||||
if (!tex || tex->GetWidth() != m_vram_texture.GetWidth() || tex->GetHeight() != m_vram_texture.GetHeight() ||
|
||||
tex->GetSamples() != static_cast<u32>(m_vram_texture.GetSamples()))
|
||||
{
|
||||
delete tex;
|
||||
|
||||
tex = static_cast<Vulkan::Texture*>(
|
||||
g_host_display
|
||||
->CreateTexture(m_vram_texture.GetWidth(), m_vram_texture.GetHeight(), 1, 1, m_vram_texture.GetSamples(),
|
||||
GPUTexture::Type::RenderTarget, GPUTexture::Format::RGBA8, nullptr, 0, false)
|
||||
.release());
|
||||
*host_texture = tex;
|
||||
if (!tex)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tex->GetWidth() != m_vram_texture.GetWidth() || tex->GetHeight() != m_vram_texture.GetHeight() ||
|
||||
tex->GetSamples() != m_vram_texture.GetSamples())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const VkImageLayout old_vram_layout = m_vram_texture.GetLayout();
|
||||
tex->TransitionToLayout(buf, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
m_vram_texture.TransitionToLayout(buf, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
vkCmdCopyImage(g_vulkan_context->GetCurrentCommandBuffer(), m_vram_texture.GetImage(), m_vram_texture.GetLayout(),
|
||||
tex->GetImage(), tex->GetLayout(), 1, &ic);
|
||||
m_vram_texture.TransitionToLayout(buf, old_vram_layout);
|
||||
tex->TransitionToLayout(buf, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
}
|
||||
}
|
||||
|
||||
return GPU_HW::DoState(sw, host_texture, update_display);
|
||||
}
|
||||
|
||||
void GPU_HW_Vulkan::ResetGraphicsAPIState()
|
||||
{
|
||||
GPU_HW::ResetGraphicsAPIState();
|
||||
|
@ -1720,6 +1650,7 @@ void GPU_HW_Vulkan::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 wid
|
|||
m_vram_texture.TransitionToLayout(cmdbuf, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void GPU_HW_Vulkan::UpdateVRAMReadTexture()
|
||||
{
|
||||
EndRenderPass();
|
||||
|
@ -1757,6 +1688,7 @@ void GPU_HW_Vulkan::UpdateVRAMReadTexture()
|
|||
m_vram_texture.TransitionToLayout(cmdbuf, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
GPU_HW::UpdateVRAMReadTexture();
|
||||
}
|
||||
#endif
|
||||
|
||||
void GPU_HW_Vulkan::UpdateDepthBufferFromMaskBit()
|
||||
{
|
||||
|
|
|
@ -21,7 +21,6 @@ public:
|
|||
|
||||
bool Initialize() override;
|
||||
void Reset(bool clear_vram) override;
|
||||
bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override;
|
||||
|
||||
void ResetGraphicsAPIState() override;
|
||||
void RestoreGraphicsAPIState() override;
|
||||
|
@ -34,7 +33,6 @@ protected:
|
|||
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
|
||||
void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) override;
|
||||
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height) override;
|
||||
void UpdateVRAMReadTexture() override;
|
||||
void UpdateDepthBufferFromMaskBit() override;
|
||||
void ClearDepthBuffer() override;
|
||||
void SetScissorFromDrawingArea() override;
|
||||
|
|
Loading…
Reference in New Issue