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));
|
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)
|
bool D3D11Device::GetHostRefreshRate(float* refresh_rate)
|
||||||
{
|
{
|
||||||
if (m_swap_chain && IsFullscreen())
|
if (m_swap_chain && IsFullscreen())
|
||||||
|
@ -751,9 +791,7 @@ bool D3D11Device::Render(bool skip_present)
|
||||||
{
|
{
|
||||||
if (skip_present || !m_swap_chain)
|
if (skip_present || !m_swap_chain)
|
||||||
{
|
{
|
||||||
if (ImGui::GetCurrentContext())
|
ImGui::Render();
|
||||||
ImGui::Render();
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -771,8 +809,7 @@ bool D3D11Device::Render(bool skip_present)
|
||||||
static_cast<float>(m_window_info.surface_height), 0.0f, 1.0f);
|
static_cast<float>(m_window_info.surface_height), 0.0f, 1.0f);
|
||||||
m_context->RSSetViewports(1, &vp);
|
m_context->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
if (ImGui::GetCurrentContext())
|
RenderImGui();
|
||||||
RenderImGui();
|
|
||||||
|
|
||||||
RenderSoftwareCursor();
|
RenderSoftwareCursor();
|
||||||
|
|
||||||
|
|
|
@ -54,11 +54,16 @@ public:
|
||||||
bool SetPostProcessingChain(const std::string_view& config) override;
|
bool SetPostProcessingChain(const std::string_view& config) override;
|
||||||
|
|
||||||
std::unique_ptr<GPUTexture> CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples,
|
std::unique_ptr<GPUTexture> CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples,
|
||||||
GPUTexture::Type type, GPUTexture::Format format, const void* data,
|
GPUTexture::Type type, GPUTexture::Format format,
|
||||||
u32 data_stride, bool dynamic = false) override;
|
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,
|
bool DownloadTexture(GPUTexture* texture, u32 x, u32 y, u32 width, u32 height, void* out_data,
|
||||||
u32 out_data_stride) override;
|
u32 out_data_stride) override;
|
||||||
bool SupportsTextureFormat(GPUTexture::Format format) const 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;
|
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() = default;
|
||||||
|
|
||||||
D3D11Texture::D3D11Texture(ComPtr<ID3D11Texture2D> texture, ComPtr<ID3D11ShaderResourceView> srv,
|
D3D11Texture::D3D11Texture(ComPtr<ID3D11Texture2D> texture, ComPtr<ID3D11ShaderResourceView> srv,
|
||||||
ComPtr<ID3D11RenderTargetView> rtv)
|
ComPtr<ID3D11View> rtv)
|
||||||
: m_texture(std::move(texture)), m_srv(std::move(srv)), m_rtv(std::move(rtv))
|
: m_texture(std::move(texture)), m_srv(std::move(srv)), m_rtv_dsv(std::move(rtv))
|
||||||
{
|
{
|
||||||
const D3D11_TEXTURE2D_DESC desc = GetDesc();
|
const D3D11_TEXTURE2D_DESC desc = GetDesc();
|
||||||
m_width = static_cast<u16>(desc.Width);
|
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)
|
if (bind_flags & D3D11_BIND_RENDER_TARGET)
|
||||||
{
|
{
|
||||||
const D3D11_RTV_DIMENSION rtv_dimension =
|
const D3D11_RTV_DIMENSION rtv_dimension =
|
||||||
(desc.SampleDesc.Count > 1) ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
|
(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 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());
|
const HRESULT hr = device->CreateRenderTargetView(texture.Get(), &rtv_desc, rtv.GetAddressOf());
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("Create RTV for texture failed: 0x%08X", hr);
|
Log_ErrorPrintf("Create RTV for texture failed: 0x%08X", hr);
|
||||||
return false;
|
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_texture = std::move(texture);
|
||||||
m_srv = std::move(srv);
|
m_srv = std::move(srv);
|
||||||
m_rtv = std::move(rtv);
|
m_rtv_dsv = std::move(rtv_dsv);
|
||||||
m_width = static_cast<u16>(width);
|
m_width = static_cast<u16>(width);
|
||||||
m_height = static_cast<u16>(height);
|
m_height = static_cast<u16>(height);
|
||||||
m_layers = static_cast<u8>(layers);
|
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)
|
if (desc.BindFlags & D3D11_BIND_RENDER_TARGET)
|
||||||
{
|
{
|
||||||
const D3D11_RTV_DIMENSION rtv_dimension =
|
const D3D11_RTV_DIMENSION rtv_dimension =
|
||||||
(desc.SampleDesc.Count > 1) ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
|
(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 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))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("Create RTV for adopted texture failed: 0x%08X", hr);
|
Log_ErrorPrintf("Create RTV for adopted texture failed: 0x%08X", hr);
|
||||||
return false;
|
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_texture = std::move(texture);
|
||||||
m_srv = std::move(srv);
|
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_width = static_cast<u16>(desc.Width);
|
||||||
m_height = static_cast<u16>(desc.Height);
|
m_height = static_cast<u16>(desc.Height);
|
||||||
m_layers = static_cast<u8>(desc.ArraySize);
|
m_layers = static_cast<u8>(desc.ArraySize);
|
||||||
|
@ -253,7 +289,7 @@ bool D3D11Texture::Adopt(ID3D11Device* device, ComPtr<ID3D11Texture2D> texture)
|
||||||
|
|
||||||
void D3D11Texture::Destroy()
|
void D3D11Texture::Destroy()
|
||||||
{
|
{
|
||||||
m_rtv.Reset();
|
m_rtv_dsv.Reset();
|
||||||
m_srv.Reset();
|
m_srv.Reset();
|
||||||
m_texture.Reset();
|
m_texture.Reset();
|
||||||
m_dynamic = false;
|
m_dynamic = false;
|
||||||
|
|
|
@ -14,8 +14,7 @@ public:
|
||||||
using ComPtr = Microsoft::WRL::ComPtr<T>;
|
using ComPtr = Microsoft::WRL::ComPtr<T>;
|
||||||
|
|
||||||
D3D11Texture();
|
D3D11Texture();
|
||||||
D3D11Texture(ComPtr<ID3D11Texture2D> texture, ComPtr<ID3D11ShaderResourceView> srv,
|
D3D11Texture(ComPtr<ID3D11Texture2D> texture, ComPtr<ID3D11ShaderResourceView> srv, ComPtr<ID3D11View> rtv);
|
||||||
ComPtr<ID3D11RenderTargetView> rtv);
|
|
||||||
~D3D11Texture();
|
~D3D11Texture();
|
||||||
|
|
||||||
static DXGI_FORMAT GetDXGIFormat(Format format);
|
static DXGI_FORMAT GetDXGIFormat(Format format);
|
||||||
|
@ -23,15 +22,32 @@ public:
|
||||||
|
|
||||||
ALWAYS_INLINE ID3D11Texture2D* GetD3DTexture() const { return m_texture.Get(); }
|
ALWAYS_INLINE ID3D11Texture2D* GetD3DTexture() const { return m_texture.Get(); }
|
||||||
ALWAYS_INLINE ID3D11ShaderResourceView* GetD3DSRV() const { return m_srv.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 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 DXGI_FORMAT GetDXGIFormat() const { return GetDXGIFormat(m_format); }
|
||||||
ALWAYS_INLINE bool IsDynamic() const { return m_dynamic; }
|
ALWAYS_INLINE bool IsDynamic() const { return m_dynamic; }
|
||||||
|
|
||||||
ALWAYS_INLINE operator ID3D11Texture2D*() const { return m_texture.Get(); }
|
ALWAYS_INLINE operator ID3D11Texture2D*() const { return m_texture.Get(); }
|
||||||
ALWAYS_INLINE operator ID3D11ShaderResourceView*() const { return m_srv.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); }
|
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,
|
bool Create(ID3D11Device* device, u32 width, u32 height, u32 layers, u32 levels, u32 samples, Type type,
|
||||||
|
@ -51,7 +67,7 @@ public:
|
||||||
private:
|
private:
|
||||||
ComPtr<ID3D11Texture2D> m_texture;
|
ComPtr<ID3D11Texture2D> m_texture;
|
||||||
ComPtr<ID3D11ShaderResourceView> m_srv;
|
ComPtr<ID3D11ShaderResourceView> m_srv;
|
||||||
ComPtr<ID3D11RenderTargetView> m_rtv;
|
ComPtr<ID3D11View> m_rtv_dsv;
|
||||||
u32 m_mapped_subresource = 0;
|
u32 m_mapped_subresource = 0;
|
||||||
bool m_dynamic = false;
|
bool m_dynamic = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,6 +39,21 @@ void GPUDevice::DestroyResources()
|
||||||
m_imgui_font_texture.reset();
|
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)
|
bool GPUDevice::ParseFullscreenMode(const std::string_view& mode, u32* width, u32* height, float* refresh_rate)
|
||||||
{
|
{
|
||||||
if (!mode.empty())
|
if (!mode.empty())
|
||||||
|
|
|
@ -90,10 +90,16 @@ public:
|
||||||
|
|
||||||
/// Creates an abstracted RGBA8 texture. If dynamic, the texture can be updated with UpdateTexture() below.
|
/// 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,
|
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,
|
GPUTexture::Type type, GPUTexture::Format format,
|
||||||
u32 data_stride, bool dynamic = false) = 0;
|
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,
|
virtual bool DownloadTexture(GPUTexture* texture, u32 x, u32 y, u32 width, u32 height, void* out_data,
|
||||||
u32 out_data_stride) = 0;
|
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.
|
/// Returns false if the window was completely occluded.
|
||||||
virtual bool Render(bool skip_present) = 0;
|
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))
|
if (!GPU::DoState(sw, host_texture, update_display))
|
||||||
return false;
|
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
|
// invalidate the whole VRAM read texture when loading state
|
||||||
if (sw.IsReading())
|
if (sw.IsReading())
|
||||||
{
|
{
|
||||||
|
@ -303,8 +339,64 @@ void GPU_HW::PrintSettingsToLog()
|
||||||
Log_InfoPrintf("Using software renderer for readbacks: %s", m_sw_renderer ? "YES" : "NO");
|
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()
|
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++;
|
m_renderer_stats.num_vram_read_texture_updates++;
|
||||||
ClearVRAMDirtyRectangle();
|
ClearVRAMDirtyRectangle();
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,7 +200,9 @@ protected:
|
||||||
|
|
||||||
void UpdateHWSettings(bool* framebuffer_changed, bool* shaders_changed);
|
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 UpdateDepthBufferFromMaskBit() = 0;
|
||||||
virtual void ClearDepthBuffer() = 0;
|
virtual void ClearDepthBuffer() = 0;
|
||||||
virtual void SetScissorFromDrawingArea() = 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,
|
SmoothingUBOData GetSmoothingUBO(u32 level, u32 left, u32 top, u32 width, u32 height, u32 tex_width,
|
||||||
u32 tex_height) const;
|
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;
|
HeapArray<u16, VRAM_WIDTH * VRAM_HEIGHT> m_vram_shadow;
|
||||||
|
|
||||||
std::unique_ptr<GPU_SW_Backend> m_sw_renderer;
|
std::unique_ptr<GPU_SW_Backend> m_sw_renderer;
|
||||||
|
|
||||||
BatchVertex* m_batch_start_vertex_ptr = nullptr;
|
BatchVertex* m_batch_start_vertex_ptr = nullptr;
|
||||||
|
|
|
@ -84,53 +84,10 @@ void GPU_HW_D3D11::Reset(bool clear_vram)
|
||||||
ClearFramebuffer();
|
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()
|
void GPU_HW_D3D11::ResetGraphicsAPIState()
|
||||||
{
|
{
|
||||||
GPU_HW::ResetGraphicsAPIState();
|
GPU_HW::ResetGraphicsAPIState();
|
||||||
|
|
||||||
m_context->GSSetShader(nullptr, nullptr, 0);
|
|
||||||
|
|
||||||
// In D3D11 we can't leave a buffer mapped across a Present() call.
|
// In D3D11 we can't leave a buffer mapped across a Present() call.
|
||||||
FlushRender();
|
FlushRender();
|
||||||
}
|
}
|
||||||
|
@ -142,12 +99,11 @@ void GPU_HW_D3D11::RestoreGraphicsAPIState()
|
||||||
m_context->IASetVertexBuffers(0, 1, m_vertex_stream_buffer.GetD3DBufferArray(), &stride, &offset);
|
m_context->IASetVertexBuffers(0, 1, m_vertex_stream_buffer.GetD3DBufferArray(), &stride, &offset);
|
||||||
m_context->IASetInputLayout(m_batch_input_layout.Get());
|
m_context->IASetInputLayout(m_batch_input_layout.Get());
|
||||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
m_context->GSSetShader(nullptr, nullptr, 0);
|
m_context->PSSetShaderResources(0, 1, GetVRAMReadTexture()->GetD3DSRVArray());
|
||||||
m_context->PSSetShaderResources(0, 1, m_vram_read_texture.GetD3DSRVArray());
|
|
||||||
m_context->PSSetSamplers(0, 1, m_point_sampler_state.GetAddressOf());
|
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());
|
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();
|
SetScissorFromDrawingArea();
|
||||||
m_batch_ubo_dirty = true;
|
m_batch_ubo_dirty = true;
|
||||||
}
|
}
|
||||||
|
@ -234,38 +190,12 @@ void GPU_HW_D3D11::SetCapabilities()
|
||||||
|
|
||||||
bool GPU_HW_D3D11::CreateFramebuffer()
|
bool GPU_HW_D3D11::CreateFramebuffer()
|
||||||
{
|
{
|
||||||
DestroyFramebuffer();
|
if (!GPU_HW::CreateFramebuffer())
|
||||||
|
|
||||||
// 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))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
const CD3D11_DEPTH_STENCIL_VIEW_DESC depth_view_desc(samples > 1 ? D3D11_DSV_DIMENSION_TEXTURE2DMS :
|
const u32 texture_width = m_vram_texture->GetWidth();
|
||||||
D3D11_DSV_DIMENSION_TEXTURE2D,
|
const u32 texture_height = m_vram_texture->GetHeight();
|
||||||
D3D11Texture::GetDXGIFormat(depth_format));
|
const GPUTexture::Format texture_format = m_vram_texture->GetFormat();
|
||||||
HRESULT hr =
|
|
||||||
m_device->CreateDepthStencilView(m_vram_depth_texture, &depth_view_desc, m_vram_depth_view.GetAddressOf());
|
|
||||||
if (FAILED(hr))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_downsample_mode == GPUDownsampleMode::Adaptive)
|
if (m_downsample_mode == GPUDownsampleMode::Adaptive)
|
||||||
{
|
{
|
||||||
|
@ -288,8 +218,8 @@ bool GPU_HW_D3D11::CreateFramebuffer()
|
||||||
const CD3D11_RENDER_TARGET_VIEW_DESC rtv_desc(m_downsample_texture, D3D11_RTV_DIMENSION_TEXTURE2D,
|
const CD3D11_RENDER_TARGET_VIEW_DESC rtv_desc(m_downsample_texture, D3D11_RTV_DIMENSION_TEXTURE2D,
|
||||||
m_downsample_texture.GetDXGIFormat(), i, 1);
|
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());
|
m_downsample_mip_views[i].first.GetAddressOf());
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return false;
|
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();
|
SetFullVRAMDirtyRectangle();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -316,9 +246,10 @@ bool GPU_HW_D3D11::CreateFramebuffer()
|
||||||
void GPU_HW_D3D11::ClearFramebuffer()
|
void GPU_HW_D3D11::ClearFramebuffer()
|
||||||
{
|
{
|
||||||
static constexpr std::array<float, 4> color = {};
|
static constexpr std::array<float, 4> color = {};
|
||||||
m_context->ClearRenderTargetView(m_vram_texture.GetD3DRTV(), color.data());
|
m_context->ClearRenderTargetView(GetVRAMTexture()->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->ClearDepthStencilView(GetVRAMDepthTexture()->GetD3DDSV(), D3D11_CLEAR_DEPTH,
|
||||||
m_context->ClearRenderTargetView(m_display_texture, color.data());
|
m_pgxp_depth_buffer ? 1.0f : 0.0f, 0);
|
||||||
|
m_context->ClearRenderTargetView(GetDisplayTexture()->GetD3DRTV(), color.data());
|
||||||
SetFullVRAMDirtyRectangle();
|
SetFullVRAMDirtyRectangle();
|
||||||
m_last_depth_z = 1.0f;
|
m_last_depth_z = 1.0f;
|
||||||
}
|
}
|
||||||
|
@ -329,12 +260,7 @@ void GPU_HW_D3D11::DestroyFramebuffer()
|
||||||
m_downsample_weight_texture.Destroy();
|
m_downsample_weight_texture.Destroy();
|
||||||
m_downsample_texture.Destroy();
|
m_downsample_texture.Destroy();
|
||||||
|
|
||||||
m_vram_read_texture.Destroy();
|
GPU_HW::DestroyFramebuffer();
|
||||||
m_vram_depth_view.Reset();
|
|
||||||
m_vram_depth_texture.Destroy();
|
|
||||||
m_vram_texture.Destroy();
|
|
||||||
m_vram_encoding_texture.Destroy();
|
|
||||||
m_display_texture.Destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPU_HW_D3D11::CreateVertexBuffer()
|
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->VSSetShader(m_screen_quad_vertex_shader.Get(), nullptr, 0);
|
||||||
m_context->GSSetShader(nullptr, nullptr, 0);
|
|
||||||
m_context->PSSetShader(shader, nullptr, 0);
|
m_context->PSSetShader(shader, nullptr, 0);
|
||||||
m_context->OMSetBlendState(m_blend_disabled_state.Get(), nullptr, 0xFFFFFFFFu);
|
m_context->OMSetBlendState(m_blend_disabled_state.Get(), nullptr, 0xFFFFFFFFu);
|
||||||
|
|
||||||
|
@ -814,7 +739,7 @@ void GPU_HW_D3D11::ClearDisplay()
|
||||||
g_host_display->ClearDisplayTexture();
|
g_host_display->ClearDisplayTexture();
|
||||||
|
|
||||||
static constexpr std::array<float, 4> clear_color = {0.0f, 0.0f, 0.0f, 1.0f};
|
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()
|
void GPU_HW_D3D11::UpdateDisplay()
|
||||||
|
@ -826,12 +751,13 @@ void GPU_HW_D3D11::UpdateDisplay()
|
||||||
if (IsUsingMultisampling())
|
if (IsUsingMultisampling())
|
||||||
{
|
{
|
||||||
UpdateVRAMReadTexture();
|
UpdateVRAMReadTexture();
|
||||||
g_host_display->SetDisplayTexture(&m_vram_read_texture, 0, 0, m_vram_read_texture.GetWidth(),
|
g_host_display->SetDisplayTexture(m_vram_read_texture.get(), 0, 0, GetVRAMReadTexture()->GetWidth(),
|
||||||
m_vram_read_texture.GetHeight());
|
GetVRAMReadTexture()->GetHeight());
|
||||||
}
|
}
|
||||||
else
|
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,
|
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();
|
g_host_display->ClearDisplayTexture();
|
||||||
}
|
}
|
||||||
else if (!m_GPUSTAT.display_area_color_depth_24 && interlaced == InterlacedRenderMode::None &&
|
else if (!m_GPUSTAT.display_area_color_depth_24 && interlaced == InterlacedRenderMode::None &&
|
||||||
!IsUsingMultisampling() && (scaled_vram_offset_x + scaled_display_width) <= m_vram_texture.GetWidth() &&
|
!IsUsingMultisampling() && (scaled_vram_offset_x + scaled_display_width) <= GetVRAMTexture()->GetWidth() &&
|
||||||
(scaled_vram_offset_y + scaled_display_height) <= m_vram_texture.GetHeight())
|
(scaled_vram_offset_y + scaled_display_height) <= GetVRAMTexture()->GetHeight())
|
||||||
{
|
{
|
||||||
|
|
||||||
if (IsUsingDownsampling())
|
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);
|
scaled_display_height);
|
||||||
}
|
}
|
||||||
else
|
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);
|
scaled_display_width, scaled_display_height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_context->RSSetState(m_cull_none_rasterizer_state_no_msaa.Get());
|
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->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_field_offset = (interlaced != InterlacedRenderMode::None) ? GetInterlacedDisplayField() : 0;
|
||||||
const u32 reinterpret_start_x = m_crtc_state.regs.X * resolution_scale;
|
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 =
|
ID3D11PixelShader* display_pixel_shader =
|
||||||
m_display_pixel_shaders[BoolToUInt8(m_GPUSTAT.display_area_color_depth_24)][static_cast<u8>(interlaced)].Get();
|
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() &&
|
Assert(scaled_display_width <= m_display_texture->GetWidth() &&
|
||||||
scaled_display_height <= m_display_texture.GetHeight());
|
scaled_display_height <= m_display_texture->GetHeight());
|
||||||
|
|
||||||
SetViewportAndScissor(0, 0, scaled_display_width, scaled_display_height);
|
SetViewportAndScissor(0, 0, scaled_display_width, scaled_display_height);
|
||||||
DrawUtilityShader(display_pixel_shader, uniforms, sizeof(uniforms));
|
DrawUtilityShader(display_pixel_shader, uniforms, sizeof(uniforms));
|
||||||
|
|
||||||
if (IsUsingDownsampling())
|
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
|
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();
|
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.
|
// Encode the 24-bit texture as 16-bit.
|
||||||
const u32 uniforms[4] = {copy_rect.left, copy_rect.top, copy_rect.GetWidth(), copy_rect.GetHeight()};
|
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->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->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);
|
SetViewportAndScissor(0, 0, encoded_width, encoded_height);
|
||||||
DrawUtilityShader(m_vram_read_pixel_shader.Get(), uniforms, sizeof(uniforms));
|
DrawUtilityShader(m_vram_read_pixel_shader.Get(), uniforms, sizeof(uniforms));
|
||||||
|
|
||||||
// Stage the readback and copy it into our shadow buffer.
|
// 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]),
|
reinterpret_cast<u32*>(&m_vram_shadow[copy_rect.top * VRAM_WIDTH + copy_rect.left]),
|
||||||
VRAM_WIDTH * sizeof(u16));
|
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_greater_state.Get() :
|
||||||
m_depth_test_always_state.Get(),
|
m_depth_test_always_state.Get(),
|
||||||
0);
|
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));
|
DrawUtilityShader(m_vram_copy_pixel_shader.Get(), &uniforms, sizeof(uniforms));
|
||||||
RestoreGraphicsAPIState();
|
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;
|
height *= m_resolution_scale;
|
||||||
|
|
||||||
const CD3D11_BOX src_box(src_x, src_y, 0, src_x + width, src_y + height, 1);
|
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);
|
m_context->CopySubresourceRegion(GetVRAMTexture()->GetD3DTexture(), 0, dst_x, dst_y, 0,
|
||||||
}
|
GetVRAMReadTexture()->GetD3DTexture(), 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_D3D11::UpdateDepthBufferFromMaskBit()
|
void GPU_HW_D3D11::UpdateDepthBufferFromMaskBit()
|
||||||
|
@ -1071,16 +979,16 @@ void GPU_HW_D3D11::UpdateDepthBufferFromMaskBit()
|
||||||
if (m_pgxp_depth_buffer)
|
if (m_pgxp_depth_buffer)
|
||||||
return;
|
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->OMSetDepthStencilState(m_depth_test_always_state.Get(), 0);
|
||||||
m_context->OMSetBlendState(m_blend_no_color_writes_state.Get(), nullptr, 0xFFFFFFFFu);
|
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);
|
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();
|
RestoreGraphicsAPIState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1088,11 +996,11 @@ void GPU_HW_D3D11::ClearDepthBuffer()
|
||||||
{
|
{
|
||||||
DebugAssert(m_pgxp_depth_buffer);
|
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;
|
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)
|
if (m_downsample_mode == GPUDownsampleMode::Adaptive)
|
||||||
DownsampleFramebufferAdaptive(source, left, top, width, height);
|
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);
|
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);
|
CD3D11_BOX src_box(left, top, 0, left + width, top + height, 1);
|
||||||
m_context->OMSetDepthStencilState(m_depth_disabled_state.Get(), 0);
|
m_context->OMSetDepthStencilState(m_depth_disabled_state.Get(), 0);
|
||||||
m_context->OMSetBlendState(m_blend_disabled_state.Get(), nullptr, 0xFFFFFFFFu);
|
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->PSSetSamplers(0, 1, m_point_sampler_state.GetAddressOf());
|
||||||
m_context->VSSetShader(m_uv_quad_vertex_shader.Get(), nullptr, 0);
|
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
|
// composite downsampled and upsampled images together
|
||||||
{
|
{
|
||||||
SetViewportAndScissor(left, top, width, height);
|
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(),
|
ID3D11ShaderResourceView* const srvs[2] = {m_downsample_texture.GetD3DSRV(),
|
||||||
m_downsample_weight_texture.GetD3DSRV()};
|
m_downsample_weight_texture.GetD3DSRV()};
|
||||||
|
@ -1166,10 +1074,10 @@ void GPU_HW_D3D11::DownsampleFramebufferAdaptive(D3D11Texture& source, u32 left,
|
||||||
|
|
||||||
RestoreGraphicsAPIState();
|
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_left = left / m_resolution_scale;
|
||||||
const u32 ds_top = top / 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->OMSetBlendState(m_blend_disabled_state.Get(), nullptr, 0xFFFFFFFFu);
|
||||||
m_context->VSSetShader(m_screen_quad_vertex_shader.Get(), nullptr, 0);
|
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->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);
|
SetViewportAndScissor(ds_left, ds_top, ds_width, ds_height);
|
||||||
m_context->Draw(3, 0);
|
m_context->Draw(3, 0);
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ public:
|
||||||
|
|
||||||
bool Initialize() override;
|
bool Initialize() override;
|
||||||
void Reset(bool clear_vram) override;
|
void Reset(bool clear_vram) override;
|
||||||
bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override;
|
|
||||||
|
|
||||||
void ResetGraphicsAPIState() override;
|
void ResetGraphicsAPIState() override;
|
||||||
void RestoreGraphicsAPIState() override;
|
void RestoreGraphicsAPIState() override;
|
||||||
|
@ -39,7 +38,6 @@ protected:
|
||||||
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
|
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 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 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 UpdateDepthBufferFromMaskBit() override;
|
||||||
void ClearDepthBuffer() override;
|
void ClearDepthBuffer() override;
|
||||||
void SetScissorFromDrawingArea() override;
|
void SetScissorFromDrawingArea() override;
|
||||||
|
@ -55,10 +53,28 @@ private:
|
||||||
MAX_UNIFORM_BUFFER_SIZE = 64
|
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();
|
void SetCapabilities();
|
||||||
bool CreateFramebuffer();
|
bool CreateFramebuffer() override;
|
||||||
void ClearFramebuffer();
|
void ClearFramebuffer();
|
||||||
void DestroyFramebuffer();
|
void DestroyFramebuffer() override;
|
||||||
|
|
||||||
bool CreateVertexBuffer();
|
bool CreateVertexBuffer();
|
||||||
bool CreateUniformBuffer();
|
bool CreateUniformBuffer();
|
||||||
|
@ -76,21 +92,13 @@ private:
|
||||||
|
|
||||||
bool BlitVRAMReplacementTexture(const TextureReplacementTexture* tex, u32 dst_x, u32 dst_y, u32 width, u32 height);
|
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 DownsampleFramebuffer(const D3D11Texture* source, u32 left, u32 top, u32 width, u32 height);
|
||||||
void DownsampleFramebufferAdaptive(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(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<ID3D11Device> m_device;
|
||||||
ComPtr<ID3D11DeviceContext> m_context;
|
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_vertex_stream_buffer;
|
||||||
|
|
||||||
D3D11::StreamBuffer m_uniform_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);
|
m_vram_texture.TransitionToState(D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
void GPU_HW_D3D12::UpdateVRAMReadTexture()
|
void GPU_HW_D3D12::UpdateVRAMReadTexture()
|
||||||
{
|
{
|
||||||
ID3D12GraphicsCommandList* cmdlist = g_d3d12_context->GetCommandList();
|
ID3D12GraphicsCommandList* cmdlist = g_d3d12_context->GetCommandList();
|
||||||
|
@ -1157,6 +1159,8 @@ void GPU_HW_D3D12::UpdateVRAMReadTexture()
|
||||||
GPU_HW::UpdateVRAMReadTexture();
|
GPU_HW::UpdateVRAMReadTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void GPU_HW_D3D12::UpdateDepthBufferFromMaskBit()
|
void GPU_HW_D3D12::UpdateDepthBufferFromMaskBit()
|
||||||
{
|
{
|
||||||
ID3D12GraphicsCommandList* cmdlist = g_d3d12_context->GetCommandList();
|
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 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 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 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 UpdateDepthBufferFromMaskBit() override;
|
||||||
void ClearDepthBuffer() override;
|
void ClearDepthBuffer() override;
|
||||||
void SetScissorFromDrawingArea() override;
|
void SetScissorFromDrawingArea() override;
|
||||||
|
|
|
@ -89,49 +89,7 @@ void GPU_HW_OpenGL::Reset(bool clear_vram)
|
||||||
ClearFramebuffer();
|
ClearFramebuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPU_HW_OpenGL::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display)
|
#if 0
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPU_HW_OpenGL::CopyFramebufferForState(GLenum target, GLuint src_texture, u32 src_fbo, u32 src_x, u32 src_y,
|
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,
|
GLuint dst_texture, u32 dst_fbo, u32 dst_x, u32 dst_y, u32 width,
|
||||||
u32 height)
|
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);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_vram_fbo_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void GPU_HW_OpenGL::ResetGraphicsAPIState()
|
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);
|
IncludeVRAMDirtyRectangle(dst_bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
void GPU_HW_OpenGL::UpdateVRAMReadTexture()
|
void GPU_HW_OpenGL::UpdateVRAMReadTexture()
|
||||||
{
|
{
|
||||||
const auto scaled_rect = m_vram_dirty_rect * m_resolution_scale;
|
const auto scaled_rect = m_vram_dirty_rect * m_resolution_scale;
|
||||||
|
@ -1245,6 +1205,7 @@ void GPU_HW_OpenGL::UpdateVRAMReadTexture()
|
||||||
|
|
||||||
GPU_HW::UpdateVRAMReadTexture();
|
GPU_HW::UpdateVRAMReadTexture();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void GPU_HW_OpenGL::UpdateDepthBufferFromMaskBit()
|
void GPU_HW_OpenGL::UpdateDepthBufferFromMaskBit()
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,7 +23,6 @@ public:
|
||||||
|
|
||||||
bool Initialize() override;
|
bool Initialize() override;
|
||||||
void Reset(bool clear_vram) override;
|
void Reset(bool clear_vram) override;
|
||||||
bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override;
|
|
||||||
|
|
||||||
void ResetGraphicsAPIState() override;
|
void ResetGraphicsAPIState() override;
|
||||||
void RestoreGraphicsAPIState() override;
|
void RestoreGraphicsAPIState() override;
|
||||||
|
@ -36,7 +35,6 @@ protected:
|
||||||
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
|
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 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 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 UpdateDepthBufferFromMaskBit() override;
|
||||||
void ClearDepthBuffer() override;
|
void ClearDepthBuffer() override;
|
||||||
void SetScissorFromDrawingArea() override;
|
void SetScissorFromDrawingArea() override;
|
||||||
|
@ -61,8 +59,6 @@ private:
|
||||||
void SetCapabilities();
|
void SetCapabilities();
|
||||||
bool CreateFramebuffer();
|
bool CreateFramebuffer();
|
||||||
void ClearFramebuffer();
|
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 CreateVertexBuffer();
|
||||||
bool CreateUniformBuffer();
|
bool CreateUniformBuffer();
|
||||||
|
|
|
@ -93,76 +93,6 @@ void GPU_HW_Vulkan::Reset(bool clear_vram)
|
||||||
ClearFramebuffer();
|
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()
|
void GPU_HW_Vulkan::ResetGraphicsAPIState()
|
||||||
{
|
{
|
||||||
GPU_HW::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);
|
m_vram_texture.TransitionToLayout(cmdbuf, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
void GPU_HW_Vulkan::UpdateVRAMReadTexture()
|
void GPU_HW_Vulkan::UpdateVRAMReadTexture()
|
||||||
{
|
{
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
|
@ -1757,6 +1688,7 @@ void GPU_HW_Vulkan::UpdateVRAMReadTexture()
|
||||||
m_vram_texture.TransitionToLayout(cmdbuf, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
m_vram_texture.TransitionToLayout(cmdbuf, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
GPU_HW::UpdateVRAMReadTexture();
|
GPU_HW::UpdateVRAMReadTexture();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void GPU_HW_Vulkan::UpdateDepthBufferFromMaskBit()
|
void GPU_HW_Vulkan::UpdateDepthBufferFromMaskBit()
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,7 +21,6 @@ public:
|
||||||
|
|
||||||
bool Initialize() override;
|
bool Initialize() override;
|
||||||
void Reset(bool clear_vram) override;
|
void Reset(bool clear_vram) override;
|
||||||
bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override;
|
|
||||||
|
|
||||||
void ResetGraphicsAPIState() override;
|
void ResetGraphicsAPIState() override;
|
||||||
void RestoreGraphicsAPIState() override;
|
void RestoreGraphicsAPIState() override;
|
||||||
|
@ -34,7 +33,6 @@ protected:
|
||||||
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color) override;
|
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 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 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 UpdateDepthBufferFromMaskBit() override;
|
||||||
void ClearDepthBuffer() override;
|
void ClearDepthBuffer() override;
|
||||||
void SetScissorFromDrawingArea() override;
|
void SetScissorFromDrawingArea() override;
|
||||||
|
|
Loading…
Reference in New Issue