gl_state_tracker: Implement dirty flags for blending

This commit is contained in:
ReinUsesLisp 2019-12-29 18:14:40 -03:00
parent f7ec078592
commit b01dd7d1c8
5 changed files with 68 additions and 15 deletions

View file

@ -458,6 +458,7 @@ void RasterizerOpenGL::Clear() {
} }
// TODO: Signal state tracker about these changes // TODO: Signal state tracker about these changes
state_tracker.NotifyBlend0();
// TODO(Rodrigo): Find out if these changes affect clearing // TODO(Rodrigo): Find out if these changes affect clearing
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
glDisablei(GL_BLEND, 0); glDisablei(GL_BLEND, 0);
@ -1102,31 +1103,53 @@ void RasterizerOpenGL::SyncFragmentColorClampState() {
} }
void RasterizerOpenGL::SyncBlendState() { void RasterizerOpenGL::SyncBlendState() {
auto& maxwell3d = system.GPU().Maxwell3D(); auto& gpu = system.GPU().Maxwell3D();
const auto& regs = maxwell3d.regs; auto& flags = gpu.dirty.flags;
const auto& regs = gpu.regs;
glBlendColor(regs.blend_color.r, regs.blend_color.g, regs.blend_color.b, regs.blend_color.a); if (flags[Dirty::BlendColor]) {
flags[Dirty::BlendColor] = false;
glBlendColor(regs.blend_color.r, regs.blend_color.g, regs.blend_color.b,
regs.blend_color.a);
}
// TODO(Rodrigo): Revisit blending, there are several registers we are not reading
if (!flags[Dirty::BlendStates]) {
return;
}
flags[Dirty::BlendStates] = false;
if (!regs.independent_blend_enable) { if (!regs.independent_blend_enable) {
const auto& src = regs.blend; if (!regs.blend.enable[0]) {
oglEnable(GL_BLEND, src.enable[0]); glDisable(GL_BLEND);
if (!src.enable[0]) {
return; return;
} }
glBlendFuncSeparate(MaxwellToGL::BlendFunc(src.factor_source_rgb), glEnable(GL_BLEND);
MaxwellToGL::BlendFunc(src.factor_dest_rgb), glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.factor_source_rgb),
MaxwellToGL::BlendFunc(src.factor_source_a), MaxwellToGL::BlendFunc(regs.blend.factor_dest_rgb),
MaxwellToGL::BlendFunc(src.factor_dest_a)); MaxwellToGL::BlendFunc(regs.blend.factor_source_a),
glBlendEquationSeparate(MaxwellToGL::BlendEquation(src.equation_rgb), MaxwellToGL::BlendFunc(regs.blend.factor_dest_a));
MaxwellToGL::BlendEquation(src.equation_a)); glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.equation_rgb),
MaxwellToGL::BlendEquation(regs.blend.equation_a));
return; return;
} }
const bool force = flags[Dirty::BlendIndependentEnabled];
flags[Dirty::BlendIndependentEnabled] = false;
for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) {
oglEnablei(GL_BLEND, regs.blend.enable[i], static_cast<GLuint>(i)); if (!force && !flags[Dirty::BlendState0 + i]) {
if (!regs.blend.enable[i]) {
continue; continue;
} }
flags[Dirty::BlendState0 + i] = false;
if (!regs.blend.enable[i]) {
glDisablei(GL_BLEND, static_cast<GLuint>(i));
continue;
}
glEnablei(GL_BLEND, static_cast<GLuint>(i));
const auto& src = regs.independent_blend[i]; const auto& src = regs.independent_blend[i];
glBlendFuncSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendFunc(src.factor_source_rgb), glBlendFuncSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendFunc(src.factor_source_rgb),
MaxwellToGL::BlendFunc(src.factor_dest_rgb), MaxwellToGL::BlendFunc(src.factor_dest_rgb),

View file

@ -129,6 +129,21 @@ void SetupDirtyShaders(Tables& tables) {
Shaders); Shaders);
} }
void SetupDirtyBlend(Tables& tables) {
FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendColor);
tables[0][OFF(independent_blend_enable)] = BlendIndependentEnabled;
for (std::size_t i = 0; i < Regs::NumRenderTargets; ++i) {
const std::size_t offset = OFF(independent_blend) + i * NUM(independent_blend[0]);
FillBlock(tables[0], offset, NUM(independent_blend[0]), BlendState0 + i);
tables[0][OFF(blend.enable) + i] = static_cast<u8>(BlendState0 + i);
}
FillBlock(tables[1], OFF(independent_blend), NUM(independent_blend), BlendStates);
FillBlock(tables[1], OFF(blend), NUM(blend), BlendStates);
}
void SetupDirtyMisc(Tables& tables) { void SetupDirtyMisc(Tables& tables) {
tables[0][OFF(clip_distance_enabled)] = ClipDistances; tables[0][OFF(clip_distance_enabled)] = ClipDistances;
} }
@ -147,6 +162,7 @@ void StateTracker::Initialize() {
SetupDirtyVertexArrays(tables); SetupDirtyVertexArrays(tables);
SetupDirtyVertexFormat(tables); SetupDirtyVertexFormat(tables);
SetupDirtyShaders(tables); SetupDirtyShaders(tables);
SetupDirtyBlend(tables);
SetupDirtyMisc(tables); SetupDirtyMisc(tables);
auto& store = dirty.on_write_stores; auto& store = dirty.on_write_stores;

View file

@ -47,8 +47,15 @@ enum : u8 {
ColorMask0, ColorMask0,
ColorMask7 = ColorMask0 + 7, ColorMask7 = ColorMask0 + 7,
BlendColor,
BlendIndependentEnabled,
BlendStates,
BlendState0,
BlendState7 = BlendState0 + 7,
Shaders, Shaders,
ClipDistances, ClipDistances,
CullTestEnable, CullTestEnable,
FrontFace, FrontFace,
CullFace, CullFace,
@ -56,7 +63,6 @@ enum : u8 {
DepthTest, DepthTest,
StencilTest, StencilTest,
ColorMask, ColorMask,
BlendState,
PolygonOffset, PolygonOffset,
Last Last
@ -103,6 +109,12 @@ public:
flags[OpenGL::Dirty::ColorMask0] = true; flags[OpenGL::Dirty::ColorMask0] = true;
} }
void NotifyBlend0() {
auto& flags = system.GPU().Maxwell3D().dirty.flags;
flags[OpenGL::Dirty::BlendStates] = true;
flags[OpenGL::Dirty::BlendState0] = true;
}
void NotifyFramebuffer() { void NotifyFramebuffer() {
auto& flags = system.GPU().Maxwell3D().dirty.flags; auto& flags = system.GPU().Maxwell3D().dirty.flags;
flags[VideoCommon::Dirty::RenderTargets] = true; flags[VideoCommon::Dirty::RenderTargets] = true;

View file

@ -520,6 +520,7 @@ void TextureCacheOpenGL::ImageBlit(View& src_view, View& dst_view,
// TODO: Signal state tracker about these changes // TODO: Signal state tracker about these changes
state_tracker.NotifyScissor0(); state_tracker.NotifyScissor0();
state_tracker.NotifyBlend0();
state_tracker.NotifyFramebuffer(); state_tracker.NotifyFramebuffer();
if (dst_params.srgb_conversion) { if (dst_params.srgb_conversion) {

View file

@ -580,6 +580,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
state_tracker.NotifyViewport0(); state_tracker.NotifyViewport0();
state_tracker.NotifyScissor0(); state_tracker.NotifyScissor0();
state_tracker.NotifyColorMask0(); state_tracker.NotifyColorMask0();
state_tracker.NotifyBlend0();
state_tracker.NotifyFramebuffer(); state_tracker.NotifyFramebuffer();
program_manager.UseVertexShader(vertex_program.handle); program_manager.UseVertexShader(vertex_program.handle);