Fix some potential issues when blending on EFB formats without alpha.

Clean up state transition tables.
This commit is contained in:
NeoBrainX 2013-01-13 23:35:07 +01:00
parent 0ebe35e0ef
commit 6870c1fdd5
5 changed files with 378 additions and 400 deletions

View File

@ -456,6 +456,7 @@ void BPWritten(const BPCmd& bp)
case BPMEM_ZCOMPARE: // Set the Z-Compare and EFB pixel format
g_renderer->SetColorMask(); // alpha writing needs to be disabled if the new pixel format doesn't have an alpha channel
g_renderer->SetBlendMode(true);
OnPixelFormatChange();
break;

View File

@ -54,8 +54,6 @@ static int s_fps = 0;
static u32 s_LastAA = 0;
static u32 s_blendMode;
static Television s_television;
ID3D11Buffer* access_efb_cbuf = NULL;
@ -76,151 +74,6 @@ struct
D3D11_RASTERIZER_DESC rastdc;
} gx_state;
// State translation lookup tables
static const D3D11_BLEND d3dSrcFactors[8] =
{
D3D11_BLEND_ZERO,
D3D11_BLEND_ONE,
D3D11_BLEND_DEST_COLOR,
D3D11_BLEND_INV_DEST_COLOR,
D3D11_BLEND_SRC_ALPHA,
D3D11_BLEND_INV_SRC_ALPHA, // NOTE: Use SRC1_ALPHA if dst alpha is enabled!
D3D11_BLEND_DEST_ALPHA,
D3D11_BLEND_INV_DEST_ALPHA
};
static const D3D11_BLEND d3dDestFactors[8] =
{
D3D11_BLEND_ZERO,
D3D11_BLEND_ONE,
D3D11_BLEND_SRC_COLOR,
D3D11_BLEND_INV_SRC_COLOR,
D3D11_BLEND_SRC_ALPHA,
D3D11_BLEND_INV_SRC_ALPHA, // NOTE: Use SRC1_ALPHA if dst alpha is enabled!
D3D11_BLEND_DEST_ALPHA,
D3D11_BLEND_INV_DEST_ALPHA
};
// 0 0x00
// 1 Source & destination
// 2 Source & ~destination
// 3 Source
// 4 ~Source & destination
// 5 Destination
// 6 Source ^ destination = Source & ~destination | ~Source & destination
// 7 Source | destination
// 8 ~(Source | destination)
// 9 ~(Source ^ destination) = ~Source & ~destination | Source & destination
// 10 ~Destination
// 11 Source | ~destination
// 12 ~Source
// 13 ~Source | destination
// 14 ~(Source & destination)
// 15 0xff
static const D3D11_BLEND_OP d3dLogicOps[16] =
{
D3D11_BLEND_OP_ADD,//0
D3D11_BLEND_OP_ADD,//1
D3D11_BLEND_OP_SUBTRACT,//2
D3D11_BLEND_OP_ADD,//3
D3D11_BLEND_OP_REV_SUBTRACT,//4
D3D11_BLEND_OP_ADD,//5
D3D11_BLEND_OP_MAX,//6
D3D11_BLEND_OP_ADD,//7
D3D11_BLEND_OP_MAX,//8
D3D11_BLEND_OP_MAX,//9
D3D11_BLEND_OP_ADD,//10
D3D11_BLEND_OP_ADD,//11
D3D11_BLEND_OP_ADD,//12
D3D11_BLEND_OP_ADD,//13
D3D11_BLEND_OP_ADD,//14
D3D11_BLEND_OP_ADD//15
};
static const D3D11_BLEND d3dLogicOpSrcFactors[16] =
{
D3D11_BLEND_ZERO,//0
D3D11_BLEND_DEST_COLOR,//1
D3D11_BLEND_ONE,//2
D3D11_BLEND_ONE,//3
D3D11_BLEND_DEST_COLOR,//4
D3D11_BLEND_ZERO,//5
D3D11_BLEND_INV_DEST_COLOR,//6
D3D11_BLEND_INV_DEST_COLOR,//7
D3D11_BLEND_INV_SRC_COLOR,//8
D3D11_BLEND_INV_SRC_COLOR,//9
D3D11_BLEND_INV_DEST_COLOR,//10
D3D11_BLEND_ONE,//11
D3D11_BLEND_INV_SRC_COLOR,//12
D3D11_BLEND_INV_SRC_COLOR,//13
D3D11_BLEND_INV_DEST_COLOR,//14
D3D11_BLEND_ONE//15
};
static const D3D11_BLEND d3dLogicOpDestFactors[16] =
{
D3D11_BLEND_ZERO,//0
D3D11_BLEND_ZERO,//1
D3D11_BLEND_INV_SRC_COLOR,//2
D3D11_BLEND_ZERO,//3
D3D11_BLEND_ONE,//4
D3D11_BLEND_ONE,//5
D3D11_BLEND_INV_SRC_COLOR,//6
D3D11_BLEND_ONE,//7
D3D11_BLEND_INV_DEST_COLOR,//8
D3D11_BLEND_SRC_COLOR,//9
D3D11_BLEND_INV_DEST_COLOR,//10
D3D11_BLEND_INV_DEST_COLOR,//11
D3D11_BLEND_INV_SRC_COLOR,//12
D3D11_BLEND_ONE,//13
D3D11_BLEND_INV_SRC_COLOR,//14
D3D11_BLEND_ONE//15
};
static const D3D11_CULL_MODE d3dCullModes[4] =
{
D3D11_CULL_NONE,
D3D11_CULL_BACK,
D3D11_CULL_FRONT,
D3D11_CULL_BACK
};
static const D3D11_COMPARISON_FUNC d3dCmpFuncs[8] =
{
D3D11_COMPARISON_NEVER,
D3D11_COMPARISON_LESS,
D3D11_COMPARISON_EQUAL,
D3D11_COMPARISON_LESS_EQUAL,
D3D11_COMPARISON_GREATER,
D3D11_COMPARISON_NOT_EQUAL,
D3D11_COMPARISON_GREATER_EQUAL,
D3D11_COMPARISON_ALWAYS
};
#define TEXF_NONE 0
#define TEXF_POINT 1
#define TEXF_LINEAR 2
static const unsigned int d3dMipFilters[4] =
{
TEXF_NONE,
TEXF_POINT,
TEXF_LINEAR,
TEXF_NONE, //reserved
};
static const D3D11_TEXTURE_ADDRESS_MODE d3dClamps[4] =
{
D3D11_TEXTURE_ADDRESS_CLAMP,
D3D11_TEXTURE_ADDRESS_WRAP,
D3D11_TEXTURE_ADDRESS_MIRROR,
D3D11_TEXTURE_ADDRESS_WRAP //reserved
};
void SetupDeviceObjects()
{
@ -338,7 +191,6 @@ void CreateScreenshotTexture()
Renderer::Renderer()
{
int x, y, w_temp, h_temp;
s_blendMode = 0;
InitFPSCounter();
@ -833,6 +685,32 @@ void SetBlendOp(D3D11_BLEND_OP val)
void Renderer::SetBlendMode(bool forceUpdate)
{
// Our render target always uses an alpha channel, so we need to override the blend functions to assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel
// Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel is assumed to always be 1.
bool target_has_alpha = bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
const D3D11_BLEND d3dSrcFactors[8] =
{
D3D11_BLEND_ZERO,
D3D11_BLEND_ONE,
D3D11_BLEND_DEST_COLOR,
D3D11_BLEND_INV_DEST_COLOR,
D3D11_BLEND_SRC_ALPHA,
D3D11_BLEND_INV_SRC_ALPHA, // NOTE: Use SRC1_ALPHA if dst alpha is enabled!
(target_has_alpha) ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_ONE,
(target_has_alpha) ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_ZERO
};
const D3D11_BLEND d3dDestFactors[8] =
{
D3D11_BLEND_ZERO,
D3D11_BLEND_ONE,
D3D11_BLEND_SRC_COLOR,
D3D11_BLEND_INV_SRC_COLOR,
D3D11_BLEND_SRC_ALPHA,
D3D11_BLEND_INV_SRC_ALPHA, // NOTE: Use SRC1_ALPHA if dst alpha is enabled!
(target_has_alpha) ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_ONE,
(target_has_alpha) ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_ZERO
};
if (bpmem.blendmode.logicopenable && !forceUpdate)
return;
@ -845,8 +723,8 @@ void Renderer::SetBlendMode(bool forceUpdate)
}
else
{
gx_state.blenddc.RenderTarget[0].BlendEnable = bpmem.blendmode.blendenable && (!( bpmem.blendmode.srcfactor == 1 && bpmem.blendmode.dstfactor == 0));
if (bpmem.blendmode.blendenable && (!( bpmem.blendmode.srcfactor == 1 && bpmem.blendmode.dstfactor == 0)))
gx_state.blenddc.RenderTarget[0].BlendEnable = bpmem.blendmode.blendenable;
if (bpmem.blendmode.blendenable)
{
SetBlendOp(D3D11_BLEND_OP_ADD);
SetSrcBlend(d3dSrcFactors[bpmem.blendmode.srcfactor]);
@ -1331,12 +1209,32 @@ void Renderer::RestoreCull()
void Renderer::SetGenerationMode()
{
const D3D11_CULL_MODE d3dCullModes[4] =
{
D3D11_CULL_NONE,
D3D11_CULL_BACK,
D3D11_CULL_FRONT,
D3D11_CULL_BACK
};
// rastdc.FrontCounterClockwise must be false for this to work
gx_state.rastdc.CullMode = d3dCullModes[bpmem.genMode.cullmode];
}
void Renderer::SetDepthMode()
{
const D3D11_COMPARISON_FUNC d3dCmpFuncs[8] =
{
D3D11_COMPARISON_NEVER,
D3D11_COMPARISON_LESS,
D3D11_COMPARISON_EQUAL,
D3D11_COMPARISON_LESS_EQUAL,
D3D11_COMPARISON_GREATER,
D3D11_COMPARISON_NOT_EQUAL,
D3D11_COMPARISON_GREATER_EQUAL,
D3D11_COMPARISON_ALWAYS
};
if (bpmem.zmode.testenable)
{
gx_state.depthdc.DepthEnable = TRUE;
@ -1353,9 +1251,85 @@ void Renderer::SetDepthMode()
void Renderer::SetLogicOpMode()
{
if (bpmem.blendmode.logicopenable && bpmem.blendmode.logicmode != 3)
// D3D11 doesn't support logic blending, so this is a huge hack
// TODO: Make use of D3D11.1's logic blending support
// 0 0x00
// 1 Source & destination
// 2 Source & ~destination
// 3 Source
// 4 ~Source & destination
// 5 Destination
// 6 Source ^ destination = Source & ~destination | ~Source & destination
// 7 Source | destination
// 8 ~(Source | destination)
// 9 ~(Source ^ destination) = ~Source & ~destination | Source & destination
// 10 ~Destination
// 11 Source | ~destination
// 12 ~Source
// 13 ~Source | destination
// 14 ~(Source & destination)
// 15 0xff
const D3D11_BLEND_OP d3dLogicOps[16] =
{
D3D11_BLEND_OP_ADD,//0
D3D11_BLEND_OP_ADD,//1
D3D11_BLEND_OP_SUBTRACT,//2
D3D11_BLEND_OP_ADD,//3
D3D11_BLEND_OP_REV_SUBTRACT,//4
D3D11_BLEND_OP_ADD,//5
D3D11_BLEND_OP_MAX,//6
D3D11_BLEND_OP_ADD,//7
D3D11_BLEND_OP_MAX,//8
D3D11_BLEND_OP_MAX,//9
D3D11_BLEND_OP_ADD,//10
D3D11_BLEND_OP_ADD,//11
D3D11_BLEND_OP_ADD,//12
D3D11_BLEND_OP_ADD,//13
D3D11_BLEND_OP_ADD,//14
D3D11_BLEND_OP_ADD//15
};
const D3D11_BLEND d3dLogicOpSrcFactors[16] =
{
D3D11_BLEND_ZERO,//0
D3D11_BLEND_DEST_COLOR,//1
D3D11_BLEND_ONE,//2
D3D11_BLEND_ONE,//3
D3D11_BLEND_DEST_COLOR,//4
D3D11_BLEND_ZERO,//5
D3D11_BLEND_INV_DEST_COLOR,//6
D3D11_BLEND_INV_DEST_COLOR,//7
D3D11_BLEND_INV_SRC_COLOR,//8
D3D11_BLEND_INV_SRC_COLOR,//9
D3D11_BLEND_INV_DEST_COLOR,//10
D3D11_BLEND_ONE,//11
D3D11_BLEND_INV_SRC_COLOR,//12
D3D11_BLEND_INV_SRC_COLOR,//13
D3D11_BLEND_INV_DEST_COLOR,//14
D3D11_BLEND_ONE//15
};
const D3D11_BLEND d3dLogicOpDestFactors[16] =
{
D3D11_BLEND_ZERO,//0
D3D11_BLEND_ZERO,//1
D3D11_BLEND_INV_SRC_COLOR,//2
D3D11_BLEND_ZERO,//3
D3D11_BLEND_ONE,//4
D3D11_BLEND_ONE,//5
D3D11_BLEND_INV_SRC_COLOR,//6
D3D11_BLEND_ONE,//7
D3D11_BLEND_INV_DEST_COLOR,//8
D3D11_BLEND_SRC_COLOR,//9
D3D11_BLEND_INV_DEST_COLOR,//10
D3D11_BLEND_INV_DEST_COLOR,//11
D3D11_BLEND_INV_SRC_COLOR,//12
D3D11_BLEND_ONE,//13
D3D11_BLEND_INV_SRC_COLOR,//14
D3D11_BLEND_ONE//15
};
if (bpmem.blendmode.logicopenable)
{
s_blendMode = 0;
gx_state.blenddc.RenderTarget[0].BlendEnable = true;
SetBlendOp(d3dLogicOps[bpmem.blendmode.logicmode]);
SetSrcBlend(d3dLogicOpSrcFactors[bpmem.blendmode.logicmode]);
@ -1379,18 +1353,32 @@ void Renderer::SetLineWidth()
void Renderer::SetSamplerState(int stage, int texindex)
{
#define TEXF_NONE 0
#define TEXF_POINT 1
#define TEXF_LINEAR 2
const unsigned int d3dMipFilters[4] =
{
TEXF_NONE,
TEXF_POINT,
TEXF_LINEAR,
TEXF_NONE, //reserved
};
const D3D11_TEXTURE_ADDRESS_MODE d3dClamps[4] =
{
D3D11_TEXTURE_ADDRESS_CLAMP,
D3D11_TEXTURE_ADDRESS_WRAP,
D3D11_TEXTURE_ADDRESS_MIRROR,
D3D11_TEXTURE_ADDRESS_WRAP //reserved
};
const FourTexUnits &tex = bpmem.tex[texindex];
const TexMode0 &tm0 = tex.texMode0[stage];
const TexMode1 &tm1 = tex.texMode1[stage];
unsigned int mip;
mip = (tm0.min_filter == 8) ? TEXF_NONE:d3dMipFilters[tm0.min_filter & 3];
if ((tm0.min_filter & 3) && (tm0.min_filter != 8) && ((tm1.max_lod >> 4) == 0)) mip = TEXF_NONE;
unsigned int mip = d3dMipFilters[tm0.min_filter & 3];
if (texindex) stage += 4;
// TODO: Clarify whether these values are correct
// NOTE: since there's no "no filter" in DX11 we're using point filters in these cases
if (g_ActiveConfig.bForceFiltering)
{
gx_state.sampdc[stage].Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;

View File

@ -73,148 +73,6 @@ static char *st;
static LPDIRECT3DSURFACE9 ScreenShootMEMSurface = NULL;
// State translation lookup tables
static const D3DBLEND d3dSrcFactors[8] =
{
D3DBLEND_ZERO,
D3DBLEND_ONE,
D3DBLEND_DESTCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_SRCALPHA,
D3DBLEND_INVSRCALPHA,
D3DBLEND_DESTALPHA,
D3DBLEND_INVDESTALPHA
};
static const D3DBLEND d3dDestFactors[8] =
{
D3DBLEND_ZERO,
D3DBLEND_ONE,
D3DBLEND_SRCCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_SRCALPHA,
D3DBLEND_INVSRCALPHA,
D3DBLEND_DESTALPHA,
D3DBLEND_INVDESTALPHA
};
// 0 0x00
// 1 Source & destination
// 2 Source & ~destination
// 3 Source
// 4 ~Source & destination
// 5 Destination
// 6 Source ^ destination = Source & ~destination | ~Source & destination
// 7 Source | destination
// 8 ~(Source | destination)
// 9 ~(Source ^ destination) = ~Source & ~destination | Source & destination
// 10 ~Destination
// 11 Source | ~destination
// 12 ~Source
// 13 ~Source | destination
// 14 ~(Source & destination)
// 15 0xff
static const D3DBLENDOP d3dLogicOpop[16] =
{
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_SUBTRACT,
D3DBLENDOP_ADD,
D3DBLENDOP_REVSUBTRACT,
D3DBLENDOP_ADD,
D3DBLENDOP_MAX,
D3DBLENDOP_ADD,
D3DBLENDOP_MAX,
D3DBLENDOP_MAX,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD
};
static const D3DBLEND d3dLogicOpSrcFactors[16] =
{
D3DBLEND_ZERO,
D3DBLEND_DESTCOLOR,
D3DBLEND_ONE,
D3DBLEND_ONE,
D3DBLEND_DESTCOLOR,
D3DBLEND_ZERO,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_ONE,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_ONE
};
static const D3DBLEND d3dLogicOpDestFactors[16] =
{
D3DBLEND_ZERO,
D3DBLEND_ZERO,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_ZERO,
D3DBLEND_ONE,
D3DBLEND_ONE,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_ONE,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_SRCCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_ONE,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_ONE
};
static const D3DCULL d3dCullModes[4] =
{
D3DCULL_NONE,
D3DCULL_CCW,
D3DCULL_CW,
D3DCULL_CCW
};
static const D3DCMPFUNC d3dCmpFuncs[8] =
{
D3DCMP_NEVER,
D3DCMP_LESS,
D3DCMP_EQUAL,
D3DCMP_LESSEQUAL,
D3DCMP_GREATER,
D3DCMP_NOTEQUAL,
D3DCMP_GREATEREQUAL,
D3DCMP_ALWAYS
};
static const D3DTEXTUREFILTERTYPE d3dMipFilters[4] =
{
D3DTEXF_NONE,
D3DTEXF_POINT,
D3DTEXF_LINEAR,
D3DTEXF_NONE, //reserved
};
static const D3DTEXTUREADDRESS d3dClamps[4] =
{
D3DTADDRESS_CLAMP,
D3DTADDRESS_WRAP,
D3DTADDRESS_MIRROR,
D3DTADDRESS_WRAP //reserved
};
void SetupDeviceObjects()
{
D3D::font.Init();
@ -796,6 +654,32 @@ void Renderer::ReinterpretPixelData(unsigned int convtype)
void Renderer::SetBlendMode(bool forceUpdate)
{
// Our render target always uses an alpha channel, so we need to override the blend functions to assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel
// Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel is assumed to always be 1.
bool target_has_alpha = bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
const D3DBLEND d3dSrcFactors[8] =
{
D3DBLEND_ZERO,
D3DBLEND_ONE,
D3DBLEND_DESTCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_SRCALPHA,
D3DBLEND_INVSRCALPHA,
(target_has_alpha) ? D3DBLEND_DESTALPHA : D3DBLEND_ONE,
(target_has_alpha) ? D3DBLEND_INVDESTALPHA : D3DBLEND_ZERO
};
const D3DBLEND d3dDestFactors[8] =
{
D3DBLEND_ZERO,
D3DBLEND_ONE,
D3DBLEND_SRCCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_SRCALPHA,
D3DBLEND_INVSRCALPHA,
(target_has_alpha) ? D3DBLEND_DESTALPHA : D3DBLEND_ONE,
(target_has_alpha) ? D3DBLEND_INVDESTALPHA : D3DBLEND_ZERO
};
if (bpmem.blendmode.logicopenable && !forceUpdate)
return;
@ -808,8 +692,8 @@ void Renderer::SetBlendMode(bool forceUpdate)
}
else
{
D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, bpmem.blendmode.blendenable && (!( bpmem.blendmode.srcfactor == 1 && bpmem.blendmode.dstfactor == 0)));
if (bpmem.blendmode.blendenable && (!( bpmem.blendmode.srcfactor == 1 && bpmem.blendmode.dstfactor == 0)))
D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, bpmem.blendmode.blendenable);
if (bpmem.blendmode.blendenable)
{
D3D::SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
D3D::SetRenderState(D3DRS_SRCBLEND, d3dSrcFactors[bpmem.blendmode.srcfactor]);
@ -1261,11 +1145,31 @@ void Renderer::RestoreAPIState()
void Renderer::SetGenerationMode()
{
const D3DCULL d3dCullModes[4] =
{
D3DCULL_NONE,
D3DCULL_CCW,
D3DCULL_CW,
D3DCULL_CCW
};
D3D::SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]);
}
void Renderer::SetDepthMode()
{
const D3DCMPFUNC d3dCmpFuncs[8] =
{
D3DCMP_NEVER,
D3DCMP_LESS,
D3DCMP_EQUAL,
D3DCMP_LESSEQUAL,
D3DCMP_GREATER,
D3DCMP_NOTEQUAL,
D3DCMP_GREATEREQUAL,
D3DCMP_ALWAYS
};
if (bpmem.zmode.testenable)
{
D3D::SetRenderState(D3DRS_ZENABLE, TRUE);
@ -1282,7 +1186,83 @@ void Renderer::SetDepthMode()
void Renderer::SetLogicOpMode()
{
if (bpmem.blendmode.logicopenable && bpmem.blendmode.logicmode != 3)
// D3D9 doesn't support logic blending, so this is a huge hack
// 0 0x00
// 1 Source & destination
// 2 Source & ~destination
// 3 Source
// 4 ~Source & destination
// 5 Destination
// 6 Source ^ destination = Source & ~destination | ~Source & destination
// 7 Source | destination
// 8 ~(Source | destination)
// 9 ~(Source ^ destination) = ~Source & ~destination | Source & destination
// 10 ~Destination
// 11 Source | ~destination
// 12 ~Source
// 13 ~Source | destination
// 14 ~(Source & destination)
// 15 0xff
const D3DBLENDOP d3dLogicOpop[16] =
{
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_SUBTRACT,
D3DBLENDOP_ADD,
D3DBLENDOP_REVSUBTRACT,
D3DBLENDOP_ADD,
D3DBLENDOP_MAX,
D3DBLENDOP_ADD,
D3DBLENDOP_MAX,
D3DBLENDOP_MAX,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD,
D3DBLENDOP_ADD
};
const D3DBLEND d3dLogicOpSrcFactors[16] =
{
D3DBLEND_ZERO,
D3DBLEND_DESTCOLOR,
D3DBLEND_ONE,
D3DBLEND_ONE,
D3DBLEND_DESTCOLOR,
D3DBLEND_ZERO,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_ONE,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_ONE
};
const D3DBLEND d3dLogicOpDestFactors[16] =
{
D3DBLEND_ZERO,
D3DBLEND_ZERO,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_ZERO,
D3DBLEND_ONE,
D3DBLEND_ONE,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_ONE,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_SRCCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_INVDESTCOLOR,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_ONE,
D3DBLEND_INVSRCCOLOR,
D3DBLEND_ONE
};
if (bpmem.blendmode.logicopenable)
{
D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, true);
D3D::SetRenderState(D3DRS_BLENDOP, d3dLogicOpop[bpmem.blendmode.logicmode]);
@ -1310,6 +1290,21 @@ void Renderer::SetLineWidth()
void Renderer::SetSamplerState(int stage, int texindex)
{
const D3DTEXTUREFILTERTYPE d3dMipFilters[4] =
{
D3DTEXF_NONE,
D3DTEXF_POINT,
D3DTEXF_LINEAR,
D3DTEXF_NONE, //reserved
};
const D3DTEXTUREADDRESS d3dClamps[4] =
{
D3DTADDRESS_CLAMP,
D3DTADDRESS_WRAP,
D3DTADDRESS_MIRROR,
D3DTADDRESS_WRAP //reserved
};
const FourTexUnits &tex = bpmem.tex[texindex];
const TexMode0 &tm0 = tex.texMode0[stage];
const TexMode1 &tm1 = tex.texMode1[stage];
@ -1323,13 +1318,11 @@ void Renderer::SetSamplerState(int stage, int texindex)
{
min = (tm0.min_filter & 4) ? D3DTEXF_LINEAR : D3DTEXF_POINT;
mag = tm0.mag_filter ? D3DTEXF_LINEAR : D3DTEXF_POINT;
mip = (tm0.min_filter == 8) ? D3DTEXF_NONE : d3dMipFilters[tm0.min_filter & 3];
if((tm0.min_filter & 3) && (tm0.min_filter != 8) && ((tm1.max_lod >> 4) == 0))
mip = D3DTEXF_NONE;
mip = d3dMipFilters[tm0.min_filter & 3];
}
if (texindex)
stage += 4;
if (mag == D3DTEXF_LINEAR && min == D3DTEXF_LINEAR && g_ActiveConfig.iMaxAnisotropy)
{
min = D3DTEXF_ANISOTROPIC;
@ -1340,8 +1333,7 @@ void Renderer::SetSamplerState(int stage, int texindex)
D3D::SetSamplerState(stage, D3DSAMP_ADDRESSU, d3dClamps[tm0.wrap_s]);
D3D::SetSamplerState(stage, D3DSAMP_ADDRESSV, d3dClamps[tm0.wrap_t]);
//float SuperSampleCoeficient = (s_LastAA < 3)? s_LastAA + 1 : s_LastAA - 1;// uncoment this changes to conserve detail when incresing ssaa level
float lodbias = (tm0.lod_bias / 32.0f);// + (s_LastAA)?(log(SuperSampleCoeficient) / log(2.0f)):0;
float lodbias = tm0.lod_bias / 32.0f;
D3D::SetSamplerState(stage, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&lodbias);
D3D::SetSamplerState(stage, D3DSAMP_MAXMIPLEVEL, tm1.min_lod >> 4);
}

View File

@ -132,58 +132,6 @@ const u32 EFB_CACHE_HEIGHT = (EFB_HEIGHT + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_
static bool s_efbCacheValid[2][EFB_CACHE_WIDTH * EFB_CACHE_HEIGHT];
static std::vector<u32> s_efbCache[2][EFB_CACHE_WIDTH * EFB_CACHE_HEIGHT]; // 2 for PEEK_Z and PEEK_COLOR
static const GLenum glSrcFactors[8] =
{
GL_ZERO,
GL_ONE,
GL_DST_COLOR,
GL_ONE_MINUS_DST_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA, // NOTE: If dual-source blending is enabled, use SRC1_ALPHA
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA
};
static const GLenum glDestFactors[8] = {
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,
GL_ONE_MINUS_SRC_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA, // NOTE: If dual-source blending is enabled, use SRC1_ALPHA
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA
};
static const GLenum glCmpFuncs[8] = {
GL_NEVER,
GL_LESS,
GL_EQUAL,
GL_LEQUAL,
GL_GREATER,
GL_NOTEQUAL,
GL_GEQUAL,
GL_ALWAYS
};
static const GLenum glLogicOpCodes[16] = {
GL_CLEAR,
GL_AND,
GL_AND_REVERSE,
GL_COPY,
GL_AND_INVERTED,
GL_NOOP,
GL_XOR,
GL_OR,
GL_NOR,
GL_EQUIV,
GL_INVERT,
GL_OR_REVERSE,
GL_COPY_INVERTED,
GL_OR_INVERTED,
GL_NAND,
GL_SET
};
#if defined HAVE_CG && HAVE_CG
void HandleCgError(CGcontext ctx, CGerror err, void* appdata)
@ -908,6 +856,32 @@ void Renderer::ReinterpretPixelData(unsigned int convtype)
void Renderer::SetBlendMode(bool forceUpdate)
{
// Our render target always uses an alpha channel, so we need to override the blend functions to assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel
// Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel is assumed to always be 1.
bool target_has_alpha = bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
const GLenum glSrcFactors[8] =
{
GL_ZERO,
GL_ONE,
GL_DST_COLOR,
GL_ONE_MINUS_DST_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA, // NOTE: If dual-source blending is enabled, use SRC1_ALPHA
(target_has_alpha) ? GL_DST_ALPHA : (GLenum)GL_ONE,
(target_has_alpha) ? GL_ONE_MINUS_DST_ALPHA : (GLenum)GL_ZERO
};
const GLenum glDestFactors[8] =
{
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,
GL_ONE_MINUS_SRC_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA, // NOTE: If dual-source blending is enabled, use SRC1_ALPHA
(target_has_alpha) ? GL_DST_ALPHA : (GLenum)GL_ONE,
(target_has_alpha) ? GL_ONE_MINUS_DST_ALPHA : (GLenum)GL_ZERO
};
// blend mode bit mask
// 0 - blend enable
// 2 - reverse subtract enable (else add)
@ -951,10 +925,10 @@ void Renderer::SetBlendMode(bool forceUpdate)
if (changes & 0x1F8)
{
#ifdef USE_DUAL_SOURCE_BLEND
GLenum srcFactor = glSrcFactors[(newval >> 3) & 7];
GLenum srcFactorAlpha = srcFactor;
GLenum dstFactor = glDestFactors[(newval >> 6) & 7];
#ifdef USE_DUAL_SOURCE_BLEND
GLenum srcFactorAlpha = srcFactor;
GLenum dstFactorAlpha = dstFactor;
if (useDualSource)
{
@ -975,7 +949,7 @@ void Renderer::SetBlendMode(bool forceUpdate)
// blend RGB change
glBlendFuncSeparate(srcFactor, dstFactor, srcFactorAlpha, dstFactorAlpha);
#else
glBlendFunc(glSrcFactors[(newval >> 3) & 7], glDestFactors[(newval >> 6) & 7]);
glBlendFunc(srcFactor, dstFactor);
#endif
}
@ -1438,6 +1412,18 @@ void Renderer::SetGenerationMode()
void Renderer::SetDepthMode()
{
const GLenum glCmpFuncs[8] =
{
GL_NEVER,
GL_LESS,
GL_EQUAL,
GL_LEQUAL,
GL_GREATER,
GL_NOTEQUAL,
GL_GEQUAL,
GL_ALWAYS
};
if (bpmem.zmode.testenable)
{
glEnable(GL_DEPTH_TEST);
@ -1454,7 +1440,27 @@ void Renderer::SetDepthMode()
void Renderer::SetLogicOpMode()
{
if (bpmem.blendmode.logicopenable && bpmem.blendmode.logicmode != 3)
const GLenum glLogicOpCodes[16] =
{
GL_CLEAR,
GL_AND,
GL_AND_REVERSE,
GL_COPY,
GL_AND_INVERTED,
GL_NOOP,
GL_XOR,
GL_OR,
GL_NOR,
GL_EQUIV,
GL_INVERT,
GL_OR_REVERSE,
GL_COPY_INVERTED,
GL_OR_INVERTED,
GL_NAND,
GL_SET
};
if (bpmem.blendmode.logicopenable)
{
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp(glLogicOpCodes[bpmem.blendmode.logicmode]);

View File

@ -58,24 +58,6 @@ namespace OGL
static u32 s_TempFramebuffer = 0;
static const GLint c_MinLinearFilter[8] = {
GL_NEAREST,
GL_NEAREST_MIPMAP_NEAREST,
GL_NEAREST_MIPMAP_LINEAR,
GL_NEAREST,
GL_LINEAR,
GL_LINEAR_MIPMAP_NEAREST,
GL_LINEAR_MIPMAP_LINEAR,
GL_LINEAR,
};
static const GLint c_WrapSettings[4] = {
GL_CLAMP_TO_EDGE,
GL_REPEAT,
GL_MIRRORED_REPEAT,
GL_REPEAT,
};
bool SaveTexture(const char* filename, u32 textarget, u32 tex, int virtual_width, int virtual_height, unsigned int level)
{
int width = std::max(virtual_width >> level, 1);
@ -357,32 +339,41 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
void TextureCache::TCacheEntry::SetTextureParameters(const TexMode0 &newmode, const TexMode1 &newmode1)
{
// TODO: not used anywhere
TexMode0 mode = newmode;
//mode1 = newmode1;
const GLint c_MinLinearFilter[8] =
{
GL_NEAREST,
GL_NEAREST_MIPMAP_NEAREST,
GL_NEAREST_MIPMAP_LINEAR,
GL_NEAREST,
GL_LINEAR,
GL_LINEAR_MIPMAP_NEAREST,
GL_LINEAR_MIPMAP_LINEAR,
GL_LINEAR,
};
const GLint c_WrapSettings[4] =
{
GL_CLAMP_TO_EDGE,
GL_REPEAT,
GL_MIRRORED_REPEAT,
GL_REPEAT,
};
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
(newmode.mag_filter || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST);
(newmode.mag_filter || g_Config.bForceFiltering) ? GL_LINEAR : GL_NEAREST);
if (bHaveMipMaps)
{
// TODO: not used anywhere
if (g_ActiveConfig.bForceFiltering && newmode.min_filter < 4)
mode.min_filter += 4; // take equivalent forced linear
int filt = newmode.min_filter;
if (g_ActiveConfig.bForceFiltering && filt < 4)
filt += 4; // take equivalent forced linear
int filt = newmode.min_filter;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c_MinLinearFilter[filt & 7]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, newmode1.min_lod >> 4);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, newmode1.max_lod >> 4);
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, (newmode.lod_bias / 32.0f));
}
else
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
(g_ActiveConfig.bForceFiltering || newmode.min_filter >= 4) ? GL_LINEAR : GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c_MinLinearFilter[filt]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, newmode1.min_lod / 16.f);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, newmode1.max_lod / 16.f);
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, newmode.lod_bias / 32.0f);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, c_WrapSettings[newmode.wrap_s]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, c_WrapSettings[newmode.wrap_t]);
// TODO: Reset anisotrop when changed to 1
if (g_Config.iMaxAnisotropy >= 1)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
(float)(1 << g_ActiveConfig.iMaxAnisotropy));