wip
This commit is contained in:
parent
cb127b6412
commit
20426d96b0
|
@ -113,15 +113,19 @@ public:
|
|||
/// Call when the window size changes externally to recreate any resources.
|
||||
virtual void ResizeRenderWindow(s32 new_window_width, s32 new_window_height) = 0;
|
||||
|
||||
virtual bool SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const = 0;
|
||||
|
||||
/// Creates an abstracted RGBA8 texture. If dynamic, the texture can be updated with UpdateTexture() below.
|
||||
virtual std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples,
|
||||
HostDisplayPixelFormat format, const void* data,
|
||||
u32 data_stride, bool dynamic = false) = 0;
|
||||
virtual void UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, const void* data,
|
||||
u32 data_stride) = 0;
|
||||
|
||||
virtual bool DownloadTexture(const void* texture_handle, HostDisplayPixelFormat texture_format, u32 x, u32 y,
|
||||
u32 width, u32 height, void* out_data, u32 out_data_stride) = 0;
|
||||
virtual bool MapTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch) = 0;
|
||||
virtual void UnmapTexture(HostDisplayTexture* texture) = 0;
|
||||
|
||||
/// Returns false if the window was completely occluded.
|
||||
virtual bool Render() = 0;
|
||||
|
@ -137,6 +141,8 @@ public:
|
|||
virtual void DestroyImGuiContext() = 0;
|
||||
virtual bool UpdateImGuiFontTexture() = 0;
|
||||
|
||||
virtual bool GetHostRefreshRate(float* refresh_rate);
|
||||
|
||||
const void* GetDisplayTextureHandle() const { return m_display_texture_handle; }
|
||||
const s32 GetDisplayTopMargin() const { return m_display_top_margin; }
|
||||
const s32 GetDisplayWidth() const { return m_display_width; }
|
||||
|
@ -200,15 +206,6 @@ public:
|
|||
HostDisplayPixelFormat format);
|
||||
static void FlipTextureDataRGBA8(u32 width, u32 height, std::vector<u32>& texture_data, u32 texture_data_stride);
|
||||
|
||||
virtual bool SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const = 0;
|
||||
|
||||
virtual bool BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch) = 0;
|
||||
virtual void EndSetDisplayPixels() = 0;
|
||||
virtual bool SetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, const void* buffer, u32 pitch);
|
||||
|
||||
virtual bool GetHostRefreshRate(float* refresh_rate);
|
||||
|
||||
void SetDisplayLinearFiltering(bool enabled) { m_display_linear_filtering = enabled; }
|
||||
void SetDisplayTopMargin(s32 height) { m_display_top_margin = height; }
|
||||
void SetDisplayIntegerScaling(bool enabled) { m_display_integer_scaling = enabled; }
|
||||
|
@ -312,10 +309,10 @@ void ReleaseHostDisplay();
|
|||
|
||||
/// Returns false if the window was completely occluded. If frame_skip is set, the frame won't be
|
||||
/// displayed, but the GPU command queue will still be flushed.
|
||||
//bool BeginPresentFrame(bool frame_skip);
|
||||
// bool BeginPresentFrame(bool frame_skip);
|
||||
|
||||
/// Presents the frame to the display, and renders OSD elements.
|
||||
//void EndPresentFrame();
|
||||
// void EndPresentFrame();
|
||||
|
||||
/// Provided by the host; renders the display.
|
||||
void RenderDisplay();
|
||||
|
|
|
@ -182,24 +182,15 @@ bool D3D11HostDisplay::SupportsDisplayPixelFormat(HostDisplayPixelFormat format)
|
|||
return (SUCCEEDED(m_device->CheckFormatSupport(dfmt, &support)) && ((support & required) == required));
|
||||
}
|
||||
|
||||
bool D3D11HostDisplay::BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch)
|
||||
bool D3D11HostDisplay::MapTexture(HostDisplayTexture* texture, HostDisplayPixelFormat format, u32 width, u32 height,
|
||||
void** out_buffer, u32* out_pitch)
|
||||
{
|
||||
ClearDisplayTexture();
|
||||
|
||||
const DXGI_FORMAT dxgi_format = s_display_pixel_format_mapping[static_cast<u32>(format)];
|
||||
if (m_display_pixels_texture.GetWidth() < width || m_display_pixels_texture.GetHeight() < height ||
|
||||
m_display_pixels_texture.GetFormat() != dxgi_format)
|
||||
{
|
||||
if (!m_display_pixels_texture.Create(m_device.Get(), width, height, 1, 1, dxgi_format, D3D11_BIND_SHADER_RESOURCE,
|
||||
nullptr, 0, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
D3D11HostDisplayTexture* tex = static_cast<D3D11HostDisplayTexture*>(texture);
|
||||
if (!tex->IsDynamic())
|
||||
return false;
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE sr;
|
||||
HRESULT hr = m_context->Map(m_display_pixels_texture.GetD3DTexture(), 0, D3D11_MAP_WRITE_DISCARD, 0, &sr);
|
||||
HRESULT hr = m_context->Map(tex->GetD3DTexture(), 0, D3D11_MAP_WRITE_DISCARD, 0, &sr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Log_ErrorPrintf("Map pixels texture failed: %08X", hr);
|
||||
|
@ -208,15 +199,12 @@ bool D3D11HostDisplay::BeginSetDisplayPixels(HostDisplayPixelFormat format, u32
|
|||
|
||||
*out_buffer = sr.pData;
|
||||
*out_pitch = sr.RowPitch;
|
||||
|
||||
SetDisplayTexture(m_display_pixels_texture.GetD3DSRV(), format, m_display_pixels_texture.GetWidth(),
|
||||
m_display_pixels_texture.GetHeight(), 0, 0, static_cast<u32>(width), static_cast<u32>(height));
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D11HostDisplay::EndSetDisplayPixels()
|
||||
void D3D11HostDisplay::UnmapTexture(HostDisplayTexture* texture)
|
||||
{
|
||||
m_context->Unmap(m_display_pixels_texture.GetD3DTexture(), 0);
|
||||
m_context->Unmap(static_cast<D3D11HostDisplayTexture*>(texture)->GetD3DTexture(), 0);
|
||||
}
|
||||
|
||||
bool D3D11HostDisplay::GetHostRefreshRate(float* refresh_rate)
|
||||
|
|
|
@ -58,10 +58,10 @@ public:
|
|||
u32 texture_data_stride) override;
|
||||
bool DownloadTexture(const void* texture_handle, HostDisplayPixelFormat texture_format, u32 x, u32 y, u32 width,
|
||||
u32 height, void* out_data, u32 out_data_stride) override;
|
||||
bool MapTexture(HostDisplayTexture* texture, HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch) override;
|
||||
void UnmapTexture(HostDisplayTexture* texture) override;
|
||||
bool SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const override;
|
||||
bool BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch) override;
|
||||
void EndSetDisplayPixels() override;
|
||||
|
||||
bool GetHostRefreshRate(float* refresh_rate) override;
|
||||
|
||||
|
@ -128,7 +128,6 @@ protected:
|
|||
ComPtr<ID3D11SamplerState> m_point_sampler;
|
||||
ComPtr<ID3D11SamplerState> m_linear_sampler;
|
||||
|
||||
D3D11::Texture m_display_pixels_texture;
|
||||
D3D11::StreamBuffer m_display_uniform_buffer;
|
||||
D3D11::AutoStagingTexture m_readback_staging_texture;
|
||||
|
||||
|
|
|
@ -48,8 +48,25 @@ public:
|
|||
const D3D12::Texture& GetTexture() const { return m_texture; }
|
||||
D3D12::Texture& GetTexture() { return m_texture; }
|
||||
|
||||
u32 GetMapX() const { return m_map_x; }
|
||||
u32 GetMapY() const { return m_map_y; }
|
||||
u32 GetMapWidth() const { return m_map_width; }
|
||||
u32 GetMapHeight() const { return m_map_height; }
|
||||
|
||||
void SetMapRect(u32 x, u32 y, u32 width, u32 height)
|
||||
{
|
||||
m_map_x = x;
|
||||
m_map_y = y;
|
||||
m_map_width = width;
|
||||
m_map_height = height;
|
||||
}
|
||||
|
||||
private:
|
||||
D3D12::Texture m_texture;
|
||||
u32 m_map_x = 0;
|
||||
u32 m_map_y = 0;
|
||||
u32 m_map_width = 0;
|
||||
u32 m_map_height = 0;
|
||||
};
|
||||
|
||||
D3D12HostDisplay::D3D12HostDisplay() = default;
|
||||
|
@ -139,34 +156,21 @@ bool D3D12HostDisplay::SupportsDisplayPixelFormat(HostDisplayPixelFormat format)
|
|||
return g_d3d12_context->SupportsTextureFormat(dfmt);
|
||||
}
|
||||
|
||||
bool D3D12HostDisplay::BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch)
|
||||
bool D3D12HostDisplay::MapTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch)
|
||||
{
|
||||
ClearDisplayTexture();
|
||||
|
||||
const DXGI_FORMAT dxgi_format = s_display_pixel_format_mapping[static_cast<u32>(format)];
|
||||
if (m_display_pixels_texture.GetWidth() < width || m_display_pixels_texture.GetHeight() < height ||
|
||||
m_display_pixels_texture.GetFormat() != dxgi_format)
|
||||
{
|
||||
if (!m_display_pixels_texture.Create(width, height, 1, dxgi_format, dxgi_format, DXGI_FORMAT_UNKNOWN,
|
||||
DXGI_FORMAT_UNKNOWN, D3D12_RESOURCE_FLAG_NONE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_display_pixels_texture.BeginStreamUpdate(0, 0, width, height, out_buffer, out_pitch))
|
||||
D3D12HostDisplayTexture* tex = static_cast<D3D12HostDisplayTexture*>(texture);
|
||||
if (!tex->GetTexture().BeginStreamUpdate(0, 0, width, height, out_buffer, out_pitch))
|
||||
return false;
|
||||
|
||||
SetDisplayTexture(&m_display_pixels_texture, format, m_display_pixels_texture.GetWidth(),
|
||||
m_display_pixels_texture.GetHeight(), 0, 0, static_cast<u32>(width), static_cast<u32>(height));
|
||||
tex->SetMapRect(x, y, width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D12HostDisplay::EndSetDisplayPixels()
|
||||
void D3D12HostDisplay::UnmapTexture(HostDisplayTexture* texture)
|
||||
{
|
||||
m_display_pixels_texture.EndStreamUpdate(0, 0, static_cast<u32>(m_display_texture_view_width),
|
||||
static_cast<u32>(m_display_texture_view_height));
|
||||
D3D12HostDisplayTexture* tex = static_cast<D3D12HostDisplayTexture*>(texture);
|
||||
tex->GetTexture().EndStreamUpdate(tex->GetMapX(), tex->GetMapY(), tex->GetMapWidth(), tex->GetMapHeight());
|
||||
}
|
||||
|
||||
bool D3D12HostDisplay::GetHostRefreshRate(float* refresh_rate)
|
||||
|
|
|
@ -59,10 +59,10 @@ public:
|
|||
u32 texture_data_stride) override;
|
||||
bool DownloadTexture(const void* texture_handle, HostDisplayPixelFormat texture_format, u32 x, u32 y, u32 width,
|
||||
u32 height, void* out_data, u32 out_data_stride) override;
|
||||
bool MapTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch) override;
|
||||
void UnmapTexture(HostDisplayTexture* texture) override;
|
||||
bool SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const override;
|
||||
bool BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch) override;
|
||||
void EndSetDisplayPixels() override;
|
||||
|
||||
bool GetHostRefreshRate(float* refresh_rate) override;
|
||||
|
||||
|
@ -115,7 +115,6 @@ protected:
|
|||
D3D12::DescriptorHandle m_point_sampler;
|
||||
D3D12::DescriptorHandle m_linear_sampler;
|
||||
|
||||
D3D12::Texture m_display_pixels_texture;
|
||||
D3D12::StreamBuffer m_display_uniform_buffer;
|
||||
D3D12::StagingTexture m_readback_staging_texture;
|
||||
|
||||
|
|
|
@ -32,9 +32,46 @@ public:
|
|||
|
||||
GLuint GetGLID() const { return m_texture.GetGLId(); }
|
||||
|
||||
u32 GetMapX() const { return m_map_x; }
|
||||
u32 GetMapY() const { return m_map_y; }
|
||||
u32 GetMapWidth() const { return m_map_width; }
|
||||
u32 GetMapHeight() const { return m_map_height; }
|
||||
u32 GetMapPBOOffset() const { return m_map_pbo_offset; }
|
||||
u32 GetMapPBOSize() const { return m_map_pbo_size; }
|
||||
|
||||
void SetMapRect(u32 x, u32 y, u32 width, u32 height, u32 pbo_offset, u32 pbo_size)
|
||||
{
|
||||
m_map_x = x;
|
||||
m_map_y = y;
|
||||
m_map_width = width;
|
||||
m_map_height = height;
|
||||
m_map_pbo_offset = pbo_offset;
|
||||
m_map_pbo_size = pbo_size;
|
||||
}
|
||||
|
||||
void BindAndUpdateLinearFilter(bool enabled)
|
||||
{
|
||||
m_texture.Bind();
|
||||
if (m_linear_filter == enabled)
|
||||
return;
|
||||
|
||||
m_linear_filter = enabled;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, enabled ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, enabled ? GL_LINEAR : GL_NEAREST);
|
||||
}
|
||||
|
||||
private:
|
||||
GL::Texture m_texture;
|
||||
HostDisplayPixelFormat m_format;
|
||||
|
||||
u32 m_map_x = 0;
|
||||
u32 m_map_y = 0;
|
||||
u32 m_map_width = 0;
|
||||
u32 m_map_height = 0;
|
||||
u32 m_map_pbo_offset = 0;
|
||||
u32 m_map_pbo_size = 0;
|
||||
|
||||
bool m_linear_filter = false;
|
||||
};
|
||||
|
||||
OpenGLHostDisplay::OpenGLHostDisplay() = default;
|
||||
|
@ -174,45 +211,17 @@ bool OpenGLHostDisplay::DownloadTexture(const void* texture_handle, HostDisplayP
|
|||
return true;
|
||||
}
|
||||
|
||||
void OpenGLHostDisplay::BindDisplayPixelsTexture()
|
||||
{
|
||||
if (m_display_pixels_texture_id == 0)
|
||||
{
|
||||
glGenTextures(1, &m_display_pixels_texture_id);
|
||||
glBindTexture(GL_TEXTURE_2D, m_display_pixels_texture_id);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_display_linear_filtering ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_display_linear_filtering ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||
m_display_texture_is_linear_filtered = m_display_linear_filtering;
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, m_display_pixels_texture_id);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLHostDisplay::UpdateDisplayPixelsTextureFilter()
|
||||
{
|
||||
if (m_display_linear_filtering == m_display_texture_is_linear_filtered)
|
||||
return;
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_display_linear_filtering ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_display_linear_filtering ? GL_LINEAR : GL_NEAREST);
|
||||
m_display_texture_is_linear_filtered = m_display_linear_filtering;
|
||||
}
|
||||
|
||||
bool OpenGLHostDisplay::SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const
|
||||
{
|
||||
const auto [gl_internal_format, gl_format, gl_type] = GetPixelFormatMapping(m_gl_context->IsGLES(), format);
|
||||
return (gl_internal_format != static_cast<GLenum>(0));
|
||||
}
|
||||
|
||||
bool OpenGLHostDisplay::BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch)
|
||||
bool OpenGLHostDisplay::MapTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch)
|
||||
{
|
||||
const u32 pixel_size = GetDisplayPixelFormatSize(format);
|
||||
OpenGLHostDisplayTexture* tex = static_cast<OpenGLHostDisplayTexture*>(texture);
|
||||
const u32 pixel_size = GetDisplayPixelFormatSize(tex->GetFormat());
|
||||
const u32 stride = Common::AlignUpPow2(width * pixel_size, 4);
|
||||
const u32 size_required = stride * height * pixel_size;
|
||||
|
||||
|
@ -227,10 +236,8 @@ bool OpenGLHostDisplay::BeginSetDisplayPixels(HostDisplayPixelFormat format, u32
|
|||
return false;
|
||||
}
|
||||
|
||||
const auto map = m_display_pixels_texture_pbo->Map(GetDisplayPixelFormatSize(format), size_required);
|
||||
m_display_texture_format = format;
|
||||
m_display_pixels_texture_pbo_map_offset = map.buffer_offset;
|
||||
m_display_pixels_texture_pbo_map_size = size_required;
|
||||
const auto map = m_display_pixels_texture_pbo->Map(GetDisplayPixelFormatSize(tex->GetFormat()), size_required);
|
||||
tex->SetMapRect(x, y, width, height, map.buffer_offset, size_required);
|
||||
*out_buffer = map.pointer;
|
||||
*out_pitch = stride;
|
||||
}
|
||||
|
@ -239,31 +246,37 @@ bool OpenGLHostDisplay::BeginSetDisplayPixels(HostDisplayPixelFormat format, u32
|
|||
if (m_gles_pixels_repack_buffer.size() < size_required)
|
||||
m_gles_pixels_repack_buffer.resize(size_required);
|
||||
|
||||
tex->SetMapRect(x, y, width, height, 0, size_required);
|
||||
*out_buffer = m_gles_pixels_repack_buffer.data();
|
||||
*out_pitch = stride;
|
||||
}
|
||||
|
||||
BindDisplayPixelsTexture();
|
||||
SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_pixels_texture_id)), format, width, height,
|
||||
0, 0, width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpenGLHostDisplay::EndSetDisplayPixels()
|
||||
void OpenGLHostDisplay::UnmapTexture(HostDisplayTexture* texture)
|
||||
{
|
||||
const u32 width = static_cast<u32>(m_display_texture_view_width);
|
||||
const u32 height = static_cast<u32>(m_display_texture_view_height);
|
||||
OpenGLHostDisplayTexture* tex = static_cast<OpenGLHostDisplayTexture*>(texture);
|
||||
|
||||
const auto [gl_internal_format, gl_format, gl_type] =
|
||||
GetPixelFormatMapping(m_gl_context->IsGLES(), m_display_texture_format);
|
||||
const auto [gl_internal_format, gl_format, gl_type] = GetPixelFormatMapping(m_gl_context->IsGLES(), tex->GetFormat());
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_display_pixels_texture_id);
|
||||
glBindTexture(GL_TEXTURE_2D, tex->GetGLID());
|
||||
if (m_use_pbo_for_pixels)
|
||||
{
|
||||
m_display_pixels_texture_pbo->Unmap(m_display_pixels_texture_pbo_map_size);
|
||||
m_display_pixels_texture_pbo->Bind();
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, gl_internal_format, width, height, 0, gl_format, gl_type,
|
||||
reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_pixels_texture_pbo_map_offset)));
|
||||
if (tex->GetMapX() == 0 && tex->GetMapY() == 0 && tex->GetMapWidth() == tex->GetWidth() &&
|
||||
tex->GetMapHeight() == tex->GetHeight())
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, gl_internal_format, tex->GetMapWidth(), tex->GetMapHeight(), 0, gl_format, gl_type,
|
||||
reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_pixels_texture_pbo_map_offset)));
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, tex->GetMapX(), tex->GetMapY(), tex->GetMapWidth(), tex->GetMapHeight(),
|
||||
gl_format, gl_type,
|
||||
reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_pixels_texture_pbo_map_offset)));
|
||||
}
|
||||
m_display_pixels_texture_pbo->Unbind();
|
||||
|
||||
m_display_pixels_texture_pbo_map_offset = 0;
|
||||
|
@ -272,52 +285,22 @@ void OpenGLHostDisplay::EndSetDisplayPixels()
|
|||
else
|
||||
{
|
||||
// glTexImage2D should be quicker on Mali...
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, gl_internal_format, width, height, 0, gl_format, gl_type,
|
||||
m_gles_pixels_repack_buffer.data());
|
||||
if (tex->GetMapX() == 0 && tex->GetMapY() == 0 && tex->GetMapWidth() == tex->GetWidth() &&
|
||||
tex->GetMapHeight() == tex->GetHeight())
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, gl_internal_format, tex->GetMapWidth(), tex->GetMapHeight(), 0, gl_format, gl_type,
|
||||
m_gles_pixels_repack_buffer.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, tex->GetMapX(), tex->GetMapY(), tex->GetMapWidth(), tex->GetMapHeight(),
|
||||
gl_format, gl_type, m_gles_pixels_repack_buffer.data());
|
||||
}
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
bool OpenGLHostDisplay::SetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, const void* buffer,
|
||||
u32 pitch)
|
||||
{
|
||||
BindDisplayPixelsTexture();
|
||||
|
||||
const auto [gl_internal_format, gl_format, gl_type] = GetPixelFormatMapping(m_gl_context->IsGLES(), format);
|
||||
const u32 pixel_size = GetDisplayPixelFormatSize(format);
|
||||
const bool is_packed_tightly = (pitch == (pixel_size * width));
|
||||
|
||||
// If we have GLES3, we can set row_length.
|
||||
if (!m_use_gles2_draw_path || is_packed_tightly)
|
||||
{
|
||||
if (!is_packed_tightly)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / pixel_size);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, gl_internal_format, width, height, 0, gl_format, gl_type, buffer);
|
||||
|
||||
if (!is_packed_tightly)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, we need to repack the image.
|
||||
const u32 packed_pitch = width * pixel_size;
|
||||
const u32 repack_size = packed_pitch * height;
|
||||
if (m_gles_pixels_repack_buffer.size() < repack_size)
|
||||
m_gles_pixels_repack_buffer.resize(repack_size);
|
||||
StringUtil::StrideMemCpy(m_gles_pixels_repack_buffer.data(), packed_pitch, buffer, pitch, packed_pitch, height);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, gl_internal_format, width, height, 0, gl_format, gl_type,
|
||||
m_gles_pixels_repack_buffer.data());
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_pixels_texture_id)), format, width, height,
|
||||
0, 0, width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpenGLHostDisplay::SetVSync(bool enabled)
|
||||
{
|
||||
if (m_gl_context->GetWindowInfo().type == WindowInfo::Type::Surfaceless)
|
||||
|
@ -520,8 +503,7 @@ HostDisplay::AdapterAndModeList OpenGLHostDisplay::GetAdapterAndModeList()
|
|||
{
|
||||
for (const GL::Context::FullscreenModeInfo& fmi : m_gl_context->EnumerateFullscreenModes())
|
||||
{
|
||||
aml.fullscreen_modes.push_back(
|
||||
GetFullscreenModeString(fmi.width, fmi.height, fmi.refresh_rate));
|
||||
aml.fullscreen_modes.push_back(GetFullscreenModeString(fmi.width, fmi.height, fmi.refresh_rate));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -712,12 +694,6 @@ void OpenGLHostDisplay::DestroyResources()
|
|||
m_post_processing_ubo.reset();
|
||||
m_post_processing_stages.clear();
|
||||
|
||||
if (m_display_pixels_texture_id != 0)
|
||||
{
|
||||
glDeleteTextures(1, &m_display_pixels_texture_id);
|
||||
m_display_pixels_texture_id = 0;
|
||||
}
|
||||
|
||||
if (m_display_vao != 0)
|
||||
{
|
||||
glDeleteVertexArrays(1, &m_display_vao);
|
||||
|
@ -886,9 +862,6 @@ void OpenGLHostDisplay::RenderDisplay(s32 left, s32 bottom, s32 width, s32 heigh
|
|||
}
|
||||
else
|
||||
{
|
||||
if (static_cast<GLuint>(reinterpret_cast<uintptr_t>(texture_handle)) == m_display_pixels_texture_id)
|
||||
UpdateDisplayPixelsTextureFilter();
|
||||
|
||||
DrawFullscreenQuadES2(m_display_texture_view_x, m_display_texture_view_y, m_display_texture_view_width,
|
||||
m_display_texture_view_height, m_display_texture_width, m_display_texture_height);
|
||||
}
|
||||
|
|
|
@ -50,11 +50,10 @@ public:
|
|||
u32 texture_data_stride) override;
|
||||
bool DownloadTexture(const void* texture_handle, HostDisplayPixelFormat texture_format, u32 x, u32 y, u32 width,
|
||||
u32 height, void* out_data, u32 out_data_stride) override;
|
||||
bool MapTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch) override;
|
||||
void UnmapTexture(HostDisplayTexture* texture) override;
|
||||
bool SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const override;
|
||||
bool BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch) override;
|
||||
void EndSetDisplayPixels() override;
|
||||
bool SetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, const void* buffer, u32 pitch) override;
|
||||
|
||||
void SetVSync(bool enabled) override;
|
||||
|
||||
|
@ -73,9 +72,6 @@ protected:
|
|||
void DestroyImGuiContext() override;
|
||||
bool UpdateImGuiFontTexture() override;
|
||||
|
||||
void BindDisplayPixelsTexture();
|
||||
void UpdateDisplayPixelsTextureFilter();
|
||||
|
||||
void RenderDisplay();
|
||||
void RenderImGui();
|
||||
void RenderSoftwareCursor();
|
||||
|
@ -107,7 +103,6 @@ protected:
|
|||
GLuint m_display_linear_sampler = 0;
|
||||
GLuint m_uniform_buffer_alignment = 1;
|
||||
|
||||
GLuint m_display_pixels_texture_id = 0;
|
||||
std::unique_ptr<GL::StreamBuffer> m_display_pixels_texture_pbo;
|
||||
u32 m_display_pixels_texture_pbo_map_offset = 0;
|
||||
u32 m_display_pixels_texture_pbo_map_size = 0;
|
||||
|
@ -118,7 +113,6 @@ protected:
|
|||
std::unique_ptr<GL::StreamBuffer> m_post_processing_ubo;
|
||||
std::vector<PostProcessingStage> m_post_processing_stages;
|
||||
|
||||
bool m_display_texture_is_linear_filtered = false;
|
||||
bool m_use_gles2_draw_path = false;
|
||||
bool m_use_pbo_for_pixels = false;
|
||||
};
|
||||
|
|
|
@ -271,8 +271,7 @@ bool VulkanHostDisplay::SupportsDisplayPixelFormat(HostDisplayPixelFormat format
|
|||
return ((fp.optimalTilingFeatures & required) == required);
|
||||
}
|
||||
|
||||
bool VulkanHostDisplay::BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch)
|
||||
bool VulkanHostDisplay::MapTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, void** out_buffer, u32* out_pitch)
|
||||
{
|
||||
const VkFormat vk_format = s_display_pixel_format_mapping[static_cast<u32>(format)];
|
||||
|
||||
|
|
|
@ -55,11 +55,11 @@ public:
|
|||
u32 texture_data_stride) override;
|
||||
bool DownloadTexture(const void* texture_handle, HostDisplayPixelFormat texture_format, u32 x, u32 y, u32 width,
|
||||
u32 height, void* out_data, u32 out_data_stride) override;
|
||||
bool MapTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch) override;
|
||||
void UnmapTexture(HostDisplayTexture* texture) override;
|
||||
|
||||
bool SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const override;
|
||||
bool BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
|
||||
u32* out_pitch) override;
|
||||
void EndSetDisplayPixels() override;
|
||||
|
||||
void SetVSync(bool enabled) override;
|
||||
|
||||
|
@ -125,7 +125,6 @@ protected:
|
|||
VkSampler m_point_sampler = VK_NULL_HANDLE;
|
||||
VkSampler m_linear_sampler = VK_NULL_HANDLE;
|
||||
|
||||
Vulkan::Texture m_display_pixels_texture;
|
||||
Vulkan::StagingTexture m_upload_staging_texture;
|
||||
Vulkan::StagingTexture m_readback_staging_texture;
|
||||
|
||||
|
|
Loading…
Reference in New Issue