Pica: Implement LogicOp function.

This commit is contained in:
bunnei 2015-05-25 18:39:03 -04:00
parent 3b5ff61201
commit e6ace38815
7 changed files with 135 additions and 8 deletions

View file

@ -135,6 +135,7 @@ void RasterizerOpenGL::Reset() {
SyncBlendFuncs();
SyncBlendColor();
SyncAlphaTest();
SyncLogicOp();
SyncStencilTest();
SyncDepthTest();
@ -249,6 +250,11 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
SyncDepthTest();
break;
// Logic op
case PICA_REG_INDEX(output_merger.logic_op):
SyncLogicOp();
break;
// TEV stage 0
case PICA_REG_INDEX(tev_stage0.color_source1):
SyncTevSources(0, regs.tev_stage0);
@ -633,6 +639,10 @@ void RasterizerOpenGL::SyncAlphaTest() {
glUniform1f(uniform_alphatest_ref, regs.output_merger.alpha_test.ref / 255.0f);
}
void RasterizerOpenGL::SyncLogicOp() {
state.logic_op = PicaToGL::LogicOp(Pica::g_state.regs.output_merger.logic_op);
}
void RasterizerOpenGL::SyncStencilTest() {
// TODO: Implement stencil test, mask, and op
}

View file

@ -125,6 +125,9 @@ private:
/// Syncs the alpha test states to match the PICA register
void SyncAlphaTest();
/// Syncs the logic op states to match the PICA register
void SyncLogicOp();
/// Syncs the stencil test states to match the PICA register
void SyncStencilTest();

View file

@ -32,6 +32,8 @@ OpenGLState::OpenGLState() {
blend.color.blue = 0.0f;
blend.color.alpha = 0.0f;
logic_op = GL_COPY;
for (auto& texture_unit : texture_units) {
texture_unit.enabled_2d = false;
texture_unit.texture_2d = 0;
@ -99,8 +101,13 @@ void OpenGLState::Apply() {
if (blend.enabled != cur_state.blend.enabled) {
if (blend.enabled) {
glEnable(GL_BLEND);
cur_state.logic_op = GL_COPY;
glLogicOp(cur_state.logic_op);
glDisable(GL_COLOR_LOGIC_OP);
} else {
glDisable(GL_BLEND);
glEnable(GL_COLOR_LOGIC_OP);
}
}
@ -118,6 +125,10 @@ void OpenGLState::Apply() {
glBlendFuncSeparate(blend.src_rgb_func, blend.dst_rgb_func, blend.src_a_func, blend.dst_a_func);
}
if (logic_op != cur_state.logic_op) {
glLogicOp(logic_op);
}
// Textures
for (unsigned texture_index = 0; texture_index < ARRAY_SIZE(texture_units); ++texture_index) {
if (texture_units[texture_index].enabled_2d != cur_state.texture_units[texture_index].enabled_2d) {

View file

@ -42,6 +42,8 @@ public:
} color; // GL_BLEND_COLOR
} blend;
GLenum logic_op; // GL_LOGIC_OP_MODE
// 3 texture units - one for each that is used in PICA fragment shader emulation
struct {
bool enabled_2d; // GL_TEXTURE_2D

View file

@ -71,6 +71,37 @@ inline GLenum BlendFunc(Pica::Regs::BlendFactor factor) {
return blend_func_table[(unsigned)factor];
}
inline GLenum LogicOp(Pica::Regs::LogicOp op) {
static const GLenum logic_op_table[] = {
GL_CLEAR, // Clear
GL_AND, // And
GL_AND_REVERSE, // AndReverse
GL_COPY, // Copy
GL_SET, // Set
GL_COPY_INVERTED, // CopyInverted
GL_NOOP, // NoOp
GL_INVERT, // Invert
GL_NAND, // Nand
GL_OR, // Or
GL_NOR, // Nor
GL_XOR, // Xor
GL_EQUIV, // Equiv
GL_AND_INVERTED, // AndInverted
GL_OR_REVERSE, // OrReverse
GL_OR_INVERTED, // OrInverted
};
// Range check table for input
if ((unsigned)op >= ARRAY_SIZE(logic_op_table)) {
LOG_CRITICAL(Render_OpenGL, "Unknown logic op %d", op);
UNREACHABLE();
return GL_COPY;
}
return logic_op_table[(unsigned)op];
}
inline GLenum CompareFunc(Pica::Regs::CompareFunc func) {
static const GLenum compare_func_table[] = {
GL_NEVER, // CompareFunc::Never