mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-14 01:59:34 +01:00
Make ConvertBlendState into a reasonably pure function with no side effects
This commit is contained in:
1 parent
e97d771e0f
commit
71103cb0ca
3 files changed
+43
-26
No files matched your search
@@ -99,6 +99,10 @@ enum class BlendEq : uint8_t {
|
||||
|
||||
struct GenericBlendState {
|
||||
bool enabled;
|
||||
bool resetShaderBlending;
|
||||
bool applyShaderBlending;
|
||||
bool dirtyShaderBlend;
|
||||
ReplaceAlphaType replaceAlphaWithStencil;
|
||||
|
||||
BlendFactor srcColor;
|
||||
BlendFactor dstColor;
|
||||
|
||||
+37
-23
@@ -224,7 +224,6 @@ bool TransformDrawEngine::ApplyShaderBlending() {
|
||||
}
|
||||
|
||||
inline void TransformDrawEngine::ResetShaderBlending() {
|
||||
// Wait - what does this have to do with FBOs?
|
||||
if (fboTexBound_) {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
@@ -234,7 +233,7 @@ inline void TransformDrawEngine::ResetShaderBlending() {
|
||||
}
|
||||
|
||||
// Try to simulate some common logic ops.
|
||||
void TransformDrawEngine::ApplyStencilReplaceAndLogicOp(ReplaceAlphaType replaceAlphaWithStencil, GenericBlendState &blendState) {
|
||||
static void ApplyStencilReplaceAndLogicOp(ReplaceAlphaType replaceAlphaWithStencil, GenericBlendState &blendState) {
|
||||
StencilValueType stencilType = STENCIL_VALUE_KEEP;
|
||||
if (replaceAlphaWithStencil == REPLACE_ALPHA_YES) {
|
||||
stencilType = ReplaceAlphaWithStencilType();
|
||||
@@ -338,7 +337,7 @@ void TransformDrawEngine::ApplyStencilReplaceAndLogicOp(ReplaceAlphaType replace
|
||||
|
||||
// Called even if AlphaBlendEnable == false - it also deals with stencil-related blend state.
|
||||
|
||||
void TransformDrawEngine::ConvertBlendState(GenericBlendState &blendState) {
|
||||
static void ConvertBlendState(GenericBlendState &blendState) {
|
||||
// Blending is a bit complex to emulate. This is due to several reasons:
|
||||
//
|
||||
// * Doubled blend modes (src, dst, inversed) aren't supported in OpenGL.
|
||||
@@ -350,26 +349,25 @@ void TransformDrawEngine::ConvertBlendState(GenericBlendState &blendState) {
|
||||
// If we can't apply blending, we make a copy of the framebuffer and do it manually.
|
||||
gstate_c.allowShaderBlend = !g_Config.bDisableSlowFramebufEffects;
|
||||
|
||||
blendState.applyShaderBlending = false;
|
||||
blendState.dirtyShaderBlend = false;
|
||||
|
||||
ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.allowShaderBlend, gstate.FrameBufFormat());
|
||||
ReplaceAlphaType replaceAlphaWithStencil = ReplaceAlphaWithStencil(replaceBlend);
|
||||
bool usePreSrc = false;
|
||||
|
||||
switch (replaceBlend) {
|
||||
case REPLACE_BLEND_NO:
|
||||
ResetShaderBlending();
|
||||
blendState.resetShaderBlending = true;
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
ApplyStencilReplaceAndLogicOp(replaceAlphaWithStencil, blendState);
|
||||
return;
|
||||
|
||||
case REPLACE_BLEND_COPY_FBO:
|
||||
if (ApplyShaderBlending()) {
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
ApplyStencilReplaceAndLogicOp(replaceAlphaWithStencil, blendState);
|
||||
return;
|
||||
}
|
||||
// Until next time, force it off.
|
||||
gstate_c.allowShaderBlend = false;
|
||||
break;
|
||||
blendState.applyShaderBlending = true;
|
||||
blendState.resetShaderBlending = false;
|
||||
blendState.replaceAlphaWithStencil = replaceAlphaWithStencil;
|
||||
break; // Surely this should be return??
|
||||
|
||||
case REPLACE_BLEND_PRE_SRC:
|
||||
case REPLACE_BLEND_PRE_SRC_2X_ALPHA:
|
||||
@@ -383,7 +381,7 @@ void TransformDrawEngine::ConvertBlendState(GenericBlendState &blendState) {
|
||||
}
|
||||
|
||||
blendState.enabled = true;
|
||||
ResetShaderBlending();
|
||||
blendState.resetShaderBlending = true;
|
||||
|
||||
const GEBlendMode blendFuncEq = gstate.getBlendEq();
|
||||
GEBlendSrcFactor blendFuncA = gstate.getBlendFuncA();
|
||||
@@ -449,9 +447,9 @@ void TransformDrawEngine::ConvertBlendState(GenericBlendState &blendState) {
|
||||
|
||||
if (usePreSrc) {
|
||||
glBlendFuncA = BlendFactor::ONE;
|
||||
// Need to pull in the fixed color.
|
||||
// Need to pull in the fixed color. TODO: If it hasn't changed, no need to dirty.
|
||||
if (blendFuncA == GE_SRCBLEND_FIXA) {
|
||||
shaderManager_->DirtyUniform(DIRTY_SHADERBLEND);
|
||||
blendState.dirtyShaderBlend = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,9 +625,29 @@ void TransformDrawEngine::ApplyDrawState(int prim) {
|
||||
// Start profiling here to skip SetTexture which is already accounted for
|
||||
PROFILE_THIS_SCOPE("applydrawstate");
|
||||
|
||||
// Set blend - unless we need to do it in the shader.
|
||||
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
|
||||
|
||||
// Do the large chunks of state conversion. We might be able to hide these two behind a dirty-flag each,
|
||||
// to avoid recomputing heavy stuff unnecessarily every draw call.
|
||||
GenericBlendState blendState;
|
||||
ConvertBlendState(blendState);
|
||||
ViewportAndScissor vpAndScissor;
|
||||
ConvertViewportAndScissor(useBufferedRendering,
|
||||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
|
||||
if (blendState.applyShaderBlending) {
|
||||
if (ApplyShaderBlending()) {
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState);
|
||||
} else {
|
||||
// Until next time, force it off.
|
||||
gstate_c.allowShaderBlend = false;
|
||||
}
|
||||
} else if (blendState.resetShaderBlending) {
|
||||
ResetShaderBlending();
|
||||
}
|
||||
|
||||
if (blendState.enabled) {
|
||||
glstate.blend.enable();
|
||||
@@ -637,13 +655,15 @@ void TransformDrawEngine::ApplyDrawState(int prim) {
|
||||
glstate.blendFuncSeparate.set(
|
||||
glBlendFactorLookup[(size_t)blendState.srcColor], glBlendFactorLookup[(size_t)blendState.dstColor],
|
||||
glBlendFactorLookup[(size_t)blendState.srcAlpha], glBlendFactorLookup[(size_t)blendState.dstAlpha]);
|
||||
if (blendState.dirtyShaderBlend) {
|
||||
shaderManager_->DirtyUniform(DIRTY_SHADERBLEND);
|
||||
}
|
||||
} else {
|
||||
glstate.blend.disable();
|
||||
}
|
||||
|
||||
bool alwaysDepthWrite = g_Config.bAlwaysDepthWrite;
|
||||
bool enableStencilTest = !g_Config.bDisableStencilTest;
|
||||
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
|
||||
|
||||
// Dither
|
||||
if (gstate.isDitherEnabled()) {
|
||||
@@ -782,12 +802,6 @@ void TransformDrawEngine::ApplyDrawState(int prim) {
|
||||
}
|
||||
}
|
||||
|
||||
ViewportAndScissor vpAndScissor;
|
||||
ConvertViewportAndScissor(useBufferedRendering,
|
||||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
|
||||
if (vpAndScissor.scissorEnable) {
|
||||
glstate.scissorTest.enable();
|
||||
if (!useBufferedRendering) {
|
||||
|
||||
@@ -194,10 +194,9 @@ private:
|
||||
void DoFlush();
|
||||
void ApplyDrawState(int prim);
|
||||
void ApplyDrawStateLate();
|
||||
void ConvertBlendState(GenericBlendState &blendState);
|
||||
void ApplyStencilReplaceAndLogicOp(ReplaceAlphaType replaceAlphaWithStencil, GenericBlendState &blendState);
|
||||
bool ApplyShaderBlending();
|
||||
inline void ResetShaderBlending();
|
||||
void ResetShaderBlending();
|
||||
|
||||
GLuint AllocateBuffer();
|
||||
void FreeBuffer(GLuint buf);
|
||||
|
||||
|
||||
Reference in new issue
Block a user