gl_state_tracker: Implement dirty flags for blending
This commit is contained in:
parent
f7ec078592
commit
b01dd7d1c8
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Reference in New Issue