mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-10 06:33:36 +02:00
Merge pull request #6940 from unknownbrackets/blend-logicop
d3d9: Emulate some logic ops with blending
This commit is contained in:
@@ -44,7 +44,7 @@
|
||||
// * Smaller than the audio, sliding with a loop at the end (state STREAMED WITH LOOP AT END = 5)
|
||||
// * Smaller with a second buffer to help with a loop in the middle (state STREAMED WITH SECOND BUF = 6)
|
||||
// * Not managed, decoding using "low level" manual looping etc. (LOW LEVEL = 8)
|
||||
// * Not managed, reseved externally - possibly by sceSas - through low level (RESERVED = 16)
|
||||
// * Not managed, reserved externally - possibly by sceSas - through low level (RESERVED = 16)
|
||||
|
||||
#define ATRAC_ERROR_API_FAIL 0x80630002
|
||||
#define ATRAC_ERROR_NO_ATRACID 0x80630003
|
||||
|
||||
@@ -376,6 +376,33 @@ static bool CanDoubleSrcBlendMode() {
|
||||
}
|
||||
}
|
||||
|
||||
enum LogicOpReplaceType {
|
||||
LOGICOPTYPE_NORMAL,
|
||||
LOGICOPTYPE_ONE,
|
||||
LOGICOPTYPE_INVERT,
|
||||
};
|
||||
|
||||
static inline LogicOpReplaceType ReplaceLogicOpType() {
|
||||
if (gstate.isLogicOpEnabled()) {
|
||||
switch (gstate.getLogicOp()) {
|
||||
case GE_LOGIC_COPY_INVERTED:
|
||||
case GE_LOGIC_AND_INVERTED:
|
||||
case GE_LOGIC_OR_INVERTED:
|
||||
case GE_LOGIC_NOR:
|
||||
case GE_LOGIC_NAND:
|
||||
case GE_LOGIC_EQUIV:
|
||||
return LOGICOPTYPE_INVERT;
|
||||
case GE_LOGIC_INVERTED:
|
||||
return LOGICOPTYPE_ONE;
|
||||
case GE_LOGIC_SET:
|
||||
return LOGICOPTYPE_ONE;
|
||||
default:
|
||||
return LOGICOPTYPE_NORMAL;
|
||||
}
|
||||
}
|
||||
return LOGICOPTYPE_NORMAL;
|
||||
}
|
||||
|
||||
// Here we must take all the bits of the gstate that determine what the fragment shader will
|
||||
// look like, and concatenate them together into an ID.
|
||||
void ComputeFragmentShaderIDDX9(FragmentShaderIDDX9 *id) {
|
||||
@@ -448,7 +475,8 @@ void ComputeFragmentShaderIDDX9(FragmentShaderIDDX9 *id) {
|
||||
gpuStats.numNonAlphaTestedDraws++;
|
||||
|
||||
id0 |= (gstate_c.bgraTexture & 1) << 29;
|
||||
// 30 and 31 are free.
|
||||
// 2 bits.
|
||||
id0 |= ReplaceLogicOpType() << 30;
|
||||
|
||||
// 3 bits.
|
||||
id1 |= replaceBlend << 0;
|
||||
@@ -790,6 +818,17 @@ void GenerateFragmentShaderDX9(char *buffer) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ReplaceLogicOpType()) {
|
||||
case LOGICOPTYPE_ONE:
|
||||
WRITE(p, " v.rgb = float3(1.0, 1.0, 1.0);\n");
|
||||
break;
|
||||
case LOGICOPTYPE_INVERT:
|
||||
WRITE(p, " v.rgb = float3(1.0, 1.0, 1.0) - v.rgb;\n");
|
||||
break;
|
||||
case LOGICOPTYPE_NORMAL:
|
||||
break;
|
||||
}
|
||||
|
||||
WRITE(p, " return v;\n");
|
||||
WRITE(p, "}\n");
|
||||
}
|
||||
|
||||
@@ -162,15 +162,76 @@ inline void TransformDrawEngineDX9::ResetShaderBlending() {
|
||||
}
|
||||
}
|
||||
|
||||
void TransformDrawEngineDX9::ApplyStencilReplaceOnly() {
|
||||
void TransformDrawEngineDX9::ApplyStencilReplaceAndLogicOp(ReplaceAlphaType replaceAlphaWithStencil) {
|
||||
StencilValueType stencilType = STENCIL_VALUE_KEEP;
|
||||
if (replaceAlphaWithStencil == REPLACE_ALPHA_YES) {
|
||||
stencilType = ReplaceAlphaWithStencilType();
|
||||
}
|
||||
|
||||
// Normally, we would add src + 0, but the logic op may have us do differently.
|
||||
D3DBLEND srcBlend = D3DBLEND_ONE;
|
||||
D3DBLEND dstBlend = D3DBLEND_ZERO;
|
||||
D3DBLENDOP blendOp = D3DBLENDOP_ADD;
|
||||
if (gstate.isLogicOpEnabled()) {
|
||||
switch (gstate.getLogicOp())
|
||||
{
|
||||
case GE_LOGIC_CLEAR:
|
||||
srcBlend = D3DBLEND_ZERO;
|
||||
break;
|
||||
case GE_LOGIC_AND:
|
||||
case GE_LOGIC_AND_REVERSE:
|
||||
WARN_LOG_REPORT_ONCE(d3dLogicOpAnd, G3D, "Unsupported AND logic op: %x", gstate.getLogicOp());
|
||||
break;
|
||||
case GE_LOGIC_COPY:
|
||||
// This is the same as off.
|
||||
break;
|
||||
case GE_LOGIC_COPY_INVERTED:
|
||||
// Handled in the shader.
|
||||
break;
|
||||
case GE_LOGIC_AND_INVERTED:
|
||||
case GE_LOGIC_NOR:
|
||||
case GE_LOGIC_NAND:
|
||||
case GE_LOGIC_EQUIV:
|
||||
// Handled in the shader.
|
||||
WARN_LOG_REPORT_ONCE(d3dLogicOpAndInverted, G3D, "Attempted invert for logic op: %x", gstate.getLogicOp());
|
||||
break;
|
||||
case GE_LOGIC_INVERTED:
|
||||
srcBlend = D3DBLEND_ONE;
|
||||
dstBlend = D3DBLEND_ONE;
|
||||
blendOp = D3DBLENDOP_SUBTRACT;
|
||||
WARN_LOG_REPORT_ONCE(d3dLogicOpInverted, G3D, "Attempted inverse for logic op: %x", gstate.getLogicOp());
|
||||
break;
|
||||
case GE_LOGIC_NOOP:
|
||||
srcBlend = D3DBLEND_ZERO;
|
||||
dstBlend = D3DBLEND_ONE;
|
||||
break;
|
||||
case GE_LOGIC_XOR:
|
||||
WARN_LOG_REPORT_ONCE(d3dLogicOpOrXor, G3D, "Unsupported XOR logic op: %x", gstate.getLogicOp());
|
||||
break;
|
||||
case GE_LOGIC_OR:
|
||||
case GE_LOGIC_OR_INVERTED:
|
||||
// Inverted in shader.
|
||||
dstBlend = D3DBLEND_ONE;
|
||||
WARN_LOG_REPORT_ONCE(d3dLogicOpOr, G3D, "Attempted or for logic op: %x", gstate.getLogicOp());
|
||||
break;
|
||||
case GE_LOGIC_OR_REVERSE:
|
||||
WARN_LOG_REPORT_ONCE(d3dLogicOpOrReverse, G3D, "Unsupported OR REVERSE logic op: %x", gstate.getLogicOp());
|
||||
break;
|
||||
case GE_LOGIC_SET:
|
||||
dstBlend = D3DBLEND_ONE;
|
||||
WARN_LOG_REPORT_ONCE(d3dLogicOpSet, G3D, "Attempted set for logic op: %x", gstate.getLogicOp());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We're not blending, but we may still want to blend for stencil.
|
||||
// This is only useful for INCR/DECR/INVERT. Others can write directly.
|
||||
switch (ReplaceAlphaWithStencilType()) {
|
||||
switch (stencilType) {
|
||||
case STENCIL_VALUE_INCR_4:
|
||||
case STENCIL_VALUE_INCR_8:
|
||||
// We'll add the incremented value output by the shader.
|
||||
dxstate.blendFunc.set(D3DBLEND_ONE, D3DBLEND_ZERO, D3DBLEND_ONE, D3DBLEND_ONE);
|
||||
dxstate.blendEquation.set(D3DBLENDOP_ADD, D3DBLENDOP_ADD);
|
||||
dxstate.blendFunc.set(srcBlend, dstBlend, D3DBLEND_ONE, D3DBLEND_ONE);
|
||||
dxstate.blendEquation.set(blendOp, D3DBLENDOP_ADD);
|
||||
dxstate.blend.enable();
|
||||
dxstate.blendSeparate.enable();
|
||||
break;
|
||||
@@ -178,22 +239,29 @@ void TransformDrawEngineDX9::ApplyStencilReplaceOnly() {
|
||||
case STENCIL_VALUE_DECR_4:
|
||||
case STENCIL_VALUE_DECR_8:
|
||||
// We'll subtract the incremented value output by the shader.
|
||||
dxstate.blendFunc.set(D3DBLEND_ONE, D3DBLEND_ZERO, D3DBLEND_ONE, D3DBLEND_ONE);
|
||||
dxstate.blendEquation.set(D3DBLENDOP_ADD, D3DBLENDOP_SUBTRACT);
|
||||
dxstate.blendFunc.set(srcBlend, dstBlend, D3DBLEND_ONE, D3DBLEND_ONE);
|
||||
dxstate.blendEquation.set(blendOp, D3DBLENDOP_SUBTRACT);
|
||||
dxstate.blend.enable();
|
||||
dxstate.blendSeparate.enable();
|
||||
break;
|
||||
|
||||
case STENCIL_VALUE_INVERT:
|
||||
// The shader will output one, and reverse subtracting will essentially invert.
|
||||
dxstate.blendFunc.set(D3DBLEND_ONE, D3DBLEND_ZERO, D3DBLEND_ONE, D3DBLEND_ONE);
|
||||
dxstate.blendEquation.set(D3DBLENDOP_ADD, D3DBLENDOP_REVSUBTRACT);
|
||||
dxstate.blendFunc.set(srcBlend, dstBlend, D3DBLEND_ONE, D3DBLEND_ONE);
|
||||
dxstate.blendEquation.set(blendOp, D3DBLENDOP_REVSUBTRACT);
|
||||
dxstate.blend.enable();
|
||||
dxstate.blendSeparate.enable();
|
||||
break;
|
||||
|
||||
default:
|
||||
dxstate.blend.disable();
|
||||
if (srcBlend == D3DBLEND_ONE && dstBlend == D3DBLEND_ZERO && blendOp == D3DBLENDOP_ADD) {
|
||||
dxstate.blend.disable();
|
||||
} else {
|
||||
dxstate.blendFunc.set(srcBlend, dstBlend, D3DBLEND_ONE, D3DBLEND_ZERO);
|
||||
dxstate.blendEquation.set(blendOp, D3DBLENDOP_ADD);
|
||||
dxstate.blend.enable();
|
||||
dxstate.blendSeparate.enable();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -206,6 +274,7 @@ void TransformDrawEngineDX9::ApplyBlendState() {
|
||||
// These may clip incorrectly, so we avoid unfortunately.
|
||||
// * Direct3D only has one arbitrary fixed color. We premultiply the other in the shader.
|
||||
// * The written output alpha should actually be the stencil value. Alpha is not written.
|
||||
// * We try to apply logical operations through blending.
|
||||
//
|
||||
// If we can't apply blending, we make a copy of the framebuffer and do it manually.
|
||||
|
||||
@@ -220,22 +289,13 @@ void TransformDrawEngineDX9::ApplyBlendState() {
|
||||
case REPLACE_BLEND_NO:
|
||||
ResetShaderBlending();
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
if (replaceAlphaWithStencil == REPLACE_ALPHA_YES) {
|
||||
ApplyStencilReplaceOnly();
|
||||
} else {
|
||||
dxstate.blend.disable();
|
||||
}
|
||||
ApplyStencilReplaceAndLogicOp(replaceAlphaWithStencil);
|
||||
return;
|
||||
|
||||
case REPLACE_BLEND_COPY_FBO:
|
||||
if (ApplyShaderBlending()) {
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
if (replaceAlphaWithStencil == REPLACE_ALPHA_YES) {
|
||||
ApplyStencilReplaceOnly();
|
||||
} else {
|
||||
// None of the below logic is interesting, we're gonna do it entirely in the shader.
|
||||
dxstate.blend.disable();
|
||||
}
|
||||
ApplyStencilReplaceAndLogicOp(replaceAlphaWithStencil);
|
||||
return;
|
||||
}
|
||||
// Until next time, force it off.
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "GPU/Common/IndexGenerator.h"
|
||||
#include "GPU/Common/VertexDecoderCommon.h"
|
||||
#include "GPU/Common/DrawEngineCommon.h"
|
||||
#include "GPU/Directx9/PixelShaderGeneratorDX9.h"
|
||||
|
||||
struct DecVtxFormat;
|
||||
|
||||
@@ -183,7 +184,7 @@ private:
|
||||
void ApplyDrawState(int prim);
|
||||
void ApplyDrawStateLate();
|
||||
void ApplyBlendState();
|
||||
void ApplyStencilReplaceOnly();
|
||||
void ApplyStencilReplaceAndLogicOp(ReplaceAlphaType replaceAlphaWithStencil);
|
||||
bool ApplyShaderBlending();
|
||||
inline void ResetShaderBlending();
|
||||
|
||||
|
||||
@@ -354,6 +354,35 @@ ReplaceBlendType ReplaceBlendWithShader() {
|
||||
}
|
||||
}
|
||||
|
||||
enum LogicOpReplaceType {
|
||||
LOGICOPTYPE_NORMAL,
|
||||
LOGICOPTYPE_ONE,
|
||||
LOGICOPTYPE_INVERT,
|
||||
};
|
||||
|
||||
static inline LogicOpReplaceType ReplaceLogicOpType() {
|
||||
#if defined(USING_GLES2)
|
||||
if (gstate.isLogicOpEnabled()) {
|
||||
switch (gstate.getLogicOp()) {
|
||||
case GE_LOGIC_COPY_INVERTED:
|
||||
case GE_LOGIC_AND_INVERTED:
|
||||
case GE_LOGIC_OR_INVERTED:
|
||||
case GE_LOGIC_NOR:
|
||||
case GE_LOGIC_NAND:
|
||||
case GE_LOGIC_EQUIV:
|
||||
return LOGICOPTYPE_INVERT;
|
||||
case GE_LOGIC_INVERTED:
|
||||
return LOGICOPTYPE_ONE;
|
||||
case GE_LOGIC_SET:
|
||||
return LOGICOPTYPE_ONE;
|
||||
default:
|
||||
return LOGICOPTYPE_NORMAL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return LOGICOPTYPE_NORMAL;
|
||||
}
|
||||
|
||||
// Here we must take all the bits of the gstate that determine what the fragment shader will
|
||||
// look like, and concatenate them together into an ID.
|
||||
void ComputeFragmentShaderID(FragmentShaderID *id) {
|
||||
@@ -425,7 +454,9 @@ void ComputeFragmentShaderID(FragmentShaderID *id) {
|
||||
else
|
||||
gpuStats.numNonAlphaTestedDraws++;
|
||||
|
||||
// 29 - 31 are free.
|
||||
// 29 is free.
|
||||
// 2 bits.
|
||||
id0 |= ReplaceLogicOpType() << 30;
|
||||
|
||||
// 3 bits.
|
||||
id1 |= replaceBlend << 0;
|
||||
@@ -1007,6 +1038,17 @@ void GenerateFragmentShader(char *buffer) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ReplaceLogicOpType()) {
|
||||
case LOGICOPTYPE_ONE:
|
||||
WRITE(p, " %s.rgb = vec3(1.0, 1.0, 1.0);\n", fragColor0);
|
||||
break;
|
||||
case LOGICOPTYPE_INVERT:
|
||||
WRITE(p, " %s.rgb = vec3(1.0, 1.0, 1.0) - %s.rgb;\n", fragColor0, fragColor0);
|
||||
break;
|
||||
case LOGICOPTYPE_NORMAL:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SHADER
|
||||
if (doTexture) {
|
||||
WRITE(p, " %s = texture2D(tex, v_texcoord.xy);\n", fragColor0);
|
||||
|
||||
+80
-20
@@ -208,35 +208,104 @@ inline void TransformDrawEngine::ResetShaderBlending() {
|
||||
}
|
||||
}
|
||||
|
||||
void TransformDrawEngine::ApplyStencilReplaceOnly() {
|
||||
void TransformDrawEngine::ApplyStencilReplaceAndLogicOp(ReplaceAlphaType replaceAlphaWithStencil) {
|
||||
StencilValueType stencilType = STENCIL_VALUE_KEEP;
|
||||
if (replaceAlphaWithStencil == REPLACE_ALPHA_YES) {
|
||||
stencilType = ReplaceAlphaWithStencilType();
|
||||
}
|
||||
|
||||
// Normally, we would add src + 0, but the logic op may have us do differently.
|
||||
GLenum srcBlend = GL_ONE;
|
||||
GLenum dstBlend = GL_ZERO;
|
||||
GLenum blendOp = GL_FUNC_ADD;
|
||||
#if defined(USING_GLES2)
|
||||
if (gstate.isLogicOpEnabled()) {
|
||||
switch (gstate.getLogicOp())
|
||||
{
|
||||
case GE_LOGIC_CLEAR:
|
||||
srcBlend = GL_ZERO;
|
||||
break;
|
||||
case GE_LOGIC_AND:
|
||||
case GE_LOGIC_AND_REVERSE:
|
||||
WARN_LOG_REPORT_ONCE(d3dLogicOpAnd, G3D, "Unsupported AND logic op: %x", gstate.getLogicOp());
|
||||
break;
|
||||
case GE_LOGIC_COPY:
|
||||
// This is the same as off.
|
||||
break;
|
||||
case GE_LOGIC_COPY_INVERTED:
|
||||
// Handled in the shader.
|
||||
break;
|
||||
case GE_LOGIC_AND_INVERTED:
|
||||
case GE_LOGIC_NOR:
|
||||
case GE_LOGIC_NAND:
|
||||
case GE_LOGIC_EQUIV:
|
||||
// Handled in the shader.
|
||||
WARN_LOG_REPORT_ONCE(d3dLogicOpAndInverted, G3D, "Attempted invert for logic op: %x", gstate.getLogicOp());
|
||||
break;
|
||||
case GE_LOGIC_INVERTED:
|
||||
srcBlend = GL_ONE;
|
||||
dstBlend = GL_ONE;
|
||||
blendOp = GL_FUNC_SUBTRACT;
|
||||
WARN_LOG_REPORT_ONCE(d3dLogicOpInverted, G3D, "Attempted inverse for logic op: %x", gstate.getLogicOp());
|
||||
break;
|
||||
case GE_LOGIC_NOOP:
|
||||
srcBlend = GL_ZERO;
|
||||
dstBlend = GL_ONE;
|
||||
break;
|
||||
case GE_LOGIC_XOR:
|
||||
WARN_LOG_REPORT_ONCE(d3dLogicOpOrXor, G3D, "Unsupported XOR logic op: %x", gstate.getLogicOp());
|
||||
break;
|
||||
case GE_LOGIC_OR:
|
||||
case GE_LOGIC_OR_INVERTED:
|
||||
// Inverted in shader.
|
||||
dstBlend = GL_ONE;
|
||||
WARN_LOG_REPORT_ONCE(d3dLogicOpOr, G3D, "Attempted or for logic op: %x", gstate.getLogicOp());
|
||||
break;
|
||||
case GE_LOGIC_OR_REVERSE:
|
||||
WARN_LOG_REPORT_ONCE(d3dLogicOpOrReverse, G3D, "Unsupported OR REVERSE logic op: %x", gstate.getLogicOp());
|
||||
break;
|
||||
case GE_LOGIC_SET:
|
||||
dstBlend = GL_ONE;
|
||||
WARN_LOG_REPORT_ONCE(d3dLogicOpSet, G3D, "Attempted set for logic op: %x", gstate.getLogicOp());
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// We're not blending, but we may still want to blend for stencil.
|
||||
// This is only useful for INCR/DECR/INVERT. Others can write directly.
|
||||
switch (ReplaceAlphaWithStencilType()) {
|
||||
switch (stencilType) {
|
||||
case STENCIL_VALUE_INCR_4:
|
||||
case STENCIL_VALUE_INCR_8:
|
||||
// We'll add the incremented value output by the shader.
|
||||
glstate.blendFuncSeparate.set(GL_ONE, GL_ZERO, GL_ONE, GL_ONE);
|
||||
glstate.blendEquationSeparate.set(GL_FUNC_ADD, GL_FUNC_ADD);
|
||||
glstate.blendFuncSeparate.set(srcBlend, dstBlend, GL_ONE, GL_ONE);
|
||||
glstate.blendEquationSeparate.set(blendOp, GL_FUNC_ADD);
|
||||
glstate.blend.enable();
|
||||
break;
|
||||
|
||||
case STENCIL_VALUE_DECR_4:
|
||||
case STENCIL_VALUE_DECR_8:
|
||||
// We'll subtract the incremented value output by the shader.
|
||||
glstate.blendFuncSeparate.set(GL_ONE, GL_ZERO, GL_ONE, GL_ONE);
|
||||
glstate.blendEquationSeparate.set(GL_FUNC_ADD, GL_FUNC_SUBTRACT);
|
||||
glstate.blendFuncSeparate.set(srcBlend, dstBlend, GL_ONE, GL_ONE);
|
||||
glstate.blendEquationSeparate.set(blendOp, GL_FUNC_SUBTRACT);
|
||||
glstate.blend.enable();
|
||||
break;
|
||||
|
||||
case STENCIL_VALUE_INVERT:
|
||||
// The shader will output one, and reverse subtracting will essentially invert.
|
||||
glstate.blendFuncSeparate.set(GL_ONE, GL_ZERO, GL_ONE, GL_ONE);
|
||||
glstate.blendEquationSeparate.set(GL_FUNC_ADD, GL_FUNC_REVERSE_SUBTRACT);
|
||||
glstate.blendFuncSeparate.set(srcBlend, dstBlend, GL_ONE, GL_ONE);
|
||||
glstate.blendEquationSeparate.set(blendOp, GL_FUNC_REVERSE_SUBTRACT);
|
||||
glstate.blend.enable();
|
||||
break;
|
||||
|
||||
default:
|
||||
glstate.blend.disable();
|
||||
if (srcBlend == GL_ONE && dstBlend == GL_ZERO && blendOp == GL_FUNC_ADD) {
|
||||
glstate.blend.disable();
|
||||
} else {
|
||||
glstate.blendFuncSeparate.set(srcBlend, dstBlend, GL_ONE, GL_ZERO);
|
||||
glstate.blendEquationSeparate.set(blendOp, GL_FUNC_ADD);
|
||||
glstate.blend.enable();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -261,22 +330,13 @@ void TransformDrawEngine::ApplyBlendState() {
|
||||
case REPLACE_BLEND_NO:
|
||||
ResetShaderBlending();
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
if (replaceAlphaWithStencil == REPLACE_ALPHA_YES) {
|
||||
ApplyStencilReplaceOnly();
|
||||
} else {
|
||||
glstate.blend.disable();
|
||||
}
|
||||
ApplyStencilReplaceAndLogicOp(replaceAlphaWithStencil);
|
||||
return;
|
||||
|
||||
case REPLACE_BLEND_COPY_FBO:
|
||||
if (ApplyShaderBlending()) {
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
if (replaceAlphaWithStencil == REPLACE_ALPHA_YES) {
|
||||
ApplyStencilReplaceOnly();
|
||||
} else {
|
||||
// None of the below logic is interesting, we're gonna do it entirely in the shader.
|
||||
glstate.blend.disable();
|
||||
}
|
||||
ApplyStencilReplaceAndLogicOp(replaceAlphaWithStencil);
|
||||
return;
|
||||
}
|
||||
// Until next time, force it off.
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "GPU/Common/IndexGenerator.h"
|
||||
#include "GPU/Common/VertexDecoderCommon.h"
|
||||
#include "GPU/Common/DrawEngineCommon.h"
|
||||
#include "GPU/GLES/FragmentShaderGenerator.h"
|
||||
#include "gfx/gl_common.h"
|
||||
#include "gfx/gl_lost_manager.h"
|
||||
|
||||
@@ -180,7 +181,7 @@ private:
|
||||
void ApplyDrawState(int prim);
|
||||
void ApplyDrawStateLate();
|
||||
void ApplyBlendState();
|
||||
void ApplyStencilReplaceOnly();
|
||||
void ApplyStencilReplaceAndLogicOp(ReplaceAlphaType replaceAlphaWithStencil);
|
||||
bool ApplyShaderBlending();
|
||||
inline void ResetShaderBlending();
|
||||
GLuint AllocateBuffer();
|
||||
|
||||
Reference in New Issue
Block a user