D3D: Fixed dstAlpha, aka "when everything is broken, at least mario have a nice shadow", and removed Cg leftover from it.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4152 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
sl1nk3.s 2009-09-02 04:10:40 +00:00
parent 649dc12a64
commit 3bba897799
10 changed files with 107 additions and 144 deletions

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Version="9,00"
Name="Plugin_VideoDX9"
ProjectGUID="{636FAD5F-02D1-4E9A-BE67-FB8EA99B9A18}"
RootNamespace="Plugin_VideoDX9"
@ -92,7 +92,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="&quot;..\..\core\common\win32\release\common.lib&quot;"
AdditionalDependencies="dsound.lib odbc32.lib odbccp32.lib comctl32.lib d3d9.lib d3dx9.lib winmm.lib cg.lib cgD3D9.lib vfw32.lib"
AdditionalDependencies="dsound.lib odbc32.lib odbccp32.lib comctl32.lib d3d9.lib d3dx9.lib winmm.lib vfw32.lib"
OutputFile="..\..\..\Binary\Win32\Plugins\Plugin_VideoDX9.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
@ -200,11 +200,11 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="cg.lib cgD3D9.lib dsound.lib odbc32.lib odbccp32.lib comctl32.lib d3d9.lib d3dx9.lib winmm.lib vfw32.lib"
AdditionalDependencies="dsound.lib odbc32.lib odbccp32.lib comctl32.lib d3d9.lib d3dx9.lib winmm.lib vfw32.lib"
OutputFile="..\..\..\Binary\x64\Plugins\Plugin_VideoDX9.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\..\..\Externals\Cg64"
AdditionalLibraryDirectories=""
GenerateManifest="false"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
@ -299,7 +299,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="&quot;..\..\core\common\win32\debug\common.lib&quot;"
AdditionalDependencies="dsound.lib odbc32.lib odbccp32.lib comctl32.lib d3d9.lib d3dx9.lib winmm.lib cg.lib cgD3D9.lib vfw32.lib"
AdditionalDependencies="dsound.lib odbc32.lib odbccp32.lib comctl32.lib d3d9.lib d3dx9.lib winmm.lib vfw32.lib"
OutputFile="..\..\..\Binary\Win32/Plugins\Plugin_VideoDX9D.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
@ -397,11 +397,11 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="cg.lib cgD3D9.lib dsound.lib odbc32.lib odbccp32.lib comctl32.lib d3d9.lib d3dx9.lib winmm.lib vfw32.lib"
AdditionalDependencies="dsound.lib odbc32.lib odbccp32.lib comctl32.lib d3d9.lib d3dx9.lib winmm.lib vfw32.lib"
OutputFile="..\..\..\Binary\x64\Plugins\Plugin_VideoDX9D.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\..\..\Externals\Cg64"
AdditionalLibraryDirectories=""
GenerateManifest="false"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"
@ -505,7 +505,7 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="dsound.lib odbc32.lib odbccp32.lib comctl32.lib d3d9.lib d3dx9.lib winmm.lib cg.lib cgD3D9.lib vfw32.lib"
AdditionalDependencies="dsound.lib odbc32.lib odbccp32.lib comctl32.lib d3d9.lib d3dx9.lib winmm.lib vfw32.lib"
OutputFile="..\..\..\Binary\Win32\Plugins\Plugin_VideoDX9DF.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
@ -614,11 +614,11 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="cg.lib cgD3D9.lib dsound.lib odbc32.lib odbccp32.lib comctl32.lib d3d9.lib d3dx9.lib winmm.lib vfw32.lib"
AdditionalDependencies="dsound.lib odbc32.lib odbccp32.lib comctl32.lib d3d9.lib d3dx9.lib winmm.lib vfw32.lib"
OutputFile="..\..\..\Binary\x64\Plugins\Plugin_VideoDX9DF.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\..\..\Externals\Cg64"
AdditionalLibraryDirectories=""
GenerateManifest="false"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(PlatformName)\$(ConfigurationName)\$(TargetName).pdb"

View file

@ -31,6 +31,7 @@ namespace D3D
int resolution;
#define VENDOR_NVIDIA 4318
#define VENDOR_ATI 4098
RECT client;
HWND hWnd;
@ -74,8 +75,10 @@ namespace D3D
void EnableAlphaToCoverage()
{
// dev->SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C'));
Renderer::SetRenderState( D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C') );
if (GetCurAdapter().ident.VendorId == VENDOR_ATI)
Renderer::SetRenderState(D3DRS_POINTSIZE, (D3DFORMAT)MAKEFOURCC('A', '2', 'M', '1'));
else
Renderer::SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C'));
}
void InitPP(int adapter, int resolution, int aa_mode, D3DPRESENT_PARAMETERS *pp)

View file

@ -23,19 +23,20 @@
namespace D3D
{
extern Shader Ps;
extern Shader Vs;
LPDIRECT3DVERTEXSHADER9 CompileVertexShader(const char *code, int len, bool assembly)
LPDIRECT3DVERTEXSHADER9 CompileVertexShader(const char *code, int len)
{
//try to compile
LPD3DXBUFFER shaderBuffer = 0;
LPD3DXBUFFER errorBuffer = 0;
LPDIRECT3DVERTEXSHADER9 vShader = 0;
HRESULT hr;
static char *versions[5] = {"ERROR", "vs_1_4", "vs_2_0", "vs_3_0", "vs_4_0"};
if (assembly)
hr = D3DXAssembleShader(code, len, 0, 0, 0, &shaderBuffer, &errorBuffer);
else
hr = D3DXCompileShader(code, len, 0, 0, "main", "vs_2_0", 0, &shaderBuffer, &errorBuffer, 0);
hr = D3DXCompileShader(code, len, 0, 0, "main", versions[Vs.Major], 0, &shaderBuffer, &errorBuffer, 0);
if (FAILED(hr))
{
@ -69,18 +70,17 @@ LPDIRECT3DVERTEXSHADER9 CompileVertexShader(const char *code, int len, bool asse
return vShader;
}
LPDIRECT3DPIXELSHADER9 CompilePixelShader(const char *code, int len, bool assembly)
LPDIRECT3DPIXELSHADER9 CompilePixelShader(const char *code, int len)
{
LPD3DXBUFFER shaderBuffer = 0;
LPD3DXBUFFER errorBuffer = 0;
LPDIRECT3DPIXELSHADER9 pShader = 0;
static char *versions[6] = {"ERROR", "ps_1_1", "ps_1_4", "ps_2_0", "ps_3_0", "ps_4_0"};
static char *versions[5] = {"ERROR", "ps_1_4", "ps_2_0", "ps_3_0", "ps_4_0"};
HRESULT hr;
if (assembly)
hr = D3DXAssembleShader(code, len, 0, 0, 0, &shaderBuffer, &errorBuffer);
else
hr = D3DXCompileShader(code, len, 0, 0, "main", "ps_2_0", // Pixel Shader 2.0 is enough for all we do
HRESULT hr;
// For some reasons, i had this kind of errors : "Shader uses texture addressing operations
// in a dependency chain that is too complex for the target shader model (ps_2_0) to handle."
hr = D3DXCompileShader(code, len, 0, 0, "main", versions[Ps.Major],
0, &shaderBuffer, &errorBuffer, 0);
if (FAILED(hr))

View file

@ -21,6 +21,6 @@
namespace D3D
{
LPDIRECT3DVERTEXSHADER9 CompileVertexShader(const char *code, int len, bool assembly);
LPDIRECT3DPIXELSHADER9 CompilePixelShader(const char *code, int len, bool assembly);
LPDIRECT3DVERTEXSHADER9 CompileVertexShader(const char *code, int len);
LPDIRECT3DPIXELSHADER9 CompilePixelShader(const char *code, int len);
}

View file

@ -28,9 +28,6 @@
#include "BPMemory.h"
#include "XFMemory.h"
#include <Cg/cg.h>
#include <Cg/cgD3D9.h>
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
const PixelShaderCache::PSCacheEntry *PixelShaderCache::last_entry;
@ -58,14 +55,14 @@ void PixelShaderCache::Shutdown()
PixelShaders.clear();
}
void PixelShaderCache::SetShader()
void PixelShaderCache::SetShader(bool dstAlpha)
{
static LPDIRECT3DPIXELSHADER9 last_shader = NULL;
DVSTARTPROFILE();
PIXELSHADERUID uid;
GetPixelShaderId(uid, PixelShaderManager::GetTextureMask(), false);
GetPixelShaderId(uid, PixelShaderManager::GetTextureMask(), dstAlpha);
PSCache::iterator iter;
iter = PixelShaders.find(uid);
@ -83,9 +80,9 @@ void PixelShaderCache::SetShader()
return;
}
bool HLSL = true;
const char *code = GeneratePixelShader(PixelShaderManager::GetTextureMask(), false, HLSL);
LPDIRECT3DPIXELSHADER9 shader = HLSL ? D3D::CompilePixelShader(code, (int)strlen(code), false) : CompileCgShader(code);
const char *code = GeneratePixelShader(PixelShaderManager::GetTextureMask(), dstAlpha, true);
LPDIRECT3DPIXELSHADER9 shader = D3D::CompilePixelShader(code, (int)strlen(code));
if (shader)
{
//Make an entry in the table
@ -111,25 +108,6 @@ void PixelShaderCache::SetShader()
}
}
LPDIRECT3DPIXELSHADER9 PixelShaderCache::CompileCgShader(const char *pstrprogram)
{
const char *opts[] = {"-profileopts", "MaxLocalParams=256", "-O2", "-q", NULL};
//const char **opts = cgD3D9GetOptimalOptions(g_cgvProf);
CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgfProf, "main", opts);
if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) {
ERROR_LOG(VIDEO, "Failed to create ps %s:\n", cgGetLastListing(g_cgcontext));
ERROR_LOG(VIDEO, pstrprogram);
return false;
}
char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM);
LPDIRECT3DPIXELSHADER9 pixel_shader = D3D::CompilePixelShader(pcompiledprog, (int)strlen(pcompiledprog), true);
cgDestroyProgram(tempprog);
tempprog = NULL;
return pixel_shader;
}
void PixelShaderCache::Cleanup()
{

View file

@ -56,7 +56,7 @@ public:
static void Init();
static void Cleanup();
static void Shutdown();
static void SetShader();
static void SetShader(bool dstAlpha);
#ifdef _DEBUG
static std::string GetCurrentShaderCode();
#endif

View file

@ -39,13 +39,6 @@
#include "EmuWindow.h"
#include "AVIDump.h"
#include <Cg/cg.h>
#include <Cg/cgD3D9.h>
CGcontext g_cgcontext;
CGprofile g_cgvProf;
CGprofile g_cgfProf;
float Renderer::m_x;
float Renderer::m_y;
float Renderer::m_width;
@ -78,30 +71,11 @@ struct Message
static std::list<Message> s_listMsgs;
void HandleCgError(CGcontext ctx, CGerror err, void* appdata)
{
if(!g_Config.bShowShaderErrors)
return;
PanicAlert("Cg error: %s\n", cgGetErrorString(err));
const char* listing = cgGetLastListing(g_cgcontext);
if (listing != NULL) {
PanicAlert("last listing: %s\n", listing);
}
}
void Renderer::Init(SVideoInitialize &_VideoInitialize)
{
EmuWindow::SetSize(g_Res[g_Config.iWindowedRes][0], g_Res[g_Config.iWindowedRes][1]);
D3D::Create(g_Config.iAdapter, EmuWindow::GetWnd(), g_Config.bFullscreen, g_Config.iFSResolution, g_Config.iMultisampleMode);
g_cgcontext = cgCreateContext();
cgGetError();
cgSetErrorHandler(HandleCgError, NULL);
cgD3D9SetDevice(D3D::dev);
g_cgvProf = cgGetProfile("vs_2_0"); //cgD3D9GetLatestVertexProfile();
g_cgfProf = cgGetProfile("ps_2_0"); //cgD3D9GetLatestPixelProfile();
float width = (float)D3D::GetDisplayWidth();
float height = (float)D3D::GetDisplayHeight();
@ -110,8 +84,8 @@ void Renderer::Init(SVideoInitialize &_VideoInitialize)
m_y = 0;
m_width = width;
m_height = height;
xScale = width / (float)EFB_WIDTH;
yScale = height / (float)EFB_HEIGHT;
xScale = m_width / (float)EFB_WIDTH;
yScale = m_height / (float)EFB_HEIGHT;
m_LastFrameDumped = false;
m_AVIDumping = false;
@ -129,10 +103,6 @@ void Renderer::Init(SVideoInitialize &_VideoInitialize)
void Renderer::Shutdown()
{
cgD3D9SetDevice(NULL);
cgDestroyContext(g_cgcontext);
g_cgcontext = NULL;
D3D::font.Shutdown();
D3D::EndFrame();
D3D::Close();
@ -390,7 +360,7 @@ void Renderer::SwapBuffers()
// clearColor |= 0x003F003F;
// D3D::BeginFrame(true,clearColor,1.0f);
D3D::BeginFrame(false, clearColor, 1.0f);
// D3D::EnableAlphaToCoverage();
D3D::EnableAlphaToCoverage();
Postprocess::BeginFrame();
VertexManager::BeginFrame();
@ -438,7 +408,6 @@ void Renderer::SetViewport(float* _Viewport)
}
*/
void Renderer::SetScissorRect()
{
int xoff = bpmem.scissorOffset.x * 2 - 342;
@ -568,8 +537,8 @@ void Renderer::SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Va
// Called from VertexShaderManager
void UpdateViewport()
{
// HACK: Update viewport causes overlay to disappear and the games to move to the
// bottom of the screen for some reason.
// TODO : remove this HACK: Update viewport is still a bit wrong and causes the
// image to be y-offset for some reason though.
return;
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
// [0] = width/2
@ -585,31 +554,19 @@ void UpdateViewport()
(rawViewport[5] - rawViewport[2]) / 16777215.0f, rawViewport[5] / 16777215.0f);*/
D3DVIEWPORT9 vp;
// Keep aspect ratio at 4:3
// rawViewport[0] = 320, rawViewport[1] = -240
int scissorXOff = bpmem.scissorOffset.x * 2 - 342;
int scissorYOff = bpmem.scissorOffset.y * 2 - 342;
float fourThree = 4.0f / 3.0f;
// These were commented out to fix "unreferenced local variable" compiler warnings.
// float wAdj, hAdj;
// float actualRatiow, actualRatioh;
// int overfl;
// int actualWid, actualHei;
int xoffs = 0;
int yoffs = 0;
int wid, hei;
vp.MinZ = (xfregs.rawViewport[5] - xfregs.rawViewport[2])/16777215.0f;
vp.MaxZ = xfregs.rawViewport[5]/16777215.0f;
wid = int(ceil(fabs(2 * xfregs.rawViewport[0])));
hei = int(ceil(fabs(2 * xfregs.rawViewport[1])));
vp.X = (int)((xfregs.rawViewport[3] - xfregs.rawViewport[0] - 342 - scissorXOff) * Renderer::GetXScale());
vp.Y = (int)(Renderer::GetTargetHeight() - (xfregs.rawViewport[4] - xfregs.rawViewport[1] - 342 - scissorYOff) * Renderer::GetYScale());
vp.X = (int)(xfregs.rawViewport[3] - xfregs.rawViewport[0] - 342 - scissorXOff) + xoffs;
vp.Y = (int)(xfregs.rawViewport[4] - xfregs.rawViewport[1] - 342 - scissorYOff) + yoffs;
vp.Width = wid;
vp.Height = hei;
vp.Width = (int)ceil(fabs(2 * xfregs.rawViewport[0]) * Renderer::GetXScale());
vp.Height = (int)ceil(fabs(2 * xfregs.rawViewport[1]) * Renderer::GetYScale());
vp.MinZ = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777215.0f; // NearZ
vp.MaxZ = xfregs.rawViewport[5] / 16777215.0f; // FarZ
D3D::dev->SetViewport(&vp);
}
}

View file

@ -66,9 +66,10 @@ public:
static float GetXScale() { return xScale; }
static float GetYScale() { return yScale; }
static float GetTargetWidth() { return m_width; }
static float GetTargetHeight() { return m_height; }
static void SetScissorRect();
// static void SetViewport(float* _Viewport);
// static void SetProjection(float* _pProjection, int constantIndex = -1);
// The little status display.

View file

@ -239,7 +239,7 @@ void Flush()
VertexShaderManager::SetConstants();
PixelShaderManager::SetConstants();
PixelShaderCache::SetShader();
PixelShaderCache::SetShader(false);
VertexShaderCache::SetShader(g_nativeVertexFmt->m_components);
int stride = g_nativeVertexFmt->GetVertexStride();
@ -249,9 +249,7 @@ void Flush()
int numPrimitives = indexGen.GetNumPrims();
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
pts[(int)collection],
0,
numVertices,
numPrimitives,
0, numVertices, numPrimitives,
fakeIBuffer,
D3DFMT_INDEX16,
fakeVBuffer,
@ -270,6 +268,54 @@ void Flush()
D3D::dev->SetIndices(0);
D3D::dev->DrawPrimitiveUP(D3DPT_POINTLIST, numVertices, fakeVBuffer, stride);
}
if (bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate)
{
DWORD write = 0;
PixelShaderCache::SetShader(true);
// update alpha only
Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA);
Renderer::SetRenderState(D3DRS_ALPHABLENDENABLE, false);
g_nativeVertexFmt->SetupVertexPointers();
if (collection != C_POINTS)
{
int numPrimitives = indexGen.GetNumPrims();
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
pts[(int)collection],
0, numVertices, numPrimitives,
fakeIBuffer,
D3DFMT_INDEX16,
fakeVBuffer,
stride))) {
#ifdef _DEBUG
std::string error_shaders;
error_shaders.append(VertexShaderCache::GetCurrentShaderCode());
error_shaders.append(PixelShaderCache::GetCurrentShaderCode());
File::WriteStringToFile(true, error_shaders, "bad_shader_combo.txt");
PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to shaders.txt.");
#endif
}
}
else
{
D3D::dev->SetIndices(0);
D3D::dev->DrawPrimitiveUP(D3DPT_POINTLIST, numVertices, fakeVBuffer, stride);
}
if (bpmem.blendmode.alphaupdate)
write = D3DCOLORWRITEENABLE_ALPHA;
if (bpmem.blendmode.colorupdate)
write |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE;
if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract)
Renderer::SetRenderState(D3DRS_ALPHABLENDENABLE, true);
Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, write);
INCSTAT(stats.thisFrame.numDrawCalls);
}
INCSTAT(stats.thisFrame.numDrawCalls);
}

View file

@ -28,9 +28,6 @@
#include "BPMemory.h"
#include "XFMemory.h"
#include <Cg/cg.h>
#include <Cg/cgD3D9.h>
VertexShaderCache::VSCache VertexShaderCache::vshaders;
const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
@ -83,9 +80,9 @@ void VertexShaderCache::SetShader(u32 components)
return;
}
bool HLSL = true;
const char *code = GenerateVertexShader(components, HLSL);
LPDIRECT3DVERTEXSHADER9 shader = HLSL ? D3D::CompileVertexShader(code, (int)strlen(code), false) : CompileCgShader(code);
const char *code = GenerateVertexShader(components, true);
LPDIRECT3DVERTEXSHADER9 shader = D3D::CompileVertexShader(code, (int)strlen(code));
if (shader)
{
// Make an entry in the table
@ -108,28 +105,9 @@ void VertexShaderCache::SetShader(u32 components)
{
PanicAlert("Failed to compile Vertex Shader:\n\n%s", code);
}
Renderer::SetFVF(NULL);
D3D::dev->SetVertexShader(shader);
}
LPDIRECT3DVERTEXSHADER9 VertexShaderCache::CompileCgShader(const char *pstrprogram)
{
//char stropt[64];
//sprintf(stropt, "MaxLocalParams=256,MaxInstructions=%d", s_nMaxVertexInstructions);
const char *opts[] = {"-profileopts", "MaxLocalParams=256", "-O2", "-q", NULL};
//const char **opts = cgD3D9GetOptimalOptions(g_cgvProf);
CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgvProf, "main", opts);
if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) {
ERROR_LOG(VIDEO, "Failed to load vs %s:\n", cgGetLastListing(g_cgcontext));
ERROR_LOG(VIDEO, pstrprogram);
return NULL;
}
const char *pcompiledprog = cgGetProgramString(tempprog, CG_COMPILED_PROGRAM);
LPDIRECT3DVERTEXSHADER9 vertex_shader = D3D::CompileVertexShader(pcompiledprog, (int)strlen(pcompiledprog), true);
cgDestroyProgram(tempprog);
tempprog = NULL;
return vertex_shader;
//D3D::dev->SetVertexShader(shader);
}
void VertexShaderCache::Cleanup()