Move FB to GPU_HW

This commit is contained in:
Stenzek 2023-07-30 22:59:54 +10:00
parent 12fbeb9280
commit 9b967e3751
16 changed files with 321 additions and 299 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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;
};

View File

@ -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())

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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()
{

View File

@ -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();

View File

@ -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()
{

View File

@ -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;