mirror of
https://github.com/azahar-emu/azahar
synced 2025-11-06 23:19:57 +01:00
video_core: Fix LCD color fill (#1198)
This commit is contained in:
parent
4447a5c9f2
commit
a15af9b550
@ -165,15 +165,16 @@ void RendererOpenGL::PrepareRendertarget() {
|
||||
|
||||
const auto color_fill = fb_id == 0 ? regs_lcd.color_fill_top : regs_lcd.color_fill_bottom;
|
||||
if (color_fill.is_enabled) {
|
||||
FillScreen(color_fill.AsVector(), texture);
|
||||
continue;
|
||||
// Resize the texture to let it be reconfigured
|
||||
texture.width = 1;
|
||||
texture.height = 1;
|
||||
}
|
||||
|
||||
if (texture.width != framebuffer.width || texture.height != framebuffer.height ||
|
||||
texture.format != framebuffer.color_format) {
|
||||
ConfigureFramebufferTexture(texture, framebuffer);
|
||||
ConfigureFramebufferTexture(texture, framebuffer, color_fill);
|
||||
}
|
||||
LoadFBToScreenInfo(framebuffer, screen_infos[i], i == 1);
|
||||
LoadFBToScreenInfo(framebuffer, screen_infos[i], i == 1, color_fill);
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,7 +232,8 @@ void RendererOpenGL::RenderToMailbox(const Layout::FramebufferLayout& layout,
|
||||
* Loads framebuffer from emulated memory into the active OpenGL texture.
|
||||
*/
|
||||
void RendererOpenGL::LoadFBToScreenInfo(const Pica::FramebufferConfig& framebuffer,
|
||||
ScreenInfo& screen_info, bool right_eye) {
|
||||
ScreenInfo& screen_info, bool right_eye,
|
||||
const Pica::ColorFill& color_fill) {
|
||||
|
||||
if (framebuffer.address_right1 == 0 || framebuffer.address_right2 == 0)
|
||||
right_eye = false;
|
||||
@ -255,15 +257,27 @@ void RendererOpenGL::LoadFBToScreenInfo(const Pica::FramebufferConfig& framebuff
|
||||
// only allows rows to have a memory alignement of 4.
|
||||
ASSERT(pixel_stride % 4 == 0);
|
||||
|
||||
if (!rasterizer.AccelerateDisplay(framebuffer, framebuffer_addr, static_cast<u32>(pixel_stride),
|
||||
if (color_fill.is_enabled ||
|
||||
!rasterizer.AccelerateDisplay(framebuffer, framebuffer_addr, static_cast<u32>(pixel_stride),
|
||||
screen_info)) {
|
||||
u32 width = framebuffer.width;
|
||||
u32 height = framebuffer.height;
|
||||
u8 fill_pixel[3];
|
||||
// Reset the screen info's display texture to its own permanent texture
|
||||
screen_info.display_texture = screen_info.texture.resource.handle;
|
||||
screen_info.display_texcoords = Common::Rectangle<f32>(0.f, 0.f, 1.f, 1.f);
|
||||
|
||||
rasterizer.FlushRegion(framebuffer_addr, framebuffer.stride * framebuffer.height);
|
||||
|
||||
const u8* framebuffer_data = system.Memory().GetPhysicalPointer(framebuffer_addr);
|
||||
u8* framebuffer_data = system.Memory().GetPhysicalPointer(framebuffer_addr);
|
||||
|
||||
if (color_fill.is_enabled) {
|
||||
memcpy(fill_pixel, color_fill.AsVector().AsArray(), sizeof(fill_pixel));
|
||||
framebuffer_data = fill_pixel;
|
||||
width = 1;
|
||||
height = 1;
|
||||
pixel_stride = 0;
|
||||
}
|
||||
|
||||
state.texture_units[0].texture_2d = screen_info.texture.resource.handle;
|
||||
state.Apply();
|
||||
@ -276,9 +290,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const Pica::FramebufferConfig& framebuff
|
||||
// they differ from the LCD resolution.
|
||||
// TODO: Applications could theoretically crash Citra here by specifying too large
|
||||
// framebuffer sizes. We should make sure that this cannot happen.
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, framebuffer.width, framebuffer.height,
|
||||
screen_info.texture.gl_format, screen_info.texture.gl_type,
|
||||
framebuffer_data);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, screen_info.texture.gl_format,
|
||||
screen_info.texture.gl_type, framebuffer_data);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
|
||||
@ -287,23 +300,6 @@ void RendererOpenGL::LoadFBToScreenInfo(const Pica::FramebufferConfig& framebuff
|
||||
}
|
||||
}
|
||||
|
||||
void RendererOpenGL::FillScreen(Common::Vec3<u8> color, TextureInfo& texture) {
|
||||
state.texture_units[0].texture_2d = texture.resource.handle;
|
||||
state.Apply();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
// Update existing texture
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, color.AsArray());
|
||||
|
||||
state.texture_units[0].texture_2d = 0;
|
||||
state.Apply();
|
||||
|
||||
// Resize the texture in case the framebuffer size has changed
|
||||
texture.width = 1;
|
||||
texture.height = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the OpenGL state and creates persistent objects.
|
||||
*/
|
||||
@ -429,13 +425,20 @@ void RendererOpenGL::ReloadShader() {
|
||||
}
|
||||
|
||||
void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
|
||||
const Pica::FramebufferConfig& framebuffer) {
|
||||
const Pica::FramebufferConfig& framebuffer,
|
||||
const Pica::ColorFill& color_fill) {
|
||||
Pica::PixelFormat format = framebuffer.color_format;
|
||||
GLint internal_format{};
|
||||
u32 width, height;
|
||||
|
||||
texture.format = format;
|
||||
texture.width = framebuffer.width;
|
||||
texture.height = framebuffer.height;
|
||||
width = texture.width = framebuffer.width;
|
||||
height = texture.height = framebuffer.height;
|
||||
if (color_fill.is_enabled) {
|
||||
width = 1;
|
||||
height = 1;
|
||||
format = Pica::PixelFormat::RGB8;
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
case Pica::PixelFormat::RGBA8:
|
||||
@ -482,8 +485,8 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
|
||||
state.Apply();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0,
|
||||
texture.gl_format, texture.gl_type, nullptr);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, texture.gl_format,
|
||||
texture.gl_type, nullptr);
|
||||
|
||||
state.texture_units[0].texture_2d = 0;
|
||||
state.Apply();
|
||||
|
||||
@ -62,7 +62,8 @@ private:
|
||||
void RenderToMailbox(const Layout::FramebufferLayout& layout,
|
||||
std::unique_ptr<Frontend::TextureMailbox>& mailbox, bool flipped);
|
||||
void ConfigureFramebufferTexture(TextureInfo& texture,
|
||||
const Pica::FramebufferConfig& framebuffer);
|
||||
const Pica::FramebufferConfig& framebuffer,
|
||||
const Pica::ColorFill& color_fill);
|
||||
void DrawScreens(const Layout::FramebufferLayout& layout, bool flipped);
|
||||
void ApplySecondLayerOpacity(bool isPortrait = false);
|
||||
void ResetSecondLayerOpacity(bool isPortrait = false);
|
||||
@ -78,8 +79,7 @@ private:
|
||||
|
||||
// Loads framebuffer from emulated memory into the display information structure
|
||||
void LoadFBToScreenInfo(const Pica::FramebufferConfig& framebuffer, ScreenInfo& screen_info,
|
||||
bool right_eye);
|
||||
void FillScreen(Common::Vec3<u8> color, TextureInfo& texture);
|
||||
bool right_eye, const Pica::ColorFill& color_fill);
|
||||
|
||||
private:
|
||||
Pica::PicaCore& pica;
|
||||
|
||||
@ -30,13 +30,11 @@ void RendererSoftware::PrepareRenderTarget() {
|
||||
const u32 fb_id = i == 2 ? 1 : 0;
|
||||
|
||||
const auto color_fill = fb_id == 0 ? regs_lcd.color_fill_top : regs_lcd.color_fill_bottom;
|
||||
if (!color_fill.is_enabled) {
|
||||
LoadFBToScreenInfo(i);
|
||||
}
|
||||
LoadFBToScreenInfo(i, color_fill);
|
||||
}
|
||||
}
|
||||
|
||||
void RendererSoftware::LoadFBToScreenInfo(int i) {
|
||||
void RendererSoftware::LoadFBToScreenInfo(int i, const Pica::ColorFill& color_fill) {
|
||||
const u32 fb_id = i == 2 ? 1 : 0;
|
||||
const auto& framebuffer = pica.regs.framebuffer_config[fb_id];
|
||||
auto& info = screen_infos[i];
|
||||
@ -54,7 +52,12 @@ void RendererSoftware::LoadFBToScreenInfo(int i) {
|
||||
for (u32 y = 0; y < info.height; y++) {
|
||||
for (u32 x = 0; x < info.width; x++) {
|
||||
const u8* pixel = framebuffer_data + (y * pixel_stride + pixel_stride - x) * bpp;
|
||||
const Common::Vec4 color = [&] {
|
||||
Common::Vec4 color = [&] {
|
||||
if (color_fill.is_enabled) {
|
||||
return Common::Vec4<u8>(color_fill.color_r, color_fill.color_g,
|
||||
color_fill.color_b, 255);
|
||||
}
|
||||
|
||||
switch (framebuffer.color_format) {
|
||||
case Pica::PixelFormat::RGBA8:
|
||||
return Common::Color::DecodeRGBA8(pixel);
|
||||
|
||||
@ -38,7 +38,7 @@ public:
|
||||
|
||||
private:
|
||||
void PrepareRenderTarget();
|
||||
void LoadFBToScreenInfo(int i);
|
||||
void LoadFBToScreenInfo(int i, const Pica::ColorFill& color_fill);
|
||||
|
||||
private:
|
||||
Memory::MemorySystem& memory;
|
||||
|
||||
@ -455,7 +455,6 @@ void RendererVulkan::ConfigureFramebufferTexture(TextureInfo& texture,
|
||||
}
|
||||
|
||||
void RendererVulkan::FillScreen(Common::Vec3<u8> color, const TextureInfo& texture) {
|
||||
return;
|
||||
const vk::ClearColorValue clear_color = {
|
||||
.float32 =
|
||||
std::array{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user