HostDisplay: Use streaming for sw renderer display
This commit is contained in:
@ -103,6 +103,21 @@ void GPU_SW::UpdateSettings()
|
||||
m_backend.UpdateSettings();
|
||||
}
|
||||
|
||||
HostDisplayTexture* GPU_SW::GetDisplayTexture(u32 width, u32 height, HostDisplayPixelFormat format)
|
||||
{
|
||||
if (!m_display_texture || m_display_texture->GetWidth() != width || m_display_texture->GetHeight() != height ||
|
||||
m_display_texture->GetFormat() != format)
|
||||
{
|
||||
g_host_display->ClearDisplayTexture();
|
||||
m_display_texture.reset();
|
||||
m_display_texture = g_host_display->CreateTexture(width, height, 1, 1, 1, format, nullptr, 0, true);
|
||||
if (!m_display_texture)
|
||||
Log_ErrorPrintf("Failed to create %ux%u %u texture", width, height, static_cast<u32>(format));
|
||||
}
|
||||
|
||||
return m_display_texture.get();
|
||||
}
|
||||
|
||||
template<HostDisplayPixelFormat out_format, typename out_type>
|
||||
static void CopyOutRow16(const u16* src_ptr, out_type* dst_ptr, u32 width);
|
||||
|
||||
@ -240,13 +255,14 @@ void GPU_SW::CopyOut15Bit(u32 src_x, u32 src_y, u32 width, u32 height, u32 field
|
||||
using OutputPixelType = std::conditional_t<
|
||||
display_format == HostDisplayPixelFormat::RGBA8 || display_format == HostDisplayPixelFormat::BGRA8, u32, u16>;
|
||||
|
||||
HostDisplayTexture* texture = GetDisplayTexture(width, height, display_format);
|
||||
if (!texture)
|
||||
return;
|
||||
|
||||
if (!interlaced)
|
||||
{
|
||||
if (!g_host_display->BeginSetDisplayPixels(display_format, width, height, reinterpret_cast<void**>(&dst_ptr),
|
||||
&dst_stride))
|
||||
{
|
||||
if (!texture->BeginUpdate(width, height, reinterpret_cast<void**>(&dst_ptr), &dst_stride))
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -293,13 +309,11 @@ void GPU_SW::CopyOut15Bit(u32 src_x, u32 src_y, u32 width, u32 height, u32 field
|
||||
}
|
||||
|
||||
if (!interlaced)
|
||||
{
|
||||
g_host_display->EndSetDisplayPixels();
|
||||
}
|
||||
texture->EndUpdate(0, 0, width, height);
|
||||
else
|
||||
{
|
||||
g_host_display->SetDisplayPixels(display_format, width, height, m_display_texture_buffer.data(), output_stride);
|
||||
}
|
||||
texture->Update(0, 0, width, height, m_display_texture_buffer.data(), output_stride);
|
||||
|
||||
g_host_display->SetDisplayTexture(texture->GetHandle(), display_format, width, height, 0, 0, width, height);
|
||||
}
|
||||
|
||||
void GPU_SW::CopyOut15Bit(HostDisplayPixelFormat display_format, u32 src_x, u32 src_y, u32 width, u32 height, u32 field,
|
||||
@ -334,13 +348,14 @@ void GPU_SW::CopyOut24Bit(u32 src_x, u32 src_y, u32 skip_x, u32 width, u32 heigh
|
||||
using OutputPixelType = std::conditional_t<
|
||||
display_format == HostDisplayPixelFormat::RGBA8 || display_format == HostDisplayPixelFormat::BGRA8, u32, u16>;
|
||||
|
||||
HostDisplayTexture* texture = GetDisplayTexture(width, height, display_format);
|
||||
if (!texture)
|
||||
return;
|
||||
|
||||
if (!interlaced)
|
||||
{
|
||||
if (!g_host_display->BeginSetDisplayPixels(display_format, width, height, reinterpret_cast<void**>(&dst_ptr),
|
||||
&dst_stride))
|
||||
{
|
||||
if (!texture->BeginUpdate(width, height, reinterpret_cast<void**>(&dst_ptr), &dst_stride))
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -451,13 +466,11 @@ void GPU_SW::CopyOut24Bit(u32 src_x, u32 src_y, u32 skip_x, u32 width, u32 heigh
|
||||
}
|
||||
|
||||
if (!interlaced)
|
||||
{
|
||||
g_host_display->EndSetDisplayPixels();
|
||||
}
|
||||
texture->EndUpdate(0, 0, width, height);
|
||||
else
|
||||
{
|
||||
g_host_display->SetDisplayPixels(display_format, width, height, m_display_texture_buffer.data(), output_stride);
|
||||
}
|
||||
texture->Update(0, 0, width, height, m_display_texture_buffer.data(), output_stride);
|
||||
|
||||
g_host_display->SetDisplayTexture(texture->GetHandle(), display_format, width, height, 0, 0, width, height);
|
||||
}
|
||||
|
||||
void GPU_SW::CopyOut24Bit(HostDisplayPixelFormat display_format, u32 src_x, u32 src_y, u32 skip_x, u32 width,
|
||||
|
||||
@ -55,9 +55,12 @@ protected:
|
||||
void FillBackendCommandParameters(GPUBackendCommand* cmd) const;
|
||||
void FillDrawCommand(GPUBackendDrawCommand* cmd, GPURenderCommand rc) const;
|
||||
|
||||
HostDisplayTexture* GetDisplayTexture(u32 width, u32 height, HostDisplayPixelFormat format);
|
||||
|
||||
HeapArray<u8, GPU_MAX_DISPLAY_WIDTH * GPU_MAX_DISPLAY_HEIGHT * sizeof(u32)> m_display_texture_buffer;
|
||||
HostDisplayPixelFormat m_16bit_display_format = HostDisplayPixelFormat::RGB565;
|
||||
HostDisplayPixelFormat m_24bit_display_format = HostDisplayPixelFormat::RGBA8;
|
||||
std::unique_ptr<HostDisplayTexture> m_display_texture;
|
||||
|
||||
GPU_SW_Backend m_backend;
|
||||
};
|
||||
|
||||
@ -20,6 +20,25 @@ std::unique_ptr<HostDisplay> g_host_display;
|
||||
|
||||
HostDisplayTexture::~HostDisplayTexture() = default;
|
||||
|
||||
bool HostDisplayTexture::BeginUpdate(u32 width, u32 height, void** out_buffer, u32* out_pitch) /* = 0*/
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void HostDisplayTexture::EndUpdate(u32 x, u32 y, u32 width, u32 height) /* = 0*/ {}
|
||||
|
||||
bool HostDisplayTexture::Update(u32 x, u32 y, u32 width, u32 height, const void* data, u32 pitch)
|
||||
{
|
||||
void* map_ptr;
|
||||
u32 map_pitch;
|
||||
if (!BeginUpdate(width, height, &map_ptr, &map_pitch))
|
||||
return false;
|
||||
|
||||
StringUtil::StrideMemCpy(map_ptr, map_pitch, data, pitch, std::min(pitch, map_pitch), height);
|
||||
EndUpdate(x, y, width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
HostDisplay::~HostDisplay() = default;
|
||||
|
||||
RenderAPI HostDisplay::GetPreferredAPI()
|
||||
@ -124,36 +143,6 @@ u32 HostDisplay::GetDisplayPixelFormatSize(HostDisplayPixelFormat format)
|
||||
}
|
||||
}
|
||||
|
||||
bool HostDisplay::SetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, const void* buffer, u32 pitch)
|
||||
{
|
||||
void* map_ptr;
|
||||
u32 map_pitch;
|
||||
if (!BeginSetDisplayPixels(format, width, height, &map_ptr, &map_pitch))
|
||||
return false;
|
||||
|
||||
if (pitch == map_pitch)
|
||||
{
|
||||
std::memcpy(map_ptr, buffer, height * map_pitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
const u32 copy_size = width * GetDisplayPixelFormatSize(format);
|
||||
DebugAssert(pitch >= copy_size && map_pitch >= copy_size);
|
||||
|
||||
const u8* src_ptr = static_cast<const u8*>(buffer);
|
||||
u8* dst_ptr = static_cast<u8*>(map_ptr);
|
||||
for (u32 i = 0; i < height; i++)
|
||||
{
|
||||
std::memcpy(dst_ptr, src_ptr, copy_size);
|
||||
src_ptr += pitch;
|
||||
dst_ptr += map_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
EndSetDisplayPixels();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HostDisplay::GetHostRefreshRate(float* refresh_rate)
|
||||
{
|
||||
if (m_window_info.surface_refresh_rate > 0.0f)
|
||||
|
||||
@ -41,6 +41,10 @@ public:
|
||||
virtual u32 GetLevels() const = 0;
|
||||
virtual u32 GetSamples() const = 0;
|
||||
virtual HostDisplayPixelFormat GetFormat() const = 0;
|
||||
|
||||
virtual bool BeginUpdate(u32 width, u32 height, void** out_buffer, u32* out_pitch)/* = 0*/;
|
||||
virtual void EndUpdate(u32 x, u32 y, u32 width, u32 height)/* = 0*/;
|
||||
virtual bool Update(u32 x, u32 y, u32 width, u32 height, const void* data, u32 pitch);
|
||||
};
|
||||
|
||||
// Interface to the frontend's renderer.
|
||||
@ -124,9 +128,6 @@ public:
|
||||
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;
|
||||
|
||||
@ -203,11 +204,6 @@ public:
|
||||
|
||||
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);
|
||||
|
||||
/// Enables/disables GPU frame timing.
|
||||
|
||||
Reference in New Issue
Block a user