mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 17:49:29 +01:00
Merge pull request #13637 from hrydgard/shaderblend-cleanup
Shaderblend code cleanup
This commit is contained in:
17 files changed
+139
-172
No files matched your search
@@ -480,8 +480,9 @@ u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr,
|
||||
return GE_VTYPE_TC_FLOAT | GE_VTYPE_COL_8888 | GE_VTYPE_NRM_FLOAT | GE_VTYPE_POS_FLOAT | (vertType & (GE_VTYPE_IDX_MASK | GE_VTYPE_THROUGH));
|
||||
}
|
||||
|
||||
bool DrawEngineCommon::ApplyShaderBlending() {
|
||||
bool DrawEngineCommon::ApplyFramebufferRead(bool *fboTexNeedsBind) {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)) {
|
||||
*fboTexNeedsBind = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -502,7 +503,7 @@ bool DrawEngineCommon::ApplyShaderBlending() {
|
||||
return false;
|
||||
}
|
||||
|
||||
fboTexNeedBind_ = true;
|
||||
*fboTexNeedsBind = true;
|
||||
|
||||
gstate_c.Dirty(DIRTY_SHADERBLEND);
|
||||
return true;
|
||||
|
||||
@@ -112,7 +112,7 @@ protected:
|
||||
// Vertex decoding
|
||||
void DecodeVertsStep(u8 *dest, int &i, int &decodedVerts);
|
||||
|
||||
bool ApplyShaderBlending();
|
||||
bool ApplyFramebufferRead(bool *fboTexNeedsBind);
|
||||
|
||||
inline int IndexSize(u32 vtype) const {
|
||||
const u32 indexType = (vtype & GE_VTYPE_IDX_MASK);
|
||||
@@ -169,7 +169,7 @@ protected:
|
||||
GEPrimitiveType prevPrim_ = GE_PRIM_INVALID;
|
||||
|
||||
// Shader blending state
|
||||
bool fboTexNeedBind_ = false;
|
||||
bool fboTexNeedsBind_ = false;
|
||||
bool fboTexBound_ = false;
|
||||
|
||||
// Hardware tessellation
|
||||
|
||||
@@ -104,6 +104,8 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
bool earlyFragmentTests = ((!enableAlphaTest && !enableColorTest) || testForceToZero) && !gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT);
|
||||
bool useAdrenoBugWorkaround = id.Bit(FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL);
|
||||
|
||||
bool readFramebufferTex = replaceBlend == REPLACE_BLEND_COPY_FBO && !gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH);
|
||||
|
||||
if (compat.shaderLanguage == ShaderLanguage::GLSL_VULKAN) {
|
||||
if (earlyFragmentTests) {
|
||||
WRITE(p, "layout (early_fragment_tests) in;\n");
|
||||
@@ -116,10 +118,8 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
WRITE(p, "layout (binding = 0) uniform sampler2D tex;\n");
|
||||
}
|
||||
|
||||
if (!isModeClear && replaceBlend > REPLACE_BLEND_STANDARD) {
|
||||
if (replaceBlend == REPLACE_BLEND_COPY_FBO) {
|
||||
WRITE(p, "layout (binding = 1) uniform sampler2D fbotex;\n");
|
||||
}
|
||||
if (readFramebufferTex) {
|
||||
WRITE(p, "layout (binding = 1) uniform sampler2D fbotex;\n");
|
||||
}
|
||||
|
||||
if (shaderDepal) {
|
||||
@@ -151,11 +151,13 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
if (compat.shaderLanguage == HLSL_D3D9) {
|
||||
if (doTexture)
|
||||
WRITE(p, "sampler tex : register(s0);\n");
|
||||
if (!isModeClear && replaceBlend > REPLACE_BLEND_STANDARD) {
|
||||
if (replaceBlend == REPLACE_BLEND_COPY_FBO) {
|
||||
WRITE(p, "vec2 u_fbotexSize : register(c%i);\n", CONST_PS_FBOTEXSIZE);
|
||||
WRITE(p, "sampler fbotex : register(s1);\n");
|
||||
}
|
||||
|
||||
if (readFramebufferTex) {
|
||||
WRITE(p, "vec2 u_fbotexSize : register(c%i);\n", CONST_PS_FBOTEXSIZE);
|
||||
WRITE(p, "sampler fbotex : register(s1);\n");
|
||||
}
|
||||
|
||||
if (replaceBlend > REPLACE_BLEND_STANDARD) {
|
||||
if (replaceBlendFuncA >= GE_SRCBLEND_FIXA) {
|
||||
WRITE(p, "float3 u_blendFixA : register(c%i);\n", CONST_PS_BLENDFIXA);
|
||||
}
|
||||
@@ -244,11 +246,11 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
} else if (compat.shaderLanguage == HLSL_D3D9) {
|
||||
if (doTexture)
|
||||
WRITE(p, "sampler tex : register(s0);\n");
|
||||
if (!isModeClear && replaceBlend > REPLACE_BLEND_STANDARD) {
|
||||
if (replaceBlend == REPLACE_BLEND_COPY_FBO) {
|
||||
WRITE(p, "vec2 u_fbotexSize : register(c%i);\n", CONST_PS_FBOTEXSIZE);
|
||||
WRITE(p, "sampler fbotex : register(s1);\n");
|
||||
}
|
||||
if (readFramebufferTex) {
|
||||
WRITE(p, "vec2 u_fbotexSize : register(c%i);\n", CONST_PS_FBOTEXSIZE);
|
||||
WRITE(p, "sampler fbotex : register(s1);\n");
|
||||
}
|
||||
if (replaceBlend > REPLACE_BLEND_STANDARD) {
|
||||
if (replaceBlendFuncA >= GE_SRCBLEND_FIXA) {
|
||||
WRITE(p, "float3 u_blendFixA : register(c%i);\n", CONST_PS_BLENDFIXA);
|
||||
}
|
||||
@@ -276,7 +278,6 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
if (enableFog) {
|
||||
WRITE(p, "float3 u_fogcolor : register(c%i);\n", CONST_PS_FOGCOLOR);
|
||||
}
|
||||
|
||||
} else if (ShaderLanguageIsOpenGL(compat.shaderLanguage)) {
|
||||
if (shaderDepal && gl_extensions.IsGLES) {
|
||||
WRITE(p, "precision highp int;\n");
|
||||
@@ -287,7 +288,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
|
||||
if (!isModeClear && replaceBlend > REPLACE_BLEND_STANDARD) {
|
||||
*uniformMask |= DIRTY_SHADERBLEND;
|
||||
if (!gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH) && replaceBlend == REPLACE_BLEND_COPY_FBO) {
|
||||
if (readFramebufferTex) {
|
||||
if (!compat.texelFetch) {
|
||||
WRITE(p, "uniform vec2 u_fbotexSize;\n");
|
||||
}
|
||||
@@ -869,7 +870,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
}
|
||||
|
||||
if (replaceBlend == REPLACE_BLEND_2X_ALPHA || replaceBlend == REPLACE_BLEND_PRE_SRC_2X_ALPHA) {
|
||||
WRITE(p, " v.a = v.a * 2.0;\n");
|
||||
WRITE(p, " v.a *= 2.0;\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -253,7 +253,7 @@ StencilValueType ReplaceAlphaWithStencilType() {
|
||||
return STENCIL_VALUE_KEEP;
|
||||
}
|
||||
|
||||
ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bufferFormat) {
|
||||
ReplaceBlendType ReplaceBlendWithShader(bool allowFramebufferRead, GEBufferFormat bufferFormat) {
|
||||
if (!gstate.isAlphaBlendEnabled() || gstate.isModeClear()) {
|
||||
return REPLACE_BLEND_NO;
|
||||
}
|
||||
@@ -262,14 +262,14 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
|
||||
// Let's get the non-factor modes out of the way first.
|
||||
switch (eq) {
|
||||
case GE_BLENDMODE_ABSDIFF:
|
||||
return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
|
||||
|
||||
case GE_BLENDMODE_MIN:
|
||||
case GE_BLENDMODE_MAX:
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_BLEND_MINMAX)) {
|
||||
return REPLACE_BLEND_STANDARD;
|
||||
} else {
|
||||
return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -292,19 +292,19 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
|
||||
return REPLACE_BLEND_2X_ALPHA;
|
||||
// Can't double, we need the source color to be correct.
|
||||
// Doubling only alpha would clamp the src alpha incorrectly.
|
||||
return !allowShaderBlend ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
|
||||
case GE_DSTBLEND_DOUBLEDSTALPHA:
|
||||
case GE_DSTBLEND_DOUBLEINVDSTALPHA:
|
||||
if (bufferFormat == GE_FORMAT_565)
|
||||
return REPLACE_BLEND_2X_ALPHA;
|
||||
return !allowShaderBlend ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
|
||||
case GE_DSTBLEND_DOUBLESRCALPHA:
|
||||
// We can't technically do this correctly (due to clamping) without reading the dst color.
|
||||
// Using a copy isn't accurate either, though, when there's overlap.
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH))
|
||||
return !allowShaderBlend ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
return REPLACE_BLEND_PRE_SRC_2X_ALPHA;
|
||||
|
||||
case GE_DSTBLEND_DOUBLEINVSRCALPHA:
|
||||
@@ -331,7 +331,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
|
||||
return REPLACE_BLEND_STANDARD;
|
||||
}
|
||||
// Can't double, we need the source color to be correct.
|
||||
return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
|
||||
|
||||
case GE_DSTBLEND_DOUBLEDSTALPHA:
|
||||
case GE_DSTBLEND_DOUBLEINVDSTALPHA:
|
||||
@@ -340,7 +340,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
|
||||
// Doubling will have no effect here.
|
||||
return REPLACE_BLEND_STANDARD;
|
||||
}
|
||||
return !allowShaderBlend ? REPLACE_BLEND_2X_SRC : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_2X_SRC : REPLACE_BLEND_COPY_FBO;
|
||||
|
||||
case GE_DSTBLEND_DOUBLESRCALPHA:
|
||||
case GE_DSTBLEND_DOUBLEINVSRCALPHA:
|
||||
@@ -349,7 +349,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
|
||||
}
|
||||
// Double both src (for dst alpha) and alpha (for dst factor.)
|
||||
// But to be accurate (clamping), we need to read the dst color.
|
||||
return !allowShaderBlend ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
|
||||
case GE_DSTBLEND_SRCALPHA:
|
||||
case GE_DSTBLEND_INVSRCALPHA:
|
||||
@@ -361,7 +361,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
|
||||
return REPLACE_BLEND_STANDARD;
|
||||
}
|
||||
// We can't technically do this correctly (due to clamping) without reading the dst alpha.
|
||||
return !allowShaderBlend ? REPLACE_BLEND_2X_SRC : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_2X_SRC : REPLACE_BLEND_COPY_FBO;
|
||||
}
|
||||
|
||||
case GE_SRCBLEND_DOUBLEINVDSTALPHA:
|
||||
@@ -375,14 +375,14 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
|
||||
if (bufferFormat == GE_FORMAT_565) {
|
||||
return REPLACE_BLEND_STANDARD;
|
||||
}
|
||||
return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
|
||||
|
||||
case GE_DSTBLEND_DOUBLESRCALPHA:
|
||||
case GE_DSTBLEND_DOUBLEINVSRCALPHA:
|
||||
if (bufferFormat == GE_FORMAT_565) {
|
||||
return REPLACE_BLEND_2X_ALPHA;
|
||||
}
|
||||
return !allowShaderBlend ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
|
||||
case GE_DSTBLEND_SRCALPHA:
|
||||
case GE_DSTBLEND_INVSRCALPHA:
|
||||
@@ -393,7 +393,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
|
||||
if (bufferFormat == GE_FORMAT_565) {
|
||||
return REPLACE_BLEND_STANDARD;
|
||||
}
|
||||
return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
|
||||
}
|
||||
|
||||
case GE_SRCBLEND_FIXA:
|
||||
@@ -401,7 +401,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
|
||||
switch (funcB) {
|
||||
case GE_DSTBLEND_DOUBLESRCALPHA:
|
||||
// Can't safely double alpha, will clamp.
|
||||
return !allowShaderBlend ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
|
||||
case GE_DSTBLEND_DOUBLEINVSRCALPHA:
|
||||
// Doubling alpha is safe for the inverse, will clamp to zero either way.
|
||||
@@ -412,7 +412,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
|
||||
if (bufferFormat == GE_FORMAT_565) {
|
||||
return REPLACE_BLEND_STANDARD;
|
||||
}
|
||||
return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
|
||||
|
||||
case GE_DSTBLEND_FIXB:
|
||||
default:
|
||||
@@ -446,14 +446,14 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
|
||||
if (funcA == GE_SRCBLEND_SRCALPHA || funcA == GE_SRCBLEND_INVSRCALPHA) {
|
||||
// Can't safely double alpha, will clamp. However, a copy may easily be worse due to overlap.
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH))
|
||||
return !allowShaderBlend ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
return REPLACE_BLEND_PRE_SRC_2X_ALPHA;
|
||||
} else {
|
||||
// This means dst alpha/color is used in the src factor.
|
||||
// Unfortunately, copying here causes overlap problems in Silent Hill games (it seems?)
|
||||
// We will just hope that doubling alpha for the dst factor will not clamp too badly.
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH))
|
||||
return !allowShaderBlend ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
|
||||
return REPLACE_BLEND_2X_ALPHA;
|
||||
}
|
||||
|
||||
@@ -470,7 +470,7 @@ ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend, GEBufferFormat bu
|
||||
if (bufferFormat == GE_FORMAT_565) {
|
||||
return REPLACE_BLEND_STANDARD;
|
||||
}
|
||||
return !allowShaderBlend ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
|
||||
return !allowFramebufferRead ? REPLACE_BLEND_STANDARD : REPLACE_BLEND_COPY_FBO;
|
||||
|
||||
default:
|
||||
return REPLACE_BLEND_STANDARD;
|
||||
@@ -906,7 +906,7 @@ static void ApplyLogicOp(BlendFactor &srcBlend, BlendFactor &dstBlend, BlendEq &
|
||||
}
|
||||
|
||||
// Try to simulate some common logic ops.
|
||||
void ApplyStencilReplaceAndLogicOp(ReplaceAlphaType replaceAlphaWithStencil, GenericBlendState &blendState) {
|
||||
void ApplyStencilReplaceAndLogicOpIgnoreBlend(ReplaceAlphaType replaceAlphaWithStencil, GenericBlendState &blendState) {
|
||||
StencilValueType stencilType = STENCIL_VALUE_KEEP;
|
||||
if (replaceAlphaWithStencil == REPLACE_ALPHA_YES) {
|
||||
stencilType = ReplaceAlphaWithStencilType();
|
||||
@@ -958,7 +958,7 @@ void ApplyStencilReplaceAndLogicOp(ReplaceAlphaType replaceAlphaWithStencil, Gen
|
||||
|
||||
// Called even if AlphaBlendEnable == false - it also deals with stencil-related blend state.
|
||||
|
||||
void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend) {
|
||||
void ConvertBlendState(GenericBlendState &blendState, bool allowFramebufferRead) {
|
||||
// Blending is a bit complex to emulate. This is due to several reasons:
|
||||
//
|
||||
// * Doubled blend modes (src, dst, inversed) aren't supported in OpenGL.
|
||||
@@ -969,25 +969,25 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend) {
|
||||
//
|
||||
// If we can't apply blending, we make a copy of the framebuffer and do it manually.
|
||||
|
||||
blendState.applyShaderBlending = false;
|
||||
blendState.dirtyShaderBlend = false;
|
||||
blendState.applyFramebufferRead = false;
|
||||
blendState.dirtyShaderBlendFixValues = false;
|
||||
blendState.useBlendColor = false;
|
||||
blendState.replaceAlphaWithStencil = REPLACE_ALPHA_NO;
|
||||
|
||||
ReplaceBlendType replaceBlend = ReplaceBlendWithShader(allowShaderBlend, gstate.FrameBufFormat());
|
||||
ReplaceBlendType replaceBlend = ReplaceBlendWithShader(allowFramebufferRead, gstate.FrameBufFormat());
|
||||
ReplaceAlphaType replaceAlphaWithStencil = ReplaceAlphaWithStencil(replaceBlend);
|
||||
bool usePreSrc = false;
|
||||
|
||||
switch (replaceBlend) {
|
||||
case REPLACE_BLEND_NO:
|
||||
blendState.resetShaderBlending = true;
|
||||
blendState.resetFramebufferRead = true;
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
ApplyStencilReplaceAndLogicOp(replaceAlphaWithStencil, blendState);
|
||||
ApplyStencilReplaceAndLogicOpIgnoreBlend(replaceAlphaWithStencil, blendState);
|
||||
return;
|
||||
|
||||
case REPLACE_BLEND_COPY_FBO:
|
||||
blendState.applyShaderBlending = true;
|
||||
blendState.resetShaderBlending = false;
|
||||
blendState.applyFramebufferRead = true;
|
||||
blendState.resetFramebufferRead = false;
|
||||
blendState.replaceAlphaWithStencil = replaceAlphaWithStencil;
|
||||
break;
|
||||
|
||||
@@ -1003,7 +1003,7 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend) {
|
||||
}
|
||||
|
||||
blendState.enabled = true;
|
||||
blendState.resetShaderBlending = true;
|
||||
blendState.resetFramebufferRead = true;
|
||||
|
||||
const GEBlendMode blendFuncEq = gstate.getBlendEq();
|
||||
GEBlendSrcFactor blendFuncA = gstate.getBlendFuncA();
|
||||
@@ -1071,7 +1071,7 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend) {
|
||||
glBlendFuncA = BlendFactor::ONE;
|
||||
// Need to pull in the fixed color. TODO: If it hasn't changed, no need to dirty.
|
||||
if (blendFuncA == GE_SRCBLEND_FIXA) {
|
||||
blendState.dirtyShaderBlend = true;
|
||||
blendState.dirtyShaderBlendFixValues = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -121,9 +121,9 @@ enum class BlendEq : uint8_t {
|
||||
|
||||
struct GenericBlendState {
|
||||
bool enabled;
|
||||
bool resetShaderBlending;
|
||||
bool applyShaderBlending;
|
||||
bool dirtyShaderBlend;
|
||||
bool resetFramebufferRead;
|
||||
bool applyFramebufferRead;
|
||||
bool dirtyShaderBlendFixValues;
|
||||
ReplaceAlphaType replaceAlphaWithStencil;
|
||||
|
||||
BlendFactor srcColor;
|
||||
@@ -158,7 +158,7 @@ struct GenericBlendState {
|
||||
};
|
||||
|
||||
void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend);
|
||||
void ApplyStencilReplaceAndLogicOp(ReplaceAlphaType replaceAlphaWithStencil, GenericBlendState &blendState);
|
||||
void ApplyStencilReplaceAndLogicOpIgnoreBlend(ReplaceAlphaType replaceAlphaWithStencil, GenericBlendState &blendState);
|
||||
|
||||
struct GenericStencilFuncState {
|
||||
bool enabled;
|
||||
|
||||
@@ -240,7 +240,9 @@ void ComputeFragmentShaderID(FShaderID *id_out, const Draw::Bugs &bugs) {
|
||||
bool doFlatShading = gstate.getShadeMode() == GE_SHADE_FLAT;
|
||||
bool useShaderDepal = gstate_c.useShaderDepal;
|
||||
|
||||
ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.allowShaderBlend, gstate.FrameBufFormat());
|
||||
// Note how we here recompute some of the work already done in state mapping.
|
||||
// Not ideal! At least we share the code.
|
||||
ReplaceBlendType replaceBlend = ReplaceBlendWithShader(gstate_c.allowFramebufferRead, gstate.FrameBufFormat());
|
||||
ReplaceAlphaType stencilToAlpha = ReplaceAlphaWithStencil(replaceBlend);
|
||||
|
||||
// All texfuncs except replace are the same for RGB as for RGBA with full alpha.
|
||||
|
||||
@@ -160,7 +160,7 @@ private:
|
||||
|
||||
void ApplyDrawState(int prim);
|
||||
void ApplyDrawStateLate(bool applyStencilRef, uint8_t stencilRef);
|
||||
void ResetShaderBlending();
|
||||
void ResetFramebufferRead();
|
||||
|
||||
ID3D11InputLayout *SetupDecFmtForDraw(D3D11VertexShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt);
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ static const D3D11_LOGIC_OP logicOps[] = {
|
||||
D3D11_LOGIC_OP_SET,
|
||||
};
|
||||
|
||||
void DrawEngineD3D11::ResetShaderBlending() {
|
||||
void DrawEngineD3D11::ResetFramebufferRead() {
|
||||
if (fboTexBound_) {
|
||||
ID3D11ShaderResourceView *srv = nullptr;
|
||||
context_->PSSetShaderResources(0, 1, &srv);
|
||||
@@ -144,7 +144,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
|
||||
bool useBufferedRendering = framebufferManager_->UseBufferedRendering();
|
||||
// Blend
|
||||
if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
|
||||
gstate_c.SetAllowShaderBlend(!g_Config.bDisableSlowFramebufEffects);
|
||||
gstate_c.SetAllowFramebufferRead(!g_Config.bDisableSlowFramebufEffects);
|
||||
if (gstate.isModeClear()) {
|
||||
keys_.blend.value = 0; // full wipe
|
||||
keys_.blend.blendEnable = false;
|
||||
@@ -157,18 +157,19 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
|
||||
keys_.blend.value = 0;
|
||||
// Set blend - unless we need to do it in the shader.
|
||||
GenericBlendState blendState;
|
||||
ConvertBlendState(blendState, gstate_c.allowShaderBlend);
|
||||
if (blendState.applyShaderBlending) {
|
||||
if (ApplyShaderBlending()) {
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState);
|
||||
ConvertBlendState(blendState, gstate_c.allowFramebufferRead);
|
||||
if (blendState.applyFramebufferRead) {
|
||||
if (ApplyFramebufferRead(&fboTexNeedsBind_)) {
|
||||
// The shader takes over the responsibility for blending, so recompute.
|
||||
ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState);
|
||||
} else {
|
||||
// Until next time, force it off.
|
||||
ResetShaderBlending();
|
||||
gstate_c.SetAllowShaderBlend(false);
|
||||
ResetFramebufferRead();
|
||||
gstate_c.SetAllowFramebufferRead(false);
|
||||
}
|
||||
} else if (blendState.resetShaderBlending) {
|
||||
ResetShaderBlending();
|
||||
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
|
||||
} else if (blendState.resetFramebufferRead) {
|
||||
ResetFramebufferRead();
|
||||
}
|
||||
|
||||
if (blendState.enabled) {
|
||||
@@ -180,7 +181,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
|
||||
keys_.blend.srcAlpha = d3d11BlendFactorLookup[(size_t)blendState.srcAlpha];
|
||||
keys_.blend.destColor = d3d11BlendFactorLookup[(size_t)blendState.dstColor];
|
||||
keys_.blend.destAlpha = d3d11BlendFactorLookup[(size_t)blendState.dstAlpha];
|
||||
if (blendState.dirtyShaderBlend) {
|
||||
if (blendState.dirtyShaderBlendFixValues) {
|
||||
gstate_c.Dirty(DIRTY_SHADERBLEND);
|
||||
}
|
||||
dynState_.useBlendColor = blendState.useBlendColor;
|
||||
@@ -446,11 +447,11 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
|
||||
|
||||
void DrawEngineD3D11::ApplyDrawStateLate(bool applyStencilRef, uint8_t stencilRef) {
|
||||
if (!gstate.isModeClear()) {
|
||||
if (fboTexNeedBind_) {
|
||||
if (fboTexNeedsBind_) {
|
||||
framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY);
|
||||
// No sampler required, we do a plain Load in the pixel shader.
|
||||
fboTexBound_ = true;
|
||||
fboTexNeedBind_ = false;
|
||||
fboTexNeedsBind_ = false;
|
||||
}
|
||||
textureCache_->ApplyTexture();
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ private:
|
||||
|
||||
void ApplyDrawState(int prim);
|
||||
void ApplyDrawStateLate();
|
||||
void ResetShaderBlending();
|
||||
void ResetFramebufferRead();
|
||||
|
||||
IDirect3DVertexDeclaration9 *SetupDecFmtForDraw(VSShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt);
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ static const D3DSTENCILOP stencilOps[] = {
|
||||
D3DSTENCILOP_KEEP, // reserved
|
||||
};
|
||||
|
||||
inline void DrawEngineDX9::ResetShaderBlending() {
|
||||
inline void DrawEngineDX9::ResetFramebufferRead() {
|
||||
if (fboTexBound_) {
|
||||
device_->SetTexture(1, nullptr);
|
||||
fboTexBound_ = false;
|
||||
@@ -115,8 +115,8 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
|
||||
|
||||
if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
|
||||
gstate_c.Clean(DIRTY_BLEND_STATE);
|
||||
// Unfortunately, this isn't implemented yet.
|
||||
gstate_c.SetAllowShaderBlend(false);
|
||||
// Unfortunately, this isn't implemented on DX9 yet.
|
||||
gstate_c.SetAllowFramebufferRead(false);
|
||||
if (gstate.isModeClear()) {
|
||||
dxstate.blend.disable();
|
||||
|
||||
@@ -127,19 +127,20 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
|
||||
} else {
|
||||
// Set blend - unless we need to do it in the shader.
|
||||
GenericBlendState blendState;
|
||||
ConvertBlendState(blendState, gstate_c.allowShaderBlend);
|
||||
ConvertBlendState(blendState, gstate_c.allowFramebufferRead);
|
||||
|
||||
if (blendState.applyShaderBlending) {
|
||||
if (ApplyShaderBlending()) {
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState);
|
||||
if (blendState.applyFramebufferRead) {
|
||||
if (ApplyFramebufferRead(&fboTexNeedsBind_)) {
|
||||
// The shader takes over the responsibility for blending, so recompute.
|
||||
ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState);
|
||||
} else {
|
||||
// Until next time, force it off.
|
||||
ResetShaderBlending();
|
||||
gstate_c.SetAllowShaderBlend(false);
|
||||
ResetFramebufferRead();
|
||||
gstate_c.SetAllowFramebufferRead(false);
|
||||
}
|
||||
} else if (blendState.resetShaderBlending) {
|
||||
ResetShaderBlending();
|
||||
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
|
||||
} else if (blendState.resetFramebufferRead) {
|
||||
ResetFramebufferRead();
|
||||
}
|
||||
|
||||
if (blendState.enabled) {
|
||||
@@ -149,7 +150,7 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
|
||||
dxstate.blendFunc.set(
|
||||
dxBlendFactorLookup[(size_t)blendState.srcColor], dxBlendFactorLookup[(size_t)blendState.dstColor],
|
||||
dxBlendFactorLookup[(size_t)blendState.srcAlpha], dxBlendFactorLookup[(size_t)blendState.dstAlpha]);
|
||||
if (blendState.dirtyShaderBlend) {
|
||||
if (blendState.dirtyShaderBlendFixValues) {
|
||||
gstate_c.Dirty(DIRTY_SHADERBLEND);
|
||||
}
|
||||
if (blendState.useBlendColor) {
|
||||
@@ -166,20 +167,6 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
|
||||
bool bmask = ((gstate.pmskc >> 16) & 0xFF) < 128;
|
||||
bool amask = (gstate.pmska & 0xFF) < 128;
|
||||
|
||||
#ifndef MOBILE_DEVICE
|
||||
u8 abits = (gstate.pmska >> 0) & 0xFF;
|
||||
u8 rbits = (gstate.pmskc >> 0) & 0xFF;
|
||||
u8 gbits = (gstate.pmskc >> 8) & 0xFF;
|
||||
u8 bbits = (gstate.pmskc >> 16) & 0xFF;
|
||||
if ((rbits != 0 && rbits != 0xFF) || (gbits != 0 && gbits != 0xFF) || (bbits != 0 && bbits != 0xFF)) {
|
||||
WARN_LOG_REPORT_ONCE(rgbmask, G3D, "Unsupported RGB mask: r=%02x g=%02x b=%02x", rbits, gbits, bbits);
|
||||
}
|
||||
if (abits != 0 && abits != 0xFF) {
|
||||
// The stencil part of the mask is supported.
|
||||
WARN_LOG_REPORT_ONCE(amask, G3D, "Unsupported alpha/stencil mask: %02x", abits);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Let's not write to alpha if stencil isn't enabled.
|
||||
if (IsStencilTestOutputDisabled()) {
|
||||
amask = false;
|
||||
@@ -297,14 +284,14 @@ void DrawEngineDX9::ApplyDrawStateLate() {
|
||||
if (!gstate.isModeClear()) {
|
||||
textureCache_->ApplyTexture();
|
||||
|
||||
if (fboTexNeedBind_) {
|
||||
if (fboTexNeedsBind_) {
|
||||
// Note that this is positions, not UVs, that we need the copy from.
|
||||
framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY);
|
||||
// If we are rendering at a higher resolution, linear is probably best for the dest color.
|
||||
device_->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device_->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
fboTexBound_ = true;
|
||||
fboTexNeedBind_ = false;
|
||||
fboTexNeedsBind_ = false;
|
||||
}
|
||||
|
||||
// TODO: Test texture?
|
||||
|
||||
@@ -193,7 +193,7 @@ private:
|
||||
void DoFlush();
|
||||
void ApplyDrawState(int prim);
|
||||
void ApplyDrawStateLate(bool setStencil, int stencilValue);
|
||||
void ResetShaderBlending();
|
||||
void ResetFramebufferRead();
|
||||
|
||||
GLRInputLayout *SetupDecFmtForDraw(LinkedShader *program, const DecVtxFormat &decFmt);
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ static const GLushort logicOps[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
inline void DrawEngineGLES::ResetShaderBlending() {
|
||||
inline void DrawEngineGLES::ResetFramebufferRead() {
|
||||
if (fboTexBound_) {
|
||||
GLRenderManager *renderManager = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
renderManager->BindTexture(TEX_SLOT_SHADERBLEND_SRC, nullptr);
|
||||
@@ -156,7 +156,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
||||
|
||||
if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
|
||||
gstate_c.Clean(DIRTY_BLEND_STATE);
|
||||
gstate_c.SetAllowShaderBlend(!g_Config.bDisableSlowFramebufEffects);
|
||||
gstate_c.SetAllowFramebufferRead(!g_Config.bDisableSlowFramebufEffects);
|
||||
|
||||
if (gstate.isModeClear()) {
|
||||
// Color Test
|
||||
@@ -167,22 +167,22 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
||||
// 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, gstate_c.allowShaderBlend);
|
||||
ConvertBlendState(blendState, gstate_c.allowFramebufferRead);
|
||||
|
||||
if (blendState.applyShaderBlending) {
|
||||
if (ApplyShaderBlending()) {
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState);
|
||||
if (blendState.applyFramebufferRead) {
|
||||
if (ApplyFramebufferRead(&fboTexNeedsBind_)) {
|
||||
// The shader takes over the responsibility for blending, so recompute.
|
||||
ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState);
|
||||
|
||||
// We copy the framebuffer here, as doing so will wipe any blend state if we do it later.
|
||||
if (fboTexNeedBind_) {
|
||||
if (fboTexNeedsBind_) {
|
||||
// Note that this is positions, not UVs, that we need the copy from.
|
||||
// TODO: If the device doesn't support blit, this will corrupt the currently applied texture.
|
||||
framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY);
|
||||
// If we are rendering at a higher resolution, linear is probably best for the dest color.
|
||||
renderManager->SetTextureSampler(1, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_LINEAR, GL_LINEAR, 0.0f);
|
||||
fboTexBound_ = true;
|
||||
fboTexNeedBind_ = false;
|
||||
fboTexNeedsBind_ = false;
|
||||
|
||||
framebufferManager_->RebindFramebuffer("RebindFramebuffer - ApplyDrawState");
|
||||
// Must dirty blend state here so we re-copy next time. Example: Lunar's spell effects.
|
||||
@@ -190,15 +190,17 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
||||
}
|
||||
} else {
|
||||
// Until next time, force it off.
|
||||
ResetShaderBlending();
|
||||
gstate_c.SetAllowShaderBlend(false);
|
||||
ResetFramebufferRead();
|
||||
gstate_c.SetAllowFramebufferRead(false);
|
||||
}
|
||||
} else if (blendState.resetShaderBlending) {
|
||||
ResetShaderBlending();
|
||||
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
|
||||
} else if (blendState.resetFramebufferRead) {
|
||||
ResetFramebufferRead();
|
||||
}
|
||||
|
||||
if (blendState.enabled) {
|
||||
if (blendState.dirtyShaderBlend) {
|
||||
if (blendState.dirtyShaderBlendFixValues) {
|
||||
// Not quite sure how necessary this is.
|
||||
gstate_c.Dirty(DIRTY_SHADERBLEND);
|
||||
}
|
||||
if (blendState.useBlendColor) {
|
||||
@@ -219,19 +221,6 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
||||
bool gmask = ((gstate.pmskc >> 8) & 0xFF) < 128;
|
||||
bool bmask = ((gstate.pmskc >> 16) & 0xFF) < 128;
|
||||
|
||||
#ifndef MOBILE_DEVICE
|
||||
u8 abits = (gstate.pmska >> 0) & 0xFF;
|
||||
u8 rbits = (gstate.pmskc >> 0) & 0xFF;
|
||||
u8 gbits = (gstate.pmskc >> 8) & 0xFF;
|
||||
u8 bbits = (gstate.pmskc >> 16) & 0xFF;
|
||||
if ((rbits != 0 && rbits != 0xFF) || (gbits != 0 && gbits != 0xFF) || (bbits != 0 && bbits != 0xFF)) {
|
||||
WARN_LOG_REPORT_ONCE(rgbmask, G3D, "Unsupported RGB mask: r=%02x g=%02x b=%02x", rbits, gbits, bbits);
|
||||
}
|
||||
if (abits != 0 && abits != 0xFF) {
|
||||
// The stencil part of the mask is supported.
|
||||
WARN_LOG_REPORT_ONCE(amask, G3D, "Unsupported alpha/stencil mask: %02x", abits);
|
||||
}
|
||||
#endif
|
||||
int mask = (int)rmask | ((int)gmask << 1) | ((int)bmask << 2) | ((int)amask << 3);
|
||||
if (blendState.enabled) {
|
||||
renderManager->SetBlendAndMask(mask, blendState.enabled,
|
||||
|
||||
+4
-4
@@ -540,9 +540,9 @@ struct GPUStateCache {
|
||||
Dirty(DIRTY_TEXCLAMP);
|
||||
}
|
||||
}
|
||||
void SetAllowShaderBlend(bool allow) {
|
||||
if (allowShaderBlend != allow) {
|
||||
allowShaderBlend = allow;
|
||||
void SetAllowFramebufferRead(bool allow) {
|
||||
if (allowFramebufferRead != allow) {
|
||||
allowFramebufferRead = allow;
|
||||
Dirty(DIRTY_FRAGMENTSHADER_STATE);
|
||||
}
|
||||
}
|
||||
@@ -564,7 +564,7 @@ struct GPUStateCache {
|
||||
|
||||
bool bgraTexture;
|
||||
bool needShaderTexClamp;
|
||||
bool allowShaderBlend;
|
||||
bool allowFramebufferRead;
|
||||
|
||||
float morphWeights[8];
|
||||
u32 deferredVertTypeDirty;
|
||||
|
||||
@@ -199,7 +199,7 @@ private:
|
||||
void ApplyDrawStateLate(VulkanRenderManager *renderManager, bool applyStencilRef, uint8_t stencilRef, bool useBlendConstant);
|
||||
void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerVulkan *shaderManager, int prim, VulkanPipelineRasterStateKey &key, VulkanDynamicState &dynState);
|
||||
void BindShaderBlendTex();
|
||||
void ResetShaderBlending();
|
||||
void ResetFramebufferRead();
|
||||
|
||||
void InitDeviceObjects();
|
||||
void DestroyDeviceObjects();
|
||||
|
||||
@@ -122,7 +122,7 @@ static const VkLogicOp logicOps[] = {
|
||||
VK_LOGIC_OP_SET,
|
||||
};
|
||||
|
||||
void DrawEngineVulkan::ResetShaderBlending() {
|
||||
void DrawEngineVulkan::ResetFramebufferRead() {
|
||||
boundSecondary_ = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
|
||||
bool useBufferedRendering = framebufferManager_->UseBufferedRendering();
|
||||
|
||||
if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {
|
||||
gstate_c.SetAllowShaderBlend(!g_Config.bDisableSlowFramebufEffects);
|
||||
gstate_c.SetAllowFramebufferRead(!g_Config.bDisableSlowFramebufEffects);
|
||||
if (gstate.isModeClear()) {
|
||||
key.logicOpEnable = false;
|
||||
key.logicOp = VK_LOGIC_OP_CLEAR;
|
||||
@@ -163,21 +163,21 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
|
||||
|
||||
// Set blend - unless we need to do it in the shader.
|
||||
GenericBlendState blendState;
|
||||
ConvertBlendState(blendState, gstate_c.allowShaderBlend);
|
||||
ConvertBlendState(blendState, gstate_c.allowFramebufferRead);
|
||||
|
||||
if (blendState.applyShaderBlending) {
|
||||
if (ApplyShaderBlending()) {
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState);
|
||||
if (blendState.applyFramebufferRead) {
|
||||
if (ApplyFramebufferRead(&fboTexNeedsBind_)) {
|
||||
// The shader takes over the responsibility for blending, so recompute.
|
||||
ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState);
|
||||
} else {
|
||||
// Until next time, force it off.
|
||||
ResetShaderBlending();
|
||||
gstate_c.SetAllowShaderBlend(false);
|
||||
ResetFramebufferRead();
|
||||
gstate_c.SetAllowFramebufferRead(false);
|
||||
// Make sure we recompute the fragment shader ID to one that doesn't try to use shader blending.
|
||||
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
|
||||
}
|
||||
} else if (blendState.resetShaderBlending) {
|
||||
ResetShaderBlending();
|
||||
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
|
||||
} else if (blendState.resetFramebufferRead) {
|
||||
ResetFramebufferRead();
|
||||
}
|
||||
|
||||
if (blendState.enabled) {
|
||||
@@ -188,7 +188,7 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
|
||||
key.srcAlpha = vkBlendFactorLookup[(size_t)blendState.srcAlpha];
|
||||
key.destColor = vkBlendFactorLookup[(size_t)blendState.dstColor];
|
||||
key.destAlpha = vkBlendFactorLookup[(size_t)blendState.dstAlpha];
|
||||
if (blendState.dirtyShaderBlend) {
|
||||
if (blendState.dirtyShaderBlendFixValues) {
|
||||
gstate_c.Dirty(DIRTY_SHADERBLEND);
|
||||
}
|
||||
dynState.useBlendColor = blendState.useBlendColor;
|
||||
@@ -213,20 +213,6 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
|
||||
bool bmask = ((gstate.pmskc >> 16) & 0xFF) < 128;
|
||||
bool amask = (gstate.pmska & 0xFF) < 128;
|
||||
|
||||
#ifndef MOBILE_DEVICE
|
||||
u8 abits = (gstate.pmska >> 0) & 0xFF;
|
||||
u8 rbits = (gstate.pmskc >> 0) & 0xFF;
|
||||
u8 gbits = (gstate.pmskc >> 8) & 0xFF;
|
||||
u8 bbits = (gstate.pmskc >> 16) & 0xFF;
|
||||
if ((rbits != 0 && rbits != 0xFF) || (gbits != 0 && gbits != 0xFF) || (bbits != 0 && bbits != 0xFF)) {
|
||||
WARN_LOG_REPORT_ONCE(rgbmask, G3D, "Unsupported RGB mask: r=%02x g=%02x b=%02x", rbits, gbits, bbits);
|
||||
}
|
||||
if (abits != 0 && abits != 0xFF) {
|
||||
// The stencil part of the mask is supported.
|
||||
WARN_LOG_REPORT_ONCE(amask, G3D, "Unsupported alpha/stencil mask: %02x", abits);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Let's not write to alpha if stencil isn't enabled.
|
||||
if (IsStencilTestOutputDisabled()) {
|
||||
amask = false;
|
||||
@@ -395,13 +381,13 @@ void DrawEngineVulkan::BindShaderBlendTex() {
|
||||
// TODO: Set the nearest/linear here (since we correctly know if alpha/color tests are needed)?
|
||||
if (!gstate.isModeClear()) {
|
||||
// TODO: Test texture?
|
||||
if (fboTexNeedBind_) {
|
||||
if (fboTexNeedsBind_) {
|
||||
// Note that this is positions, not UVs, that we need the copy from.
|
||||
framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY);
|
||||
// If we are rendering at a higher resolution, linear is probably best for the dest color.
|
||||
boundSecondary_ = (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_TEXTURE1_IMAGEVIEW);
|
||||
fboTexBound_ = true;
|
||||
fboTexNeedBind_ = false;
|
||||
fboTexNeedsBind_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -462,8 +462,8 @@ void RasterizeFonts(const FontReferenceList &fontRefs, vector<CharRange> &ranges
|
||||
} else {
|
||||
dist = -closest.find_closest(ctx, cty, 1);
|
||||
}
|
||||
dist = dist / supersample * distmult + 127.5;
|
||||
dist = floor(dist + 0.5);
|
||||
dist = dist / supersample * distmult + 127.5f;
|
||||
dist = floor(dist + 0.5f);
|
||||
if (dist < 0) dist = 0;
|
||||
if (dist > 255) dist = 255;
|
||||
|
||||
@@ -564,7 +564,7 @@ struct FontDesc {
|
||||
}
|
||||
}
|
||||
|
||||
height = metrics_height / 64.0 / supersample;
|
||||
height = metrics_height / 64.0f / supersample;
|
||||
}
|
||||
|
||||
void OutputSelf(FILE *fil, float tw, float th, const vector<Data> &results) const {
|
||||
@@ -987,7 +987,7 @@ int main(int argc, char **argv) {
|
||||
fwrite(&header, 1, sizeof(header), meta);
|
||||
// For each image
|
||||
for (int i = 0; i < (int)images.size(); i++) {
|
||||
AtlasImage atlas_image = images[i].ToAtlasImage(dest.width(), dest.height(), results);
|
||||
AtlasImage atlas_image = images[i].ToAtlasImage((float)dest.width(), (float)dest.height(), results);
|
||||
fwrite(&atlas_image, 1, sizeof(atlas_image), meta);
|
||||
}
|
||||
// For each font
|
||||
@@ -998,7 +998,7 @@ int main(int argc, char **argv) {
|
||||
fwrite(&font_header, 1, sizeof(font_header), meta);
|
||||
auto ranges = font.GetRanges();
|
||||
fwrite(ranges.data(), sizeof(AtlasCharRange), ranges.size(), meta);
|
||||
auto chars = font.GetChars(dest.width(), dest.height(), results);
|
||||
auto chars = font.GetChars((float)dest.width(), (float)dest.height(), results);
|
||||
fwrite(chars.data(), sizeof(AtlasChar), chars.size(), meta);
|
||||
}
|
||||
fclose(meta);
|
||||
@@ -1010,7 +1010,7 @@ int main(int argc, char **argv) {
|
||||
for (int i = 0; i < (int)fonts.size(); i++) {
|
||||
FontDesc &xfont = fonts[i];
|
||||
xfont.ComputeHeight(results, distmult);
|
||||
xfont.OutputSelf(cpp_file, dest.width(), dest.height(), results);
|
||||
xfont.OutputSelf(cpp_file, (float)dest.width(), (float)dest.height(), results);
|
||||
}
|
||||
|
||||
if (fonts.size()) {
|
||||
@@ -1024,7 +1024,7 @@ int main(int argc, char **argv) {
|
||||
if (images.size()) {
|
||||
fprintf(cpp_file, "const AtlasImage %s_images[%i] = {\n", atlas_name, (int)images.size());
|
||||
for (int i = 0; i < (int)images.size(); i++) {
|
||||
images[i].OutputSelf(cpp_file, dest.width(), dest.height(), results);
|
||||
images[i].OutputSelf(cpp_file, (float)dest.width(), (float)dest.height(), results);
|
||||
}
|
||||
fprintf(cpp_file, "};\n");
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
@@ -90,7 +90,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>../../../../;../../ext;../../;../../../../ext;../prebuilt</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
@@ -108,4 +108,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
Reference in new issue
Block a user