GPU: Implement interlaced rendering in hardware backends
This commit is contained in:
@ -197,35 +197,39 @@ bool GPU_HW_OpenGL_ES::CompilePrograms()
|
||||
{
|
||||
for (u8 dithering = 0; dithering < 2; dithering++)
|
||||
{
|
||||
const bool textured = (static_cast<TextureMode>(texture_mode) != TextureMode::Disabled);
|
||||
const std::string vs = shadergen.GenerateBatchVertexShader(textured);
|
||||
const std::string fs = shadergen.GenerateBatchFragmentShader(static_cast<BatchRenderMode>(render_mode),
|
||||
static_cast<TextureMode>(texture_mode),
|
||||
ConvertToBoolUnchecked(dithering));
|
||||
for (u8 interlacing = 0; interlacing < 2; interlacing++)
|
||||
{
|
||||
const bool textured = (static_cast<TextureMode>(texture_mode) != TextureMode::Disabled);
|
||||
const std::string vs = shadergen.GenerateBatchVertexShader(textured);
|
||||
const std::string fs = shadergen.GenerateBatchFragmentShader(
|
||||
static_cast<BatchRenderMode>(render_mode), static_cast<TextureMode>(texture_mode),
|
||||
ConvertToBoolUnchecked(dithering), ConvertToBoolUnchecked(interlacing));
|
||||
|
||||
std::optional<GL::Program> prog = m_shader_cache.GetProgram(vs, fs, [this, textured](GL::Program& prog) {
|
||||
prog.BindAttribute(0, "a_pos");
|
||||
prog.BindAttribute(1, "a_col0");
|
||||
if (textured)
|
||||
{
|
||||
prog.BindAttribute(2, "a_texcoord");
|
||||
prog.BindAttribute(3, "a_texpage");
|
||||
}
|
||||
});
|
||||
if (!prog)
|
||||
return false;
|
||||
|
||||
prog->Bind();
|
||||
prog->RegisterUniform("u_texture_window_mask");
|
||||
prog->RegisterUniform("u_texture_window_offset");
|
||||
prog->RegisterUniform("u_src_alpha_factor");
|
||||
prog->RegisterUniform("u_dst_alpha_factor");
|
||||
prog->RegisterUniform("u_set_mask_while_drawing");
|
||||
prog->RegisterUniform("u_interlaced_displayed_field");
|
||||
|
||||
std::optional<GL::Program> prog = m_shader_cache.GetProgram(vs, fs, [this, textured](GL::Program& prog) {
|
||||
prog.BindAttribute(0, "a_pos");
|
||||
prog.BindAttribute(1, "a_col0");
|
||||
if (textured)
|
||||
{
|
||||
prog.BindAttribute(2, "a_texcoord");
|
||||
prog.BindAttribute(3, "a_texpage");
|
||||
}
|
||||
});
|
||||
if (!prog)
|
||||
return false;
|
||||
prog->Uniform1i("samp0", 0);
|
||||
|
||||
prog->Bind();
|
||||
prog->RegisterUniform("u_texture_window_mask");
|
||||
prog->RegisterUniform("u_texture_window_offset");
|
||||
prog->RegisterUniform("u_src_alpha_factor");
|
||||
prog->RegisterUniform("u_dst_alpha_factor");
|
||||
prog->RegisterUniform("u_set_mask_while_drawing");
|
||||
|
||||
if (textured)
|
||||
prog->Uniform1i("samp0", 0);
|
||||
|
||||
m_render_programs[render_mode][texture_mode][dithering] = std::move(*prog);
|
||||
m_render_programs[render_mode][texture_mode][dithering][interlacing] = std::move(*prog);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -277,7 +281,7 @@ void GPU_HW_OpenGL_ES::SetVertexPointers()
|
||||
void GPU_HW_OpenGL_ES::SetDrawState(BatchRenderMode render_mode)
|
||||
{
|
||||
const GL::Program& prog = m_render_programs[static_cast<u8>(render_mode)][static_cast<u8>(m_batch.texture_mode)]
|
||||
[BoolToUInt8(m_batch.dithering)];
|
||||
[BoolToUInt8(m_batch.dithering)][BoolToUInt8(m_batch.interlacing)];
|
||||
m_batch_ubo_dirty |= !prog.IsBound();
|
||||
prog.Bind();
|
||||
|
||||
@ -311,6 +315,7 @@ void GPU_HW_OpenGL_ES::SetDrawState(BatchRenderMode render_mode)
|
||||
prog.Uniform1f(2, m_batch_ubo_data.u_src_alpha_factor);
|
||||
prog.Uniform1f(3, m_batch_ubo_data.u_dst_alpha_factor);
|
||||
prog.Uniform1i(4, static_cast<s32>(m_batch_ubo_data.u_set_mask_while_drawing));
|
||||
prog.Uniform1i(5, static_cast<s32>(m_batch_ubo_data.u_interlaced_displayed_field));
|
||||
m_batch_ubo_dirty = false;
|
||||
}
|
||||
}
|
||||
@ -380,8 +385,7 @@ void GPU_HW_OpenGL_ES::UpdateDisplay()
|
||||
const u32 scaled_flipped_vram_offset_y =
|
||||
m_vram_texture.GetHeight() - scaled_vram_offset_y - scaled_display_height;
|
||||
|
||||
const u32 reinterpret_field_offset =
|
||||
(m_crtc_state.regs.Y + BoolToUInt8(interlaced && m_GPUSTAT.interlaced_field)) & 1u;
|
||||
const u32 reinterpret_field_offset = BoolToUInt32(m_GPUSTAT.displaying_odd_line);
|
||||
const u32 reinterpret_start_x = m_crtc_state.regs.X * m_resolution_scale;
|
||||
const u32 reinterpret_width = scaled_display_width + (m_crtc_state.display_vram_left - m_crtc_state.regs.X);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user