mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-30 01:29:42 -06:00
Put infrastructure in place so that other plugins may support dual-source blending.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6296 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -254,37 +254,73 @@ void EmuGfxState::SetRenderTargetWriteMask(UINT8 mask)
|
||||
void EmuGfxState::SetSrcBlend(D3D11_BLEND val)
|
||||
{
|
||||
// TODO: Check whether e.g. the dest color check is needed here
|
||||
blenddesc.RenderTarget[0].SrcBlend = val;
|
||||
if (m_useDstAlpha)
|
||||
{
|
||||
// Colors should blend against SRC1_ALPHA
|
||||
if (val == D3D11_BLEND_SRC_ALPHA)
|
||||
val = D3D11_BLEND_SRC1_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_SRC_ALPHA)
|
||||
val = D3D11_BLEND_INV_SRC1_ALPHA;
|
||||
|
||||
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (val == D3D11_BLEND_SRC_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_SRC_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
else if (val == D3D11_BLEND_DEST_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_DEST_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_DEST_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
|
||||
else blenddesc.RenderTarget[0].SrcBlendAlpha = val;
|
||||
// Colors should blend against SRC_ALPHA
|
||||
if (val == D3D11_BLEND_SRC1_ALPHA)
|
||||
val = D3D11_BLEND_SRC_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_SRC1_ALPHA)
|
||||
val = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
|
||||
if (val == D3D11_BLEND_SRC_COLOR)
|
||||
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_SRC_COLOR)
|
||||
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
else if (val == D3D11_BLEND_DEST_COLOR)
|
||||
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_DEST_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_DEST_COLOR)
|
||||
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
|
||||
else
|
||||
blenddesc.RenderTarget[0].SrcBlendAlpha = val;
|
||||
}
|
||||
|
||||
blenddesc.RenderTarget[0].SrcBlend = val;
|
||||
}
|
||||
|
||||
void EmuGfxState::SetDestBlend(D3D11_BLEND val)
|
||||
{
|
||||
// TODO: Check whether e.g. the source color check is needed here
|
||||
blenddesc.RenderTarget[0].DestBlend = val;
|
||||
if (m_useDstAlpha)
|
||||
{
|
||||
// Colors should blend against SRC1_ALPHA
|
||||
if (val == D3D11_BLEND_SRC_ALPHA)
|
||||
val = D3D11_BLEND_SRC1_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_SRC_ALPHA)
|
||||
val = D3D11_BLEND_INV_SRC1_ALPHA;
|
||||
|
||||
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (val == D3D11_BLEND_SRC_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_SRC_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
else if (val == D3D11_BLEND_DEST_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_DEST_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
|
||||
else blenddesc.RenderTarget[0].DestBlendAlpha = val;
|
||||
// Colors should blend against SRC_ALPHA
|
||||
if (val == D3D11_BLEND_SRC1_ALPHA)
|
||||
val = D3D11_BLEND_SRC_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_SRC1_ALPHA)
|
||||
val = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
|
||||
if (val == D3D11_BLEND_SRC_COLOR)
|
||||
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_SRC_COLOR)
|
||||
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
else if (val == D3D11_BLEND_DEST_COLOR)
|
||||
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_DEST_COLOR)
|
||||
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
|
||||
else
|
||||
blenddesc.RenderTarget[0].DestBlendAlpha = val;
|
||||
}
|
||||
|
||||
blenddesc.RenderTarget[0].DestBlend = val;
|
||||
}
|
||||
|
||||
void EmuGfxState::SetBlendOp(D3D11_BLEND_OP val)
|
||||
|
@ -228,10 +228,10 @@ void PixelShaderCache::Shutdown()
|
||||
g_ps_disk_cache.Close();
|
||||
}
|
||||
|
||||
bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||
bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
|
||||
{
|
||||
PIXELSHADERUID uid;
|
||||
GetPixelShaderId(&uid, dstAlpha);
|
||||
GetPixelShaderId(&uid, dstAlphaMode);
|
||||
|
||||
// Check if the shader is already set
|
||||
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
||||
@ -256,7 +256,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||
}
|
||||
|
||||
// Need to compile a new shader
|
||||
const char* code = GeneratePixelShaderCode(dstAlpha, API_D3D11,components);
|
||||
const char* code = GeneratePixelShaderCode(dstAlphaMode, API_D3D11, components);
|
||||
|
||||
D3DBlob* pbytecode;
|
||||
if (!D3D::CompilePixelShader(code, strlen(code), &pbytecode))
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
static void Init();
|
||||
static void Clear();
|
||||
static void Shutdown();
|
||||
static bool SetShader(bool dstAlpha,u32 components);
|
||||
static bool SetShader(DSTALPHA_MODE dstAlphaMode, u32 components);
|
||||
static bool InsertByteCode(const PIXELSHADERUID &uid, void* bytecode, unsigned int bytecodelen);
|
||||
|
||||
static ID3D11PixelShader* GetColorMatrixProgram();
|
||||
|
@ -90,8 +90,8 @@ static const D3D11_BLEND d3dSrcFactors[8] =
|
||||
D3D11_BLEND_ONE,
|
||||
D3D11_BLEND_DEST_COLOR,
|
||||
D3D11_BLEND_INV_DEST_COLOR,
|
||||
D3D11_BLEND_SRC1_ALPHA,
|
||||
D3D11_BLEND_INV_SRC1_ALPHA, // Use dual-source color blending for dst alpha
|
||||
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
|
||||
};
|
||||
@ -102,8 +102,8 @@ static const D3D11_BLEND d3dDestFactors[8] =
|
||||
D3D11_BLEND_ONE,
|
||||
D3D11_BLEND_SRC_COLOR,
|
||||
D3D11_BLEND_INV_SRC_COLOR,
|
||||
D3D11_BLEND_SRC1_ALPHA,
|
||||
D3D11_BLEND_INV_SRC1_ALPHA, // Use dual-source color blending for dst alpha
|
||||
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
|
||||
};
|
||||
|
@ -223,7 +223,9 @@ void VertexManager::vFlush()
|
||||
|
||||
D3D::gfxstate->SetDstAlpha(useDstAlpha);
|
||||
|
||||
if (!PixelShaderCache::SetShader(useDstAlpha,g_nativeVertexFmt->m_components))
|
||||
if (!PixelShaderCache::SetShader(
|
||||
useDstAlpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE,
|
||||
g_nativeVertexFmt->m_components))
|
||||
goto shader_fail;
|
||||
if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components))
|
||||
goto shader_fail;
|
||||
|
@ -273,10 +273,10 @@ void PixelShaderCache::Shutdown()
|
||||
unique_shaders.clear();
|
||||
}
|
||||
|
||||
bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||
bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
|
||||
{
|
||||
PIXELSHADERUID uid;
|
||||
GetPixelShaderId(&uid, dstAlpha ? 1 : 0);
|
||||
GetPixelShaderId(&uid, dstAlphaMode);
|
||||
|
||||
// Check if the shader is already set
|
||||
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
||||
@ -308,7 +308,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||
}
|
||||
|
||||
// Need to compile a new shader
|
||||
const char *code = GeneratePixelShaderCode(dstAlpha, API_D3D9,components);
|
||||
const char *code = GeneratePixelShaderCode(dstAlphaMode, API_D3D9, components);
|
||||
|
||||
u32 code_hash = HashAdler32((const u8 *)code, strlen(code));
|
||||
unique_shaders.insert(code_hash);
|
||||
|
@ -60,7 +60,7 @@ private:
|
||||
public:
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
static bool SetShader(bool dstAlpha, u32 componets);
|
||||
static bool SetShader(DSTALPHA_MODE dstAlphaMode, u32 componets);
|
||||
static bool InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate);
|
||||
static LPDIRECT3DPIXELSHADER9 GetColorMatrixProgram(int SSAAMode);
|
||||
static LPDIRECT3DPIXELSHADER9 GetColorCopyProgram(int SSAAMode);
|
||||
|
@ -155,7 +155,7 @@ void VertexManager::vFlush()
|
||||
VertexShaderManager::SetConstants();
|
||||
PixelShaderManager::SetConstants();
|
||||
|
||||
if (!PixelShaderCache::SetShader(false,g_nativeVertexFmt->m_components))
|
||||
if (!PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components))
|
||||
{
|
||||
DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
|
||||
goto shader_fail;
|
||||
@ -175,7 +175,7 @@ void VertexManager::vFlush()
|
||||
if (bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate)
|
||||
{
|
||||
DWORD write = 0;
|
||||
if (!PixelShaderCache::SetShader(true, g_nativeVertexFmt->m_components))
|
||||
if (!PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS, g_nativeVertexFmt->m_components))
|
||||
{
|
||||
DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
|
||||
goto shader_fail;
|
||||
|
@ -184,11 +184,11 @@ void PixelShaderCache::Shutdown()
|
||||
PixelShaders.clear();
|
||||
}
|
||||
|
||||
FRAGMENTSHADER* PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||
FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
|
||||
{
|
||||
DVSTARTPROFILE();
|
||||
PIXELSHADERUID uid;
|
||||
GetPixelShaderId(&uid, dstAlpha ? 1 : 0);
|
||||
GetPixelShaderId(&uid, dstAlphaMode);
|
||||
|
||||
// Check if the shader is already set
|
||||
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
||||
@ -216,7 +216,7 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||
PSCacheEntry& newentry = PixelShaders[uid];
|
||||
newentry.frameCount = frameCount;
|
||||
pShaderLast = &newentry.shader;
|
||||
const char *code = GeneratePixelShaderCode(dstAlpha,API_OPENGL,components);
|
||||
const char *code = GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components);
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
|
||||
|
@ -71,7 +71,7 @@ public:
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
|
||||
static FRAGMENTSHADER* SetShader(bool dstAlphaEnable,u32 components);
|
||||
static FRAGMENTSHADER* SetShader(DSTALPHA_MODE dstAlphaMode, u32 components);
|
||||
static bool CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram);
|
||||
|
||||
static GLuint GetColorMatrixProgram();
|
||||
|
@ -185,7 +185,7 @@ void VertexManager::vFlush()
|
||||
PixelShaderManager::SetConstants();
|
||||
|
||||
// finally bind
|
||||
FRAGMENTSHADER* ps = PixelShaderCache::SetShader(false,g_nativeVertexFmt->m_components);
|
||||
FRAGMENTSHADER* ps = PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components);
|
||||
VERTEXSHADER* vs = VertexShaderCache::SetShader(g_nativeVertexFmt->m_components);
|
||||
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here.
|
||||
if (vs) VertexShaderCache::SetCurrentShader(vs->glprogid);
|
||||
@ -195,7 +195,9 @@ void VertexManager::vFlush()
|
||||
// run through vertex groups again to set alpha
|
||||
if (!g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate)
|
||||
{
|
||||
ps = PixelShaderCache::SetShader(true,g_nativeVertexFmt->m_components);
|
||||
// TODO: If host supports GL_ARB_blend_func_extended, use
|
||||
// DSTALPHA_DUAL_SOURCE_BLEND and set blend modes accordingly.
|
||||
ps = PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS,g_nativeVertexFmt->m_components);
|
||||
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid);
|
||||
|
||||
// only update alpha
|
||||
|
Reference in New Issue
Block a user